Browse Source

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

pull/3239/merge
Damien George 7 years ago
parent
commit
77e1da40e2
  1. 7
      ports/stm32/usb.c
  2. 80
      ports/stm32/usbd_hid_interface.c
  3. 35
      ports/stm32/usbd_hid_interface.h
  4. 11
      ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h
  5. 14
      ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c

7
ports/stm32/usb.c

@ -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)) {

80
ports/stm32/usbd_hid_interface.c

@ -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;
}

35
ports/stm32/usbd_hid_interface.h

@ -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

11
ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.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_

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

@ -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…
Cancel
Save