Skip to content

Commit c26de01

Browse files
committed
works! no timeouts
1 parent 0b8f1b9 commit c26de01

File tree

6 files changed

+213
-46
lines changed

6 files changed

+213
-46
lines changed

ports/cxd56/mpconfigport.mk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ USB_CDC_EP_NUM_DATA_IN = 1
77
USB_MSC_EP_NUM_OUT = 5
88
USB_MSC_EP_NUM_IN = 4
99

10+
# Number of USB endpoint pairs.
11+
USB_NUM_EP = 5
12+
1013
MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz
1114

1215
CIRCUITPY_AUDIOBUSIO = 0

shared-bindings/usb_cdc/Serial.c

Lines changed: 110 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,16 @@
6767
//| ...
6868
//|
6969
//| def write(self, buf: ReadableBuffer) -> Optional[int]:
70-
//| """Write the buffer of bytes to the bus.
70+
//| """Write as many bytes as possible from the buffer of bytes.
7171
//|
7272
//| :return: the number of bytes written
7373
//| :rtype: int or None"""
7474
//| ...
7575
//|
76+
//| def flush(self) -> None:
77+
//| """Force out any unwritten bytes, waiting until they are written."""
78+
//| ...
79+
//|
7680

7781
// These three methods are used by the shared stream methods.
7882
STATIC mp_uint_t usb_cdc_serial_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
@@ -97,27 +101,121 @@ STATIC mp_uint_t usb_cdc_serial_write(mp_obj_t self_in, const void *buf_in, mp_u
97101
STATIC mp_uint_t usb_cdc_serial_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
98102
usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in);
99103
mp_uint_t ret;
100-
if (request == MP_IOCTL_POLL) {
101-
mp_uint_t flags = arg;
102-
ret = 0;
103-
if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_cdc_serial_bytes_available(self) > 0) {
104-
ret |= MP_IOCTL_POLL_RD;
105-
}
106-
if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_cdc_serial_ready_to_tx(self)) {
107-
ret |= MP_IOCTL_POLL_WR;
104+
switch (request) {
105+
case MP_IOCTL_POLL: {
106+
mp_uint_t flags = arg;
107+
ret = 0;
108+
if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_cdc_serial_get_in_waiting(self) > 0) {
109+
ret |= MP_IOCTL_POLL_RD;
110+
}
111+
if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_cdc_serial_get_out_waiting(self) == 0) {
112+
ret |= MP_IOCTL_POLL_WR;
113+
}
114+
break;
108115
}
109-
} else {
110-
*errcode = MP_EINVAL;
111-
ret = MP_STREAM_ERROR;
116+
117+
case MP_STREAM_FLUSH:
118+
common_hal_usb_cdc_serial_flush(self);
119+
break;
120+
121+
default:
122+
*errcode = MP_EINVAL;
123+
ret = MP_STREAM_ERROR;
112124
}
113125
return ret;
114126
}
115127

