aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/os/hal/ports/NUMICRO/LLD/USBv1/usb_memcpy.S
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/os/hal/ports/NUMICRO/LLD/USBv1/usb_memcpy.S')
-rw-r--r--lib/chibios-contrib/os/hal/ports/NUMICRO/LLD/USBv1/usb_memcpy.S159
1 files changed, 159 insertions, 0 deletions
diff --git a/lib/chibios-contrib/os/hal/ports/NUMICRO/LLD/USBv1/usb_memcpy.S b/lib/chibios-contrib/os/hal/ports/NUMICRO/LLD/USBv1/usb_memcpy.S
new file mode 100644
index 000000000..7b4958a1f
--- /dev/null
+++ b/lib/chibios-contrib/os/hal/ports/NUMICRO/LLD/USBv1/usb_memcpy.S
@@ -0,0 +1,159 @@
1/*
2 ChibiOS - Copyright (C) 2020 Alex Lewontin
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file usb_memcpy.S
19 * @brief Definition of the usb_memcpy function
20 *
21 * @addtogroup USB
22 * @{
23 */
24
25#if !defined(__DOXYGEN__)
26
27 .syntax unified
28 .cpu cortex-m0
29 .thumb
30
31 .section .text, "ax"
32 .align 4
33 .global usb_memcpy
34
35/* size_t usb_memcpy(volatile void* destination, const volatile void* source, size_t num); */
36usb_memcpy:
37 cmp r2, #0
38 beq.n zero_return
39 push {r2, r4, r5, r6, r7, lr}
40
41 movs r3, #3
42
43check_alignment:
44 tst r0, r3
45 bne.n offset
46 tst r1, r3
47 bne.n unaligned
48
49aligned:
50/* r0: dest, r1: src, r2: num, r3: #3 */
51 movs r4, r2
52
53 bics r4, r3
54 movs r6, r4
55
56 b.n aligned_loop_check
57aligned_loop_top:
58 subs r4, r4, #4
59 ldr r5, [r1, r4]
60 str r5, [r0, r4]
61aligned_loop_check:
62 bne.n aligned_loop_top
63
64
65leftover_check:
66 ands r2, r3
67 beq.n return
68
69/* if there are leftovers, we can read them all in one */
70
71/* byte mode */
72 ldr r4, =0x40060000
73 ldr r5, [r4, #16]
74 movs r7, #128
75 lsls r7, r7, #3 /* USBD_ATTR_BYTEM_Msk */
76 orrs r5, r7
77 str r5, [r4, #16]
78 adds r1, r1, r6
79 adds r0, r0, r6
80
81/*
82 * r0: dest
83 * r1: src
84 * r2 is 1, 2, or 3 (# of bytes left)
85 * r3: #3
86 * r4: &USBD
87 * r5: USBD->ATTR
88 * r6: leftover offset base
89 * r7: USBD_ATTR_BYTEM_Msk
90 */
91 ldrb r3, [r1, #0]
92 strb r3, [r0, #0]
93
94 cmp r2, #1
95 beq.n word_mode_return
96
97 ldrb r3, [r1, #1]
98 strb r3, [r0, #1]
99
100 cmp r2, #2
101 beq.n word_mode_return
102
103 ldrb r3, [r1, #2]
104 strb r3, [r0, #2]
105
106word_mode_return:
107 ldr r5, [r4, #16]
108 bics r5, r7
109 str r5, [r4, #16]
110return:
111 pop {r0, r4, r5, r6, r7, pc}
112zero_return:
113 movs r0, #0
114 bx.n lr
115
116offset:
117 ldr r4, =0x40060000
118 ldr r5, [r4, #16]
119 movs r7, #128
120 lsls r7, r7, #3 /* USBD_ATTR_BYTEM_Msk */
121 orrs r5, r7
122 str r5, [r4, #16]
123
124offset_loop:
125 ldrb r6, [r1, #0]
126 strb r6, [r0, #0]
127 adds r0, r0, #1
128 adds r1, r1, #1
129 subs r2, r2, #1
130
131 beq.n word_mode_return
132 tst r0, r3
133 bne.n offset_loop
134 tst r1, r3
135 bne.n unaligned_loop_top
136
137 ldr r5, [r4, #16]
138 bics r5, r7
139 str r5, [r4, #16]
140 b.n aligned
141
142unaligned:
143 ldr r4, =0x40060000
144 ldr r5, [r4, #16]
145 movs r7, #128
146 lsls r7, r7, #3 /* USBD_ATTR_BYTEM_Msk */
147 orrs r5, r7
148 str r5, [r4, #16]
149
150unaligned_loop_top:
151 subs r2, r2, #1
152 ldrb r5, [r1, r2]
153 strb r5, [r0, r2]
154unaligned_loop_check:
155 bne.n unaligned_loop_top
156
157 b.n word_mode_return
158
159#endif