diff options
| author | Ha Thach <[email protected]> | 2023-10-17 22:31:33 +0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-10-17 22:31:33 +0700 |
| commit | 80ee30724479e6c756b7e10900f105e81217e1c0 (patch) | |
| tree | a8d13578e653c43df0288e294d05bdcb8658a254 /hw/bsp | |
| parent | c4566c4d2ba5219e6c2ea821912b888d0270ff07 (diff) | |
| parent | 118823c254ab002cf3aeed54653de0c9a93672d3 (diff) | |
Merge branch 'master' into feat-stm32u575_nucleo
Diffstat (limited to 'hw/bsp')
80 files changed, 2531 insertions, 452 deletions
diff --git a/hw/bsp/board.c b/hw/bsp/board.c index 417630a03..562792625 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -44,17 +44,16 @@ // If using SES IDE, use the Syscalls/SEGGER_RTT_Syscalls_SES.c instead #if !(defined __SES_ARM) && !(defined __SES_RISCV) && !(defined __CROSSWORKS_ARM) + #include "SEGGER_RTT.h" -TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) -{ +TU_ATTR_USED int sys_write(int fhdl, const void *buf, size_t count) { (void) fhdl; - SEGGER_RTT_Write(0, (const char*) buf, (int) count); + SEGGER_RTT_Write(0, (const char *) buf, (int) count); return count; } -TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) -{ +TU_ATTR_USED int sys_read(int fhdl, char *buf, size_t count) { (void) fhdl; int rd = (int) SEGGER_RTT_Read(0, buf, count); return (rd > 0) ? rd : -1; @@ -67,8 +66,7 @@ TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) #include "board_mcu.h" -TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) -{ +TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) { (void) fhdl; uint8_t const* buf8 = (uint8_t const*) buf; @@ -79,8 +77,7 @@ TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) return (int) count; } -TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) -{ +TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) { (void) fhdl; (void) buf; (void) count; @@ -90,14 +87,12 @@ TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) #else // Default logging with on-board UART -TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) -{ +TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) { (void) fhdl; return board_uart_write(buf, (int) count); } -TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) -{ +TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) { (void) fhdl; int rd = board_uart_read((uint8_t*) buf, (int) count); return (rd > 0) ? rd : -1; @@ -105,8 +100,7 @@ TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) #endif -int board_getchar(void) -{ +int board_getchar(void) { char c; - return ( sys_read(0, &c, 1) > 0 ) ? (int) c : (-1); + return (sys_read(0, &c, 1) > 0) ? (int) c : (-1); } diff --git a/hw/bsp/espressif/boards/CMakeLists.txt b/hw/bsp/espressif/boards/CMakeLists.txt index 325263c1d..8209e8747 100644 --- a/hw/bsp/espressif/boards/CMakeLists.txt +++ b/hw/bsp/espressif/boards/CMakeLists.txt @@ -4,3 +4,5 @@ idf_component_register(SRCS family.c INCLUDE_DIRS "." ${BOARD} ${hw_dir} PRIV_REQUIRES "driver" REQUIRES led_strip src tinyusb_src) + +target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) diff --git a/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h b/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h index 2ec80ef47..44ff11aa0 100644 --- a/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h +++ b/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h @@ -36,6 +36,14 @@ #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 36 +#define MAX3421_MOSI_PIN 35 +#define MAX3421_MISO_PIN 37 +#define MAX3421_CS_PIN 15 +#define MAX3421_INTR_PIN 14 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/espressif/boards/espressif_kaluga_1/board.h b/hw/bsp/espressif/boards/espressif_kaluga_1/board.h index 0acb9c439..613e6ae0c 100644 --- a/hw/bsp/espressif/boards/espressif_kaluga_1/board.h +++ b/hw/bsp/espressif/boards/espressif_kaluga_1/board.h @@ -37,6 +37,14 @@ #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 36 +#define MAX3421_MOSI_PIN 35 +#define MAX3421_MISO_PIN 37 +#define MAX3421_CS_PIN 15 +#define MAX3421_INTR_PIN 14 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake new file mode 100644 index 000000000..abbdf7abc --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake @@ -0,0 +1,2 @@ +# Apply board specific content here +set(IDF_TARGET "esp32s2") diff --git a/hw/bsp/espressif/boards/espressif_s2_devkitc/board.h b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.h new file mode 100644 index 000000000..e068efef9 --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.h @@ -0,0 +1,45 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * 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. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// Note: On the production version (v1.2) WS2812 is connected to GPIO 18, +// however earlier revision v1.1 WS2812 is connected to GPIO 17 +#define NEOPIXEL_PIN 18 + +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h b/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h index fe33b5c43..4b4151e72 100644 --- a/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h +++ b/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h @@ -36,6 +36,14 @@ #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 36 +#define MAX3421_MOSI_PIN 35 +#define MAX3421_MISO_PIN 37 +#define MAX3421_CS_PIN 15 +#define MAX3421_INTR_PIN 14 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index 8f857fb71..912ca5f35 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -33,27 +33,55 @@ #include "soc/usb_periph.h" #include "driver/rmt.h" +#include "driver/uart.h" #if ESP_IDF_VERSION_MAJOR > 4 #include "esp_private/periph_ctrl.h" #else + #include "driver/periph_ctrl.h" + #endif +// Note; current code use UART0 can cause device to reset while monitoring +#define USE_UART 0 +#define UART_ID UART_NUM_0 + #ifdef NEOPIXEL_PIN + #include "led_strip.h" -static led_strip_t *strip; + +static led_strip_t* strip; #endif +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + +#include "driver/spi_master.h" + +static void max3421_init(void); + +#endif + +static void configure_pins(usb_hal_context_t* usb); + //--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION +// Implementation //--------------------------------------------------------------------+ -static void configure_pins(usb_hal_context_t *usb); - // Initialize on-board peripherals : led, button, uart and USB -void board_init(void) -{ +void board_init(void) { +#if USE_UART + // uart init + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE + }; + uart_driver_install(UART_ID, 1024, 0, 0, NULL, 0); + uart_param_config(UART_ID, &uart_config); +#endif #ifdef NEOPIXEL_PIN #ifdef NEOPIXEL_POWER_PIN @@ -84,19 +112,21 @@ void board_init(void) periph_module_enable(PERIPH_USB_MODULE); usb_hal_context_t hal = { - .use_external_phy = false // use built-in PHY + .use_external_phy = false // use built-in PHY }; usb_hal_init(&hal); configure_pins(&hal); + +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + max3421_init(); +#endif } -static void configure_pins(usb_hal_context_t *usb) -{ +static void configure_pins(usb_hal_context_t* usb) { /* usb_periph_iopins currently configures USB_OTG as USB Device. * Introduce additional parameters in usb_hal_context_t when adding support - * for USB Host. - */ - for (const usb_iopin_dsc_t *iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) { + * for USB Host. */ + for (const usb_iopin_dsc_t* iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) { if ((usb->use_external_phy) || (iopin->ext_phy_only == 0)) { esp_rom_gpio_pad_select_gpio(iopin->pin); if (iopin->is_output) { @@ -115,6 +145,7 @@ static void configure_pins(usb_hal_context_t *usb) esp_rom_gpio_pad_unhold(iopin->pin); } } + if (!usb->use_external_phy) { gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3); gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3); @@ -122,8 +153,7 @@ static void configure_pins(usb_hal_context_t *usb) } // Turn LED on or off -void board_led_write(bool state) -{ +void board_led_write(bool state) { #ifdef NEOPIXEL_PIN strip->set_pixel(strip, 0, (state ? 0x88 : 0x00), 0x00, 0x00); strip->refresh(strip, 100); @@ -132,21 +162,138 @@ void board_led_write(bool state) // Get the current state of button // a '1' means active (pressed), a '0' means inactive. -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return gpio_get_level(BUTTON_PIN) == BUTTON_STATE_ACTIVE; } // Get characters from UART -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; - return 0; +int board_uart_read(uint8_t* buf, int len) { +#if USE_UART + return uart_read_bytes(UART_ID, buf, len, 0); +#else + return -1; +#endif } // Send characters to UART -int board_uart_write(void const * buf, int len) -{ - (void) buf; (void) len; +int board_uart_write(void const* buf, int len) { + (void) buf; + (void) len; return 0; } + +int board_getchar(void) { + uint8_t c = 0; + return board_uart_read(&c, 1) > 0 ? (int) c : (-1); +} + +//--------------------------------------------------------------------+ +// API: SPI transfer with MAX3421E, must be implemented by application +//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +static spi_device_handle_t max3421_spi; +SemaphoreHandle_t max3421_intr_sem; + +static void IRAM_ATTR max3421_isr_handler(void* arg) { + (void) arg; // arg is gpio num + gpio_set_level(13, 1); + + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + xSemaphoreGiveFromISR(max3421_intr_sem, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken) { + portYIELD_FROM_ISR(); + } + + gpio_set_level(13, 0); +} + +static void max3421_intr_task(void* param) { + (void) param; + + while (1) { + xSemaphoreTake(max3421_intr_sem, portMAX_DELAY); + tuh_int_handler(BOARD_TUH_RHPORT, false); + } +} + +static void max3421_init(void) { + // CS pin + gpio_set_direction(MAX3421_CS_PIN, GPIO_MODE_OUTPUT); + gpio_set_level(MAX3421_CS_PIN, 1); + + // SPI + spi_bus_config_t buscfg = { + .miso_io_num = MAX3421_MISO_PIN, + .mosi_io_num = MAX3421_MOSI_PIN, + .sclk_io_num = MAX3421_SCK_PIN, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .data4_io_num = -1, + .data5_io_num = -1, + .data6_io_num = -1, + .data7_io_num = -1, + .max_transfer_sz = 1024 + }; + ESP_ERROR_CHECK(spi_bus_initialize(MAX3421_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); + + spi_device_interface_config_t max3421_cfg = { + .mode = 0, + .clock_speed_hz = 26000000, + .spics_io_num = -1, // manual control CS + .queue_size = 1 + }; + ESP_ERROR_CHECK(spi_bus_add_device(MAX3421_SPI_HOST, &max3421_cfg, &max3421_spi)); + + // debug + gpio_set_direction(13, GPIO_MODE_OUTPUT); + gpio_set_level(13, 0); + + // Interrupt pin + max3421_intr_sem = xSemaphoreCreateBinary(); + xTaskCreate(max3421_intr_task, "max3421 intr", 2048, NULL, configMAX_PRIORITIES - 2, NULL); + + gpio_set_direction(MAX3421_INTR_PIN, GPIO_MODE_INPUT); + gpio_set_intr_type(MAX3421_INTR_PIN, GPIO_INTR_NEGEDGE); + + gpio_install_isr_service(0); + gpio_isr_handler_add(MAX3421_INTR_PIN, max3421_isr_handler, NULL); +} + +void tuh_max3421_int_api(uint8_t rhport, bool enabled) { + (void) rhport; + if (enabled) { + gpio_intr_enable(MAX3421_INTR_PIN); + } else { + gpio_intr_disable(MAX3421_INTR_PIN); + } +} + +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { + (void) rhport; + gpio_set_level(MAX3421_CS_PIN, active ? 0 : 1); +} + +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { + (void) rhport; + + if (tx_buf == NULL) { + // fifo read, transmit rx_buf as dummy + tx_buf = rx_buf; + } + + // length in bits + size_t const len_bits = xfer_bytes << 3; + + spi_transaction_t xact = { + .length = len_bits, + .rxlength = rx_buf ? len_bits : 0, + .tx_buffer = tx_buf, + .rx_buffer = rx_buf + }; + + ESP_ERROR_CHECK(spi_device_transmit(max3421_spi, &xact)); + return true; +} + +#endif diff --git a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt index bf8e45be2..abe276910 100644 --- a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt +++ b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt @@ -16,40 +16,58 @@ else() return() endif() -list(APPEND compile_options - "-DCFG_TUSB_MCU=${tusb_mcu}" - "-DCFG_TUSB_OS=OPT_OS_FREERTOS" - #"-DCFG_TUSB_DEBUG=1" - ) +list(APPEND compile_definitions + CFG_TUSB_MCU=${tusb_mcu} + CFG_TUSB_OS=OPT_OS_FREERTOS + ) -idf_component_get_property(freertos_component_dir freertos COMPONENT_DIR) +list(APPEND srcs + # common + ${tusb_src}/tusb.c + ${tusb_src}/common/tusb_fifo.c + # device + ${tusb_src}/device/usbd.c + ${tusb_src}/device/usbd_control.c + ${tusb_src}/class/audio/audio_device.c + ${tusb_src}/class/cdc/cdc_device.c + ${tusb_src}/class/dfu/dfu_device.c + ${tusb_src}/class/dfu/dfu_rt_device.c + ${tusb_src}/class/hid/hid_device.c + ${tusb_src}/class/midi/midi_device.c + ${tusb_src}/class/msc/msc_device.c + ${tusb_src}/class/net/ecm_rndis_device.c + ${tusb_src}/class/net/ncm_device.c + ${tusb_src}/class/usbtmc/usbtmc_device.c + ${tusb_src}/class/vendor/vendor_device.c + ${tusb_src}/class/video/video_device.c + ${tusb_src}/portable/synopsys/dwc2/dcd_dwc2.c + # host + ${tusb_src}/host/usbh.c + ${tusb_src}/host/hub.c + ${tusb_src}/class/cdc/cdc_host.c + ${tusb_src}/class/hid/hid_host.c + ${tusb_src}/class/msc/msc_host.c + ${tusb_src}/class/vendor/vendor_host.c + ) -list(APPEND includes_public - "${tusb_src}" - # The FreeRTOS API include convention in tinyusb is different from esp-idf - #"${freertos_component_dir}/include/freertos" - ) +# use max3421 as host controller +if (MAX3421_HOST STREQUAL "1") + list(APPEND srcs ${tusb_src}/portable/analog/max3421/hcd_max3421.c) + list(APPEND compile_definitions CFG_TUH_MAX3421=1) +endif () -list(APPEND srcs - "${tusb_src}/tusb.c" - "${tusb_src}/common/tusb_fifo.c" - "${tusb_src}/device/usbd.c" - "${tusb_src}/device/usbd_control.c" - "${tusb_src}/class/cdc/cdc_device.c" - "${tusb_src}/class/dfu/dfu_rt_device.c" - "${tusb_src}/class/hid/hid_device.c" - "${tusb_src}/class/midi/midi_device.c" - "${tusb_src}/class/msc/msc_device.c" - "${tusb_src}/class/net/ecm_rndis_device.c" - "${tusb_src}/class/net/ncm_device.c" - "${tusb_src}/class/usbtmc/usbtmc_device.c" - "${tusb_src}/class/vendor/vendor_device.c" - "${tusb_src}/portable/synopsys/dwc2/dcd_dwc2.c" - ) +if (DEFINED LOG) + list(APPEND compile_definitions CFG_TUSB_DEBUG=${LOG}) + if (LOG STREQUAL "4") + # no inline for debug level 4 + list(APPEND compile_definitions TU_ATTR_ALWAYS_INLINE=) + endif () +endif() idf_component_register(SRCS ${srcs} - INCLUDE_DIRS ${includes_public} - REQUIRES src - ) + INCLUDE_DIRS ${tusb_src} + REQUIRES src + ) -target_compile_options(${COMPONENT_LIB} PUBLIC ${compile_options}) +target_compile_definitions(${COMPONENT_LIB} PUBLIC ${compile_definitions}) +target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 7c89427c0..9c625b58e 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -40,6 +40,7 @@ if (NOT FAMILY STREQUAL rp2040) # enable LTO if supported skip rp2040 include(CheckIPOSupported) check_ipo_supported(RESULT IPO_SUPPORTED) + cmake_print_variables(IPO_SUPPORTED) if (IPO_SUPPORTED) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) endif() @@ -216,6 +217,7 @@ function(family_configure_common TARGET RTOS) if (NOT TARGET segger_rtt) add_library(segger_rtt STATIC ${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c) target_include_directories(segger_rtt PUBLIC ${TOP}/lib/SEGGER_RTT/RTT) + target_compile_definitions(segger_rtt PUBLIC SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) endif() target_link_libraries(${TARGET} PUBLIC segger_rtt) endif () @@ -252,6 +254,15 @@ function(family_add_tinyusb TARGET OPT_MCU RTOS) # link tinyusb with freeRTOS kernel target_link_libraries(${TARGET}-tinyusb PUBLIC freertos_kernel) endif () + + # use max3421 as host controller + if (MAX3421_HOST STREQUAL "1") + target_compile_definitions(${TARGET}-tinyusb_config INTERFACE CFG_TUH_MAX3421=1) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/analog/max3421/hcd_max3421.c + ) + endif () + endfunction() @@ -437,5 +448,10 @@ if (NOT FAMILY_MCUS) set(FAMILY_MCUS ${FAMILY}) endif() +# if use max3421 as host controller, expand FAMILY_MCUS to include max3421 +if (MAX3421_HOST STREQUAL "1") + set(FAMILY_MCUS ${FAMILY_MCUS} MAX3421) +endif () + # save it in case of re-inclusion set(FAMILY_MCUS ${FAMILY_MCUS} CACHE INTERNAL "") diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index ec95a8b24..32d89f794 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -188,7 +188,7 @@ void USB_OTG1_IRQHandler(void) #endif #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } @@ -199,7 +199,7 @@ void USB_OTG2_IRQHandler(void) #endif #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); + tuh_int_handler(1, true); #endif } diff --git a/hw/bsp/kinetis_kl/family.c b/hw/bsp/kinetis_kl/family.c index 3e9aa83a4..c436be3e6 100644 --- a/hw/bsp/kinetis_kl/family.c +++ b/hw/bsp/kinetis_kl/family.c @@ -39,7 +39,7 @@ void USB0_IRQHandler(void) { #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED tud_int_handler(0); diff --git a/hw/bsp/kinetis_kl/family.cmake b/hw/bsp/kinetis_kl/family.cmake index 793ef1783..4151979a0 100644 --- a/hw/bsp/kinetis_kl/family.cmake +++ b/hw/bsp/kinetis_kl/family.cmake @@ -22,48 +22,47 @@ set(FAMILY_MCUS KINETIS_KL CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/drivers/gpio/fsl_gpio.c - ${SDK_DIR}/drivers/lpsci/fsl_lpsci.c - ${SDK_DIR}/drivers/uart/fsl_uart.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c - ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers - ${SDK_DIR}/drivers/common - ${SDK_DIR}/drivers/gpio - ${SDK_DIR}/drivers/lpsci - ${SDK_DIR}/drivers/port - ${SDK_DIR}/drivers/smc - ${SDK_DIR}/drivers/uart - ) + if (TARGET ${BOARD_TARGET}) + return() + endif () - update_board(${BOARD_TARGET}) + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/drivers/gpio/fsl_gpio.c + ${SDK_DIR}/drivers/lpsci/fsl_lpsci.c + ${SDK_DIR}/drivers/uart/fsl_uart.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMSIS_DIR}/CMSIS/Core/Include + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ${SDK_DIR}/drivers/common + ${SDK_DIR}/drivers/gpio + ${SDK_DIR}/drivers/lpsci + ${SDK_DIR}/drivers/port + ${SDK_DIR}/drivers/smc + ${SDK_DIR}/drivers/uart + ) + update_board(${BOARD_TARGET}) - # LD_FILE and STARTUP_FILE can be defined in board.cmake + # LD_FILE and STARTUP_FILE can be defined in board.cmake + target_sources(${BOARD_TARGET} PUBLIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) - target_sources(${BOARD_TARGET} PUBLIC - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + # nanolib + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - # nanolib - --specs=nosys.specs - --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() diff --git a/hw/bsp/lpc17/boards/lpcxpresso1769/lpcxpresso1769.c b/hw/bsp/lpc17/boards/lpcxpresso1769/lpcxpresso1769.c index c7d655368..8c26b906f 100644 --- a/hw/bsp/lpc17/boards/lpcxpresso1769/lpcxpresso1769.c +++ b/hw/bsp/lpc17/boards/lpcxpresso1769/lpcxpresso1769.c @@ -37,7 +37,7 @@ void USB_IRQHandler(void) #endif #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } diff --git a/hw/bsp/lpc17/boards/mbed1768/mbed1768.c b/hw/bsp/lpc17/boards/mbed1768/mbed1768.c index b2c92d640..613dcb570 100644 --- a/hw/bsp/lpc17/boards/mbed1768/mbed1768.c +++ b/hw/bsp/lpc17/boards/mbed1768/mbed1768.c @@ -151,7 +151,7 @@ void USB_IRQHandler(void) #endif #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } diff --git a/hw/bsp/lpc17/family.mk b/hw/bsp/lpc17/family.mk index abf6abe13..44b406d90 100644 --- a/hw/bsp/lpc17/family.mk +++ b/hw/bsp/lpc17/family.mk @@ -22,6 +22,8 @@ MCU_DIR = hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x SRC_C += \ src/portable/nxp/lpc17_40/dcd_lpc17_40.c \ + src/portable/ohci/ohci.c \ + src/portable/nxp/lpc17_40/hcd_lpc17_40.c \ $(MCU_DIR)/../gcc/cr_startup_lpc175x_6x.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ $(MCU_DIR)/src/clock_17xx_40xx.c \ @@ -29,7 +31,7 @@ SRC_C += \ $(MCU_DIR)/src/iocon_17xx_40xx.c \ $(MCU_DIR)/src/sysctl_17xx_40xx.c \ $(MCU_DIR)/src/sysinit_17xx_40xx.c \ - $(MCU_DIR)/src/uart_17xx_40xx.c + $(MCU_DIR)/src/uart_17xx_40xx.c \ INC += \ $(TOP)/$(MCU_DIR)/inc diff --git a/hw/bsp/lpc18/family.c b/hw/bsp/lpc18/family.c index b11f4fe0e..e6abecb4b 100644 --- a/hw/bsp/lpc18/family.c +++ b/hw/bsp/lpc18/family.c @@ -43,25 +43,23 @@ //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ +void USB0_IRQHandler(void) { #if PORT_SUPPORT_DEVICE(0) - tud_int_handler(0); + tud_int_handler(0); #endif #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } -void USB1_IRQHandler(void) -{ +void USB1_IRQHandler(void) { #if PORT_SUPPORT_DEVICE(1) - tud_int_handler(1); + tud_int_handler(1); #endif #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); + tuh_int_handler(1, true); #endif } @@ -74,28 +72,26 @@ const uint32_t OscRateIn = 12000000; const uint32_t ExtRateIn = 0; // Invoked by startup code -void SystemInit(void) -{ +void SystemInit(void) { #ifdef __USE_LPCOPEN - extern void (* const g_pfnVectors[])(void); + extern void (*const g_pfnVectors[])(void); unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08; - *pSCB_VTOR = (unsigned int) g_pfnVectors; + *pSCB_VTOR = (unsigned int) g_pfnVectors; #endif board_lpc18_pinmux(); - #ifdef TRACE_ETM +#ifdef TRACE_ETM // Trace clock is limited to 60MHz, limit CPU clock to 120MHz Chip_SetupCoreClock(CLKIN_CRYSTAL, 120000000UL, true); - #else +#else // CPU clock max to 180 Mhz Chip_SetupCoreClock(CLKIN_CRYSTAL, MAX_CLOCK_FREQ, true); - #endif +#endif } -void board_init(void) -{ +void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE @@ -135,27 +131,22 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ +void board_led_write(bool state) { Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED_PORT, LED_PIN, state); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { // active low return Chip_GPIO_GetPinState(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN) ? 0 : 1; } -int board_uart_read(uint8_t* buf, int len) -{ +int board_uart_read(uint8_t *buf, int len) { return Chip_UART_Read(UART_DEV, buf, len); } -int board_uart_write(void const * buf, int len) -{ - uint8_t const* buf8 = (uint8_t const*) buf; - for(int i=0; i<len; i++) - { +int board_uart_write(void const *buf, int len) { + uint8_t const *buf8 = (uint8_t const *) buf; + for (int i = 0; i < len; i++) { while ((Chip_UART_ReadLineStatus(UART_DEV) & UART_LSR_THRE) == 0) {} Chip_UART_SendByte(UART_DEV, buf8[i]); } @@ -165,13 +156,13 @@ int board_uart_write(void const * buf, int len) #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ + +void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif diff --git a/hw/bsp/lpc40/family.c b/hw/bsp/lpc40/family.c index 526e3a080..d6c8ef32a 100644 --- a/hw/bsp/lpc40/family.c +++ b/hw/bsp/lpc40/family.c @@ -37,7 +37,7 @@ void USB_IRQHandler(void) { #endif #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } diff --git a/hw/bsp/lpc43/family.c b/hw/bsp/lpc43/family.c index d52c1a071..8be729f7d 100644 --- a/hw/bsp/lpc43/family.c +++ b/hw/bsp/lpc43/family.c @@ -213,7 +213,7 @@ void USB0_IRQHandler(void) #endif #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } @@ -224,7 +224,7 @@ void USB1_IRQHandler(void) #endif #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); + tuh_int_handler(1, true); #endif } diff --git a/hw/bsp/lpc54/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/lpc54/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..fc0ab1f2d --- /dev/null +++ b/hw/bsp/lpc54/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,165 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "fsl_device_registers.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1) + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +#endif diff --git a/hw/bsp/lpc54/boards/lpcxpresso54114/board.cmake b/hw/bsp/lpc54/boards/lpcxpresso54114/board.cmake new file mode 100644 index 000000000..c0bbeecd5 --- /dev/null +++ b/hw/bsp/lpc54/boards/lpcxpresso54114/board.cmake @@ -0,0 +1,21 @@ +set(MCU_VARIANT LPC54114) +set(MCU_CORE LPC54114_cm4) + +set(JLINK_DEVICE LPC54114J256_M4) +set(PYOCD_TARGET LPC54114) + +set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/LPC54114J256_cm4_flash.ld) + +# Device port default to PORT1 Highspeed +if (NOT DEFINED PORT) + set(PORT 1) +endif() + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CPU_LPC54114J256BD64_cm4 + ) + target_link_libraries(${TARGET} PUBLIC + ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/libpower_cm4_hardabi.a + ) +endfunction() diff --git a/hw/bsp/lpc54/boards/lpcxpresso54608/board.cmake b/hw/bsp/lpc54/boards/lpcxpresso54608/board.cmake new file mode 100644 index 000000000..f0715fa12 --- /dev/null +++ b/hw/bsp/lpc54/boards/lpcxpresso54608/board.cmake @@ -0,0 +1,22 @@ +set(MCU_VARIANT LPC54608) +set(MCU_CORE LPC54608) + +set(JLINK_DEVICE LPC54608J512) +set(PYOCD_TARGET LPC54608) +set(NXPLINK_DEVICE LPC54608:LPCXpresso54608) + +set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/LPC54608J512_flash.ld) + +# Device port default to PORT1 Highspeed +if (NOT DEFINED PORT) + set(PORT 1) +endif() + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CPU_LPC54608J512ET180 + ) + target_link_libraries(${TARGET} PUBLIC + ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/libpower_hardabi.a + ) +endfunction() diff --git a/hw/bsp/lpc54/family.cmake b/hw/bsp/lpc54/family.cmake index b016441c1..cdd513fe4 100644 --- a/hw/bsp/lpc54/family.cmake +++ b/hw/bsp/lpc54/family.cmake @@ -28,83 +28,85 @@ set(HOST_PORT $<NOT:${PORT}>) #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - add_library(${BOARD_TARGET} STATIC - # driver - ${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c - ${SDK_DIR}/drivers/common/fsl_common_arm.c - ${SDK_DIR}/drivers/flexcomm/fsl_flexcomm.c - ${SDK_DIR}/drivers/flexcomm/fsl_usart.c - # mcu - ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c - ) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + add_library(${BOARD_TARGET} STATIC + # driver + ${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c + ${SDK_DIR}/drivers/common/fsl_common_arm.c + ${SDK_DIR}/drivers/flexcomm/fsl_flexcomm.c + ${SDK_DIR}/drivers/flexcomm/fsl_usart.c + # mcu + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) + BOARD_TUD_RHPORT=${PORT} + BOARD_TUH_RHPORT=${HOST_PORT} + ) + # Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM + if (PORT EQUAL 1) target_compile_definitions(${BOARD_TARGET} PUBLIC - CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) - BOARD_TUD_RHPORT=${PORT} - BOARD_TUH_RHPORT=${HOST_PORT} + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + BOARD_TUH_MAX_SPEED=OPT_MODE_FULL_SPEED + CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) ) - # Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM - if (PORT EQUAL 1) - target_compile_definitions(${BOARD_TARGET} PUBLIC - BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED - BOARD_TUH_MAX_SPEED=OPT_MODE_FULL_SPEED - CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) - ) - else () - target_compile_definitions(${BOARD_TARGET} PUBLIC - BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED - BOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED - CFG_TUH_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) - #CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) - ) - endif () - - target_include_directories(${BOARD_TARGET} PUBLIC - ${TOP}/lib/sct_neopixel - # driver - ${SDK_DIR}/drivers/common - ${SDK_DIR}/drivers/flexcomm - ${SDK_DIR}/drivers/lpc_iocon - ${SDK_DIR}/drivers/lpc_gpio - ${SDK_DIR}/drivers/lpuart - ${SDK_DIR}/drivers/sctimer - # mcu - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + else () + target_compile_definitions(${BOARD_TARGET} PUBLIC + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + BOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED + CFG_TUH_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) + #CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) ) + endif () + + target_include_directories(${BOARD_TARGET} PUBLIC + ${TOP}/lib/sct_neopixel + # driver + ${SDK_DIR}/drivers/common + ${SDK_DIR}/drivers/flexcomm + ${SDK_DIR}/drivers/lpc_iocon + ${SDK_DIR}/drivers/lpc_gpio + ${SDK_DIR}/drivers/lpuart + ${SDK_DIR}/drivers/sctimer + # mcu + ${CMSIS_DIR}/CMSIS/Core/Include + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ) - update_board(${BOARD_TARGET}) + update_board(${BOARD_TARGET}) - if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) - set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) - endif () + if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) + endif () - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) - endif () + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) + endif () - target_sources(${BOARD_TARGET} PUBLIC - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) + target_sources(${BOARD_TARGET} PUBLIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - # linker file - "LINKER:--script=${LD_FILE_GNU}" - # nanolib - --specs=nosys.specs - --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + # linker file + "LINKER:--script=${LD_FILE_GNU}" + # nanolib + --specs=nosys.specs + --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) endif () endfunction() @@ -124,8 +126,6 @@ function(family_configure_example TARGET RTOS) # BSP ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c - # external driver - ${TOP}/lib/sct_neopixel/sct_neopixel.c ) # https://github.com/gsteiert/sct_neopixel/pull/1 diff --git a/hw/bsp/msp432e4/family.c b/hw/bsp/msp432e4/family.c index 10f3ac736..d5ef7f930 100644 --- a/hw/bsp/msp432e4/family.c +++ b/hw/bsp/msp432e4/family.c @@ -34,7 +34,7 @@ void USB0_IRQHandler(void) { #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED tud_int_handler(0); diff --git a/hw/bsp/ngx4330/ngx4330.c b/hw/bsp/ngx4330/ngx4330.c index a767d5f29..bd84e449b 100644 --- a/hw/bsp/ngx4330/ngx4330.c +++ b/hw/bsp/ngx4330/ngx4330.c @@ -214,7 +214,7 @@ void USB0_IRQHandler(void) #endif #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } @@ -225,7 +225,7 @@ void USB1_IRQHandler(void) #endif #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); + tuh_int_handler(1, true); #endif } diff --git a/hw/bsp/nrf/boards/adafruit_clue/board.cmake b/hw/bsp/nrf/boards/adafruit_clue/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/adafruit_clue/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake b/hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake new file mode 100644 index 000000000..93647063a --- /dev/null +++ b/hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/arduino_nano33_ble.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/circuitplayground_bluefruit/board.cmake b/hw/bsp/nrf/boards/circuitplayground_bluefruit/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/circuitplayground_bluefruit/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake b/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake new file mode 100644 index 000000000..726438d05 --- /dev/null +++ b/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake @@ -0,0 +1,9 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) +#set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) + +# enable max3421 host driver for this board +set(MAX3421_HOST 1) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/feather_nrf52840_express/board.h b/hw/bsp/nrf/boards/feather_nrf52840_express/board.h index 8e6ce3230..3d59516d8 100644 --- a/hw/bsp/nrf/boards/feather_nrf52840_express/board.h +++ b/hw/bsp/nrf/boards/feather_nrf52840_express/board.h @@ -45,6 +45,13 @@ #define UART_RX_PIN 24 #define UART_TX_PIN 25 +// SPI for USB host shield +#define MAX3421_SCK_PIN 14 +#define MAX3421_MOSI_PIN 13 +#define MAX3421_MISO_PIN 15 +#define MAX3421_CS_PIN 27 // D10 +#define MAX3421_INTR_PIN 26 // D9 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/nrf/boards/feather_nrf52840_express/board.mk b/hw/bsp/nrf/boards/feather_nrf52840_express/board.mk index b80807963..488f07b82 100644 --- a/hw/bsp/nrf/boards/feather_nrf52840_express/board.mk +++ b/hw/bsp/nrf/boards/feather_nrf52840_express/board.mk @@ -1,6 +1,9 @@ MCU_VARIANT = nrf52840 CFLAGS += -DNRF52840_XXAA +# enable max3421 host driver for this board +MAX3421_HOST = 1 + # All source paths should be relative to the top level. LD_FILE = hw/bsp/nrf/linker/nrf52840_s140_v6.ld diff --git a/hw/bsp/nrf/boards/feather_nrf52840_sense/board.cmake b/hw/bsp/nrf/boards/feather_nrf52840_sense/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/feather_nrf52840_sense/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake b/hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake new file mode 100644 index 000000000..ffa5932c1 --- /dev/null +++ b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/nrf52840_mdk_dongle.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/pca10056/board.cmake b/hw/bsp/nrf/boards/pca10056/board.cmake index b4fe39fc0..693d7beed 100644 --- a/hw/bsp/nrf/boards/pca10056/board.cmake +++ b/hw/bsp/nrf/boards/pca10056/board.cmake @@ -2,7 +2,4 @@ set(MCU_VARIANT nrf52840) set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - NRF52840_XXAA - ) endfunction() diff --git a/hw/bsp/nrf/boards/pca10056/board.h b/hw/bsp/nrf/boards/pca10056/board.h index f4368f830..9459e7911 100644 --- a/hw/bsp/nrf/boards/pca10056/board.h +++ b/hw/bsp/nrf/boards/pca10056/board.h @@ -31,6 +31,8 @@ extern "C" { #endif +#define _PINNUM(port, pin) ((port)*32 + (pin)) + // LED #define LED_PIN 13 #define LED_STATE_ON 0 @@ -43,6 +45,13 @@ #define UART_RX_PIN 8 #define UART_TX_PIN 6 +// SPI for USB host shield +#define MAX3421_SCK_PIN _PINNUM(1, 15) +#define MAX3421_MOSI_PIN _PINNUM(1, 13) +#define MAX3421_MISO_PIN _PINNUM(1, 14) +#define MAX3421_CS_PIN _PINNUM(1, 12) +#define MAX3421_INTR_PIN _PINNUM(1, 11) + #ifdef __cplusplus } #endif diff --git a/hw/bsp/nrf/boards/pca10059/board.cmake b/hw/bsp/nrf/boards/pca10059/board.cmake new file mode 100644 index 000000000..c79eb5964 --- /dev/null +++ b/hw/bsp/nrf/boards/pca10059/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/pca10059.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/pca10095/board.cmake b/hw/bsp/nrf/boards/pca10095/board.cmake index 1e72243c9..ca5399a3a 100644 --- a/hw/bsp/nrf/boards/pca10095/board.cmake +++ b/hw/bsp/nrf/boards/pca10095/board.cmake @@ -2,10 +2,6 @@ set(MCU_VARIANT nrf5340_application) set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf5340_xxaa_application.ld) function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - NRF5340_XXAA - NRF5340_XXAA_APPLICATION - ) target_sources(${TARGET} PRIVATE ${NRFX_DIR}/drivers/src/nrfx_usbreg.c ) diff --git a/hw/bsp/nrf/boards/pca10095/board.h b/hw/bsp/nrf/boards/pca10095/board.h index fd3c63d6a..ad3379bf6 100644 --- a/hw/bsp/nrf/boards/pca10095/board.h +++ b/hw/bsp/nrf/boards/pca10095/board.h @@ -31,6 +31,8 @@ extern "C" { #endif +#define _PINNUM(port, pin) ((port)*32 + (pin)) + // LED #define LED_PIN 28 #define LED_STATE_ON 0 @@ -43,6 +45,13 @@ #define UART_RX_PIN 32 #define UART_TX_PIN 33 +// SPI for USB host shield +#define MAX3421_SCK_PIN _PINNUM(1, 15) +#define MAX3421_MOSI_PIN _PINNUM(1, 13) +#define MAX3421_MISO_PIN _PINNUM(1, 14) +#define MAX3421_CS_PIN _PINNUM(1, 12) +#define MAX3421_INTR_PIN _PINNUM(1, 11) + #ifdef __cplusplus } #endif diff --git a/hw/bsp/nrf/boards/pca10100/board.cmake b/hw/bsp/nrf/boards/pca10100/board.cmake new file mode 100644 index 000000000..c30026815 --- /dev/null +++ b/hw/bsp/nrf/boards/pca10100/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52833) +set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52833_xxaa.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake new file mode 100644 index 000000000..693d7beed --- /dev/null +++ b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 9ca666e36..c431389f3 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -34,12 +34,15 @@ #pragma GCC diagnostic ignored "-Wcast-align" #pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wundef" +#pragma GCC diagnostic ignored "-Wredundant-decls" #endif #include "nrfx.h" #include "hal/nrf_gpio.h" +#include "drivers/include/nrfx_gpiote.h" #include "drivers/include/nrfx_power.h" #include "drivers/include/nrfx_uarte.h" +#include "drivers/include/nrfx_spim.h" #ifdef SOFTDEVICE_PRESENT #include "nrf_sdm.h" @@ -54,8 +57,7 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USBD_IRQHandler(void) -{ +void USBD_IRQHandler(void) { tud_int_handler(0); } @@ -86,15 +88,25 @@ static nrfx_uarte_t _uart_id = NRFX_UARTE_INSTANCE(0); // We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. extern void tusb_hal_nrf_power_event(uint32_t event); - // nrf power callback, could be unused if SD is enabled or usb is disabled (board_test example) -TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) -{ +TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) { tusb_hal_nrf_power_event((uint32_t) event); } -void board_init(void) -{ +//------------- Host using MAX2341E -------------// +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +static void max3421_init(void); + +static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(1); +#endif + + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +void board_init(void) { // stop LF clock just in case we jump from application without reset NRF_CLOCK->TASKS_LFCLKSTOP = 1UL; @@ -110,22 +122,21 @@ void board_init(void) nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP); // 1ms tick timer - SysTick_Config(SystemCoreClock/1000); + SysTick_Config(SystemCoreClock / 1000); // UART - nrfx_uarte_config_t uart_cfg = - { - .pseltxd = UART_TX_PIN, - .pselrxd = UART_RX_PIN, - .pselcts = NRF_UARTE_PSEL_DISCONNECTED, - .pselrts = NRF_UARTE_PSEL_DISCONNECTED, - .p_context = NULL, - .baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE - .interrupt_priority = 7, - .hal_cfg = { - .hwfc = NRF_UARTE_HWFC_DISABLED, - .parity = NRF_UARTE_PARITY_EXCLUDED, - } + nrfx_uarte_config_t uart_cfg = { + .pseltxd = UART_TX_PIN, + .pselrxd = UART_RX_PIN, + .pselcts = NRF_UARTE_PSEL_DISCONNECTED, + .pselrts = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = NULL, + .baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE + .interrupt_priority = 7, + .hal_cfg = { + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED, + } }; nrfx_uarte_init(&_uart_id, &uart_cfg, NULL); //uart_handler); @@ -165,61 +176,62 @@ void board_init(void) // USB power may already be ready at this time -> no event generated // We need to invoke the handler based on the status initially - #ifdef NRF5340_XXAA +#ifdef NRF5340_XXAA usb_reg = NRF_USBREGULATOR->USBREGSTATUS; - #else +#else usb_reg = NRF_POWER->USBREGSTATUS; - #endif +#endif } if ( usb_reg & VBUSDETECT_Msk ) tusb_hal_nrf_power_event(USB_EVT_DETECTED); if ( usb_reg & OUTPUTRDY_Msk ) tusb_hal_nrf_power_event(USB_EVT_READY); #endif + +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + max3421_init(); +#endif + } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - nrf_gpio_pin_write(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + nrf_gpio_pin_write(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == nrf_gpio_pin_read(BUTTON_PIN); } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; return 0; // return NRFX_SUCCESS == nrfx_uart_rx(&_uart_id, buf, (size_t) len) ? len : 0; } -int board_uart_write(void const * buf, int len) -{ +int board_uart_write(void const* buf, int len) { return (NRFX_SUCCESS == nrfx_uarte_tx(&_uart_id, (uint8_t const*) buf, (size_t) len)) ? len : 0; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ + +void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif #ifdef SOFTDEVICE_PRESENT // process SOC event from SD -uint32_t proc_soc(void) -{ +uint32_t proc_soc(void) { uint32_t soc_evt; uint32_t err = sd_evt_get(&soc_evt); @@ -236,25 +248,115 @@ uint32_t proc_soc(void) return err; } -uint32_t proc_ble(void) -{ +uint32_t proc_ble(void) { // do nothing with ble return NRF_ERROR_NOT_FOUND; } -void SD_EVT_IRQHandler(void) -{ +void SD_EVT_IRQHandler(void) { // process BLE and SOC until there is no more events - while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) ) - { - + while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) ) { } } -void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info) -{ +void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info) { (void) id; (void) pc; (void) info; } #endif + +//--------------------------------------------------------------------+ +// API: SPI transfer with MAX3421E, must be implemented by application +//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +void max3421_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { + if (!(pin == MAX3421_INTR_PIN && action == NRF_GPIOTE_POLARITY_HITOLO)) return; + tuh_int_handler(1, true); +} + +static void max3421_init(void) { + // MAX3421 need 3.3v signal (may not be needed) +// #if defined(UICR_REGOUT0_VOUT_Msk) +// if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != UICR_REGOUT0_VOUT_3V3) { +// NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; +// while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} +// +// NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~UICR_REGOUT0_VOUT_Msk) | UICR_REGOUT0_VOUT_3V3; +// +// NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; +// while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} +// +// NVIC_SystemReset(); +// } +// #endif + + // manually manage CS + nrf_gpio_cfg_output(MAX3421_CS_PIN); + nrf_gpio_pin_write(MAX3421_CS_PIN, 1); + + // USB host using max3421e usb controller via SPI + nrfx_spim_config_t cfg = { + .sck_pin = MAX3421_SCK_PIN, + .mosi_pin = MAX3421_MOSI_PIN, + .miso_pin = MAX3421_MISO_PIN, + .ss_pin = NRFX_SPIM_PIN_NOT_USED, + .ss_active_high = false, + .irq_priority = 3, + .orc = 0xFF, + // default setting 4 Mhz, Mode 0, MSB first + .frequency = NRF_SPIM_FREQ_4M, + .mode = NRF_SPIM_MODE_0, + .bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST, + }; + + // no handler --> blocking + nrfx_spim_init(&_spi, &cfg, NULL, NULL); + + // max3421e interrupt pin + nrfx_gpiote_init(1); + nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true); + in_config.pull = NRF_GPIO_PIN_PULLUP; + + NVIC_SetPriority(GPIOTE_IRQn, 2); + + nrfx_gpiote_in_init(MAX3421_INTR_PIN, &in_config, max3421_int_handler); + nrfx_gpiote_trigger_enable(MAX3421_INTR_PIN, true); +} + +// API to enable/disable MAX3421 INTR pin interrupt +void tuh_max3421_int_api(uint8_t rhport, bool enabled) { + (void) rhport; + + // use NVIC_Enable/Disable instead since nrfx_gpiote_trigger_enable/disable clear pending and can miss interrupt + // when disabled and re-enabled. + if (enabled) { + NVIC_EnableIRQ(GPIOTE_IRQn); + } else { + NVIC_DisableIRQ(GPIOTE_IRQn); + } +} + +// API to control MAX3421 SPI CS +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { + (void) rhport; + nrf_gpio_pin_write(MAX3421_CS_PIN, active ? 0 : 1); +} + +// API to transfer data with MAX3421 SPI +// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { + (void) rhport; + + nrfx_spim_xfer_desc_t xfer = { + .p_tx_buffer = tx_buf, + .tx_length = tx_buf ? xfer_bytes : 0, + .p_rx_buffer = rx_buf, + .rx_length = rx_buf ? xfer_bytes : 0, + }; + + return nrfx_spim_xfer(&_spi, &xfer, 0) == NRFX_SUCCESS; +} + +#endif diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 2b13249f4..99d9ac6dd 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -32,14 +32,23 @@ function(add_board_target BOARD_TARGET) if (NOT TARGET ${BOARD_TARGET}) add_library(${BOARD_TARGET} STATIC # driver + ${NRFX_DIR}/helpers/nrfx_flag32_allocator.c + ${NRFX_DIR}/drivers/src/nrfx_gpiote.c ${NRFX_DIR}/drivers/src/nrfx_power.c + ${NRFX_DIR}/drivers/src/nrfx_spim.c ${NRFX_DIR}/drivers/src/nrfx_uarte.c # mcu ${NRFX_DIR}/mdk/system_${MCU_VARIANT}.c ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - CONFIG_GPIO_AS_PINRESET - ) + target_compile_definitions(${BOARD_TARGET} PUBLIC CONFIG_GPIO_AS_PINRESET) + + if (MCU_VARIANT STREQUAL "nrf52840") + target_compile_definitions(${BOARD_TARGET} PUBLIC NRF52840_XXAA) + elseif (MCU_VARIANT STREQUAL "nrf52833") + target_compile_definitions(${BOARD_TARGET} PUBLIC NRF52833_XXAA) + elseif (MCU_VARIANT STREQUAL "nrf5340_application") + target_compile_definitions(${BOARD_TARGET} PUBLIC NRF5340_XXAA NRF5340_XXAA_APPLICATION) + endif () if (TRACE_ETM STREQUAL "1") # ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace diff --git a/hw/bsp/nrf/family.mk b/hw/bsp/nrf/family.mk index cdcfe39bd..4b53b9a4f 100644 --- a/hw/bsp/nrf/family.mk +++ b/hw/bsp/nrf/family.mk @@ -1,5 +1,6 @@ UF2_FAMILY_ID = 0xADA52840 -DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/nordic/nrfx + +NRFX_DIR = hw/mcu/nordic/nrfx include $(TOP)/$(BOARD_PATH)/board.mk @@ -14,24 +15,27 @@ CFLAGS += \ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=undef -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=cast-qual -Wno-error=redundant-decls -LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk +LDFLAGS += -L$(TOP)/${NRFX_DIR}/mdk SRC_C += \ src/portable/nordic/nrf5x/dcd_nrf5x.c \ - hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \ - hw/mcu/nordic/nrfx/drivers/src/nrfx_uarte.c \ - hw/mcu/nordic/nrfx/mdk/system_$(MCU_VARIANT).c + ${NRFX_DIR}/helpers/nrfx_flag32_allocator.c \ + ${NRFX_DIR}/drivers/src/nrfx_gpiote.c \ + ${NRFX_DIR}/drivers/src/nrfx_power.c \ + ${NRFX_DIR}/drivers/src/nrfx_spim.c \ + ${NRFX_DIR}/drivers/src/nrfx_uarte.c \ + ${NRFX_DIR}/mdk/system_$(MCU_VARIANT).c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - $(TOP)/hw/mcu/nordic/nrfx \ - $(TOP)/hw/mcu/nordic/nrfx/mdk \ - $(TOP)/hw/mcu/nordic/nrfx/hal \ - $(TOP)/hw/mcu/nordic/nrfx/drivers/include \ - $(TOP)/hw/mcu/nordic/nrfx/drivers/src \ + $(TOP)/${NRFX_DIR} \ + $(TOP)/${NRFX_DIR}/mdk \ + $(TOP)/${NRFX_DIR}/hal \ + $(TOP)/${NRFX_DIR}/drivers/include \ + $(TOP)/${NRFX_DIR}/drivers/src \ -SRC_S += hw/mcu/nordic/nrfx/mdk/gcc_startup_$(MCU_VARIANT).S +SRC_S += ${NRFX_DIR}/mdk/gcc_startup_$(MCU_VARIANT).S ASFLAGS += -D__HEAP_SIZE=0 diff --git a/hw/bsp/nrf/nrfx_config.h b/hw/bsp/nrf/nrfx_config.h index 696a3fb04..95ef33ce4 100644 --- a/hw/bsp/nrf/nrfx_config.h +++ b/hw/bsp/nrf/nrfx_config.h @@ -5,13 +5,13 @@ #define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY 7 #define NRFX_CLOCK_ENABLED 0 +#define NRFX_GPIOTE_ENABLED 1 #define NRFX_UARTE_ENABLED 1 #define NRFX_UARTE0_ENABLED 1 -#define NRFX_UARTE1_ENABLED 0 -#define NRFX_UARTE2_ENABLED 0 -#define NRFX_UARTE3_ENABLED 0 +#define NRFX_SPIM_ENABLED 1 +#define NRFX_SPIM1_ENABLED 1 // use SPI1 since nrf5340 share uart with spi #define NRFX_PRS_ENABLED 0 #define NRFX_USBREG_ENABLED 1 @@ -42,5 +42,4 @@ #error "Unknown device." #endif - #endif // NRFX_CONFIG_H__ diff --git a/hw/bsp/nrf/nrfx_glue.h b/hw/bsp/nrf/nrfx_glue.h index cdf49b4ab..ef756c670 100644 --- a/hw/bsp/nrf/nrfx_glue.h +++ b/hw/bsp/nrf/nrfx_glue.h @@ -220,6 +220,75 @@ static inline bool _NRFX_IRQ_IS_PENDING(IRQn_Type irq_number) /** @} */ +//------------------------------------------------------------------------------ + +#include <soc/nrfx_atomic.h> + +/** + * @brief Atomic 32 bit unsigned type. + */ +#define nrfx_atomic_t nrfx_atomic_u32_t + +/** + * @brief Stores value to an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value to store. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_STORE(p_data, value) nrfx_atomic_u32_fetch_store(p_data, value) + +/** + * @brief Performs logical OR operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of OR operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_OR(p_data, value) nrfx_atomic_u32_fetch_or(p_data, value) + +/** + * @brief Performs logical AND operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of AND operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_AND(p_data, value) nrfx_atomic_u32_fetch_and(p_data, value) + +/** + * @brief Performs logical XOR operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of XOR operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_XOR(p_data, value) nrfx_atomic_u32_fetch_xor(p_data, value) + +/** + * @brief Performs logical ADD operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of ADD operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_ADD(p_data, value) nrfx_atomic_u32_fetch_add(p_data, value) + +/** + * @brief Performs logical SUB operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of SUB operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_SUB(p_data, value) nrfx_atomic_u32_fetch_sub(p_data, value) + #ifdef __cplusplus } #endif diff --git a/hw/bsp/ra/family.c b/hw/bsp/ra/family.c index 0aa58d86d..fdf4c8666 100644 --- a/hw/bsp/ra/family.c +++ b/hw/bsp/ra/family.c @@ -188,7 +188,7 @@ void usbfs_interrupt_handler(void) { R_BSP_IrqStatusClear(irq); #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if PORT_SUPPORT_DEVICE(0) @@ -201,7 +201,7 @@ void usbfs_resume_handler(void) { R_BSP_IrqStatusClear(irq); #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if PORT_SUPPORT_DEVICE(0) @@ -229,7 +229,7 @@ void usbhs_interrupt_handler(void) { R_BSP_IrqStatusClear(irq); #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); + tuh_int_handler(1, true); #endif #if PORT_SUPPORT_DEVICE(1) diff --git a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c index 513eca678..032dac810 100644 --- a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c +++ b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c @@ -177,7 +177,7 @@ void INT_Excep_SCI5_RXI5(void) void INT_Excep_USB0_USBI0(void) { #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED tud_int_handler(0); diff --git a/hw/bsp/samd21/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/samd21/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..02e868741 --- /dev/null +++ b/hw/bsp/samd21/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,165 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "sam.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1) + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +#endif diff --git a/hw/bsp/samd21/boards/atsamd21_xpro/board.cmake b/hw/bsp/samd21/boards/atsamd21_xpro/board.cmake new file mode 100644 index 000000000..46a3880ed --- /dev/null +++ b/hw/bsp/samd21/boards/atsamd21_xpro/board.cmake @@ -0,0 +1,9 @@ +set(JLINK_DEVICE ATSAMD21J18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/samd21j18a_flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21J18A__ + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/samd21/boards/circuitplayground_express/board.cmake b/hw/bsp/samd21/boards/circuitplayground_express/board.cmake new file mode 100644 index 000000000..c1a612936 --- /dev/null +++ b/hw/bsp/samd21/boards/circuitplayground_express/board.cmake @@ -0,0 +1,9 @@ +set(JLINK_DEVICE ATSAMD21G18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21G18A__ + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/samd21/boards/curiosity_nano/board.cmake b/hw/bsp/samd21/boards/curiosity_nano/board.cmake new file mode 100644 index 000000000..ff779c0fd --- /dev/null +++ b/hw/bsp/samd21/boards/curiosity_nano/board.cmake @@ -0,0 +1,10 @@ +set(JLINK_DEVICE atsamd21g17a) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/samd21g17a_flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21G17A__ + CFG_EXAMPLE_MSC_READONLY + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/samd21/boards/cynthion_d21/board.cmake b/hw/bsp/samd21/boards/cynthion_d21/board.cmake new file mode 100644 index 000000000..fb54b7561 --- /dev/null +++ b/hw/bsp/samd21/boards/cynthion_d21/board.cmake @@ -0,0 +1,12 @@ +set(JLINK_DEVICE ATSAMD21G18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/samd21g18a_flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21G18A__ + CFG_EXAMPLE_VIDEO_READONLY + ) + target_link_options(${TARGET} PUBLIC + "LINKER:--defsym=BOOTLOADER_SIZE=0x800" + ) +endfunction() diff --git a/hw/bsp/samd21/boards/feather_m0_express/board.cmake b/hw/bsp/samd21/boards/feather_m0_express/board.cmake new file mode 100644 index 000000000..c1a612936 --- /dev/null +++ b/hw/bsp/samd21/boards/feather_m0_express/board.cmake @@ -0,0 +1,9 @@ +set(JLINK_DEVICE ATSAMD21G18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21G18A__ + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/samd21/boards/itsybitsy_m0/board.cmake b/hw/bsp/samd21/boards/itsybitsy_m0/board.cmake new file mode 100644 index 000000000..c1a612936 --- /dev/null +++ b/hw/bsp/samd21/boards/itsybitsy_m0/board.cmake @@ -0,0 +1,9 @@ +set(JLINK_DEVICE ATSAMD21G18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21G18A__ + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/samd21/boards/metro_m0_express/board.cmake b/hw/bsp/samd21/boards/metro_m0_express/board.cmake new file mode 100644 index 000000000..c1a612936 --- /dev/null +++ b/hw/bsp/samd21/boards/metro_m0_express/board.cmake @@ -0,0 +1,9 @@ +set(JLINK_DEVICE ATSAMD21G18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21G18A__ + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/samd21/boards/metro_m0_express/board.h b/hw/bsp/samd21/boards/metro_m0_express/board.h index d26aae53c..6dd53e901 100644 --- a/hw/bsp/samd21/boards/metro_m0_express/board.h +++ b/hw/bsp/samd21/boards/metro_m0_express/board.h @@ -43,6 +43,22 @@ #define UART_RX_PIN 4 #define UART_TX_PIN 5 +// SPI for USB host shield +#define MAX3421_SERCOM_ID 4 // SERCOM4 +#define MAX3421_SERCOM_FUNCTION 3 // function D (Sercom Alt) + +#define MAX3421_SCK_PIN (32+11) +#define MAX3421_MOSI_PIN (32+10) +#define MAX3421_MISO_PIN 12 +#define MAX3421_TX_PAD 1 // MOSI = PAD_2, SCK = PAD_3 +#define MAX3421_RX_PAD 0 // MISO = PAD_2 + +#define MAX3421_CS_PIN 18 // D10 + +#define MAX3421_INTR_PIN 7 // D9 +#define MAX3421_INTR_EIC_ID 7 // EIC7 + + #ifdef __cplusplus } #endif diff --git a/hw/bsp/samd21/boards/qtpy/board.cmake b/hw/bsp/samd21/boards/qtpy/board.cmake new file mode 100644 index 000000000..f6cd446dd --- /dev/null +++ b/hw/bsp/samd21/boards/qtpy/board.cmake @@ -0,0 +1,9 @@ +set(JLINK_DEVICE ATSAMD21E18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21E18A__ + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/samd21/boards/seeeduino_xiao/board.cmake b/hw/bsp/samd21/boards/seeeduino_xiao/board.cmake new file mode 100644 index 000000000..c1a612936 --- /dev/null +++ b/hw/bsp/samd21/boards/seeeduino_xiao/board.cmake @@ -0,0 +1,9 @@ +set(JLINK_DEVICE ATSAMD21G18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21G18A__ + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/samd21/boards/trinket_m0/board.cmake b/hw/bsp/samd21/boards/trinket_m0/board.cmake new file mode 100644 index 000000000..f6cd446dd --- /dev/null +++ b/hw/bsp/samd21/boards/trinket_m0/board.cmake @@ -0,0 +1,9 @@ +set(JLINK_DEVICE ATSAMD21E18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21E18A__ + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/samd21/family.c b/hw/bsp/samd21/family.c index 46297f97f..ccb2c99b1 100644 --- a/hw/bsp/samd21/family.c +++ b/hw/bsp/samd21/family.c @@ -28,6 +28,12 @@ #include "bsp/board_api.h" #include "board.h" +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + #include "hal/include/hal_gpio.h" #include "hal/include/hal_init.h" #include "hri/hri_nvmctrl_d21.h" @@ -36,31 +42,40 @@ #include "hpl_pm_config.h" #include "hpl/pm/hpl_pm_base.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +/* Referenced GCLKs, should be initialized firstly */ +#define _GCLK_INIT_1ST (1 << 0 | 1 << 1) + +/* Not referenced GCLKs, initialized last */ +#define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB_Handler(void) -{ +void USB_Handler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ -// UART support +// Implementation //--------------------------------------------------------------------+ static void uart_init(void); -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 +#define MAX3421_SERCOM TU_XSTRCAT(SERCOM, MAX3421_SERCOM_ID) -/* Referenced GCLKs, should be initialized firstly */ -#define _GCLK_INIT_1ST (1 << 0 | 1 << 1) +static void max3421_init(void); -/* Not referenced GCLKs, initialized last */ -#define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) +#endif -void board_init(void) -{ +void board_init(void) { // Clock init ( follow hpl_init.c ) hri_nvmctrl_set_CTRLB_RWS_bf(NVMCTRL, 2); @@ -75,7 +90,7 @@ void board_init(void) // Update SystemCoreClock since it is hard coded with asf4 and not correct // Init 1ms tick timer (samd SystemCoreClock may not correct) SystemCoreClock = CONF_CPU_FREQUENCY; -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(CONF_CPU_FREQUENCY / 1000); #endif @@ -93,7 +108,7 @@ void board_init(void) uart_init(); -#if CFG_TUSB_OS == OPT_OS_FREERTOS +#if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif @@ -124,22 +139,24 @@ void board_init(void) gpio_set_pin_function(PIN_PA19, PINMUX_PA19F_TCC0_WO3); _gclk_enable_channel(TCC0_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); + +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + max3421_init(); +#endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - (void)state; +void board_led_write(bool state) { + (void) state; #ifdef LED_PIN - gpio_set_pin_level(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); + gpio_set_pin_level(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); #endif } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { #ifdef BUTTON_PIN return BUTTON_STATE_ACTIVE == gpio_get_pin_level(BUTTON_PIN); #else @@ -217,33 +234,191 @@ int board_uart_write(void const * buf, int len) } #else // ! defined(UART_SERCOM) -static void uart_init(void) -{ +static void uart_init(void) { } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; return 0; } -int board_uart_write(void const * buf, int len) -{ - (void) buf; (void) len; +int board_uart_write(void const* buf, int len) { + (void) buf; + (void) len; return 0; } + #endif -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ + +void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + +#endif + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +static void max3421_init(void) { + //------------- SPI Init -------------// + // MAX3421E max SPI clock is 26MHz however SAMD can only work reliably at 12 Mhz + uint32_t const baudrate = 12000000u; + + // Enable the APB clock for SERCOM + PM->APBCMASK.reg |= 1u << (PM_APBCMASK_SERCOM0_Pos + MAX3421_SERCOM_ID); + + // Configure GCLK for SERCOM +// GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_SERCOM4_CORE | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(GCLK_CLKCTRL_ID_SERCOM0_CORE_Val + MAX3421_SERCOM_ID) | + GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN; + while (GCLK->STATUS.bit.SYNCBUSY); + + Sercom* sercom = MAX3421_SERCOM; + + // Disable the SPI module + sercom->SPI.CTRLA.bit.ENABLE = 0; + + // Reset the SPI module + sercom->SPI.CTRLA.bit.SWRST = 1; + while (sercom->SPI.SYNCBUSY.bit.SWRST); + + // Set up SPI in master mode, MSB first, SPI mode 0 + sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(MAX3421_TX_PAD) | SERCOM_SPI_CTRLA_DIPO(MAX3421_RX_PAD) | + SERCOM_SPI_CTRLA_MODE(3); + + sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN; + while (sercom->SPI.SYNCBUSY.bit.CTRLB == 1); + + // Set the baud rate + sercom->SPI.BAUD.reg = (uint8_t) (SystemCoreClock / (2 * baudrate) - 1); + + // Configure PA12 as MOSI (PAD0), PA13 as SCK (PAD1), PA14 as MISO (PAD2), function C (sercom) + gpio_set_pin_direction(MAX3421_SCK_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(MAX3421_SCK_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_SCK_PIN, MAX3421_SERCOM_FUNCTION); + + gpio_set_pin_direction(MAX3421_MOSI_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(MAX3421_MOSI_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_MOSI_PIN, MAX3421_SERCOM_FUNCTION); + + gpio_set_pin_direction(MAX3421_MISO_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(MAX3421_MISO_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_MISO_PIN, MAX3421_SERCOM_FUNCTION); + + // CS pin + gpio_set_pin_direction(MAX3421_CS_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_level(MAX3421_CS_PIN, 1); + + // Enable the SPI module + sercom->SPI.CTRLA.bit.ENABLE = 1; + while (sercom->SPI.SYNCBUSY.bit.ENABLE); + + //------------- External Interrupt -------------// + + // Enable the APB clock for EIC (External Interrupt Controller) + PM->APBAMASK.reg |= PM_APBAMASK_EIC; + + // Configure GCLK for EIC + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_EIC | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN; + while (GCLK->STATUS.bit.SYNCBUSY); + + // Configure PA20 as an input with function A (external interrupt) + gpio_set_pin_direction(MAX3421_INTR_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(MAX3421_INTR_PIN, GPIO_PULL_UP); + gpio_set_pin_function(MAX3421_INTR_PIN, 0); + + // Disable EIC + EIC->CTRL.bit.ENABLE = 0; + while (EIC->STATUS.bit.SYNCBUSY); + + // Configure EIC to trigger on falling edge + uint8_t const sense_shift = MAX3421_INTR_EIC_ID * 4; + EIC->CONFIG[0].reg &= ~(7 << sense_shift); + EIC->CONFIG[0].reg |= 2 << sense_shift; + +#if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(EIC_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + // Enable External Interrupt + EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID); + + // Enable EIC + EIC->CTRL.bit.ENABLE = 1; + while (EIC->STATUS.bit.SYNCBUSY); +} + +void EIC_Handler(void) { + // Clear the interrupt flag + EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID); + + // Call the TinyUSB interrupt handler + tuh_int_handler(1, true); +} + +// API to enable/disable MAX3421 INTR pin interrupt +void tuh_max3421_int_api(uint8_t rhport, bool enabled) { + (void) rhport; + + if (enabled) { + NVIC_EnableIRQ(EIC_IRQn); + } else { + NVIC_DisableIRQ(EIC_IRQn); + } +} + +// API to control MAX3421 SPI CS +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { + (void) rhport; + gpio_set_pin_level(MAX3421_CS_PIN, active ? 0 : 1); +} + +// API to transfer data with MAX3421 SPI +// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { + (void) rhport; + + Sercom* sercom = MAX3421_SERCOM; + + for (size_t count = 0; count < xfer_bytes; count++) { + // Wait for the transmit buffer to be empty + while (!sercom->SPI.INTFLAG.bit.DRE); + + // Write data to be transmitted + uint8_t data = 0x00; + if (tx_buf) { + data = tx_buf[count]; + } + + sercom->SPI.DATA.reg = (uint32_t) data; + + // Wait for the receive buffer to be filled + while (!sercom->SPI.INTFLAG.bit.RXC); + + // Read received data + data = (uint8_t) sercom->SPI.DATA.reg; + if (rx_buf) { + rx_buf[count] = data; + } + } + + // wait for bus idle and clear flags + while (!(sercom->SPI.INTFLAG.reg & (SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE))); + sercom->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE; + + return true; +} + #endif diff --git a/hw/bsp/samd21/family.cmake b/hw/bsp/samd21/family.cmake new file mode 100644 index 000000000..07186934a --- /dev/null +++ b/hw/bsp/samd21/family.cmake @@ -0,0 +1,105 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/microchip/samd21) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS SAMD21 CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (NOT TARGET ${BOARD_TARGET}) + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/gcc/system_samd21.c + ${SDK_DIR}/hpl/gclk/hpl_gclk.c + ${SDK_DIR}/hpl/pm/hpl_pm.c + ${SDK_DIR}/hpl/sysctrl/hpl_sysctrl.c + ${SDK_DIR}/hal/src/hal_atomic.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR} + ${SDK_DIR}/config + ${SDK_DIR}/include + ${SDK_DIR}/hal/include + ${SDK_DIR}/hal/utils/include + ${SDK_DIR}/hpl/pm + ${SDK_DIR}/hpl/port + ${SDK_DIR}/hri + ${SDK_DIR}/CMSIS/Include + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC CONF_DFLL_OVERWRITE_CALIBRATION=0) + + update_board(${BOARD_TARGET}) + + if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") + endif () + + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd21.c) + endif () + + target_sources(${BOARD_TARGET} PRIVATE + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_SAMD21 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/microchip/samd/dcd_samd.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/samd21/family.mk b/hw/bsp/samd21/family.mk index 49a1a781a..79c63812d 100644 --- a/hw/bsp/samd21/family.mk +++ b/hw/bsp/samd21/family.mk @@ -1,5 +1,5 @@ UF2_FAMILY_ID = 0x68ed2b88 -DEPS_SUBMODULES += hw/mcu/microchip +SDK_DIR = hw/mcu/microchip/samd21 include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus @@ -18,24 +18,24 @@ CFLAGS_SKIP += -Wcast-qual SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ - hw/mcu/microchip/samd21/gcc/gcc/startup_samd21.c \ - hw/mcu/microchip/samd21/gcc/system_samd21.c \ - hw/mcu/microchip/samd21/hpl/gclk/hpl_gclk.c \ - hw/mcu/microchip/samd21/hpl/pm/hpl_pm.c \ - hw/mcu/microchip/samd21/hpl/sysctrl/hpl_sysctrl.c \ - hw/mcu/microchip/samd21/hal/src/hal_atomic.c + ${SDK_DIR}/gcc/gcc/startup_samd21.c \ + ${SDK_DIR}/gcc/system_samd21.c \ + ${SDK_DIR}/hpl/gclk/hpl_gclk.c \ + ${SDK_DIR}/hpl/pm/hpl_pm.c \ + ${SDK_DIR}/hpl/sysctrl/hpl_sysctrl.c \ + ${SDK_DIR}/hal/src/hal_atomic.c INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/hw/mcu/microchip/samd21/ \ - $(TOP)/hw/mcu/microchip/samd21/config \ - $(TOP)/hw/mcu/microchip/samd21/include \ - $(TOP)/hw/mcu/microchip/samd21/hal/include \ - $(TOP)/hw/mcu/microchip/samd21/hal/utils/include \ - $(TOP)/hw/mcu/microchip/samd21/hpl/pm/ \ - $(TOP)/hw/mcu/microchip/samd21/hpl/port \ - $(TOP)/hw/mcu/microchip/samd21/hri \ - $(TOP)/hw/mcu/microchip/samd21/CMSIS/Include + $(TOP)/${SDK_DIR}/ \ + $(TOP)/${SDK_DIR}/config \ + $(TOP)/${SDK_DIR}/include \ + $(TOP)/${SDK_DIR}/hal/include \ + $(TOP)/${SDK_DIR}/hal/utils/include \ + $(TOP)/${SDK_DIR}/hpl/pm/ \ + $(TOP)/${SDK_DIR}/hpl/port \ + $(TOP)/${SDK_DIR}/hri \ + $(TOP)/${SDK_DIR}/CMSIS/Include # flash using bossac at least version 1.8 # can be found in arduino15/packages/arduino/tools/bossac/ diff --git a/hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..32db4ad95 --- /dev/null +++ b/hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,165 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "sam.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*6*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1) + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +#endif diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.cmake b/hw/bsp/samd51/boards/feather_m4_express/board.cmake new file mode 100644 index 000000000..d83211d9e --- /dev/null +++ b/hw/bsp/samd51/boards/feather_m4_express/board.cmake @@ -0,0 +1,8 @@ +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/board.cmake b/hw/bsp/samd51/boards/itsybitsy_m4/board.cmake new file mode 100644 index 000000000..d83211d9e --- /dev/null +++ b/hw/bsp/samd51/boards/itsybitsy_m4/board.cmake @@ -0,0 +1,8 @@ +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.cmake b/hw/bsp/samd51/boards/metro_m4_express/board.cmake new file mode 100644 index 000000000..d83211d9e --- /dev/null +++ b/hw/bsp/samd51/boards/metro_m4_express/board.cmake @@ -0,0 +1,8 @@ +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.h b/hw/bsp/samd51/boards/metro_m4_express/board.h index 5d7734576..b3b80db89 100644 --- a/hw/bsp/samd51/boards/metro_m4_express/board.h +++ b/hw/bsp/samd51/boards/metro_m4_express/board.h @@ -43,6 +43,22 @@ #define UART_TX_PIN 23 #define UART_RX_PIN 22 +// SPI for USB host shield +#define MAX3421_SERCOM_ID 2 // SERCOM2 +#define MAX3421_SERCOM_FUNCTION 2 // function C + +#define MAX3421_SCK_PIN 13 +#define MAX3421_MOSI_PIN 12 +#define MAX3421_MISO_PIN 14 +#define MAX3421_TX_PAD 0 // MOSI = PAD_0, SCK = PAD_1 +#define MAX3421_RX_PAD 2 // MISO = PAD_2 + +#define MAX3421_CS_PIN 18 // D10 + +#define MAX3421_INTR_PIN 20 // D9 +#define MAX3421_INTR_EIC_ID 4 // EIC4 + + #ifdef __cplusplus } #endif diff --git a/hw/bsp/samd51/boards/pybadge/board.cmake b/hw/bsp/samd51/boards/pybadge/board.cmake new file mode 100644 index 000000000..d83211d9e --- /dev/null +++ b/hw/bsp/samd51/boards/pybadge/board.cmake @@ -0,0 +1,8 @@ +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd51/boards/pyportal/board.cmake b/hw/bsp/samd51/boards/pyportal/board.cmake new file mode 100644 index 000000000..d83211d9e --- /dev/null +++ b/hw/bsp/samd51/boards/pyportal/board.cmake @@ -0,0 +1,8 @@ +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd51/family.c b/hw/bsp/samd51/family.c index 7ec208b30..bca18e1a2 100644 --- a/hw/bsp/samd51/family.c +++ b/hw/bsp/samd51/family.c @@ -28,46 +28,63 @@ #include "bsp/board_api.h" #include "board.h" +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + #include "hal/include/hal_gpio.h" #include "hal/include/hal_init.h" #include "hpl/gclk/hpl_gclk_base.h" #include "hpl_mclk_config.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +/* Referenced GCLKs, should be initialized firstly */ +#define _GCLK_INIT_1ST 0xFFFFFFFF + +/* Not referenced GCLKs, initialized last */ +#define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB_0_Handler (void) -{ +void USB_0_Handler(void) { tud_int_handler(0); } -void USB_1_Handler (void) -{ +void USB_1_Handler(void) { tud_int_handler(0); } -void USB_2_Handler (void) -{ +void USB_2_Handler(void) { tud_int_handler(0); } -void USB_3_Handler (void) -{ +void USB_3_Handler(void) { tud_int_handler(0); } //--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION +// Implementation //--------------------------------------------------------------------+ -/* Referenced GCLKs, should be initialized firstly */ -#define _GCLK_INIT_1ST 0xFFFFFFFF +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 +#define MAX3421_SERCOM TU_XSTRCAT(SERCOM, MAX3421_SERCOM_ID) +#define MAX3421_EIC_Handler TU_XSTRCAT3(EIC_, MAX3421_INTR_EIC_ID, _Handler) -/* Not referenced GCLKs, initialized last */ -#define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) +static void max3421_init(void); -void board_init(void) -{ +#endif + +void board_init(void) { // Clock init ( follow hpl_init.c ) hri_nvmctrl_set_CTRLA_RWS_bf(NVMCTRL, 0); @@ -93,7 +110,7 @@ void board_init(void) gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); -#if CFG_TUSB_OS == OPT_OS_FREERTOS +#if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); NVIC_SetPriority(USB_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); @@ -118,45 +135,239 @@ void board_init(void) gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); + +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + max3421_init(); +#endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ +void board_led_write(bool state) { gpio_set_pin_level(LED_PIN, state); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { // button is active low return gpio_get_pin_level(BUTTON_PIN) ? 0 : 1; } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; return 0; } -int board_uart_write(void const * buf, int len) -{ - (void) buf; (void) len; +int board_uart_write(void const* buf, int len) { + (void) buf; + (void) len; return 0; } -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ +void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + +#endif + +//--------------------------------------------------------------------+ +// API: SPI transfer with MAX3421E, must be implemented by application +//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +static void max3421_init(void) { + //------------- SPI Init -------------// + + // MAX3421E max SPI clock is 26MHz however SAMD can only work reliably at 12 Mhz + uint32_t const baudrate = 12000000u; + + struct { + volatile uint32_t* mck_apb; + uint32_t mask; + uint8_t gclk_id_core; + uint8_t gclk_id_slow; + } const sercom_clock[] = { + { &MCLK->APBAMASK.reg, MCLK_APBAMASK_SERCOM0, SERCOM0_GCLK_ID_CORE, SERCOM0_GCLK_ID_SLOW }, + { &MCLK->APBAMASK.reg, MCLK_APBAMASK_SERCOM1, SERCOM1_GCLK_ID_CORE, SERCOM1_GCLK_ID_SLOW }, + { &MCLK->APBBMASK.reg, MCLK_APBBMASK_SERCOM2, SERCOM2_GCLK_ID_CORE, SERCOM2_GCLK_ID_SLOW }, + { &MCLK->APBBMASK.reg, MCLK_APBBMASK_SERCOM3, SERCOM3_GCLK_ID_CORE, SERCOM3_GCLK_ID_SLOW }, + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM4, SERCOM4_GCLK_ID_CORE, SERCOM4_GCLK_ID_SLOW }, + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM5, SERCOM5_GCLK_ID_CORE, SERCOM5_GCLK_ID_SLOW }, + #ifdef SERCOM6_GCLK_ID_CORE + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM6, SERCOM6_GCLK_ID_CORE, SERCOM6_GCLK_ID_SLOW }, + #endif + #ifdef SERCOM7_GCLK_ID_CORE + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM7, SERCOM7_GCLK_ID_CORE, SERCOM7_GCLK_ID_SLOW }, + #endif + }; + + Sercom* sercom = MAX3421_SERCOM; + + // Enable the APB clock for SERCOM + *sercom_clock[MAX3421_SERCOM_ID].mck_apb |= sercom_clock[MAX3421_SERCOM_ID].mask; + + // Configure GCLK for SERCOM + GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_core].reg = + GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_slow].reg = + GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + + // Disable the SPI module + sercom->SPI.CTRLA.bit.ENABLE = 0; + + // Reset the SPI module + sercom->SPI.CTRLA.bit.SWRST = 1; + while (sercom->SPI.SYNCBUSY.bit.SWRST); + + // Set up SPI in master mode, MSB first, SPI mode 0 + sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(MAX3421_TX_PAD) | SERCOM_SPI_CTRLA_DIPO(MAX3421_RX_PAD) | + SERCOM_SPI_CTRLA_MODE(3); + + sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN; + while (sercom->SPI.SYNCBUSY.bit.CTRLB == 1); + + // Set the baud rate + uint8_t baud_reg = (uint8_t) (SystemCoreClock / (2 * baudrate)); + if (baud_reg) { + baud_reg--; + } + + sercom->SPI.BAUD.reg = baud_reg; + + // Configure PA12 as MOSI (PAD0), PA13 as SCK (PAD1), PA14 as MISO (PAD2), function C (sercom) + gpio_set_pin_direction(MAX3421_SCK_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(MAX3421_SCK_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_SCK_PIN, MAX3421_SERCOM_FUNCTION); + + gpio_set_pin_direction(MAX3421_MOSI_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(MAX3421_MOSI_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_MOSI_PIN, MAX3421_SERCOM_FUNCTION); + + gpio_set_pin_direction(MAX3421_MISO_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(MAX3421_MISO_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_MISO_PIN, MAX3421_SERCOM_FUNCTION); + + // CS pin + gpio_set_pin_direction(MAX3421_CS_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_level(MAX3421_CS_PIN, 1); + + // Enable the SPI module + sercom->SPI.CTRLA.bit.ENABLE = 1; + while (sercom->SPI.SYNCBUSY.bit.ENABLE); + + //------------- External Interrupt -------------// + + // Enable the APB clock for EIC (External Interrupt Controller) + MCLK->APBAMASK.reg |= MCLK_APBAMASK_EIC; + + // Configure GCLK for EIC + GCLK->PCHCTRL[EIC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + + // Configure PA20 as an input with function A (external interrupt) + gpio_set_pin_direction(MAX3421_INTR_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(MAX3421_INTR_PIN, GPIO_PULL_UP); + gpio_set_pin_function(MAX3421_INTR_PIN, 0); + + // Disable EIC + EIC->CTRLA.bit.ENABLE = 0; + while (EIC->SYNCBUSY.bit.ENABLE); + + // Configure EIC to trigger on falling edge + volatile uint32_t* eic_config; + uint8_t sense_shift; + if (MAX3421_INTR_EIC_ID < 8) { + eic_config = &EIC->CONFIG[0].reg; + sense_shift = MAX3421_INTR_EIC_ID * 4; + } else { + eic_config = &EIC->CONFIG[1].reg; + sense_shift = (MAX3421_INTR_EIC_ID - 8) * 4; + } + + *eic_config &= ~(7 << sense_shift); + *eic_config |= 2 << sense_shift; + +#if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(EIC_0_IRQn + MAX3421_INTR_EIC_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + // Enable External Interrupt + EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID); + + // Enable EIC + EIC->CTRLA.bit.ENABLE = 1; + while (EIC->SYNCBUSY.bit.ENABLE); +} + +void MAX3421_EIC_Handler(void) { + // Clear the interrupt flag + EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID); + + // Call the TinyUSB interrupt handler + tuh_int_handler(1, true); +} + +// API to enable/disable MAX3421 INTR pin interrupt +void tuh_max3421_int_api(uint8_t rhport, bool enabled) { + (void) rhport; + + const IRQn_Type irq = EIC_0_IRQn + MAX3421_INTR_EIC_ID; + if (enabled) { + NVIC_EnableIRQ(irq); + } else { + NVIC_DisableIRQ(irq); + } +} + +// API to control MAX3421 SPI CS +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { + (void) rhport; + gpio_set_pin_level(MAX3421_CS_PIN, active ? 0 : 1); +} + +// API to transfer data with MAX3421 SPI +// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { + (void) rhport; + + Sercom* sercom = MAX3421_SERCOM; + + for (size_t count = 0; count < xfer_bytes; count++) { + // Wait for the transmit buffer to be empty + while (!sercom->SPI.INTFLAG.bit.DRE); + + // Write data to be transmitted + uint8_t data = 0x00; + if (tx_buf) { + data = tx_buf[count]; + } + + sercom->SPI.DATA.reg = (uint32_t) data; + + // Wait for the receive buffer to be filled + while (!sercom->SPI.INTFLAG.bit.RXC); + + // Read received data + data = (uint8_t) sercom->SPI.DATA.reg; + if (rx_buf) { + rx_buf[count] = data; + } + } + + // wait for bus idle and clear flags + while (!(sercom->SPI.INTFLAG.reg & (SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE))); + sercom->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE; + + return true; +} + #endif diff --git a/hw/bsp/samd51/family.cmake b/hw/bsp/samd51/family.cmake new file mode 100644 index 000000000..fa9586066 --- /dev/null +++ b/hw/bsp/samd51/family.cmake @@ -0,0 +1,104 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/microchip/samd51) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS SAMD51 CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (NOT TARGET ${BOARD_TARGET}) + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/gcc/system_samd51.c + ${SDK_DIR}/hpl/gclk/hpl_gclk.c + ${SDK_DIR}/hpl/mclk/hpl_mclk.c + ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c + ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c + ${SDK_DIR}/hal/src/hal_atomic.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/ + ${SDK_DIR}/config + ${SDK_DIR}/include + ${SDK_DIR}/hal/include + ${SDK_DIR}/hal/utils/include + ${SDK_DIR}/hpl/port + ${SDK_DIR}/hri + ${SDK_DIR}/CMSIS/Include + ) + + update_board(${BOARD_TARGET}) + + if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") + endif () + + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd51.c) + endif () + + target_sources(${BOARD_TARGET} PRIVATE + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_SAMD51 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/microchip/samd/dcd_samd.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/stm32g4/family.cmake b/hw/bsp/stm32g4/family.cmake index 675a96c74..eee6bd9ed 100644 --- a/hw/bsp/stm32g4/family.cmake +++ b/hw/bsp/stm32g4/family.cmake @@ -26,50 +26,46 @@ set(FAMILY_MCUS STM32G4 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + if (TARGET ${BOARD_TARGET}) + return() + endif () - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc - ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - update_board(${BOARD_TARGET}) + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + update_board(${BOARD_TARGET}) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - # nanolib - --specs=nosys.specs - --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + # nanolib + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) endif () endfunction() diff --git a/hw/bsp/stm32u5/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32u5/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..138fc6ba6 --- /dev/null +++ b/hw/bsp/stm32u5/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,165 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "stm32u5xx.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1) + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +#endif diff --git a/hw/bsp/stm32u5/boards/stm32u575eval/board.cmake b/hw/bsp/stm32u5/boards/stm32u575eval/board.cmake new file mode 100644 index 000000000..57ba85c71 --- /dev/null +++ b/hw/bsp/stm32u5/boards/stm32u575eval/board.cmake @@ -0,0 +1,10 @@ +set(MCU_VARIANT stm32u575xx) +set(JLINK_DEVICE stm32u575ai) + +set(LD_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/linker/STM32U575xx_FLASH.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32U575xx + ) +endfunction() diff --git a/hw/bsp/stm32u5/boards/stm32u575eval/board.mk b/hw/bsp/stm32u5/boards/stm32u575eval/board.mk index 19cd2a5b0..a75b2af78 100644 --- a/hw/bsp/stm32u5/boards/stm32u575eval/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u575eval/board.mk @@ -7,4 +7,4 @@ LD_FILE = $(BOARD_PATH)/STM32U575AIIXQ_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s # For flash-jlink target -JLINK_DEVICE = stm32u575 +JLINK_DEVICE = stm32u575ai diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c index c1fe3f412..ab4194623 100644 --- a/hw/bsp/stm32u5/family.c +++ b/hw/bsp/stm32u5/family.c @@ -25,15 +25,25 @@ * This file is part of the TinyUSB stack. */ +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wundef" +#endif + #include "stm32u5xx_hal.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "bsp/board_api.h" #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void OTG_FS_IRQHandler(void) -{ +void OTG_FS_IRQHandler(void) { tud_int_handler(0); } @@ -43,8 +53,7 @@ void OTG_FS_IRQHandler(void) UART_HandleTypeDef UartHandle; -void board_init(void) -{ +void board_init(void) { board_clock_init(); @@ -126,8 +135,8 @@ void board_init(void) GPIO_InitStruct.Alternate = GPIO_AF10_USB; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); -#if OTG_FS_VBUS_SENSE - // Configure VBUS Pin +#if defined(OTG_FS_VBUS_SENSE) && OTG_FS_VBUS_SENSE + // Configure VBUS Pin OTG_FS_VBUS_SENSE GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; @@ -155,50 +164,44 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ +void board_led_write(bool state) { HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } -int board_uart_read(uint8_t *buf, int len) -{ - (void)buf; - (void)len; +int board_uart_read(uint8_t *buf, int len) { + (void) buf; + (void) len; return 0; } -int board_uart_write(void const *buf, int len) -{ - HAL_UART_Transmit(&UartHandle, (uint8_t *)(uintptr_t)buf, len, 0xffff); +int board_uart_write(void const *buf, int len) { + HAL_UART_Transmit(&UartHandle, (uint8_t *) (uintptr_t) buf, len, 0xffff); return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void SysTick_Handler(void) -{ + +void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif -void HardFault_Handler(void) -{ +void HardFault_Handler(void) { asm("bkpt"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. -void _init(void) -{ +void _init(void) { } diff --git a/hw/bsp/stm32u5/family.cmake b/hw/bsp/stm32u5/family.cmake new file mode 100644 index 000000000..8f9ac1109 --- /dev/null +++ b/hw/bsp/stm32u5/family.cmake @@ -0,0 +1,108 @@ +include_guard() + +if (NOT BOARD) + message(FATAL_ERROR "BOARD not specified") +endif () + +set(ST_FAMILY u5) +set(ST_PREFIX stm32${ST_FAMILY}xx) + +set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) +set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS STM32U5 CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (NOT TARGET ${BOARD_TARGET}) + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + # nanolib + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_STM32U5 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c + #${TOP}/src/portable/st/typec/typec_stm32.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_stlink(${TARGET}) + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/stm32u5/family.mk b/hw/bsp/stm32u5/family.mk index dace63a51..c3e66c5a5 100644 --- a/hw/bsp/stm32u5/family.mk +++ b/hw/bsp/stm32u5/family.mk @@ -20,12 +20,12 @@ SRC_C += \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c INC += \ diff --git a/hw/bsp/tm4c123/family.c b/hw/bsp/tm4c123/family.c index ad5ae505f..738bc3fa0 100644 --- a/hw/bsp/tm4c123/family.c +++ b/hw/bsp/tm4c123/family.c @@ -8,7 +8,7 @@ void USB0_Handler(void) { #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED |
