-
Sergi Hernandez authoredSergi Hernandez authored
usb.c 7.43 KiB
#include "stm32_usb.h"
#include "usbd_cdc.h"
#define RX_DATA_SIZE 64
#define TX_DATA_SIZE 64
// private variables
extern PCD_HandleTypeDef PCDHandle;
USBD_HandleTypeDef USBHandle;
TComm *usb_comm_dev;
uint8_t usb_rx_buffer[RX_DATA_SIZE];
uint8_t usb_tx_buffer[TX_DATA_SIZE];
unsigned char usb_dma_phase;
unsigned char *usb_dma_phase_data;
unsigned short int usb_dma_phase_length;
unsigned short int usb_dma_phase_write_ptr;
// private functions
/**
* @brief CDC_Init_FS
* Initializes the CDC media low layer over the FS USB IP
* @param None
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t usb_cdc_init(void)
{
/* USER CODE BEGIN 3 */
/* Set Application Buffers */
USBD_CDC_SetTxBuffer(&USBHandle, usb_tx_buffer, 0);
USBD_CDC_SetRxBuffer(&USBHandle, usb_rx_buffer);
/* initialize internal variables */
usb_dma_phase=0x00;
usb_dma_phase_data=0x00;
usb_dma_phase_length=0;
usb_dma_phase_write_ptr=0;
return (USBD_OK);
/* USER CODE END 3 */
}
/**
* @brief CDC_DeInit_FS
* DeInitializes the CDC media low layer
* @param None
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t usb_cdc_deinit(void)
{
/* USER CODE BEGIN 4 */
return (USBD_OK);
/* USER CODE END 4 */
}
/**
* @brief CDC_Control_FS
* Manage the CDC class requests
* @param cmd: Command code
* @param pbuf: Buffer containing command data (request parameters)
* @param length: Number of data to be sent (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t usb_cdc_control(uint8_t cmd, uint8_t* pbuf, uint16_t length)
{
/* USER CODE BEGIN 5 */
switch (cmd)
{
case CDC_SEND_ENCAPSULATED_COMMAND:
break;
case CDC_GET_ENCAPSULATED_RESPONSE:
break;
case CDC_SET_COMM_FEATURE:
break;
case CDC_GET_COMM_FEATURE:
break;
case CDC_CLEAR_COMM_FEATURE:
break;
/*******************************************************************************/
/* Line Coding Structure */
/*-----------------------------------------------------------------------------*/
/* Offset | Field | Size | Value | Description */
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
/* 4 | bCharFormat | 1 | Number | Stop bits */
/* 0 - 1 Stop bit */
/* 1 - 1.5 Stop bits */
/* 2 - 2 Stop bits */
/* 5 | bParityType | 1 | Number | Parity */
/* 0 - None */
/* 1 - Odd */
/* 2 - Even */
/* 3 - Mark */
/* 4 - Space */
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
/*******************************************************************************/
case CDC_SET_LINE_CODING:
break;
case CDC_GET_LINE_CODING:
pbuf[0]=(uint8_t)115200;
pbuf[1]=(uint8_t)(115200>>8);
pbuf[2]=(uint8_t)(115200>>16);
pbuf[3]=(uint8_t)(115200>>24);
pbuf[4]=0;
pbuf[5]=0;
pbuf[6]=8;
break;
case CDC_SET_CONTROL_LINE_STATE:
break;
case CDC_SEND_BREAK:
break;
default:
break;
}
return (USBD_OK);
/* USER CODE END 5 */
}
/**
* @brief CDC_Receive_FS
* Data received over USB OUT endpoint are sent over CDC interface
* through this function.
*
* @note
* This function will block any OUT packet reception on USB endpoint
* untill exiting this function. If you exit this function before transfer
* is complete on CDC interface (ie. using DMA controller) it will result
* in receiving more data while previous ones are still not sent.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t usb_cdc_receive(uint8_t* Buf, uint32_t *Len)
{
int i=0;
/* USER CODE BEGIN 6 */
for(i=0;i<(*Len);i++)
{
if(!usb_dma_phase)
comm_do_irq_receive(usb_comm_dev,Buf[i]);
else /* do DMA phase */
{
usb_dma_phase_data[usb_dma_phase_write_ptr]=Buf[i];
usb_dma_phase_length--;
usb_dma_phase_write_ptr++;
if(usb_dma_phase_length==0)
comm_do_dma_receive(usb_comm_dev);
}
}
USBD_CDC_ReceivePacket(&USBHandle);
return (USBD_OK);
/* USER CODE END 6 */
}
USBD_CDC_ItfTypeDef usb_cdc_ops =
{
usb_cdc_init,
usb_cdc_deinit,
usb_cdc_control,
usb_cdc_receive
};
// interrupt handlers
void USB_LP_CAN_RX0_IRQHandler(void)
{
/* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */
/* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */
HAL_PCD_IRQHandler(&PCDHandle);
/* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */
/* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */
}
/* public functions*/
void usb_init(TComm *comm_dev,USBD_DescriptorsTypeDef *pdesc,USBD_ClassTypeDef *pclass)
{
/* Initialize the comm structure */
comm_dev->send_irq=usb_send_irq;
comm_dev->enable_tx_irq=usb_enable_tx_irq;
comm_dev->receive_irq=usb_receive_irq;
comm_dev->cancel_receive_irq=usb_cancel_receive_irq;
if(comm_dev->use_dma)
{
comm_dev->send_dma=usb_send_dma;
comm_dev->receive_dma=usb_receive_dma;
comm_dev->cancel_receive_dma=usb_cancel_receive_dma;
}
comm_dev->irq_send_cb=0x00000000;
comm_dev->irq_receive_cb=0x00000000;
comm_dev->dma_send_cb=0x00000000;
comm_dev->dma_receive_cb=0x00000000;
/* initialize internal variables */
usb_comm_dev=comm_dev;
/* initialize and start the USB device */
USBD_Init(&USBHandle, pdesc, DEVICE_FS);
USBD_RegisterClass(&USBHandle, pclass);
USBD_CDC_RegisterInterface(&USBHandle, &usb_cdc_ops);
USBD_Start(&USBHandle);
}
void usb_disconnect(void)
{
HAL_PCD_DevDisconnect(&PCDHandle);
}
void usb_connect(void)
{
HAL_PCD_DevConnect(&PCDHandle);
}
/* IRQ functions */
unsigned char usb_send_irq(unsigned char first_byte)
{
return 0x00;
}
unsigned char usb_enable_tx_irq(void)
{
return 0x00;
}
unsigned char usb_receive_irq(void)
{
usb_dma_phase=0x00;
return 0x00;
}
unsigned char usb_cancel_receive_irq(void)
{
return 0x00;
}
/* DMA functions */
unsigned char usb_send_dma(unsigned char *data,unsigned short int length)
{
uint8_t byte;
/* USER CODE BEGIN 7 */
USBD_CDC_SetTxBuffer(&USBHandle,data,length);
USBD_CDC_TransmitPacket(&USBHandle);
/* force the tx completion */
comm_do_dma_send(usb_comm_dev);
comm_do_irq_send(usb_comm_dev,&byte);
/* USER CODE END 7 */
return 0x00;
}
unsigned char usb_receive_dma(unsigned char *data,unsigned short int length)
{
usb_dma_phase=0x01;
usb_dma_phase_data=data;
usb_dma_phase_length=length;
usb_dma_phase_write_ptr=0;
return 0x00;
}
unsigned char usb_cancel_receive_dma(void)
{
usb_dma_phase=0x00;
usb_dma_phase_data=0x00;
usb_dma_phase_length=0;
usb_dma_phase_write_ptr=0;
return 0x00;
}