diff options
| author | Scott Shawcroft <scott@tannewt.org> | 2018-10-19 18:46:22 -0700 |
|---|---|---|
| committer | Scott Shawcroft <scott@tannewt.org> | 2018-11-08 17:25:30 -0800 |
| commit | 9d91111b1b6a1eee77a88b13faf695ee0c5caea3 (patch) | |
| tree | 97b1bf6ae67f8c91f7a32a0246e2f8ebd9a749c7 /shared-module | |
| parent | d08747d374057b24803b429bbf6474a2e4dcea5c (diff) | |
Move atmel-samd to tinyusb and support nRF flash.
This started while adding USB MIDI support (and descriptor support is
in this change.) When seeing that I'd have to implement the MIDI class
logic twice, once for atmel-samd and once for nrf, I decided to refactor
the USB stack so its shared across ports. This has led to a number of
changes that remove items from the ports folder and move them into
supervisor.
Furthermore, we had external SPI flash support for nrf pending so I
factored out the connection between the usb stack and the flash API as
well. This PR also includes the QSPI support for nRF.
Diffstat (limited to 'shared-module')
| -rw-r--r-- | shared-module/bitbangio/SPI.c | 3 | ||||
| -rw-r--r-- | shared-module/storage/__init__.c | 26 | ||||
| -rw-r--r-- | shared-module/usb_hid/Device.c | 88 | ||||
| -rw-r--r-- | shared-module/usb_hid/Device.h | 55 | ||||
| -rw-r--r-- | shared-module/usb_hid/__init__.c | 154 |
5 files changed, 324 insertions, 2 deletions
diff --git a/shared-module/bitbangio/SPI.c b/shared-module/bitbangio/SPI.c index 9e4508355..6d3a28523 100644 --- a/shared-module/bitbangio/SPI.c +++ b/shared-module/bitbangio/SPI.c @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#include "mpconfigport.h" - +#include "py/mpconfig.h" #include "py/obj.h" #include "py/runtime.h" diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c index edce286b1..f09edd785 100644 --- a/shared-module/storage/__init__.c +++ b/shared-module/storage/__init__.c @@ -32,8 +32,12 @@ #include "py/mperrno.h" #include "py/obj.h" #include "py/runtime.h" +#include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/os/__init__.h" #include "shared-bindings/storage/__init__.h" +#include "supervisor/filesystem.h" +#include "supervisor/flash.h" +#include "supervisor/usb.h" STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) { if (vfs == MP_VFS_NONE) { @@ -138,3 +142,25 @@ void common_hal_storage_umount_path(const char* mount_path) { mp_obj_t common_hal_storage_getmount(const char *mount_path) { return storage_object_from_path(mount_path); } + +void common_hal_storage_remount(const char *mount_path, bool readonly) { + if (strcmp(mount_path, "/") != 0) { + mp_raise_OSError(MP_EINVAL); + } + + #ifdef USB_AVAILABLE + // TODO(dhalbert): is this is a good enough check? It checks for + // CDC enabled. There is no "MSC enabled" check. + if (usb_enabled()) { + mp_raise_RuntimeError(translate("Cannot remount '/' when USB is active.")); + } + #endif + + supervisor_flash_set_usb_writable(readonly); +} + +void common_hal_storage_erase_filesystem(void) { + filesystem_init(false, true); // Force a re-format. + common_hal_mcu_reset(); + // We won't actually get here, since we're resetting. +} diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c new file mode 100644 index 000000000..820e14ad0 --- /dev/null +++ b/shared-module/usb_hid/Device.c @@ -0,0 +1,88 @@ +/* + * 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 <string.h> +#include "tick.h" +#include "py/runtime.h" +#include "shared-bindings/usb_hid/Device.h" +#include "shared-module/usb_hid/Device.h" +#include "supervisor/shared/translate.h" +#include "tusb.h" + +uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) { + return self->usage_page; +} + +uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) { + return self->usage; +} + +void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) { + if (len != self->report_length) { + mp_raise_ValueError_varg(translate("Buffer incorrect size. Should be %d bytes."), self->report_length); + } + + // Wait until interface is ready, timeout = 2 seconds + uint64_t end_ticks = ticks_ms + 2000; + while ( (ticks_ms < end_ticks) && !tud_hid_generic_ready() ) { } + + if ( !tud_hid_generic_ready() ) { + mp_raise_msg(&mp_type_OSError, translate("USB Busy")); + } + + memcpy(self->report_buffer, report, len); + + if ( !tud_hid_generic_report(self->report_id, self->report_buffer, len) ) { + mp_raise_msg(&mp_type_OSError, translate("USB Error")); + } +} + +// Callbacks invoked when receive Get_Report request through control endpoint +uint16_t tud_hid_generic_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { + // only support Input Report + if ( report_type != HID_REPORT_TYPE_INPUT ) return 0; + + // index is ID-1 + uint8_t idx = ( report_id ? (report_id-1) : 0 ); + + // fill buffer with current report + memcpy(buffer, usb_hid_devices[idx].report_buffer, reqlen); + return reqlen; +} + +// Callbacks invoked when receive Set_Report request through control endpoint +void tud_hid_generic_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { + // index is ID-1 + uint8_t idx = ( report_id ? (report_id-1) : 0 ); + + if ( report_type == HID_REPORT_TYPE_OUTPUT ) { + // Check if it is Keyboard device + if ( (usb_hid_devices[idx].usage_page == HID_USAGE_PAGE_DESKTOP) && (usb_hid_devices[idx].usage == HID_USAGE_DESKTOP_KEYBOARD) ) { + // This is LED indicator (CapsLock, NumLock) + // TODO Light up some LED here + } + } +} diff --git a/shared-module/usb_hid/Device.h b/shared-module/usb_hid/Device.h new file mode 100644 index 000000000..10f2ee897 --- /dev/null +++ b/shared-module/usb_hid/Device.h @@ -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. + */ + +#ifndef SHARED_MODULE_USB_HID_DEVICE_H +#define SHARED_MODULE_USB_HID_DEVICE_H + +#include <stdint.h> +#include <stdbool.h> + +#include "py/obj.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct { + mp_obj_base_t base; + uint8_t* report_buffer; + uint8_t report_id; + uint8_t report_length; + uint8_t usage_page; + uint8_t usage; +} usb_hid_device_obj_t; + + +extern usb_hid_device_obj_t usb_hid_devices[]; + +#ifdef __cplusplus + } +#endif + +#endif /* SHARED_MODULE_USB_HID_DEVICE_H */ diff --git a/shared-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c new file mode 100644 index 000000000..c0f9c897c --- /dev/null +++ b/shared-module/usb_hid/__init__.c @@ -0,0 +1,154 @@ +/* + * 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 "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "genhdr/autogen_usb_descriptor.h" +#include "shared-module/usb_hid/Device.h" +#include "shared-bindings/usb_hid/Device.h" +#include "tusb.h" + +#ifdef USB_HID_REPORT_ID_KEYBOARD +static uint8_t keyboard_report_buffer[USB_HID_REPORT_LENGTH_KEYBOARD]; +#endif + +#ifdef USB_HID_REPORT_ID_MOUSE +static uint8_t mouse_report_buffer[USB_HID_REPORT_LENGTH_MOUSE]; +#endif + +#ifdef USB_HID_REPORT_ID_CONSUMER +static uint8_t consumer_report_buffer[USB_HID_REPORT_LENGTH_CONSUMER]; +#endif + +#ifdef USB_HID_REPORT_ID_SYS_CONTROL +static uint8_t sys_control_report_buffer[USB_HID_REPORT_LENGTH_SYS_CONTROL]; +#endif + +#ifdef USB_HID_REPORT_ID_GAMEPAD +static uint8_t gamepad_report_buffer[USB_HID_REPORT_LENGTH_GAMEPAD]; +#endif + +#ifdef USB_HID_REPORT_ID_DIGITIZER +static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER]; +#endif + +usb_hid_device_obj_t usb_hid_devices[] = { +#if USB_HID_REPORT_ID_KEYBOARD + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = keyboard_report_buffer , + .report_id = USB_HID_REPORT_ID_KEYBOARD , + .report_length = USB_HID_REPORT_LENGTH_KEYBOARD , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_KEYBOARD , + }, +#endif + +#if USB_HID_REPORT_ID_MOUSE + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = mouse_report_buffer , + .report_id = USB_HID_REPORT_ID_MOUSE , + .report_length = USB_HID_REPORT_LENGTH_MOUSE , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_MOUSE , + }, +#endif + +#if USB_HID_REPORT_ID_CONSUMER + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = consumer_report_buffer , + .report_id = USB_HID_REPORT_ID_CONSUMER , + .report_length = USB_HID_REPORT_LENGTH_CONSUMER , + .usage_page = HID_USAGE_PAGE_CONSUMER , + .usage = HID_USAGE_CONSUMER_CONTROL , + }, +#endif + +#if USB_HID_REPORT_ID_SYS_CONTROL + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = sys_control_report_buffer , + .report_id = USB_HID_REPORT_ID_SYS_CONTROL , + .report_length = USB_HID_REPORT_LENGTH_SYS_CONTROL , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_SYSTEM_CONTROL , + }, +#endif + +#if USB_HID_REPORT_ID_GAMEPAD + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = gamepad_report_buffer , + .report_id = USB_HID_REPORT_ID_GAMEPAD , + .report_length = USB_HID_REPORT_LENGTH_GAMEPAD , + .usage_page = HID_USAGE_PAGE_DESKTOP , + .usage = HID_USAGE_DESKTOP_GAMEPAD , + }, +#endif + +#if USB_HID_REPORT_ID_DIGITIZER + { + .base = { .type = &usb_hid_device_type } , + .report_buffer = digitizer_report_buffer , + .report_id = USB_HID_REPORT_ID_DIGITIZER , + .report_length = USB_HID_REPORT_LENGTH_DIGITIZER , + .usage_page = 0x0D , + .usage = 0x02 , + }, +#endif +}; + + +mp_obj_tuple_t common_hal_usb_hid_devices = { + .base = { + .type = &mp_type_tuple, + }, + .len = USB_HID_NUM_DEVICES, + .items = { +#if USB_HID_NUM_DEVICES >= 1 + (mp_obj_t) &usb_hid_devices[0], +#endif +#if USB_HID_NUM_DEVICES >= 2 + (mp_obj_t) &usb_hid_devices[1], +#endif +#if USB_HID_NUM_DEVICES >= 3 + (mp_obj_t) &usb_hid_devices[2], +#endif +#if USB_HID_NUM_DEVICES >= 4 + (mp_obj_t) &usb_hid_devices[3], +#endif +#if USB_HID_NUM_DEVICES >= 5 + (mp_obj_t) &usb_hid_devices[4], +#endif +#if USB_HID_NUM_DEVICES >= 6 + (mp_obj_t) &usb_hid_devices[5], +#endif + } +}; |