128+
//| connected: bool
129+
//| """True if this Serial is connected to a host. (read-only)"""
130+
//|
131+
STATIC mp_obj_t usb_cdc_serial_get_connected(mp_obj_t self_in) {
132+
usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in);
133+
return mp_obj_new_bool(common_hal_usb_cdc_serial_get_connected(self));
134+
}
135+
MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_get_connected_obj, usb_cdc_serial_get_connected);
136+
137+
const mp_obj_property_t usb_cdc_serial__connected_obj = {
138+
.base.type = &mp_type_property,
139+
.proxy = {(mp_obj_t)&usb_cdc_serial_get_connected_obj,
140+
(mp_obj_t)&mp_const_none_obj,
141+
(mp_obj_t)&mp_const_none_obj},
142+
};
143+
144+
//| in_waiting: int
145+
//| """Returns the number of bytes waiting to be read on the USB serial input. (read-only)"""
146+
//|
147+
STATIC mp_obj_t usb_cdc_serial_get_in_waiting(mp_obj_t self_in) {
148+
usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in);
149+
return mp_obj_new_int(common_hal_usb_cdc_serial_get_in_waiting(self));
150+
}
151+
MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_get_in_waiting_obj, usb_cdc_serial_get_in_waiting);
152+
153+
const mp_obj_property_t usb_cdc_serial_in_waiting_obj = {
154+
.base.type = &mp_type_property,
155+
.proxy = {(mp_obj_t)&usb_cdc_serial_get_in_waiting_obj,
156+
(mp_obj_t)&mp_const_none_obj,
157+
(mp_obj_t)&mp_const_none_obj},
158+
};
159+
160+
//| out_waiting: int
161+
//| """Returns the number of bytes waiting to be written on the USB serial output. (read-only)"""
162+
//|
163+
STATIC mp_obj_t usb_cdc_serial_get_out_waiting(mp_obj_t self_in) {
164+
usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in);
165+
return mp_obj_new_int(common_hal_usb_cdc_serial_get_out_waiting(self));
166+
}
167+
MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_get_out_waiting_obj, usb_cdc_serial_get_out_waiting);
168+
169+
const mp_obj_property_t usb_cdc_serial_out_waiting_obj = {
170+
.base.type = &mp_type_property,
171+
.proxy = {(mp_obj_t)&usb_cdc_serial_get_out_waiting_obj,
172+
(mp_obj_t)&mp_const_none_obj,
173+
(mp_obj_t)&mp_const_none_obj},
174+
};
175+
176+
//| def reset_input_buffer(self) -> None:
177+
//| """Clears any unread bytes."""
178+
//| ...
179+
//|
180+
STATIC mp_obj_t usb_cdc_serial_reset_input_buffer(mp_obj_t self_in) {
181+
usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in);
182+
common_hal_usb_cdc_serial_reset_input_buffer(self);
183+
return mp_const_none;
184+
}
185+
MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_reset_input_buffer_obj, usb_cdc_serial_reset_input_buffer);
186+
187+
//| def reset_output_buffer(self) -> None:
188+
//| """Clears any unwritten bytes."""
189+
//| ...
190+
//|
191+
STATIC mp_obj_t usb_cdc_serial_reset_output_buffer(mp_obj_t self_in) {
192+
usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in);
193+
common_hal_usb_cdc_serial_reset_output_buffer(self);
194+
return mp_const_none;
195+
}
196+
MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_reset_output_buffer_obj, usb_cdc_serial_reset_output_buffer);
197+
198+
116199
STATIC const mp_rom_map_elem_t usb_cdc_serial_locals_dict_table[] = {
117200
// Standard stream methods.
201+
{ MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
118202
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
119203
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
204+
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)},
205+
{ MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj)},
120206
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
207+
208+
// Other pyserial-inspired attributes.
209+
{ MP_OBJ_NEW_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&usb_cdc_serial_in_waiting_obj) },
210+
{ MP_OBJ_NEW_QSTR(MP_QSTR_out_waiting), MP_ROM_PTR(&usb_cdc_serial_out_waiting_obj) },
211+
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&usb_cdc_serial_reset_input_buffer_obj) },
212+
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset_output_buffer), MP_ROM_PTR(&usb_cdc_serial_reset_output_buffer_obj) },
213+
214+
// Not in pyserial protocol.
215+
{ MP_OBJ_NEW_QSTR(MP_QSTR_connected), MP_ROM_PTR(&usb_cdc_serial_get_connected_obj) },
216+
217+
218+
121219
};
122220
STATIC MP_DEFINE_CONST_DICT(usb_cdc_serial_locals_dict, usb_cdc_serial_locals_dict_table);
123221

shared-bindings/usb_cdc/Serial.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,16 @@
3232
extern const mp_obj_type_t usb_cdc_serial_type;
3333

