stmhal: Add ioctl to USB_VCP object, so it works with select.
This patch also enables non-blocking streams on stmhal port. One can now make a USB-UART pass-through function: def pass_through(usb, uart): while True: select.select([usb, uart], [], []) if usb.any(): uart.write(usb.read(256)) if uart.any(): usb.write(uart.read(256)) pass_through(pyb.USB_VCP(), pyb.UART(1, 9600))
This commit is contained in:
parent
efc49c5591
commit
9a41b32b3f
@ -48,6 +48,7 @@
|
||||
*/
|
||||
#define MICROPY_ENABLE_LFN (1)
|
||||
#define MICROPY_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
|
||||
#define MICROPY_STREAMS_NON_BLOCK (1)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
||||
|
55
stmhal/usb.c
55
stmhal/usb.c
@ -24,7 +24,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_desc.h"
|
||||
@ -40,6 +42,7 @@
|
||||
#include "stream.h"
|
||||
#include "bufhelper.h"
|
||||
#include "usb.h"
|
||||
#include "pybioctl.h"
|
||||
|
||||
#ifdef USE_DEVICE_MODE
|
||||
USBD_HandleTypeDef hUSBDDevice;
|
||||
@ -243,16 +246,6 @@ STATIC mp_obj_t pyb_usb_vcp_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map_
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_vcp_recv_obj, 1, pyb_usb_vcp_recv);
|
||||
|
||||
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, -1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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, -1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
mp_obj_t pyb_usb_vcp___exit__(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
return mp_const_none;
|
||||
}
|
||||
@ -279,9 +272,51 @@ STATIC const mp_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);
|
||||
if (ret == 0) {
|
||||
// return EAGAIN error to indicate non-blocking
|
||||
*errcode = EAGAIN;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
if (ret == 0) {
|
||||
// return EAGAIN error to indicate non-blocking
|
||||
*errcode = EAGAIN;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC mp_uint_t pyb_usb_vcp_ioctl(mp_obj_t self_in, mp_uint_t request, int *errcode, ...) {
|
||||
va_list vargs;
|
||||
va_start(vargs, errcode);
|
||||
mp_uint_t ret;
|
||||
if (request == MP_IOCTL_POLL) {
|
||||
mp_uint_t flags = va_arg(vargs, mp_uint_t);
|
||||
ret = 0;
|
||||
if ((flags & MP_IOCTL_POLL_RD) && USBD_CDC_RxNum() > 0) {
|
||||
ret |= MP_IOCTL_POLL_RD;
|
||||
}
|
||||
if ((flags & MP_IOCTL_POLL_WR) && USBD_CDC_TxHalfEmpty()) {
|
||||
ret |= MP_IOCTL_POLL_WR;
|
||||
}
|
||||
} else {
|
||||
*errcode = EINVAL;
|
||||
ret = MP_STREAM_ERROR;
|
||||
}
|
||||
va_end(vargs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC const mp_stream_p_t pyb_usb_vcp_stream_p = {
|
||||
.read = pyb_usb_vcp_read,
|
||||
.write = pyb_usb_vcp_write,
|
||||
.ioctl = pyb_usb_vcp_ioctl,
|
||||
};
|
||||
|
||||
const mp_obj_type_t pyb_usb_vcp_type = {
|
||||
|
@ -402,6 +402,14 @@ void USBD_CDC_SetInterrupt(int chr, void *data) {
|
||||
user_interrupt_data = data;
|
||||
}
|
||||
|
||||
int USBD_CDC_TxHalfEmpty(void) {
|
||||
int32_t tx_waiting = (int32_t)UserTxBufPtrIn - (int32_t)UserTxBufPtrOut;
|
||||
if (tx_waiting < 0) {
|
||||
tx_waiting += APP_TX_DATA_SIZE;
|
||||
}
|
||||
return tx_waiting <= APP_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) {
|
||||
|
@ -37,6 +37,7 @@ void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void);
|
||||
int USBD_CDC_IsConnected(void);
|
||||
void USBD_CDC_SetInterrupt(int chr, void *data);
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user