From b30c02afa078f7713faa14087ae28433dee49027 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 14 Mar 2014 00:30:37 +0000 Subject: stmhal: Get USB enumerating a CDC device. Enumerates CDC device over USB, but doesn't transmit/receive yet. --- stmhal/usbd_cdc_interface.c | 461 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 stmhal/usbd_cdc_interface.c (limited to 'stmhal/usbd_cdc_interface.c') diff --git a/stmhal/usbd_cdc_interface.c b/stmhal/usbd_cdc_interface.c new file mode 100644 index 000000000..cb1c41f24 --- /dev/null +++ b/stmhal/usbd_cdc_interface.c @@ -0,0 +1,461 @@ +/** + ****************************************************************************** + * @file USB_Device/CDC_Standalone/Src/usbd_cdc_interface.c + * @author MCD Application Team + * @version V1.0.1 + * @date 26-February-2014 + * @brief Source file for USBD CDC interface + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" +#include "usbd_cdc_interface.h" + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_CDC + * @brief usbd core module + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define APP_RX_DATA_SIZE 2048 +#define APP_TX_DATA_SIZE 2048 + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +USBD_CDC_LineCodingTypeDef LineCoding = + { + 115200, /* baud rate*/ + 0x00, /* stop bits-1*/ + 0x00, /* parity - none*/ + 0x08 /* nb. of bits 8*/ + }; + +uint8_t UserRxBuffer[APP_RX_DATA_SIZE];/* Received Data over USB are stored in this buffer */ +uint8_t UserTxBuffer[APP_TX_DATA_SIZE];/* Received Data over UART (CDC interface) are stored in this buffer */ +uint32_t BuffLength; +uint32_t UserTxBufPtrIn = 0;/* Increment this pointer or roll it back to + start address when data are received over USART */ +uint32_t UserTxBufPtrOut = 0; /* Increment this pointer or roll it back to + start address when data are sent over USB */ + +/* UART handler declaration */ +UART_HandleTypeDef UartHandle; +/* TIM handler declaration */ +TIM_HandleTypeDef TimHandle; +/* USB handler declaration */ +extern USBD_HandleTypeDef hUSBDDevice; + +/* Private function prototypes -----------------------------------------------*/ +static int8_t CDC_Itf_Init (void); +static int8_t CDC_Itf_DeInit (void); +static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length); +static int8_t CDC_Itf_Receive (uint8_t* pbuf, uint32_t *Len); + +static void Error_Handler(void); +static void ComPort_Config(void); +//static void TIM_Config(void); + +USBD_CDC_ItfTypeDef USBD_CDC_fops = +{ + CDC_Itf_Init, + CDC_Itf_DeInit, + CDC_Itf_Control, + CDC_Itf_Receive +}; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief CDC_Itf_Init + * Initializes the CDC media low layer + * @param None + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_Itf_Init(void) +{ +#if 0 + /*##-1- Configure the UART peripheral ######################################*/ + /* Put the USART peripheral in the Asynchronous mode (UART Mode) */ + /* USART configured as follow: + - Word Length = 8 Bits + - Stop Bit = One Stop bit + - Parity = No parity + - BaudRate = 115200 baud + - Hardware flow control disabled (RTS and CTS signals) */ + UartHandle.Instance = USARTx; + UartHandle.Init.BaudRate = 115200; + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + UartHandle.Init.StopBits = UART_STOPBITS_1; + UartHandle.Init.Parity = UART_PARITY_NONE; + UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle.Init.Mode = UART_MODE_TX_RX; + + if(HAL_UART_Init(&UartHandle) != HAL_OK) + { + /* Initialization Error */ + Error_Handler(); + } + + /*##-2- Put UART peripheral in IT reception process ########################*/ + /* Any data received will be stored in "UserTxBuffer" buffer */ + if(HAL_UART_Receive_IT(&UartHandle, (uint8_t *)UserTxBuffer, 1) != HAL_OK) + { + /* Transfer error in reception process */ + Error_Handler(); + } + + /*##-3- Configure the TIM Base generation #################################*/ + TIM_Config(); + + /*##-4- Start the TIM Base generation in interrupt mode ####################*/ + /* Start Channel1 */ + if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK) + { + /* Starting Error */ + Error_Handler(); + } +#endif + + /*##-5- Set Application Buffers ############################################*/ + USBD_CDC_SetTxBuffer(&hUSBDDevice, UserTxBuffer, 0); + USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer); + + return (USBD_OK); +} + +/** + * @brief CDC_Itf_DeInit + * DeInitializes the CDC media low layer + * @param None + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_Itf_DeInit(void) +{ +#if 0 + /* DeInitialize the UART peripheral */ + if(HAL_UART_DeInit(&UartHandle) != HAL_OK) + { + /* Initialization Error */ + Error_Handler(); + } +#endif + return (USBD_OK); +} + +/** + * @brief CDC_Itf_Control + * Manage the CDC class requests + * @param Cmd: Command code + * @param Buf: Buffer containing command data (request parameters) + * @param Len: Number of data to be sent (in bytes) + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length) +{ + switch (cmd) + { + case CDC_SEND_ENCAPSULATED_COMMAND: + /* Add your code here */ + break; + + case CDC_GET_ENCAPSULATED_RESPONSE: + /* Add your code here */ + break; + + case CDC_SET_COMM_FEATURE: + /* Add your code here */ + break; + + case CDC_GET_COMM_FEATURE: + /* Add your code here */ + break; + + case CDC_CLEAR_COMM_FEATURE: + /* Add your code here */ + break; + + case CDC_SET_LINE_CODING: + LineCoding.bitrate = (uint32_t)(pbuf[0] | (pbuf[1] << 8) |\ + (pbuf[2] << 16) | (pbuf[3] << 24)); + LineCoding.format = pbuf[4]; + LineCoding.paritytype = pbuf[5]; + LineCoding.datatype = pbuf[6]; + + /* Set the new configuration */ + ComPort_Config(); + break; + + case CDC_GET_LINE_CODING: + pbuf[0] = (uint8_t)(LineCoding.bitrate); + pbuf[1] = (uint8_t)(LineCoding.bitrate >> 8); + pbuf[2] = (uint8_t)(LineCoding.bitrate >> 16); + pbuf[3] = (uint8_t)(LineCoding.bitrate >> 24); + pbuf[4] = LineCoding.format; + pbuf[5] = LineCoding.paritytype; + pbuf[6] = LineCoding.datatype; + + /* Add your code here */ + break; + + case CDC_SET_CONTROL_LINE_STATE: + /* Add your code here */ + break; + + case CDC_SEND_BREAK: + /* Add your code here */ + break; + + default: + break; + } + + return (USBD_OK); +} + +/** + * @brief TIM period elapsed callback + * @param htim: TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + uint32_t buffptr; + uint32_t buffsize; + + if(UserTxBufPtrOut != UserTxBufPtrIn) + { + if(UserTxBufPtrOut > UserTxBufPtrIn) /* rollback */ + { + buffsize = APP_RX_DATA_SIZE - UserTxBufPtrOut; + } + else + { + buffsize = UserTxBufPtrIn - UserTxBufPtrOut; + } + + buffptr = UserTxBufPtrOut; + + USBD_CDC_SetTxBuffer(&hUSBDDevice, (uint8_t*)&UserTxBuffer[buffptr], buffsize); + + if(USBD_CDC_TransmitPacket(&hUSBDDevice) == USBD_OK) + { + UserTxBufPtrOut += buffsize; + if (UserTxBufPtrOut == APP_RX_DATA_SIZE) + { + UserTxBufPtrOut = 0; + } + } + } +} + +/** + * @brief Rx Transfer completed callback + * @param huart: UART handle + * @retval None + */ +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) +{ + /* Increment Index for buffer writing */ + UserTxBufPtrIn++; + + /* To avoid buffer overflow */ + if(UserTxBufPtrIn == APP_RX_DATA_SIZE) + { + UserTxBufPtrIn = 0; + } + + /* Start another reception: provide the buffer pointer with offset and the buffer size */ + HAL_UART_Receive_IT(huart, (uint8_t *)(UserTxBuffer + UserTxBufPtrIn), 1); +} + +/** + * @brief CDC_Itf_DataRx + * Data received over USB OUT endpoint are sent over CDC interface + * through this function. + * @param Buf: Buffer of data to be transmitted + * @param Len: Number of data received (in bytes) + * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) +{ + HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len); + return (USBD_OK); +} + +/** + * @brief Tx Transfer completed callback + * @param huart: UART handle + * @retval None + */ +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) +{ + /* Initiate next USB packet transfer once UART completes transfer (transmitting data over Tx line) */ + USBD_CDC_ReceivePacket(&hUSBDDevice); +} + +/** + * @brief ComPort_Config + * Configure the COM Port with the parameters received from host. + * @param None. + * @retval None. + * @note When a configuration is not supported, a default value is used. + */ +static void ComPort_Config(void) +{ + if(HAL_UART_DeInit(&UartHandle) != HAL_OK) + { + /* Initialization Error */ + Error_Handler(); + } + + /* set the Stop bit */ + switch (LineCoding.format) + { + case 0: + UartHandle.Init.StopBits = UART_STOPBITS_1; + break; + case 2: + UartHandle.Init.StopBits = UART_STOPBITS_2; + break; + default : + UartHandle.Init.StopBits = UART_STOPBITS_1; + break; + } + + /* set the parity bit*/ + switch (LineCoding.paritytype) + { + case 0: + UartHandle.Init.Parity = UART_PARITY_NONE; + break; + case 1: + UartHandle.Init.Parity = UART_PARITY_ODD; + break; + case 2: + UartHandle.Init.Parity = UART_PARITY_EVEN; + break; + default : + UartHandle.Init.Parity = UART_PARITY_NONE; + break; + } + + /*set the data type : only 8bits and 9bits is supported */ + switch (LineCoding.datatype) + { + case 0x07: + /* With this configuration a parity (Even or Odd) must be set */ + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + break; + case 0x08: + if(UartHandle.Init.Parity == UART_PARITY_NONE) + { + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + } + else + { + UartHandle.Init.WordLength = UART_WORDLENGTH_9B; + } + + break; + default : + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + break; + } + + UartHandle.Init.BaudRate = LineCoding.bitrate; + UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle.Init.Mode = UART_MODE_TX_RX; + + if(HAL_UART_Init(&UartHandle) != HAL_OK) + { + /* Initialization Error */ + Error_Handler(); + } + + /* Start reception: provide the buffer pointer with offset and the buffer size */ + HAL_UART_Receive_IT(&UartHandle, (uint8_t *)(UserTxBuffer + UserTxBufPtrIn), 1); +} + +/** + * @brief TIM_Config: Configure TIMx timer + * @param None. + * @retval None. + */ +#if 0 +static void TIM_Config(void) +{ + /* Set TIMx instance */ + TimHandle.Instance = TIMx; + + /* Initialize TIM3 peripheral as follow: + + Period = 10000 - 1 + + Prescaler = ((SystemCoreClock/2)/10000) - 1 + + ClockDivision = 0 + + Counter direction = Up + */ + TimHandle.Init.Period = (CDC_POLLING_INTERVAL*1000) - 1; + TimHandle.Init.Prescaler = 84-1; + TimHandle.Init.ClockDivision = 0; + TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; + if(HAL_TIM_Base_Init(&TimHandle) != HAL_OK) + { + /* Initialization Error */ + Error_Handler(); + } +} +#endif + +/** + * @brief UART error callbacks + * @param UartHandle: UART handle + * @retval None + */ +void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle) +{ + /* Transfer error occured in reception and/or transmission process */ + Error_Handler(); +} + +/** + * @brief This function is executed in case of error occurrence. + * @param None + * @retval None + */ +static void Error_Handler(void) +{ + /* Add your own code here */ +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + -- cgit v1.2.3