1 /***********************************************************************
2 * Filename : hal_lpuart.c
3 * Description : lpuart driver source file
4 * Author(s) : xwl
5 * version : V1.0
6 * Modify date : 2019-11-19
7 ***********************************************************************/
8 #include "ACM32Fxx_HAL.h"
9
10 static uint16_t ep1_stall[2]= {0}; // EP1 stall״̬
11 static uint16_t ep2_stall[2]= {0}; // EP2 stall״̬
12 static uint16_t ep3_stall[2]= {0}; // EP3 stall״̬
13 static uint16_t ep4_stall[2]= {0}; // EP3 stall״̬
14
HAL_FSUSB_MSP_Init(void)15 uint32_t HAL_FSUSB_MSP_Init(void)
16 {
17 GPIO_InitTypeDef GPIO_init_para;
18
19 System_Module_Reset(RST_USB);
20 System_Module_Enable(EN_USB);
21
22 if( HAL_OK != System_USB_PHY_Config())
23 {
24 return HAL_ERROR;
25 }
26
27 SCU->PABADS = (SCU->PABADS | ( (0x3 << 11)) );
28 // GPIO_init_para.Pin = GPIO_PIN_11 | GPIO_PIN_12;
29 // GPIO_init_para.Mode = GPIO_MODE_ANALOG;
30 // GPIO_init_para.Pull = GPIO_NOPULL;
31 // GPIO_init_para.Alternate = GPIO_FUNCTION_0;
32 // HAL_GPIO_Init(GPIOA, &GPIO_init_para);
33
34 NVIC_ClearPendingIRQ(USB_IRQn);
35 NVIC_EnableIRQ(USB_IRQn);
36
37 return HAL_OK;
38 }
39
HAL_FSUSB_Init(void)40 uint32_t HAL_FSUSB_Init(void)
41 {
42 if (HAL_OK != HAL_FSUSB_MSP_Init())
43 {
44 return HAL_ERROR;
45 }
46
47 System_Delay(10);
48
49 USBCTRL->WORKING_MODE = 0x04; //disconnect usb/ reset USBC
50 System_Delay(3000);
51 USBCTRL->WORKING_MODE = 0x09 ; //auto reset, fullspeed
52
53 USBCTRL->EPxCSR[0] |= 1<<8; //enable EP0
54 USBCTRL->EPxCSR[1] |= 1<<8; //enable EP1
55 USBCTRL->EPxCSR[2] |= 1<<8; //enable EP2
56 USBCTRL->EPxCSR[3] |= 1<<8; //enable EP3
57 USBCTRL->EPxCSR[4] |= 1<<8; //enable EP4
58 USBCTRL->EPADDR_CFG = 0x4321;
59
60 USBINT->INT_EN = 0x92427; // enable Reset,Resume,Suspend,setup, EP1/2/3/4 OUT interrupt
61
62 USBCTRL->WORKING_MODE |= (1<<6)|(1<<4); //connect
63
64 return HAL_OK;
65 }
66
HAL_FSUSB_Get_FIFO_Length(uint8_t ep_index)67 uint16_t HAL_FSUSB_Get_FIFO_Length(uint8_t ep_index)
68 {
69 return USBCTRL->EPxCSR[ep_index]&0xff;
70 }
71
HAL_USB_Clear_FIFO(uint8_t ep_index,uint8_t ep_dir)72 void HAL_USB_Clear_FIFO(uint8_t ep_index, uint8_t ep_dir)
73 {
74 USBCTRL->EPxCSR[ep_index] |= 1<<9;
75 }
76
HAL_USB_Get_Stall_Status(uint8_t ep_index,uint8_t ep_dir)77 uint16_t HAL_USB_Get_Stall_Status(uint8_t ep_index, uint8_t ep_dir)
78 {
79 switch(ep_index)
80 {
81 case USB_EP1:
82 {
83 if(ep_dir == EP_DIR_IN) return ep1_stall[0]; //in
84 else return ep1_stall[1]; //out
85 }
86 case USB_EP2:
87 {
88 if(ep_dir == EP_DIR_IN) return ep2_stall[0]; //in
89 else return ep2_stall[1]; //out
90 }
91 case USB_EP3:
92 {
93 if(ep_dir == EP_DIR_IN) return ep3_stall[0]; //in
94 else return ep3_stall[1]; //out
95 }
96 case USB_EP4:
97 {
98 if(ep_dir == EP_DIR_IN) return ep4_stall[0]; //in
99 else return ep4_stall[1]; //out
100 }
101
102 default: return 0xff;
103 }
104 }
105
usb_clear_stall(uint8_t ep_index,uint8_t ep_dir)106 void usb_clear_stall(uint8_t ep_index, uint8_t ep_dir)
107 {
108 switch(ep_index)
109 {
110 case USB_EP1:
111 {
112 if(ep_dir == EP_DIR_IN) ep1_stall[0]=0x0000; //in
113 else ep1_stall[1]=0x0000; //out
114 break;
115 }
116 case USB_EP2:
117 {
118 if(ep_dir == EP_DIR_IN) ep2_stall[0]=0x0000; //in
119 else ep2_stall[1]=0x0000; //out
120 break;
121 }
122 case USB_EP3:
123 {
124 if(ep_dir == EP_DIR_IN) ep3_stall[0]=0x0000; //in
125 else ep3_stall[1]=0x0000; //out
126 break;
127 }
128 case USB_EP4:
129 {
130 if(ep_dir == EP_DIR_IN) ep4_stall[0]=0x0000; //in
131 else ep4_stall[1]=0x0000; //out
132 break;
133 }
134
135 default: return;
136 }
137
138 USBCTRL->EPxCSR[ep_index] = 0x02100; //clear in/out toggle,stall,stall status
139 USBCTRL->EPxCSR[ep_index] |= (1<<18)|(1<<15); //enable change
140 // flag_clear_stall=0;
141 }
142
143
144
usb_send_stall(uint8_t ep_index,uint8_t ep_dir)145 void usb_send_stall(uint8_t ep_index, uint8_t ep_dir)
146 {
147 switch(ep_index)
148 {
149 case USB_EP1:
150 {
151 if(ep_dir == EP_DIR_IN) ep1_stall[0]=0x0001; //in
152 else ep1_stall[1]=0x0001; //out
153 break;
154 }
155 case USB_EP2:
156 {
157 if(ep_dir == EP_DIR_IN) ep2_stall[0]=0x0001; //in
158 else ep2_stall[1]=0x0001; //out
159 break;
160 }
161 case USB_EP3:
162 {
163 if(ep_dir == EP_DIR_IN) ep3_stall[0]=0x0001; //in
164 else ep3_stall[1]=0x0001; //out
165 break;
166 }
167 case USB_EP4:
168 {
169 if(ep_dir == EP_DIR_IN) ep4_stall[0]=0x0001; //in
170 else ep4_stall[1]=0x0001; //out
171 break;
172 }
173
174 default: return;
175 }
176
177 USBCTRL->EPxCSR[ep_index] |= (1<<12);
178 }
179
180
HAL_FSUSB_Read_EP_MEM8(uint8_t * dst,uint32_t length,uint32_t fifo_offset,uint8_t ep_index)181 void HAL_FSUSB_Read_EP_MEM8(uint8_t *dst, uint32_t length, uint32_t fifo_offset, uint8_t ep_index)
182 {
183 uint8_t *src;
184
185 src = (uint8_t *)(USB_BASE+0x200+(ep_index<<6)+fifo_offset);
186 while(length--)
187 {
188 *dst++ = *src++;
189 }
190 }
191
HAL_FSUSB_Write_EP_MEM8(uint8_t * src,uint32_t length,uint32_t fifo_offset,uint8_t ep_index)192 void HAL_FSUSB_Write_EP_MEM8(uint8_t *src, uint32_t length, uint32_t fifo_offset, uint8_t ep_index)
193 {
194
195 uint8_t *dst;
196
197 dst = (uint8_t *)(USB_BASE+0x200+(ep_index<<6)+fifo_offset);
198
199 while(length--)
200 {
201 *dst++ = *src++;
202 }
203 }
204
205
HAL_FSUSB_Start_EP_Transfer(uint32_t length,uint8_t ep_index)206 uint8_t HAL_FSUSB_Start_EP_Transfer(uint32_t length,uint8_t ep_index)
207 {
208 uint8_t intoken_cnt;
209
210 USBCTRL->EPxSENDBN[ep_index]= length;
211
212 while(1)
213 {
214 // if a new out data packet received, return error to caller
215 if( (USBINT->INT_STAT_RAW & MASK_EPX_OUT(ep_index)) && (USBINT->INT_STAT_RAW & MASK_EPX_ACK(ep_index)) )
216 {
217 USBINT->INT_CLR = MASK_EPX_OUT(ep_index);
218 USBINT->INT_CLR = MASK_EPX_ACK(ep_index);
219 return ERROR_OUT_OUT;
220 }
221 // wait for IN token to start transfer
222 if(USBINT->INT_STAT_RAW & MASK_EPX_IN(ep_index) )
223 {
224 USBINT->INT_CLR = MASK_EPX_IN(ep_index);
225 USBCTRL->WORKING_MODE |= (1<<11);//return NAK when timeout
226 USBCTRL->EPxCSR[ep_index] |= (1<<10);//data is ready for tx
227 break;
228 }
229 }
230
231
232 while(1)
233 {
234 if( USBCTRL->EPxCSR[ep_index]&0x1000000 ) //received ACK from host
235 {
236 USBINT->INT_CLR = MASK_EPX_ACK(ep_index);
237 USBINT->INT_CLR = MASK_EPX_IN(ep_index);
238 return 0;//pass
239 }
240
241 if(USBINT->INT_STAT_RAW & (1<<21) ) // timeout occurs when wait ACK
242 {
243 USBINT->INT_CLR = (1<<21);
244 intoken_cnt = 4;
245 while(intoken_cnt) // wait 3 SOF frame for bad signal, during this time, device will send NACK when IN token received
246 {
247 if(USBINT->INT_STAT_RAW & (1<<3))
248 {
249 intoken_cnt --;
250 USBINT->INT_CLR = (1<<3);
251 }
252 }
253 USBINT->INT_CLR = MASK_EPX_TIMEOUT(ep_index); // device recover to send data packet after IN token received
254 }
255
256 if(USBINT->INT_STAT_RAW & MASK_EPX_OUT(ep_index))
257 {
258 return ERROR_IN_OUT;
259 }
260 }
261 }
262
263
HAL_FSUSB_Send_Data(uint8_t * buffer,uint32_t length,uint8_t ep_index)264 uint8_t HAL_FSUSB_Send_Data(uint8_t *buffer,uint32_t length,uint8_t ep_index)
265 {
266 uint8_t ret;
267
268 while(length>=EPX_MAX_PACKET_SIZE)
269 {
270 HAL_FSUSB_Write_EP_MEM8(buffer,EPX_MAX_PACKET_SIZE,0, ep_index);
271 ret = HAL_FSUSB_Start_EP_Transfer(EPX_MAX_PACKET_SIZE, ep_index);
272 if(ret == ERROR_OUT_OUT)
273 {
274 if( USBCTRL->EPxCSR[ep_index] & ( 1<< 19) )//Toggle error
275 {
276 USBCTRL->EPxCSR[ep_index] ^= (1<<17); //out toggle want
277 USBCTRL->EPxCSR[ep_index] |= (1<<18); //update want toggle;
278 }
279 USBCTRL->EPxCSR[ep_index] |= 1<<11; //set rx ready
280 continue; // received a same packet, has processed this packet, just fill respoonse to fifo and send it to host
281 }
282 else if(ret != 0)
283 {
284 return 1; // send data fail, exit with error code to let caller know
285 }
286 length -= EPX_MAX_PACKET_SIZE;
287 buffer += EPX_MAX_PACKET_SIZE;
288 }
289 // remaining data, less than EPX_MAX_PACKET_SIZE
290 while(length>0)
291 {
292 HAL_FSUSB_Write_EP_MEM8(buffer,length,0,ep_index);
293 ret = HAL_FSUSB_Start_EP_Transfer(length,ep_index);
294 if(ret == ERROR_OUT_OUT)
295 {
296 if( USBCTRL->EPxCSR[ep_index] & ( 1<< 19) )//Toggle error
297 {
298 USBCTRL->EPxCSR[ep_index] ^= (1<<17); //out toggle want
299 USBCTRL->EPxCSR[ep_index] |= (1<<18); //update want toggle;
300 }
301 USBCTRL->EPxCSR[ep_index] |= 1<<11; //set rx ready
302 continue;
303 }
304 else if(ret != 0)
305 {
306 return 1; // send data fail, exit with error code to let caller know
307 }
308 length -= length;
309 buffer += length;
310 }
311
312 return 0;
313 }
314
315
HAL_FSUSB_Receive_Data(uint8_t * buffer,uint32_t length,uint8_t ep_index)316 void HAL_FSUSB_Receive_Data(uint8_t *buffer,uint32_t length,uint8_t ep_index)
317 {
318 uint32_t len;
319
320 while(length>0)
321 {
322 while(1)
323 {
324 // wait an out data packet and device has sent an ACK to HOST
325 if( (USBINT->INT_STAT_RAW & MASK_EPX_OUT(ep_index)) && (USBINT->INT_STAT_RAW & MASK_EPX_ACK(ep_index)) )
326 {
327 break;
328 }
329 }
330 USBINT->INT_CLR = MASK_EPX_OUT(ep_index);
331 USBINT->INT_CLR = MASK_EPX_ACK(ep_index);
332
333 if( USBCTRL->EPxCSR[ep_index] & ( 1<< 19) )//Toggle error
334 {
335 USBCTRL->EPxCSR[ep_index] ^= (1<<17); //out toggle want
336 USBCTRL->EPxCSR[ep_index] |= (1<<18); //update want toggle;
337 USBCTRL->EPxCSR[ep_index] |= 1<<11; //set rx ready, wait for a new packet
338 continue; //discard this packet
339 }
340
341 len =HAL_FSUSB_Get_FIFO_Length(ep_index);
342 HAL_FSUSB_Read_EP_MEM8(buffer,len,0,ep_index);
343 USBCTRL->EPxCSR[ep_index] |= 1<<11; //set rx ready to wait next packet
344
345 length -= len;
346 buffer += len;
347 }
348 }
349
350
351 //ep_index表示的是菜单
HAL_FSUSB_EP0_Send_Empty_Packet(void)352 void HAL_FSUSB_EP0_Send_Empty_Packet(void)
353 {
354 HAL_FSUSB_Start_EP_Transfer(0,USB_EP0);
355 }
356
HAL_FSUSB_EP0_Send_Stall(void)357 void HAL_FSUSB_EP0_Send_Stall(void)
358 {
359 USBCTRL->EPxCSR[0] |= 1<<12;
360 while(!(USBCTRL->EPxCSR[0] &0x2000));
361 USBCTRL->EPxCSR[0] |= 0x2000;
362 }
363
364
365
366
367
368
369
370
371
372
373