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