diff options
Diffstat (limited to 'ports')
-rw-r--r-- | ports/zephyr/CMakeLists.txt | 1 | ||||
-rw-r--r-- | ports/zephyr/Kconfig | 8 | ||||
-rw-r--r-- | ports/zephyr/boards/beagleconnect_freedom.conf | 1 | ||||
-rw-r--r-- | ports/zephyr/boards/nrf9151dk_nrf9151.conf | 7 | ||||
-rw-r--r-- | ports/zephyr/boards/nrf9151dk_nrf9151.overlay | 22 | ||||
-rw-r--r-- | ports/zephyr/main.c | 8 | ||||
-rw-r--r-- | ports/zephyr/src/usbd.c | 183 | ||||
-rw-r--r-- | ports/zephyr/zephyr_storage.c | 19 |
8 files changed, 246 insertions, 3 deletions
diff --git a/ports/zephyr/CMakeLists.txt b/ports/zephyr/CMakeLists.txt index 4f457f4a58..debf2bd2c1 100644 --- a/ports/zephyr/CMakeLists.txt +++ b/ports/zephyr/CMakeLists.txt @@ -128,6 +128,7 @@ add_dependencies(${MICROPY_TARGET} zephyr_generated_headers) target_sources(app PRIVATE src/zephyr_start.c src/zephyr_getchar.c + src/usbd.c ) target_link_libraries(app PRIVATE ${MICROPY_TARGET}) diff --git a/ports/zephyr/Kconfig b/ports/zephyr/Kconfig index f8d1543155..6db0133f4f 100644 --- a/ports/zephyr/Kconfig +++ b/ports/zephyr/Kconfig @@ -49,6 +49,14 @@ config MICROPY_FROZEN_MANIFEST depends on MICROPY_FROZEN_MODULES default "boards/manifest.py" +config MICROPY_USB_DEVICE_VID + hex "USB VID" + default 0x2fe3 + +config MICROPY_USB_DEVICE_PID + hex "USB PID" + default 0x0001 + endmenu # MicroPython Options source "Kconfig.zephyr" diff --git a/ports/zephyr/boards/beagleconnect_freedom.conf b/ports/zephyr/boards/beagleconnect_freedom.conf index 1e3f6037bd..8fe2583205 100644 --- a/ports/zephyr/boards/beagleconnect_freedom.conf +++ b/ports/zephyr/boards/beagleconnect_freedom.conf @@ -1,4 +1,5 @@ # Hardware features +CONFIG_ADC=y CONFIG_PWM=y CONFIG_I2C=y CONFIG_SPI=y diff --git a/ports/zephyr/boards/nrf9151dk_nrf9151.conf b/ports/zephyr/boards/nrf9151dk_nrf9151.conf new file mode 100644 index 0000000000..e89f332ba1 --- /dev/null +++ b/ports/zephyr/boards/nrf9151dk_nrf9151.conf @@ -0,0 +1,7 @@ +# Enable external flash +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_SPI_NOR_SFDP_DEVICETREE=y + +CONFIG_FLASH=y +CONFIG_FLASH_MAP=y diff --git a/ports/zephyr/boards/nrf9151dk_nrf9151.overlay b/ports/zephyr/boards/nrf9151dk_nrf9151.overlay new file mode 100644 index 0000000000..85cab57414 --- /dev/null +++ b/ports/zephyr/boards/nrf9151dk_nrf9151.overlay @@ -0,0 +1,22 @@ +/ { + /* Configure partition manager to use gd25wb256 as the external flash */ + chosen { + nordic,pm-ext-flash = &gd25wb256; + }; +}; + +/delete-node/ &storage_partition; + +&gd25wb256 { + status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + reg = <0x00000000 0x2000000>; + label = "storage"; + }; + }; +}; diff --git a/ports/zephyr/main.c b/ports/zephyr/main.c index 206b7f92d3..d4498c1079 100644 --- a/ports/zephyr/main.c +++ b/ports/zephyr/main.c @@ -63,6 +63,10 @@ static char heap[MICROPY_HEAP_SIZE]; +#if defined(CONFIG_USB_DEVICE_STACK_NEXT) +extern int mp_usbd_init(void); +#endif // defined(CONFIG_USB_DEVICE_STACK_NEXT) + void init_zephyr(void) { // We now rely on CONFIG_NET_APP_SETTINGS to set up bootstrap // network addresses. @@ -143,6 +147,10 @@ soft_reset: usb_enable(NULL); #endif + #ifdef CONFIG_USB_DEVICE_STACK_NEXT + mp_usbd_init(); + #endif + #if MICROPY_VFS vfs_init(); #endif diff --git a/ports/zephyr/src/usbd.c b/ports/zephyr/src/usbd.c new file mode 100644 index 0000000000..2444706cbe --- /dev/null +++ b/ports/zephyr/src/usbd.c @@ -0,0 +1,183 @@ +/* +* This file is part of the MicroPython project, http://micropython.org/ +* +* The MIT License (MIT) +* +* Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) +* +* 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 <zephyr/device.h> +#include <zephyr/usb/usbd.h> +#include <zephyr/usb/bos.h> + +#if defined(CONFIG_USB_DEVICE_STACK_NEXT) + +#include <zephyr/logging/log.h> +LOG_MODULE_REGISTER(mp_usbd); + +/* By default, do not register the USB DFU class DFU mode instance. */ +static const char *const blocklist[] = { + "dfu_dfu", + NULL, +}; + +USBD_DEVICE_DEFINE(mp_usbd, + DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)), + CONFIG_MICROPY_USB_DEVICE_VID, CONFIG_MICROPY_USB_DEVICE_PID); + +USBD_DESC_LANG_DEFINE(mp_lang); +USBD_DESC_MANUFACTURER_DEFINE(mp_mfr, "Zephyr Project"); +USBD_DESC_PRODUCT_DEFINE(mp_product, "Micropython on Zephyr RTOS"); +USBD_DESC_SERIAL_NUMBER_DEFINE(mp_sn); + +USBD_DESC_CONFIG_DEFINE(fs_cfg_desc, "FS Configuration"); +USBD_DESC_CONFIG_DEFINE(hs_cfg_desc, "HS Configuration"); + +/* not self-powered, no remote wakeup */ +static const uint8_t attributes = 0; + +/* Full speed configuration +* power = 250 * 2 mA = 500mA +*/ +USBD_CONFIGURATION_DEFINE(mp_fs_config, + attributes, + 250, &fs_cfg_desc); + +/* High speed configuration */ +USBD_CONFIGURATION_DEFINE(mp_hs_config, + attributes, + 250, &hs_cfg_desc); + +static void mp_fix_code_triple(struct usbd_context *uds_ctx, + const enum usbd_speed speed) { + /* Always use class code information from Interface Descriptors */ + if (IS_ENABLED(CONFIG_USBD_CDC_ACM_CLASS) || + IS_ENABLED(CONFIG_USBD_CDC_ECM_CLASS) || + IS_ENABLED(CONFIG_USBD_CDC_NCM_CLASS) || + IS_ENABLED(CONFIG_USBD_AUDIO2_CLASS)) { + /* + * Class with multiple interfaces have an Interface + * Association Descriptor available, use an appropriate triple + * to indicate it. + */ + usbd_device_set_code_triple(uds_ctx, speed, + USB_BCC_MISCELLANEOUS, 0x02, 0x01); + } else { + usbd_device_set_code_triple(uds_ctx, speed, 0, 0, 0); + } +} + +struct usbd_context *mp_usbd_init_device(usbd_msg_cb_t msg_cb) { + int err; + + err = usbd_add_descriptor(&mp_usbd, &mp_lang); + if (err) { + LOG_ERR("Failed to initialize language descriptor (%d)", err); + return NULL; + } + + err = usbd_add_descriptor(&mp_usbd, &mp_mfr); + if (err) { + LOG_ERR("Failed to initialize manufacturer descriptor (%d)", err); + return NULL; + } + + err = usbd_add_descriptor(&mp_usbd, &mp_product); + if (err) { + LOG_ERR("Failed to initialize product descriptor (%d)", err); + return NULL; + } + + err = usbd_add_descriptor(&mp_usbd, &mp_sn); + if (err) { + LOG_ERR("Failed to initialize SN descriptor (%d)", err); + return NULL; + } + + if (usbd_caps_speed(&mp_usbd) == USBD_SPEED_HS) { + err = usbd_add_configuration(&mp_usbd, USBD_SPEED_HS, + &mp_hs_config); + if (err) { + LOG_ERR("Failed to add High-Speed configuration"); + return NULL; + } + + err = usbd_register_all_classes(&mp_usbd, USBD_SPEED_HS, 1, blocklist); + if (err) { + LOG_ERR("Failed to add register classes"); + return NULL; + } + + mp_fix_code_triple(&mp_usbd, USBD_SPEED_HS); + } + + err = usbd_add_configuration(&mp_usbd, USBD_SPEED_FS, + &mp_fs_config); + if (err) { + LOG_ERR("Failed to add Full-Speed configuration"); + return NULL; + } + + err = usbd_register_all_classes(&mp_usbd, USBD_SPEED_FS, 1, blocklist); + if (err) { + LOG_ERR("Failed to add register classes"); + return NULL; + } + + mp_fix_code_triple(&mp_usbd, USBD_SPEED_FS); + + if (msg_cb != NULL) { + err = usbd_msg_register_cb(&mp_usbd, msg_cb); + if (err) { + LOG_ERR("Failed to register message callback"); + return NULL; + } + } + + err = usbd_init(&mp_usbd); + if (err) { + LOG_ERR("Failed to initialize device support"); + return NULL; + } + + return &mp_usbd; +} + +static struct usbd_context *mp_usbd_context; + +int mp_usbd_init(void) { + int err; + + mp_usbd_context = mp_usbd_init_device(NULL); + if (mp_usbd_context == NULL) { + return -ENODEV; + } + + err = usbd_enable(mp_usbd_context); + if (err) { + return err; + } + + return 0; +} + +#endif // defined(CONFIG_USB_DEVICE_STACK_NEXT) diff --git a/ports/zephyr/zephyr_storage.c b/ports/zephyr/zephyr_storage.c index 484feb1130..40bcef7338 100644 --- a/ports/zephyr/zephyr_storage.c +++ b/ports/zephyr/zephyr_storage.c @@ -139,6 +139,20 @@ MP_DEFINE_CONST_OBJ_TYPE( #endif // CONFIG_DISK_ACCESS #ifdef CONFIG_FLASH_MAP + +#define FLASH_AREA_DEFINE_LABEL(part) CONCAT(MP_QSTR_ID_, DT_STRING_TOKEN(part, label)) +#define FLASH_AREA_DEFINE_NB(part) CONCAT(MP_QSTR_ID_, DT_FIXED_PARTITION_ID(part)) + +#define FLASH_AREA_DEFINE_GETNAME(part) COND_CODE_1(DT_NODE_HAS_PROP(part, label), \ + (FLASH_AREA_DEFINE_LABEL(part)), (FLASH_AREA_DEFINE_NB(part))) + +#define FLASH_AREA_DEFINE_DEFINE(part) { MP_ROM_QSTR(FLASH_AREA_DEFINE_GETNAME(part)), MP_ROM_INT(DT_FIXED_PARTITION_ID(part)) }, + +#define FLASH_AREA_DEFINE(part) COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_MTD_FROM_FIXED_PARTITION(part)), \ + (FLASH_AREA_DEFINE_DEFINE(part)), ()) + +#define FOREACH_PARTITION(n) DT_FOREACH_CHILD(n, FLASH_AREA_DEFINE) + const mp_obj_type_t zephyr_flash_area_type; typedef struct _zephyr_flash_area_obj_t { @@ -244,9 +258,8 @@ static const mp_rom_map_elem_t zephyr_flash_area_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&zephyr_flash_area_readblocks_obj) }, { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&zephyr_flash_area_writeblocks_obj) }, { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&zephyr_flash_area_ioctl_obj) }, - #if FIXED_PARTITION_EXISTS(storage_partition) - { MP_ROM_QSTR(MP_QSTR_STORAGE), MP_ROM_INT(FIXED_PARTITION_ID(storage_partition)) }, - #endif + /* Generate list of partition IDs from Zephyr Devicetree */ + DT_FOREACH_STATUS_OKAY(fixed_partitions, FOREACH_PARTITION) }; static MP_DEFINE_CONST_DICT(zephyr_flash_area_locals_dict, zephyr_flash_area_locals_dict_table); |