Browse Source

stm32/usbdev: Put all CDC state in a struct.

pull/3239/merge
Damien George 7 years ago
parent
commit
980b33177b
  1. 52
      ports/stm32/usb.c
  2. 202
      ports/stm32/usbd_cdc_interface.c
  3. 111
      ports/stm32/usbd_cdc_interface.h
  4. 20
      ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h
  5. 45
      ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c
  6. 20
      ports/stm32/usbdev/class/src/usbd_msc_bot.c
  7. 34
      ports/stm32/usbdev/class/src/usbd_msc_scsi.c

52
ports/stm32/usb.c

@ -55,6 +55,8 @@ mp_uint_t pyb_usb_flags = 0;
#ifdef USE_DEVICE_MODE
STATIC USBD_HandleTypeDef hUSBDDevice;
STATIC usbd_cdc_msc_hid_state_t usbd_cdc_msc_hid_state;
STATIC usbd_cdc_itf_t usbd_cdc_itf;
pyb_usb_storage_medium_t pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_NONE;
#endif
@ -105,25 +107,37 @@ bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_H
#ifdef USE_DEVICE_MODE
if (!(pyb_usb_flags & PYB_USB_FLAG_DEV_ENABLED)) {
// only init USB once in the device's power-lifetime
// configure the VID, PID and the USBD mode (interfaces it will expose)
USBD_SetVIDPIDRelease(vid, pid, 0x0200, mode == USBD_MODE_CDC);
if (USBD_SelectMode(mode, hid_info) != 0) {
return false;
}
USBD_Init(&hUSBDDevice, (USBD_DescriptorsTypeDef*)&USBD_Descriptors, USB_PHY_ID);
USBD_RegisterClass(&hUSBDDevice, &USBD_CDC_MSC_HID);
USBD_CDC_RegisterInterface(&hUSBDDevice, (USBD_CDC_ItfTypeDef*)&USBD_CDC_fops);
// set up the USBD state
USBD_HandleTypeDef *usbd = &hUSBDDevice;
usbd->id = USB_PHY_ID;
usbd->dev_state = USBD_STATE_DEFAULT;
usbd->pDesc = (USBD_DescriptorsTypeDef*)&USBD_Descriptors;
usbd->pClass = &USBD_CDC_MSC_HID;
usbd_cdc_msc_hid_state.cdc = &usbd_cdc_itf;
usbd->pClassData = &usbd_cdc_msc_hid_state;
switch (pyb_usb_storage_medium) {
#if MICROPY_HW_HAS_SDCARD
case PYB_USB_STORAGE_MEDIUM_SDCARD:
USBD_MSC_RegisterStorage(&hUSBDDevice, (USBD_StorageTypeDef*)&USBD_SDCARD_STORAGE_fops);
USBD_MSC_RegisterStorage(usbd, (USBD_StorageTypeDef*)&USBD_SDCARD_STORAGE_fops);
break;
#endif
default:
USBD_MSC_RegisterStorage(&hUSBDDevice, (USBD_StorageTypeDef*)&USBD_FLASH_STORAGE_fops);
USBD_MSC_RegisterStorage(usbd, (USBD_StorageTypeDef*)&USBD_FLASH_STORAGE_fops);
break;
}
USBD_HID_RegisterInterface(&hUSBDDevice, (USBD_HID_ItfTypeDef*)&USBD_HID_fops);
USBD_Start(&hUSBDDevice);
USBD_HID_RegisterInterface(usbd, (USBD_HID_ItfTypeDef*)&USBD_HID_fops);
// start the USB device
USBD_LL_Init(usbd);
USBD_LL_Start(usbd);
}
pyb_usb_flags |= PYB_USB_FLAG_DEV_ENABLED;
#endif
@ -143,13 +157,13 @@ bool usb_vcp_is_enabled(void) {
}
int usb_vcp_recv_byte(uint8_t *c) {
return USBD_CDC_Rx(c, 1, 0);
return usbd_cdc_rx(&usbd_cdc_itf, c, 1, 0);
}
void usb_vcp_send_strn(const char *str, int len) {
#ifdef USE_DEVICE_MODE
if (pyb_usb_flags & PYB_USB_FLAG_DEV_ENABLED) {
USBD_CDC_TxAlways((const uint8_t*)str, len);
usbd_cdc_tx_always(&usbd_cdc_itf, (const uint8_t*)str, len);
}
#endif
}
@ -159,9 +173,9 @@ void usb_vcp_send_strn_cooked(const char *str, int len) {
if (pyb_usb_flags & PYB_USB_FLAG_DEV_ENABLED) {
for (const char *top = str + len; str < top; str++) {
if (*str == '\n') {
USBD_CDC_TxAlways((const uint8_t*)"\r\n", 2);
usbd_cdc_tx_always(&usbd_cdc_itf, (const uint8_t*)"\r\n", 2);
} else {
USBD_CDC_TxAlways((const uint8_t*)str, 1);
usbd_cdc_tx_always(&usbd_cdc_itf, (const uint8_t*)str, 1);
}
}
}
@ -362,7 +376,7 @@ STATIC mp_obj_t pyb_usb_vcp_setinterrupt(mp_obj_t self_in, mp_obj_t int_chr_in)
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_usb_vcp_setinterrupt_obj, pyb_usb_vcp_setinterrupt);
STATIC mp_obj_t pyb_usb_vcp_isconnected(mp_obj_t self_in) {
return mp_obj_new_bool(USBD_CDC_IsConnected());
return mp_obj_new_bool(usbd_cdc_is_connected(&usbd_cdc_itf));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_usb_vcp_isconnected_obj, pyb_usb_vcp_isconnected);
@ -375,7 +389,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(pyb_have_cdc_obj, pyb_have_cdc);
/// \method any()
/// Return `True` if any characters waiting, else `False`.
STATIC mp_obj_t pyb_usb_vcp_any(mp_obj_t self_in) {
if (USBD_CDC_RxNum() > 0) {
if (usbd_cdc_rx_num(&usbd_cdc_itf) > 0) {
return mp_const_true;
} else {
return mp_const_false;
@ -407,7 +421,7 @@ STATIC mp_obj_t pyb_usb_vcp_send(size_t n_args, const mp_obj_t *args, mp_map_t *
pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data);
// send the data
int ret = USBD_CDC_Tx(bufinfo.buf, bufinfo.len, vals[1].u_int);
int ret = usbd_cdc_tx(&usbd_cdc_itf, bufinfo.buf, bufinfo.len, vals[1].u_int);
return mp_obj_new_int(ret);
}
@ -433,7 +447,7 @@ STATIC mp_obj_t pyb_usb_vcp_recv(size_t n_args, const mp_obj_t *args, mp_map_t *
mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &vstr);
// receive the data
int ret = USBD_CDC_Rx((uint8_t*)vstr.buf, vstr.len, vals[1].u_int);
int ret = usbd_cdc_rx(&usbd_cdc_itf, (uint8_t*)vstr.buf, vstr.len, vals[1].u_int);
// return the received data
if (o_ret != MP_OBJ_NULL) {
@ -470,7 +484,7 @@ STATIC const mp_rom_map_elem_t pyb_usb_vcp_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(pyb_usb_vcp_locals_dict, pyb_usb_vcp_locals_dict_table);
STATIC mp_uint_t pyb_usb_vcp_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
int ret = USBD_CDC_Rx((byte*)buf, size, 0);
int ret = usbd_cdc_rx(&usbd_cdc_itf, (byte*)buf, size, 0);
if (ret == 0) {
// return EAGAIN error to indicate non-blocking
*errcode = MP_EAGAIN;
@ -480,7 +494,7 @@ STATIC mp_uint_t pyb_usb_vcp_read(mp_obj_t self_in, void *buf, mp_uint_t size, i
}
STATIC mp_uint_t pyb_usb_vcp_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
int ret = USBD_CDC_Tx((const byte*)buf, size, 0);
int ret = usbd_cdc_tx(&usbd_cdc_itf, (const byte*)buf, size, 0);
if (ret == 0) {
// return EAGAIN error to indicate non-blocking
*errcode = MP_EAGAIN;
@ -494,10 +508,10 @@ STATIC mp_uint_t pyb_usb_vcp_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_
if (request == MP_STREAM_POLL) {
mp_uint_t flags = arg;
ret = 0;
if ((flags & MP_STREAM_POLL_RD) && USBD_CDC_RxNum() > 0) {
if ((flags & MP_STREAM_POLL_RD) && usbd_cdc_rx_num(&usbd_cdc_itf) > 0) {
ret |= MP_STREAM_POLL_RD;
}
if ((flags & MP_STREAM_POLL_WR) && USBD_CDC_TxHalfEmpty()) {
if ((flags & MP_STREAM_POLL_WR) && usbd_cdc_tx_half_empty(&usbd_cdc_itf)) {
ret |= MP_STREAM_POLL_WR;
}
} else {

202
ports/stm32/usbd_cdc_interface.c

@ -41,12 +41,9 @@
#include "usbd_cdc_interface.h"
#include "pendsv.h"
#include "py/mpstate.h"
#include "py/obj.h"
#include "lib/utils/interrupt_char.h"
#include "irq.h"
#include "timer.h"
#include "usb.h"
// CDC control commands
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00
@ -59,78 +56,26 @@
#define CDC_SET_CONTROL_LINE_STATE 0x22
#define CDC_SEND_BREAK 0x23
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define APP_RX_DATA_SIZE 1024 // this must be 2 or greater, and a power of 2
#define APP_TX_DATA_SIZE 1024 // I think this can be any value (was 2048)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static __IO uint8_t dev_is_connected = 0; // indicates if we are connected
static uint8_t cdc_rx_packet_buf[CDC_DATA_FS_MAX_PACKET_SIZE]; // received data from USB OUT endpoint is stored in this buffer
static uint8_t cdc_rx_user_buf[APP_RX_DATA_SIZE]; // received data is buffered here until the user reads it
static volatile uint16_t cdc_rx_buf_put = 0; // circular buffer index
static uint16_t cdc_rx_buf_get = 0; // circular buffer index
static uint8_t UserTxBuffer[APP_TX_DATA_SIZE]; // data for USB IN endpoind is stored in this buffer
static uint16_t UserTxBufPtrIn = 0; // increment this pointer modulo APP_TX_DATA_SIZE when new data is available
static __IO uint16_t UserTxBufPtrOut = 0; // increment this pointer modulo APP_TX_DATA_SIZE when data is drained
static uint16_t UserTxBufPtrOutShadow = 0; // shadow of above
static uint8_t UserTxBufPtrWaitCount = 0; // used to implement a timeout waiting for low-level USB driver
static uint8_t UserTxNeedEmptyPacket = 0; // used to flush the USB IN endpoint if the last packet was exactly the endpoint packet size
/* Private function prototypes -----------------------------------------------*/
static int8_t CDC_Itf_Init (USBD_HandleTypeDef *pdev);
static int8_t CDC_Itf_DeInit (void);
static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length);
static int8_t CDC_Itf_Receive (USBD_HandleTypeDef *pdev, uint8_t* pbuf, uint32_t *Len);
const USBD_CDC_ItfTypeDef USBD_CDC_fops = {
CDC_Itf_Init,
CDC_Itf_DeInit,
CDC_Itf_Control,
CDC_Itf_Receive
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief CDC_Itf_Init
* Initializes the CDC media low layer
* @param None
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Itf_Init(USBD_HandleTypeDef *pdev) {
USBD_CDC_SetTxBuffer(pdev, UserTxBuffer, 0);
USBD_CDC_SetRxBuffer(pdev, cdc_rx_packet_buf);
cdc_rx_buf_put = 0;
cdc_rx_buf_get = 0;
return USBD_OK;
void usbd_cdc_init(usbd_cdc_itf_t *cdc, USBD_HandleTypeDef *pdev) {
cdc->usb = pdev;
cdc->rx_buf_put = 0;
cdc->rx_buf_get = 0;
cdc->tx_buf_ptr_in = 0;
cdc->tx_buf_ptr_out = 0;
cdc->tx_buf_ptr_out_shadow = 0;
cdc->tx_buf_ptr_wait_count = 0;
cdc->tx_need_empty_packet = 0;
cdc->dev_is_connected = 0;
USBD_CDC_SetTxBuffer(pdev, cdc->tx_buf, 0);
USBD_CDC_SetRxBuffer(pdev, cdc->rx_packet_buf);
}
/**
* @brief CDC_Itf_DeInit
* DeInitializes the CDC media low layer
* @param None
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Itf_DeInit(void) {
return USBD_OK;
}
/**
* @brief CDC_Itf_Control
* Manage the CDC class requests
* @param Cmd: Command code
* @param Buf: Buffer containing command data (request parameters)
* @param Len: Number of data to be sent (in bytes)
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Itf_Control(uint8_t cmd, uint8_t* pbuf, uint16_t length) {
// Manage the CDC class requests
// cmd: command code
// pbuf: buffer containing command data (request parameters)
// length: number of data to be sent (in bytes)
// Returns USBD_OK if all operations are OK else USBD_FAIL
int8_t usbd_cdc_control(usbd_cdc_itf_t *cdc, uint8_t cmd, uint8_t* pbuf, uint16_t length) {
switch (cmd) {
case CDC_SEND_ENCAPSULATED_COMMAND:
/* Add your code here */
@ -175,7 +120,7 @@ static int8_t CDC_Itf_Control(uint8_t cmd, uint8_t* pbuf, uint16_t length) {
break;
case CDC_SET_CONTROL_LINE_STATE:
dev_is_connected = length & 1; // wValue is passed in Len (bit of a hack)
cdc->dev_is_connected = length & 1; // wValue is passed in Len (bit of a hack)
break;
case CDC_SEND_BREAK:
@ -193,53 +138,56 @@ static int8_t CDC_Itf_Control(uint8_t cmd, uint8_t* pbuf, uint16_t length) {
// SOF (start of frame) callback so that it is called exactly at the time it is
// needed (reducing latency), and often enough (increasing bandwidth).
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
if (!dev_is_connected) {
usbd_cdc_msc_hid_state_t *usbd = ((USBD_HandleTypeDef*)hpcd->pData)->pClassData;
usbd_cdc_itf_t *cdc = usbd->cdc;
if (cdc == NULL || !cdc->dev_is_connected) {
// CDC device is not connected to a host, so we are unable to send any data
return;
}
if (UserTxBufPtrOut == UserTxBufPtrIn && !UserTxNeedEmptyPacket) {
if (cdc->tx_buf_ptr_out == cdc->tx_buf_ptr_in && !cdc->tx_need_empty_packet) {
// No outstanding data to send
return;
}
if (UserTxBufPtrOut != UserTxBufPtrOutShadow) {
if (cdc->tx_buf_ptr_out != cdc->tx_buf_ptr_out_shadow) {
// We have sent data and are waiting for the low-level USB driver to
// finish sending it over the USB in-endpoint.
// SOF occurs every 1ms, so we have a 500 * 1ms = 500ms timeout
// We have a relatively large timeout because the USB host may be busy
// doing other things and we must give it a chance to read our data.
if (UserTxBufPtrWaitCount < 500) {
if (cdc->tx_buf_ptr_wait_count < 500) {
USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
if (USBx_INEP(CDC_IN_EP & 0x7f)->DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ) {
// USB in-endpoint is still reading the data
UserTxBufPtrWaitCount++;
cdc->tx_buf_ptr_wait_count++;
return;
}
}
UserTxBufPtrOut = UserTxBufPtrOutShadow;
cdc->tx_buf_ptr_out = cdc->tx_buf_ptr_out_shadow;
}
if (UserTxBufPtrOutShadow != UserTxBufPtrIn || UserTxNeedEmptyPacket) {
if (cdc->tx_buf_ptr_out_shadow != cdc->tx_buf_ptr_in || cdc->tx_need_empty_packet) {
uint32_t buffptr;
uint32_t buffsize;
if (UserTxBufPtrOutShadow > UserTxBufPtrIn) { // rollback
buffsize = APP_TX_DATA_SIZE - UserTxBufPtrOutShadow;
if (cdc->tx_buf_ptr_out_shadow > cdc->tx_buf_ptr_in) { // rollback
buffsize = USBD_CDC_TX_DATA_SIZE - cdc->tx_buf_ptr_out_shadow;
} else {
buffsize = UserTxBufPtrIn - UserTxBufPtrOutShadow;
buffsize = cdc->tx_buf_ptr_in - cdc->tx_buf_ptr_out_shadow;
}
buffptr = UserTxBufPtrOutShadow;
buffptr = cdc->tx_buf_ptr_out_shadow;
USBD_CDC_SetTxBuffer(hpcd->pData, (uint8_t*)&UserTxBuffer[buffptr], buffsize);
USBD_CDC_SetTxBuffer(hpcd->pData, (uint8_t*)&cdc->tx_buf[buffptr], buffsize);
if (USBD_CDC_TransmitPacket(hpcd->pData) == USBD_OK) {
UserTxBufPtrOutShadow += buffsize;
if (UserTxBufPtrOutShadow == APP_TX_DATA_SIZE) {
UserTxBufPtrOutShadow = 0;
cdc->tx_buf_ptr_out_shadow += buffsize;
if (cdc->tx_buf_ptr_out_shadow == USBD_CDC_TX_DATA_SIZE) {
cdc->tx_buf_ptr_out_shadow = 0;
}
UserTxBufPtrWaitCount = 0;
cdc->tx_buf_ptr_wait_count = 0;
// According to the USB specification, a packet size of 64 bytes (CDC_DATA_FS_MAX_PACKET_SIZE)
// gets held at the USB host until the next packet is sent. This is because a
@ -247,62 +195,54 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
// the host waits for all data to arrive (ie, waits for a packet < max packet size).
// To flush a packet of exactly max packet size, we need to send a zero-size packet.
// See eg http://www.cypress.com/?id=4&rID=92719
UserTxNeedEmptyPacket = (buffsize > 0 && buffsize % CDC_DATA_FS_MAX_PACKET_SIZE == 0 && UserTxBufPtrOutShadow == UserTxBufPtrIn);
cdc->tx_need_empty_packet = (buffsize > 0 && buffsize % CDC_DATA_FS_MAX_PACKET_SIZE == 0 && cdc->tx_buf_ptr_out_shadow == cdc->tx_buf_ptr_in);
}
}
}
/**
* @brief CDC_Itf_DataRx
* Data received over USB OUT endpoint is processed here.
* @param Buf: Buffer of data received
* @param Len: Number of data received (in bytes)
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
* @note The buffer we are passed here is just cdc_rx_packet_buf, so we are
* free to modify it.
*/
static int8_t CDC_Itf_Receive(USBD_HandleTypeDef *pdev, uint8_t* Buf, uint32_t *Len) {
// Data received over USB OUT endpoint is processed here.
// Buf: buffer of data received
// Len: number of data received (in bytes)
// Returns USBD_OK if all operations are OK else USBD_FAIL
// The buffer we are passed here is just cdc_rx_packet_buf, so we are free to modify it.
int8_t usbd_cdc_receive(usbd_cdc_itf_t *cdc, uint8_t* Buf, uint32_t *Len) {
// copy the incoming data into the circular buffer
for (uint8_t *src = Buf, *top = Buf + *Len; src < top; ++src) {
if (mp_interrupt_char != -1 && *src == mp_interrupt_char) {
pendsv_kbd_intr();
} else {
uint16_t next_put = (cdc_rx_buf_put + 1) & (APP_RX_DATA_SIZE - 1);
if (next_put == cdc_rx_buf_get) {
uint16_t next_put = (cdc->rx_buf_put + 1) & (USBD_CDC_RX_DATA_SIZE - 1);
if (next_put == cdc->rx_buf_get) {
// overflow, we just discard the rest of the chars
break;
}
cdc_rx_user_buf[cdc_rx_buf_put] = *src;
cdc_rx_buf_put = next_put;
cdc->rx_user_buf[cdc->rx_buf_put] = *src;
cdc->rx_buf_put = next_put;
}
}
// initiate next USB packet transfer
USBD_CDC_SetRxBuffer(pdev, cdc_rx_packet_buf);
USBD_CDC_ReceivePacket(pdev);
USBD_CDC_SetRxBuffer(cdc->usb, cdc->rx_packet_buf);
USBD_CDC_ReceivePacket(cdc->usb);
return USBD_OK;
}
int USBD_CDC_IsConnected(void) {
return dev_is_connected;
}
int USBD_CDC_TxHalfEmpty(void) {
int32_t tx_waiting = (int32_t)UserTxBufPtrIn - (int32_t)UserTxBufPtrOut;
int usbd_cdc_tx_half_empty(usbd_cdc_itf_t *cdc) {
int32_t tx_waiting = (int32_t)cdc->tx_buf_ptr_in - (int32_t)cdc->tx_buf_ptr_out;
if (tx_waiting < 0) {
tx_waiting += APP_TX_DATA_SIZE;
tx_waiting += USBD_CDC_TX_DATA_SIZE;
}
return tx_waiting <= APP_TX_DATA_SIZE / 2;
return tx_waiting <= USBD_CDC_TX_DATA_SIZE / 2;
}
// timout in milliseconds.
// Returns number of bytes written to the device.
int USBD_CDC_Tx(const uint8_t *buf, uint32_t len, uint32_t timeout) {
int usbd_cdc_tx(usbd_cdc_itf_t *cdc, const uint8_t *buf, uint32_t len, uint32_t timeout) {
for (uint32_t i = 0; i < len; i++) {
// Wait until the device is connected and the buffer has space, with a given timeout
uint32_t start = HAL_GetTick();
while (!dev_is_connected || ((UserTxBufPtrIn + 1) & (APP_TX_DATA_SIZE - 1)) == UserTxBufPtrOut) {
while (!cdc->dev_is_connected || ((cdc->tx_buf_ptr_in + 1) & (USBD_CDC_TX_DATA_SIZE - 1)) == cdc->tx_buf_ptr_out) {
// Wraparound of tick is taken care of by 2's complement arithmetic.
if (HAL_GetTick() - start >= timeout) {
// timeout
@ -316,8 +256,8 @@ int USBD_CDC_Tx(const uint8_t *buf, uint32_t len, uint32_t timeout) {
}
// Write data to device buffer
UserTxBuffer[UserTxBufPtrIn] = buf[i];
UserTxBufPtrIn = (UserTxBufPtrIn + 1) & (APP_TX_DATA_SIZE - 1);
cdc->tx_buf[cdc->tx_buf_ptr_in] = buf[i];
cdc->tx_buf_ptr_in = (cdc->tx_buf_ptr_in + 1) & (USBD_CDC_TX_DATA_SIZE - 1);
}
// Success, return number of bytes read
@ -327,18 +267,18 @@ int USBD_CDC_Tx(const uint8_t *buf, uint32_t len, uint32_t timeout) {
// Always write all of the data to the device tx buffer, even if the
// device is not connected, or if the buffer is full. Has a small timeout
// to wait for the buffer to be drained, in the case the device is connected.
void USBD_CDC_TxAlways(const uint8_t *buf, uint32_t len) {
void usbd_cdc_tx_always(usbd_cdc_itf_t *cdc, const uint8_t *buf, uint32_t len) {
for (int i = 0; i < len; i++) {
// If the CDC device is not connected to the host then we don't have anyone to receive our data.
// The device may become connected in the future, so we should at least try to fill the buffer
// and hope that it doesn't overflow by the time the device connects.
// If the device is not connected then we should go ahead and fill the buffer straight away,
// ignoring overflow. Otherwise, we should make sure that we have enough room in the buffer.
if (dev_is_connected) {
if (cdc->dev_is_connected) {
// If the buffer is full, wait until it gets drained, with a timeout of 500ms
// (wraparound of tick is taken care of by 2's complement arithmetic).
uint32_t start = HAL_GetTick();
while (((UserTxBufPtrIn + 1) & (APP_TX_DATA_SIZE - 1)) == UserTxBufPtrOut && HAL_GetTick() - start <= 500) {
while (((cdc->tx_buf_ptr_in + 1) & (USBD_CDC_TX_DATA_SIZE - 1)) == cdc->tx_buf_ptr_out && HAL_GetTick() - start <= 500) {
if (query_irq() == IRQ_STATE_DISABLED) {
// IRQs disabled so buffer will never be drained; exit loop
break;
@ -365,28 +305,28 @@ void USBD_CDC_TxAlways(const uint8_t *buf, uint32_t len) {
*/
}
UserTxBuffer[UserTxBufPtrIn] = buf[i];
UserTxBufPtrIn = (UserTxBufPtrIn + 1) & (APP_TX_DATA_SIZE - 1);
cdc->tx_buf[cdc->tx_buf_ptr_in] = buf[i];
cdc->tx_buf_ptr_in = (cdc->tx_buf_ptr_in + 1) & (USBD_CDC_TX_DATA_SIZE - 1);
}
}
// Returns number of bytes in the rx buffer.
int USBD_CDC_RxNum(void) {
int32_t rx_waiting = (int32_t)cdc_rx_buf_put - (int32_t)cdc_rx_buf_get;
int usbd_cdc_rx_num(usbd_cdc_itf_t *cdc) {
int32_t rx_waiting = (int32_t)cdc->rx_buf_put - (int32_t)cdc->rx_buf_get;
if (rx_waiting < 0) {
rx_waiting += APP_RX_DATA_SIZE;
rx_waiting += USBD_CDC_RX_DATA_SIZE;
}
return rx_waiting;
}
// timout in milliseconds.
// Returns number of bytes read from the device.
int USBD_CDC_Rx(uint8_t *buf, uint32_t len, uint32_t timeout) {
int usbd_cdc_rx(usbd_cdc_itf_t *cdc, uint8_t *buf, uint32_t len, uint32_t timeout) {
// loop to read bytes
for (uint32_t i = 0; i < len; i++) {
// Wait until we have at least 1 byte to read
uint32_t start = HAL_GetTick();
while (cdc_rx_buf_put == cdc_rx_buf_get) {
while (cdc->rx_buf_put == cdc->rx_buf_get) {
// Wraparound of tick is taken care of by 2's complement arithmetic.
if (HAL_GetTick() - start >= timeout) {
// timeout
@ -400,8 +340,8 @@ int USBD_CDC_Rx(uint8_t *buf, uint32_t len, uint32_t timeout) {
}
// Copy byte from device to user buffer
buf[i] = cdc_rx_user_buf[cdc_rx_buf_get];
cdc_rx_buf_get = (cdc_rx_buf_get + 1) & (APP_RX_DATA_SIZE - 1);
buf[i] = cdc->rx_user_buf[cdc->rx_buf_get];
cdc->rx_buf_get = (cdc->rx_buf_get + 1) & (USBD_CDC_RX_DATA_SIZE - 1);
}
// Success, return number of bytes read

111
ports/stm32/usbd_cdc_interface.h

@ -1,45 +1,66 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*/
#ifndef MICROPY_INCLUDED_STMHAL_USBD_CDC_INTERFACE_H
#define MICROPY_INCLUDED_STMHAL_USBD_CDC_INTERFACE_H
/**
******************************************************************************
* @file USB_Device/CDC_Standalone/Inc/usbd_cdc_interface.h
* @author MCD Application Team
* @version V1.0.1
* @date 26-February-2014
* @brief Header for usbd_cdc_interface.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
*
* 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.
*
******************************************************************************
*/
extern const USBD_CDC_ItfTypeDef USBD_CDC_fops;
int USBD_CDC_IsConnected(void);
int USBD_CDC_TxHalfEmpty(void);
int USBD_CDC_Tx(const uint8_t *buf, uint32_t len, uint32_t timeout);
void USBD_CDC_TxAlways(const uint8_t *buf, uint32_t len);
int USBD_CDC_RxNum(void);
int USBD_CDC_Rx(uint8_t *buf, uint32_t len, uint32_t timeout);
#endif // MICROPY_INCLUDED_STMHAL_USBD_CDC_INTERFACE_H
/*
* This file is part of the MicroPython project, http://micropython.org/
*/
#ifndef MICROPY_INCLUDED_STMHAL_USBD_CDC_INTERFACE_H
#define MICROPY_INCLUDED_STMHAL_USBD_CDC_INTERFACE_H
/**
******************************************************************************
* @file USB_Device/CDC_Standalone/Inc/usbd_cdc_interface.h
* @author MCD Application Team
* @version V1.0.1
* @date 26-February-2014
* @brief Header for usbd_cdc_interface.c file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
*
* 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.
*
******************************************************************************
*/
#define USBD_CDC_RX_DATA_SIZE (1024) // this must be 2 or greater, and a power of 2
#define USBD_CDC_TX_DATA_SIZE (1024) // I think this can be any value (was 2048)
typedef struct _usbd_cdc_itf_t {
USBD_HandleTypeDef *usb; // the parent USB device
uint8_t rx_packet_buf[CDC_DATA_FS_MAX_PACKET_SIZE]; // received data from USB OUT endpoint is stored in this buffer
uint8_t rx_user_buf[USBD_CDC_RX_DATA_SIZE]; // received data is buffered here until the user reads it
volatile uint16_t rx_buf_put; // circular buffer index
uint16_t rx_buf_get; // circular buffer index
uint8_t tx_buf[USBD_CDC_TX_DATA_SIZE]; // data for USB IN endpoind is stored in this buffer
uint16_t tx_buf_ptr_in; // increment this pointer modulo APP_TX_DATA_SIZE when new data is available
volatile uint16_t tx_buf_ptr_out; // increment this pointer modulo APP_TX_DATA_SIZE when data is drained
uint16_t tx_buf_ptr_out_shadow; // shadow of above
uint8_t tx_buf_ptr_wait_count; // used to implement a timeout waiting for low-level USB driver
uint8_t tx_need_empty_packet; // used to flush the USB IN endpoint if the last packet was exactly the endpoint packet size
volatile uint8_t dev_is_connected; // indicates if we are connected
} usbd_cdc_itf_t;
static inline int usbd_cdc_is_connected(usbd_cdc_itf_t *cdc) {
return cdc->dev_is_connected;
}
int usbd_cdc_tx_half_empty(usbd_cdc_itf_t *cdc);
int usbd_cdc_tx(usbd_cdc_itf_t *cdc, const uint8_t *buf, uint32_t len, uint32_t timeout);
void usbd_cdc_tx_always(usbd_cdc_itf_t *cdc, const uint8_t *buf, uint32_t len);
int usbd_cdc_rx_num(usbd_cdc_itf_t *cdc);
int usbd_cdc_rx(usbd_cdc_itf_t *cdc, uint8_t *buf, uint32_t len, uint32_t timeout);
#endif // MICROPY_INCLUDED_STMHAL_USBD_CDC_INTERFACE_H

20
ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h

@ -27,13 +27,6 @@ typedef struct {
uint8_t datatype;
} USBD_CDC_LineCodingTypeDef;
typedef struct _USBD_CDC_Itf {
int8_t (* Init) (USBD_HandleTypeDef *pdev);
int8_t (* DeInit) (void);
int8_t (* Control) (uint8_t, uint8_t * , uint16_t);
int8_t (* Receive) (USBD_HandleTypeDef *pdev, uint8_t *, uint32_t *);
} USBD_CDC_ItfTypeDef;
typedef struct {
uint32_t data[CDC_DATA_FS_MAX_PACKET_SIZE/4]; /* Force 32bits alignment */
uint8_t CmdOpCode;
@ -86,6 +79,12 @@ typedef struct {
uint32_t scsi_blk_len;
} USBD_MSC_BOT_HandleTypeDef;
typedef struct _usbd_cdc_msc_hid_state_t {
void *cdc;
void *msc;
void *hid;
} usbd_cdc_msc_hid_state_t;
#define USBD_HID_MOUSE_MAX_PACKET (4)
#define USBD_HID_MOUSE_REPORT_DESC_SIZE (74)
@ -103,7 +102,6 @@ int USBD_SelectMode(uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info);
// returns the current usb mode
uint8_t USBD_GetMode();
uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, USBD_CDC_ItfTypeDef *fops);
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);
@ -119,4 +117,10 @@ uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t
uint8_t USBD_HID_SetNAK(USBD_HandleTypeDef *pdev);
uint8_t USBD_HID_ClearNAK(USBD_HandleTypeDef *pdev);
// These are provided externally to implement the CDC interface
struct _usbd_cdc_itf_t;
void usbd_cdc_init(struct _usbd_cdc_itf_t *cdc, USBD_HandleTypeDef *pdev);
int8_t usbd_cdc_control(struct _usbd_cdc_itf_t *cdc, uint8_t cmd, uint8_t* pbuf, uint16_t length);
int8_t usbd_cdc_receive(struct _usbd_cdc_itf_t *cdc, uint8_t* Buf, uint32_t *Len);
#endif // _USB_CDC_MSC_CORE_H_

45
ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c

@ -95,7 +95,6 @@ static uint8_t usbd_config_desc_size;
static uint8_t *hid_desc;
static const uint8_t *hid_report_desc;
static USBD_CDC_ItfTypeDef *CDC_fops;
static USBD_StorageTypeDef *MSC_fops;
static USBD_HID_ItfTypeDef *HID_fops;
@ -647,6 +646,8 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
return 1;
}
usbd_cdc_msc_hid_state_t *state = pdev->pClassData;
if (usbd_mode & USBD_MODE_CDC) {
// CDC VCP component
@ -669,7 +670,7 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
CDC_CMD_PACKET_SIZE);
// Init physical Interface components
CDC_fops->Init(pdev);
usbd_cdc_init(state->cdc, pdev);
// Init Xfer states
CDC_ClassData.TxState =0;
@ -694,8 +695,8 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
USBD_EP_TYPE_BULK,
MSC_MAX_PACKET);
// MSC uses the pClassData pointer because SCSI and BOT reference it
pdev->pClassData = &MSC_BOT_ClassData;
// Set the MSC data for SCSI and BOT to reference it
state->msc = &MSC_BOT_ClassData;
// Init the BOT layer
MSC_BOT_Init(pdev);
@ -736,19 +737,18 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
}
static uint8_t USBD_CDC_MSC_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
if (usbd_mode & USBD_MODE_CDC) {
usbd_cdc_msc_hid_state_t *state = pdev->pClassData;
if ((usbd_mode & USBD_MODE_CDC) && state->cdc) {
// CDC VCP component
// close endpoints
USBD_LL_CloseEP(pdev, CDC_IN_EP);
USBD_LL_CloseEP(pdev, CDC_OUT_EP);
USBD_LL_CloseEP(pdev, CDC_CMD_EP);
// DeInit physical Interface components
CDC_fops->DeInit();
}
if (usbd_mode & USBD_MODE_MSC) {
if ((usbd_mode & USBD_MODE_MSC) && state->msc) {
// MSC component
// close endpoints
@ -758,8 +758,8 @@ static uint8_t USBD_CDC_MSC_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
// DeInit the BOT layer
MSC_BOT_DeInit(pdev);
// clear the pointer
pdev->pClassData = NULL;
// clear the state pointer
state->msc = NULL;
}
if (usbd_mode & USBD_MODE_HID) {
@ -791,6 +791,8 @@ static uint8_t USBD_CDC_MSC_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTyp
SU: 21 20 0 1
*/
usbd_cdc_msc_hid_state_t *state = pdev->pClassData;
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
// Class request
@ -801,7 +803,7 @@ static uint8_t USBD_CDC_MSC_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTyp
if (req->wLength) {
if (req->bmRequest & 0x80) {
// device-to-host request
CDC_fops->Control(req->bRequest, (uint8_t*)CDC_ClassData.data, req->wLength);
usbd_cdc_control(state->cdc, req->bRequest, (uint8_t*)CDC_ClassData.data, req->wLength);
USBD_CtlSendData(pdev, (uint8_t*)CDC_ClassData.data, req->wLength);
} else {
// host-to-device request
@ -812,7 +814,7 @@ static uint8_t USBD_CDC_MSC_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTyp
} else {
// Not a Data request
// Transfer the command to the interface layer
return CDC_fops->Control(req->bRequest, NULL, req->wValue);
return usbd_cdc_control(state->cdc, req->bRequest, NULL, req->wValue);
}
} else if ((usbd_mode & USBD_MODE_MSC) && req->wIndex == MSC_IFACE_NUM_WITH_CDC) {
// MSC component
@ -931,8 +933,9 @@ static uint8_t EP0_TxSent(USBD_HandleTypeDef *pdev) {
*/
static uint8_t USBD_CDC_MSC_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) {
if ((CDC_fops != NULL) && (CDC_ClassData.CmdOpCode != 0xff)) {
CDC_fops->Control(CDC_ClassData.CmdOpCode, (uint8_t*)CDC_ClassData.data, CDC_ClassData.CmdLength);
usbd_cdc_msc_hid_state_t *state = pdev->pClassData;
if (state->cdc != NULL && CDC_ClassData.CmdOpCode != 0xff) {
usbd_cdc_control(state->cdc, CDC_ClassData.CmdOpCode, (uint8_t*)CDC_ClassData.data, CDC_ClassData.CmdLength);
CDC_ClassData.CmdOpCode = 0xff;
}
@ -957,13 +960,14 @@ static uint8_t USBD_CDC_MSC_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
}
static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) {
usbd_cdc_msc_hid_state_t *state = pdev->pClassData;
if ((usbd_mode & USBD_MODE_CDC) && epnum == (CDC_OUT_EP & 0x7f)) {
/* Get the received data length */
CDC_ClassData.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 */
CDC_fops->Receive(pdev, CDC_ClassData.RxBuffer, &CDC_ClassData.RxLength);
usbd_cdc_receive(state->cdc, CDC_ClassData.RxBuffer, &CDC_ClassData.RxLength);
return USBD_OK;
} else if ((usbd_mode & USBD_MODE_MSC) && epnum == (MSC_OUT_EP & 0x7f)) {
@ -992,15 +996,6 @@ uint8_t *USBD_CDC_MSC_HID_GetDeviceQualifierDescriptor (uint16_t *length) {
return NULL;
}
uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_CDC_ItfTypeDef *fops) {
if (fops == NULL) {
return USBD_FAIL;
} else {
CDC_fops = fops;
return USBD_OK;
}
}
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint16_t length) {
CDC_ClassData.TxBuffer = pbuff;
CDC_ClassData.TxLength = length;

20
ports/stm32/usbdev/class/src/usbd_msc_bot.c

@ -104,7 +104,7 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev);
*/
void MSC_BOT_Init (USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
hmsc->bot_state = USBD_BOT_IDLE;
hmsc->bot_status = USBD_BOT_STATUS_NORMAL;
@ -132,7 +132,7 @@ void MSC_BOT_Init (USBD_HandleTypeDef *pdev)
*/
void MSC_BOT_Reset (USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
hmsc->bot_state = USBD_BOT_IDLE;
hmsc->bot_status = USBD_BOT_STATUS_RECOVERY;
@ -152,7 +152,7 @@ void MSC_BOT_Reset (USBD_HandleTypeDef *pdev)
*/
void MSC_BOT_DeInit (USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
hmsc->bot_state = USBD_BOT_IDLE;
}
@ -166,7 +166,7 @@ void MSC_BOT_DeInit (USBD_HandleTypeDef *pdev)
void MSC_BOT_DataIn (USBD_HandleTypeDef *pdev,
uint8_t epnum)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
switch (hmsc->bot_state)
{
@ -199,7 +199,7 @@ void MSC_BOT_DataIn (USBD_HandleTypeDef *pdev,
void MSC_BOT_DataOut (USBD_HandleTypeDef *pdev,
uint8_t epnum)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
switch (hmsc->bot_state)
{
@ -231,7 +231,7 @@ void MSC_BOT_DataOut (USBD_HandleTypeDef *pdev,
*/
static void MSC_BOT_CBW_Decode (USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
hmsc->csw.dTag = hmsc->cbw.dTag;
hmsc->csw.dDataResidue = hmsc->cbw.dDataLength;
@ -300,7 +300,7 @@ static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev,
uint8_t* buf,
uint16_t len)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
len = MIN (hmsc->cbw.dDataLength, len);
hmsc->csw.dDataResidue -= len;
@ -320,7 +320,7 @@ static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev,
void MSC_BOT_SendCSW (USBD_HandleTypeDef *pdev,
uint8_t CSW_Status)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
hmsc->csw.dSignature = USBD_BOT_CSW_SIGNATURE;
hmsc->csw.bStatus = CSW_Status;
@ -348,7 +348,7 @@ void MSC_BOT_SendCSW (USBD_HandleTypeDef *pdev,
static void MSC_BOT_Abort (USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
if ((hmsc->cbw.bmFlags == 0) &&
(hmsc->cbw.dDataLength != 0) &&
@ -377,7 +377,7 @@ static void MSC_BOT_Abort (USBD_HandleTypeDef *pdev)
void MSC_BOT_CplClrFeature (USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
if(hmsc->bot_status == USBD_BOT_STATUS_ERROR )/* Bad CBW Signature */
{

34
ports/stm32/usbdev/class/src/usbd_msc_scsi.c

@ -190,7 +190,7 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev,
*/
static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
/* case 9 : Hi > D0 */
if (hmsc->cbw.dDataLength != 0)
@ -227,7 +227,7 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *par
{
uint8_t* pPage;
uint16_t len;
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
if (params[1] & 0x01)/*Evpd is set*/
{
@ -264,7 +264,7 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *par
*/
static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
if(((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size) != 0)
{
@ -300,7 +300,7 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_
*/
static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
uint16_t blk_size;
uint32_t blk_nbr;
@ -345,7 +345,7 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, ui
*/
static int8_t SCSI_ModeSense6 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
uint16_t len = 8 ;
hmsc->bot_data_length = len;
@ -367,7 +367,7 @@ static int8_t SCSI_ModeSense6 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *
static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
uint16_t len = 8;
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
hmsc->bot_data_length = len;
@ -381,7 +381,7 @@ static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
static int8_t SCSI_SynchronizeCache(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) {
// nothing to synchronize, so just return "success"
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
hmsc->bot_data_length = 0;
return 0;
}
@ -397,7 +397,7 @@ static int8_t SCSI_SynchronizeCache(USBD_HandleTypeDef *pdev, uint8_t lun, uint
static int8_t SCSI_RequestSense (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
uint8_t i;
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
for(i=0 ; i < REQUEST_SENSE_DATA_LEN ; i++)
{
@ -439,7 +439,7 @@ static int8_t SCSI_RequestSense (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
*/
void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey = sKey;
hmsc->scsi_sense[hmsc->scsi_sense_tail].w.ASC = ASC << 8;
@ -458,7 +458,7 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_
*/
static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
hmsc->bot_data_length = 0;
// On Mac OS X, when the device is ejected a SCSI_START_STOP_UNIT command is sent.
@ -479,7 +479,7 @@ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
*/
static int8_t SCSI_AllowMediumRemoval(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
hmsc->bot_data_length = 0;
((USBD_StorageTypeDef *)pdev->pUserData)->PreventAllowMediumRemoval(lun, params[0]);
return 0;
@ -494,7 +494,7 @@ static int8_t SCSI_AllowMediumRemoval(USBD_HandleTypeDef *pdev, uint8_t lun, ui
*/
static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
if(hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
{
@ -562,7 +562,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *para
static int8_t SCSI_Write10 (USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
{
@ -652,7 +652,7 @@ static int8_t SCSI_Write10 (USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *pa
static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
if ((params[1]& 0x02) == 0x02)
{
@ -687,7 +687,7 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *pa
*/
static int8_t SCSI_CheckAddressRange (USBD_HandleTypeDef *pdev, uint8_t lun , uint32_t blk_offset , uint16_t blk_nbr)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr )
{
@ -708,7 +708,7 @@ static int8_t SCSI_CheckAddressRange (USBD_HandleTypeDef *pdev, uint8_t lun , u
*/
static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev, uint8_t lun)
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
uint32_t len;
len = MIN(hmsc->scsi_blk_len , MSC_MEDIA_PACKET);
@ -756,7 +756,7 @@ static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev, uint8_t lun)
static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef *pdev, uint8_t lun)
{
uint32_t len;
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
USBD_MSC_BOT_HandleTypeDef *hmsc = ((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->msc;
len = MIN(hmsc->scsi_blk_len , MSC_MEDIA_PACKET);

Loading…
Cancel
Save