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