Skip to content
Snippets Groups Projects
Commit 27839dd7 authored by Sergi Hernandez's avatar Sergi Hernandez
Browse files

Added an USB High Speed communication device for the F4 family.

parent a406d90d
No related branches found
No related tags found
No related merge requests found
#ifndef USB_F4_H
#define USB_F4_H
#include "stm32f4xx_hal.h"
#include "comm.h"
#include "usbd_def.h"
/* public functions */
void usb_init(TComm *comm_dev,USBD_DescriptorsTypeDef *pdesc,USBD_ClassTypeDef *pclass);
void usb_disconnect(void);
void usb_connect(void);
/* IRQ functions */
unsigned char usb_send_irq(unsigned char first_byte);
unsigned char usb_enable_tx_irq(void);
unsigned char usb_receive_irq(void);
unsigned char usb_cancel_receive_irq(void);
/* DMA functions */
unsigned char usb_send_dma(unsigned char *data,unsigned short int length);
unsigned char usb_receive_dma(unsigned char *data,unsigned short int length);
unsigned char usb_cancel_receive_dma(void);
#endif
#include "usb.h"
#include "usbd_cdc.h"
#define RX_DATA_SIZE 1024
#define TX_DATA_SIZE 1024
// private variables
extern PCD_HandleTypeDef hpcd_USB_OTG_HS;
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
*/
static 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
*/
static 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
*/
static 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
*/
static 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_SetRxBuffer(&USBHandle, &Buf[0]);
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 OTG_HS_EP1_OUT_IRQHandler(void)
{
/* USER CODE BEGIN OTG_HS_EP1_OUT_IRQn 0 */
/* USER CODE END OTG_HS_EP1_OUT_IRQn 0 */
HAL_PCD_IRQHandler(&hpcd_USB_OTG_HS);
/* USER CODE BEGIN OTG_HS_EP1_OUT_IRQn 1 */
/* USER CODE END OTG_HS_EP1_OUT_IRQn 1 */
}
void OTG_HS_EP1_IN_IRQHandler(void)
{
/* USER CODE BEGIN OTG_HS_EP1_IN_IRQn 0 */
/* USER CODE END OTG_HS_EP1_IN_IRQn 0 */
HAL_PCD_IRQHandler(&hpcd_USB_OTG_HS);
/* USER CODE BEGIN OTG_HS_EP1_IN_IRQn 1 */
/* USER CODE END OTG_HS_EP1_IN_IRQn 1 */
}
void OTG_HS_IRQHandler(void)
{
/* USER CODE BEGIN OTG_HS_IRQn 0 */
/* USER CODE END OTG_HS_IRQn 0 */
HAL_PCD_IRQHandler(&hpcd_USB_OTG_HS);
/* USER CODE BEGIN OTG_HS_IRQn 1 */
/* USER CODE END OTG_HS_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_HS);
USBD_RegisterClass(&USBHandle,pclass);
USBD_CDC_RegisterInterface(&USBHandle,&usb_cdc_ops);
USBD_Start(&USBHandle);
}
void usb_disconnect(void)
{
HAL_PCD_DevDisconnect(&hpcd_USB_OTG_HS);
}
void usb_connect(void)
{
HAL_PCD_DevConnect(&hpcd_USB_OTG_HS);
}
/* 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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment