Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
eb239b83
Commit
eb239b83
authored
Aug 29, 2016
by
Philip Potter
Committed by
Damien George
Oct 04, 2016
Browse files
stmhal/usb: Add support to receive USB HID messages from host.
parent
03de5a13
Changes
7
Hide whitespace changes
Inline
Side-by-side
docs/library/pyb.USB_HID.rst
View file @
eb239b83
...
...
@@ -20,6 +20,17 @@ Constructors
Methods
-------
.. method:: USB_HID.recv(data, \*, timeout=5000)
Receive data on the bus:
- ``data`` can be an integer, which is the number of bytes to receive,
or a mutable buffer, which will be filled with received bytes.
- ``timeout`` is the timeout in milliseconds to wait for the receive.
Return value: if ``data`` is an integer then a new buffer of the bytes received,
otherwise the number of bytes read into ``data`` is returned.
.. method:: USB_HID.send(data)
Send data over the USB HID interface:
...
...
stmhal/Makefile
View file @
eb239b83
...
...
@@ -121,6 +121,7 @@ SRC_C = \
usbd_conf.c
\
usbd_desc.c
\
usbd_cdc_interface.c
\
usbd_hid_interface.c
\
usbd_msc_storage.c
\
mphalport.c
\
irq.c
\
...
...
stmhal/usb.c
View file @
eb239b83
...
...
@@ -32,6 +32,7 @@
#include "usbd_cdc_msc_hid.h"
#include "usbd_cdc_interface.h"
#include "usbd_msc_storage.h"
#include "usbd_hid_interface.h"
#include "py/objstr.h"
#include "py/runtime.h"
...
...
@@ -123,6 +124,7 @@ bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_H
USBD_MSC_RegisterStorage
(
&
hUSBDDevice
,
(
USBD_StorageTypeDef
*
)
&
USBD_FLASH_STORAGE_fops
);
break
;
}
USBD_HID_RegisterInterface
(
&
hUSBDDevice
,
(
USBD_HID_ItfTypeDef
*
)
&
USBD_HID_fops
);
USBD_Start
(
&
hUSBDDevice
);
}
pyb_usb_flags
|=
PYB_USB_FLAG_DEV_ENABLED
;
...
...
@@ -553,6 +555,43 @@ STATIC mp_obj_t pyb_usb_hid_make_new(const mp_obj_type_t *type, mp_uint_t n_args
return
(
mp_obj_t
)
&
pyb_usb_hid_obj
;
}
/// \method recv(data, *, timeout=5000)
///
/// Receive data on the bus:
///
/// - `data` can be an integer, which is the number of bytes to receive,
/// or a mutable buffer, which will be filled with received bytes.
/// - `timeout` is the timeout in milliseconds to wait for the receive.
///
/// Return value: if `data` is an integer then a new buffer of the bytes received,
/// otherwise the number of bytes read into `data` is returned.
STATIC
mp_obj_t
pyb_usb_hid_recv
(
mp_uint_t
n_args
,
const
mp_obj_t
*
args
,
mp_map_t
*
kw_args
)
{
static
const
mp_arg_t
allowed_args
[]
=
{
{
MP_QSTR_data
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_timeout
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
5000
}
},
};
// parse args
mp_arg_val_t
vals
[
MP_ARRAY_SIZE
(
allowed_args
)];
mp_arg_parse_all
(
n_args
-
1
,
args
+
1
,
kw_args
,
MP_ARRAY_SIZE
(
allowed_args
),
allowed_args
,
vals
);
// get the buffer to receive into
vstr_t
vstr
;
mp_obj_t
o_ret
=
pyb_buf_get_for_recv
(
vals
[
0
].
u_obj
,
&
vstr
);
// receive the data
int
ret
=
USBD_HID_Rx
((
uint8_t
*
)
vstr
.
buf
,
vstr
.
len
,
vals
[
1
].
u_int
);
// return the received data
if
(
o_ret
!=
MP_OBJ_NULL
)
{
return
mp_obj_new_int
(
ret
);
// number of bytes read into given buffer
}
else
{
vstr
.
len
=
ret
;
// set actual number of bytes read
return
mp_obj_new_str_from_vstr
(
&
mp_type_bytes
,
&
vstr
);
// create a new buffer
}
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_KW
(
pyb_usb_hid_recv_obj
,
1
,
pyb_usb_hid_recv
);
STATIC
mp_obj_t
pyb_usb_hid_send
(
mp_obj_t
self_in
,
mp_obj_t
report_in
)
{
#ifdef USE_DEVICE_MODE
mp_buffer_info_t
bufinfo
;
...
...
@@ -587,6 +626,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(pyb_hid_send_report_obj, pyb_hid_send_report);
STATIC
const
mp_map_elem_t
pyb_usb_hid_locals_dict_table
[]
=
{
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_send
),
(
mp_obj_t
)
&
pyb_usb_hid_send_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_recv
),
(
mp_obj_t
)
&
pyb_usb_hid_recv_obj
},
};
STATIC
MP_DEFINE_CONST_DICT
(
pyb_usb_hid_locals_dict
,
pyb_usb_hid_locals_dict_table
);
...
...
stmhal/usbd_hid_interface.c
0 → 100644
View file @
eb239b83
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* Taken from ST Cube library and heavily modified. See below for original
* copyright header.
*/
/**
******************************************************************************
* @file USB_Device/CDC_Standalone/Src/usbd_cdc_interface.c
* @author MCD Application Team
* @version V1.0.1
* @date 26-February-2014
* @brief Source file for USBD CDC interface
******************************************************************************
* @attention
*
* <h2><center>© 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.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#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
__IO
uint8_t
dev_is_connected
=
0
;
// indicates if we are connected
static
uint8_t
buffer
[
2
][
64
];
// 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
;
// length of last read
static
int8_t
current_write_buffer
=
0
;
// which buffer to write to
static
size_t
rx_packet_size
=
64
;
// expected size of packets to receive
/* Private function prototypes -----------------------------------------------*/
static
int8_t
HID_Itf_Receive
(
uint8_t
*
pbuf
,
uint32_t
Len
);
const
USBD_HID_ItfTypeDef
USBD_HID_fops
=
{
HID_Itf_Receive
};
/**
* @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
(
uint8_t
*
Buf
,
uint32_t
Len
)
{
current_write_buffer
=
!
current_write_buffer
;
last_read_len
=
Len
;
// initiate next USB packet transfer, to append to existing data in buffer
USBD_HID_SetRxBuffer
(
&
hUSBDDevice
,
buffer
[
current_write_buffer
]);
USBD_HID_ReceivePacket
(
&
hUSBDDevice
);
return
USBD_OK
;
}
// timout in milliseconds.
// Returns number of bytes read from the device.
int
USBD_HID_Rx
(
uint8_t
*
buf
,
uint32_t
len
,
uint32_t
timeout
)
{
// Wait until we have buffer to read
uint32_t
start
=
HAL_GetTick
();
while
(
current_read_buffer
==
current_write_buffer
)
{
// Wraparound of tick is taken care of by 2's complement arithmetic.
if
(
HAL_GetTick
()
-
start
>=
timeout
)
{
// timeout
return
0
;
}
if
(
query_irq
()
==
IRQ_STATE_DISABLED
)
{
// IRQs disabled so buffer will never be filled; return immediately
return
0
;
}
__WFI
();
// enter sleep mode, waiting for interrupt
}
// There is not enough space in buffer
if
(
len
<
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
;
// Success, return number of bytes read
return
last_read_len
;
}
stmhal/usbd_hid_interface.h
0 → 100644
View file @
eb239b83
/*
* This file is part of the MicroPython project, http://micropython.org/
*/
#include "usbd_cdc_msc_hid.h"
extern
const
USBD_HID_ItfTypeDef
USBD_HID_fops
;
int
USBD_HID_Rx
(
uint8_t
*
buf
,
uint32_t
len
,
uint32_t
timeout
);
stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h
View file @
eb239b83
...
...
@@ -6,9 +6,10 @@
#include "usbd_msc_scsi.h"
#include "usbd_ioreq.h"
// CDC and
MSC
packet sizes
// CDC
, MSC
and
HID
packet sizes
#define CDC_DATA_FS_MAX_PACKET_SIZE (64) // endpoint IN & OUT packet size
#define MSC_MEDIA_PACKET (2048) // was 8192; how low can it go whilst still working?
#define HID_DATA_FS_MAX_PACKET_SIZE (64) // endpoint IN & OUT packet size
// Need to define here for BOT and SCSI layers
#define MSC_IN_EP (0x81)
...
...
@@ -46,6 +47,10 @@ typedef struct {
__IO
uint32_t
RxState
;
}
USBD_CDC_HandleTypeDef
;
typedef
struct
_USBD_HID_Itf
{
int8_t
(
*
Receive
)(
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
);
...
...
@@ -105,6 +110,9 @@ 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
);
uint8_t
USBD_HID_SendReport
(
USBD_HandleTypeDef
*
pdev
,
uint8_t
*
report
,
uint16_t
len
);
...
...
stmhal/usbdev/class/src/usbd_cdc_msc_hid.c
View file @
eb239b83
...
...
@@ -81,6 +81,8 @@ typedef struct {
uint32_t
IdleState
;
uint32_t
AltSetting
;
HID_StateTypeDef
state
;
uint8_t
*
RxBuffer
;
uint32_t
RxLength
;
}
USBD_HID_HandleTypeDef
;
static
uint8_t
usbd_mode
;
...
...
@@ -94,6 +96,7 @@ static const uint8_t *hid_report_desc;
static
USBD_CDC_ItfTypeDef
*
CDC_fops
;
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
;
...
...
@@ -962,6 +965,9 @@ static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
}
else
if
((
usbd_mode
&
USBD_MODE_MSC
)
&&
epnum
==
(
MSC_OUT_EP
&
0x7f
))
{
MSC_BOT_DataOut
(
pdev
,
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
(
HID_ClassData
.
RxBuffer
,
HID_ClassData
.
RxLength
);
}
return
USBD_OK
;
...
...
@@ -1039,6 +1045,33 @@ 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
;
}
// prepare OUT endpoint for reception
uint8_t
USBD_HID_ReceivePacket
(
USBD_HandleTypeDef
*
pdev
)
{
// Suspend or Resume USB Out process
if
(
pdev
->
dev_speed
==
USBD_SPEED_HIGH
)
{
return
USBD_FAIL
;
}
// Prepare Out endpoint to receive next packet
USBD_LL_PrepareReceive
(
pdev
,
hid_out_ep
,
HID_ClassData
.
RxBuffer
,
HID_DATA_FS_MAX_PACKET_SIZE
);
return
USBD_OK
;
}
int
USBD_HID_CanSendReport
(
USBD_HandleTypeDef
*
pdev
)
{
return
pdev
->
dev_state
==
USBD_STATE_CONFIGURED
&&
HID_ClassData
.
state
==
HID_IDLE
;
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment