/** * @brief Device Initialization * @param pdev: device instance * @retval : None */ void DCD_Init(USB_CORE_HANDLE *pdev) { /*Device is in Default State*/ pdev->dev.device_status = USB_DEFAULT; pdev->dev.device_address = 0; pdev->dev.speed = USB_SPEED_FULL; /*kept for API compatibility reason*/ /*CNTR_FRES = 1*/ SetCNTR(CNTR_FRES); /*CNTR_FRES = 0*/ SetCNTR(0); /*Clear pending interrupts*/ SetISTR(0); /*Set Btable Adress*/ SetBTABLE(BTABLE_ADDRESS); /*set wInterrupt_Mask global variable*/ wInterrupt_Mask = CNTR_CTRM | CNTR_WKUPM | CNTR_SUSPM | CNTR_ERRM | CNTR_SOFM \ | CNTR_ESOFM | CNTR_RESETM; /*Set interrupt mask*/ SetCNTR(wInterrupt_Mask); }
vsf_err_t stm32_usbd_fini(void) { // reset SetCNTR(CNTR_FRES); SetISTR(0); SetCNTR(CNTR_FRES + CNTR_PDWN); return VSFERR_NONE; }
vsf_err_t stm32_usbd_init(void) { struct stm32_info_t *stm32_info; memset(stm32_usbd_IN_epsize, 0, sizeof(stm32_usbd_IN_epsize)); memset(stm32_usbd_OUT_epsize, 0, sizeof(stm32_usbd_OUT_epsize)); memset(stm32_usbd_IN_dbuffer, 0, sizeof(stm32_usbd_IN_dbuffer)); memset(stm32_usbd_OUT_dbuffer, 0, sizeof(stm32_usbd_OUT_dbuffer)); memset(stm32_usbd_epaddr, -1, sizeof(stm32_usbd_epaddr)); if (stm32_interface_get_info(&stm32_info)) { return VSFERR_FAIL; } switch (stm32_info->sys_freq_hz) { case 72 * 1000 * 1000: RCC->CFGR &= ~STM32_RCC_CFGR_USBPRE; break; case 48 * 1000 * 1000: RCC->CFGR |= STM32_RCC_CFGR_USBPRE; break; default: return VSFERR_INVALID_PARAMETER; } RCC->APB1ENR |= STM32_RCC_APB1ENR_USBEN; // reset SetCNTR(CNTR_FRES); SetCNTR(0); // It seems that there MUST be at least 8 clock cycles // between clear FRES and clear ISTR, or RESET flash can't be cleared __asm("nop"); __asm("nop"); __asm("nop"); __asm("nop"); __asm("nop"); __asm("nop"); __asm("nop"); SetISTR(0); SetCNTR(CNTR_CTRM | CNTR_WKUPM | CNTR_SUSPM | CNTR_ERRM | CNTR_RESETM); SetBTABLE(0); return VSFERR_NONE; }
u16 __ARM_UsbSendData(u8* cpSourceBuffer, u16 wSendLength) { u16 wUsbIntMaskReserved; u16 wActuralSendSize; u32 dwTimeoutCounter; u16 wReturnLength; wReturnLength = wSendLength; while(1) { wUsbIntMaskReserved = GetCNTR(); SetCNTR((~USB_CNTR_SOFM)& wUsbIntMaskReserved); //mask usb SOF interrupt wActuralSendSize = UsbWrite(cpSourceBuffer, wSendLength); SetCNTR(wUsbIntMaskReserved); //restore usb SOF interrupt if(wActuralSendSize < wSendLength) //have some data left due to usb tx buffer full { wSendLength -= wActuralSendSize; //adjust send size = unsend data dwTimeoutCounter = 0x0110F0000; //wait a while, usb tx buffer will release some space while(dwTimeoutCounter > 0) //loop till tx buff is not full { if(GetUsbTxBufferAvailableLength() != 0) { break; } dwTimeoutCounter--; } if(dwTimeoutCounter == 0) //timeout means usb tx jammed, go to function end { break; } } else { break; } } return wReturnLength; //AVR original code always return the expected send length, maybe have issue if usb tx timeout }
/*Transfer Com2 received data to USB tx for loop or debug test*/ void UartCom2RxProcess(void) { u16 wCom2RxDataLength; //u16 wUsbTxAvailableBufferLength; u16 wTransferLength; u16 wUsbIntMaskReserved; u16 wActualTransferLength; /*get usb free send buffer length */ //wUsbTxAvailableBufferLength = GetUsbTxBufferAvailableLength(); /* get com2 port data length in receive buffer */ wCom2RxDataLength = GetComRxBufferDataLength(COM2); if((USART_RX_DATA_SIZE - wCom2RxBufferStart) < wCom2RxDataLength) //if rx buffer overturn, only access data till buffer end { wTransferLength = USART_RX_DATA_SIZE - wCom2RxBufferStart; cFlagCom2DataReceived = TRUE; //flag for rest data process in main loop } else { wTransferLength = wCom2RxDataLength; } wUsbIntMaskReserved = GetCNTR(); SetCNTR((~USB_CNTR_SOFM)& wUsbIntMaskReserved); //mask usb SOF interrupt to prevent SOF break data copy wActualTransferLength = UsbWrite(((u8*) (cCom2RxBuffer + wCom2RxBufferStart)), wTransferLength); SetCNTR(wUsbIntMaskReserved); //restore usb SOF interrupt wCom2RxBufferStart += wActualTransferLength; if(wCom2RxBufferStart == USART_RX_DATA_SIZE) { wCom2RxBufferStart = 0; } }