1 /*
2 * Copyright 2021 MindMotion Microelectronics Co., Ltd.
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "hal_usb.h"
9
10
USB_SetBufDespTableAddr(USB_Type * USBx,uint32_t addr)11 void USB_SetBufDespTableAddr(USB_Type * USBx, uint32_t addr)
12 {
13 USBx->BDTPAGE01 = USB_BDTPAGE01_BDTBA(addr >> 9u);
14 USBx->BDTPAGE02 = USB_BDTPAGE02_BDTBA(addr >> 16u);
15 USBx->BDTPAGE03 = USB_BDTPAGE03_BDTBA(addr >> 24u);
16 }
17
USB_InitDevice(USB_Type * USBx,USB_Device_Init_Type * init)18 void USB_InitDevice(USB_Type * USBx, USB_Device_Init_Type *init)
19 {
20 if ( (uintptr_t)(init->BufDespTable_Addr) % 512u != 0u)
21 {
22 return;
23 }
24 USB_SetDeviceAddr(USBx, 0x00u);
25 USB_SetBufDespTableAddr(USBx, init->BufDespTable_Addr);
26 USB_Enable(USBx, true);
27 }
28
USB_EnableInterrupts(USB_Type * USBx,uint32_t interrupts,bool enable)29 void USB_EnableInterrupts(USB_Type * USBx, uint32_t interrupts, bool enable)
30 {
31 if(enable)
32 {
33 USBx->INTENB |= interrupts;
34 }
35 else
36 {
37 USBx->INTENB &= ~interrupts;
38 }
39 }
40
USB_GetEnabledInterrupts(USB_Type * USBx)41 uint32_t USB_GetEnabledInterrupts(USB_Type * USBx)
42 {
43 return USBx->INTENB;
44 }
45
USB_GetInterruptStatus(USB_Type * USBx)46 uint32_t USB_GetInterruptStatus(USB_Type * USBx)
47 {
48 uint32_t stat = USBx->INTSTAT;
49 uint32_t enb = USBx->INTENB;
50 return stat & enb;
51 }
52
USB_ClearInterruptStatus(USB_Type * USBx,uint32_t interrupts)53 void USB_ClearInterruptStatus(USB_Type * USBx, uint32_t interrupts)
54 {
55 uint32_t enb = USBx->INTENB;
56 USBx->INTSTAT = interrupts & enb;
57 }
58
USB_EnableErrInterrupts(USB_Type * USBx,uint32_t interrupts,bool enable)59 void USB_EnableErrInterrupts(USB_Type * USBx, uint32_t interrupts, bool enable)
60 {
61 if(enable)
62 {
63 USBx->ERRENB |= interrupts;
64 }
65 else
66 {
67 USBx->ERRENB &= ~interrupts;
68 }
69 }
70
71
USB_GetEnabledErrInterrupts(USB_Type * USBx)72 uint32_t USB_GetEnabledErrInterrupts(USB_Type * USBx)
73 {
74 return USBx->ERRENB;
75 }
76
USB_GetErrInterruptStatus(USB_Type * USBx)77 uint32_t USB_GetErrInterruptStatus(USB_Type * USBx)
78 {
79 uint32_t stat = USBx->ERRSTAT;
80 uint32_t enb = USBx->ERRENB;
81 USBx->ERRSTAT = stat & ~enb;
82 return stat & enb;
83 }
84
USB_ClearErrInterruptStatus(USB_Type * USBx,uint32_t interrupts)85 void USB_ClearErrInterruptStatus(USB_Type * USBx, uint32_t interrupts)
86 {
87 uint32_t enb = USBx->ERRENB;
88 USBx->ERRSTAT = interrupts & enb;
89 }
90
USB_GetBufDespIndex(USB_Type * USBx)91 uint32_t USB_GetBufDespIndex(USB_Type * USBx)
92 {
93 return (USBx->STAT)>>2;
94 }
95
USB_Enable(USB_Type * USBx,bool enable)96 void USB_Enable(USB_Type * USBx, bool enable)
97 {
98 if(enable)
99 {
100 USBx->CTL |= USB_CTL_USBEN_MASK;
101 }
102 else
103 {
104 USBx->CTL &= ~USB_CTL_USBEN_MASK;
105 }
106 }
107
USB_EnableOddEvenReset(USB_Type * USBx,bool enable)108 void USB_EnableOddEvenReset(USB_Type * USBx, bool enable)
109 {
110 if(enable)
111 {
112 USBx->CTL |= USB_CTL_ODDRST_MASK;
113 }
114 else
115 {
116 USBx->CTL &= ~USB_CTL_ODDRST_MASK;
117 }
118 }
119
USB_EnableResumeSignal(USB_Type * USBx,bool enable)120 void USB_EnableResumeSignal(USB_Type * USBx, bool enable)
121 {
122 if(enable)
123 {
124 USBx->CTL |= USB_CTL_RESUME_MASK;
125 }
126 else
127 {
128 USBx->CTL &= ~USB_CTL_RESUME_MASK;
129 }
130 }
131
USB_EnableSuspend(USB_Type * USBx,bool enable)132 void USB_EnableSuspend(USB_Type * USBx, bool enable)
133 {
134 if(true == enable)
135 {
136 USBx->CTL |= USB_CTL_TXDSUSPENDTOKENBUSY_MASK;
137 }
138 else
139 {
140 USBx->CTL &= ~USB_CTL_TXDSUSPENDTOKENBUSY_MASK;
141 }
142
143 }
144
145
USB_SetDeviceAddr(USB_Type * USBx,uint8_t addr)146 void USB_SetDeviceAddr(USB_Type * USBx, uint8_t addr)
147 {
148 USBx->ADDR = ( (USBx->ADDR & ~USB_ADDR_ADDR_MASK)
149 | (addr & USB_ADDR_ADDR_MASK) )
150 ;
151 }
152
USB_GetDeviceAddr(USB_Type * USBx)153 uint8_t USB_GetDeviceAddr(USB_Type * USBx)
154 {
155 return USBx->ADDR & USB_ADDR_ADDR_MASK;
156 }
157
USB_GetBufDespTableAddr(USB_Type * USBx)158 uint32_t USB_GetBufDespTableAddr(USB_Type * USBx)
159 {
160 return (uint32_t)
161 ( ( (USBx->BDTPAGE01 >> USB_BDTPAGE01_BDTBA_SHIFT) << 9u )
162 | ( (USBx->BDTPAGE02 >> USB_BDTPAGE02_BDTBA_SHIFT) << 16u)
163 | ( (USBx->BDTPAGE03 >> USB_BDTPAGE03_BDTBA_SHIFT) << 24u)
164 );
165 }
166
USB_GetFrameNumber(USB_Type * USBx)167 uint32_t USB_GetFrameNumber(USB_Type * USBx)
168 {
169 return (USBx->FRMNUML) | (USBx->FRMNUML << 7u);
170 }
171
USB_GetBufDesp(USB_Type * USBx)172 USB_BufDesp_Type * USB_GetBufDesp(USB_Type * USBx)
173 {
174 USB_BufDespTable_Type *bdt = (USB_BufDespTable_Type *)USB_GetBufDespTableAddr(USBx);
175 return &bdt->Index[USBx->STAT >> 2];
176 }
177
USB_BufDesp_GetTokenPid(USB_BufDesp_Type * bd)178 USB_TokenPid_Type USB_BufDesp_GetTokenPid(USB_BufDesp_Type * bd)
179 {
180 return (USB_TokenPid_Type)bd->TOK_PID;
181 }
182
USB_BufDesp_GetPacketAddr(USB_BufDesp_Type * bd)183 uint32_t USB_BufDesp_GetPacketAddr(USB_BufDesp_Type * bd)
184 {
185 return bd->ADDR;
186 }
187
USB_BufDesp_GetPacketSize(USB_BufDesp_Type * bd)188 uint32_t USB_BufDesp_GetPacketSize(USB_BufDesp_Type * bd)
189 {
190 return bd->BC;
191 }
192
USB_BufDesp_Reset(USB_BufDesp_Type * bd)193 void USB_BufDesp_Reset(USB_BufDesp_Type * bd)
194 {
195 bd->BDT_STALL = 0u;
196 bd->NINC = 0u;
197 bd->KEEP = 0u;
198 bd->DTS = 1u;
199 }
200
USB_GetEndPointIndex(USB_Type * USBx)201 uint32_t USB_GetEndPointIndex(USB_Type * USBx)
202 {
203 return (USBx->STAT & USB_STAT_ENDP_MASK) >> USB_STAT_ENDP_SHIFT;
204 }
205
USB_GetXferDirection(USB_Type * USBx)206 USB_Direction_Type USB_GetXferDirection(USB_Type * USBx)
207 {
208 return (USB_Direction_Type)( (USBx->STAT & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT);
209 }
210
USB_GetBufDespOddEven(USB_Type * USBx)211 USB_BufDesp_OddEven_Type USB_GetBufDespOddEven(USB_Type * USBx)
212 {
213 return (USB_BufDesp_OddEven_Type)( (USBx->STAT & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT );
214 }
215
USB_BufDesp_Xfer(USB_BufDesp_Type * bd,uint32_t data_n,uint8_t * buffer,uint32_t len)216 bool USB_BufDesp_Xfer(USB_BufDesp_Type * bd, uint32_t data_n, uint8_t * buffer, uint32_t len)
217 {
218 if (1u == bd->OWN)
219 {
220 return false;
221 }
222 bd->ADDR = (uint32_t)buffer;
223 bd->DATA = data_n;
224 bd->BC = len;
225 bd->OWN = 1u;
226 return true;
227 }
228
USB_BufDesp_IsBusy(USB_BufDesp_Type * bd)229 bool USB_BufDesp_IsBusy(USB_BufDesp_Type * bd)
230 {
231 if (1u == bd->OWN)
232 {
233 return true;
234 }
235 else
236 {
237 return false;
238 }
239 }
240
USB_EnableEndPoint(USB_Type * USBx,uint32_t index,USB_EndPointMode_Type mode,bool enable)241 void USB_EnableEndPoint(USB_Type * USBx, uint32_t index, USB_EndPointMode_Type mode, bool enable)
242 {
243 if (false == enable)
244 {
245 USBx->EPCTL[index] = 0u;
246 USB_BufDespTable_Type * bdt = (USB_BufDespTable_Type * )USB_GetBufDespTableAddr(USBx);
247 bdt->Table[index][0u][0u].HEAD = 0u;
248 bdt->Table[index][0u][1u].HEAD = 0u;
249 bdt->Table[index][1u][0u].HEAD = 0u;
250 bdt->Table[index][1u][1u].HEAD = 0u;
251 return;
252 }
253 if (USB_EndPointMode_Control == mode)
254 {
255 USBx->EPCTL[index] |= USB_EPCTL_EPCTLDISEPRXENEPTXEN(3) | USB_EPCTL_EPHSHK_MASK;
256 }
257 else if (USB_EndPointMode_Bulk == mode)
258 {
259 USBx->EPCTL[index] |= USB_EPCTL_EPCTLDISEPRXENEPTXEN(7u) | USB_EPCTL_EPHSHK_MASK;
260 }
261 else if (USB_EndPointMode_Interrupt == mode)
262 {
263 USBx->EPCTL[index] |= USB_EPCTL_EPCTLDISEPRXENEPTXEN(7u) | USB_EPCTL_EPHSHK_MASK;
264 }
265 else if (USB_EndPointMode_Isochronous == mode)
266 {
267 USBx->EPCTL[index] |= USB_EPCTL_EPCTLDISEPRXENEPTXEN(7u);
268 }
269 }
270
USB_EnableEndPointStall(USB_Type * USBx,uint32_t index,bool enable)271 void USB_EnableEndPointStall(USB_Type * USBx, uint32_t index, bool enable)
272 {
273 USB_BufDespTable_Type * bdt = (USB_BufDespTable_Type * )USB_GetBufDespTableAddr(USBx);
274 for (uint32_t i = 0; i < USB_BDT_EP_NUM; i++)
275 {
276 if (true == enable)
277 {
278 USBx->EPCTL[i] |= USB_EPCTL_EPSTALL_MASK;
279 bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_IN ].BDT_STALL = 1u;
280 bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_OUT].BDT_STALL = 1u;
281 bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_IN ].BDT_STALL = 1u;
282 bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_OUT].BDT_STALL = 1u;
283 }
284 else
285 {
286 USBx->EPCTL[i] &= ~USB_EPCTL_EPSTALL_MASK;
287 bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_IN ].BDT_STALL = 0u;
288 bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_IN ].OWN = 0u;
289 bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_OUT].BDT_STALL = 0u;
290 bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_OUT].OWN = 0u;
291 bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_IN ].BDT_STALL = 0u;
292 bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_IN ].OWN = 0u;
293 bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_OUT].BDT_STALL = 0u;
294 bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_OUT].OWN = 0u;
295 }
296 }
297 }
298
USB_GetEnabledEndPointStall(USB_Type * USBx)299 uint32_t USB_GetEnabledEndPointStall(USB_Type * USBx)
300 {
301 uint32_t status = 0u;
302 for(uint32_t i = 0u; i < USB_BDT_EP_NUM; i++)
303 {
304 if (0 != (USBx->EPCTL[i] & USB_EPCTL_EPSTALL_MASK) )
305 {
306 status |= 1u << i;
307 }
308 }
309 return status;
310 }
311
312 /* EOF. */
313
314