stm32/usbdev: Put all HID state in a struct.
This commit is contained in:
parent
980b33177b
commit
77e1da40e2
@ -57,6 +57,7 @@ mp_uint_t pyb_usb_flags = 0;
|
||||
STATIC USBD_HandleTypeDef hUSBDDevice;
|
||||
STATIC usbd_cdc_msc_hid_state_t usbd_cdc_msc_hid_state;
|
||||
STATIC usbd_cdc_itf_t usbd_cdc_itf;
|
||||
STATIC usbd_hid_itf_t usbd_hid_itf;
|
||||
pyb_usb_storage_medium_t pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_NONE;
|
||||
#endif
|
||||
|
||||
@ -121,6 +122,7 @@ bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_H
|
||||
usbd->pDesc = (USBD_DescriptorsTypeDef*)&USBD_Descriptors;
|
||||
usbd->pClass = &USBD_CDC_MSC_HID;
|
||||
usbd_cdc_msc_hid_state.cdc = &usbd_cdc_itf;
|
||||
usbd_cdc_msc_hid_state.hid = &usbd_hid_itf;
|
||||
usbd->pClassData = &usbd_cdc_msc_hid_state;
|
||||
|
||||
switch (pyb_usb_storage_medium) {
|
||||
@ -133,7 +135,6 @@ bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_H
|
||||
USBD_MSC_RegisterStorage(usbd, (USBD_StorageTypeDef*)&USBD_FLASH_STORAGE_fops);
|
||||
break;
|
||||
}
|
||||
USBD_HID_RegisterInterface(usbd, (USBD_HID_ItfTypeDef*)&USBD_HID_fops);
|
||||
|
||||
// start the USB device
|
||||
USBD_LL_Init(usbd);
|
||||
@ -582,7 +583,7 @@ STATIC mp_obj_t pyb_usb_hid_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_HID_Rx(&hUSBDDevice, (uint8_t*)vstr.buf, vstr.len, vals[1].u_int);
|
||||
int ret = usbd_hid_rx(&usbd_hid_itf, vstr.len, (uint8_t*)vstr.buf, vals[1].u_int);
|
||||
|
||||
// return the received data
|
||||
if (o_ret != MP_OBJ_NULL) {
|
||||
@ -642,7 +643,7 @@ STATIC mp_uint_t pyb_usb_hid_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_HID_RxNum() > 0) {
|
||||
if ((flags & MP_STREAM_POLL_RD) && usbd_hid_rx_num(&usbd_hid_itf) > 0) {
|
||||
ret |= MP_STREAM_POLL_RD;
|
||||
}
|
||||
if ((flags & MP_STREAM_POLL_WR) && USBD_HID_CanSendReport(&hUSBDDevice)) {
|
||||
|
@ -36,75 +36,47 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "usbd_cdc_msc_hid.h"
|
||||
#include "usbd_hid_interface.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "irq.h"
|
||||
#include "usb.h"
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
static uint8_t buffer[2][HID_DATA_FS_MAX_PACKET_SIZE]; // pair of buffers to read individual packets into
|
||||
static int8_t current_read_buffer = 0; // which buffer to read from
|
||||
static uint32_t last_read_len = 0; // length of last read
|
||||
static int8_t current_write_buffer = 0; // which buffer to write to
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static int8_t HID_Itf_Init (USBD_HandleTypeDef *pdev);
|
||||
static int8_t HID_Itf_Receive (USBD_HandleTypeDef *pdev, uint8_t* pbuf, uint32_t Len);
|
||||
|
||||
const USBD_HID_ItfTypeDef USBD_HID_fops = {
|
||||
HID_Itf_Init,
|
||||
HID_Itf_Receive
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief HID_Itf_Init
|
||||
* Initializes the HID media low layer
|
||||
* @param None
|
||||
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t HID_Itf_Init(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
current_read_buffer = 0;
|
||||
last_read_len = 0;
|
||||
current_write_buffer = 0;
|
||||
USBD_HID_SetRxBuffer(pdev, buffer[current_write_buffer]);
|
||||
return USBD_OK;
|
||||
void usbd_hid_init(usbd_hid_itf_t *hid, USBD_HandleTypeDef *pdev) {
|
||||
hid->usb = pdev;
|
||||
hid->current_read_buffer = 0;
|
||||
hid->last_read_len = 0;
|
||||
hid->current_write_buffer = 0;
|
||||
USBD_HID_SetRxBuffer(pdev, hid->buffer[hid->current_write_buffer]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HID_Itf_Receive
|
||||
* 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 UserRxBuffer, so we are
|
||||
* free to modify it.
|
||||
*/
|
||||
static int8_t HID_Itf_Receive(USBD_HandleTypeDef *pdev, uint8_t* Buf, uint32_t Len) {
|
||||
current_write_buffer = !current_write_buffer;
|
||||
last_read_len = 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 hid->buffer, so we are free to modify it.
|
||||
int8_t usbd_hid_receive(usbd_hid_itf_t *hid, size_t len, uint8_t *buf) {
|
||||
hid->current_write_buffer = !hid->current_write_buffer;
|
||||
hid->last_read_len = len;
|
||||
// initiate next USB packet transfer, to append to existing data in buffer
|
||||
USBD_HID_SetRxBuffer(pdev, buffer[current_write_buffer]);
|
||||
USBD_HID_ReceivePacket(pdev);
|
||||
USBD_HID_SetRxBuffer(hid->usb, hid->buffer[hid->current_write_buffer]);
|
||||
USBD_HID_ReceivePacket(hid->usb);
|
||||
// Set NAK to indicate we need to process read buffer
|
||||
USBD_HID_SetNAK(pdev);
|
||||
USBD_HID_SetNAK(hid->usb);
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
// Returns number of ready rx buffers.
|
||||
int USBD_HID_RxNum(void) {
|
||||
return (current_read_buffer != current_write_buffer);
|
||||
int usbd_hid_rx_num(usbd_hid_itf_t *hid) {
|
||||
return hid->current_read_buffer != hid->current_write_buffer;
|
||||
}
|
||||
|
||||
// timout in milliseconds.
|
||||
// Returns number of bytes read from the device.
|
||||
int USBD_HID_Rx(USBD_HandleTypeDef *pdev, uint8_t *buf, uint32_t len, uint32_t timeout) {
|
||||
int usbd_hid_rx(usbd_hid_itf_t *hid, size_t len, uint8_t *buf, uint32_t timeout) {
|
||||
// Wait until we have buffer to read
|
||||
uint32_t start = HAL_GetTick();
|
||||
while (current_read_buffer == current_write_buffer) {
|
||||
while (hid->current_read_buffer == hid->current_write_buffer) {
|
||||
// Wraparound of tick is taken care of by 2's complement arithmetic.
|
||||
if (HAL_GetTick() - start >= timeout) {
|
||||
// timeout
|
||||
@ -118,17 +90,17 @@ int USBD_HID_Rx(USBD_HandleTypeDef *pdev, uint8_t *buf, uint32_t len, uint32_t t
|
||||
}
|
||||
|
||||
// There is not enough space in buffer
|
||||
if (len < last_read_len) {
|
||||
if (len < hid->last_read_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copy bytes from device to user buffer
|
||||
memcpy(buf, buffer[current_read_buffer], last_read_len);
|
||||
current_read_buffer = !current_read_buffer;
|
||||
memcpy(buf, hid->buffer[hid->current_read_buffer], hid->last_read_len);
|
||||
hid->current_read_buffer = !hid->current_read_buffer;
|
||||
|
||||
// Clear NAK to indicate we are ready to read more data
|
||||
USBD_HID_ClearNAK(pdev);
|
||||
USBD_HID_ClearNAK(hid->usb);
|
||||
|
||||
// Success, return number of bytes read
|
||||
return last_read_len;
|
||||
return hid->last_read_len;
|
||||
}
|
||||
|
@ -1,14 +1,21 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_STMHAL_USBD_HID_INTERFACE_H
|
||||
#define MICROPY_INCLUDED_STMHAL_USBD_HID_INTERFACE_H
|
||||
|
||||
#include "usbd_cdc_msc_hid.h"
|
||||
|
||||
extern const USBD_HID_ItfTypeDef USBD_HID_fops;
|
||||
|
||||
int USBD_HID_RxNum(void);
|
||||
int USBD_HID_Rx(USBD_HandleTypeDef *pdev, uint8_t *buf, uint32_t len, uint32_t timeout);
|
||||
|
||||
#endif // MICROPY_INCLUDED_STMHAL_USBD_HID_INTERFACE_H
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_STMHAL_USBD_HID_INTERFACE_H
|
||||
#define MICROPY_INCLUDED_STMHAL_USBD_HID_INTERFACE_H
|
||||
|
||||
#include "usbd_cdc_msc_hid.h"
|
||||
|
||||
typedef struct _usbd_hid_itf_t {
|
||||
USBD_HandleTypeDef *usb; // the parent USB device
|
||||
|
||||
uint8_t buffer[2][HID_DATA_FS_MAX_PACKET_SIZE]; // pair of buffers to read individual packets into
|
||||
int8_t current_read_buffer; // which buffer to read from
|
||||
uint32_t last_read_len; // length of last read
|
||||
int8_t current_write_buffer; // which buffer to write to
|
||||
} usbd_hid_itf_t;
|
||||
|
||||
int usbd_hid_rx_num(usbd_hid_itf_t *hid);
|
||||
int usbd_hid_rx(usbd_hid_itf_t *hid, size_t len, uint8_t *buf, uint32_t timeout);
|
||||
|
||||
#endif // MICROPY_INCLUDED_STMHAL_USBD_HID_INTERFACE_H
|
||||
|
@ -40,11 +40,6 @@ typedef struct {
|
||||
__IO uint32_t RxState;
|
||||
} USBD_CDC_HandleTypeDef;
|
||||
|
||||
typedef struct _USBD_HID_Itf {
|
||||
int8_t (* Init) (USBD_HandleTypeDef *pdev);
|
||||
int8_t (* Receive)(USBD_HandleTypeDef *pdev, uint8_t *, uint32_t);
|
||||
} USBD_HID_ItfTypeDef;
|
||||
|
||||
typedef struct _USBD_STORAGE {
|
||||
int8_t (* Init) (uint8_t lun);
|
||||
int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint16_t *block_size);
|
||||
@ -109,7 +104,6 @@ uint8_t USBD_CDC_TransmitPacket (USBD_HandleTypeDef *pdev);
|
||||
|
||||
uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef *fops);
|
||||
|
||||
uint8_t USBD_HID_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_HID_ItfTypeDef *fops);
|
||||
uint8_t USBD_HID_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
|
||||
uint8_t USBD_HID_ReceivePacket(USBD_HandleTypeDef *pdev);
|
||||
int USBD_HID_CanSendReport(USBD_HandleTypeDef *pdev);
|
||||
@ -123,4 +117,9 @@ 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);
|
||||
|
||||
// These are provided externally to implement the HID interface
|
||||
struct _usbd_hid_itf_t;
|
||||
void usbd_hid_init(struct _usbd_hid_itf_t *hid, USBD_HandleTypeDef *pdev);
|
||||
int8_t usbd_hid_receive(struct _usbd_hid_itf_t *hid, size_t len, uint8_t *buf);
|
||||
|
||||
#endif // _USB_CDC_MSC_CORE_H_
|
||||
|
@ -96,7 +96,6 @@ static uint8_t *hid_desc;
|
||||
static const uint8_t *hid_report_desc;
|
||||
|
||||
static USBD_StorageTypeDef *MSC_fops;
|
||||
static USBD_HID_ItfTypeDef *HID_fops;
|
||||
|
||||
static USBD_CDC_HandleTypeDef CDC_ClassData;
|
||||
static USBD_MSC_BOT_HandleTypeDef MSC_BOT_ClassData;
|
||||
@ -725,7 +724,7 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
|
||||
USBD_EP_TYPE_INTR,
|
||||
mps_out);
|
||||
|
||||
HID_fops->Init(pdev);
|
||||
usbd_hid_init(state->hid, pdev);
|
||||
|
||||
// Prepare Out endpoint to receive next packet
|
||||
USBD_LL_PrepareReceive(pdev, hid_out_ep, HID_ClassData.RxBuffer, mps_out);
|
||||
@ -975,7 +974,7 @@ static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
return USBD_OK;
|
||||
} else if ((usbd_mode & USBD_MODE_HID) && epnum == (hid_out_ep & 0x7f)) {
|
||||
HID_ClassData.RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
|
||||
HID_fops->Receive(pdev, HID_ClassData.RxBuffer, HID_ClassData.RxLength);
|
||||
usbd_hid_receive(state->hid, HID_ClassData.RxLength, HID_ClassData.RxBuffer);
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
@ -1044,15 +1043,6 @@ uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef *
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t USBD_HID_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_HID_ItfTypeDef *fops) {
|
||||
if (fops == NULL) {
|
||||
return USBD_FAIL;
|
||||
} else {
|
||||
HID_fops = fops;
|
||||
return USBD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t USBD_HID_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) {
|
||||
HID_ClassData.RxBuffer = pbuff;
|
||||
return USBD_OK;
|
||||
|
Loading…
x
Reference in New Issue
Block a user