123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- /***********************************************************************
- * Filename : hal_lpuart.c
- * Description : lpuart driver source file
- * Author(s) : xwl
- * version : V1.0
- * Modify date : 2019-11-19
- ***********************************************************************/
- #include "ACM32Fxx_HAL.h"
- static uint16_t ep1_stall[2]= {0}; // EP1 stall״̬
- static uint16_t ep2_stall[2]= {0}; // EP2 stall״̬
- static uint16_t ep3_stall[2]= {0}; // EP3 stall״̬
- static uint16_t ep4_stall[2]= {0}; // EP3 stall״̬
- uint32_t HAL_FSUSB_MSP_Init(void)
- {
- GPIO_InitTypeDef GPIO_init_para;
- System_Module_Reset(RST_USB);
- System_Module_Enable(EN_USB);
-
- if( HAL_OK != System_USB_PHY_Config())
- {
- return HAL_ERROR;
- }
-
- SCU->PABADS = (SCU->PABADS | ( (0x3 << 11)) );
- // GPIO_init_para.Pin = GPIO_PIN_11 | GPIO_PIN_12;
- // GPIO_init_para.Mode = GPIO_MODE_ANALOG;
- // GPIO_init_para.Pull = GPIO_NOPULL;
- // GPIO_init_para.Alternate = GPIO_FUNCTION_0;
- // HAL_GPIO_Init(GPIOA, &GPIO_init_para);
-
- NVIC_ClearPendingIRQ(USB_IRQn);
- NVIC_EnableIRQ(USB_IRQn);
-
- return HAL_OK;
- }
- uint32_t HAL_FSUSB_Init(void)
- {
- if (HAL_OK != HAL_FSUSB_MSP_Init())
- {
- return HAL_ERROR;
- }
-
- System_Delay(10);
-
- USBCTRL->WORKING_MODE = 0x04; //disconnect usb/ reset USBC
- System_Delay(3000);
- USBCTRL->WORKING_MODE = 0x09 ; //auto reset, fullspeed
-
- USBCTRL->EPxCSR[0] |= 1<<8; //enable EP0
- USBCTRL->EPxCSR[1] |= 1<<8; //enable EP1
- USBCTRL->EPxCSR[2] |= 1<<8; //enable EP2
- USBCTRL->EPxCSR[3] |= 1<<8; //enable EP3
- USBCTRL->EPxCSR[4] |= 1<<8; //enable EP4
- USBCTRL->EPADDR_CFG = 0x4321;
-
- USBINT->INT_EN = 0x92427; // enable Reset,Resume,Suspend,setup, EP1/2/3/4 OUT interrupt
-
- USBCTRL->WORKING_MODE |= (1<<6)|(1<<4); //connect
-
- return HAL_OK;
- }
- uint16_t HAL_FSUSB_Get_FIFO_Length(uint8_t ep_index)
- {
- return USBCTRL->EPxCSR[ep_index]&0xff;
- }
- void HAL_USB_Clear_FIFO(uint8_t ep_index, uint8_t ep_dir)
- {
- USBCTRL->EPxCSR[ep_index] |= 1<<9;
- }
- uint16_t HAL_USB_Get_Stall_Status(uint8_t ep_index, uint8_t ep_dir)
- {
- switch(ep_index)
- {
- case USB_EP1:
- {
- if(ep_dir == EP_DIR_IN) return ep1_stall[0]; //in
- else return ep1_stall[1]; //out
- }
- case USB_EP2:
- {
- if(ep_dir == EP_DIR_IN) return ep2_stall[0]; //in
- else return ep2_stall[1]; //out
- }
- case USB_EP3:
- {
- if(ep_dir == EP_DIR_IN) return ep3_stall[0]; //in
- else return ep3_stall[1]; //out
- }
- case USB_EP4:
- {
- if(ep_dir == EP_DIR_IN) return ep4_stall[0]; //in
- else return ep4_stall[1]; //out
- }
- default: return 0xff;
- }
- }
- void usb_clear_stall(uint8_t ep_index, uint8_t ep_dir)
- {
- switch(ep_index)
- {
- case USB_EP1:
- {
- if(ep_dir == EP_DIR_IN) ep1_stall[0]=0x0000; //in
- else ep1_stall[1]=0x0000; //out
- break;
- }
- case USB_EP2:
- {
- if(ep_dir == EP_DIR_IN) ep2_stall[0]=0x0000; //in
- else ep2_stall[1]=0x0000; //out
- break;
- }
- case USB_EP3:
- {
- if(ep_dir == EP_DIR_IN) ep3_stall[0]=0x0000; //in
- else ep3_stall[1]=0x0000; //out
- break;
- }
- case USB_EP4:
- {
- if(ep_dir == EP_DIR_IN) ep4_stall[0]=0x0000; //in
- else ep4_stall[1]=0x0000; //out
- break;
- }
- default: return;
- }
- USBCTRL->EPxCSR[ep_index] = 0x02100; //clear in/out toggle,stall,stall status
- USBCTRL->EPxCSR[ep_index] |= (1<<18)|(1<<15); //enable change
- // flag_clear_stall=0;
- }
- void usb_send_stall(uint8_t ep_index, uint8_t ep_dir)
- {
- switch(ep_index)
- {
- case USB_EP1:
- {
- if(ep_dir == EP_DIR_IN) ep1_stall[0]=0x0001; //in
- else ep1_stall[1]=0x0001; //out
- break;
- }
- case USB_EP2:
- {
- if(ep_dir == EP_DIR_IN) ep2_stall[0]=0x0001; //in
- else ep2_stall[1]=0x0001; //out
- break;
- }
- case USB_EP3:
- {
- if(ep_dir == EP_DIR_IN) ep3_stall[0]=0x0001; //in
- else ep3_stall[1]=0x0001; //out
- break;
- }
- case USB_EP4:
- {
- if(ep_dir == EP_DIR_IN) ep4_stall[0]=0x0001; //in
- else ep4_stall[1]=0x0001; //out
- break;
- }
- default: return;
- }
- USBCTRL->EPxCSR[ep_index] |= (1<<12);
- }
- void HAL_FSUSB_Read_EP_MEM8(uint8_t *dst, uint32_t length, uint32_t fifo_offset, uint8_t ep_index)
- {
- uint8_t *src;
- src = (uint8_t *)(USB_BASE+0x200+(ep_index<<6)+fifo_offset);
- while(length--)
- {
- *dst++ = *src++;
- }
- }
-
- void HAL_FSUSB_Write_EP_MEM8(uint8_t *src, uint32_t length, uint32_t fifo_offset, uint8_t ep_index)
- {
- uint8_t *dst;
- dst = (uint8_t *)(USB_BASE+0x200+(ep_index<<6)+fifo_offset);
- while(length--)
- {
- *dst++ = *src++;
- }
- }
- uint8_t HAL_FSUSB_Start_EP_Transfer(uint32_t length,uint8_t ep_index)
- {
- uint8_t intoken_cnt;
-
- USBCTRL->EPxSENDBN[ep_index]= length;
-
- while(1)
- {
- // if a new out data packet received, return error to caller
- if( (USBINT->INT_STAT_RAW & MASK_EPX_OUT(ep_index)) && (USBINT->INT_STAT_RAW & MASK_EPX_ACK(ep_index)) )
- {
- USBINT->INT_CLR = MASK_EPX_OUT(ep_index);
- USBINT->INT_CLR = MASK_EPX_ACK(ep_index);
- return ERROR_OUT_OUT;
- }
- // wait for IN token to start transfer
- if(USBINT->INT_STAT_RAW & MASK_EPX_IN(ep_index) )
- {
- USBINT->INT_CLR = MASK_EPX_IN(ep_index);
- USBCTRL->WORKING_MODE |= (1<<11);//return NAK when timeout
- USBCTRL->EPxCSR[ep_index] |= (1<<10);//data is ready for tx
- break;
- }
- }
-
- while(1)
- {
- if( USBCTRL->EPxCSR[ep_index]&0x1000000 ) //received ACK from host
- {
- USBINT->INT_CLR = MASK_EPX_ACK(ep_index);
- USBINT->INT_CLR = MASK_EPX_IN(ep_index);
- return 0;//pass
- }
-
- if(USBINT->INT_STAT_RAW & (1<<21) ) // timeout occurs when wait ACK
- {
- USBINT->INT_CLR = (1<<21);
- intoken_cnt = 4;
- while(intoken_cnt) // wait 3 SOF frame for bad signal, during this time, device will send NACK when IN token received
- {
- if(USBINT->INT_STAT_RAW & (1<<3))
- {
- intoken_cnt --;
- USBINT->INT_CLR = (1<<3);
- }
- }
- USBINT->INT_CLR = MASK_EPX_TIMEOUT(ep_index); // device recover to send data packet after IN token received
- }
-
- if(USBINT->INT_STAT_RAW & MASK_EPX_OUT(ep_index))
- {
- return ERROR_IN_OUT;
- }
- }
- }
-
- uint8_t HAL_FSUSB_Send_Data(uint8_t *buffer,uint32_t length,uint8_t ep_index)
- {
- uint8_t ret;
-
- while(length>=EPX_MAX_PACKET_SIZE)
- {
- HAL_FSUSB_Write_EP_MEM8(buffer,EPX_MAX_PACKET_SIZE,0, ep_index);
- ret = HAL_FSUSB_Start_EP_Transfer(EPX_MAX_PACKET_SIZE, ep_index);
- if(ret == ERROR_OUT_OUT)
- {
- if( USBCTRL->EPxCSR[ep_index] & ( 1<< 19) )//Toggle error
- {
- USBCTRL->EPxCSR[ep_index] ^= (1<<17); //out toggle want
- USBCTRL->EPxCSR[ep_index] |= (1<<18); //update want toggle;
- }
- USBCTRL->EPxCSR[ep_index] |= 1<<11; //set rx ready
- continue; // received a same packet, has processed this packet, just fill respoonse to fifo and send it to host
- }
- else if(ret != 0)
- {
- return 1; // send data fail, exit with error code to let caller know
- }
- length -= EPX_MAX_PACKET_SIZE;
- buffer += EPX_MAX_PACKET_SIZE;
- }
- // remaining data, less than EPX_MAX_PACKET_SIZE
- while(length>0)
- {
- HAL_FSUSB_Write_EP_MEM8(buffer,length,0,ep_index);
- ret = HAL_FSUSB_Start_EP_Transfer(length,ep_index);
- if(ret == ERROR_OUT_OUT)
- {
- if( USBCTRL->EPxCSR[ep_index] & ( 1<< 19) )//Toggle error
- {
- USBCTRL->EPxCSR[ep_index] ^= (1<<17); //out toggle want
- USBCTRL->EPxCSR[ep_index] |= (1<<18); //update want toggle;
- }
- USBCTRL->EPxCSR[ep_index] |= 1<<11; //set rx ready
- continue;
- }
- else if(ret != 0)
- {
- return 1; // send data fail, exit with error code to let caller know
- }
- length -= length;
- buffer += length;
- }
-
- return 0;
- }
- void HAL_FSUSB_Receive_Data(uint8_t *buffer,uint32_t length,uint8_t ep_index)
- {
- uint32_t len;
- while(length>0)
- {
- while(1)
- {
- // wait an out data packet and device has sent an ACK to HOST
- if( (USBINT->INT_STAT_RAW & MASK_EPX_OUT(ep_index)) && (USBINT->INT_STAT_RAW & MASK_EPX_ACK(ep_index)) )
- {
- break;
- }
- }
- USBINT->INT_CLR = MASK_EPX_OUT(ep_index);
- USBINT->INT_CLR = MASK_EPX_ACK(ep_index);
-
- if( USBCTRL->EPxCSR[ep_index] & ( 1<< 19) )//Toggle error
- {
- USBCTRL->EPxCSR[ep_index] ^= (1<<17); //out toggle want
- USBCTRL->EPxCSR[ep_index] |= (1<<18); //update want toggle;
- USBCTRL->EPxCSR[ep_index] |= 1<<11; //set rx ready, wait for a new packet
- continue; //discard this packet
- }
-
- len =HAL_FSUSB_Get_FIFO_Length(ep_index);
- HAL_FSUSB_Read_EP_MEM8(buffer,len,0,ep_index);
- USBCTRL->EPxCSR[ep_index] |= 1<<11; //set rx ready to wait next packet
- length -= len;
- buffer += len;
- }
- }
- //ep_index表示的是菜单
- void HAL_FSUSB_EP0_Send_Empty_Packet(void)
- {
- HAL_FSUSB_Start_EP_Transfer(0,USB_EP0);
- }
-
- void HAL_FSUSB_EP0_Send_Stall(void)
- {
- USBCTRL->EPxCSR[0] |= 1<<12;
- while(!(USBCTRL->EPxCSR[0] &0x2000));
- USBCTRL->EPxCSR[0] |= 0x2000;
- }
|