3434
extern size_t common_hal_usb_cdc_serial_read(usb_cdc_serial_obj_t *self, uint8_t *data, size_t len, int *errcode);
35-
extern uint32_t common_hal_usb_cdc_serial_bytes_available(usb_cdc_serial_obj_t *self);
36-
extern void common_hal_usb_cdc_serial_clear_buffer(usb_cdc_serial_obj_t *self);
3735
extern size_t common_hal_usb_cdc_serial_write(usb_cdc_serial_obj_t *self, const uint8_t *data, size_t len, int *errcode);
38-
extern bool common_hal_usb_cdc_serial_ready_to_tx(usb_cdc_serial_obj_t *self);
36+
37+
extern uint32_t common_hal_usb_cdc_serial_get_in_waiting(usb_cdc_serial_obj_t *self);
38+
extern uint32_t common_hal_usb_cdc_serial_get_out_waiting(usb_cdc_serial_obj_t *self);
39+
40+
extern void common_hal_usb_cdc_serial_reset_input_buffer(usb_cdc_serial_obj_t *self);
41+
extern uint32_t common_hal_usb_cdc_serial_reset_output_buffer(usb_cdc_serial_obj_t *self);
42+
43+
extern uint32_t common_hal_usb_cdc_serial_flush(usb_cdc_serial_obj_t *self);
44+
45+
extern bool common_hal_usb_cdc_serial_get_connected(usb_cdc_serial_obj_t *self);
3946

4047
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC_SERIAL_H

shared-bindings/usb_cdc/__init__.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,13 @@
3636

3737
//| """USB CDC Serial streams
3838
//|
39-
//| The `usb_cdc` module allows access to USB CDC (serial) communications.
39+
//| The `usb_cdc` module allows access to USB CDC (serial) communications."""
4040
//|
4141
//| serials: Tuple[Serial, ...]
42-
//| """Tuple of all CDC streams. Each item is a `Serial`."""
42+
//| """Tuple of all CDC streams. Each item is a `Serial`.
43+
//| ``serials[0]`` is the USB REPL connection.
44+
//| ``serials[1]`` is a second USB serial connection, unconnected to the REPL.
45+
//| """
4346
//|
4447

4548
static const mp_map_elem_t usb_cdc_module_globals_table[] = {

shared-module/usb_cdc/Serial.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,33 @@ size_t common_hal_usb_cdc_serial_read(usb_cdc_serial_obj_t *self, uint8_t *data,
3131
return tud_cdc_n_read(self->idx, data, len);
3232
}
3333

34-
uint32_t common_hal_usb_cdc_serial_bytes_available(usb_cdc_serial_obj_t *self) {
34+
size_t common_hal_usb_cdc_serial_write(usb_cdc_serial_obj_t *self, const uint8_t *data, size_t len, int *errcode) {
35+
uint32_t num_written = tud_cdc_n_write(self->idx, data, len);
36+
tud_cdc_n_write_flush(self->idx);
37+
return num_written;
38+
}
39+
40+
uint32_t common_hal_usb_cdc_serial_get_in_waiting(usb_cdc_serial_obj_t *self) {
3541
return tud_cdc_n_available(self->idx);
3642
}
3743

38-
size_t common_hal_usb_cdc_serial_write(usb_cdc_serial_obj_t *self, const uint8_t *data, size_t len, int *errcode) {
39-
return tud_cdc_n_write(self->idx, data, len);
44+
uint32_t common_hal_usb_cdc_serial_get_out_waiting(usb_cdc_serial_obj_t *self) {
45+
// Return number of FIFO bytes currently occupied.
46+
return CFG_TUD_CDC_TX_BUFSIZE - tud_cdc_n_write_available(self->idx);
47+
}
48+
49+
void common_hal_usb_cdc_serial_reset_input_buffer(usb_cdc_serial_obj_t *self) {
50+
tud_cdc_n_read_flush(self->idx);
51+
}
52+
53+
uint32_t common_hal_usb_cdc_serial_reset_output_buffer(usb_cdc_serial_obj_t *self) {
54+
return tud_cdc_n_write_clear(self->idx);
55+
}
56+
57+
uint32_t common_hal_usb_cdc_serial_flush(usb_cdc_serial_obj_t *self) {
58+
return tud_cdc_n_write_flush(self->idx);
4059
}
4160

42-
bool common_hal_usb_cdc_serial_ready_to_tx(usb_cdc_serial_obj_t *self) {
61+
bool common_hal_usb_cdc_serial_get_connected(usb_cdc_serial_obj_t *self) {
4362
return tud_cdc_n_connected(self->idx);
4463
}

0 commit comments

Comments
 (0)