summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2021-02-12 19:01:14 -0500
committerDan Halbert <halbert@halwitz.org>2021-02-12 19:01:14 -0500
commitd54b5861a30b1b1a352e1c22fc67e729ec95390d (patch)
tree1bd4349929b88ff41d38014eb0d111237a73db8f
parentf0564b49862eaef0b9752b62d80ef00e3e12a3ee (diff)
wip
-rw-r--r--ports/atmel-samd/mpconfigport.mk4
-rw-r--r--ports/nrf/bluetooth/ble_uart.c4
-rwxr-xr-xports/nrf/common-hal/supervisor/Runtime.c14
-rw-r--r--ports/nrf/supervisor/serial.c10
-rw-r--r--ports/raspberrypi/common-hal/pwmio/PWMOut.c2
-rw-r--r--py/circuitpy_defns.mk3
-rw-r--r--py/circuitpy_mpconfig.h8
-rw-r--r--py/circuitpy_mpconfig.mk32
-rw-r--r--shared-bindings/usb_cdc/Serial.c139
-rw-r--r--shared-bindings/usb_cdc/Serial.h40
-rw-r--r--shared-bindings/usb_cdc/__init__.c57
-rw-r--r--shared-bindings/usb_cdc/__init__.h34
-rw-r--r--shared-module/usb_cdc/Serial.c44
-rw-r--r--shared-module/usb_cdc/Serial.h38
-rw-r--r--shared-module/usb_cdc/__init__.c55
-rw-r--r--shared-module/usb_cdc/__init__.h32
-rw-r--r--supervisor/shared/serial.c10
-rw-r--r--supervisor/supervisor.mk162
-rw-r--r--tools/gen_usb_descriptor.py2
19 files changed, 566 insertions, 124 deletions
diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk
index 9839a2aa4..e47acfb36 100644
--- a/ports/atmel-samd/mpconfigport.mk
+++ b/ports/atmel-samd/mpconfigport.mk
@@ -49,9 +49,9 @@ CIRCUITPY_SDCARDIO ?= 0
CIRCUITPY_FRAMEBUFFERIO ?= 0
# SAMD21 needs separate endpoint pairs for MSC BULK IN and BULK OUT, otherwise it's erratic.
-# Because of that, there aren't enough endpoints for serial2.
+# Because of that, there aren't enough endpoints for a secondary CDC serial connection.
USB_MSC_EP_NUM_OUT = 1
-CIRCUITPY_USB_SERIAL2 = 0
+CIRCUITPY_USB_CDC = 0
CIRCUITPY_ULAB = 0
diff --git a/ports/nrf/bluetooth/ble_uart.c b/ports/nrf/bluetooth/ble_uart.c
index 1e7a319bd..1b87b82d1 100644
--- a/ports/nrf/bluetooth/ble_uart.c
+++ b/ports/nrf/bluetooth/ble_uart.c
@@ -40,7 +40,7 @@
#include "shared-bindings/_bleio/Service.h"
#include "shared-bindings/_bleio/UUID.h"
-#if CIRCUITPY_SERIAL_BLE
+#if CIRCUITPY_REPL_BLE
static const char default_name[] = "CP-REPL"; // max 8 chars or uuid won't fit in adv data
static const char NUS_UUID[] = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
@@ -190,4 +190,4 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
}
}
-#endif // CIRCUITPY_SERIAL_BLE
+#endif // CIRCUITPY_REPL_BLE
diff --git a/ports/nrf/common-hal/supervisor/Runtime.c b/ports/nrf/common-hal/supervisor/Runtime.c
index a8f50f70e..def609cda 100755
--- a/ports/nrf/common-hal/supervisor/Runtime.c
+++ b/ports/nrf/common-hal/supervisor/Runtime.c
@@ -35,17 +35,3 @@ bool common_hal_supervisor_runtime_get_serial_connected(void) {
bool common_hal_get_supervisor_runtime_serial_bytes_available(void) {
return (bool) serial_bytes_available();
}
-
-#if CIRCUITPY_USB_SERIAL2
-mp_obj_t common_hal_supervisor_runtime_get_serial2(void) {
- return (bool) serial_connected();
-}
-
-bool common_hal_supervisor_runtime_get_serial2_connected(void) {
- return (bool) serial_connected();
-}
-
-bool common_hal_get_supervisor_runtime_serial2_bytes_available(void) {
- return (bool) serial_bytes_available();
-}
-#endif
diff --git a/ports/nrf/supervisor/serial.c b/ports/nrf/supervisor/serial.c
index b19e9267c..2c2c0116f 100644
--- a/ports/nrf/supervisor/serial.c
+++ b/ports/nrf/supervisor/serial.c
@@ -28,15 +28,15 @@
#include "supervisor/serial.h"
-#if CIRCUITPY_SERIAL_BLE
+#if CIRCUITPY_REPL_BLE
#include "ble_uart.h"
-#elif CIRCUITPY_SERIAL_UART
+#elif CIRCUITPY_REPL_UART
#include <string.h>
#include "nrf_gpio.h"
#include "nrfx_uarte.h"
#endif
-#if CIRCUITPY_SERIAL_BLE
+#if CIRCUITPY_REPL_BLE
void serial_init(void) {
ble_uart_init();
@@ -58,7 +58,7 @@ void serial_write(const char *text) {
ble_uart_stdout_tx_str(text);
}
-#elif CIRCUITPY_SERIAL_UART
+#elif CIRCUITPY_REPL_UART
uint8_t serial_received_char;
nrfx_uarte_t serial_instance = NRFX_UARTE_INSTANCE(0);
@@ -124,4 +124,4 @@ void serial_write_substring(const char *text, uint32_t len) {
}
}
-#endif // CIRCUITPY_SERIAL_UART
+#endif // CIRCUITPY_REPL_UART
diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.c b/ports/raspberrypi/common-hal/pwmio/PWMOut.c
index 3d8979a03..799ee887f 100644
--- a/ports/raspberrypi/common-hal/pwmio/PWMOut.c
+++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.c
@@ -164,6 +164,7 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t* self) {
extern void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t* self, uint16_t duty) {
self->duty_cycle = duty;
uint16_t actual_duty = duty * self->top / ((1 << 16) - 1);
+ mp_printf(&mp_plat_print, "actual_duty: %d, self->top: %d\n", actual_duty, top); /// ***
pwm_set_chan_level(self->slice, self->channel, actual_duty);
}
@@ -200,6 +201,7 @@ void common_hal_pwmio_pwmout_set_frequency(pwmio_pwmout_obj_t* self, uint32_t fr
} else {
uint32_t top = common_hal_mcu_processor_get_frequency() / frequency;
self->actual_frequency = common_hal_mcu_processor_get_frequency() / top;
+ mp_printf(&mp_plat_print, "high speed self->top: %d\n", top); /// ***
self->top = top;
pwm_set_clkdiv_int_frac(self->slice, 1, 0);
pwm_set_wrap(self->slice, self->top - 1);
diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk
index f907bf7ae..c6dfbb5f2 100644
--- a/py/circuitpy_defns.mk
+++ b/py/circuitpy_defns.mk
@@ -286,6 +286,9 @@ endif
ifeq ($(CIRCUITPY_UHEAP),1)
SRC_PATTERNS += uheap/%
endif
+ifeq ($(CIRCUITPY_USB_CDC),1)
+SRC_PATTERNS += usb_cdc/%
+endif
ifeq ($(CIRCUITPY_USB_HID),1)
SRC_PATTERNS += usb_hid/%
endif
diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h
index ee23c7156..7db864a42 100644
--- a/py/circuitpy_mpconfig.h
+++ b/py/circuitpy_mpconfig.h
@@ -736,6 +736,13 @@ extern const struct _mp_obj_module_t uheap_module;
#define UHEAP_MODULE
#endif
+#if CIRCUITPY_USB_CDC
+extern const struct _mp_obj_module_t usb_cdc_module;
+#define USB_CDC_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_usb_cdc),(mp_obj_t)&usb_cdc_module },
+#else
+#define USB_CDC_MODULE
+#endif
+
#if CIRCUITPY_USB_HID
extern const struct _mp_obj_module_t usb_hid_module;
#define USB_HID_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module },
@@ -875,6 +882,7 @@ extern const struct _mp_obj_module_t msgpack_module;
SUPERVISOR_MODULE \
TOUCHIO_MODULE \
UHEAP_MODULE \
+ USB_CDC_MODULE \
USB_HID_MODULE \
USB_MIDI_MODULE \
USTACK_MODULE \
diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk
index b63bbcb3e..1a12bc50b 100644
--- a/py/circuitpy_mpconfig.mk
+++ b/py/circuitpy_mpconfig.mk
@@ -232,6 +232,15 @@ CFLAGS += -DCIRCUITPY_RANDOM=$(CIRCUITPY_RANDOM)
CIRCUITPY_RE ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_RE=$(CIRCUITPY_RE)
+CIRCUITPY_REPL_BLE ?= 0
+CFLAGS += -DCIRCUITPY_REPL_BLE=$(CIRCUITPY_REPL_BLE)
+
+CIRCUITPY_REPL_UART ?= 0
+CFLAGS += -DCIRCUITPY_REPL_UART=$(CIRCUITPY_REPL_UART)
+
+CIRCUITPY_REPL_USB ?= 1
+CFLAGS += -DCIRCUITPY_REPL_USB=$(CIRCUITPY_REPL_USB)
+
# Should busio.I2C() check for pullups?
# Some boards in combination with certain peripherals may not want this.
CIRCUITPY_REQUIRE_I2C_PULLUPS ?= 1
@@ -264,18 +273,6 @@ CFLAGS += -DCIRCUITPY_SDCARDIO=$(CIRCUITPY_SDCARDIO)
CIRCUITPY_SDIOIO ?= 0
CFLAGS += -DCIRCUITPY_SDIOIO=$(CIRCUITPY_SDIOIO)
-# Second USB CDC serial channel.
-CIRCUITPY_SERIAL2 ?=
-CFLAGS += -DCIRCUITPY_SERIAL2=$(CIRCUITPY_SERIAL2)
-
-# REPL over BLE
-CIRCUITPY_SERIAL_BLE ?= 0
-CFLAGS += -DCIRCUITPY_SERIAL_BLE=$(CIRCUITPY_SERIAL_BLE)
-
-# REPL over UART
-CIRCUITPY_SERIAL_UART ?= 0
-CFLAGS += -DCIRCUITPY_SERIAL_UART=$(CIRCUITPY_SERIAL_UART)
-
CIRCUITPY_SHARPDISPLAY ?= $(CIRCUITPY_FRAMEBUFFERIO)
CFLAGS += -DCIRCUITPY_SHARPDISPLAY=$(CIRCUITPY_SHARPDISPLAY)
@@ -315,6 +312,10 @@ CFLAGS += -DCIRCUITPY_TOUCHIO=$(CIRCUITPY_TOUCHIO)
CIRCUITPY_UHEAP ?= 0
CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP)
+# Secondary CDC is usually available if there are at least 8 endpoints.
+CIRCUITPY_USB_CDC ?= $(shell expr $(USB_NUM_EP) '>=' 8)
+CFLAGS += -DCIRCUITPY_USB_CDC=$(CIRCUITPY_USB_CDC)
+
CIRCUITPY_USB_HID ?= 1
CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID)
@@ -345,9 +346,6 @@ CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI)
CIRCUITPY_USB_MSC ?= 1
CFLAGS += -DCIRCUITPY_USB_MSC=$(CIRCUITPY_USB_MSC)
-CIRCUITPY_USB_SERIAL ?= 1
-CFLAGS += -DCIRCUITPY_USB_SERIAL=$(CIRCUITPY_USB_SERIAL)
-
CIRCUITPY_USB_VENDOR ?= 0
CFLAGS += -DCIRCUITPY_USB_VENDOR=$(CIRCUITPY_USB_VENDOR)
@@ -355,10 +353,6 @@ ifndef USB_NUM_EP
$(error "USB_NUM_EP (number of USB endpoint pairs)must be defined")
endif
-# Secondary CDC is usually available if there are at least 8 endpoints.
-CIRCUITPY_USB_SERIAL2 ?= $(shell expr $(USB_NUM_EP) '>=' 8)
-CFLAGS += -DCIRCUITPY_USB_SERIAL2=$(CIRCUITPY_USB_SERIAL2)
-
# For debugging.
CIRCUITPY_USTACK ?= 0
CFLAGS += -DCIRCUITPY_USTACK=$(CIRCUITPY_USTACK)
diff --git a/shared-bindings/usb_cdc/Serial.c b/shared-bindings/usb_cdc/Serial.c
new file mode 100644
index 000000000..72e9482a2
--- /dev/null
+++ b/shared-bindings/usb_cdc/Serial.c
@@ -0,0 +1,139 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#include "shared-bindings/usb_cdc/Serial.h"
+#include "shared-bindings/util.h"
+
+#include "py/ioctl.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "py/stream.h"
+#include "supervisor/shared/translate.h"
+
+//| class Serial:
+//| """Receives cdc commands over USB"""
+//|
+//| def __init__(self) -> None:
+//| """You cannot create an instance of `usb_cdc.Serial`.
+//|
+//| Serial objects are constructed for every corresponding entry in the USB
+//| descriptor and added to the ``usb_cdc.ports`` tuple."""
+//| ...
+//|
+
+// These are standard stream methods. Code is in py/stream.c.
+//
+//| def read(self, nbytes: Optional[int] = None) -> Optional[bytes]:
+//| """Read characters. If ``nbytes`` is specified then read at most that many
+//| bytes. Otherwise, read everything that arrives until the connection
+//| times out. Providing the number of bytes expected is highly recommended
+//| because it will be faster.
+//|
+//| :return: Data read
+//| :rtype: bytes or None"""
+//| ...
+//|
+//| def readinto(self, buf: WriteableBuffer, nbytes: Optional[int] = None) -> Optional[bytes]:
+//| """Read bytes into the ``buf``. If ``nbytes`` is specified then read at most
+//| that many bytes. Otherwise, read at most ``len(buf)`` bytes.
+//|
+//| :return: number of bytes read and stored into ``buf``
+//| :rtype: bytes or None"""
+//| ...
+//|
+//| def write(self, buf: ReadableBuffer) -> Optional[int]:
+//| """Write the buffer of bytes to the bus.
+//|
+//| :return: the number of bytes written
+//| :rtype: int or None"""
+//| ...
+//|
+
+// These three methods are used by the shared stream methods.
+STATIC mp_uint_t usb_cdc_serial_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
+ usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ byte *buf = buf_in;
+
+ // make sure we want at least 1 char
+ if (size == 0) {
+ return 0;
+ }
+
+ return common_hal_usb_cdc_serial_read(self, buf, size, errcode);
+}
+
+STATIC mp_uint_t usb_cdc_serial_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
+ usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ const byte *buf = buf_in;
+
+ return common_hal_usb_cdc_serial_write(self, buf, size, errcode);
+}
+
+STATIC mp_uint_t usb_cdc_serial_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
+ usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_uint_t ret;
+ if (request == MP_IOCTL_POLL) {
+ mp_uint_t flags = arg;
+ ret = 0;
+ if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_cdc_serial_bytes_available(self) > 0) {
+ ret |= MP_IOCTL_POLL_RD;
+ }
+ if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_cdc_serial_ready_to_tx(self)) {
+ ret |= MP_IOCTL_POLL_WR;
+ }
+ } else {
+ *errcode = MP_EINVAL;
+ ret = MP_STREAM_ERROR;
+ }
+ return ret;
+}
+
+STATIC const mp_rom_map_elem_t usb_cdc_serial_locals_dict_table[] = {
+ // Standard stream methods.
+ { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(usb_cdc_serial_locals_dict, usb_cdc_serial_locals_dict_table);
+
+STATIC const mp_stream_p_t usb_cdc_serial_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
+ .read = usb_cdc_serial_read,
+ .write = usb_cdc_serial_write,
+ .ioctl = usb_cdc_serial_ioctl,
+ .is_text = false,
+};
+
+const mp_obj_type_t usb_cdc_serial_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Serial,
+ .getiter = mp_identity_getiter,
+ .iternext = mp_stream_unbuffered_iter,
+ .protocol = &usb_cdc_serial_stream_p,
+ .locals_dict = (mp_obj_dict_t*)&usb_cdc_serial_locals_dict,
+};
diff --git a/shared-bindings/usb_cdc/Serial.h b/shared-bindings/usb_cdc/Serial.h
new file mode 100644
index 000000000..1ef4167d5
--- /dev/null
+++ b/shared-bindings/usb_cdc/Serial.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC_SERIAL_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC_SERIAL_H
+
+#include "shared-module/usb_cdc/Serial.h"
+
+extern const mp_obj_type_t usb_cdc_serial_type;
+
+extern size_t common_hal_usb_cdc_serial_read(usb_cdc_serial_obj_t *self, uint8_t *data, size_t len, int *errcode);
+extern uint32_t common_hal_usb_cdc_serial_bytes_available(usb_cdc_serial_obj_t *self);
+extern void common_hal_usb_cdc_serial_clear_buffer(usb_cdc_serial_obj_t *self);
+extern size_t common_hal_usb_cdc_serial_write(usb_cdc_serial_obj_t *self, const uint8_t *data, size_t len, int *errcode);
+extern bool common_hal_usb_cdc_serial_ready_to_tx(usb_cdc_serial_obj_t *self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC_SERIAL_H
diff --git a/shared-bindings/usb_cdc/__init__.c b/shared-bindings/usb_cdc/__init__.c
new file mode 100644
index 000000000..d6a70b177
--- /dev/null
+++ b/shared-bindings/usb_cdc/__init__.c
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Dan Halbertfor Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/usb_cdc/__init__.h"
+#include "shared-bindings/usb_cdc/Serial.h"
+
+#include "py/runtime.h"
+
+//| """USB CDC Serial streams
+//|
+//| The `usb_cdc` module allows access to USB CDC (serial) communications.
+//|
+//| serial: Tuple[Serial, ...]
+//| """Tuple of all CDC streams. Each item is a `Serial`."""
+//|
+
+mp_map_elem_t usb_cdc_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usb_cdc) },
+ { MP_ROM_QSTR(MP_QSTR_Serial), MP_OBJ_FROM_PTR(&usb_cdc_serial_type) },
+ { MP_ROM_QSTR(MP_QSTR_serial), mp_const_empty_tuple },
+};
+
+// This isn't const so we can set the streams dynamically.
+MP_DEFINE_MUTABLE_DICT(usb_cdc_module_globals, usb_cdc_module_globals_table);
+
+const mp_obj_module_t usb_cdc_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&usb_cdc_module_globals,
+};
diff --git a/shared-bindings/usb_cdc/__init__.h b/shared-bindings/usb_cdc/__init__.h
new file mode 100644
index 000000000..7938e9172
--- /dev/null
+++ b/shared-bindings/usb_cdc/__init__.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC___INIT___H
+
+#include "py/obj.h"
+
+extern mp_obj_dict_t usb_cdc_module_globals;
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC___INIT___H
diff --git a/shared-module/usb_cdc/Serial.c b/shared-module/usb_cdc/Serial.c
new file mode 100644
index 000000000..663b23c25
--- /dev/null
+++ b/shared-module/usb_cdc/Serial.c
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-module/usb_cdc/Serial.h"
+#include "tusb.h"
+
+size_t common_hal_usb_cdc_serial_read(usb_cdc_serial_obj_t *self, uint8_t *data, size_t len, int *errcode) {
+ return tud_cdc_n_read(self->idx, data, len);
+}
+
+uint32_t common_hal_usb_cdc_serial_bytes_available(usb_cdc_serial_obj_t *self) {
+ return tud_cdc_n_available(self->idx);
+}
+
+size_t common_hal_usb_cdc_serial_write(usb_cdc_serial_obj_t *self, const uint8_t *data, size_t len, int *errcode) {
+ return tud_cdc_n_write(self->idx, data, len);
+}
+
+bool common_hal_usb_cdc_serial_ready_to_tx(usb_cdc_serial_obj_t *self) {
+ return tud_cdc_n_connected(self->idx);
+}
diff --git a/shared-module/usb_cdc/Serial.h b/shared-module/usb_cdc/Serial.h
new file mode 100644
index 000000000..7e3c53e8a
--- /dev/null
+++ b/shared-module/usb_cdc/Serial.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SHARED_MODULE_USB_CDC_SERIAL_H
+#define SHARED_MODULE_USB_CDC_SERIAL_H
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ // Which CDC device?
+ uint8_t idx;
+} usb_cdc_serial_obj_t;
+
+#endif // SHARED_MODULE_USB_CDC_SERIAL_H
diff --git a/shared-module/usb_cdc/__init__.c b/shared-module/usb_cdc/__init__.c
new file mode 100644
index 000000000..ae2412cdd
--- /dev/null
+++ b/shared-module/usb_cdc/__init__.c
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 hathach for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/usb_cdc/__init__.h"
+
+#include "genhdr/autogen_usb_descriptor.h"
+#include "py/obj.h"
+#include "py/mphal.h"
+#include "py/runtime.h"
+#include "py/objtuple.h"
+#include "shared-bindings/usb_cdc/Serial.h"
+#include "tusb.h"
+
+supervisor_allocation* usb_cdc_allocation;
+
+static usb_cdc_serial_obj_t serial_objs[CFG_TUD_CDC];
+
+void usb_cdc_init(void) {
+
+ serial_obj_ptrs *usb_cdc_serial_obj_t[CFG_TUD_CDC];
+
+ for (size_t i = 0; i < CFG_TUD_CDC; i++) {
+ serial_objs[i].base.type = &usb_cdc_serial_type;
+ serial_objs[i].idx = i;
+ serial_obj_ptrs[i] = &serial_objs[i];
+ }
+
+ serials_tuple->base.type = mp_obj_new_tuple(CFG_TUD_CDC, serials);
+
+ repl->base.type =
+ repl->idx = 0; mp_map_lookup(&usb_cdc_module_globals.map, MP_ROM_QSTR(MP_QSTR_serial), MP_MAP_LOOKUP)->value = MP_OBJ_FROM_PTR(serials_tuple);
+}
diff --git a/shared-module/usb_cdc/__init__.h b/shared-module/usb_cdc/__init__.h
new file mode 100644
index 000000000..02b48e116
--- /dev/null
+++ b/shared-module/usb_cdc/__init__.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Dan Halbert for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SHARED_MODULE_USB_CDC___INIT___H
+#define SHARED_MODULE_USB_CDC___INIT___H
+
+void usb_cdc_init(void);
+
+#endif /* SHARED_MODULE_USB_CDC___INIT___H */
diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c
index 40151cbf6..9cc12de51 100644
--- a/supervisor/shared/serial.c
+++ b/supervisor/shared/serial.c
@@ -148,13 +148,3 @@ void serial_write_substring(const char* text, uint32_t length) {
void serial_write(const char* text) {
serial_write_substring(text, strlen(text));
}
-
-#if CIRCUITPY_USB_SERIAL2
-bool serial2_bytes_available(void) {
- return tud_cdc_n_available(1) > 0;
-}
-
-bool serial2_connected(void) {
- return tud_cdc_n_connected(1);
-}
-#endif
diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk
index b36b9bc00..374b7a72b 100644
--- a/supervisor/supervisor.mk
+++ b/supervisor/supervisor.mk
@@ -33,84 +33,100 @@ endif
# (Right now INTERNAL_FLASH_FILESYSTEM and (Q)SPI_FLASH_FILESYSTEM are mutually exclusive.
# But that might not be true in the future.)
ifdef EXTERNAL_FLASH_DEVICES
- CFLAGS += -DEXTERNAL_FLASH_DEVICES=$(EXTERNAL_FLASH_DEVICES) \
- -DEXTERNAL_FLASH_DEVICE_COUNT=$(EXTERNAL_FLASH_DEVICE_COUNT)
-
- SRC_SUPERVISOR += supervisor/shared/external_flash/external_flash.c
- ifeq ($(SPI_FLASH_FILESYSTEM),1)
- SRC_SUPERVISOR += supervisor/shared/external_flash/spi_flash.c
- else
- endif
- ifeq ($(QSPI_FLASH_FILESYSTEM),1)
- SRC_SUPERVISOR += supervisor/qspi_flash.c supervisor/shared/external_flash/qspi_flash.c
- endif
+ CFLAGS += -DEXTERNAL_FLASH_DEVICES=$(EXTERNAL_FLASH_DEVICES) \
+ -DEXTERNAL_FLASH_DEVICE_COUNT=$(EXTERNAL_FLASH_DEVICE_COUNT)
+
+ SRC_SUPERVISOR += supervisor/shared/external_flash/external_flash.c
+ ifeq ($(SPI_FLASH_FILESYSTEM),1)
+ SRC_SUPERVISOR += supervisor/shared/external_flash/spi_flash.c
+ endif
+ ifeq ($(QSPI_FLASH_FILESYSTEM),1)
+ SRC_SUPERVISOR += supervisor/qspi_flash.c supervisor/shared/external_flash/qspi_flash.c
+ endif
else
- ifeq ($(DISABLE_FILESYSTEM),1)
- SRC_SUPERVISOR += supervisor/stub/internal_flash.c
- else
- SRC_SUPERVISOR += supervisor/internal_flash.c
- endif
+ ifeq ($(DISABLE_FILESYSTEM),1)
+ SRC_SUPERVISOR += supervisor/stub/internal_flash.c
+ else
+ SRC_SUPERVISOR += supervisor/internal_flash.c
+ endif
endif
ifeq ($(USB),FALSE)
- ifeq ($(wildcard supervisor/serial.c),)
- SRC_SUPERVISOR += supervisor/stub/serial.c
- else
- SRC_SUPERVISOR += supervisor/serial.c
- endif
+ ifeq ($(wildcard supervisor/serial.c),)
+ SRC_SUPERVISOR += supervisor/stub/serial.c
+ else
+ SRC_SUPERVISOR += supervisor/serial.c
+ endif
else
- SRC_SUPERVISOR += \
- lib/tinyusb/src/common/tusb_fifo.c \
- lib/tinyusb/src/device/usbd.c \
- lib/tinyusb/src/device/usbd_control.c \
- lib/tinyusb/src/class/msc/msc_device.c \
- lib/tinyusb/src/class/cdc/cdc_device.c \
- lib/tinyusb/src/tusb.c \
- supervisor/shared/serial.c \
- supervisor/shared/workflow.c \
- supervisor/usb.c \
- supervisor/shared/usb/usb_desc.c \
- supervisor/shared/usb/usb.c \
- supervisor/shared/usb/usb_msc_flash.c \
- $(BUILD)/autogen_usb_descriptor.c
-
- ifeq ($(CIRCUITPY_USB_HID), 1)
- SRC_SUPERVISOR += \
- lib/tinyusb/src/class/hid/hid_device.c \
- shared-bindings/usb_hid/__init__.c \
- shared-bindings/usb_hid/Device.c \
- shared-module/usb_hid/__init__.c \
- shared-module/usb_hid/Device.c
- endif
-
- ifeq ($(CIRCUITPY_USB_MIDI), 1)
- SRC_SUPERVISOR += \
- lib/tinyusb/src/class/midi/midi_device.c \
- shared-bindings/usb_midi/__init__.c \
- shared-bindings/usb_midi/PortIn.c \
- shared-bindings/usb_midi/PortOut.c \
- shared-module/usb_midi/__init__.c \
- shared-module/usb_midi/PortIn.c \
- shared-module/usb_midi/PortOut.c
- endif
-
- ifeq ($(CIRCUITPY_USB_VENDOR), 1)
- SRC_SUPERVISOR += \
- lib/tinyusb/src/class/vendor/vendor_device.c
- endif
-
- CFLAGS += -DUSB_AVAILABLE
+ SRC_SUPERVISOR += \
+ lib/tinyusb/src/class/cdc/cdc_device.c \
+ lib/tinyusb/src/common/tusb_fifo.c \
+ lib/tinyusb/src/device/usbd.c \
+ lib/tinyusb/src/device/usbd_control.c \
+ lib/tinyusb/src/tusb.c \
+ supervisor/shared/serial.c \
+ supervisor/shared/workflow.c \
+ supervisor/usb.c \
+ supervisor/shared/usb/usb_desc.c \
+ supervisor/shared/usb/usb.c \
+ $(BUILD)/autogen_usb_descriptor.c \
+
+ ifeq ($(CIRCUITPY_USB_CDC), 1)
+ SRC_SUPERVISOR += \
+ shared-bindings/usb_cdc/__init__.c \
+ shared-bindings/usb_cdc/Serial.c \
+ shared-module/usb_cdc/__init__.c \
+ shared-module/usb_cdc/Serial.c \
+
+ endif
+
+ ifeq ($(CIRCUITPY_USB_HID), 1)
+ SRC_SUPERVISOR += \
+ lib/tinyusb/src/class/hid/hid_device.c \
+ shared-bindings/usb_hid/__init__.c \
+ shared-bindings/usb_hid/Device.c \
+ shared-module/usb_hid/__init__.c \
+ shared-module/usb_hid/Device.c \
+
+ endif
+
+ ifeq ($(CIRCUITPY_USB_MIDI), 1)
+ SRC_SUPERVISOR += \
+ lib/tinyusb/src/class/midi/midi_device.c \
+ shared-bindings/usb_midi/__init__.c \
+ shared-bindings/usb_midi/PortIn.c \
+ shared-bindings/usb_midi/PortOut.c \
+ shared-module/usb_midi/__init__.c \
+ shared-module/usb_midi/PortIn.c \
+ shared-module/usb_midi/PortOut.c \
+
+ endif
+
+ ifeq ($(CIRCUITPY_USB_MSC), 1)
+ SRC_SUPERVISOR += \
+ lib/tinyusb/src/class/msc/msc_device.c \
+ supervisor/shared/usb/usb_msc_flash.c \
+
+ endif
+
+ ifeq ($(CIRCUITPY_USB_VENDOR), 1)
+ SRC_SUPERVISOR += \
+ lib/tinyusb/src/class/vendor/vendor_device.c \
+
+ endif
+
+ CFLAGS += -DUSB_AVAILABLE
endif
SUPERVISOR_O = $(addprefix $(BUILD)/, $(SRC_SUPERVISOR:.c=.o))
ifeq ($(CIRCUITPY_DISPLAYIO), 1)
- SRC_SUPERVISOR += \
- supervisor/shared/display.c
+ SRC_SUPERVISOR += \
+ supervisor/shared/display.c
- ifeq ($(CIRCUITPY_TERMINALIO), 1)
- SUPERVISOR_O += $(BUILD)/autogen_display_resources.o
- endif
+ ifeq ($(CIRCUITPY_TERMINALIO), 1)
+ SUPERVISOR_O += $(BUILD)/autogen_display_resources.o
+ endif
endif
USB_INTERFACE_NAME ?= "CircuitPython"
@@ -126,16 +142,20 @@ endif
# It gets added automatically.
USB_WEBUSB_URL ?= "circuitpython.org"
+ifeq ($(CIRCUITPY_REPL_USB),1)
+USB_DEVICES += CDC
+endif
+
+ifeq ($(CIRCUITPY_USB_HID),1)
+USB_DEVICES += HID
+endif
ifeq ($(CIRCUITPY_USB_MIDI),1)
USB_DEVICES += AUDIO
endif
ifeq ($(CIRCUITPY_USB_MSC),1)
USB_DEVICES += MSC
endif
-ifeq ($(CIRCUITPY_USB_SERIAL),1)
-USB_DEVICES += CDC
-endif
-ifeq ($(CIRCUITPY_USB_SERIAL2),1)
+ifeq ($(CIRCUITPY_USB_CDC),1)
# Inform TinyUSB there are two CDC devices.
CFLAGS += -DCFG_TUD_CDC=2
USB_DEVICES += CDC2
diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py
index b056f853a..3f4249f0a 100644
--- a/tools/gen_usb_descriptor.py
+++ b/tools/gen_usb_descriptor.py
@@ -830,7 +830,6 @@ extern uint16_t const * const string_desc_arr [{string_descriptor_length}];
rhport0_mode="OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED"
if args.highspeed
else "OPT_MODE_DEVICE",
- hid_num_devices=len(args.hid_devices),
msc_vendor=args.manufacturer[:8],
msc_product=args.product[:16],
)
@@ -844,6 +843,7 @@ extern const uint8_t hid_report_descriptor[{hid_report_descriptor_length}];
#define USB_HID_NUM_DEVICES {hid_num_devices}
""".format(
hid_report_descriptor_length=len(bytes(combined_hid_report_descriptor)),
+ hid_num_devices=len(args.hid_devices),
)
)