From 5701faa7de472ac1f4bf881a50d527bede719a5f Mon Sep 17 00:00:00 2001 From: Bob-the-Kuhn Date: Fri, 20 Mar 2020 15:49:59 -0500 Subject: [PATCH 1/2] copy over changes from working branch --- cores/arduino/stm32/usb/cdc/usbd_cdc.c | 2 + cores/arduino/stm32/usb/cdc/usbd_cdc_if.c | 2 + .../stm32/usb/msc_cdc_composite/SdMscDriver.c | 377 ++++ .../stm32/usb/msc_cdc_composite/SdMscDriver.h | 13 + .../stm32/usb/msc_cdc_composite/usbd_cdc.h | 170 ++ .../usbd_desc_msc_cdc_composite.c | 1742 +++++++++++++++++ .../stm32/usb/msc_cdc_composite/usbd_msc.h | 133 ++ .../usb/msc_cdc_composite/usbd_msc_bot.h | 143 ++ .../usbd_msc_cdc_composite.h | 195 ++ .../usbd_msc_cdc_composite_bot.h | 142 ++ .../usbd_msc_cdc_composite_if.c | 379 ++++ .../msc_cdc_composite/usbd_msc_composite.h | 73 + .../usbd_msc_composite_bot.c | 409 ++++ .../usbd_msc_composite_scsi.c | 678 +++++++ .../usb/msc_cdc_composite/usbd_msc_data.c | 132 ++ .../usb/msc_cdc_composite/usbd_msc_data.h | 104 + .../usb/msc_cdc_composite/usbd_msc_scsi.h | 192 ++ cores/arduino/stm32/usb/usbd_conf.c | 75 +- cores/arduino/stm32/usb/usbd_conf.c mod | 753 +++++++ cores/arduino/stm32/usb/usbd_def.h | 377 ++++ cores/arduino/stm32/usb/usbd_desc.c | 5 +- cores/arduino/stm32/usb/usbd_desc.h | 6 + cores/arduino/stm32/usb/usbd_ep_conf.c | 82 + cores/arduino/stm32/usb/usbd_ep_conf.h | 95 + 24 files changed, 6237 insertions(+), 42 deletions(-) create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.c create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.h create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_cdc.h create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_desc_msc_cdc_composite.c create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc.h create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_bot.h create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite.h create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite_bot.h create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite_if.c create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite.h create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite_bot.c create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite_scsi.c create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_data.c create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_data.h create mode 100644 cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_scsi.h create mode 100644 cores/arduino/stm32/usb/usbd_conf.c mod create mode 100644 cores/arduino/stm32/usb/usbd_def.h create mode 100644 cores/arduino/stm32/usb/usbd_ep_conf.c create mode 100644 cores/arduino/stm32/usb/usbd_ep_conf.h diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c index 4aac278a2a..8ee1b28254 100644 --- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c +++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c @@ -52,6 +52,7 @@ #ifdef USBCON #ifdef USBD_USE_CDC +#ifndef USBD_USE_CDC_COMPOSITE /* Includes ------------------------------------------------------------------*/ #include "usbd_cdc.h" @@ -894,6 +895,7 @@ uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev) } } +#endif /* !USBD_USE_CDC_COMPOSITE */ #endif /* USBD_USE_CDC */ #endif /* USBCON */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c index b4b1933a6a..367be01173 100644 --- a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c +++ b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c @@ -19,6 +19,7 @@ #ifdef USBCON #ifdef USBD_USE_CDC +#ifndef USBD_USE_CDC_COMPOSITE /* Includes ------------------------------------------------------------------*/ #include "usbd_desc.h" @@ -335,6 +336,7 @@ bool CDC_resume_receive(void) return false; } +#endif /* !USBD_USE_CDC_COMPOSITE */ #endif /* USBD_USE_CDC */ #endif /* USBCON */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.c b/cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.c new file mode 100644 index 0000000000..619a76ed20 --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.c @@ -0,0 +1,377 @@ +#ifdef USBD_USE_CDC_COMPOSITE + +#include + +#include "usbd_msc_scsi.h" +#include "usbd_msc_composite.h" +#include "usbd_msc_cdc_composite.h" + +#include "usbd_msc_cdc_composite_bot.h" + +#if defined(STM32F103xE) || defined(STM32F103xG) +#include "stm32f1xx_hal_rcc_ex.h" +#elif defined(STM32F4xx) +#include "stm32f4xx_hal_rcc_ex.h" +#else +#error "ERROR - Only STM32F103xE, STM32F103xG or STM32F4xx CPUs supported" +#endif + + + + +#define TIMEOUT_SD_ACCESS 0xFF // guess - don't know units +#define SD_RETRY_COUNT 3 + +MSC_lock_typedef MSC_lock_byte = MSC_UNLOCKED; // start out with MSC unlocked + +SD_HandleTypeDef hsd; // create SDIO structure + +HAL_SD_CardCSDTypeDef pCSD; // create structure to hold decoded CSD data +HAL_SD_CardCIDTypeDef pCID; // create structure to hold decoded CID data +HAL_SD_CardStatusTypeDef pStatus; // create structure to hold card status data +HAL_SD_CardInfoTypeDef pCardInfo; // create structure to hold card info + +HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypeDef *pCSD); +HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID); +HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypeDef *pStatus); +HAL_StatusTypeDef HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef *hsd, uint32_t WideMode); + +HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd); +HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd); +HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo); +HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout); +HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout); +HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init); + +HAL_StatusTypeDef SD_SDIO_Init(); + +#define MSC_USB_ACQUIRE_DEF (extern "C" {HAL_StatusTypeDef SD_SDIO_Init(); MSC_lock_typedef MSC_lock_byte;}}) +#define MSC_USB_ACQUIRE do {SD_SDIO_Init();}while(0) +#define MSC_USB_RELEASE_DEF (extern "C" {MSC_lock_typedef MSC_lock_byte;}) +#define MSC_USB_RELEASE do {MSC_lock_byte = MSC_UNLOCKED;}while(0) + +#define TRANSFER_CLOCK_DIV ((uint8_t)SDIO_INIT_CLK_DIV/40) + + +HAL_SD_CardStatusTypeDef bob_get_CardStatus() { //bob + + HAL_SD_CardStatusTypeDef temp; + + HAL_SD_GetCardStatus(&hsd, &temp); + + + //temp.DataBusWidth= pStatus.DataBusWidth & 0x03; /*!< uint8_t Shows the currently defined data bus width */ + //temp.SecuredMode= pStatus.SecuredMode & 0x01; /*!< uint8_t Card is in secured mode of operation */ + //temp.CardType= pStatus.CardType; /*!< uint16_t Carries information about card type */ + //temp.ProtectedAreaSize= pStatus.ProtectedAreaSize; /*!< uint32_t Carries information about the capacity of protected area */ + //temp.SpeedClass= pStatus.SpeedClass; /*!< uint8_t Carries information about the speed class of the card */ + //temp.PerformanceMove= pStatus.PerformanceMove; /*!< uint8_t Carries information about the card's performance move */ + //temp.AllocationUnitSize= pStatus.AllocationUnitSize; /*!< uint8_t Carries information about the card's allocation unit size */ + //temp.EraseSize= pStatus.EraseSize; /*!< uint16_t Determines the number of AUs to be erased in one operation */ + //temp.EraseTimeout= pStatus.EraseTimeout; /*!< uint8_t Determines the timeout for any number of AU erase */ + //temp.EraseOffset= pStatus.EraseOffset; /*!< uint8_t Carries information about the erase offset */ + + return temp; +} + +struct bob_CSD { + uint32_t bob_CSD_0; + uint32_t bob_CSD_1; + uint32_t bob_CSD_2; + uint32_t bob_CSD_3; +}; + + + + +struct bob_CSD bob_get_CSD() { + struct bob_CSD temp; + + temp.bob_CSD_0 = hsd.CSD[0]; + temp.bob_CSD_1 = hsd.CSD[1]; + temp.bob_CSD_2 = hsd.CSD[2]; + temp.bob_CSD_3 = hsd.CSD[3]; + + return temp; +} + +struct bob_CSD bob_get_CID() { + struct bob_CSD temp; + + temp.bob_CSD_0 = hsd.CID[0]; + temp.bob_CSD_1 = hsd.CID[1]; + temp.bob_CSD_2 = hsd.CID[2]; + temp.bob_CSD_3 = hsd.CID[3]; + + return temp; +} + +struct bob_SECTOR { + uint8_t bob_sector[512]; + int8_t status; +}; + +int8_t SD_MSC_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + +struct bob_SECTOR bob_sector_read(uint32_t sector) { + struct bob_SECTOR temp; + + temp.status = SD_MSC_Read(0, temp.bob_sector, sector, 1); + + return temp; +} + + + +void go_to_transfer_speed() { + + SD_InitTypeDef Init; + + /* Default SDIO peripheral configuration for SD card initialization */ + Init.ClockEdge = hsd.Init.ClockEdge; + Init.ClockBypass = hsd.Init.ClockBypass; + Init.ClockPowerSave = hsd.Init.ClockPowerSave; + Init.BusWide = hsd.Init.BusWide; + Init.HardwareFlowControl = hsd.Init.HardwareFlowControl; +// Init.ClockDiv = TRANSFER_CLOCK_DIV; + Init.ClockDiv = SDIO_INIT_CLK_DIV; + + /* Initialize SDIO peripheral interface with default configuration */ + SDIO_Init(hsd.Instance, Init); +} + +void SD_LowLevel_Init(void) { + + uint32_t tempreg; + + GPIO_InitTypeDef GPIO_InitStruct; + + __HAL_RCC_GPIOC_CLK_ENABLE(); //enable GPIO clocks + __HAL_RCC_GPIOD_CLK_ENABLE(); //enable GPIO clocks + + GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_12; // D0 & SCK + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = 1; //GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + // #if defined(SDIO_D1_PIN) && defined(SDIO_D2_PIN) && defined(SDIO_D3_PIN) // define D1-D3 only if have a four bit wide SDIO bus + GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11; // D1-D3 + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = 1; //GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + //#endif + + // Configure PD.02 CMD line + GPIO_InitStruct.Pin = GPIO_PIN_2; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + RCC->APB2RSTR &= ~RCC_APB2RSTR_SDIORST_Msk; // take SDIO out of reset + RCC->APB2ENR |= RCC_APB2RSTR_SDIORST_Msk; // enable SDIO clock + + // Enable the DMA2 Clock + + //Initialize the SDIO (with initial <400Khz Clock) + tempreg = 0; //Reset value + tempreg |= SDIO_CLKCR_CLKEN; //Clock is enabled + tempreg |= (uint32_t)0x76; //Clock Divider. Clock = 48000/(118+2) = 400Khz + //Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable + SDIO->CLKCR = tempreg; + + //Power up the SDIO + SDIO->POWER = 0x03; +} + + +void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init + UNUSED(hsd); /* Prevent unused argument(s) compilation warning */ + __HAL_RCC_SDIO_CLK_ENABLE(); // turn on SDIO clock +} + +#define SD_RETRY_COUNT 3 + +HAL_StatusTypeDef SD_SDIO_Init() { + //init SDIO and get SD card info + + uint8_t retryCnt = SD_RETRY_COUNT; + + uint8_t status; + hsd.Instance = SDIO; + hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET + SD_LowLevel_Init(); + + uint8_t retry_Cnt = retryCnt; + for (;;) { + status = HAL_SD_Init(&hsd); // low level init, enable SDIO & populate some HSD fields, init SD card and get CID & CSD registers + if (!status) break; + if (!--retry_Cnt) return false; // return failing status if retries are exhausted + } + + retry_Cnt = retryCnt; + for (;;) { + if (!HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B)) break; // some cards are only 1 bit wide so a pass here is not required + if (!--retry_Cnt) break; + } + if (!retry_Cnt) { // wide bus failed, go back to one bit wide mode + hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET + SD_LowLevel_Init(); + retry_Cnt = retryCnt; + for (;;) { + status = HAL_SD_Init(&hsd); + if (!status) break; + if (!--retry_Cnt) return false; // return failing status if retries are exhausted + } + } + + return true; +} + + +#ifndef USBD_OK +#define USBD_OK 0 +#endif + + + +int8_t SD_MSC_Init(uint8_t lun); + +int8_t SD_MSC_GetCapacity(uint8_t lun, + uint32_t *block_num, + uint16_t *block_size); + +int8_t SD_MSC_IsReady(uint8_t lun); + +int8_t SD_MSC_IsWriteProtected(uint8_t lun); + +int8_t SD_MSC_Read(uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len); + +int8_t SD_MSC_Write(uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len); + +int8_t SD_MSC_GetMaxLun(void); + + + + +#define STANDARD_INQUIRY_DATA_LEN 0x24U + + +uint8_t SD_MSC_Inquirydata[] = {/* 36 */ + /* LUN 0 */ + 0x00, + 0x80, + 0x02, + 0x02, + (STANDARD_INQUIRY_DATA_LEN - 5), + 0x00, + 0x00, + 0x00, + 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */ + 'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */ + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + '0', '.', '0', '1', /* Version : 4 Bytes */ +}; + + +USBD_StorageTypeDef SdMscDriver = { + SD_MSC_Init, + SD_MSC_GetCapacity, + SD_MSC_IsReady, + SD_MSC_IsWriteProtected, + SD_MSC_Read, + SD_MSC_Write, + SD_MSC_GetMaxLun, + (int8_t *)SD_MSC_Inquirydata +}; + + + +int8_t SD_MSC_Init(uint8_t lun) +{ + (void)lun; // Not used + + SD_SDIO_Init(); + return USBD_OK; +} + + +int8_t SD_MSC_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size) +{ + (void)lun; // Not used + + *block_num = hsd.SdCard.BlockNbr; // Card Capacity in blocks + *block_size = hsd.SdCard.BlockSize; // number of bytes in a block + + return USBD_OK; +} + + +int8_t SD_MSC_IsReady(uint8_t lun) +{ + (void)lun; // Not used + if (hsd.State == HAL_SD_STATE_READY) { + return USBD_OK; + } + return USBD_FAIL; +} + +uint8_t temp_msc[512]; + +int8_t SD_MSC_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) +{ + (void)lun; // Not used + + int8_t status; + uint8_t retryCnt = SD_RETRY_COUNT; + + for (;;) { + status = HAL_SD_ReadBlocks(&hsd, buf, blk_addr, blk_len, TIMEOUT_SD_ACCESS); // read 512 byte block(s) with 500mS timeout + status |= HAL_SD_GetCardState(&hsd); // make sure all is OK + if (!status) return USBD_OK; // return passing status + if (!--retryCnt) return USBD_FAIL; // return failing status if retries are exhausted + } +} + + +int8_t SD_MSC_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) +{ + (void)lun; // Not used + + + int8_t status; + uint8_t retryCnt = SD_RETRY_COUNT; + + for (;;) { + status = HAL_SD_WriteBlocks(&hsd, buf, blk_addr, blk_len, TIMEOUT_SD_ACCESS); // write 512 byte block(s) with 500mS timeout + status |= HAL_SD_GetCardState(&hsd); // make sure all is OK + if (!status) return (bool) USBD_OK; // return passing status + if (!--retryCnt) return (bool) USBD_FAIL; // return failing status if retries are exhausted + } +} + + +int8_t SD_MSC_IsWriteProtected(uint8_t lun) +{ + (void)lun; // Not used + + return USBD_OK; // Never write protected +} + + +int8_t SD_MSC_GetMaxLun(void) +{ + + return 0; // We have just 1 Logic unit number (LUN) which is zero +} + +#endif /* USBD_USE_CDC_COMPOSITE */ + + diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.h b/cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.h new file mode 100644 index 0000000000..903c316b52 --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.h @@ -0,0 +1,13 @@ +#ifndef SDMSCDRIVER_H +#define SDMSCDRIVER_H + +//#include "usbd_msc.h" +#include "usbd_msc_cdc_composite.h" + +bool initSDIOThread(); +void xSDIOThread(void *pvParameters); +void xSDTestThread(void *pvParameters); + +extern USBD_StorageTypeDef SdMscDriver; + +#endif // SDMSCDRIVER_H diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_cdc.h b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_cdc.h new file mode 100644 index 0000000000..022b087bbe --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_cdc.h @@ -0,0 +1,170 @@ +/** + ****************************************************************************** + * @file usbd_cdc.h + * @author MCD Application Team + * @brief header file for the usbd_cdc.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, 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/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CDC_H +#define __USB_CDC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_cdc + * @brief This file is the Header file for usbd_cdc.c + * @{ + */ + + +/** @defgroup usbd_cdc_Exported_Defines + * @{ + */ + +#ifdef USBD_USE_CDC_COMPOSITE +#define CDC_OUT_EP 0x02U /* EP2 for data OUT */ +#define CDC_IN_EP 0x82U /* EP2 for data IN */ +#define CDC_CMD_EP 0x83U /* EP3 for CDC commands */ +#else +#define CDC_OUT_EP 0x01U /* EP1 for data OUT */ +#define CDC_IN_EP 0x81U /* EP1 for data IN */ +#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */ +#endif + +#ifndef CDC_HS_BINTERVAL +#define CDC_HS_BINTERVAL 0x10U +#endif /* CDC_HS_BINTERVAL */ + +#ifndef CDC_FS_BINTERVAL +#define CDC_FS_BINTERVAL 0x10U +#endif /* CDC_FS_BINTERVAL */ + +/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ +#define CDC_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ +#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ +#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ + +#define USB_CDC_CONFIG_DESC_SIZ 67U +#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE +#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE + +#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE +#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE + +/*---------------------------------------------------------------------*/ +/* CDC definitions */ +/*---------------------------------------------------------------------*/ +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00U +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01U +#define CDC_SET_COMM_FEATURE 0x02U +#define CDC_GET_COMM_FEATURE 0x03U +#define CDC_CLEAR_COMM_FEATURE 0x04U +#define CDC_SET_LINE_CODING 0x20U +#define CDC_GET_LINE_CODING 0x21U +#define CDC_SET_CONTROL_LINE_STATE 0x22U +#define CDC_SEND_BREAK 0x23U + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ +typedef struct { + uint32_t bitrate; + uint8_t format; + uint8_t paritytype; + uint8_t datatype; +} USBD_CDC_LineCodingTypeDef; + +typedef struct _USBD_CDC_Itf { + int8_t (* Init)(void); + int8_t (* DeInit)(void); + int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length); + int8_t (* Receive)(uint8_t *Buf, uint32_t *Len); + int8_t (* Transferred)(void); + +} USBD_CDC_ItfTypeDef; + +#ifndef __IO +#define __IO volatile /*!< \brief Defines 'read / write' permissions */ +#endif + +typedef struct _USBD_CDC_HandleTypeDef { + uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32bits alignment */ + uint8_t CmdOpCode; + uint8_t CmdLength; + uint8_t *RxBuffer; + uint8_t *TxBuffer; + uint32_t RxLength; + uint32_t TxLength; + + __IO uint32_t TxState; + __IO uint32_t RxState; +} USBD_CDC_HandleTypeDef; + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ +struct _Device_cb; // USBD_ClassTypeDef +extern struct _Device_cb USBD_CDC; +#define USBD_CDC_CLASS &USBD_CDC +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_CDC_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_desc_msc_cdc_composite.c b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_desc_msc_cdc_composite.c new file mode 100644 index 0000000000..7fffde1b1b --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_desc_msc_cdc_composite.c @@ -0,0 +1,1742 @@ +/** + ****************************************************************************** + * @file usbd_desc.c + * @author MCD Application Team + * @brief This file provides the USBD descriptors and string formatting method. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, 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/SLA0044 + * + ****************************************************************************** + */ + +/** + ****************************************************************************** + * + * The composite MSC CDC USB device is mainly adapted from the GPSlogger + * repository https://github.com/grafalex82/GPSLogger/tree/master/Libs/USB + * + * See the article "CDC + MSC USB Composite Device for STM32 HAL" (URL: + * https://habr.com/en/post/335018/) for the theory behind the MSC CDC + * composite device as implemented in the above repository. + * + * The composite MSC CDC USB device requires a modified USBD_HandleTypeDef + * structure. The MSC and CDC classes require dedicated data structures. + * + ****************************************************************************** + */ + +#if defined(USBCON) && defined(USBD_USE_CDC_COMPOSITE) +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" +#include "usbd_core.h" +#include "usbd_desc.h" +#include "utils.h" + +#include "usbd_cdc.h" +#include "usbd_ctlreq.h" +#include "usbd_msc_cdc_composite.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#if USBD_VID == 0x2341 + #define USBD_MANUFACTURER_STRING "Arduino LLC" +#elif USBD_VID == 0x2A03 +#define USBD_MANUFACTURER_STRING "Arduino srl" +#elif USBD_VID == 0x0483 +#define USBD_MANUFACTURER_STRING "STMicroelectronics" +#elif !defined(USB_MANUFACTURER) +// Fall through to unknown if no manufacturer name was provided in a macro +#define USBD_MANUFACTURER_STRING "Unknown" +#else +#define USBD_MANUFACTURER_STRING USB_MANUFACTURER +#endif + +#define USBD_LANGID_STRING 0x409 /* 1033 US.S English */ + +#define USBD_CDC_PID 0x5740 // 22336 +#define USBD_CDC_PRODUCT_HS_STRING CONCATS(USB_PRODUCT, "MSC & CDC in HS Mode") +#define USBD_CDC_PRODUCT_FS_STRING CONCATS(USB_PRODUCT, "MSC & CDC in FS Mode") +#define USBD_CDC_CONFIGURATION_HS_STRING CONCATS(USB_PRODUCT, "CDC Config") +#define USBD_CDC_INTERFACE_HS_STRING CONCATS(USB_PRODUCT, "CDC Interface") +#define USBD_CDC_CONFIGURATION_FS_STRING CONCATS(USB_PRODUCT, "CDC Config") +#define USBD_CDC_INTERFACE_FS_STRING CONCATS(USB_PRODUCT, "CDC Interface") +#define USBD_MSC_INTERFACE_STRING CONCATS(USB_PRODUCT, "MSC Interface") + + +/** + * Possible values of class + */ + +#define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class +#define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface +#define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface +#define CDC_CLASS_MULTI 0xEF //!< CDC Multi-interface Function + + +//USB CDC Subclass IDs + +#define CDC_SUBCLASS_DLCM 0x01 // Direct Line Control Model +#define CDC_SUBCLASS_ACM 0x02 // Abstract Control Model +#define CDC_SUBCLASS_TCM 0x03 // Telephone Control Model +#define CDC_SUBCLASS_MCCM 0x04 // Multi-Channel Control Model +#define CDC_SUBCLASS_CCM 0x05 // CAPI Control Model +#define CDC_SUBCLASS_ETH 0x06 // Ethernet Networking Control Model +#define CDC_SUBCLASS_ATM 0x07 // ATM Networking Control Model + +//USB CDC Communication Interface Protocol IDs + +#define CDC_PROTOCOL_V25TER 0x01 // Common AT commands + + +/* Private macro -------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Common function */ +uint8_t *USBD_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); + +/* Class specific */ +uint8_t *USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t *USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); + +#ifdef USB_SUPPORT_USER_STRING_DESC +uint8_t *USBD_Class_USRStringDesc(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length); +#endif /* USB_SUPPORT_USER_STRING_DESC */ + +/* Private variables ---------------------------------------------------------*/ +USBD_DescriptorsTypeDef CDC_Desc = { + USBD_CDC_DeviceDescriptor, + USBD_LangIDStrDescriptor, + USBD_ManufacturerStrDescriptor, + USBD_CDC_ProductStrDescriptor, + USBD_SerialStrDescriptor, + USBD_CDC_ConfigStrDescriptor, + USBD_CDC_InterfaceStrDescriptor, +}; + + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN uint8_t USBD_CDC_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { + 0x12, /* bLength */ + USB_DESC_TYPE_DEVICE, /* bDescriptorType */ + 0x00, /* bcdUSB (USB version, minor)*/ + 0x02, /* bcdUSB (USB version, major)*/ + CDC_CLASS_MULTI, /* bDeviceClass (MULTI 0xEF) */ + CDC_SUBCLASS_ACM, /* bDeviceSubClass */ + CDC_PROTOCOL_V25TER, /* bDeviceProtocol */ + USB_MAX_EP0_SIZE, /* bMaxPacketSize */ + LOBYTE(USBD_VID), /* idVendor */ + HIBYTE(USBD_VID), /* idVendor */ + LOBYTE(USBD_CDC_PID), /* idVendor */ + HIBYTE(USBD_CDC_PID), /* idVendor */ + 0x00, /* bcdDevice rel. 2.00 */ + 0x02, + USBD_IDX_MFC_STR, /* Index of manufacturer string */ + USBD_IDX_PRODUCT_STR, /* Index of product string */ + USBD_IDX_SERIAL_STR, /* Index of serial number string */ + USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */ +}; /* USB_DeviceDescriptor */ + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = { + USB_LEN_LANGID_STR_DESC, + USB_DESC_TYPE_STRING, + LOBYTE(USBD_LANGID_STRING), + HIBYTE(USBD_LANGID_STRING), +}; + +uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] = { + USB_SIZ_STRING_SERIAL, + USB_DESC_TYPE_STRING, +}; + +__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END; + +/* Private functions ---------------------------------------------------------*/ +static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len); +static void Get_SerialNum(void); + +/** + * @brief Returns the device descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t *USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_CDC_DeviceDesc); + return (uint8_t *)USBD_CDC_DeviceDesc; +} + +/** + * @brief Returns the LangID string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t *USBD_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_LangIDDesc); + return (uint8_t *)USBD_LangIDDesc; +} + +/** + * @brief Returns the product string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t *USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if (speed == USBD_SPEED_HIGH) { + USBD_GetString((uint8_t *)USBD_CDC_PRODUCT_HS_STRING, USBD_StrDesc, length); + } else { + USBD_GetString((uint8_t *)USBD_CDC_PRODUCT_FS_STRING, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** + * @brief Returns the manufacturer string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t *USBD_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); + return USBD_StrDesc; +} + +/** + * @brief Returns the serial number string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t *USBD_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = USB_SIZ_STRING_SERIAL; + + /* Update the serial number string descriptor with the data from the unique ID*/ + Get_SerialNum(); + + return (uint8_t *)USBD_StringSerial; +} + +/** + * @brief Returns the configuration string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t *USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if (speed == USBD_SPEED_HIGH) { + USBD_GetString((uint8_t *)USBD_CDC_CONFIGURATION_HS_STRING, USBD_StrDesc, length); + } else { + USBD_GetString((uint8_t *)USBD_CDC_CONFIGURATION_FS_STRING, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** + * @brief Returns the interface string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t *USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if (speed == USBD_SPEED_HIGH) { + USBD_GetString((uint8_t *)USBD_CDC_INTERFACE_HS_STRING, USBD_StrDesc, length); + } else { + USBD_GetString((uint8_t *)USBD_CDC_INTERFACE_FS_STRING, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** + * @brief Returns the interface string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t *USBD_MSC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + USBD_GetString((uint8_t *)USBD_MSC_INTERFACE_STRING, USBD_StrDesc, length); + return USBD_StrDesc; +} + + + +/** + * @brief Create the serial number string descriptor + * @param None + * @retval None + */ +static void Get_SerialNum(void) +{ + + uint32_t deviceserial0, deviceserial1, deviceserial2; + + deviceserial0 = *(uint32_t *)DEVICE_ID1; + deviceserial1 = *(uint32_t *)DEVICE_ID2; + deviceserial2 = *(uint32_t *)DEVICE_ID3; + + deviceserial0 += deviceserial2; + + if (deviceserial0 != 0) { + IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8); + IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4); + } +} + +/** + * @brief Convert Hex 32Bits value into char + * @param value: value to convert + * @param pbuf: pointer to the buffer + * @param len: buffer length + * @retval None + */ +static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len) +{ + uint8_t idx = 0; + + for (idx = 0 ; idx < len ; idx ++) { + if (((value >> 28)) < 0xA) { + pbuf[ 2 * idx] = (value >> 28) + '0'; + } else { + pbuf[2 * idx] = (value >> 28) + 'A' - 10; + } + + value = value << 4; + + pbuf[ 2 * idx + 1] = 0; + } +} + + + + + +/** + * Composite MSC CDC + * + * Source: + * https://github.com/grafalex82/GPSLogger/tree/master/Libs/USB/ + * file: usbd_msc_cdc.c + * + * Articles: + * https://weekly-geekly.github.io/articles/335018/index.html + * + * Copyright?? + * + * License?? + * + * AUTHOR + * + */ + +/* Includes ------------------------------------------------------------------*/ + + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_MSC_CDC + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_MSC_CDC_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_MSC_CDC_Private_Defines + * @{ + */ + +/** @defgroup MSC_CORE_Private_FunctionPrototypes + * @{ + */ + + + +#if defined (__ICCARM__) /*!< IAR Compiler */ +#pragma data_alignment = 4 +#endif + +#define USB_MSC_CDC_CONFIG_DESC_SIZ 98 + +///////////////////////////////////////////////////////////////////////////// +// MSC_CDC_HS +///////////////////////////////////////////////////////////////////////////// + +/* USB MSC+CDC device Configuration Descriptor */ +uint8_t USBD_MSC_CDC_HSCfgDesc[USB_MSC_CDC_CONFIG_DESC_SIZ] = { + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_MSC_CDC_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ + 0x00, + 0x03, /*bNumInterfaces: 3 interface*/ + 0x01, /*bConfigurationValue: Configuration value*/ + 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ + 0xC0, /*bmAttributes: bus powered and Supports Remote Wakeup */ + 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + /* 09 bytes */ + + + + /******** IAD should be positioned just before the CDC interfaces ****** + IAD to associate the two CDC interfaces */ + + 0x08, /* bLength */ + 0x0B, /* bDescriptorType */ + 0x00, /* bFirstInterface */ + 0x02, /* bInterfaceCount */ + 0x02, /* bFunctionClass */ + 0x02, /* bFunctionSubClass */ + 0x01, /* bFunctionProtocol */ + 0x04, /* iFunction (Index of string descriptor describing this function) */ + /* 08 bytes */ + + /******************** CDC interfaces ********************/ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x05, /* iInterface: */ + /* 09 bytes */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + /* 05 bytes */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + /* 04 bytes */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + CDC_INTERFACE_IDX, /* bMasterInterface: Communication class interface */ + CDC_INTERFACE_IDX + 1, /* bSlaveInterface0: Data Class Interface */ + /* 05 bytes */ + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x03, + CDC_INTERFACE_IDX + 1, /* bDataInterface: 1 */ + /* 05 bytes */ + + + + /*Endpoint 2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SIZE), + 0x10, /* bInterval: */ + /* 07 bytes */ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x05, /* iInterface: */ + /* 09 bytes */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), + 0x00, /* bInterval */ + /* 07 bytes */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), + 0x00, /* bInterval: ignore for Bulk transfer */ + /* 07 bytes */ + + + + /******************** Mass Storage interface ********************/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x02, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints*/ + 0x08, /* bInterfaceClass: MSC Class */ + 0x06, /* bInterfaceSubClass : SCSI transparent command set*/ + 0x50, /* nInterfaceProtocol */ + 0x00, /* iInterface: */ + /* 09 bytes */ + + /******************** Mass Storage Endpoints ********************/ + 0x07, /*Endpoint descriptor length = 7*/ + 0x05, /*Endpoint descriptor type */ + MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(USB_MSC_PACKET_SIZE), + HIBYTE(USB_MSC_PACKET_SIZE), + 0x00, /*Polling interval in milliseconds */ + /* 07 bytes */ + + 0x07, /*Endpoint descriptor length = 7 */ + 0x05, /*Endpoint descriptor type */ + MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(USB_MSC_PACKET_SIZE), + HIBYTE(USB_MSC_PACKET_SIZE), + 0x00, /*Polling interval in milliseconds*/ + /* 07 bytes */ + + + +}; + +///////////////////////////////////////////////////////////////////////////// +// MSC_CDC_FS +////////////////////////////////////////////////////////////////////////////// + +/* USB MSC+CDC device Configuration Descriptor */ +uint8_t USBD_MSC_CDC_FSCfgDesc[USB_MSC_CDC_CONFIG_DESC_SIZ] = { + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_MSC_CDC_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ + 0x00, + 0x03, /*bNumInterfaces: 3 interface*/ + 0x01, /*bConfigurationValue: Configuration value*/ + 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ + 0xC0, /*bmAttributes: bus powered and Supports Remote Wakeup */ + 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + /* 09 bytes */ + + + + /******************** CDC interface ********************/ + + /******** IAD should be positioned just before the CDC interfaces ****** + IAD to associate the two CDC interfaces */ + + 0x08, /* bLength */ + 0x0B, /* bDescriptorType */ + 0x00, /* bFirstInterface */ + 0x02, /* bInterfaceCount */ + 0x02, /* bFunctionClass */ + 0x02, /* bFunctionSubClass */ + 0x01, /* bFunctionProtocol */ + 0x04, /* iFunction (Index of string descriptor describing this function) */ + /* 08 bytes */ + + /******************** CDC interfaces ********************/ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x05, /* iInterface: */ + /* 09 bytes */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + /* 05 bytes */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + /* 04 bytes */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + CDC_INTERFACE_IDX, /* bMasterInterface: Communication class interface */ + CDC_INTERFACE_IDX + 1, /* bSlaveInterface0: Data Class Interface */ + /* 05 bytes */ + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x03, + CDC_INTERFACE_IDX + 1, /* bDataInterface: 1 */ + /* 05 bytes */ + + + + /*CMD Endpoint Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SIZE), + 0x10, /* bInterval: */ + /* 07 bytes */ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x05, /* iInterface: */ + /* 09 bytes */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00, /* bInterval */ + /* 07 bytes */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00, /* bInterval: ignore for Bulk transfer */ + /* 07 bytes */ + + + /******************** Mass Storage interface ********************/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x02, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints*/ + 0x08, /* bInterfaceClass: MSC Class */ + 0x06, /* bInterfaceSubClass : SCSI transparent command set*/ + 0x50, /* nInterfaceProtocol */ + 0x00, /* iInterface: */ + /* 09 bytes */ + + /******************** Mass Storage Endpoints ********************/ + 0x07, /*Endpoint descriptor length = 7*/ + 0x05, /*Endpoint descriptor type */ + MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(USB_MSC_PACKET_SIZE), + HIBYTE(USB_MSC_PACKET_SIZE), + 0x00, /*Polling interval in milliseconds */ + /* 07 bytes */ + + 0x07, /*Endpoint descriptor length = 7 */ + 0x05, /*Endpoint descriptor type */ + MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(USB_MSC_PACKET_SIZE), + HIBYTE(USB_MSC_PACKET_SIZE), + 0x00, /*Polling interval in milliseconds*/ + /* 07 bytes */ + +}; + +///////////////////////////////////////////////////////////////////////////// +// MSC_CDC_OtherSpeed +///////////////////////////////////////////////////////////////////////////// + +/* USB MSC+CDC device Configuration Descriptor */ +uint8_t USBD_MSC_CDC_OtherSpeedCfgDesc[USB_MSC_CDC_CONFIG_DESC_SIZ] = { + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_MSC_CDC_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ + 0x00, + 0x03, /*bNumInterfaces: 3 interface*/ + 0x01, /*bConfigurationValue: Configuration value*/ + 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ + 0xC0, /*bmAttributes: bus powered and Supports Remote Wakeup */ + 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + /* 09 bytes */ + + + /******** IAD should be positioned just before the CDC interfaces ****** + IAD to associate the two CDC interfaces */ + + 0x08, /* bLength */ + 0x0B, /* bDescriptorType */ + 0x00, /* bFirstInterface */ + 0x02, /* bInterfaceCount */ + 0x02, /* bFunctionClass */ + 0x02, /* bFunctionSubClass */ + 0x01, /* bFunctionProtocol */ + 0x04, /* iFunction (Index of string descriptor describing this function) */ + /* 08 bytes */ + + /******************** CDC interfaces ********************/ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x05, /* iInterface: */ + /* 09 bytes */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + /* 05 bytes */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + /* 04 bytes */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + CDC_INTERFACE_IDX, /* bMasterInterface: Communication class interface */ + CDC_INTERFACE_IDX + 1, /* bSlaveInterface0: Data Class Interface */ + /* 05 bytes */ + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x03, + CDC_INTERFACE_IDX + 1, /* bDataInterface: 1 */ + /* 05 bytes */ + + + + /*CMD Endpoint Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SIZE), + 0x10, /* bInterval: */ + /* 07 bytes */ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x05, /* iInterface: */ + /* 09 bytes */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ + 0x00, + 0x00, /* bInterval: ignore for Bulk transfer */ + /* 07 bytes */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ + 0x00, + 0x00, /* bInterval: ignore for Bulk transfer */ + /* 07 bytes */ + + + /******************** Mass Storage interface ********************/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x02, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints*/ + 0x08, /* bInterfaceClass: MSC Class */ + 0x06, /* bInterfaceSubClass : SCSI transparent command set*/ + 0x50, /* nInterfaceProtocol */ + 0x00, /* iInterface: */ + /* 09 bytes */ + + /******************** Mass Storage Endpoints ********************/ + 0x07, /*Endpoint descriptor length = 7*/ + 0x05, /*Endpoint descriptor type */ + MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(USB_MSC_PACKET_SIZE), + HIBYTE(USB_MSC_PACKET_SIZE), + 0x00, /*Polling interval in milliseconds */ + /* 07 bytes */ + + 0x07, /*Endpoint descriptor length = 7 */ + 0x05, /*Endpoint descriptor type */ + MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(USB_MSC_PACKET_SIZE), + HIBYTE(USB_MSC_PACKET_SIZE), + 0x00, /*Polling interval in milliseconds*/ + /* 07 bytes */ + +}; + +#if defined (__ICCARM__) /*!< IAR Compiler */ +#pragma data_alignment = 4 +#endif +/* USB Standard Device Descriptor */ +uint8_t USBD_MSC_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] = { + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + USB_MAX_PACKET_SIZE, + 0x01, + 0x00, +}; + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + + +uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); + +uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); + +/** + * @} + */ + + +/** @defgroup USBD_MSC_CDC_Private_Macros + * @{ + */ + +/** + * @} + */ + + + +/** @defgroup USBD_CDC_Private_FunctionPrototypes + * @{ + */ + + +uint8_t USBD_CDC_EP_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +uint8_t USBD_CDC_EP_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); + +uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); + +uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev); + + + +/** @defgroup USBD_MSC_CDC_Private_FunctionPrototypes + * @{ + */ + + +static uint8_t USBD_MSC_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +static uint8_t USBD_MSC_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +static uint8_t USBD_MSC_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +static uint8_t USBD_MSC_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_MSC_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t *USBD_MSC_CDC_GetFSCfgDesc(uint16_t *length); + +static uint8_t *USBD_MSC_CDC_GetHSCfgDesc(uint16_t *length); + +static uint8_t *USBD_MSC_CDC_GetOtherSpeedCfgDesc(uint16_t *length); + +uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length); + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +/** + * @} + */ + +/** @defgroup USBD_MSC_CDC_Private_Variables + * @{ + */ + + +USBD_ClassTypeDef USBD_MSC_CDC_ClassDriver = { + USBD_MSC_CDC_Init, + USBD_MSC_CDC_DeInit, + USBD_MSC_CDC_Setup, + NULL, //USBD_MSC_CDC_EP0_TxReady, + USBD_CDC_EP0_RxReady, + USBD_MSC_CDC_DataIn, + USBD_MSC_CDC_DataOut, + NULL, //USBD_MSC_CDC_SOF, + NULL, //USBD_MSC_CDC_IsoINIncomplete, + NULL, //USBD_MSC_CDC_IsoOutIncomplete, + USBD_MSC_CDC_GetHSCfgDesc, + USBD_MSC_CDC_GetFSCfgDesc, + USBD_MSC_CDC_GetOtherSpeedCfgDesc, + USBD_CDC_GetDeviceQualifierDescriptor, +}; + + + + +/** @defgroup MSC_CORE_Private_Functions + * @{ + */ + +/** + * @brief USBD_MSC_Init + * Initialize the mass storage configuration + * @param pdev: device instance + * @param cfgidx: configuration index + * @retval status + */ +uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + if (pdev->dev_speed == USBD_SPEED_HIGH) { + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); + pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U; + + /* Open EP IN */ + USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); + pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U; + } else { + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); + pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U; + + /* Open EP IN */ + USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); + pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U; + } + pdev->pClassDataMSC = USBD_malloc(sizeof(USBD_MSC_BOT_HandleTypeDef)); + + if (pdev->pClassDataMSC == NULL) { + return USBD_FAIL; + } + + /* Init the BOT layer */ + MSC_BOT_Init(pdev); + + return USBD_OK; +} + +/** + * @brief USBD_MSC_DeInit + * DeInitilaize the mass storage configuration + * @param pdev: device instance + * @param cfgidx: configuration index + * @retval status + */ +uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + /* Close MSC EPs */ + USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR); + pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 0U; + + /* Close EP IN */ + USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR); + pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 0U; + + /* De-Init the BOT layer */ + MSC_BOT_DeInit(pdev); + + /* Free MSC Class Resources */ + if (pdev->pClassDataMSC != NULL) { + USBD_free(pdev->pClassDataMSC); + pdev->pClassDataMSC = NULL; + } + return USBD_OK; +} + + +/** +* @brief USBD_MSC_DataIn +* handle data IN Stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + MSC_BOT_DataIn(pdev, epnum); + return USBD_OK; +} + +/** +* @brief USBD_MSC_DataOut +* handle data OUT Stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + MSC_BOT_DataOut(pdev, epnum); + return USBD_OK; +} + +/** @defgroup USBD_CDC_Private_Functions + * @{ + */ + +/** + * @brief USBD_CDC_Init + * Initialize the CDC interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + uint8_t ret = 0U; + UNUSED(cfgidx); + USBD_CDC_HandleTypeDef *hcdc; + + if (pdev->dev_speed == USBD_SPEED_HIGH) { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, + CDC_DATA_HS_IN_PACKET_SIZE); + + pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, + CDC_DATA_HS_OUT_PACKET_SIZE); + + pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + + } else { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, + CDC_DATA_FS_IN_PACKET_SIZE); + + pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, + CDC_DATA_FS_OUT_PACKET_SIZE); + + pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + } + /* Open Command IN EP */ + USBD_LL_OpenEP(pdev, CDC_CMD_EP, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE); + pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U; + + pdev->pClassDataCDC = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); + + if (pdev->pClassDataCDC == NULL) { + ret = 1U; + } else { + hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassDataCDC; + + /* Init physical Interface components */ + ((USBD_CDC_ItfTypeDef *)pdev->pClassSpecificInterfaceCDC)->Init(); + + /* Init Xfer states */ + hcdc->TxState = 0U; + hcdc->RxState = 0U; + + if (pdev->dev_speed == USBD_SPEED_HIGH) { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, + CDC_DATA_HS_OUT_PACKET_SIZE); + } else { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); + } + } + return ret; +} + +/** + * @brief USBD_CDC_Init + * DeInitialize the CDC layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + uint8_t ret = 0U; + UNUSED(cfgidx); + + /* Close EP IN */ + USBD_LL_CloseEP(pdev, CDC_IN_EP); + pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U; + + /* Close EP OUT */ + USBD_LL_CloseEP(pdev, CDC_OUT_EP); + pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 0U; + + /* Close Command IN EP */ + USBD_LL_CloseEP(pdev, CDC_CMD_EP); + pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U; + + /* DeInit physical Interface components */ + if (pdev->pClassDataCDC != NULL) { + ((USBD_CDC_ItfTypeDef *)pdev->pClassSpecificInterfaceCDC)->DeInit(); + USBD_free(pdev->pClassDataCDC); + pdev->pClassDataCDC = NULL; + } + + return ret; +} + +/** + * @brief USBD_CDC_Setup + * Handle the CDC specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassDataCDC; + uint8_t ifalt = 0U; + uint16_t status_info = 0U; + uint8_t ret = USBD_OK; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) { + case USB_REQ_TYPE_CLASS : + if (req->wLength) { + if (req->bmRequest & 0x80U) { + ((USBD_CDC_ItfTypeDef *)pdev->pClassSpecificInterfaceCDC)->Control(req->bRequest, + (uint8_t *)(void *)hcdc->data, + req->wLength); + + USBD_CtlSendData(pdev, (uint8_t *)(void *)hcdc->data, req->wLength); + } else { + + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)req->wLength; + + USBD_CtlPrepareRx(pdev, (uint8_t *)(void *)hcdc->data, req->wLength); + } + } else { + ((USBD_CDC_ItfTypeDef *)pdev->pClassSpecificInterfaceCDC)->Control(req->bRequest, + (uint8_t *)(void *)req, 0U); + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U); + } else { + + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + USBD_CtlSendData(pdev, &ifalt, 1U); + } else { + + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state != USBD_STATE_CONFIGURED) { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + + return ret; +} + +/** + * @brief USBD_CDC_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCDC; + PCD_HandleTypeDef *hpcd = pdev->pPCDHandle; + USBD_CDC_ItfTypeDef *ctrl = (USBD_CDC_ItfTypeDef *)pdev->pClassSpecificInterfaceCDC; + + if (pdev->pClassDataCDC != NULL) { + if ((pdev->ep_in[epnum].total_length > 0U) && ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) { + /* Update the packet total length */ + pdev->ep_in[epnum].total_length = 0U; + + /* Send ZLP */ + USBD_LL_Transmit(pdev, epnum, NULL, 0U); + } else { + hcdc->TxState = 0U; + if (ctrl->Transferred) { + ctrl->Transferred(); + } + } + return USBD_OK; + } else { + return USBD_FAIL; + } +} + +/** + * @brief USBD_CDC_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassDataCDC; + + /* Get the received data length */ + hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum); + + /* USB data will be immediately processed, this allow next USB traffic being + NAKed till the end of the application Xfer */ + if (pdev->pClassDataCDC != NULL) { + ((USBD_CDC_ItfTypeDef *)pdev->pClassSpecificInterfaceCDC)->Receive(hcdc->RxBuffer, &hcdc->RxLength); + + return USBD_OK; + } else { + return USBD_FAIL; + } +} + +/** + * @brief USBD_CDC_EP0_RxReady + * Handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassDataCDC; + + if ((pdev->pClassSpecificInterfaceCDC != NULL) && (hcdc->CmdOpCode != 0xFFU)) { + ((USBD_CDC_ItfTypeDef *)pdev->pClassSpecificInterfaceCDC)->Control(hcdc->CmdOpCode, + (uint8_t *)(void *)hcdc->data, + (uint16_t)hcdc->CmdLength); + hcdc->CmdOpCode = 0xFFU; + + } + return USBD_OK; +} + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) +{ + *length = sizeof(USBD_CDC_DeviceQualifierDesc); + return USBD_CDC_DeviceQualifierDesc; +} + +/** +* @brief USBD_CDC_RegisterInterface + * @param pdev: device instance + * @param fops: CD Interface callback + * @retval status + */ +uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CDC_ItfTypeDef *fops) +{ + uint8_t ret = USBD_FAIL; + + if (fops != NULL) { + pdev->pClassSpecificInterfaceCDC = fops; + ret = USBD_OK; + } + + return ret; +} + +/** + * @brief USBD_CDC_SetTxBuffer + * @param pdev: device instance + * @param pbuff: Tx Buffer + * @retval status + */ +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff, + uint16_t length) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassDataCDC; + + hcdc->TxBuffer = pbuff; + hcdc->TxLength = length; + + return USBD_OK; +} + + +/** + * @brief USBD_CDC_SetRxBuffer + * @param pdev: device instance + * @param pbuff: Rx Buffer + * @retval status + */ +uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassDataCDC; + + hcdc->RxBuffer = pbuff; + + return USBD_OK; +} + +/** + * @brief USBD_CDC_TransmitPacket + * Transmit packet on IN endpoint + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassDataCDC; + + if (pdev->pClassDataCDC != NULL) { + if (hcdc->TxState == 0U) { + /* Tx Transfer in progress */ + hcdc->TxState = 1U; + + /* Update the packet total length */ + pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength; + + /* Transmit next packet */ + USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer, + (uint16_t)hcdc->TxLength); + + return USBD_OK; + } else { + return USBD_BUSY; + } + } else { + return USBD_FAIL; + } +} + + +/** + * @brief USBD_CDC_ReceivePacket + * prepare OUT Endpoint for reception + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassDataCDC; + + /* Suspend or Resume USB Out process */ + if (pdev->pClassDataCDC != NULL) { + if (pdev->dev_speed == USBD_SPEED_HIGH) { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + CDC_OUT_EP, + hcdc->RxBuffer, + CDC_DATA_HS_OUT_PACKET_SIZE); + } else { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + CDC_OUT_EP, + hcdc->RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); + } + return USBD_OK; + } else { + return USBD_FAIL; + } +} + +/** + * @} + */ + +/** @defgroup USBD_MSC_CDC_Private_Functions + * @{ + */ + +/** + * @brief USBD_MSC_CDC_Init + * Initialize the MSC+CDC interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_MSC_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + /* CDC initialization */ + uint8_t ret = USBD_CDC_Init(pdev, cfgidx); + if (ret != 0) { + return ret; + } + pdev->pClassDataMSC = USBD_malloc(sizeof(USBD_MSC_BOT_HandleTypeDef)); + + /* MSC initialization */ + ret = USBD_MSC_Init(pdev, cfgidx); + if (ret != 0) { + return ret; + } + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, USB_MAX_PACKET_SIZE); + + /* Open EP IN */ + USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, USB_MAX_PACKET_SIZE); + + + /* Init the BOT layer */ + MSC_BOT_Init(pdev); + ret = 0; + + return ret; +} + +/** + * @brief USBD_MSC_CDC_DeInit + * DeInitialize the MSC+CDC layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_MSC_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + /* MSC De-initialization */ + USBD_MSC_DeInit(pdev, cfgidx); + + /* CDC De-initialization */ + USBD_CDC_DeInit(pdev, cfgidx); + + return USBD_OK; +} + + +/** +* @brief USBD_MSC_Setup +* Handle the MSC specific requests +* @param pdev: device instance +* @param req: USB request +* @retval status +*/ +uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassDataMSC; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) { + + /* Class request */ + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) { + case BOT_GET_MAX_LUN : + + if ((req->wValue == 0) && + (req->wLength == 1) && + ((req->bmRequest & 0x80) == 0x80)) { + hmsc->max_lun = pdev->pClassSpecificInterfaceMSC->GetMaxLun(); + USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1); + } else { + + USBD_CtlError(pdev, req); + return USBD_FAIL; + } + break; + + case BOT_RESET : + if ((req->wValue == 0) && + (req->wLength == 0) && + ((req->bmRequest & 0x80) != 0x80)) { + MSC_BOT_Reset(pdev); + } else { + + USBD_CtlError(pdev, req); + return USBD_FAIL; + } + break; + + default: + USBD_CtlError(pdev, req); + return USBD_FAIL; + } + break; + /* Interface & Endpoint request */ + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData(pdev, (uint8_t *)&hmsc->interface, 1); + break; + + case USB_REQ_SET_INTERFACE : + hmsc->interface = (uint8_t)(req->wValue); + break; + + case USB_REQ_CLEAR_FEATURE: + + /* Flush the FIFO and Clear the stall status */ + USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex); + + /* Reactivate the EP */ + USBD_LL_CloseEP(pdev, (uint8_t)req->wIndex); + if ((((uint8_t)req->wIndex) & 0x80) == 0x80) { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, USB_MAX_PACKET_SIZE); + } else { + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, USB_MAX_PACKET_SIZE); + } + + /* Handle BOT error */ + MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); + break; + + } + break; + + default: + break; + } + return 0; +} + +/** + * @brief USBD_MSC_CDC_Setup + * Handle the MSC+CDC specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +uint8_t USBD_MSC_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + // Route requests to MSC interface or its endpoints to MSC class implementaion + if (((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE && req->wIndex == MSC_INTERFACE_IDX) || + ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_ENDPOINT && ((req->wIndex & 0x7F) == MSC_EP_IDX))) { + return USBD_MSC_Setup(pdev, req); + } + + return USBD_CDC_Setup(pdev, req); +} + +/** + * @brief USBD_MSC_CDC_DataIn + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_MSC_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + if (epnum == MSC_EP_IDX) { + return USBD_MSC_DataIn(pdev, epnum); + } + return USBD_CDC_DataIn(pdev, epnum); +} + +/** + * @brief USBD_MSC_CDC_DataOut + * handle data OUT Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_MSC_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + if (epnum == MSC_EPOUT_ADDR) { + return USBD_MSC_DataOut(pdev, epnum); + } + return USBD_CDC_DataOut(pdev, epnum); +} + +////////////////////////////////////////////////////////////// +// HS +////////////////////////////////////////////////////////////// + + + +/** + * @brief USBD_MSC_CDC_GetFSCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_MSC_CDC_GetFSCfgDesc(uint16_t *length) +{ + *length = sizeof(USBD_MSC_CDC_FSCfgDesc); + return USBD_MSC_CDC_FSCfgDesc; +} + +/** + * @brief USBD_MSC_CDC_GetHSCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_MSC_CDC_GetHSCfgDesc(uint16_t *length) +{ + *length = sizeof(USBD_MSC_CDC_HSCfgDesc); + return USBD_MSC_CDC_HSCfgDesc; +} + +/** + * @brief USBD_MSC_CDC_GetOtherSpeedCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_MSC_CDC_GetOtherSpeedCfgDesc(uint16_t *length) +{ + *length = sizeof(USBD_MSC_CDC_OtherSpeedCfgDesc); + return USBD_MSC_CDC_OtherSpeedCfgDesc; +} + +#endif /* USBCON && USBD_USE_CDC_COMPOSITE */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc.h b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc.h new file mode 100644 index 0000000000..28341c57df --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc.h @@ -0,0 +1,133 @@ +/** + ****************************************************************************** + * @file usbd_msc.h + * @author MCD Application Team + * @brief Header for the usbd_msc.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, 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/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_H +#define __USBD_MSC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_cdc_composite_bot.h" +#include "usbd_msc_scsi.h" +#include "usbd_ioreq.h" +//#include "usbd_core.h" + +/** @addtogroup USBD_MSC_BOT + * @{ + */ + +/** @defgroup USBD_MSC + * @brief This file is the Header file for usbd_msc.c + * @{ + */ + + +/** @defgroup USBD_BOT_Exported_Defines + * @{ + */ +/* MSC Class Config */ +#ifndef MSC_MEDIA_PACKET +#define MSC_MEDIA_PACKET 64 // 512U +#endif /* MSC_MEDIA_PACKET */ + +#define MSC_MAX_FS_PACKET 0x40U +#define MSC_MAX_HS_PACKET 0x200U + +#define BOT_GET_MAX_LUN 0xFE +#define BOT_RESET 0xFF +#define USB_MSC_CONFIG_DESC_SIZ 32 + + +#define MSC_EPIN_ADDR 0x83U +#define MSC_EPOUT_ADDR 0x03U + +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Types + * @{ + */ + +// forward declarations +struct _USBD_MSC_BOT_CBWTypeDef; +struct _USBD_MSC_BOT_CSWTypeDef; +struct _SENSE_ITEM; // USBD_SCSI_SenseTypeDef + +typedef struct _USBD_STORAGE { + int8_t (* Init)(uint8_t lun); + int8_t (* GetCapacity)(uint8_t lun, uint32_t *block_num, uint16_t *block_size); + int8_t (* IsReady)(uint8_t lun); + int8_t (* IsWriteProtected)(uint8_t lun); + int8_t (* Read)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + int8_t (* GetMaxLun)(void); + int8_t *pInquiry; + +} USBD_StorageTypeDef; + + +typedef struct _USBD_MSC_BOT_HandleTypeDef { + uint32_t max_lun; + uint32_t interface; + uint8_t bot_state; + uint8_t bot_status; + uint16_t bot_data_length; + uint8_t bot_data[MSC_MEDIA_PACKET]; + struct _USBD_MSC_BOT_CBWTypeDef cbw; + struct _USBD_MSC_BOT_CSWTypeDef csw; + + struct _SENSE_ITEM scsi_sense [SENSE_LIST_DEEPTH]; // USBD_SCSI_SenseTypeDef + uint8_t scsi_sense_head; + uint8_t scsi_sense_tail; + + uint16_t scsi_blk_size; + uint32_t scsi_blk_nbr; + + uint32_t scsi_blk_addr; + uint32_t scsi_blk_len; +} USBD_MSC_BOT_HandleTypeDef; + +/* Structure for MSC process */ +extern USBD_ClassTypeDef USBD_MSC; +#define USBD_MSC_CLASS &USBD_MSC + +uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, + USBD_StorageTypeDef *fops); +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MSC_H */ +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_bot.h b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_bot.h new file mode 100644 index 0000000000..09158f668d --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_bot.h @@ -0,0 +1,143 @@ +/** + ****************************************************************************** + * @file usbd_msc_bot.h + * @author MCD Application Team + * @brief Header for the usbd_msc_bot.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, 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/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_BOT_H +#define __USBD_MSC_BOT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup MSC_BOT + * @brief This file is the Header file for usbd_msc_bot.c + * @{ + */ + + +/** @defgroup USBD_CORE_Exported_Defines + * @{ + */ +#define USBD_BOT_IDLE 0U /* Idle state */ +#define USBD_BOT_DATA_OUT 1U /* Data Out state */ +#define USBD_BOT_DATA_IN 2U /* Data In state */ +#define USBD_BOT_LAST_DATA_IN 3U /* Last Data In Last */ +#define USBD_BOT_SEND_DATA 4U /* Send Immediate data */ +#define USBD_BOT_NO_DATA 5U /* No data Stage */ + +#define USBD_BOT_CBW_SIGNATURE 0x43425355U +#define USBD_BOT_CSW_SIGNATURE 0x53425355U +#define USBD_BOT_CBW_LENGTH 31U +#define USBD_BOT_CSW_LENGTH 13U +#define USBD_BOT_MAX_DATA 256U + +/* CSW Status Definitions */ +#define USBD_CSW_CMD_PASSED 0x00U +#define USBD_CSW_CMD_FAILED 0x01U +#define USBD_CSW_PHASE_ERROR 0x02U + +/* BOT Status */ +#define USBD_BOT_STATUS_NORMAL 0U +#define USBD_BOT_STATUS_RECOVERY 1U +#define USBD_BOT_STATUS_ERROR 2U + + +#define USBD_DIR_IN 0U +#define USBD_DIR_OUT 1U +#define USBD_BOTH_DIR 2U + +/** + * @} + */ + +/** @defgroup MSC_CORE_Private_TypesDefinitions + * @{ + */ + +typedef struct { + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataLength; + uint8_t bmFlags; + uint8_t bLUN; + uint8_t bCBLength; + uint8_t CB[16]; + uint8_t ReservedForAlign; +} USBD_MSC_BOT_CBWTypeDef; + + +typedef struct { + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataResidue; + uint8_t bStatus; + uint8_t ReservedForAlign[3]; +} USBD_MSC_BOT_CSWTypeDef; + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_Types + * @{ + */ + +/** + * @} + */ +/** @defgroup USBD_CORE_Exported_FunctionsPrototypes + * @{ + */ +void MSC_BOT_Init(USBD_HandleTypeDef *pdev); +void MSC_BOT_Reset(USBD_HandleTypeDef *pdev); +void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev); +void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); + +void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); + +void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status); + +void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MSC_BOT_H */ +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite.h b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite.h new file mode 100644 index 0000000000..16c05b64e7 --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite.h @@ -0,0 +1,195 @@ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_MSC_CDC_COMPOSITE_H +#define __USB_MSC_CDC_COMPOSITE_H + + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +//#include "usbd_ioreq.h" +#include "usbd_core.h" +#include "usbd_msc_scsi.h" +#include "usbd_msc_cdc_composite_bot.h" +#include "cdc_queue.h" +#include + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_MSC_CDC_Exported_Defines + * @{ + */ + +typedef enum { + MSC_UNLOCKED = 0U, + MSC_USB_LOCK = 1U, + MSC_BOOT_LOCK = 2U, + MSC_APP1_LOCK = 3U, + MSC_APP2_LOCK = 4U, + MSC_APP3_LOCK = 5U, + MSC_APP4_LOCK = 6U, +} MSC_lock_typedef; + +extern MSC_lock_typedef MSC_lock_byte; +#define MSC_LOCK // let the world know there is a MSC lock mechanism + +// endpoints numbers +#define MSC_EP_IDX 0x01 // only EP 0, EP 1 & EP 2 are bidirectional +#define CDC_CMD_EP_IDX 0x03 // unable to determine why EP 3 will not transmit + +//#define MSC_EP_IDX 0x03 // only EP 0, EP 1 & EP 2 are bidirectional +//#define CDC_CMD_EP_IDX 0x01 // unable to determine why EP 3 will not transmit +#define CDC_EP_IDX 0x02 // EP 3 can receive data from the host because there + +//#define MSC_INTERFACE_IDX 0x2 // Index of MSC interface +//#define CDC_INTERFACE_IDX 0x0 // Index of CDC interface +#define MSC_INTERFACE_IDX MSC_EP_IDX // Index of MSC interface +#define CDC_INTERFACE_IDX CDC_EP_IDX // Index of CDC interface + +#define IN_EP_DIR 0x80 // Adds a direction bit + +#define MSC_OUT_EP MSC_EP_IDX /* EP1 for BULK OUT */ +#define MSC_IN_EP (MSC_EP_IDX | IN_EP_DIR) /* EP1 for BULK IN */ + +#ifdef CDC_CMD_EP +#undef CDC_CMD_EP +#endif +#define CDC_CMD_EP (CDC_CMD_EP_IDX| IN_EP_DIR) /* EP3 for CDC commands */ + +#ifdef CDC_OUT_EP +#undef CDC_OUT_EP +#endif +#define CDC_OUT_EP CDC_EP_IDX /* EP2 for data OUT */ + +#ifdef CDC_IN_EP +#undef CDC_IN_EP +#endif +#define CDC_IN_EP (CDC_EP_IDX | IN_EP_DIR) /* EP2 for data IN */ + +#ifdef USB_MAX_PACKET_SIZE +#undef USB_MAX_PACKET_SIZE +#endif +#define USB_MAX_PACKET_SIZE USB_MAX_EP0_SIZE + +#ifdef CDC_CMD_PACKET_SIZE +#undef CDC_CMD_PACKET_SIZE +#endif +#define CDC_CMD_PACKET_SIZE 0x0010 // 8 /* Control Endpoint Packet size */ + +#ifdef CDC_DATA_PACKET_SIZE +#undef CDC_DATA_PACKET_SIZE +#endif +#define CDC_DATA_PACKET_SIZE USB_MAX_PACKET_SIZE + +#define USB_MSC_PACKET_SIZE 64 + + + +/** @addtogroup USBD_MSC_BOT + * @{ + */ + +/** @defgroup USBD_MSC + * @brief This file is the Header file for usbd_msc.c + * @{ + */ + + +/** @defgroup USBD_BOT_Exported_Defines + * @{ + */ +/* MSC Class Config */ +#ifndef MSC_MEDIA_PACKET +#define MSC_MEDIA_PACKET 8192 +#endif /* MSC_MEDIA_PACKET */ + +#define MSC_MAX_FS_PACKET 0x40U +#define MSC_MAX_HS_PACKET 0x200U + +#define BOT_GET_MAX_LUN 0xFE +#define BOT_RESET 0xFF +#define USB_MSC_CONFIG_DESC_SIZ 32 + + +#define MSC_EPIN_ADDR MSC_IN_EP +#define MSC_EPOUT_ADDR MSC_OUT_EP + +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Types + * @{ + */ + +// forward declarations +//struct _USBD_MSC_BOT_CBWTypeDef; +//struct _USBD_MSC_BOT_CSWTypeDef; +struct _SENSE_ITEM; // USBD_SCSI_SenseTypeDef + +typedef struct _USBD_STORAGE { + int8_t (* Init)(uint8_t lun); + int8_t (* GetCapacity)(uint8_t lun, uint32_t *block_num, uint16_t *block_size); + int8_t (* IsReady)(uint8_t lun); + int8_t (* IsWriteProtected)(uint8_t lun); + int8_t (* Read)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + int8_t (* GetMaxLun)(void); + int8_t *pInquiry; + +} USBD_StorageTypeDef; + + +typedef struct _USBD_MSC_BOT_HandleTypeDef { + uint32_t max_lun; + uint32_t interface; + uint8_t bot_state; + uint8_t bot_status; + uint16_t bot_data_length; + uint8_t bot_data[MSC_MEDIA_PACKET]; + USBD_MSC_BOT_CBWTypeDef cbw; + USBD_MSC_BOT_CSWTypeDef csw; + + struct _SENSE_ITEM scsi_sense [SENSE_LIST_DEEPTH]; // USBD_SCSI_SenseTypeDef + uint8_t scsi_sense_head; + uint8_t scsi_sense_tail; + + uint16_t scsi_blk_size; + uint32_t scsi_blk_nbr; + + uint32_t scsi_blk_addr; + uint32_t scsi_blk_len; +} USBD_MSC_BOT_HandleTypeDef; + +/* Structure for MSC process */ +extern USBD_ClassTypeDef USBD_MSC; +#define USBD_MSC_CLASS &USBD_MSC + +uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, + USBD_StorageTypeDef *fops); +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_MSC_CDC_COMPOSITE_H */ +/** + * @} + */ + +/** + * @} + */ diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite_bot.h b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite_bot.h new file mode 100644 index 0000000000..38def15ae7 --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite_bot.h @@ -0,0 +1,142 @@ +/** + ****************************************************************************** + * @file usbd_msc_bot.h + * @author MCD Application Team + * @brief Header for the usbd_msc_bot.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, 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/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_BOT_H +#define __USBD_MSC_BOT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup MSC_BOT + * @brief This file is the Header file for usbd_msc_bot.c + * @{ + */ + + +/** @defgroup USBD_CORE_Exported_Defines + * @{ + */ +#define USBD_BOT_IDLE 0U /* Idle state */ +#define USBD_BOT_DATA_OUT 1U /* Data Out state */ +#define USBD_BOT_DATA_IN 2U /* Data In state */ +#define USBD_BOT_LAST_DATA_IN 3U /* Last Data In Last */ +#define USBD_BOT_SEND_DATA 4U /* Send Immediate data */ +#define USBD_BOT_NO_DATA 5U /* No data Stage */ + +#define USBD_BOT_CBW_SIGNATURE 0x43425355U +#define USBD_BOT_CSW_SIGNATURE 0x53425355U +#define USBD_BOT_CBW_LENGTH 31U +#define USBD_BOT_CSW_LENGTH 13U +#define USBD_BOT_MAX_DATA 256U + +/* CSW Status Definitions */ +#define USBD_CSW_CMD_PASSED 0x00U +#define USBD_CSW_CMD_FAILED 0x01U +#define USBD_CSW_PHASE_ERROR 0x02U + +/* BOT Status */ +#define USBD_BOT_STATUS_NORMAL 0U +#define USBD_BOT_STATUS_RECOVERY 1U +#define USBD_BOT_STATUS_ERROR 2U + + +#define USBD_DIR_IN 0U +#define USBD_DIR_OUT 1U +#define USBD_BOTH_DIR 2U + +/** + * @} + */ + +/** @defgroup MSC_CORE_Private_TypesDefinitions + * @{ + */ + +typedef struct _USBD_MSC_BOT_CBWTypeDef { + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataLength; + uint8_t bmFlags; + uint8_t bLUN; + uint8_t bCBLength; + uint8_t CB[16]; + uint8_t _ReservedForAlign; +} USBD_MSC_BOT_CBWTypeDef; + + +typedef struct _USBD_MSC_BOT_CSWTypeDef { + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataResidue; + uint8_t bStatus; + uint8_t ReservedForAlign[3]; +} USBD_MSC_BOT_CSWTypeDef; + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_Types + * @{ + */ + +/** + * @} + */ +/** @defgroup USBD_CORE_Exported_FunctionsPrototypes + * @{ + */ +void MSC_BOT_Init(USBD_HandleTypeDef *pdev); +void MSC_BOT_Reset(USBD_HandleTypeDef *pdev); +void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev); +void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); + +void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); + +void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status); + +void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MSC_BOT_H */ +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite_if.c b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite_if.c new file mode 100644 index 0000000000..c5901aa9d7 --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_cdc_composite_if.c @@ -0,0 +1,379 @@ +/** + ****************************************************************************** + * @file usbd_cdc_if.c + * @author MCD Application Team + * @brief Generic media access Layer. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, 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/SLA0044 + * + ****************************************************************************** + */ + +#ifdef USBCON +#ifdef USBD_USE_CDC_COMPOSITE + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_desc.h" +#include "usbd_cdc_if.h" +#include "usbd_def.h" +#include "usbd_msc_cdc_composite.h" + + +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint16_t length); +uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev); +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); + + +#ifdef USE_USB_HS +#define CDC_MAX_PACKET_SIZE USB_OTG_HS_MAX_PACKET_SIZE +#elif defined(USB_OTG_FS) || defined(USB_OTG_FS_MAX_PACKET_SIZE) +#define CDC_MAX_PACKET_SIZE USB_OTG_FS_MAX_PACKET_SIZE +#else /* USB */ +#define CDC_MAX_PACKET_SIZE USB_MAX_EP0_SIZE +#endif + +/* USBD_CDC Private Variables */ +/* USB Device Core CDC handle declaration */ +USBD_HandleTypeDef hUSBD_Device_CDC; + +static bool CDC_initialized = false; +static uint32_t transmitStart = 0; + +/* Received Data over USB are stored in this buffer */ +CDC_TransmitQueue_TypeDef TransmitQueue; +CDC_ReceiveQueue_TypeDef ReceiveQueue; +__IO uint32_t lineState = 0; +__IO bool receivePended = true; + + +/** USBD_CDC Private Function Prototypes */ + +static int8_t USBD_CDC_Init(void); +static int8_t USBD_CDC_DeInit(void); +static int8_t USBD_CDC_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length); +static int8_t USBD_CDC_Receive(uint8_t *pbuf, uint32_t *Len); +static int8_t USBD_CDC_Transferred(void); + +USBD_CDC_ItfTypeDef USBD_CDC_fops = { + USBD_CDC_Init, + USBD_CDC_DeInit, + USBD_CDC_Control, + USBD_CDC_Receive, + USBD_CDC_Transferred +}; + +USBD_CDC_LineCodingTypeDef linecoding = { + 250000, /* baud rate*/ + 0x00, /* stop bits-1*/ + 0x00, /* parity - none*/ + 0x08 /* nb. of bits 8*/ +}; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief USBD_CDC_Init + * Initializes 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 USBD_CDC_Init(void) +{ + + /* Set Application Buffers */ + CDC_TransmitQueue_Init(&TransmitQueue); + CDC_ReceiveQueue_Init(&ReceiveQueue); + receivePended = true; + USBD_CDC_SetRxBuffer(&hUSBD_Device_CDC, CDC_ReceiveQueue_ReserveBlock(&ReceiveQueue)); + + return (USBD_OK); +} + +/** + * @brief USBD_CDC_DeInit + * 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 USBD_CDC_DeInit(void) +{ + + return (USBD_OK); +} + + +/** + * @brief USBD_CDC_Control + * 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 USBD_CDC_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) +{ + UNUSED(length); + 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: + 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]; + 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; + + break; + + case CDC_SET_CONTROL_LINE_STATE: + lineState = + (((USBD_SetupReqTypedef *)pbuf)->wValue & 0x01) != 0; // Check DTR state + if (lineState) { // Reset the transmit timeout when the port is connected + transmitStart = 0; + } +#ifdef DTR_TOGGLING_SEQ + dtr_toggling++; /* Count DTR toggling */ +#endif + break; + + case CDC_SEND_BREAK: + break; + + default: + break; + } + + return (USBD_OK); +} + +/** + * @brief USBD_CDC_Receive + * Data received over USB OUT endpoint are sent over CDC interface + * through this function. + * + * @note + * This function will issue a NAK packet on any OUT packet received 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 USBD_CDC_Receive(uint8_t *Buf, uint32_t *Len) +{ + UNUSED(Buf); + /* It always contains required amount of free space for writing */ + CDC_ReceiveQueue_CommitBlock(&ReceiveQueue, (uint16_t)(*Len)); + receivePended = false; + /* If enough space in the queue for a full buffer then continue receive */ + CDC_resume_receive(); + return USBD_OK; +} + + +static int8_t USBD_CDC_Transferred(void) +{ + + CDC_TransmitQueue_CommitRead(&TransmitQueue); + CDC_continue_transmit(); + return (USBD_OK); +} + +#ifndef p_CDC_ClassData +#ifdef USBD_USE_CDC_COMPOSITE +#define p_CDC_ClassData pClassDataCDC +#else +#define p_CDC_ClassData pClassData +#endif +#endif + +/* + * The value USB_CDC_TRANSMIT_TIMEOUT is defined in terms of HAL_GetTick() units. + * Typically it is 1ms value. The timeout determines when we would consider the + * host "too slow" and threat the USB CDC port as disconnected. + */ +#ifndef USB_CDC_TRANSMIT_TIMEOUT +#define USB_CDC_TRANSMIT_TIMEOUT 0xffffffffll +#endif + +bool CDC_connected() +{ + /* Save the transmitStart value in a local variable to avoid twice reading - fix #478 */ + uint32_t transmitTime = transmitStart; + if (transmitTime) { + transmitTime = HAL_GetTick() - transmitTime; + } + + if (!(hUSBD_Device_CDC.dev_state == USBD_STATE_CONFIGURED)) { + return 0; } + if (!(transmitTime < USB_CDC_TRANSMIT_TIMEOUT)) { + return 0;} + if (!lineState) { + return 0;} + else { + return 1; } +} + + +void CDC_continue_transmit(void) +{ + + uint16_t size; + uint8_t *buffer; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) hUSBD_Device_CDC.p_CDC_ClassData; + /* + * TS: This method can be called both in the main thread + * (via USBSerial::write) and in the IRQ stream (via USBD_CDC_Transferred), + * BUT the main thread cannot pass this condition while waiting for a IRQ! + * This is not possible because TxState is not zero while waiting for data + * transfer ending! The IRQ thread is uninterrupted, since its priority + * is higher than that of the main thread. So this method is thread safe. + */ + if (hcdc->TxState == 0U) { + buffer = CDC_TransmitQueue_ReadBlock(&TransmitQueue, &size); + if (size > 0) { + transmitStart = HAL_GetTick(); + USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, buffer, size); + /* + * size never exceed PMA buffer and USBD_CDC_TransmitPacket make full + * copy of block in PMA, so no need to worry about buffer damage + */ + USBD_CDC_TransmitPacket(&hUSBD_Device_CDC); + } + } +} + +bool CDC_resume_receive(void) +{ + + /* + * TS: main and IRQ threads can't pass it at same time, because + * IRQ may occur only if receivePended is true. So it is thread-safe! + */ + if (!receivePended) { + uint8_t *block = CDC_ReceiveQueue_ReserveBlock(&ReceiveQueue); + if (block != NULL) { + receivePended = true; + /* Set new buffer */ + USBD_CDC_SetRxBuffer(&hUSBD_Device_CDC, block); + USBD_CDC_ReceivePacket(&hUSBD_Device_CDC); + return true; + } + } + return false; +} + +uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +extern USBD_ClassTypeDef USBD_MSC_CDC_ClassDriver; + +extern USBD_CDC_ItfTypeDef USBD_MSC_CDC_fops; +extern USBD_StorageTypeDef SdMscDriver; +uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_CDC_ItfTypeDef *fops); +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id); +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); +USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev); + +/** +* @brief USBD_MSC_RegisterStorage +* @param fops: storage callback +* @retval status +*/ +uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, + USBD_StorageTypeDef *fops) +{ + if (fops != NULL) { + pdev->pClassSpecificInterfaceMSC = fops; + } + return USBD_OK; +} + +void CDC_init(void) +{ + + if (!CDC_initialized) { + /* Init Device Library */ + USBD_Init(&hUSBD_Device_CDC, &CDC_Desc, 0); + /* Add Supported Class */ + USBD_RegisterClass(&hUSBD_Device_CDC, &USBD_MSC_CDC_ClassDriver); + /* Add CDC Interface Class */ + USBD_CDC_RegisterInterface(&hUSBD_Device_CDC, &USBD_CDC_fops); + /* Start SD card interface */ + USBD_MSC_RegisterStorage(&hUSBD_Device_CDC, &SdMscDriver); + /* Start Device Process */ + USBD_Start(&hUSBD_Device_CDC); + CDC_initialized = true; + } +} + +void CDC_deInit(void) +{ + + if (CDC_initialized) { + USBD_Stop(&hUSBD_Device_CDC); + USBD_MSC_DeInit(&hUSBD_Device_CDC, 1); + USBD_CDC_DeInit(); + USBD_DeInit(&hUSBD_Device_CDC); + CDC_initialized = false; + } +} + + +#endif /* USBD_USE_CDC_COMPOSITE */ +#endif /* USBCON */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite.h b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite.h new file mode 100644 index 0000000000..e0d50e4d1a --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite.h @@ -0,0 +1,73 @@ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_MSC_CDC_CORE_H +#define __USB_MSC_CDC_CORE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_MSC_CDC_Exported_Defines + * @{ + */ + + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_MSC_CDC_ClassDriver; +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_MSC_CDC_CORE_H */ +/** + * @} + */ + +/** + * @} + */ diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite_bot.c b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite_bot.c new file mode 100644 index 0000000000..27c399edb0 --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite_bot.c @@ -0,0 +1,409 @@ +/** + ****************************************************************************** + * @file usbd_msc_bot.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides all the BOT protocol core functions. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2015 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. + * + ****************************************************************************** + */ + +#if defined(USBCON) && defined(USBD_USE_CDC_COMPOSITE) + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" +#include "usbd_msc_cdc_composite_bot.h" +#include "usbd_msc_cdc_composite.h" +#include "usbd_msc_scsi.h" +#include "usbd_ioreq.h" +#include "usbd_msc_cdc_composite.h" + +int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd); +void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC); +USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint16_t len); +USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint16_t len); +USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint16_t len); +USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint16_t len); +USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev); +uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr); + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_BOT + * @brief BOT protocol module + * @{ + */ + +/** @defgroup MSC_BOT_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_FunctionPrototypes + * @{ + */ +static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev); + +static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len); + +static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev); +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Functions + * @{ + */ + + + +/** +* @brief MSC_BOT_Init +* Initialize the BOT Process +* @param pdev: device instance +* @retval None +*/ +void MSC_BOT_Init(USBD_HandleTypeDef *pdev) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassDataMSC; + + hmsc->bot_state = USBD_BOT_IDLE; + hmsc->bot_status = USBD_BOT_STATUS_NORMAL; + + hmsc->scsi_sense_tail = 0; + hmsc->scsi_sense_head = 0; + + pdev->pClassSpecificInterfaceMSC->Init(0); + + USBD_LL_FlushEP(pdev, MSC_OUT_EP); + USBD_LL_FlushEP(pdev, MSC_IN_EP); + + /* Prapare EP to Receive First BOT Cmd */ + USBD_LL_PrepareReceive(pdev, + MSC_OUT_EP, + (uint8_t *)(void *)&hmsc->cbw, + USBD_BOT_CBW_LENGTH); +} + +/** +* @brief MSC_BOT_Reset +* Reset the BOT Machine +* @param pdev: device instance +* @retval None +*/ +void MSC_BOT_Reset(USBD_HandleTypeDef *pdev) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassDataMSC; + + hmsc->bot_state = USBD_BOT_IDLE; + hmsc->bot_status = USBD_BOT_STATUS_RECOVERY; + + /* Prapare EP to Receive First BOT Cmd */ + USBD_LL_PrepareReceive(pdev, + MSC_OUT_EP, + (uint8_t *)(void *)&hmsc->cbw, + USBD_BOT_CBW_LENGTH); +} + +/** +* @brief MSC_BOT_DeInit +* Deinitialize the BOT Machine +* @param pdev: device instance +* @retval None +*/ +void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassDataMSC; + hmsc->bot_state = USBD_BOT_IDLE; +} + +/** +* @brief MSC_BOT_DataIn +* Handle BOT IN data stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval None +*/ +void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassDataMSC; + + switch (hmsc->bot_state) { + case USBD_BOT_DATA_IN: + if (SCSI_ProcessCmd(pdev, + hmsc->cbw.bLUN, + &hmsc->cbw.CB[0]) < 0) { + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED); + } + break; + + case USBD_BOT_SEND_DATA: + case USBD_BOT_LAST_DATA_IN: + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED); + + break; + + default: + break; + } +} +/** +* @brief MSC_BOT_DataOut +* Process MSC OUT data +* @param pdev: device instance +* @param epnum: endpoint index +* @retval None +*/ +void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassDataMSC; + + switch (hmsc->bot_state) { + case USBD_BOT_IDLE: + MSC_BOT_CBW_Decode(pdev); + break; + + case USBD_BOT_DATA_OUT: + + if (SCSI_ProcessCmd(pdev, + hmsc->cbw.bLUN, + &hmsc->cbw.CB[0]) < 0) { + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED); + } + + break; + + default: + break; + } +} + +/** +* @brief MSC_BOT_CBW_Decode +* Decode the CBW command and set the BOT state machine accordingly +* @param pdev: device instance +* @retval None +*/ +static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassDataMSC; + + hmsc->csw.dTag = hmsc->cbw.dTag; + hmsc->csw.dDataResidue = hmsc->cbw.dDataLength; + + if ((USBD_LL_GetRxDataSize(pdev, MSC_OUT_EP) != USBD_BOT_CBW_LENGTH) || + (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) || + (hmsc->cbw.bLUN > 1) || + (hmsc->cbw.bCBLength < 1) || + (hmsc->cbw.bCBLength > 16)) { + + SCSI_SenseCode(pdev, + hmsc->cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + + hmsc->bot_status = USBD_BOT_STATUS_ERROR; + MSC_BOT_Abort(pdev); + + } else { + if (SCSI_ProcessCmd(pdev, + hmsc->cbw.bLUN, + &hmsc->cbw.CB[0]) < 0) { + if (hmsc->bot_state == USBD_BOT_NO_DATA) { + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED); + } else { + + MSC_BOT_Abort(pdev); + } + } + /*Burst xfer handled internally*/ + else if ((hmsc->bot_state != USBD_BOT_DATA_IN) && + (hmsc->bot_state != USBD_BOT_DATA_OUT) && + (hmsc->bot_state != USBD_BOT_LAST_DATA_IN)) { + if (hmsc->bot_data_length > 0) { + MSC_BOT_SendData(pdev, + hmsc->bot_data, + hmsc->bot_data_length); + } else if (hmsc->bot_data_length == 0) { + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED); + } + else + { + MSC_BOT_Abort(pdev); + } + } + else + { + return; + } + } +} + +/** +* @brief MSC_BOT_SendData +* Send the requested data +* @param pdev: device instance +* @param buf: pointer to data buffer +* @param len: Data Length +* @retval None +*/ +static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassDataMSC; + + len = MIN(hmsc->cbw.dDataLength, len); + hmsc->csw.dDataResidue -= len; + hmsc->csw.bStatus = USBD_CSW_CMD_PASSED; + hmsc->bot_state = USBD_BOT_SEND_DATA; + + USBD_LL_Transmit(pdev, MSC_IN_EP, pbuf, len); +} + +/** +* @brief MSC_BOT_SendCSW +* Send the Command Status Wrapper +* @param pdev: device instance +* @param status : CSW status +* @retval None +*/ +void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, + uint8_t CSW_Status) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassDataMSC; + + hmsc->csw.dSignature = USBD_BOT_CSW_SIGNATURE; + hmsc->csw.bStatus = CSW_Status; + hmsc->bot_state = USBD_BOT_IDLE; + + USBD_LL_Transmit(pdev, + MSC_IN_EP, + (uint8_t *)(void *)&hmsc->csw, + USBD_BOT_CSW_LENGTH); + + /* Prepare EP to Receive next Cmd */ + USBD_LL_PrepareReceive(pdev, + MSC_OUT_EP, + (uint8_t *)(void *)&hmsc->cbw, + USBD_BOT_CBW_LENGTH); + +} + +/** +* @brief MSC_BOT_Abort +* Abort the current transfer +* @param pdev: device instance +* @retval status +*/ + +static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassDataMSC; + + if ((hmsc->cbw.bmFlags == 0) && + (hmsc->cbw.dDataLength != 0) && + (hmsc->bot_status == USBD_BOT_STATUS_NORMAL)) { + USBD_LL_StallEP(pdev, MSC_OUT_EP); + } + USBD_LL_StallEP(pdev, MSC_IN_EP); + + if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) { + USBD_LL_PrepareReceive(pdev, + MSC_OUT_EP, + (uint8_t *)(void *)&hmsc->cbw, + USBD_BOT_CBW_LENGTH); + } +} + +/** +* @brief MSC_BOT_CplClrFeature +* Complete the clear feature request +* @param pdev: device instance +* @param epnum: endpoint index +* @retval None +*/ + +void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassDataMSC; + + if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) { /* Bad CBW Signature */ + + USBD_LL_StallEP(pdev, MSC_IN_EP); + hmsc->bot_status = USBD_BOT_STATUS_NORMAL; + } else if (((epnum & 0x80) == 0x80) && (hmsc->bot_status != USBD_BOT_STATUS_RECOVERY)) { + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED); + } + +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +#endif // USBCON & USBD_USE_CDC_COMPOSITE + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite_scsi.c b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite_scsi.c new file mode 100644 index 0000000000..9f27355636 --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_composite_scsi.c @@ -0,0 +1,678 @@ +/** + ****************************************************************************** + * @file usbd_msc_scsi.c + * @author MCD Application Team + * @brief This file provides all the USBD SCSI layer functions. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, 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/SLA0044 + * + ****************************************************************************** + */ + +/* BSPDependencies +- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c" +- "stm32xxxxx_{eval}{discovery}_io.c" +- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c" +EndBSPDependencies */ + +#ifdef USBD_USE_CDC_COMPOSITE + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" +#include "usbd_msc_cdc_composite_bot.h" +#include "usbd_msc_scsi.h" +#include "usbd_msc_cdc_composite.h" +#include "usbd_msc_data.h" + +void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC); + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_SCSI + * @brief Mass storage SCSI layer module + * @{ + */ + +/** @defgroup MSC_SCSI_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_FunctionPrototypes + * @{ + */ +static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, + uint32_t blk_offset, uint32_t blk_nbr); + +static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun); +static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun); +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Functions + * @{ + */ + + +/** +* @brief SCSI_ProcessCmd +* Process SCSI commands +* @param pdev: device instance +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd) +{ + + switch (cmd[0]) { + case SCSI_TEST_UNIT_READY: // 0x00 + SCSI_TestUnitReady(pdev, lun, cmd); + break; + + case SCSI_REQUEST_SENSE: // 0x03 + SCSI_RequestSense(pdev, lun, cmd); + break; + + case SCSI_INQUIRY: // 0x12U 18 + SCSI_Inquiry(pdev, lun, cmd); + break; + + case SCSI_START_STOP_UNIT: // 0x1BU 27 + SCSI_StartStopUnit(pdev, lun, cmd); + break; + + case SCSI_ALLOW_MEDIUM_REMOVAL: // 0x1EU 30 + SCSI_StartStopUnit(pdev, lun, cmd); + break; + + case SCSI_MODE_SENSE6: // 0x1AU 26 + SCSI_ModeSense6(pdev, lun, cmd); + break; + + case SCSI_MODE_SENSE10: // 0x5AU 90 + SCSI_ModeSense10(pdev, lun, cmd); + break; + + case SCSI_READ_FORMAT_CAPACITIES: // 0x23U 35 + SCSI_ReadFormatCapacity(pdev, lun, cmd); + break; + + case SCSI_READ_CAPACITY10: // 0x25U 37 + SCSI_ReadCapacity10(pdev, lun, cmd); + break; + + case SCSI_READ10: // 0x28U 40 + SCSI_Read10(pdev, lun, cmd); + break; + + case SCSI_WRITE10: // 0x2AU 42 + SCSI_Write10(pdev, lun, cmd); + break; + + case SCSI_VERIFY10: // 0x2FU 47 + SCSI_Verify10(pdev, lun, cmd); + break; + + default: + SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + return 0; +} + + +/** +* @brief SCSI_TestUnitReady +* Process SCSI Test Unit Ready Command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataMSC; + + /* case 9 : Hi > D0 */ + if (hmsc->cbw.dDataLength != 0U) { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + + return -1; + } + + if (((USBD_StorageTypeDef *)pdev->pClassSpecificInterfaceMSC)->IsReady(lun) != 0) { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + hmsc->bot_state = USBD_BOT_NO_DATA; + + return -1; + } + hmsc->bot_data_length = 0U; + + return 0; +} + +/** +* @brief SCSI_Inquiry +* Process Inquiry command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + uint8_t *pPage; + uint16_t len; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataMSC; + + if (params[1] & 0x01U) {/*Evpd is set*/ + len = LENGTH_INQUIRY_PAGE00; + hmsc->bot_data_length = len; + + while (len) { + len--; + hmsc->bot_data[len] = MSC_Page00_Inquiry_Data[len]; + } + } else { + pPage = (uint8_t *)(void *) & ((USBD_StorageTypeDef *)pdev->pClassSpecificInterfaceMSC)->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN]; + len = (uint16_t)pPage[4] + 5U; + + if (params[4] <= len) { + len = params[4]; + } + hmsc->bot_data_length = len; + + while (len) { + len--; + hmsc->bot_data[len] = pPage[len]; + } + } + + return 0; +} + +/** +* @brief SCSI_ReadCapacity10 +* Process Read Capacity 10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataMSC; + + if (((USBD_StorageTypeDef *)pdev->pClassSpecificInterfaceMSC)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size) != 0) { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + return -1; + } else { + + hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24); + hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16); + hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 8); + hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1U); + + hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >> 24); + hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >> 16); + hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >> 8); + hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size); + + hmsc->bot_data_length = 8U; + return 0; + } +} +/** +* @brief SCSI_ReadFormatCapacity +* Process Read Format Capacity command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataMSC; + + uint16_t blk_size; + uint32_t blk_nbr; + uint16_t i; + + for (i = 0U; i < 12U ; i++) { + hmsc->bot_data[i] = 0U; + } + + if (((USBD_StorageTypeDef *)pdev->pClassSpecificInterfaceMSC)->GetCapacity(lun, &blk_nbr, &blk_size) != 0U) { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + return -1; + } else { + hmsc->bot_data[3] = 0x08U; + hmsc->bot_data[4] = (uint8_t)((blk_nbr - 1U) >> 24); + hmsc->bot_data[5] = (uint8_t)((blk_nbr - 1U) >> 16); + hmsc->bot_data[6] = (uint8_t)((blk_nbr - 1U) >> 8); + hmsc->bot_data[7] = (uint8_t)(blk_nbr - 1U); + + hmsc->bot_data[8] = 0x02U; + hmsc->bot_data[9] = (uint8_t)(blk_size >> 16); + hmsc->bot_data[10] = (uint8_t)(blk_size >> 8); + hmsc->bot_data[11] = (uint8_t)(blk_size); + + hmsc->bot_data_length = 12U; + return 0; + } +} +/** +* @brief SCSI_ModeSense6 +* Process Mode Sense6 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataMSC; + uint16_t len = 8U; + hmsc->bot_data_length = len; + + while (len) { + len--; + hmsc->bot_data[len] = MSC_Mode_Sense6_data[len]; + } + return 0; +} + +/** +* @brief SCSI_ModeSense10 +* Process Mode Sense10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + uint16_t len = 8U; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataMSC; + + hmsc->bot_data_length = len; + + while (len) { + len--; + hmsc->bot_data[len] = MSC_Mode_Sense10_data[len]; + } + + return 0; +} + +/** +* @brief SCSI_RequestSense +* Process Request Sense command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ + +static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + uint8_t i; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataMSC; + + for (i = 0U ; i < REQUEST_SENSE_DATA_LEN; i++) { + hmsc->bot_data[i] = 0U; + } + + hmsc->bot_data[0] = 0x70U; + hmsc->bot_data[7] = REQUEST_SENSE_DATA_LEN - 6U; + + if ((hmsc->scsi_sense_head != hmsc->scsi_sense_tail)) { + + hmsc->bot_data[2] = hmsc->scsi_sense[hmsc->scsi_sense_head].Skey; + hmsc->bot_data[12] = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASCQ; + hmsc->bot_data[13] = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASC; + hmsc->scsi_sense_head++; + + if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH) { + hmsc->scsi_sense_head = 0U; + } + } + hmsc->bot_data_length = REQUEST_SENSE_DATA_LEN; + + if (params[4] <= REQUEST_SENSE_DATA_LEN) { + hmsc->bot_data_length = params[4]; + } + return 0; +} + +/** +* @brief SCSI_SenseCode +* Load the last error code in the error list +* @param lun: Logical unit number +* @param sKey: Sense Key +* @param ASC: Additional Sense Key +* @retval none + +*/ +void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataMSC; + + hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey = sKey; + hmsc->scsi_sense[hmsc->scsi_sense_tail].w.ASC = ASC << 8; + hmsc->scsi_sense_tail++; + if (hmsc->scsi_sense_tail == SENSE_LIST_DEEPTH) { + hmsc->scsi_sense_tail = 0U; + } +} +/** +* @brief SCSI_StartStopUnit +* Process Start Stop Unit command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *) pdev->pClassDataMSC; + hmsc->bot_data_length = 0U; + return 0; +} + +/** +* @brief SCSI_Read10 +* Process Read10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *) pdev->pClassDataMSC; + + if (hmsc->bot_state == USBD_BOT_IDLE) { /* Idle */ + /* case 10 : Ho <> Di */ + if ((hmsc->cbw.bmFlags & 0x80U) != 0x80U) { +// if (hmsc->bot_state == USBD_BOT_IDLE) { /* Idle */ + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + + if (((USBD_StorageTypeDef *)pdev->pClassSpecificInterfaceMSC)->IsReady(lun) != 0) { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + return -1; + } + + hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) | + ((uint32_t)params[3] << 16) | + ((uint32_t)params[4] << 8) | + (uint32_t)params[5]; + + hmsc->scsi_blk_len = ((uint32_t)params[7] << 8) | (uint32_t)params[8]; + + if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, + hmsc->scsi_blk_len) < 0) { + return -1; /* error */ + } + + hmsc->bot_state = USBD_BOT_DATA_IN; + + /* cases 4, 5 : Hi <> Dn */ + if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + } + hmsc->bot_data_length = MSC_MEDIA_PACKET; + + return SCSI_ProcessRead(pdev, lun); +} + +/** +* @brief SCSI_Write10 +* Process Write10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ + +static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *) pdev->pClassDataMSC; + uint32_t len; + + if (hmsc->bot_state == USBD_BOT_IDLE) { /* Idle */ + /* case 8 : Hi <> Do */ + if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U) { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + + /* Check whether Media is ready */ + if (((USBD_StorageTypeDef *)pdev->pClassSpecificInterfaceMSC)->IsReady(lun) != 0) { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + return -1; + } + + /* Check If media is write-protected */ + if (((USBD_StorageTypeDef *)pdev->pClassSpecificInterfaceMSC)->IsWriteProtected(lun) != 0) { + SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED); + return -1; + } + + hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) | + ((uint32_t)params[3] << 16) | + ((uint32_t)params[4] << 8) | + (uint32_t)params[5]; + + hmsc->scsi_blk_len = ((uint32_t)params[7] << 8) | + (uint32_t)params[8]; + + /* check if LBA address is in the right range */ + if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, + hmsc->scsi_blk_len) < 0) { + return -1; /* error */ + } + + len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + + /* cases 3, 11, 13 : Hn,Ho <> D0 */ + if (hmsc->cbw.dDataLength != len) { + SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } + + len = MIN(len, MSC_MEDIA_PACKET); + + /* Prepare EP to receive first data packet */ + hmsc->bot_state = USBD_BOT_DATA_OUT; + USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len); + } else { /* Write Process ongoing */ + return SCSI_ProcessWrite(pdev, lun); + } + return 0; +} + + +/** +* @brief SCSI_Verify10 +* Process Verify10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ + +static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *) pdev->pClassDataMSC; + + if ((params[1] & 0x02U) == 0x02U) { + SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); + return -1; /* Error, Verify Mode Not supported*/ + } + + if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, + hmsc->scsi_blk_len) < 0) { + return -1; /* error */ + } + hmsc->bot_data_length = 0U; + return 0; +} + +/** +* @brief SCSI_CheckAddressRange +* Check address range +* @param lun: Logical unit number +* @param blk_offset: first block address +* @param blk_nbr: number of block to be processed +* @retval status +*/ +static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, + uint32_t blk_offset, uint32_t blk_nbr) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *) pdev->pClassDataMSC; + + if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr) { + SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE); + return -1; + } + return 0; +} + +/** +* @brief SCSI_ProcessRead +* Handle Read Process +* @param lun: Logical unit number +* @retval status +*/ +static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataMSC; + uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + + len = MIN(len, MSC_MEDIA_PACKET); + + if (((USBD_StorageTypeDef *)pdev->pClassSpecificInterfaceMSC)->Read(lun, + hmsc->bot_data, + hmsc->scsi_blk_addr, + (len / hmsc->scsi_blk_size)) < 0) { + SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR); + return -1; + } + + USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, hmsc->bot_data, len); + + hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size); + hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size); + + /* case 6 : Hi = Di */ + hmsc->csw.dDataResidue -= len; + + if (hmsc->scsi_blk_len == 0U) { + hmsc->bot_state = USBD_BOT_LAST_DATA_IN; + } + return 0; +} + +/** +* @brief SCSI_ProcessWrite +* Handle Write Process +* @param lun: Logical unit number +* @retval status +*/ + +static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *) pdev->pClassDataMSC; + uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + + len = MIN(len, MSC_MEDIA_PACKET); + + if (((USBD_StorageTypeDef *)pdev->pClassSpecificInterfaceMSC)->Write(lun, hmsc->bot_data, + hmsc->scsi_blk_addr, + (len / hmsc->scsi_blk_size)) < 0) { + SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, WRITE_FAULT); + + return -1; + } + + hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size); + hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size); + + /* case 12 : Ho = Do */ + hmsc->csw.dDataResidue -= len; + + if (hmsc->scsi_blk_len == 0U) { + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED); + } else { + len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET); + /* Prepare EP to Receive next packet */ + USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len); + } + + return 0; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +#endif // USBD_USE_CDC_COMPOSITE + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_data.c b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_data.c new file mode 100644 index 0000000000..13a85f52c3 --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_data.c @@ -0,0 +1,132 @@ +/** + ****************************************************************************** + * @file usbd_msc_data.c + * @author MCD Application Team + * @brief This file provides all the vital inquiry pages and sense data. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, 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/SLA0044 + * + ****************************************************************************** + */ + +/* BSPDependencies +- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c" +- "stm32xxxxx_{eval}{discovery}_io.c" +- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c" +EndBSPDependencies */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_data.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_DATA + * @brief Mass storage info/data module + * @{ + */ + +/** @defgroup MSC_DATA_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Variables + * @{ + */ + + +/* USB Mass storage Page 0 Inquiry Data */ +const uint8_t MSC_Page00_Inquiry_Data[] = { + 0x00, + 0x00, + 0x00, + (LENGTH_INQUIRY_PAGE00 - 4U), + 0x00, + 0x80, + 0x83 +}; +/* USB Mass storage sense 6 Data */ +const uint8_t MSC_Mode_Sense6_data[] = { + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; +/* USB Mass storage sense 10 Data */ +const uint8_t MSC_Mode_Sense10_data[] = { + 0x00, + 0x06, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Functions + * @{ + */ + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_data.h b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_data.h new file mode 100644 index 0000000000..578749b2cb --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_data.h @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file usbd_msc_data.h + * @author MCD Application Team + * @brief Header for the usbd_msc_data.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, 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/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_DATA_H +#define __USBD_MSC_DATA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" +#include + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USB_INFO + * @brief general defines for the usb device library file + * @{ + */ + +/** @defgroup USB_INFO_Exported_Defines + * @{ + */ +#define MODE_SENSE6_LEN 8U +#define MODE_SENSE10_LEN 8U +#define LENGTH_INQUIRY_PAGE00 7U +#define LENGTH_FORMAT_CAPACITIES 20U + +/** + * @} + */ + + +/** @defgroup USBD_INFO_Exported_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBD_INFO_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_INFO_Exported_Variables + * @{ + */ +extern const uint8_t MSC_Page00_Inquiry_Data[]; +extern const uint8_t MSC_Mode_Sense6_data[]; +extern const uint8_t MSC_Mode_Sense10_data[] ; + +/** + * @} + */ + +/** @defgroup USBD_INFO_Exported_FunctionsPrototype + * @{ + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MSC_DATA_H */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_scsi.h b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_scsi.h new file mode 100644 index 0000000000..1629d786c3 --- /dev/null +++ b/cores/arduino/stm32/usb/msc_cdc_composite/usbd_msc_scsi.h @@ -0,0 +1,192 @@ +/** + ****************************************************************************** + * @file usbd_msc_scsi.h + * @author MCD Application Team + * @brief Header for the usbd_msc_scsi.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_SCSI_H +#define __USBD_MSC_SCSI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_SCSI + * @brief header file for the storage disk file + * @{ + */ + +/** @defgroup USBD_SCSI_Exported_Defines + * @{ + */ + +#define SENSE_LIST_DEEPTH 4U + +/* SCSI Commands */ +#define SCSI_FORMAT_UNIT 0x04U +#define SCSI_INQUIRY 0x12U +#define SCSI_MODE_SELECT6 0x15U +#define SCSI_MODE_SELECT10 0x55U +#define SCSI_MODE_SENSE6 0x1AU +#define SCSI_MODE_SENSE10 0x5AU +#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1EU +#define SCSI_READ6 0x08U +#define SCSI_READ10 0x28U +#define SCSI_READ12 0xA8U +#define SCSI_READ16 0x88U + +#define SCSI_READ_CAPACITY10 0x25U +#define SCSI_READ_CAPACITY16 0x9EU + +#define SCSI_REQUEST_SENSE 0x03U +#define SCSI_START_STOP_UNIT 0x1BU +#define SCSI_TEST_UNIT_READY 0x00U +#define SCSI_WRITE6 0x0AU +#define SCSI_WRITE10 0x2AU +#define SCSI_WRITE12 0xAAU +#define SCSI_WRITE16 0x8AU + +#define SCSI_VERIFY10 0x2FU +#define SCSI_VERIFY12 0xAFU +#define SCSI_VERIFY16 0x8FU + +#define SCSI_SEND_DIAGNOSTIC 0x1DU +#define SCSI_READ_FORMAT_CAPACITIES 0x23U + +#define NO_SENSE 0U +#define RECOVERED_ERROR 1U +#define NOT_READY 2U +#define MEDIUM_ERROR 3U +#define HARDWARE_ERROR 4U +#define ILLEGAL_REQUEST 5U +#define UNIT_ATTENTION 6U +#define DATA_PROTECT 7U +#define BLANK_CHECK 8U +#define VENDOR_SPECIFIC 9U +#define COPY_ABORTED 10U +#define ABORTED_COMMAND 11U +#define VOLUME_OVERFLOW 13U +#define MISCOMPARE 14U + + +#define INVALID_CDB 0x20U +#define INVALID_FIELED_IN_COMMAND 0x24U +#define PARAMETER_LIST_LENGTH_ERROR 0x1AU +#define INVALID_FIELD_IN_PARAMETER_LIST 0x26U +#define ADDRESS_OUT_OF_RANGE 0x21U +#define MEDIUM_NOT_PRESENT 0x3AU +#define MEDIUM_HAVE_CHANGED 0x28U +#define WRITE_PROTECTED 0x27U +#define UNRECOVERED_READ_ERROR 0x11U +#define WRITE_FAULT 0x03U + +#define READ_FORMAT_CAPACITY_DATA_LEN 0x0CU +#define READ_CAPACITY10_DATA_LEN 0x08U +#define MODE_SENSE10_DATA_LEN 0x08U +#define MODE_SENSE6_DATA_LEN 0x04U +#define REQUEST_SENSE_DATA_LEN 0x12U +#define STANDARD_INQUIRY_DATA_LEN 0x24U +#define BLKVFY 0x04U + +extern uint8_t Page00_Inquiry_Data[]; +extern uint8_t Standard_Inquiry_Data[]; +extern uint8_t Standard_Inquiry_Data2[]; +extern uint8_t Mode_Sense6_data[]; +extern uint8_t Mode_Sense10_data[]; +extern uint8_t Scsi_Sense_Data[]; +extern uint8_t ReadCapacity10_Data[]; +extern uint8_t ReadFormatCapacity_Data []; +/** + * @} + */ + + +/** @defgroup USBD_SCSI_Exported_TypesDefinitions + * @{ + */ + +typedef struct _SENSE_ITEM +{ + char Skey; + union + { + struct _ASCs + { + char ASC; + char ASCQ; + } b; + uint8_t ASC; + char *pData; + } w; +} USBD_SCSI_SenseTypeDef; +/** + * @} + */ + +/** @defgroup USBD_SCSI_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_SCSI_Exported_Variables + * @{ + */ + +/** + * @} + */ +/** @defgroup USBD_SCSI_Exported_FunctionsPrototype + * @{ + */ +int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd); + +void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, + uint8_t ASC); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MSC_SCSI_H */ +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/cores/arduino/stm32/usb/usbd_conf.c b/cores/arduino/stm32/usb/usbd_conf.c index f58c6669cc..0d3af6ca71 100644 --- a/cores/arduino/stm32/usb/usbd_conf.c +++ b/cores/arduino/stm32/usb/usbd_conf.c @@ -20,21 +20,24 @@ /* Includes ------------------------------------------------------------------*/ #include "usbd_core.h" #include "usbd_if.h" +#include "usbd_ep_conf.h" #include "stm32yyxx_ll_pwr.h" #ifndef HAL_PCD_MODULE_ENABLED #error "HAL_PCD_MODULE_ENABLED is required" #else + +#ifndef p_Data + #ifdef USBD_USE_CDC_COMPOSITE +#define p_Data pPCDHandle +#else +#define p_Data pData +#endif +#endif + /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -/* Size in words, byte size divided by 2 */ -#define PMA_EP0_OUT_ADDR (8 * 4) -#define PMA_EP0_IN_ADDR (PMA_EP0_OUT_ADDR + USB_MAX_EP0_SIZE) -#define PMA_CDC_OUT_BASE (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE) -#define PMA_CDC_OUT_ADDR ((PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) | \ - (PMA_CDC_OUT_BASE << 16U)) -#define PMA_CDC_IN_ADDR (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE * 2) -#define PMA_CDC_CMD_ADDR (PMA_CDC_IN_ADDR + USB_FS_MAX_PACKET_SIZE) + /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ PCD_HandleTypeDef g_hpcd; @@ -465,7 +468,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) { USBD_reenumerate(); /* Set common LL Driver parameters */ - g_hpcd.Init.dev_endpoints = 4; + g_hpcd.Init.dev_endpoints = DEV_NUM_EP; g_hpcd.Init.ep0_mps = DEP0CTL_MPS_64; #if !defined(STM32F1xx) && !defined(STM32F2xx) || defined(USB) g_hpcd.Init.lpm_enable = DISABLE; @@ -503,33 +506,23 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) /* Link The driver to the stack */ g_hpcd.pData = pdev; - pdev->pData = &g_hpcd; + pdev->p_Data = &g_hpcd; /* Initialize LL Driver */ if (HAL_PCD_Init(&g_hpcd) != HAL_OK) { Error_Handler(); } -#ifdef USE_USB_HS +#if !defined (USB) || defined(USBD_USE_CDC_COMPOSITE) /* configure EPs FIFOs */ - HAL_PCDEx_SetRxFiFo(&g_hpcd, 0x200); - HAL_PCDEx_SetTxFiFo(&g_hpcd, 0, 0x80); - HAL_PCDEx_SetTxFiFo(&g_hpcd, 1, 0x40); - HAL_PCDEx_SetTxFiFo(&g_hpcd, 2, 0x160); -#else /* USE_USB_FS */ -#ifdef USB_OTG_FS - /* configure EPs FIFOs */ - HAL_PCDEx_SetRxFiFo(&g_hpcd, 0x80); - HAL_PCDEx_SetTxFiFo(&g_hpcd, 0, 0x40); - HAL_PCDEx_SetTxFiFo(&g_hpcd, 1, 0x40); - HAL_PCDEx_SetTxFiFo(&g_hpcd, 2, 0x40); + HAL_PCDEx_SetRxFiFo(&g_hpcd, ep_def[0].ep_size); + for (uint32_t i = 0; i < (DEV_NUM_EP); i++) { + HAL_PCDEx_SetTxFiFo(&g_hpcd, ep_def[i].ep_adress & 0xF, ep_def[i].ep_size); + } #else - HAL_PCDEx_PMAConfig(&g_hpcd, 0x00, PCD_SNG_BUF, PMA_EP0_OUT_ADDR); - HAL_PCDEx_PMAConfig(&g_hpcd, 0x80, PCD_SNG_BUF, PMA_EP0_IN_ADDR); - HAL_PCDEx_PMAConfig(&g_hpcd, 0x01, PCD_DBL_BUF, PMA_CDC_OUT_ADDR); - HAL_PCDEx_PMAConfig(&g_hpcd, 0x82, PCD_SNG_BUF, PMA_CDC_IN_ADDR); - HAL_PCDEx_PMAConfig(&g_hpcd, 0x83, PCD_SNG_BUF, PMA_CDC_CMD_ADDR); -#endif + for (uint32_t i = 0; i < (DEV_NUM_EP + 1); i++) { + HAL_PCDEx_PMAConfig(&g_hpcd, ep_def[i].ep_adress, ep_def[i].ep_kind, ep_def[i].ep_size); + } #endif /* USE_USB_HS */ return USBD_OK; } @@ -541,7 +534,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) */ USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) { - HAL_PCD_DeInit(pdev->pData); + HAL_PCD_DeInit(pdev->p_Data); return USBD_OK; } @@ -552,7 +545,7 @@ USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) */ USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) { - HAL_PCD_Start(pdev->pData); + HAL_PCD_Start(pdev->p_Data); return USBD_OK; } @@ -563,7 +556,7 @@ USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) */ USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) { - HAL_PCD_Stop(pdev->pData); + HAL_PCD_Stop(pdev->p_Data); return USBD_OK; } @@ -580,7 +573,7 @@ USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_type, uint16_t ep_mps) { - HAL_PCD_EP_Open(pdev->pData, + HAL_PCD_EP_Open(pdev->p_Data, ep_addr, ep_mps, ep_type); @@ -595,7 +588,7 @@ USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, */ USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { - HAL_PCD_EP_Close(pdev->pData, ep_addr); + HAL_PCD_EP_Close(pdev->p_Data, ep_addr); return USBD_OK; } @@ -607,7 +600,7 @@ USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) */ USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { - HAL_PCD_EP_Flush(pdev->pData, ep_addr); + HAL_PCD_EP_Flush(pdev->p_Data, ep_addr); return USBD_OK; } @@ -619,7 +612,7 @@ USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) */ USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { - HAL_PCD_EP_SetStall(pdev->pData, ep_addr); + HAL_PCD_EP_SetStall(pdev->p_Data, ep_addr); return USBD_OK; } @@ -631,7 +624,7 @@ USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) */ USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { - HAL_PCD_EP_ClrStall(pdev->pData, ep_addr); + HAL_PCD_EP_ClrStall(pdev->p_Data, ep_addr); return USBD_OK; } @@ -643,7 +636,7 @@ USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_add */ uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { - PCD_HandleTypeDef *hpcd = pdev->pData; + PCD_HandleTypeDef *hpcd = pdev->p_Data; if ((ep_addr & 0x80) == 0x80) { return hpcd->IN_ep[ep_addr & 0x7F].is_stall; @@ -660,7 +653,7 @@ uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) */ USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) { - HAL_PCD_SetAddress(pdev->pData, dev_addr); + HAL_PCD_SetAddress(pdev->p_Data, dev_addr); return USBD_OK; } @@ -677,7 +670,7 @@ USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint16_t size) { - HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size); + HAL_PCD_EP_Transmit(pdev->p_Data, ep_addr, pbuf, size); return USBD_OK; } @@ -694,7 +687,7 @@ USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint16_t size) { - HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size); + HAL_PCD_EP_Receive(pdev->p_Data, ep_addr, pbuf, size); return USBD_OK; } @@ -706,7 +699,7 @@ USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, */ uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { - return HAL_PCD_EP_GetRxCount(pdev->pData, ep_addr); + return HAL_PCD_EP_GetRxCount(pdev->p_Data, ep_addr); } /** diff --git a/cores/arduino/stm32/usb/usbd_conf.c mod b/cores/arduino/stm32/usb/usbd_conf.c mod new file mode 100644 index 0000000000..10b4a53f0d --- /dev/null +++ b/cores/arduino/stm32/usb/usbd_conf.c mod @@ -0,0 +1,753 @@ +/** + ****************************************************************************** + * @file usbd_conf.c + * @author MCD Application Team + * @brief USB Device configuration and interface file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, 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/SLA0044 + * + ****************************************************************************** + */ + +/** + ****************************************************************************** + * + * The composite MSC CDC USB device is mainly adapted from the GPSlogger + * repository https://github.com/grafalex82/GPSLogger/tree/master/Libs/USB + * + * See the article "CDC + MSC USB Composite Device for STM32 HAL" (URL: + * https://habr.com/en/post/335018/) for the theory behind the MSC CDC + * composite device as implemented in the above repository. + * + * The composite MSC CDC USB device requires a modified USBD_HandleTypeDef + * structure. The MSC and CDC classes require dedicated data structures. + * + ****************************************************************************** + */ + +#ifdef USBCON +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" +#include "usbd_if.h" +#include "usbd_ep_conf.h" +#include "stm32yyxx_ll_pwr.h" + +#ifndef HAL_PCD_MODULE_ENABLED +#error "HAL_PCD_MODULE_ENABLED is required" +#else + +#ifndef p_Data +#ifdef USBD_USE_CDC_COMPOSITE +#define p_Data pPCDHandle +#else +#define p_Data pData +#endif +#endif + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Size in words, byte size divided by 2 */ +#define PMA_EP0_OUT_ADDR (8 * 4) +#define PMA_EP0_IN_ADDR (PMA_EP0_OUT_ADDR + USB_MAX_EP0_SIZE) +#define PMA_CDC_OUT_BASE (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE) +#define PMA_CDC_OUT_ADDR ((PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) | \ + (PMA_CDC_OUT_BASE << 16U)) +#define PMA_CDC_IN_ADDR (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE * 2) +#define PMA_CDC_CMD_ADDR (PMA_CDC_IN_ADDR + USB_FS_MAX_PACKET_SIZE) +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +PCD_HandleTypeDef g_hpcd; +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/******************************************************************************* + PCD BSP Routines +*******************************************************************************/ + +/** + * @brief Initializes the PCD MSP. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) +{ + const PinMap *map = NULL; +#if defined(PWR_CR2_USV) + /* Enable VDDUSB on Pwrctrl CR2 register*/ +#if !defined(STM32WBxx) + if (__HAL_RCC_PWR_IS_CLK_DISABLED()) { + __HAL_RCC_PWR_CLK_ENABLE(); + HAL_PWREx_EnableVddUSB(); + __HAL_RCC_PWR_CLK_DISABLE(); + } else +#endif + { + HAL_PWREx_EnableVddUSB(); + } +#endif +#ifdef STM32H7xx + if (!LL_PWR_IsActiveFlag_USB()) { + HAL_PWREx_EnableUSBVoltageDetector(); + } +#endif +#if defined (USB) + if (hpcd->Instance == USB) { + + /* Configure USB FS GPIOs */ + map = PinMap_USB; + while (map->pin != NC) { + pin_function(map->pin, map->function); + map++; + } + + /* Enable USB FS Clock */ + __HAL_RCC_USB_CLK_ENABLE(); + +#if defined (USE_USB_INTERRUPT_REMAPPED) + /*USB interrupt remapping enable */ + __HAL_REMAPINTERRUPT_USB_ENABLE(); +#endif + +#if defined(STM32G4xx) || defined(STM32WBxx) + HAL_NVIC_SetPriority(USB_HP_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); + HAL_NVIC_EnableIRQ(USB_HP_IRQn); + HAL_NVIC_SetPriority(USB_LP_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); + HAL_NVIC_EnableIRQ(USB_LP_IRQn); +#else + /* Set USB FS Interrupt priority */ + HAL_NVIC_SetPriority(USB_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); + + /* Enable USB FS Interrupt */ + HAL_NVIC_EnableIRQ(USB_IRQn); +#endif /* STM32WBxx */ + + if (hpcd->Init.low_power_enable == 1) { + /* Enable EXTI for USB wakeup */ +#ifdef __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG + __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG(); +#endif +#ifdef __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_EDGE + __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_EDGE(); +#endif + __HAL_USB_WAKEUP_EXTI_ENABLE_IT(); +#if defined(STM32F1xx) || defined(STM32F3xx) + /* USB Wakeup Interrupt */ + HAL_NVIC_EnableIRQ(USBWakeUp_IRQn); + + /* Enable USB Wake-up interrupt */ + HAL_NVIC_SetPriority(USBWakeUp_IRQn, 0, 0); +#endif + } + } +#endif /* USB */ +#if defined (USB_OTG_FS) + if (hpcd->Instance == USB_OTG_FS) { + + /* Configure USB FS GPIOs */ + map = PinMap_USB_OTG_FS; + while (map->pin != NC) { + pin_function(map->pin, map->function); + map++; + } + + /* Enable USB FS Clock */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + + /* Set USB FS Interrupt priority */ + HAL_NVIC_SetPriority(OTG_FS_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); + + /* Enable USB FS Interrupt */ + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + + if (hpcd->Init.low_power_enable == 1) { + /* Enable EXTI Line 18 for USB wakeup */ +#ifdef __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG + __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG(); +#endif +#ifdef __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE + __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE(); +#endif + __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT(); +#if !defined(STM32L4xx) + /* Set EXTI Wakeup Interrupt priority */ + HAL_NVIC_SetPriority(OTG_FS_WKUP_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); + + /* Enable EXTI Interrupt */ + HAL_NVIC_EnableIRQ(OTG_FS_WKUP_IRQn); +#endif + } + } +#endif /* USB_OTG_FS */ +#if defined (USB_OTG_HS) + if (hpcd->Instance == USB_OTG_HS) { + /* Configure USB HS GPIOs */ + map = PinMap_USB_OTG_HS; + while (map->pin != NC) { + pin_function(map->pin, map->function); + map++; + } +#ifndef USE_USB_HS_IN_FS + __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); +#endif /* USE_USB_HS_IN_FS */ + + /* Enable USB HS Clocks */ + __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); + + /* Set USBHS Interrupt priority */ + HAL_NVIC_SetPriority(OTG_HS_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); + + /* Enable USB HS Interrupt */ + HAL_NVIC_EnableIRQ(OTG_HS_IRQn); + + if (hpcd->Init.low_power_enable == 1) { + /* Enable EXTI Line 20 for USB wakeup */ +#ifdef __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG + __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG(); +#endif +#ifdef __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE + __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE(); +#endif + __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT(); + + /* Set EXTI Wakeup Interrupt priority */ + HAL_NVIC_SetPriority(OTG_HS_WKUP_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); + + /* Enable EXTI Interrupt */ + HAL_NVIC_EnableIRQ(OTG_HS_WKUP_IRQn); + } + } +#endif /* USB_OTG_HS */ +} + +/** + * @brief De-Initializes the PCD MSP. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) +{ + /* Disable USB FS Clock */ +#if defined (USB) + if (hpcd->Instance == USB) { + __HAL_RCC_USB_CLK_DISABLE(); + } +#endif +#if defined (USB_OTG_FS) + if (hpcd->Instance == USB_OTG_FS) { + /* Disable USB FS Clock */ + __HAL_RCC_USB_OTG_FS_CLK_DISABLE(); + } +#endif +#if defined (USB_OTG_HS) + if (hpcd->Instance == USB_OTG_HS) { + /* Disable USB HS Clocks */ + __HAL_RCC_USB_OTG_HS_CLK_DISABLE(); + } +#endif /* USB_OTG_HS */ +} + +/******************************************************************************* + LL Driver Callbacks (PCD -> USB Device Library) +*******************************************************************************/ + +/** + * @brief SetupStage callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_SetupStage(hpcd->pData, (uint8_t *)hpcd->Setup); +} + +/** + * @brief DataOut Stage callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_DataOutStage(hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff); + } + +/** + * @brief DataIn Stage callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_DataInStage(hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff); +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_SOF(hpcd->pData); +} + +/** + * @brief Reset callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_SpeedTypeDef speed = USBD_SPEED_FULL; + +#if defined (USB_OTG_HS) + /* Set USB Current Speed */ + switch (hpcd->Init.speed) { + case PCD_SPEED_HIGH: + speed = USBD_SPEED_HIGH; + break; + + case PCD_SPEED_FULL: + speed = USBD_SPEED_FULL; + break; + + default: + speed = USBD_SPEED_FULL; + break; + + } +#endif + /* Reset Device */ + USBD_LL_Reset(hpcd->pData); + + USBD_LL_SetSpeed(hpcd->pData, speed); +} + +/** + * @brief Suspend callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_Suspend(hpcd->pData); + __HAL_PCD_GATE_PHYCLOCK(hpcd); + + /*Enter in STOP mode */ + if (hpcd->Init.low_power_enable) { + /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register */ + SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); + } +} + +/** + * @brief Resume callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) +{ + if (hpcd->Init.low_power_enable) { + SystemClock_Config(); + + /* Reset SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); + } + __HAL_PCD_UNGATE_PHYCLOCK(hpcd); + USBD_LL_Resume(hpcd->pData); +} + +/** + * @brief ISOOUTIncomplete callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_IsoOUTIncomplete(hpcd->pData, epnum); +} + +/** + * @brief ISOINIncomplete callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_IsoINIncomplete(hpcd->pData, epnum); +} + +/** + * @brief ConnectCallback callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_DevConnected(hpcd->pData); +} + +/** + * @brief Disconnect callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_DevDisconnected(hpcd->pData); +} + + + +/** + * @brief This function handles USB-On-The-Go FS/HS global interrupt request. + * @param None + * @retval None + */ +#ifdef USE_USB_HS +void OTG_HS_IRQHandler(void) +#elif defined(USB_OTG_FS) +void OTG_FS_IRQHandler(void) +#else /* USB */ +void USB_IRQHandler(void) +#endif +{ + HAL_PCD_IRQHandler(&g_hpcd); +} + +#if defined(STM32WBxx) +/** + * @brief This function handles USB high priority interrupt. + * @param None + * @retval None +*/ +void USB_HP_IRQHandler(void) +{ + HAL_PCD_IRQHandler(&g_hpcd); +} + +/** + * @brief This function handles USB low priority interrupt, USB wake-up interrupt through EXTI line 28. + * @param None + * @retval None +*/ +void USB_LP_IRQHandler(void) +{ + HAL_PCD_IRQHandler(&g_hpcd); +} +#else +/** + * @brief This function handles USB OTG FS Wakeup IRQ Handler. + * @param None + * @retval None + */ +#ifdef USE_USB_HS +void OTG_HS_WKUP_IRQHandler(void) +#elif defined(USB_OTG_FS) +void OTG_FS_WKUP_IRQHandler(void) +#else +void USBWakeUp_IRQHandler(void) +#endif +{ + if ((&g_hpcd)->Init.low_power_enable) { + /* Reset SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); + + /* Configures system clock after wake-up from STOP: enable HSE, PLL and select + PLL as system clock source (HSE and PLL are disabled in STOP mode) */ + SystemClock_Config(); + + /* ungate PHY clock */ + __HAL_PCD_UNGATE_PHYCLOCK((&g_hpcd)); + } +#if defined(USE_USB_HS) && defined(__HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG) + /* Clear EXTI pending Bit*/ + __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG(); +#elif defined(USB_OTG_FS) && defined(__HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG) + /* Clear EXTI pending Bit*/ + __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG(); +#elif defined(__HAL_USB_WAKEUP_EXTI_CLEAR_FLAG) + __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG(); +#endif +} +#endif +/******************************************************************************* + LL Driver Interface (USB Device Library --> PCD) +*******************************************************************************/ +/** + * @brief Initializes the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) +{ + USBD_reenumerate(); + /* Set common LL Driver parameters */ +#ifdef USBD_USE_CDC_COMPOSITE + g_hpcd.Init.dev_endpoints = 7; +#else + g_hpcd.Init.dev_endpoints = 4; +#endif + g_hpcd.Init.ep0_mps = DEP0CTL_MPS_64; +#if !defined(STM32F1xx) && !defined(STM32F2xx) || defined(USB) + g_hpcd.Init.lpm_enable = DISABLE; + g_hpcd.Init.battery_charging_enable = DISABLE; +#endif + g_hpcd.Init.low_power_enable = DISABLE; + g_hpcd.Init.Sof_enable = DISABLE; + + /* Set specific LL Driver parameters */ +#ifdef USE_USB_HS + g_hpcd.Instance = USB_OTG_HS; + g_hpcd.Init.use_dedicated_ep1 = DISABLE; + g_hpcd.Init.dma_enable = DISABLE; +#ifdef USE_USB_HS_IN_FS + g_hpcd.Init.phy_itface = PCD_PHY_EMBEDDED; +#else + g_hpcd.Init.phy_itface = PCD_PHY_ULPI; +#endif + g_hpcd.Init.speed = PCD_SPEED_HIGH; + g_hpcd.Init.vbus_sensing_enable = ENABLE; + g_hpcd.Init.use_external_vbus = DISABLE; +#else /* USE_USB_FS */ +#ifdef USB_OTG_FS + g_hpcd.Instance = USB_OTG_FS; + g_hpcd.Init.use_dedicated_ep1 = DISABLE; + g_hpcd.Init.dma_enable = DISABLE; + g_hpcd.Init.vbus_sensing_enable = DISABLE; + g_hpcd.Init.use_external_vbus = DISABLE; +#else + g_hpcd.Instance = USB; +#endif + g_hpcd.Init.phy_itface = PCD_PHY_EMBEDDED; + g_hpcd.Init.speed = PCD_SPEED_FULL; +#endif /* USE_USB_HS */ + + /* Link The driver to the stack */ + g_hpcd.pData = pdev; + pdev->p_Data = &g_hpcd; + + /* Initialize LL Driver */ + if (HAL_PCD_Init(&g_hpcd) != HAL_OK) { + Error_Handler(); + } + // set the FIFO start and length registers in the USB controller +#ifdef USE_USB_COMPOSITE + // MSC + CDC buffers + HAL_PCDEx_SetRxFiFo(&g_hpcd, 0x100); + HAL_PCDEx_SetTxFiFo(&g_hpcd, 0, 0x180); // EP0 FIFO size + HAL_PCDEx_SetTxFiFo(&g_hpcd, 1, 0x180); // EP1 FIFO size + HAL_PCDEx_SetTxFiFo(&g_hpcd, 3, 0x40); // EP3 FIFO size + +#elif !defined (USB) + /* configure EPs FIFOs */ + HAL_PCDEx_SetRxFiFo(&g_hpcd, ep_def[0].ep_size); + for (uint32_t i = 1; i < (DEV_NUM_EP + 1); i++) { + HAL_PCDEx_SetTxFiFo(&g_hpcd, ep_def[i].ep_adress & 0xF, ep_def[i].ep_size); + } +#else + for (uint32_t i = 0; i < (DEV_NUM_EP + 1); i++) { + HAL_PCDEx_PMAConfig(&g_hpcd, ep_def[i].ep_adress, ep_def[i].ep_kind, ep_def[i].ep_size); + } +#endif /* USE_USB_HS */ + return USBD_OK; +} + +/** + * @brief De-Initializes the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) +{ + HAL_PCD_DeInit(pdev->p_Data); + return USBD_OK; +} + +/** + * @brief Starts the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) +{ + HAL_PCD_Start(pdev->p_Data); + return USBD_OK; +} + +/** + * @brief Stops the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) +{ + HAL_PCD_Stop(pdev->p_Data); + return USBD_OK; +} + +/** + * @brief Opens an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @param ep_type: Endpoint Type + * @param ep_mps: Endpoint Max Packet Size + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps) +{ + HAL_PCD_EP_Open(pdev->p_Data, + ep_addr, + ep_mps, + ep_type); + return USBD_OK; +} + +/** + * @brief Closes an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_PCD_EP_Close(pdev->p_Data, ep_addr); + return USBD_OK; +} + +/** + * @brief Flushes an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_PCD_EP_Flush(pdev->p_Data, ep_addr); + return USBD_OK; +} + +/** + * @brief Sets a Stall condition on an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_PCD_EP_SetStall(pdev->p_Data, ep_addr); + return USBD_OK; +} + +/** + * @brief Clears a Stall condition on an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_PCD_EP_ClrStall(pdev->p_Data, ep_addr); + return USBD_OK; +} + +/** + * @brief Returns Stall condition. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval Stall (1: Yes, 0: No) + */ +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + PCD_HandleTypeDef *hpcd = pdev->p_Data; + + if ((ep_addr & 0x80) == 0x80) { + return hpcd->IN_ep[ep_addr & 0x7F].is_stall; + } else { + return hpcd->OUT_ep[ep_addr & 0x7F].is_stall; + } +} + +/** + * @brief Assigns a USB address to the device. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) +{ + HAL_PCD_SetAddress(pdev->p_Data, dev_addr); + return USBD_OK; +} + +/** + * @brief Transmits data over an endpoint. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @param pbuf: Pointer to data to be sent + * @param size: Data size + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size) +{ + HAL_PCD_EP_Transmit(pdev->p_Data, ep_addr, pbuf, size); + return USBD_OK; +} + +/** + * @brief Prepares an endpoint for reception. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @param pbuf: Pointer to data to be received + * @param size: Data size + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size) +{ + HAL_PCD_EP_Receive(pdev->p_Data, ep_addr, pbuf, size); + return USBD_OK; +} + +/** + * @brief Returns the last transferred packet size. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval Received Data Size + */ +uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return HAL_PCD_EP_GetRxCount(pdev->p_Data, ep_addr); +} + +/** + * @brief Delays routine for the USB Device Library. + * @param Delay: Delay in ms + * @retval None + */ +void USBD_LL_Delay(uint32_t Delay) +{ + HAL_Delay(Delay); +} +#endif /* HAL_PCD_MODULE_ENABLED */ +#endif /* USBCON */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/cores/arduino/stm32/usb/usbd_def.h b/cores/arduino/stm32/usb/usbd_def.h new file mode 100644 index 0000000000..eff88b24af --- /dev/null +++ b/cores/arduino/stm32/usb/usbd_def.h @@ -0,0 +1,377 @@ +/** + ****************************************************************************** + * @file usbd_def.h + * @author MCD Application Team + * @brief General defines for the usb device library + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, 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/SLA0044 + * + ****************************************************************************** + */ + +/** + ****************************************************************************** + * + * The composite MSC CDC USB device requires a modified USBD_HandleTypeDef + * structure. The MSC and CDC classes require dedicated data structures. + * + * The modified USBD_HandleTypeDef structure is copied from the GPSlogger + * repository https://github.com/grafalex82/GPSLogger/tree/master/Libs/USB + * + * See the article "CDC + MSC USB Composite Device for STM32 HAL" (URL: + * https://habr.com/en/post/335018/) for the theory behind the MSC CDC + * composite device as implemented in the above repository. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_DEF_H +#define __USBD_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" + +/** @addtogroup STM32_USBD_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USB_DEF + * @brief general defines for the usb device library file + * @{ + */ + +/** @defgroup USB_DEF_Exported_Defines + * @{ + */ + +#ifndef NULL +#define NULL 0U +#endif /* NULL */ + +#ifndef USBD_MAX_NUM_INTERFACES +#define USBD_MAX_NUM_INTERFACES 1U +#endif /* USBD_MAX_NUM_CONFIGURATION */ + +#ifndef USBD_MAX_NUM_CONFIGURATION +#define USBD_MAX_NUM_CONFIGURATION 1U +#endif /* USBD_MAX_NUM_CONFIGURATION */ + +#ifndef USBD_LPM_ENABLED +#define USBD_LPM_ENABLED 0U +#endif /* USBD_LPM_ENABLED */ + +#ifndef USBD_SELF_POWERED +#define USBD_SELF_POWERED 1U +#endif /*USBD_SELF_POWERED */ + +#ifndef USBD_SUPPORT_USER_STRING_DESC +#define USBD_SUPPORT_USER_STRING_DESC 0U +#endif /* USBD_SUPPORT_USER_STRING_DESC */ + +#define USB_LEN_DEV_QUALIFIER_DESC 0x0AU +#define USB_LEN_DEV_DESC 0x12U +#define USB_LEN_CFG_DESC 0x09U +#define USB_LEN_IF_DESC 0x09U +#define USB_LEN_EP_DESC 0x07U +#define USB_LEN_OTG_DESC 0x03U +#define USB_LEN_LANGID_STR_DESC 0x04U +#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09U + +#define USBD_IDX_LANGID_STR 0x00U +#define USBD_IDX_MFC_STR 0x01U +#define USBD_IDX_PRODUCT_STR 0x02U +#define USBD_IDX_SERIAL_STR 0x03U +#define USBD_IDX_CONFIG_STR 0x04U +#define USBD_IDX_INTERFACE_STR 0x05U + +#define USB_REQ_TYPE_STANDARD 0x00U +#define USB_REQ_TYPE_CLASS 0x20U +#define USB_REQ_TYPE_VENDOR 0x40U +#define USB_REQ_TYPE_MASK 0x60U + +#define USB_REQ_RECIPIENT_DEVICE 0x00U +#define USB_REQ_RECIPIENT_INTERFACE 0x01U +#define USB_REQ_RECIPIENT_ENDPOINT 0x02U +#define USB_REQ_RECIPIENT_MASK 0x03U + +#define USB_REQ_GET_STATUS 0x00U +#define USB_REQ_CLEAR_FEATURE 0x01U +#define USB_REQ_SET_FEATURE 0x03U +#define USB_REQ_SET_ADDRESS 0x05U +#define USB_REQ_GET_DESCRIPTOR 0x06U +#define USB_REQ_SET_DESCRIPTOR 0x07U +#define USB_REQ_GET_CONFIGURATION 0x08U +#define USB_REQ_SET_CONFIGURATION 0x09U +#define USB_REQ_GET_INTERFACE 0x0AU +#define USB_REQ_SET_INTERFACE 0x0BU +#define USB_REQ_SYNCH_FRAME 0x0CU + +#define USB_DESC_TYPE_DEVICE 0x01U +#define USB_DESC_TYPE_CONFIGURATION 0x02U +#define USB_DESC_TYPE_STRING 0x03U +#define USB_DESC_TYPE_INTERFACE 0x04U +#define USB_DESC_TYPE_ENDPOINT 0x05U +#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U +#define USB_DESC_TYPE_BOS 0x0FU + +#define USB_CONFIG_REMOTE_WAKEUP 0x02U +#define USB_CONFIG_SELF_POWERED 0x01U + +#define USB_FEATURE_EP_HALT 0x00U +#define USB_FEATURE_REMOTE_WAKEUP 0x01U +#define USB_FEATURE_TEST_MODE 0x02U + +#define USB_DEVICE_CAPABITY_TYPE 0x10U + +#define USB_HS_MAX_PACKET_SIZE 512U +#define USB_FS_MAX_PACKET_SIZE 64U +#define USB_MAX_EP0_SIZE 64U + +/* Device Status */ +#define USBD_STATE_DEFAULT 0x01U +#define USBD_STATE_ADDRESSED 0x02U +#define USBD_STATE_CONFIGURED 0x03U +#define USBD_STATE_SUSPENDED 0x04U + + +/* EP0 State */ +#define USBD_EP0_IDLE 0x00U +#define USBD_EP0_SETUP 0x01U +#define USBD_EP0_DATA_IN 0x02U +#define USBD_EP0_DATA_OUT 0x03U +#define USBD_EP0_STATUS_IN 0x04U +#define USBD_EP0_STATUS_OUT 0x05U +#define USBD_EP0_STALL 0x06U + +#define USBD_EP_TYPE_CTRL 0x00U +#define USBD_EP_TYPE_ISOC 0x01U +#define USBD_EP_TYPE_BULK 0x02U +#define USBD_EP_TYPE_INTR 0x03U + + +/** + * @} + */ + + +/** @defgroup USBD_DEF_Exported_TypesDefinitions + * @{ + */ + +// forward declarations +#ifdef USBD_USE_CDC_COMPOSITE +struct _USBD_MSC_BOT_HandleTypeDef; +struct _USBD_STORAGE; //USBD_StorageTypeDef +struct _USBD_CDC_HandleTypeDef; +struct _USBD_CDC_Itf; +#endif + +typedef struct usb_setup_req { + uint8_t bmRequest; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} USBD_SetupReqTypedef; + +struct _USBD_HandleTypeDef; + +typedef struct _Device_cb { + uint8_t (*Init)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx); + uint8_t (*DeInit)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx); + /* Control Endpoints*/ + uint8_t (*Setup)(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + uint8_t (*EP0_TxSent)(struct _USBD_HandleTypeDef *pdev); + uint8_t (*EP0_RxReady)(struct _USBD_HandleTypeDef *pdev); + /* Class Specific Endpoints*/ + uint8_t (*DataIn)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + uint8_t (*DataOut)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + uint8_t (*SOF)(struct _USBD_HandleTypeDef *pdev); + uint8_t (*IsoINIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + uint8_t (*IsoOUTIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + + uint8_t *(*GetHSConfigDescriptor)(uint16_t *length); + uint8_t *(*GetFSConfigDescriptor)(uint16_t *length); + uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length); + uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length); +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); +#endif + +} USBD_ClassTypeDef; + +/* Following USB Device Speed */ +typedef enum { + USBD_SPEED_HIGH = 0U, + USBD_SPEED_FULL = 1U, + USBD_SPEED_LOW = 2U, +} USBD_SpeedTypeDef; + +/* Following USB Device status */ +typedef enum { + USBD_OK = 0U, + USBD_BUSY, + USBD_FAIL, +} USBD_StatusTypeDef; + +/* USB Device descriptors structure */ +typedef struct { + uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); +#if (USBD_LPM_ENABLED == 1U) + uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); +#endif +} USBD_DescriptorsTypeDef; + +/* USB Device handle structure */ +typedef struct { + uint32_t status; + uint32_t is_used; + uint32_t total_length; + uint32_t rem_length; + uint32_t maxpacket; +} USBD_EndpointTypeDef; + +/* USB Device handle structure */ +typedef struct _USBD_HandleTypeDef { + uint8_t id; + uint32_t dev_config; + uint32_t dev_default_config; + uint32_t dev_config_status; + USBD_SpeedTypeDef dev_speed; + USBD_EndpointTypeDef ep_in[16]; + USBD_EndpointTypeDef ep_out[16]; + uint32_t ep0_state; + uint32_t ep0_data_len; + uint32_t ep0_rem_len; + uint32_t ep0_total_len; + uint8_t dev_state; + uint8_t dev_old_state; + uint8_t dev_address; + uint8_t dev_connection_status; + uint8_t dev_test_mode; + uint32_t dev_remote_wakeup; + + USBD_SetupReqTypedef request; + USBD_DescriptorsTypeDef *pDesc; + USBD_ClassTypeDef *pClass; + +#ifdef USBD_USE_CDC_COMPOSITE // MSC & CDC need separate variable structures + struct _USBD_MSC_BOT_HandleTypeDef *pClassDataMSC; + struct _USBD_STORAGE *pClassSpecificInterfaceMSC; // USBD_StorageTypeDef + struct _USBD_CDC_HandleTypeDef *pClassDataCDC; + struct _USBD_CDC_Itf *pClassSpecificInterfaceCDC; // USBD_CDC_ItfTypeDef + PCD_HandleTypeDef *pPCDHandle; +#else + void *pClassData; + void *pUserData; + void *pData; +#endif + +} USBD_HandleTypeDef; + +/** + * @} + */ + + + +/** @defgroup USBD_DEF_Exported_Macros + * @{ + */ +#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ + (((uint16_t)(*(((uint8_t *)(addr)) + 1U))) << 8U)) + +#define LOBYTE(x) ((uint8_t)((x) & 0x00FFU)) +#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + + +#if defined (__GNUC__) +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif /* __packed */ +#endif /* __GNUC__ */ + + +/* In HS mode and when the DMA is used, all variables and data structures dealing + with the DMA during the transaction process should be 4-bytes aligned */ + +#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ +#ifndef __ALIGN_END +#define __ALIGN_END __attribute__ ((aligned (4U))) +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#define __ALIGN_BEGIN +#endif /* __ALIGN_BEGIN */ +#else +#ifndef __ALIGN_END +#define __ALIGN_END +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#if defined (__CC_ARM) /* ARM Compiler */ +#define __ALIGN_BEGIN __align(4U) +#elif defined (__ICCARM__) /* IAR Compiler */ +#define __ALIGN_BEGIN +#endif /* __CC_ARM */ +#endif /* __ALIGN_BEGIN */ +#endif /* __GNUC__ */ + + +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_FunctionsPrototype + * @{ + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_DEF_H */ + +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/usbd_desc.c b/cores/arduino/stm32/usb/usbd_desc.c index 1e930256c9..c9881dde10 100644 --- a/cores/arduino/stm32/usb/usbd_desc.c +++ b/cores/arduino/stm32/usb/usbd_desc.c @@ -12,15 +12,17 @@ * This software component is licensed by ST under Ultimate Liberty license * SLA0044, 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/SLA0044 + * www.st.com/SLA0044 * ****************************************************************************** */ #ifdef USBCON +#ifndef USBD_USE_CDC_COMPOSITE /* Includes ------------------------------------------------------------------*/ #include "usbd_core.h" #include "usbd_desc.h" #include "utils.h" +#include /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ @@ -301,5 +303,6 @@ static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len) pbuf[ 2 * idx + 1] = 0; } } +#endif /* !USBD_USE_CDC_COMPOSITE*/ #endif /* USBCON */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/cores/arduino/stm32/usb/usbd_desc.h b/cores/arduino/stm32/usb/usbd_desc.h index b0437740f9..5cf49e7831 100644 --- a/cores/arduino/stm32/usb/usbd_desc.h +++ b/cores/arduino/stm32/usb/usbd_desc.h @@ -36,6 +36,12 @@ /* Exported functions ------------------------------------------------------- */ extern USBD_DescriptorsTypeDef USBD_Desc; +#ifdef USBD_USE_HID_COMPOSITE +extern USBD_DescriptorsTypeDef HID_Desc; +#endif +#ifdef USBD_USE_CDC +extern USBD_DescriptorsTypeDef CDC_Desc; +#endif #endif /* USBCON */ #endif /* __USBD_DESC_H*/ diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.c b/cores/arduino/stm32/usb/usbd_ep_conf.c new file mode 100644 index 0000000000..10d69cc462 --- /dev/null +++ b/cores/arduino/stm32/usb/usbd_ep_conf.c @@ -0,0 +1,82 @@ +/** + ****************************************************************************** + * @file usbd_ep_conf.c + * @brief USB Device endpoints configuration + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +#if defined(HAL_PCD_MODULE_ENABLED) && defined(USBCON) +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ep_conf.h" + +#ifdef USBD_USE_CDC +const ep_desc_t ep_def[] = { +#ifdef USBD_USE_CDC_COMPOSITE + {0, 0x080}, // receive buffer // 40 or 80 works but not 100 + {0, 0x040}, // EP0 FIFO size + {1, 0x040}, // EP1 FIFO size + {2, 0x040}, // EP2 FIFO size // 40 works but 100 doesn't + {3, 0x040} // EP3 FIFO size + +// {0, 0x80}, // 40 or 80 works but not 100 +// {0, 0x40}, +// {1, 0x40}, +// {2, 0x40}, +// {3, 0x40} +// +#elif defined(USE_USB_HS) /* USE_USB_FS */ + {0x00, CDC_DATA_HS_MAX_PACKET_SIZE}, + {0x80, CDC_DATA_HS_MAX_PACKET_SIZE}, + {CDC_OUT_EP, CDC_DATA_HS_MAX_PACKET_SIZE}, + {CDC_IN_EP, CDC_DATA_HS_MAX_PACKET_SIZE}, + {CDC_CMD_EP, CDC_CMD_PACKET_SIZE} +#elif defined(USB_OTG_FS) /* USE_USB_FS */ + {0x00, CDC_DATA_FS_MAX_PACKET_SIZE}, + {0x80, CDC_DATA_FS_MAX_PACKET_SIZE}, + {CDC_OUT_EP, CDC_DATA_FS_MAX_PACKET_SIZE}, + {CDC_IN_EP, CDC_DATA_FS_MAX_PACKET_SIZE}, + {CDC_CMD_EP, CDC_CMD_PACKET_SIZE} +#else + {0x00, PMA_EP0_OUT_ADDR, PCD_SNG_BUF}, + {0x80, PMA_EP0_IN_ADDR, PCD_SNG_BUF}, + {CDC_OUT_EP, PMA_CDC_OUT_ADDR, PCD_DBL_BUF}, + {CDC_IN_EP, PMA_CDC_IN_ADDR, PCD_SNG_BUF}, + {CDC_CMD_EP, PMA_CDC_CMD_ADDR, PCD_SNG_BUF} +#endif +}; +#endif /* USBD_USE_CDC */ + +#ifdef USBD_USE_HID_COMPOSITE +const ep_desc_t ep_def[] = { +#if !defined (USB) +#ifdef USE_USB_HS + {0x00, USB_HS_MAX_PACKET_SIZE}, + {0x80, USB_HS_MAX_PACKET_SIZE}, +#else + {0x00, USB_FS_MAX_PACKET_SIZE}, + {0x80, USB_FS_MAX_PACKET_SIZE}, +#endif + {HID_MOUSE_EPIN_ADDR, HID_MOUSE_EPIN_SIZE}, + {HID_KEYBOARD_EPIN_ADDR, HID_KEYBOARD_EPIN_SIZE}, +#else + {0x00, PMA_EP0_OUT_ADDR, PCD_SNG_BUF}, + {0x80, PMA_EP0_IN_ADDR, PCD_SNG_BUF}, + {HID_MOUSE_EPIN_ADDR, PMA_MOUSE_IN_ADDR, PCD_SNG_BUF}, + {HID_KEYBOARD_EPIN_ADDR, PMA_KEYBOARD_IN_ADDR, PCD_SNG_BUF}, +#endif +}; +#endif /* USBD_USE_HID_COMPOSITE */ + +#endif /* HAL_PCD_MODULE_ENABLED && USBCON */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.h b/cores/arduino/stm32/usb/usbd_ep_conf.h new file mode 100644 index 0000000000..6b05eff898 --- /dev/null +++ b/cores/arduino/stm32/usb/usbd_ep_conf.h @@ -0,0 +1,95 @@ +/** + ****************************************************************************** + * @file usbd_ep_conf.h + * @brief USB Device endpoints configuration + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_EP_CONF_H +#define __USBD_EP_CONF_H + +#ifdef USBCON + +#include +#include "usbd_def.h" + +typedef struct { + uint32_t ep_adress; /* Endpoint address */ + uint32_t ep_size; /* Endpoint size */ +#if defined (USB) + uint32_t ep_kind; /* PCD Endpoint Kind: PCD_SNG_BUF or PCD_DBL_BUF */ +#endif +} ep_desc_t; + + +/* CDC Endpoints Configurations */ +#ifdef USBD_USE_CDC + +#ifdef USBD_USE_CDC_COMPOSITE +#define CDC_OUT_EP 0x02U /* EP2 for data OUT */ +#define CDC_IN_EP 0x82U /* EP2 for data IN */ +#define CDC_CMD_EP 0x83U /* EP3 for CDC commands */ +#else +#define CDC_OUT_EP 0x01U /* EP1 for data OUT */ +#define CDC_IN_EP 0x81U /* EP1 for data IN */ +#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */ +#endif + +#define DEV_NUM_EP 0x04U /* Device Endpoints number including EP0 */ + +/* CDC Endpoints parameters*/ +#define CDC_DATA_HS_MAX_PACKET_SIZE USB_HS_MAX_PACKET_SIZE /* Endpoint IN & OUT Packet size */ +#define CDC_DATA_FS_MAX_PACKET_SIZE USB_FS_MAX_PACKET_SIZE /* Endpoint IN & OUT Packet size */ +#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ +#endif /* USBD_USE_CDC */ + + +/* HID composite (Mouse + Keyboard) Endpoints Configurations */ +#ifdef USBD_USE_HID_COMPOSITE +#define HID_MOUSE_EPIN_ADDR 0x81U +#define HID_KEYBOARD_EPIN_ADDR 0x82U + +#define HID_MOUSE_EPIN_SIZE 0x04U +#define HID_KEYBOARD_EPIN_SIZE 0x08U + +#define DEV_NUM_EP 0x03U /* Device Endpoints number including EP0 */ +#endif /* USBD_USE_HID_COMPOSITE */ + +/* Require DEV_NUM_EP to be defined */ +#if defined (USB) +/* Size in words, byte size divided by 2 */ +#define PMA_EP0_OUT_ADDR (8 * DEV_NUM_EP) +#define PMA_EP0_IN_ADDR (PMA_EP0_OUT_ADDR + USB_MAX_EP0_SIZE) + +#ifdef USBD_USE_CDC +#define PMA_CDC_OUT_BASE (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE) +#define PMA_CDC_OUT_ADDR ((PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) | \ + (PMA_CDC_OUT_BASE << 16U)) +#define PMA_CDC_IN_ADDR (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE * 2) +#define PMA_CDC_CMD_ADDR (PMA_CDC_IN_ADDR + CDC_CMD_PACKET_SIZE) +#endif /* USBD_USE_CDC */ +#ifdef USBD_USE_HID_COMPOSITE +#define PMA_MOUSE_IN_ADDR (PMA_EP0_IN_ADDR + HID_MOUSE_EPIN_SIZE) +#define PMA_KEYBOARD_IN_ADDR (PMA_MOUSE_IN_ADDR + HID_KEYBOARD_EPIN_SIZE) +#endif /* USBD_USE_HID_COMPOSITE */ +#endif /* USB */ + +extern const ep_desc_t ep_def[DEV_NUM_EP + 1]; + + +#endif /* USBCON */ +#endif /* __USBD_EP_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ \ No newline at end of file From 4d67833ef505b0e5b98a1bcbfd12db0d5e04d1cf Mon Sep 17 00:00:00 2001 From: Bob-the-Kuhn Date: Fri, 20 Mar 2020 16:18:25 -0500 Subject: [PATCH 2/2] more changes from the working directory --- cores/arduino/stm32/usb/cdc/usbd_cdc.h | 18 ++--- .../stm32/usb/msc_cdc_composite/SdMscDriver.c | 74 +------------------ 2 files changed, 6 insertions(+), 86 deletions(-) diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.h b/cores/arduino/stm32/usb/cdc/usbd_cdc.h index 9fd1fb08c1..869f8e4294 100644 --- a/cores/arduino/stm32/usb/cdc/usbd_cdc.h +++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.h @@ -26,7 +26,8 @@ extern "C" { #endif /* Includes ------------------------------------------------------------------*/ -#include "usbd_ioreq.h" +#include "usbd_ioreq.h" +#include "usbd_ep_conf.h" /** @addtogroup STM32_USB_DEVICE_LIBRARY * @{ @@ -37,26 +38,18 @@ extern "C" { * @{ */ - /** @defgroup usbd_cdc_Exported_Defines * @{ */ -#define CDC_IN_EP 0x82U /* EP1 for data IN */ -#define CDC_OUT_EP 0x01U /* EP1 for data OUT */ -#define CDC_CMD_EP 0x83U /* EP2 for CDC commands */ - #ifndef CDC_HS_BINTERVAL -#define CDC_HS_BINTERVAL 0x10U +#define CDC_HS_BINTERVAL 0x10U #endif /* CDC_HS_BINTERVAL */ #ifndef CDC_FS_BINTERVAL -#define CDC_FS_BINTERVAL 0x10U +#define CDC_FS_BINTERVAL 0x10U #endif /* CDC_FS_BINTERVAL */ -/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ -#define CDC_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ -#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ -#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ +/* CDC Endpoints parameters */ #define USB_CDC_CONFIG_DESC_SIZ 67U #define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE @@ -115,7 +108,6 @@ typedef struct { uint8_t *TxBuffer; uint32_t RxLength; uint32_t TxLength; - uint32_t TxLastLength; __IO uint32_t TxState; __IO uint32_t RxState; diff --git a/cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.c b/cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.c index 619a76ed20..b64c63579a 100644 --- a/cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.c +++ b/cores/arduino/stm32/usb/msc_cdc_composite/SdMscDriver.c @@ -52,77 +52,6 @@ HAL_StatusTypeDef SD_SDIO_Init(); #define TRANSFER_CLOCK_DIV ((uint8_t)SDIO_INIT_CLK_DIV/40) - -HAL_SD_CardStatusTypeDef bob_get_CardStatus() { //bob - - HAL_SD_CardStatusTypeDef temp; - - HAL_SD_GetCardStatus(&hsd, &temp); - - - //temp.DataBusWidth= pStatus.DataBusWidth & 0x03; /*!< uint8_t Shows the currently defined data bus width */ - //temp.SecuredMode= pStatus.SecuredMode & 0x01; /*!< uint8_t Card is in secured mode of operation */ - //temp.CardType= pStatus.CardType; /*!< uint16_t Carries information about card type */ - //temp.ProtectedAreaSize= pStatus.ProtectedAreaSize; /*!< uint32_t Carries information about the capacity of protected area */ - //temp.SpeedClass= pStatus.SpeedClass; /*!< uint8_t Carries information about the speed class of the card */ - //temp.PerformanceMove= pStatus.PerformanceMove; /*!< uint8_t Carries information about the card's performance move */ - //temp.AllocationUnitSize= pStatus.AllocationUnitSize; /*!< uint8_t Carries information about the card's allocation unit size */ - //temp.EraseSize= pStatus.EraseSize; /*!< uint16_t Determines the number of AUs to be erased in one operation */ - //temp.EraseTimeout= pStatus.EraseTimeout; /*!< uint8_t Determines the timeout for any number of AU erase */ - //temp.EraseOffset= pStatus.EraseOffset; /*!< uint8_t Carries information about the erase offset */ - - return temp; -} - -struct bob_CSD { - uint32_t bob_CSD_0; - uint32_t bob_CSD_1; - uint32_t bob_CSD_2; - uint32_t bob_CSD_3; -}; - - - - -struct bob_CSD bob_get_CSD() { - struct bob_CSD temp; - - temp.bob_CSD_0 = hsd.CSD[0]; - temp.bob_CSD_1 = hsd.CSD[1]; - temp.bob_CSD_2 = hsd.CSD[2]; - temp.bob_CSD_3 = hsd.CSD[3]; - - return temp; -} - -struct bob_CSD bob_get_CID() { - struct bob_CSD temp; - - temp.bob_CSD_0 = hsd.CID[0]; - temp.bob_CSD_1 = hsd.CID[1]; - temp.bob_CSD_2 = hsd.CID[2]; - temp.bob_CSD_3 = hsd.CID[3]; - - return temp; -} - -struct bob_SECTOR { - uint8_t bob_sector[512]; - int8_t status; -}; - -int8_t SD_MSC_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); - -struct bob_SECTOR bob_sector_read(uint32_t sector) { - struct bob_SECTOR temp; - - temp.status = SD_MSC_Read(0, temp.bob_sector, sector, 1); - - return temp; -} - - - void go_to_transfer_speed() { SD_InitTypeDef Init; @@ -133,8 +62,7 @@ void go_to_transfer_speed() { Init.ClockPowerSave = hsd.Init.ClockPowerSave; Init.BusWide = hsd.Init.BusWide; Init.HardwareFlowControl = hsd.Init.HardwareFlowControl; -// Init.ClockDiv = TRANSFER_CLOCK_DIV; - Init.ClockDiv = SDIO_INIT_CLK_DIV; + Init.ClockDiv = TRANSFER_CLOCK_DIV; /* Initialize SDIO peripheral interface with default configuration */ SDIO_Init(hsd.Instance, Init);