Skip to content

Commit 9a41b32

Browse files
committed
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))
1 parent efc49c5 commit 9a41b32

4 files changed

Lines changed: 55 additions & 10 deletions

File tree

stmhal/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
*/
4949
#define MICROPY_ENABLE_LFN (1)
5050
#define MICROPY_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
51+
#define MICROPY_STREAMS_NON_BLOCK (1)
5152
#define MICROPY_MODULE_WEAK_LINKS (1)
5253
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
5354
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)

stmhal/usb.c

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
* THE SOFTWARE.
2525
*/
2626

27+
#include <stdarg.h>
2728
#include <string.h>
29+
#include <errno.h>
2830

2931
#include "usbd_core.h"
3032
#include "usbd_desc.h"
@@ -40,6 +42,7 @@
4042
#include "stream.h"
4143
#include "bufhelper.h"
4244
#include "usb.h"
45+
#include "pybioctl.h"
4346

4447
#ifdef USE_DEVICE_MODE
4548
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_
243246
}
244247
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_vcp_recv_obj, 1, pyb_usb_vcp_recv);
245248

246-
STATIC mp_uint_t pyb_usb_vcp_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
247-
int ret = USBD_CDC_Rx((byte*)buf, size, -1);
248-
return ret;
249-
}
250-
251-
STATIC mp_uint_t pyb_usb_vcp_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
252-
int ret = USBD_CDC_Tx((const byte*)buf, size, -1);
253-
return ret;
254-
}
255-
256249
mp_obj_t pyb_usb_vcp___exit__(mp_uint_t n_args, const mp_obj_t *args) {
257250
return mp_const_none;
258251
}
@@ -279,9 +272,51 @@ STATIC const mp_map_elem_t pyb_usb_vcp_locals_dict_table[] = {
279272

280273
STATIC MP_DEFINE_CONST_DICT(pyb_usb_vcp_locals_dict, pyb_usb_vcp_locals_dict_table);
281274

275+
STATIC mp_uint_t pyb_usb_vcp_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
276+
int ret = USBD_CDC_Rx((byte*)buf, size, 0);
277+
if (ret == 0) {
278+
// return EAGAIN error to indicate non-blocking
279+
*errcode = EAGAIN;
280+
return MP_STREAM_ERROR;
281+
}
282+
return ret;
283+
}
284+
285+
STATIC mp_uint_t pyb_usb_vcp_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
286+
int ret = USBD_CDC_Tx((const byte*)buf, size, 0);
287+
if (ret == 0) {
288+
// return EAGAIN error to indicate non-blocking
289+
*errcode = EAGAIN;
290+
return MP_STREAM_ERROR;
291+
}
292+
return ret;
293+
}
294+
295+
STATIC mp_uint_t pyb_usb_vcp_ioctl(mp_obj_t self_in, mp_uint_t request, int *errcode, ...) {
296+
va_list vargs;
297+
va_start(vargs, errcode);
298+
mp_uint_t ret;
299+
if (request == MP_IOCTL_POLL) {
300+
mp_uint_t flags = va_arg(vargs, mp_uint_t);
301+
ret = 0;
302+
if ((flags & MP_IOCTL_POLL_RD) && USBD_CDC_RxNum() > 0) {
303+
ret |= MP_IOCTL_POLL_RD;
304+
}
305+
if ((flags & MP_IOCTL_POLL_WR) && USBD_CDC_TxHalfEmpty()) {
306+
ret |= MP_IOCTL_POLL_WR;
307+
}
308+
} else {
309+
*errcode = EINVAL;
310+
ret = MP_STREAM_ERROR;
311+
}
312+
va_end(vargs);
313+
return ret;
314+
}
315+
282316
STATIC const mp_stream_p_t pyb_usb_vcp_stream_p = {
283317
.read = pyb_usb_vcp_read,
284318
.write = pyb_usb_vcp_write,
319+
.ioctl = pyb_usb_vcp_ioctl,
285320
};
286321

287322
const mp_obj_type_t pyb_usb_vcp_type = {

stmhal/usbd_cdc_interface.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,14 @@ void USBD_CDC_SetInterrupt(int chr, void *data) {
402402
user_interrupt_data = data;
403403
}
404404

405+
int USBD_CDC_TxHalfEmpty(void) {
406+
int32_t tx_waiting = (int32_t)UserTxBufPtrIn - (int32_t)UserTxBufPtrOut;
407+
if (tx_waiting < 0) {
408+
tx_waiting += APP_TX_DATA_SIZE;
409+
}
410+
return tx_waiting <= APP_TX_DATA_SIZE / 2;
411+
}
412+
405413
// timout in milliseconds.
406414
// Returns number of bytes written to the device.
407415
int USBD_CDC_Tx(const uint8_t *buf, uint32_t len, uint32_t timeout) {

stmhal/usbd_cdc_interface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void);
3737
int USBD_CDC_IsConnected(void);
3838
void USBD_CDC_SetInterrupt(int chr, void *data);
3939

40+
int USBD_CDC_TxHalfEmpty(void);
4041
int USBD_CDC_Tx(const uint8_t *buf, uint32_t len, uint32_t timeout);
4142
void USBD_CDC_TxAlways(const uint8_t *buf, uint32_t len);
4243

0 commit comments

Comments
 (0)