initial USB CDC+HID vendor code merge
merged in example USB CDC + HID code, but removed any comms with actual USART peripheral. this code is not yet tested. once tested and USB enumerates, work can proceed.
This commit is contained in:
347
gat_stand_fw/user/usb/cdc.c
Normal file
347
gat_stand_fw/user/usb/cdc.c
Normal file
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
* cdc.c
|
||||
*
|
||||
* Created on: Nov 6, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
#include "cdc.h"
|
||||
|
||||
#include "usb_lib.h"
|
||||
|
||||
#include "../../usblib/config/usb_desc.h"
|
||||
#include "../../usblib/config/usb_prop.h"
|
||||
|
||||
|
||||
|
||||
#define USB_TIM TIM4
|
||||
#define USB_TIM_IRQn TIM4_IRQn
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Variable Definition */
|
||||
/* Global */
|
||||
|
||||
/* The following are serial port transmit and receive related variables and buffers */
|
||||
volatile CDC_CTL Cdc;
|
||||
|
||||
__attribute__ ((aligned(4))) uint8_t CDC_Tx_Buf[DEF_CDC_TX_BUF_LEN]; /* Serial port 2 transmit data buffer */
|
||||
__attribute__ ((aligned(4))) uint8_t CDC_Rx_Buf[DEF_CDC_RX_BUF_LEN]; /* Serial port 2 receive data buffer */
|
||||
|
||||
extern uint8_t USBD_Endp3_Busy;
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USB_TIM_Init
|
||||
*
|
||||
* @brief 100us Timer
|
||||
* 144 * 100 * 13.8888 -----> 100uS
|
||||
* todo: document why we need this counter.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USB_TIM_Init( void )
|
||||
{
|
||||
TIM_TimeBaseInitTypeDef tim = {0};
|
||||
|
||||
TIM_DeInit(USB_TIM);
|
||||
|
||||
/* Time base configuration */
|
||||
tim.TIM_Period = 100 - 1;
|
||||
tim.TIM_Prescaler = SystemCoreClock / 1000000 - 1;
|
||||
tim.TIM_ClockDivision = 0;
|
||||
tim.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
TIM_TimeBaseInit(USB_TIM, &tim);
|
||||
|
||||
/* Clear USB_TIM update pending flag */
|
||||
TIM_ClearFlag(USB_TIM, TIM_FLAG_Update);
|
||||
|
||||
/* TIM IT enable */
|
||||
TIM_ITConfig(USB_TIM, TIM_IT_Update, ENABLE);
|
||||
|
||||
/* Enable Interrupt */
|
||||
NVIC_EnableIRQ(USB_TIM_IRQn);
|
||||
|
||||
/* USB_TIM enable counter */
|
||||
TIM_Cmd(USB_TIM, ENABLE);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UART2_ParaInit
|
||||
*
|
||||
* @brief Cdc2 parameters initialization
|
||||
* mode = 0 : Used in usb modify initialization
|
||||
* mode = 1 : Used in default initializations
|
||||
* @return none
|
||||
*/
|
||||
void CDC_ParaInit(uint8_t mode)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
Cdc.Rx_LoadPtr = 0x00;
|
||||
Cdc.Rx_DealPtr = 0x00;
|
||||
Cdc.Rx_RemainLen = 0x00;
|
||||
Cdc.Rx_TimeOut = 0x00;
|
||||
Cdc.Rx_TimeOutMax = 30;
|
||||
|
||||
Cdc.Tx_LoadNum = 0x00;
|
||||
Cdc.Tx_DealNum = 0x00;
|
||||
Cdc.Tx_RemainNum = 0x00;
|
||||
|
||||
for(i = 0; i < DEF_CDC_TX_BUF_NUM_MAX; i++) {
|
||||
Cdc.Tx_PackLen[ i ] = 0x00;
|
||||
}
|
||||
|
||||
Cdc.Tx_Flag = 0x00;
|
||||
Cdc.Tx_CurPackLen = 0x00;
|
||||
Cdc.Tx_CurPackPtr = 0x00;
|
||||
|
||||
Cdc.USB_Up_IngFlag = 0x00;
|
||||
Cdc.USB_Up_TimeOut = 0x00;
|
||||
Cdc.USB_Up_Pack0_Flag = 0x00;
|
||||
Cdc.USB_Down_StopFlag = 0x00;
|
||||
|
||||
if(mode) {
|
||||
Cdc.Com_Cfg[ 0 ] = (uint8_t)( DEF_CDC_BAUDRATE );
|
||||
Cdc.Com_Cfg[ 1 ] = (uint8_t)( DEF_CDC_BAUDRATE >> 8 );
|
||||
Cdc.Com_Cfg[ 2 ] = (uint8_t)( DEF_CDC_BAUDRATE >> 16 );
|
||||
Cdc.Com_Cfg[ 3 ] = (uint8_t)( DEF_CDC_BAUDRATE >> 24 );
|
||||
Cdc.Com_Cfg[ 4 ] = DEF_CDC_STOPBIT;
|
||||
Cdc.Com_Cfg[ 5 ] = DEF_CDC_PARITY;
|
||||
Cdc.Com_Cfg[ 6 ] = DEF_CDC_DATABIT;
|
||||
Cdc.Com_Cfg[ 7 ] = DEF_CDC_RX_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn CDC_USB_Init
|
||||
*
|
||||
* @brief CDC initialization in usb interrupt
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void CDC_USB_Init(void)
|
||||
{
|
||||
uint32_t baudrate;
|
||||
uint8_t stopbits __attribute__((unused));
|
||||
uint8_t parity __attribute__((unused));
|
||||
|
||||
baudrate = ( uint32_t )( Cdc.Com_Cfg[ 3 ] << 24 ) + ( uint32_t )( Cdc.Com_Cfg[ 2 ] << 16 );
|
||||
baudrate += ( uint32_t )( Cdc.Com_Cfg[ 1 ] << 8 ) + ( uint32_t )( Cdc.Com_Cfg[ 0 ] );
|
||||
stopbits = Cdc.Com_Cfg[ 4 ];
|
||||
parity = Cdc.Com_Cfg[ 5 ];
|
||||
|
||||
// this is the point where you would apply these settings.
|
||||
// since we are virtual only with no real UART, there is nothing to do here.
|
||||
// UART2_Init( 0, baudrate, stopbits, parity );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UART2_DataTx_Process
|
||||
*
|
||||
* @brief Cdc2 data transmission processing
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void CDC_DataTx_Process( void )
|
||||
{
|
||||
// uint16_t count;
|
||||
|
||||
/* uart1 transmission processing */
|
||||
if( Cdc.Tx_Flag ) {
|
||||
// process incoming data from the host.
|
||||
|
||||
/*
|
||||
// Query whether the DMA transmission of the serial port is completed
|
||||
if( USART2->STATR & USART_FLAG_TC )
|
||||
{
|
||||
USART2->STATR = (uint16_t)( ~USART_FLAG_TC );
|
||||
USART2->CTLR3 &= ( ~USART_DMAReq_Tx );
|
||||
|
||||
Cdc.Tx_Flag = 0x00;
|
||||
|
||||
NVIC_DisableIRQ( USB_LP_CAN1_RX0_IRQn );
|
||||
NVIC_DisableIRQ( USB_HP_CAN1_TX_IRQn );
|
||||
|
||||
// Calculate the variables of last data
|
||||
count = Cdc.Tx_CurPackLen - DEF_UART2_TX_DMA_CH->CNTR;
|
||||
Cdc.Tx_CurPackLen -= count;
|
||||
Cdc.Tx_CurPackPtr += count;
|
||||
if( Cdc.Tx_CurPackLen == 0x00 )
|
||||
{
|
||||
Cdc.Tx_PackLen[ Cdc.Tx_DealNum ] = 0x0000;
|
||||
Cdc.Tx_DealNum++;
|
||||
if( Cdc.Tx_DealNum >= DEF_CDC_TX_BUF_NUM_MAX )
|
||||
{
|
||||
Cdc.Tx_DealNum = 0x00;
|
||||
}
|
||||
Cdc.Tx_RemainNum--;
|
||||
}
|
||||
|
||||
// If the current serial port has suspended the downlink, restart the driver downlink
|
||||
if( ( Cdc.USB_Down_StopFlag == 0x01 ) && ( Cdc.Tx_RemainNum < 2 ) )
|
||||
{
|
||||
SetEPRxValid( ENDP2 );
|
||||
Cdc.USB_Down_StopFlag = 0x00;
|
||||
}
|
||||
*/
|
||||
|
||||
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||
NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn);
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load data from the serial port send buffer to send
|
||||
if(Cdc.Tx_RemainNum) {
|
||||
// Determine whether to load from the last unsent buffer or from a new buffer
|
||||
if( Cdc.Tx_CurPackLen == 0x00 ) {
|
||||
Cdc.Tx_CurPackLen = Cdc.Tx_PackLen[ Cdc.Tx_DealNum ];
|
||||
Cdc.Tx_CurPackPtr = ( Cdc.Tx_DealNum * DEF_USB_FS_PACK_LEN );
|
||||
}
|
||||
|
||||
// todo: figure out wtf all this does.
|
||||
/*
|
||||
// Configure DMA and send
|
||||
USART_ClearFlag( USART2, USART_FLAG_TC );
|
||||
DMA_Cmd( DEF_UART2_TX_DMA_CH, DISABLE );
|
||||
DEF_UART2_TX_DMA_CH->MADDR = (uint32_t)&UART2_Tx_Buf[ Cdc.Tx_CurPackPtr ];
|
||||
DEF_UART2_TX_DMA_CH->CNTR = Cdc.Tx_CurPackLen;
|
||||
DMA_Cmd( DEF_UART2_TX_DMA_CH, ENABLE );
|
||||
USART2->CTLR3 |= USART_DMAReq_Tx;
|
||||
Cdc.Tx_Flag = 0x01;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UART2_DataRx_Deal
|
||||
*
|
||||
* @brief Cdc2 data receiving processing
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void CDC_DataRx_Process( void )
|
||||
{
|
||||
// uint16_t temp16;
|
||||
// uint32_t remain_len;
|
||||
// uint16_t packlen;
|
||||
|
||||
/* Serial port 1 data DMA receive processing */
|
||||
NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||
NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn);
|
||||
|
||||
// process sending data over USB to the host.
|
||||
/*
|
||||
CDC_Rx_DMACurCount = DEF_UART2_RX_DMA_CH->CNTR;
|
||||
if( CDC_Rx_DMALastCount != CDC_Rx_DMACurCount )
|
||||
|
||||
{
|
||||
if( CDC_Rx_DMALastCount > CDC_Rx_DMACurCount )
|
||||
{
|
||||
temp16 = CDC_Rx_DMALastCount - CDC_Rx_DMACurCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp16 = DEF_CDC_RX_BUF_LEN - CDC_Rx_DMACurCount;
|
||||
temp16 += CDC_Rx_DMALastCount;
|
||||
}
|
||||
CDC_Rx_DMALastCount = CDC_Rx_DMACurCount;
|
||||
if( ( Cdc.Rx_RemainLen + temp16 ) > DEF_CDC_RX_BUF_LEN )
|
||||
{
|
||||
// Overflow handling
|
||||
// Save frame error status
|
||||
printf("U0_O:%08lx\n",(uint32_t)Cdc.Rx_RemainLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cdc.Rx_RemainLen += temp16;
|
||||
}
|
||||
|
||||
// Setting reception status
|
||||
Cdc.Rx_TimeOut = 0x00;
|
||||
}
|
||||
*/
|
||||
|
||||
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||
NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn);
|
||||
|
||||
/*****************************************************************/
|
||||
/* Serial port 1 data processing via USB upload and reception */
|
||||
if( Cdc.Rx_RemainLen ) {
|
||||
if( Cdc.USB_Up_IngFlag == 0 ) {
|
||||
// todo: figure out wtf this does.
|
||||
/*
|
||||
// Calculate the length of this upload
|
||||
remain_len = Cdc.Rx_RemainLen;
|
||||
packlen = 0x00;
|
||||
if( remain_len >= DEF_USBD_MAX_PACK_SIZE ) {
|
||||
packlen = DEF_USBD_MAX_PACK_SIZE;
|
||||
}
|
||||
else {
|
||||
if( Cdc.Rx_TimeOut >= Cdc.Rx_TimeOutMax ) {
|
||||
packlen = remain_len;
|
||||
}
|
||||
}
|
||||
|
||||
if( packlen > ( DEF_CDC_RX_BUF_LEN - Cdc.Rx_DealPtr ) ) {
|
||||
packlen = ( DEF_CDC_RX_BUF_LEN - Cdc.Rx_DealPtr );
|
||||
}
|
||||
|
||||
// Upload serial data via usb
|
||||
if( packlen ) {
|
||||
NVIC_DisableIRQ( USB_LP_CAN1_RX0_IRQn );
|
||||
NVIC_DisableIRQ( USB_HP_CAN1_TX_IRQn );
|
||||
Cdc.USB_Up_IngFlag = 0x01;
|
||||
Cdc.USB_Up_TimeOut = 0x00;
|
||||
USBD_ENDPx_DataUp( ENDP3, &UART2_Rx_Buf[ Cdc.Rx_DealPtr], packlen);
|
||||
// Calculate the variables of interest
|
||||
Cdc.Rx_RemainLen -= packlen;
|
||||
Cdc.Rx_DealPtr += packlen;
|
||||
if( Cdc.Rx_DealPtr >= DEF_CDC_RX_BUF_LEN )
|
||||
{
|
||||
Cdc.Rx_DealPtr = 0x00;
|
||||
}
|
||||
|
||||
// Start 0-length packet timeout timer
|
||||
if( packlen == DEF_CDC_RX_BUF_LEN )
|
||||
{
|
||||
Cdc.USB_Up_Pack0_Flag = 0x01;
|
||||
}
|
||||
|
||||
NVIC_EnableIRQ( USB_LP_CAN1_RX0_IRQn );
|
||||
NVIC_EnableIRQ( USB_HP_CAN1_TX_IRQn );
|
||||
}
|
||||
*/
|
||||
}
|
||||
else {
|
||||
/* Set the upload success flag directly if the upload is not successful after the timeout */
|
||||
if(Cdc.USB_Up_TimeOut >= DEF_CDC_USB_UP_TIMEOUT) {
|
||||
Cdc.USB_Up_IngFlag = 0x00;
|
||||
USBD_Endp3_Busy = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
/* Determine if a 0-length packet needs to be uploaded (required for CDC mode) */
|
||||
if( Cdc.USB_Up_Pack0_Flag ) {
|
||||
if( Cdc.USB_Up_IngFlag == 0 ) {
|
||||
if( Cdc.USB_Up_TimeOut >= ( DEF_CDC_RX_TIMEOUT * 20 ) ) {
|
||||
NVIC_DisableIRQ( USB_LP_CAN1_RX0_IRQn );
|
||||
NVIC_DisableIRQ( USB_HP_CAN1_TX_IRQn );
|
||||
Cdc.USB_Up_IngFlag = 0x01;
|
||||
Cdc.USB_Up_TimeOut = 0x00;
|
||||
|
||||
USBD_ENDPx_DataUp( ENDP3, &CDC_Rx_Buf[ Cdc.Rx_DealPtr], 0);
|
||||
|
||||
Cdc.USB_Up_IngFlag = 0;
|
||||
Cdc.USB_Up_Pack0_Flag = 0x00;
|
||||
NVIC_EnableIRQ( USB_LP_CAN1_RX0_IRQn );
|
||||
NVIC_EnableIRQ( USB_HP_CAN1_TX_IRQn );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
91
gat_stand_fw/user/usb/cdc.h
Normal file
91
gat_stand_fw/user/usb/cdc.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* cdc.h
|
||||
*
|
||||
* Created on: Nov 6, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
#ifndef USER_USB_CDC_H_
|
||||
#define USER_USB_CDC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Related macro definitions */
|
||||
/* Serial buffer related definitions */
|
||||
#define DEF_CDC_RX_BUF_LEN ( 4 * 512 ) /* Serial x receive buffer size */
|
||||
#define DEF_CDC_TX_BUF_LEN ( 2 * 512 ) /* Serial x transmit buffer size */
|
||||
#define DEF_USB_FS_PACK_LEN 64 /* USB full speed mode packet size for serial x data */
|
||||
#define DEF_CDC_TX_BUF_NUM_MAX (DEF_CDC_TX_BUF_LEN / DEF_USB_FS_PACK_LEN) /* Serial x transmit buffer size */
|
||||
|
||||
/* Serial port receive timeout related macro definition */
|
||||
#define DEF_CDC_BAUDRATE 115200 /* Default baud rate for serial port */
|
||||
#define DEF_CDC_STOPBIT 0 /* Default stop bit for serial port */
|
||||
#define DEF_CDC_PARITY 0 /* Default parity bit for serial port */
|
||||
#define DEF_CDC_DATABIT 8 /* Default data bit for serial port */
|
||||
#define DEF_CDC_RX_TIMEOUT 30 /* Serial port receive timeout, in 100uS */
|
||||
#define DEF_CDC_USB_UP_TIMEOUT 60000 /* Serial port receive upload timeout, in 100uS */
|
||||
|
||||
|
||||
/************************************************************/
|
||||
/* Serial port X related structure definition */
|
||||
typedef struct __attribute__((packed)) _UART_CTL
|
||||
{
|
||||
uint16_t Rx_LoadPtr; /* Serial x data receive buffer load pointer */
|
||||
uint16_t Rx_DealPtr; /* Pointer to serial x data receive buffer processing */
|
||||
volatile uint16_t Rx_RemainLen; /* Remaining unprocessed length of the serial x data receive buffer */
|
||||
uint8_t Rx_TimeOut; /* Serial x data receive timeout */
|
||||
uint8_t Rx_TimeOutMax; /* Serial x data receive timeout maximum */
|
||||
|
||||
volatile uint16_t Tx_LoadNum; /* Serial x data send buffer load number */
|
||||
volatile uint16_t Tx_DealNum; /* Serial x data send buffer processing number */
|
||||
volatile uint16_t Tx_RemainNum; /* Serial x data send buffer remaining unprocessed number */
|
||||
volatile uint16_t Tx_PackLen[DEF_CDC_TX_BUF_NUM_MAX]; /* The current packet length of the serial x data send buffer */
|
||||
uint8_t Tx_Flag; /* Serial x data send status */
|
||||
uint8_t Recv1;
|
||||
uint16_t Tx_CurPackLen; /* The current packet length sent by serial port x */
|
||||
uint16_t Tx_CurPackPtr; /* Pointer to the packet currently being sent by serial port x */
|
||||
|
||||
uint8_t USB_Up_IngFlag; /* Serial xUSB packet being uploaded flag */
|
||||
uint8_t Recv2;
|
||||
uint16_t USB_Up_TimeOut; /* Serial xUSB packet upload timeout timer */
|
||||
uint8_t USB_Up_Pack0_Flag; /* Serial xUSB data needs to upload 0-length packet flag */
|
||||
uint8_t USB_Down_StopFlag; /* Serial xUSB packet stop down flag */
|
||||
|
||||
uint8_t Com_Cfg[ 8 ]; /* Serial x parameter configuration (default baud rate is 115200, 1 stop bit, no parity, 8 data bits) */
|
||||
uint8_t Recv3;
|
||||
uint8_t USB_Int_UpFlag; /* Serial x interrupt upload status */
|
||||
uint16_t USB_Int_UpTimeCount; /* Serial x interrupt upload timing */
|
||||
} CDC_CTL, *PCDC_CTL;
|
||||
|
||||
/***********************************************************************************************************************/
|
||||
/* Constant, variable extents */
|
||||
/* The following are serial port transmit and receive related variables and buffers */
|
||||
extern volatile CDC_CTL Cdc; /* Serial x control related structure */
|
||||
extern __attribute__ ((aligned(4))) uint8_t CDC_Tx_Buf[DEF_CDC_TX_BUF_LEN]; /* Serial x transmit buffer */
|
||||
extern __attribute__ ((aligned(4))) uint8_t CDC_Rx_Buf[DEF_CDC_RX_BUF_LEN]; /* Serial x transmit buffer */
|
||||
|
||||
/***********************************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
void CDC_USB_Init(void);
|
||||
void CDC_DataTx_Process( void ); /* Serial port 1 data sending processing */
|
||||
void CDC_DataRx_Process( void ); /* Serial port 1 data reception processing */
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USER_USB_CDC_H_ */
|
||||
Reference in New Issue
Block a user