From 170a3caed4d2175e42dfd11a9d3436bcdb084a18 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Thu, 27 Oct 2022 10:56:28 -0400 Subject: [PATCH 01/23] Update tusb DFU demo --- examples/freertos/usb/src/dfu_demo_support.c | 2 +- .../tinyusb_demos/dfu_runtime/src/demo_main.c | 168 +++++++++++------- .../dfu_runtime/src/tusb_config.h | 8 +- .../dfu_runtime/src/usb_descriptors.c | 15 +- examples/freertos/usb/usb.cmake | 77 ++++---- 5 files changed, 159 insertions(+), 111 deletions(-) diff --git a/examples/freertos/usb/src/dfu_demo_support.c b/examples/freertos/usb/src/dfu_demo_support.c index c5bd0d2a5..c0f806eb1 100644 --- a/examples/freertos/usb/src/dfu_demo_support.c +++ b/examples/freertos/usb/src/dfu_demo_support.c @@ -28,7 +28,7 @@ int check_dfu_mode(void) (uint8_t*)&mode, (unsigned)(MODE_ADDR), (size_t)sizeof(int)); - // rtos_printf("Mode is %u\n", mode); + rtos_printf("Mode is %u\n", mode); if(mode == 0xffffffff) mode = 0; // uninitialized should be handled as RT return mode; } diff --git a/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/demo_main.c b/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/demo_main.c index 2f2f3ede6..715951e03 100644 --- a/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/demo_main.c +++ b/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/demo_main.c @@ -130,85 +130,137 @@ void tud_resume_cb(void) } //--------------------------------------------------------------------+ -// Class callbacks +// DFU callbacks +// Note: alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. //--------------------------------------------------------------------+ static size_t total_len = 0; static size_t bytes_avail = 0; static uint32_t dn_base_addr = 0; -bool tud_dfu_firmware_valid_check_cb() + +// Invoked right before tud_dfu_download_cb() (state=DFU_DNBUSY) or tud_dfu_manifest_cb() (state=DFU_MANIFEST) +// Application return timeout in milliseconds (bwPollTimeout) for the next download/manifest operation. +// During this period, USB host won't try to communicate with us. +uint32_t tud_dfu_get_timeout_cb(uint8_t alt, uint8_t state) +{ + if ( state == DFU_DNBUSY ) + { + return 10; /* 10 ms */ + } + else if (state == DFU_MANIFEST) + { + // since we don't buffer entire image and do any flashing in manifest stage + return 0; + } + + return 0; +} + +// Invoked when received DFU_DNLOAD (wLength>0) following by DFU_GETSTATUS (state=DFU_DNBUSY) requests +// This callback could be returned before flashing op is complete (async). +// Once finished flashing, application must call tud_dfu_finish_flashing() +void tud_dfu_download_cb(uint8_t alt, uint16_t block_num, uint8_t const* data, uint16_t length) +{ + (void) alt; + rtos_printf("Block[%u] Len[%u] Buffer\n", block_num, length); + if (dn_base_addr == 0) + { + uint32_t addr = 0; + total_len = 0; + int tmp = boot_image_locate_available_spot(bim_ctx_ptr, &addr, &bytes_avail); + if(tmp == -1) + { + boot_image_t* imgptr = NULL; + imgptr = boot_image_get_last_image(bim_ctx_ptr); + addr = imgptr->startAddress; + bytes_avail = bim_ctx_ptr->boot_partition_size - addr; + } + rtos_printf("Using addr 0x%x\nsize %u\n", addr, bytes_avail); + dn_base_addr = addr; + } + + if(length > 0) + { + unsigned cur_addr = dn_base_addr + (block_num * bim_ctx_ptr->page_size); + if((bytes_avail - total_len) >= length) + { + // rtos_printf("write %d at 0x%x\n", length, cur_addr); + boot_image_write(bim_ctx_ptr->app_data, cur_addr, data, length); + total_len += length; + } else { + rtos_printf("Insufficient space\n"); + } + } +} + +// Invoked when download process is complete, received DFU_DNLOAD (wLength=0) following by DFU_GETSTATUS (state=Manifest) +// Application can do checksum, or actual flashing if buffered entire image previously. +// Once finished flashing, application must call tud_dfu_finish_flashing() +void tud_dfu_manifest_cb(uint8_t alt) { + (void) alt; + rtos_printf("Download completed, enter manifestation\n"); uint8_t dummy; + rtos_printf("Pass firmware validity check addr 0x%x size %u\n", dn_base_addr, total_len); set_rt_mode(); boot_image_read(bim_ctx_ptr->app_data, 0, &dummy, 1); // dummy read to ensure flash writes have completed reboot(); - return true; + + /* TODO actually verify */ + // tud_dfu_finish_flashing(DFU_STATUS_ERR_VERIFY); + // flashing op for manifest is complete without error + // Application can perform checksum, should it fail, use appropriate status such as errVERIFY. + tud_dfu_finish_flashing(DFU_STATUS_OK); } -void tud_dfu_req_dnload_data_cb(uint16_t wBlockNum, uint8_t* data, uint16_t length) +// Invoked when received DFU_UPLOAD request +// Application must populate data with up to length bytes and +// Return the number of written bytes +uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length) { - // rtos_printf("Block[%u] Len[%u] Buffer\n", wBlockNum, length); - - if (dn_base_addr == 0) - { - uint32_t addr = 0; - total_len = 0; - int tmp = boot_image_locate_available_spot(bim_ctx_ptr, &addr, &bytes_avail); - if(tmp == -1) - { - boot_image_t* imgptr = NULL; - imgptr = boot_image_get_last_image(bim_ctx_ptr); - addr = imgptr->startAddress; - bytes_avail = bim_ctx_ptr->boot_partition_size - addr; - } - rtos_printf("Using addr 0x%x\nsize %u\n", addr, bytes_avail); - dn_base_addr = addr; - } - - if(length > 0) - { - unsigned cur_addr = dn_base_addr + (wBlockNum * bim_ctx_ptr->page_size); - if((bytes_avail - total_len) >= length) - { - // rtos_printf("write %d at 0x%x\n", length, cur_addr); - boot_image_write(bim_ctx_ptr->app_data, cur_addr, data, length); - total_len += length; + (void) alt; - tud_dfu_dnload_complete(); - } else { - rtos_printf("Insufficient space\n"); - } - } + memset(data, 0x00, length); + uint32_t addr = block_num * FLASH_PAGE_SIZE; + uint32_t endaddr; + +#if 1 + // Test code which will just read out all of flash rather than a specific image + endaddr = 0x800000; +#else + boot_image_t* imgptr = NULL; + imgptr = boot_image_get_last_image(bim_ctx_ptr); + addr += imgptr->startAddress; + endaddr = imgptr->startAddress + imgptr->size; +#endif + return (addr >= endaddr) ? 0 : (uint16_t)boot_image_read(bim_ctx_ptr->app_data, addr, data, length); } -bool tud_dfu_device_data_done_check_cb() +// Invoked when the Host has terminated a download or upload transfer +void tud_dfu_abort_cb(uint8_t alt) { - rtos_printf("Dummy device data done check... Returning true\n"); - return true; + (void) alt; + uint8_t dummy; + rtos_printf("Host Aborted transfer. Reboot to RT\n"); + set_rt_mode(); + boot_image_read(bim_ctx_ptr->app_data, 0, &dummy, 1); // dummy read to ensure flash writes have completed + reboot(); } -void tud_dfu_abort_cb() +// Invoked when a DFU_DETACH request is received +void tud_dfu_detach_cb(void) { - rtos_printf("Host Aborted transfer\n"); + rtos_printf("Host detach, reboot\n"); + set_rt_mode(); + reboot(); } -uint16_t tud_dfu_req_upload_data_cb(uint16_t block_num, uint8_t* data, uint16_t length) +void tud_dfu_runtime_reboot_to_dfu_cb(void) { - memset(data, 0x00, length); - uint32_t addr = block_num * FLASH_PAGE_SIZE; - uint32_t endaddr; - -#if 0 - // Test code which will just read out all of flash rather than a specific image - endaddr = 0x800000; -#else - boot_image_t* imgptr = NULL; - imgptr = boot_image_get_last_image(bim_ctx_ptr); - addr += imgptr->startAddress; - endaddr = imgptr->startAddress + imgptr->size; -#endif - return (addr >= endaddr) ? 0 : (uint16_t)boot_image_read(bim_ctx_ptr->app_data, addr, data, length); + rtos_printf("Host detach, reboot\n"); + set_dfu_mode(); + reboot(); } static void reboot(void) @@ -219,12 +271,6 @@ static void reboot(void) while(1) {;} } -void tud_dfu_runtime_reboot_to_dfu_cb(void) -{ - set_dfu_mode(); - reboot(); -} - //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ diff --git a/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/tusb_config.h b/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/tusb_config.h index 92648f3a4..319b2072b 100644 --- a/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/tusb_config.h +++ b/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/tusb_config.h @@ -76,12 +76,14 @@ #define CFG_TUD_ENDPOINT0_SIZE 64 #endif -#define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 4096 +// #define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 4096 +#define CFG_TUD_DFU_XFER_BUFSIZE ( OPT_MODE_HIGH_SPEED ? 512 : 64 ) //------------- CLASS -------------// -#define CFG_TUD_DFU_RUNTIME 1 -#define CFG_TUD_DFU_MODE 1 +// #define CFG_TUD_DFU_RUNTIME 1 +// #define CFG_TUD_DFU_MODE 1 +#define CFG_TUD_DFU 1 #ifdef __cplusplus } diff --git a/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/usb_descriptors.c b/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/usb_descriptors.c index 6e0f0e31d..2e153bbab 100644 --- a/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/usb_descriptors.c +++ b/examples/freertos/usb/tinyusb_demos/dfu_runtime/src/usb_descriptors.c @@ -119,11 +119,9 @@ enum ITF1_NUM_TOTAL }; -#define CONFIG_1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_MODE_DESC_LEN ) +#define CONFIG_1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_DESC_LEN(1) ) -#define FUNC_ATTRS (DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK | DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) -// #define FUNC_ATTRS (DFU_FUNC_ATTR_WILL_DETACH_BITMASK | DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK | DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) -// #define FUNC_ATTRS 0x0d // original +#define FUNC_ATTRS (DFU_ATTR_CAN_UPLOAD | DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_MANIFESTATION_TOLERANT) uint8_t const desc_configuration_rt[] = { @@ -131,7 +129,7 @@ uint8_t const desc_configuration_rt[] = TUD_CONFIG_DESCRIPTOR(1, ITF0_NUM_TOTAL, 0, CONFIG_0_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, attributes, detach timeout, transfer size */ - TUD_DFU_RT_DESCRIPTOR(ITF0_NUM_DFU_RT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE), + TUD_DFU_RT_DESCRIPTOR(ITF0_NUM_DFU_RT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), }; uint8_t const desc_configuration_mode[] = @@ -140,7 +138,7 @@ uint8_t const desc_configuration_mode[] = TUD_CONFIG_DESCRIPTOR(1, ITF1_NUM_TOTAL, 0, CONFIG_1_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, attributes, detach timeout, transfer size */ - TUD_DFU_MODE_DESCRIPTOR(ITF1_NUM_DFU_MODE, 0, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE), + TUD_DFU_DESCRIPTOR(ITF1_NUM_DFU_MODE, 1, 5, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), }; // Invoked when received GET CONFIGURATION DESCRIPTOR @@ -149,7 +147,9 @@ uint8_t const desc_configuration_mode[] = uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations - return check_dfu_mode() ? desc_configuration_rt : desc_configuration_mode; + return desc_configuration_mode; + /* TODO tmp always mode for now*/ + // return check_dfu_mode() ? desc_configuration_rt : desc_configuration_mode; } //--------------------------------------------------------------------+ @@ -164,6 +164,7 @@ char const* string_desc_arr [] = "TinyUSB Device", // 2: Product "123456", // 3: Serials, should use chip ID "TinyUSB DFU runtime", // 4: DFU runtime + "TinyUSB DFU FLASH", // 5: DFU device }; static uint16_t _desc_str[32]; diff --git a/examples/freertos/usb/usb.cmake b/examples/freertos/usb/usb.cmake index b6fbd19e5..15d124543 100644 --- a/examples/freertos/usb/usb.cmake +++ b/examples/freertos/usb/usb.cmake @@ -211,48 +211,47 @@ create_run_target(example_freertos_usb_tusb_demo_dfu) create_debug_target(example_freertos_usb_tusb_demo_dfu) -# Incomplete pending xcore tools updates #********************** # DFU Runtime Tile Targets #********************** -# file(GLOB_RECURSE DEMO_SOURCES ${CMAKE_CURRENT_LIST_DIR}/tinyusb_demos/dfu_runtime/src/*.c ) -# set(DEMO_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/tinyusb_demos/dfu_runtime/src/) -# set(DEMO_COMPILE_DEFINITIONS BOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED -# DFU_DEMO=1 -# ) -# set(TARGET_NAME tile0_example_freertos_usb_tusb_demo_dfu_runtime) -# add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) -# target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES} ${DEMO_SOURCES}) -# target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${DEMO_INCLUDES}) -# target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} ${DEMO_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0) -# target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) -# target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) -# target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) -# unset(TARGET_NAME) -# -# set(TARGET_NAME tile1_example_freertos_usb_tusb_demo_dfu_runtime) -# add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) -# target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES} ${DEMO_SOURCES}) -# target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${DEMO_INCLUDES}) -# target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} ${DEMO_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1) -# target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) -# target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) -# target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) -# unset(TARGET_NAME) -# unset(DEMO_SOURCES) -# unset(DEMO_INCLUDES) -# unset(DEMO_COMPILE_DEFINITIONS) -# -# #********************** -# # Merge binaries -# #********************** -# merge_binaries(example_freertos_usb_tusb_demo_dfu_runtime tile0_example_freertos_usb_tusb_demo_dfu_runtime tile1_example_freertos_usb_tusb_demo_dfu_runtime 1) -# -# #********************** -# # Create run and debug targets -# #********************** -# create_run_target(example_freertos_usb_tusb_demo_dfu_runtime) -# create_debug_target(example_freertos_usb_tusb_demo_dfu_runtime) +file(GLOB_RECURSE DEMO_SOURCES ${CMAKE_CURRENT_LIST_DIR}/tinyusb_demos/dfu_runtime/src/*.c ) +set(DEMO_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/tinyusb_demos/dfu_runtime/src/) +set(DEMO_COMPILE_DEFINITIONS BOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + DFU_DEMO=1 +) +set(TARGET_NAME tile0_example_freertos_usb_tusb_demo_dfu_runtime) +add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) +target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES} ${DEMO_SOURCES}) +target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${DEMO_INCLUDES}) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} ${DEMO_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0) +target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) +target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) +unset(TARGET_NAME) + +set(TARGET_NAME tile1_example_freertos_usb_tusb_demo_dfu_runtime) +add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) +target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES} ${DEMO_SOURCES}) +target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${DEMO_INCLUDES}) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} ${DEMO_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1) +target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) +target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) +unset(TARGET_NAME) +unset(DEMO_SOURCES) +unset(DEMO_INCLUDES) +unset(DEMO_COMPILE_DEFINITIONS) + +#********************** +# Merge binaries +#********************** +merge_binaries(example_freertos_usb_tusb_demo_dfu_runtime tile0_example_freertos_usb_tusb_demo_dfu_runtime tile1_example_freertos_usb_tusb_demo_dfu_runtime 1) + +#********************** +# Create run and debug targets +#********************** +create_run_target(example_freertos_usb_tusb_demo_dfu_runtime) +create_debug_target(example_freertos_usb_tusb_demo_dfu_runtime) #********************** From 4157b4b5913204e198ead1d1799bc7a97d119ebd Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Mon, 7 Nov 2022 10:57:08 -0500 Subject: [PATCH 02/23] Add dfu app skeleton, fix strange xscope bug Link order appears to cause the dfu app to break when acquiring the xscope lock for no discernable reason. Save commit for later investigation. To reproduce in the dfu bsp_config add rtos::drivers::usb before rtos::sw_services::usb in the target_link_libraries call. --- examples/examples.cmake | 1 + examples/freertos/dfu/README.rst | 65 ++++ examples/freertos/dfu/XCORE-AI-EXPLORER.xn | 109 +++++++ .../freertos/dfu/bsp_config/CMakeLists.txt | 32 ++ .../platform/driver_instances.c | 31 ++ .../platform/driver_instances.h | 45 +++ .../platform/platform_conf.h | 83 +++++ .../platform/platform_init.c | 196 ++++++++++++ .../platform/platform_init.h | 12 + .../platform/platform_start.c | 60 ++++ examples/freertos/dfu/dfu.cmake | 81 +++++ examples/freertos/dfu/src/FreeRTOSConfig.h | 113 +++++++ examples/freertos/dfu/src/app_conf.h | 38 +++ examples/freertos/dfu/src/config.xscope | 24 ++ examples/freertos/dfu/src/demo_main.h | 9 + examples/freertos/dfu/src/dfu_demo_support.c | 114 +++++++ examples/freertos/dfu/src/main.c | 90 ++++++ examples/freertos/dfu/src/tusb_config.h | 50 +++ examples/freertos/dfu/src/usb/demo_main.c | 294 ++++++++++++++++++ .../freertos/dfu/src/usb/usb_descriptors.c | 171 ++++++++++ .../tinyusb_demos/dfu_runtime/src/demo_main.c | 2 +- 21 files changed, 1619 insertions(+), 1 deletion(-) create mode 100644 examples/freertos/dfu/README.rst create mode 100644 examples/freertos/dfu/XCORE-AI-EXPLORER.xn create mode 100644 examples/freertos/dfu/bsp_config/CMakeLists.txt create mode 100644 examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.c create mode 100644 examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.h create mode 100644 examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_conf.h create mode 100644 examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c create mode 100644 examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.h create mode 100644 examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_start.c create mode 100644 examples/freertos/dfu/dfu.cmake create mode 100644 examples/freertos/dfu/src/FreeRTOSConfig.h create mode 100644 examples/freertos/dfu/src/app_conf.h create mode 100644 examples/freertos/dfu/src/config.xscope create mode 100644 examples/freertos/dfu/src/demo_main.h create mode 100644 examples/freertos/dfu/src/dfu_demo_support.c create mode 100644 examples/freertos/dfu/src/main.c create mode 100644 examples/freertos/dfu/src/tusb_config.h create mode 100644 examples/freertos/dfu/src/usb/demo_main.c create mode 100644 examples/freertos/dfu/src/usb/usb_descriptors.c diff --git a/examples/examples.cmake b/examples/examples.cmake index 43a73a636..c2e370aed 100644 --- a/examples/examples.cmake +++ b/examples/examples.cmake @@ -4,6 +4,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL XCORE_XS3A) include(${CMAKE_CURRENT_LIST_DIR}/bare-metal/explorer_board/explorer_board.cmake) ## FreeRTOS examples + include(${CMAKE_CURRENT_LIST_DIR}/freertos/dfu/dfu.cmake) include(${CMAKE_CURRENT_LIST_DIR}/freertos/device_control/device_control.cmake) include(${CMAKE_CURRENT_LIST_DIR}/freertos/dispatcher/dispatcher.cmake) include(${CMAKE_CURRENT_LIST_DIR}/freertos/explorer_board/explorer_board.cmake) diff --git a/examples/freertos/dfu/README.rst b/examples/freertos/dfu/README.rst new file mode 100644 index 000000000..803d733ac --- /dev/null +++ b/examples/freertos/dfu/README.rst @@ -0,0 +1,65 @@ +############## +DFU +############## + +This example application demonstrates a method to add DFU to a FreeRTOS application on XCORE. + +********************* +Building the firmware +********************* + +Run the following commands in the xcore_sdk root folder to build the firmware: + +.. tab:: Linux and Mac + + .. code-block:: console + + cmake -B build -DCMAKE_TOOLCHAIN_FILE=xmos_cmake_toolchain/xs3a.cmake + cd build + make example_freertos_dfu + +.. tab:: Windows + + .. code-block:: console + + cmake -G "NMake Makefiles" -B build -DCMAKE_TOOLCHAIN_FILE=xmos_cmake_toolchain/xs3a.cmake + cd build + nmake example_freertos_dfu + + +******************** +Running the firmware +******************** + +From the xcore_sdk build folder run: + +.. tab:: Linux and Mac + + .. code-block:: console + + make run_example_freertos_dfu + +.. tab:: Windows + + .. code-block:: console + + nmake run_example_freertos_dfu + + +******************************** +Debugging the firmware with xgdb +******************************** + +From the xcore_sdk build folder run: + +.. tab:: Linux and Mac + + .. code-block:: console + + make debug_example_freertos_dfu + +.. tab:: Windows + + .. code-block:: console + + nmake debug_example_freertos_dfu diff --git a/examples/freertos/dfu/XCORE-AI-EXPLORER.xn b/examples/freertos/dfu/XCORE-AI-EXPLORER.xn new file mode 100644 index 000000000..4dde19f84 --- /dev/null +++ b/examples/freertos/dfu/XCORE-AI-EXPLORER.xn @@ -0,0 +1,109 @@ + + + Board + xcore.ai Explorer Kit + + + tileref tile[2] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/freertos/dfu/bsp_config/CMakeLists.txt b/examples/freertos/dfu/bsp_config/CMakeLists.txt new file mode 100644 index 000000000..3610d0df2 --- /dev/null +++ b/examples/freertos/dfu/bsp_config/CMakeLists.txt @@ -0,0 +1,32 @@ +## Create Explorer Board 2V0 target +add_library(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0 INTERFACE) +target_sources(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0 + INTERFACE + XCORE-AI-EXPLORER_2V0/platform/driver_instances.c + XCORE-AI-EXPLORER_2V0/platform/platform_init.c + XCORE-AI-EXPLORER_2V0/platform/platform_start.c +) +target_include_directories(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0 + INTERFACE + XCORE-AI-EXPLORER_2V0 +) +target_link_libraries(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0 + INTERFACE + core::general + rtos::freertos + rtos::drivers::general + rtos::sw_services::usb +) +target_compile_definitions(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0 + INTERFACE + XCOREAI_EXPLORER=1 + PLATFORM_SUPPORTS_TILE_0=1 + PLATFORM_SUPPORTS_TILE_1=1 + PLATFORM_SUPPORTS_TILE_2=0 + PLATFORM_SUPPORTS_TILE_3=0 + USB_TILE_NO=0 + USB_TILE=tile[USB_TILE_NO] +) + +## Create an alias +add_library(example::freertos::dfu::bsp_config::xcore_ai_explorer ALIAS example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0) diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.c b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.c new file mode 100644 index 000000000..f7b119809 --- /dev/null +++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.c @@ -0,0 +1,31 @@ +// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the +// XMOS Public License: Version 1 + +#include "platform/driver_instances.h" + +static rtos_intertile_t intertile_ctx_s; +rtos_intertile_t *intertile_ctx = &intertile_ctx_s; + +static rtos_qspi_flash_t qspi_flash_ctx_s; +rtos_qspi_flash_t *qspi_flash_ctx = &qspi_flash_ctx_s; + +static rtos_spi_master_t spi_master_ctx_s; +rtos_spi_master_t *spi_master_ctx = &spi_master_ctx_s; + +static rtos_spi_master_device_t wifi_device_ctx_s; +rtos_spi_master_device_t *wifi_device_ctx = &wifi_device_ctx_s; + +static rtos_gpio_t gpio_ctx_t0_s; +rtos_gpio_t *gpio_ctx_t0 = &gpio_ctx_t0_s; + +static rtos_gpio_t gpio_ctx_t1_s; +rtos_gpio_t *gpio_ctx_t1 = &gpio_ctx_t1_s; + +static rtos_i2c_master_t i2c_master_ctx_s; +rtos_i2c_master_t *i2c_master_ctx = &i2c_master_ctx_s; + +static rtos_uart_tx_t uart_tx_ctx_s; +rtos_uart_tx_t *uart_tx_ctx = &uart_tx_ctx_s; + +static rtos_uart_rx_t uart_rx_ctx_s; +rtos_uart_rx_t *uart_rx_ctx = &uart_rx_ctx_s; \ No newline at end of file diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.h b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.h new file mode 100644 index 000000000..1a92103e9 --- /dev/null +++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.h @@ -0,0 +1,45 @@ +// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the +// XMOS Public License: Version 1 + +#ifndef DRIVER_INSTANCES_H_ +#define DRIVER_INSTANCES_H_ + +#include "rtos_intertile.h" +#include "rtos_i2c_master.h" +#include "rtos_spi_master.h" +#include "rtos_qspi_flash.h" +#include "rtos_gpio.h" +#include "rtos_uart_tx.h" +#include "rtos_uart_rx.h" +#include "usb_support.h" + +#define FLASH_TILE_NO 0 +#define I2C_TILE_NO 0 +#define UART_TILE_NO 1 + +/** TILE 0 Clock Blocks */ +#define FLASH_CLKBLK XS1_CLKBLK_1 +// #define UNUSED_CLKBLK XS1_CLKBLK_2 +#define SPI_CLKBLK XS1_CLKBLK_3 +#define XUD_CLKBLK_1 XS1_CLKBLK_4 /* Reserved for lib_xud */ +#define XUD_CLKBLK_2 XS1_CLKBLK_5 /* Reserved for lib_xud */ + +/** TILE 1 Clock Blocks */ +// #define UNUSED_CLKBLK XS1_CLKBLK_1 +// #define UNUSED_CLKBLK XS1_CLKBLK_2 +// #define UNUSED_CLKBLK XS1_CLKBLK_3 +// #define UNUSED_CLKBLK XS1_CLKBLK_4 +// #define UNUSED_CLKBLK XS1_CLKBLK_5 + +extern rtos_intertile_t *intertile_ctx; +extern rtos_qspi_flash_t *qspi_flash_ctx; +extern rtos_spi_master_t *spi_master_ctx; +extern rtos_spi_master_device_t *wifi_device_ctx; +extern rtos_gpio_t *gpio_ctx_t0; +extern rtos_gpio_t *gpio_ctx_t1; +extern rtos_i2c_master_t *i2c_master_ctx; +extern rtos_uart_tx_t *uart_tx_ctx; +extern rtos_uart_rx_t *uart_rx_ctx; + + +#endif /* DRIVER_INSTANCES_H_ */ diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_conf.h b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_conf.h new file mode 100644 index 000000000..e6305f163 --- /dev/null +++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_conf.h @@ -0,0 +1,83 @@ +// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the +// XMOS Public License: Version 1 + +#ifndef PLATFORM_CONF_H_ +#define PLATFORM_CONF_H_ + +/* + * This file contains defaults to build a basic project targetting the + * XCORE-AI-EXPLORER board. Users may create their own app_conf.h to override + * any default settings. + * + * For a different soft tapeout design, it is recommended to create an entirely + * different board support package. + */ + +#if __has_include("app_conf.h") +#include "app_conf.h" +#endif /* __has_include("app_conf.h") */ + +/*****************************************/ +/* Intertile Communication Configuration */ +/*****************************************/ +#ifndef appconfI2C_MASTER_RPC_PORT +#define appconfI2C_MASTER_RPC_PORT 10 +#endif /* appconfI2C_MASTER_RPC_PORT */ + +#ifndef appconfI2C_MASTER_RPC_PRIORITY +#define appconfI2C_MASTER_RPC_PRIORITY (configMAX_PRIORITIES/2) +#endif /* appconfI2C_MASTER_RPC_PRIORITY */ + +#ifndef appconfGPIO_T0_RPC_PORT +#define appconfGPIO_T0_RPC_PORT 11 +#endif /* appconfGPIO_T0_RPC_PORT */ + +#ifndef appconfGPIO_T1_RPC_PORT +#define appconfGPIO_T1_RPC_PORT 12 +#endif /* appconfGPIO_T1_RPC_PORT */ + +#ifndef appconfGPIO_RPC_PRIORITY +#define appconfGPIO_RPC_PRIORITY (configMAX_PRIORITIES/2) +#endif /* appconfGPIO_RPC_PRIORITY */ + +/*****************************************/ +/* I/O and interrupt cores for Tile 0 */ +/*****************************************/ +#ifndef appconfI2C_IO_CORE +#define appconfI2C_IO_CORE 2 /* Must be kept off core 0 with the RTOS tick ISR */ +#endif /* appconfI2C_IO_CORE */ + +#ifndef appconfI2C_INTERRUPT_CORE +#define appconfI2C_INTERRUPT_CORE 0 /* Must be kept off I/O cores. */ +#endif /* appconfI2C_INTERRUPT_CORE */ + +/*****************************************/ +/* I/O and interrupt cores for Tile 1 */ +/*****************************************/ +#ifndef appconfUART_RX_IO_CORE +#define appconfUART_RX_IO_CORE 3 /* Must be kept off core 0 with the RTOS tick ISR */ +#endif /* appconfUART_RX_IO_CORE */ + +#ifndef appconfUART_RX_INTERRUPT_CORE +#define appconfUART_RX_INTERRUPT_CORE 4 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ +#endif /* appconfUART_RX_INTERRUPT_CORE */ + +/*****************************************/ +/* I/O Settings */ +/*****************************************/ +#ifndef appconfUART_BAUD_RATE +#define appconfUART_BAUD_RATE 115200 +#endif /* appconfUART_BAUD_RATE */ + +/*****************************************/ +/* I/O Task Priorities */ +/*****************************************/ +#ifndef appconfSPI_MASTER_TASK_PRIORITY +#define appconfSPI_MASTER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#endif /* appconfSPI_MASTER_TASK_PRIORITY */ + +#ifndef appconfQSPI_FLASH_TASK_PRIORITY +#define appconfQSPI_FLASH_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#endif /* appconfQSPI_FLASH_TASK_PRIORITY */ + +#endif /* PLATFORM_CONF_H_ */ diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c new file mode 100644 index 000000000..bc774bd23 --- /dev/null +++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c @@ -0,0 +1,196 @@ +// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the +// XMOS Public License: Version 1 + +#include + +#include "platform_conf.h" +#include "platform/driver_instances.h" + +static void flash_init(void) +{ +#if ON_TILE(FLASH_TILE_NO) + qspi_flash_ctx->ctx.sfdp_skip = true; + qspi_flash_ctx->ctx.sfdp_supported = false; + qspi_flash_ctx->ctx.page_size_bytes = 256; + qspi_flash_ctx->ctx.page_count = 16384; + qspi_flash_ctx->ctx.flash_size_kbytes = 4096; + qspi_flash_ctx->ctx.address_bytes = 3; + qspi_flash_ctx->ctx.erase_info[0].size_log2 = 12; + qspi_flash_ctx->ctx.erase_info[0].cmd = 0xEEFEEEEE; + qspi_flash_ctx->ctx.erase_info[1].size_log2 = 15; + qspi_flash_ctx->ctx.erase_info[1].cmd = 0xEFEFEEFE; + qspi_flash_ctx->ctx.erase_info[2].size_log2 = 16; + qspi_flash_ctx->ctx.erase_info[2].cmd = 0xFFEFFEEE; + qspi_flash_ctx->ctx.erase_info[3].size_log2 = 0; + qspi_flash_ctx->ctx.erase_info[3].cmd = 0; + qspi_flash_ctx->ctx.busy_poll_cmd = 0xEEEEEFEF; + qspi_flash_ctx->ctx.busy_poll_bit = 0; + qspi_flash_ctx->ctx.busy_poll_ready_value = 0; + qspi_flash_ctx->ctx.qe_reg = 2; + qspi_flash_ctx->ctx.qe_bit = 1; + qspi_flash_ctx->ctx.sr2_read_cmd = 0xEEFFEFEF; + qspi_flash_ctx->ctx.sr2_write_cmd = 0xEEEEEEEE; + + rtos_qspi_flash_init( + qspi_flash_ctx, + FLASH_CLKBLK, + PORT_SQI_CS, + PORT_SQI_SCLK, + PORT_SQI_SIO, + + /** Derive QSPI clock from the 600 MHz xcore clock **/ + qspi_io_source_clock_xcore, + + /** Full speed clock configuration **/ + 5, // 600 MHz / (2*5) -> 60 MHz, + 1, + qspi_io_sample_edge_rising, + 0, + + /** SPI read clock configuration **/ + 12, // 600 MHz / (2*12) -> 25 MHz + 0, + qspi_io_sample_edge_falling, + 0, + + qspi_flash_page_program_1_4_4); +#endif +} + +static void gpio_init(void) +{ + static rtos_driver_rpc_t gpio_rpc_config_t0; + static rtos_driver_rpc_t gpio_rpc_config_t1; + rtos_intertile_t *client_intertile_ctx[1] = {intertile_ctx}; + +#if ON_TILE(0) + rtos_gpio_init(gpio_ctx_t0); + + rtos_gpio_rpc_host_init( + gpio_ctx_t0, + &gpio_rpc_config_t0, + client_intertile_ctx, + 1); + + rtos_gpio_rpc_client_init( + gpio_ctx_t1, + &gpio_rpc_config_t1, + intertile_ctx); +#endif + +#if ON_TILE(1) + rtos_gpio_init(gpio_ctx_t1); + + rtos_gpio_rpc_client_init( + gpio_ctx_t0, + &gpio_rpc_config_t0, + intertile_ctx); + + rtos_gpio_rpc_host_init( + gpio_ctx_t1, + &gpio_rpc_config_t1, + client_intertile_ctx, + 1); +#endif +} + +static void i2c_init(void) +{ + static rtos_driver_rpc_t i2c_rpc_config; + +#if ON_TILE(I2C_TILE_NO) + rtos_intertile_t *client_intertile_ctx[1] = {intertile_ctx}; + rtos_i2c_master_init( + i2c_master_ctx, + PORT_I2C_SCL, 0, 0, + PORT_I2C_SDA, 0, 0, + 0, + 100); + + rtos_i2c_master_rpc_host_init( + i2c_master_ctx, + &i2c_rpc_config, + client_intertile_ctx, + 1); +#else + rtos_i2c_master_rpc_client_init( + i2c_master_ctx, + &i2c_rpc_config, + intertile_ctx); +#endif +} + +static void spi_init(void) +{ +#if ON_TILE(0) + rtos_spi_master_init( + spi_master_ctx, + SPI_CLKBLK, + WIFI_CS_N, + WIFI_CLK, + WIFI_MOSI, + WIFI_MISO); + + rtos_spi_master_device_init( + wifi_device_ctx, + spi_master_ctx, + 1, /* WiFi CS pin is on bit 1 of the CS port */ + SPI_MODE_0, + spi_master_source_clock_ref, + 0, /* 50 MHz */ + spi_master_sample_delay_2, /* what should this be? 2? 3? 4? */ + 0, /* should this be > 0 if the above is 3-4 ? */ + 1, + 0, + 0); +#endif +} + + +static void uart_init(void) +{ +#if ON_TILE(UART_TILE_NO) + hwtimer_t tmr_rx = hwtimer_alloc(); + + rtos_uart_rx_init( + uart_rx_ctx, + (1 << appconfUART_RX_IO_CORE), + XS1_PORT_1M, //X1D36 + appconfUART_BAUD_RATE, + 8, + UART_PARITY_NONE, + 1, + tmr_rx); + + + hwtimer_t tmr_tx = hwtimer_alloc(); + + rtos_uart_tx_init( + uart_tx_ctx, + XS1_PORT_1P, //X1D39 + appconfUART_BAUD_RATE, + 8, + UART_PARITY_NONE, + 1, + tmr_tx); +#endif +} + +void usb_init(void) +{ +#if ON_TILE(USB_TILE_NO) + usb_manager_init(); +#endif +} + +void platform_init(chanend_t other_tile_c) +{ + rtos_intertile_init(intertile_ctx, other_tile_c); + + flash_init(); + gpio_init(); + spi_init(); + i2c_init(); + uart_init(); + usb_init(); +} diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.h b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.h new file mode 100644 index 000000000..bae19eb7a --- /dev/null +++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.h @@ -0,0 +1,12 @@ +// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the +// XMOS Public License: Version 1 + +#ifndef PLATFORM_INIT_H_ +#define PLATFORM_INIT_H_ + +#include + +void platform_init(chanend_t other_tile_c); +void platform_start(void); + +#endif /* PLATFORM_INIT_H_ */ diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_start.c b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_start.c new file mode 100644 index 000000000..caa1e6613 --- /dev/null +++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_start.c @@ -0,0 +1,60 @@ +// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the +// XMOS Public License: Version 1 + +#include + +#include "platform_conf.h" +#include "platform/driver_instances.h" + +static void gpio_start(void) +{ + rtos_gpio_rpc_config(gpio_ctx_t0, appconfGPIO_T0_RPC_PORT, appconfGPIO_RPC_PRIORITY); + rtos_gpio_rpc_config(gpio_ctx_t1, appconfGPIO_T1_RPC_PORT, appconfGPIO_RPC_PRIORITY); + +#if ON_TILE(0) + rtos_gpio_start(gpio_ctx_t0); +#endif +#if ON_TILE(1) + rtos_gpio_start(gpio_ctx_t1); +#endif +} + +static void spi_start(void) +{ +#if ON_TILE(0) + rtos_spi_master_start(spi_master_ctx, appconfSPI_MASTER_TASK_PRIORITY); +#endif +} + +static void i2c_start(void) +{ + rtos_i2c_master_rpc_config(i2c_master_ctx, appconfI2C_MASTER_RPC_PORT, appconfI2C_MASTER_RPC_PRIORITY); +#if ON_TILE(I2C_TILE_NO) + rtos_i2c_master_start(i2c_master_ctx); +#endif +} + +static void flash_start(void) +{ +#if ON_TILE(0) + rtos_qspi_flash_start(qspi_flash_ctx, appconfQSPI_FLASH_TASK_PRIORITY); +#endif +} + +static void usb_start(void) +{ +#if ON_TILE(USB_TILE_NO) + usb_manager_start(appconfUSB_MANAGER_TASK_PRIORITY); +#endif +} + +void platform_start(void) +{ + rtos_intertile_start(intertile_ctx); + + gpio_start(); + spi_start(); + flash_start(); + i2c_start(); + usb_start(); +} diff --git a/examples/freertos/dfu/dfu.cmake b/examples/freertos/dfu/dfu.cmake new file mode 100644 index 000000000..c897ebfbf --- /dev/null +++ b/examples/freertos/dfu/dfu.cmake @@ -0,0 +1,81 @@ +#********************** +# Gather Sources +#********************** +file(GLOB_RECURSE APP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.c) +set(APP_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/src) + +#********************** +# Import example specific bsp_config +#********************** +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/bsp_config) + +#********************** +# Flags +#********************** +set(APP_COMPILER_FLAGS + -Os + -g + -report + -fxscope + -lquadspi + -mcmodel=large + -Wno-xcore-fptrgroup + ${CMAKE_CURRENT_LIST_DIR}/src/config.xscope + ${CMAKE_CURRENT_LIST_DIR}/XCORE-AI-EXPLORER.xn +) +set(APP_COMPILE_DEFINITIONS + DEBUG_PRINT_ENABLE=1 + PLATFORM_USES_TILE_0=1 + PLATFORM_USES_TILE_1=1 + + XUD_CORE_CLOCK=600 +) + +set(APP_LINK_OPTIONS + -lquadspi + -fxscope + -report + ${CMAKE_CURRENT_LIST_DIR}/XCORE-AI-EXPLORER.xn + ${CMAKE_CURRENT_LIST_DIR}/src/config.xscope +) + +set(APP_LINK_LIBRARIES + example::freertos::dfu::bsp_config::xcore_ai_explorer +) + +#********************** +# Tile Targets +#********************** +set(TARGET_NAME tile0_example_freertos_dfu) +add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) +target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES}) +target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES}) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0) +target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) +target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS} +"-Wm,--map,memory0.map") +unset(TARGET_NAME) + +set(TARGET_NAME tile1_example_freertos_dfu) +add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) +target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES}) +target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES}) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1) +target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) +target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS} +"-Wm,--map,memory1.map") +unset(TARGET_NAME) + +#********************** +# Merge binaries +#********************** +merge_binaries(example_freertos_dfu tile0_example_freertos_dfu tile1_example_freertos_dfu 1) + +#********************** +# Create run and debug targets +#********************** +create_run_target(example_freertos_dfu) +create_debug_target(example_freertos_dfu) +create_flash_app_target(example_freertos_dfu) diff --git a/examples/freertos/dfu/src/FreeRTOSConfig.h b/examples/freertos/dfu/src/FreeRTOSConfig.h new file mode 100644 index 000000000..e45891dac --- /dev/null +++ b/examples/freertos/dfu/src/FreeRTOSConfig.h @@ -0,0 +1,113 @@ +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/* Here is a good place to include header files that are required across +your application. */ +#include "platform.h" + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configUSE_TICKLESS_IDLE 0 +#define configCPU_CLOCK_HZ 100000000 +#define configNUM_CORES 5 +#define configTICK_RATE_HZ 1000 +#define configMAX_PRIORITIES 32 +#define configRUN_MULTIPLE_PRIORITIES 1 +#define configUSE_TASK_PREEMPTION_DISABLE 1 +#define configUSE_CORE_AFFINITY 1 +#define configMINIMAL_STACK_SIZE ( configSTACK_DEPTH_TYPE ) 1256 +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 2 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ +#define configQUEUE_REGISTRY_SIZE 10 +#define configUSE_QUEUE_SETS 1 +#define configUSE_TIME_SLICING 1 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 /* Required for FreeRTOS_TCP_WIN.c TODO: active closed bug, may have been fixed upstream */ +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 +#define configSTACK_DEPTH_TYPE uint32_t +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t + + +/* Memory allocation related definitions. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE 256*1024 +#define configAPPLICATION_ALLOCATED_HEAP 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_MINIMAL_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#define configUSE_CORE_INIT_HOOK 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 0 +#define configUSE_STATS_FORMATTING_FUNCTIONS 2 /* Setting to 2 does not include in tasks.c */ + +/* Co-routine related definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 1 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE << 2 ) + +/* Define to trap errors during development. */ +#define configASSERT(x) xassert(x) + +/* Define to enable debug_printf() */ +#define configENABLE_DEBUG_PRINTF 1 + +/* Define to map sprintf and snprintf to the + * lite versions in lib_rtos_support */ + #include +#define configUSE_DEBUG_SPRINTF 1 + +/* Define to enable debug prints from tasks.c */ +#if ON_TILE(0) +#define configTASKS_DEBUG 0 +#endif +#if ON_TILE(1) +#define configTASKS_DEBUG 0 +#endif + +/* FreeRTOS MPU specific definitions. */ +#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xResumeFromISR 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xEventGroupSetBitFromISR 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_xQueueGetMutexHolder 1 + +/* A header file that defines trace macro can be included here. */ +// #include "xcore_trace.h" + +#endif /* FREERTOS_CONFIG_H */ diff --git a/examples/freertos/dfu/src/app_conf.h b/examples/freertos/dfu/src/app_conf.h new file mode 100644 index 000000000..9d3762515 --- /dev/null +++ b/examples/freertos/dfu/src/app_conf.h @@ -0,0 +1,38 @@ +// Copyright 2022 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef APP_CONF_H_ +#define APP_CONF_H_ + +/* Intertile Communication Configuration */ +#define appconfI2C_MASTER_RPC_PORT 10 +#define appconfI2C_MASTER_RPC_PRIORITY (configMAX_PRIORITIES/2) + +#define appconfGPIO_T0_RPC_PORT 11 +#define appconfGPIO_T1_RPC_PORT 12 +#define appconfGPIO_RPC_PRIORITY (configMAX_PRIORITIES/2) + +/* I/O and interrupt cores for Tile 0 */ +#define appconfI2C_IO_CORE 4 /* Must be kept off core 0 with the RTOS tick ISR */ +#define appconfI2C_INTERRUPT_CORE 0 /* Must be kept off I/O cores. */ +#define appconfXUD_IO_CORE 1 /* Must be kept off core 0 with the RTOS tick ISR */ +#define appconfUSB_INTERRUPT_CORE 3 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ +#define appconfUSB_SOF_INTERRUPT_CORE 4 /* Must be kept off I/O cores. Best kept off cores with other ISRs. */ +#define appconfSPI_IO_CORE 4 /* Must be kept off core 0 with the RTOS tick ISR */ +#define appconfSPI_INTERRUPT_CORE 0 /* Must be kept off I/O cores. */ + +/* I/O and interrupt cores for Tile 1 */ +#define appconfUART_RX_IO_CORE 3 /* Must be kept off core 0 with the RTOS tick ISR */ +#define appconfUART_RX_INTERRUPT_CORE 4 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ + +/* UART Configuration */ +#define appconfUART_BAUD_RATE 806400 + +/* Task Priorities */ +#define appconfSTARTUP_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define appconfSPI_MASTER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define appconfQSPI_FLASH_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define appconfUART_RX_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define appconfUSB_MANAGER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) + +#endif /* APP_CONF_H_ */ diff --git a/examples/freertos/dfu/src/config.xscope b/examples/freertos/dfu/src/config.xscope new file mode 100644 index 000000000..bb71bfe23 --- /dev/null +++ b/examples/freertos/dfu/src/config.xscope @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/freertos/dfu/src/demo_main.h b/examples/freertos/dfu/src/demo_main.h new file mode 100644 index 000000000..27da62def --- /dev/null +++ b/examples/freertos/dfu/src/demo_main.h @@ -0,0 +1,9 @@ +// Copyright 2022 XMOS LIMITED. This Software is subject to the terms of the +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef DEMO_MAIN_H_ +#define DEMO_MAIN_H_ + +void create_tinyusb_demo(unsigned priority); + +#endif /* DEMO_MAIN_H_ */ diff --git a/examples/freertos/dfu/src/dfu_demo_support.c b/examples/freertos/dfu/src/dfu_demo_support.c new file mode 100644 index 000000000..c0f806eb1 --- /dev/null +++ b/examples/freertos/dfu/src/dfu_demo_support.c @@ -0,0 +1,114 @@ +// Copyright 2022 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +/* System headers */ +#include +#include + +/* FreeRTOS headers */ +#include "FreeRTOS.h" +#include "task.h" + +/* App headers */ +#include "rtos_usb.h" +#include "usb_support.h" +#include "platform/platform_init.h" +#include "platform/driver_instances.h" + +#if DFU_DEMO +#define QSPI_FLASH_SECTOR_SIZE 4096 +#define MODE_ADDR 0x200000 +static int mode = 0; +void write_dfu_mode(void); + +int check_dfu_mode(void) +{ + rtos_qspi_flash_read( + qspi_flash_ctx, + (uint8_t*)&mode, + (unsigned)(MODE_ADDR), + (size_t)sizeof(int)); + rtos_printf("Mode is %u\n", mode); + if(mode == 0xffffffff) mode = 0; // uninitialized should be handled as RT + return mode; +} + +void set_rt_mode(void) +{ + mode = 0; + write_dfu_mode(); +} + +void set_dfu_mode(void) +{ + mode = 1; + write_dfu_mode(); +} + +void write_dfu_mode(void) +{ + uint8_t *tmp_buf = rtos_osal_malloc( sizeof(uint8_t) * QSPI_FLASH_SECTOR_SIZE); + rtos_qspi_flash_lock(qspi_flash_ctx); + { + rtos_qspi_flash_read( + qspi_flash_ctx, + tmp_buf, + (unsigned)(MODE_ADDR), + (size_t)QSPI_FLASH_SECTOR_SIZE); + + memcpy(tmp_buf, &mode, sizeof(int)); + + rtos_qspi_flash_erase( + qspi_flash_ctx, + (unsigned)(MODE_ADDR), + (size_t)QSPI_FLASH_SECTOR_SIZE); + rtos_qspi_flash_write( + qspi_flash_ctx, + (uint8_t *) tmp_buf, + (unsigned)(MODE_ADDR), + (size_t)QSPI_FLASH_SECTOR_SIZE); + } + rtos_qspi_flash_unlock(qspi_flash_ctx); + + rtos_osal_free(tmp_buf); +} + +size_t boot_image_read(void* ctx, unsigned addr, uint8_t *buf, size_t len) +{ + rtos_qspi_flash_t *qspi = (rtos_qspi_flash_t *)ctx; + rtos_qspi_flash_read(qspi, buf, addr, len); + return len; +} + +size_t boot_image_write(void* ctx, unsigned addr, const uint8_t *buf, size_t len) +{ + rtos_qspi_flash_t *qspi = (rtos_qspi_flash_t *)ctx; + + uint8_t *tmp_buf = rtos_osal_malloc( sizeof(uint8_t) * QSPI_FLASH_SECTOR_SIZE); + rtos_qspi_flash_lock(qspi); + { + rtos_qspi_flash_read( + qspi, + tmp_buf, + (unsigned)(addr), + (size_t)QSPI_FLASH_SECTOR_SIZE); + + memcpy(tmp_buf, buf, len); + + rtos_qspi_flash_erase( + qspi, + (unsigned)(addr), + (size_t)QSPI_FLASH_SECTOR_SIZE); + rtos_qspi_flash_write( + qspi, + (uint8_t *) tmp_buf, + (unsigned)(addr), + (size_t)QSPI_FLASH_SECTOR_SIZE); + } + rtos_qspi_flash_unlock(qspi); + + rtos_osal_free(tmp_buf); + + return len; +} +#endif diff --git a/examples/freertos/dfu/src/main.c b/examples/freertos/dfu/src/main.c new file mode 100644 index 000000000..206856b06 --- /dev/null +++ b/examples/freertos/dfu/src/main.c @@ -0,0 +1,90 @@ +// Copyright 2022 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +/* System headers */ +#include +#include + +/* FreeRTOS headers */ +#include "FreeRTOS.h" +#include "queue.h" + +/* Library headers */ + +/* App headers */ +#include "app_conf.h" +#include "usb_support.h" +#include "xcore/channel_streaming.h" +#include "platform/platform_init.h" +#include "platform/driver_instances.h" + +void vApplicationMallocFailedHook( void ) +{ + rtos_printf("Malloc Failed on tile %d!\n", THIS_XCORE_TILE); + for(;;); +} + +void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) { + rtos_printf("\nStack Overflow!!! %d %s!\n", THIS_XCORE_TILE, pcTaskName); + configASSERT(0); +} + +#include "demo_main.h" + +void startup_task(void *arg) +{ + rtos_printf("Startup task running from tile %d on core %d\n", THIS_XCORE_TILE, portGET_CORE_ID()); + + platform_start(); + +#if ON_TILE(USB_TILE_NO) + create_tinyusb_demo(appconfSTARTUP_TASK_PRIORITY); +#endif + + for (;;) { + rtos_printf("Tile[%d]:\n\tMinimum heap free: %d\n\tCurrent heap free: %d\n", THIS_XCORE_TILE, xPortGetMinimumEverFreeHeapSize(), xPortGetFreeHeapSize()); + vTaskDelay(pdMS_TO_TICKS(5000)); + } +} + +void vApplicationMinimalIdleHook(void) +{ + rtos_printf("idle hook on tile %d core %d\n", THIS_XCORE_TILE, rtos_core_id_get()); + asm volatile("waiteu"); +} + +void tile_common_init(chanend_t c) +{ + platform_init(c); + chanend_free(c); + + xTaskCreate((TaskFunction_t) startup_task, + "startup_task", + RTOS_THREAD_STACK_SIZE(startup_task), + NULL, + appconfSTARTUP_TASK_PRIORITY, + NULL); + + rtos_printf("start scheduler on tile %d\n", THIS_XCORE_TILE); + vTaskStartScheduler(); +} + +#if ON_TILE(0) +void main_tile0(chanend_t c0, chanend_t c1, chanend_t c2, chanend_t c3) { + (void)c0; + (void)c2; + (void)c3; + + tile_common_init(c1); +} +#endif + +#if ON_TILE(1) +void main_tile1(chanend_t c0, chanend_t c1, chanend_t c2, chanend_t c3) { + (void)c1; + (void)c2; + (void)c3; + + tile_common_init(c0); +} +#endif diff --git a/examples/freertos/dfu/src/tusb_config.h b/examples/freertos/dfu/src/tusb_config.h new file mode 100644 index 000000000..0dd5aeeda --- /dev/null +++ b/examples/freertos/dfu/src/tusb_config.h @@ -0,0 +1,50 @@ +// Copyright (c) 2022 XMOS LIMITED. This Software is subject to the terms of the +// XMOS Public License: Version 1 + +#ifndef TUSB_CONFIG_H_ +#define TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "app_conf.h" + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) +#define CFG_TUSB_OS OPT_OS_CUSTOM + +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) + +#define CFG_TUSB_DEBUG_PRINTF rtos_printf + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#define CFG_TUD_EP_MAX 12 +#define CFG_TUD_TASK_QUEUE_SZ 8 +#define CFG_TUD_ENDPOINT0_SIZE 64 + +#define CFG_TUD_XCORE_INTERRUPT_CORE appconfUSB_INTERRUPT_CORE +#define CFG_TUD_XCORE_SOF_INTERRUPT_CORE appconfUSB_SOF_INTERRUPT_CORE +#define CFG_TUD_XCORE_IO_CORE_MASK (1 << appconfXUD_IO_CORE) + +//------------- CLASS -------------// +#define CFG_TUD_DFU 1 + +// DFU buffer size, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR +#define CFG_TUD_DFU_XFER_BUFSIZE ( OPT_MODE_HIGH_SPEED ? 512 : 64 ) + +#ifdef __cplusplus + } +#endif + +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/freertos/dfu/src/usb/demo_main.c b/examples/freertos/dfu/src/usb/demo_main.c new file mode 100644 index 000000000..f26218f9e --- /dev/null +++ b/examples/freertos/dfu/src/usb/demo_main.c @@ -0,0 +1,294 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#include +#include +#include + +#include "FreeRTOS.h" +#include "timers.h" +#include "platform/driver_instances.h" +#include "demo_main.h" +#include "tusb.h" + +/* + * After device is enumerated in dfu mode run the following commands + * + * To transfer firmware from host to device (best to test with text file) + * + * $ dfu-util -d cafe -a 0 -D [filename] + * $ dfu-util -d cafe -a 1 -D [filename] + * + * To transfer firmware from device to host: + * + * $ dfu-util -d cafe -a 0 -U [filename] + * $ dfu-util -d cafe -a 1 -U [filename] + * + */ + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ +const char* upload_image[2]= +{ + "Hello world from TinyUSB DFU! - Partition 0", + "Hello world from TinyUSB DFU! - Partition 1" +}; + +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +static TimerHandle_t blinky_timer_ctx = NULL; +static rtos_gpio_port_id_t led_port = 0; +static uint32_t led_val = 0; +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + + +static void reboot(void); + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) +{ + if(blinky_timer_ctx != NULL) + xTimerChangePeriod(blinky_timer_ctx, pdMS_TO_TICKS(BLINK_MOUNTED), 0); +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + if(blinky_timer_ctx != NULL) + xTimerChangePeriod(blinky_timer_ctx, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) +{ + (void) remote_wakeup_en; + if(blinky_timer_ctx != NULL) + xTimerChangePeriod(blinky_timer_ctx, pdMS_TO_TICKS(BLINK_SUSPENDED), 0); +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + if(blinky_timer_ctx != NULL) + xTimerChangePeriod(blinky_timer_ctx, pdMS_TO_TICKS(BLINK_MOUNTED), 0); +} + +//--------------------------------------------------------------------+ +// DFU callbacks +// Note: alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. +//--------------------------------------------------------------------+ + +static size_t total_len = 0; +static size_t bytes_avail = 0; +static uint32_t dn_base_addr = 0; + +// Invoked right before tud_dfu_download_cb() (state=DFU_DNBUSY) or tud_dfu_manifest_cb() (state=DFU_MANIFEST) +// Application return timeout in milliseconds (bwPollTimeout) for the next download/manifest operation. +// During this period, USB host won't try to communicate with us. +uint32_t tud_dfu_get_timeout_cb(uint8_t alt, uint8_t state) +{ + if ( state == DFU_DNBUSY ) + { + // For this example + // - Atl0 Flash is fast : 10 ms + // - Alt1 EEPROM is slow: 100 ms + return (alt == 0) ? 10 : 100; + } + else if (state == DFU_MANIFEST) + { + // since we don't buffer entire image and do any flashing in manifest stage + return 0; + } + + return 0; +} + +// Invoked when received DFU_DNLOAD (wLength>0) following by DFU_GETSTATUS (state=DFU_DNBUSY) requests +// This callback could be returned before flashing op is complete (async). +// Once finished flashing, application must call tud_dfu_finish_flashing() +void tud_dfu_download_cb(uint8_t alt, uint16_t block_num, uint8_t const* data, uint16_t length) +{ + // (void) alt; + // (void) block_num; + + rtos_printf("Received Alt %d BlockNum %d of length %d\n", alt, block_num, length); + + // if (dn_base_addr == 0) + // { + // uint32_t addr = 0; + // total_len = 0; + // int tmp = boot_image_locate_available_spot(bim_ctx_ptr, &addr, &bytes_avail); + // if(tmp == -1) + // { + // boot_image_t* imgptr = NULL; + // imgptr = boot_image_get_last_image(bim_ctx_ptr); + // addr = imgptr->startAddress; + // bytes_avail = bim_ctx_ptr->boot_partition_size - addr; + // } + // rtos_printf("Using addr 0x%x\nsize %u\n", addr, bytes_avail); + // dn_base_addr = addr; + // } + + // if(length > 0) + // { + // unsigned cur_addr = dn_base_addr + (block_num * bim_ctx_ptr->page_size); + // if((bytes_avail - total_len) >= length) + // { + // // rtos_printf("write %d at 0x%x\n", length, cur_addr); + // boot_image_write(bim_ctx_ptr->app_data, cur_addr, data, length); + // total_len += length; + // } else { + // rtos_printf("Insufficient space\n"); + // } + // } + + // flashing op for download complete without error + tud_dfu_finish_flashing(DFU_STATUS_OK); +} + +// Invoked when download process is complete, received DFU_DNLOAD (wLength=0) following by DFU_GETSTATUS (state=Manifest) +// Application can do checksum, or actual flashing if buffered entire image previously. +// Once finished flashing, application must call tud_dfu_finish_flashing() +void tud_dfu_manifest_cb(uint8_t alt) +{ + (void) alt; + rtos_printf("Download completed, enter manifestation\n"); + + // flashing op for manifest is complete without error + // Application can perform checksum, should it fail, use appropriate status such as errVERIFY. + tud_dfu_finish_flashing(DFU_STATUS_OK); + + // rtos_printf("Pass firmware validity check addr 0x%x size %u\n", dn_base_addr, total_len); + // set_rt_mode(); + // boot_image_read(bim_ctx_ptr->app_data, 0, &dummy, sizeof(dummy)); // dummy read to ensure flash writes have completed + // reboot(); +} + +// Invoked when received DFU_UPLOAD request +// Application must populate data with up to length bytes and +// Return the number of written bytes +uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length) +{ + (void) block_num; + (void) length; + + uint16_t const xfer_len = (uint16_t) strlen(upload_image[alt]); + memcpy(data, upload_image[alt], xfer_len); + + return xfer_len; + +// (void) alt; + +// memset(data, 0x00, length); +// uint32_t addr = block_num * FLASH_PAGE_SIZE; +// uint32_t endaddr; + +// #if 0 +// // Test code which will just read out all of flash rather than a specific image +// endaddr = 0x800000; +// #else +// boot_image_t* imgptr = NULL; +// imgptr = boot_image_get_last_image(bim_ctx_ptr); +// addr += imgptr->startAddress; +// endaddr = imgptr->startAddress + imgptr->size; +// #endif +// return (addr >= endaddr) ? 0 : (uint16_t)boot_image_read(bim_ctx_ptr->app_data, addr, data, length); + + +} + +// Invoked when the Host has terminated a download or upload transfer +void tud_dfu_abort_cb(uint8_t alt) +{ + (void) alt; + rtos_printf("Host aborted transfer\n"); + // set_rt_mode(); + // boot_image_read(bim_ctx_ptr->app_data, 0, &dummy, sizeof(dummy)); // dummy read to ensure flash writes have completed +} + +// Invoked when a DFU_DETACH request is received +void tud_dfu_detach_cb(void) +{ + rtos_printf("Host detach, we should probably reboot\n"); + // set_rt_mode(); + reboot(); +} + +void tud_dfu_runtime_reboot_to_dfu_cb(void) +{ + rtos_printf("Host detach, reboot\n"); + // set_dfu_mode(); + reboot(); +} + +static void reboot(void) +{ + rtos_printf("Reboot initiated by tile:0x%x\n", get_local_tile_id()); + write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_COUNT_NUM, 0x10000); + write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_CFG_NUM, (1 << XS1_WATCHDOG_COUNT_ENABLE_SHIFT) | (1 << XS1_WATCHDOG_TRIGGER_ENABLE_SHIFT) ); + while(1) {;} +} + +//--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ + +void led_blinky_cb(TimerHandle_t xTimer) +{ + (void) xTimer; + led_val ^= 1; + + rtos_gpio_port_out(gpio_ctx_t0, led_port, led_val); +} + +void create_tinyusb_demo(unsigned priority) +{ + led_port = rtos_gpio_port(PORT_LEDS); + rtos_gpio_port_enable(gpio_ctx_t0, led_port); + rtos_gpio_port_out(gpio_ctx_t0, led_port, led_val); + + blinky_timer_ctx = xTimerCreate("blinky", + pdMS_TO_TICKS(blink_interval_ms), + pdTRUE, + NULL, + led_blinky_cb); + xTimerStart(blinky_timer_ctx, 0); +} diff --git a/examples/freertos/dfu/src/usb/usb_descriptors.c b/examples/freertos/dfu/src/usb/usb_descriptors.c new file mode 100644 index 000000000..350334aa5 --- /dev/null +++ b/examples/freertos/dfu/src/usb/usb_descriptors.c @@ -0,0 +1,171 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#include "tusb.h" +#include "class/dfu/dfu_device.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + #if CFG_TUD_CDC + // Use Interface Association Descriptor (IAD) for CDC + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + #else + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + #endif + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) +{ + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ + +// Number of Alternate Interface (each for 1 flash partition) +#define ALT_COUNT 2 + +enum +{ + ITF_NUM_DFU_MODE, + ITF_NUM_TOTAL +}; + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_DESC_LEN(ALT_COUNT)) + +#define FUNC_ATTRS (DFU_ATTR_CAN_UPLOAD | DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_MANIFESTATION_TOLERANT) + +uint8_t const desc_configuration[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + + // Interface number, Alternate count, starting string index, attributes, detach timeout, transfer size + TUD_DFU_DESCRIPTOR(ITF_NUM_DFU_MODE, ALT_COUNT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), +}; + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + return desc_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// array of pointer to string descriptors +char const* string_desc_arr [] = +{ + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + "123456", // 3: Serials, should use chip ID + "FLASH", // 4: DFU Partition 1 + "EEPROM", // 5: DFU Partition 2 +}; + +static uint16_t _desc_str[32]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + (void) langid; + + size_t chr_count; + + if ( index == 0) + { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + } + else + { + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors + + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + + const char* str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + if ( chr_count > 31 ) { + chr_count = 31; + } + + // Convert ASCII string into UTF-16 + for(uint8_t i=0; i Date: Tue, 8 Nov 2022 14:17:18 -0500 Subject: [PATCH 03/23] Fix align bug between tusb and xud --- .../freertos/dfu/bsp_config/CMakeLists.txt | 1 + examples/freertos/dfu/src/tusb_config.h | 5 ++- .../freertos/dfu/src/usb/usb_descriptors.c | 45 ++++++++++++++----- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/examples/freertos/dfu/bsp_config/CMakeLists.txt b/examples/freertos/dfu/bsp_config/CMakeLists.txt index 3610d0df2..d79885056 100644 --- a/examples/freertos/dfu/bsp_config/CMakeLists.txt +++ b/examples/freertos/dfu/bsp_config/CMakeLists.txt @@ -15,6 +15,7 @@ target_link_libraries(example_freertos_dfu_board_support_config_xcore_ai_explore core::general rtos::freertos rtos::drivers::general + rtos::drivers::usb rtos::sw_services::usb ) target_compile_definitions(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0 diff --git a/examples/freertos/dfu/src/tusb_config.h b/examples/freertos/dfu/src/tusb_config.h index 0dd5aeeda..6acb2a953 100644 --- a/examples/freertos/dfu/src/tusb_config.h +++ b/examples/freertos/dfu/src/tusb_config.h @@ -21,7 +21,7 @@ #define CFG_TUSB_DEBUG 0 #endif -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(8))) #define CFG_TUSB_DEBUG_PRINTF rtos_printf @@ -38,7 +38,8 @@ #define CFG_TUD_XCORE_IO_CORE_MASK (1 << appconfXUD_IO_CORE) //------------- CLASS -------------// -#define CFG_TUD_DFU 1 +#define CFG_TUD_DFU 1 +#define CFG_TUD_DFU_RUNTIME 1 // DFU buffer size, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR #define CFG_TUD_DFU_XFER_BUFSIZE ( OPT_MODE_HIGH_SPEED ? 512 : 64 ) diff --git a/examples/freertos/dfu/src/usb/usb_descriptors.c b/examples/freertos/dfu/src/usb/usb_descriptors.c index 350334aa5..bed671713 100644 --- a/examples/freertos/dfu/src/usb/usb_descriptors.c +++ b/examples/freertos/dfu/src/usb/usb_descriptors.c @@ -82,25 +82,44 @@ uint8_t const * tud_descriptor_device_cb(void) //--------------------------------------------------------------------+ // Number of Alternate Interface (each for 1 flash partition) -#define ALT_COUNT 2 +#define ALT_COUNT 1 enum { - ITF_NUM_DFU_MODE, - ITF_NUM_TOTAL + ITF0_NUM_DFU_RT, + ITF0_NUM_TOTAL }; -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_DESC_LEN(ALT_COUNT)) +#define CONFIG_0_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_RT_DESC_LEN) -#define FUNC_ATTRS (DFU_ATTR_CAN_UPLOAD | DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_MANIFESTATION_TOLERANT) +enum +{ + ITF1_NUM_DFU_MODE, + ITF1_NUM_TOTAL +}; + +#define CONFIG_1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_DESC_LEN(ALT_COUNT) ) + +#define FUNC_ATTRS (DFU_ATTR_CAN_UPLOAD | DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_WILL_DETACH | DFU_ATTR_MANIFESTATION_TOLERANT) + +uint8_t const desc_configuration_rt[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF0_NUM_TOTAL, 0, CONFIG_0_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + + // Interface number, string index, attributes, detach timeout, transfer size */ + TUD_DFU_RT_DESCRIPTOR(ITF0_NUM_DFU_RT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), -uint8_t const desc_configuration[] = + // TUD_DFU_RT_DESCRIPTOR(ITF0_NUM_DFU_RT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), +}; + +uint8_t const desc_configuration_mode[] = { // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + TUD_CONFIG_DESCRIPTOR(1, ITF1_NUM_TOTAL, 0, CONFIG_1_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), - // Interface number, Alternate count, starting string index, attributes, detach timeout, transfer size - TUD_DFU_DESCRIPTOR(ITF_NUM_DFU_MODE, ALT_COUNT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), + // Interface number, alt count, string index, attributes, detach timeout, transfer size */ + TUD_DFU_DESCRIPTOR(ITF1_NUM_DFU_MODE, ALT_COUNT, 5, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), }; // Invoked when received GET CONFIGURATION DESCRIPTOR @@ -109,7 +128,9 @@ uint8_t const desc_configuration[] = uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations - return desc_configuration; + return desc_configuration_mode; + // return check_dfu_mode() ? desc_configuration_rt : desc_configuration_mode; + } //--------------------------------------------------------------------+ @@ -123,8 +144,8 @@ char const* string_desc_arr [] = "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product "123456", // 3: Serials, should use chip ID - "FLASH", // 4: DFU Partition 1 - "EEPROM", // 5: DFU Partition 2 + "TinyUSB DFU runtime", // 4: DFU runtime + "TinyUSB DFU device", // 5: DFU device }; static uint16_t _desc_str[32]; From e29c1ddfa113fc952443fe001946d65509cbe763 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Wed, 9 Nov 2022 17:30:53 -0500 Subject: [PATCH 04/23] Update rtos submodule --- modules/rtos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/rtos b/modules/rtos index 463f55cc4..5bd462749 160000 --- a/modules/rtos +++ b/modules/rtos @@ -1 +1 @@ -Subproject commit 463f55cc46e5e8ab06071ad6bcd010c893a4d43d +Subproject commit 5bd462749b334ab71938f611f978220dfb792dea From 8ed15c171b539bba8b4ee7d43197113fbac74364 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Wed, 9 Nov 2022 17:32:51 -0500 Subject: [PATCH 05/23] Add dfu example over usb --- .../freertos/dfu/bsp_config/CMakeLists.txt | 2 + .../platform/driver_instances.c | 5 +- .../platform/driver_instances.h | 3 +- .../platform/platform_init.c | 13 +- examples/freertos/dfu/dfu.cmake | 3 +- examples/freertos/dfu/src/demo_main.h | 9 - examples/freertos/dfu/src/dfu_demo_support.c | 114 ------- examples/freertos/dfu/src/main.c | 6 - examples/freertos/dfu/src/tusb_config.h | 3 +- examples/freertos/dfu/src/usb/app_dfu.c | 249 +++++++++++++++ examples/freertos/dfu/src/usb/demo_main.c | 294 ------------------ .../freertos/dfu/src/usb/usb_descriptors.c | 42 +-- 12 files changed, 281 insertions(+), 462 deletions(-) delete mode 100644 examples/freertos/dfu/src/demo_main.h delete mode 100644 examples/freertos/dfu/src/dfu_demo_support.c create mode 100644 examples/freertos/dfu/src/usb/app_dfu.c delete mode 100644 examples/freertos/dfu/src/usb/demo_main.c diff --git a/examples/freertos/dfu/bsp_config/CMakeLists.txt b/examples/freertos/dfu/bsp_config/CMakeLists.txt index d79885056..e7321512e 100644 --- a/examples/freertos/dfu/bsp_config/CMakeLists.txt +++ b/examples/freertos/dfu/bsp_config/CMakeLists.txt @@ -16,7 +16,9 @@ target_link_libraries(example_freertos_dfu_board_support_config_xcore_ai_explore rtos::freertos rtos::drivers::general rtos::drivers::usb + rtos::drivers::dfu_image rtos::sw_services::usb + ) target_compile_definitions(example_freertos_dfu_board_support_config_xcore_ai_explorer_2V0 INTERFACE diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.c b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.c index f7b119809..d5344d6e2 100644 --- a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.c +++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.c @@ -28,4 +28,7 @@ static rtos_uart_tx_t uart_tx_ctx_s; rtos_uart_tx_t *uart_tx_ctx = &uart_tx_ctx_s; static rtos_uart_rx_t uart_rx_ctx_s; -rtos_uart_rx_t *uart_rx_ctx = &uart_rx_ctx_s; \ No newline at end of file +rtos_uart_rx_t *uart_rx_ctx = &uart_rx_ctx_s; + +static rtos_dfu_image_t dfu_image_ctx_s; +rtos_dfu_image_t *dfu_image_ctx = &dfu_image_ctx_s; diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.h b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.h index 1a92103e9..ee4a4d65a 100644 --- a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.h +++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/driver_instances.h @@ -8,6 +8,7 @@ #include "rtos_i2c_master.h" #include "rtos_spi_master.h" #include "rtos_qspi_flash.h" +#include "rtos_dfu_image.h" #include "rtos_gpio.h" #include "rtos_uart_tx.h" #include "rtos_uart_rx.h" @@ -40,6 +41,6 @@ extern rtos_gpio_t *gpio_ctx_t1; extern rtos_i2c_master_t *i2c_master_ctx; extern rtos_uart_tx_t *uart_tx_ctx; extern rtos_uart_rx_t *uart_rx_ctx; - +extern rtos_dfu_image_t *dfu_image_ctx; #endif /* DRIVER_INSTANCES_H_ */ diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c index bc774bd23..b3b0d0f34 100644 --- a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c +++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c @@ -2,13 +2,22 @@ // XMOS Public License: Version 1 #include +#include #include "platform_conf.h" #include "platform/driver_instances.h" - +#include +#include static void flash_init(void) { #if ON_TILE(FLASH_TILE_NO) + rtos_dfu_image_init( + dfu_image_ctx, + FLASH_CLKBLK, + PORT_SQI_CS, + PORT_SQI_SCLK, + PORT_SQI_SIO); + qspi_flash_ctx->ctx.sfdp_skip = true; qspi_flash_ctx->ctx.sfdp_supported = false; qspi_flash_ctx->ctx.page_size_bytes = 256; @@ -53,7 +62,7 @@ static void flash_init(void) qspi_io_sample_edge_falling, 0, - qspi_flash_page_program_1_4_4); + qspi_flash_page_program_1_1_4); #endif } diff --git a/examples/freertos/dfu/dfu.cmake b/examples/freertos/dfu/dfu.cmake index c897ebfbf..39f383081 100644 --- a/examples/freertos/dfu/dfu.cmake +++ b/examples/freertos/dfu/dfu.cmake @@ -17,7 +17,6 @@ set(APP_COMPILER_FLAGS -g -report -fxscope - -lquadspi -mcmodel=large -Wno-xcore-fptrgroup ${CMAKE_CURRENT_LIST_DIR}/src/config.xscope @@ -32,7 +31,7 @@ set(APP_COMPILE_DEFINITIONS ) set(APP_LINK_OPTIONS - -lquadspi + -lquadflash -fxscope -report ${CMAKE_CURRENT_LIST_DIR}/XCORE-AI-EXPLORER.xn diff --git a/examples/freertos/dfu/src/demo_main.h b/examples/freertos/dfu/src/demo_main.h deleted file mode 100644 index 27da62def..000000000 --- a/examples/freertos/dfu/src/demo_main.h +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2022 XMOS LIMITED. This Software is subject to the terms of the -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - -#ifndef DEMO_MAIN_H_ -#define DEMO_MAIN_H_ - -void create_tinyusb_demo(unsigned priority); - -#endif /* DEMO_MAIN_H_ */ diff --git a/examples/freertos/dfu/src/dfu_demo_support.c b/examples/freertos/dfu/src/dfu_demo_support.c deleted file mode 100644 index c0f806eb1..000000000 --- a/examples/freertos/dfu/src/dfu_demo_support.c +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2022 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - -/* System headers */ -#include -#include - -/* FreeRTOS headers */ -#include "FreeRTOS.h" -#include "task.h" - -/* App headers */ -#include "rtos_usb.h" -#include "usb_support.h" -#include "platform/platform_init.h" -#include "platform/driver_instances.h" - -#if DFU_DEMO -#define QSPI_FLASH_SECTOR_SIZE 4096 -#define MODE_ADDR 0x200000 -static int mode = 0; -void write_dfu_mode(void); - -int check_dfu_mode(void) -{ - rtos_qspi_flash_read( - qspi_flash_ctx, - (uint8_t*)&mode, - (unsigned)(MODE_ADDR), - (size_t)sizeof(int)); - rtos_printf("Mode is %u\n", mode); - if(mode == 0xffffffff) mode = 0; // uninitialized should be handled as RT - return mode; -} - -void set_rt_mode(void) -{ - mode = 0; - write_dfu_mode(); -} - -void set_dfu_mode(void) -{ - mode = 1; - write_dfu_mode(); -} - -void write_dfu_mode(void) -{ - uint8_t *tmp_buf = rtos_osal_malloc( sizeof(uint8_t) * QSPI_FLASH_SECTOR_SIZE); - rtos_qspi_flash_lock(qspi_flash_ctx); - { - rtos_qspi_flash_read( - qspi_flash_ctx, - tmp_buf, - (unsigned)(MODE_ADDR), - (size_t)QSPI_FLASH_SECTOR_SIZE); - - memcpy(tmp_buf, &mode, sizeof(int)); - - rtos_qspi_flash_erase( - qspi_flash_ctx, - (unsigned)(MODE_ADDR), - (size_t)QSPI_FLASH_SECTOR_SIZE); - rtos_qspi_flash_write( - qspi_flash_ctx, - (uint8_t *) tmp_buf, - (unsigned)(MODE_ADDR), - (size_t)QSPI_FLASH_SECTOR_SIZE); - } - rtos_qspi_flash_unlock(qspi_flash_ctx); - - rtos_osal_free(tmp_buf); -} - -size_t boot_image_read(void* ctx, unsigned addr, uint8_t *buf, size_t len) -{ - rtos_qspi_flash_t *qspi = (rtos_qspi_flash_t *)ctx; - rtos_qspi_flash_read(qspi, buf, addr, len); - return len; -} - -size_t boot_image_write(void* ctx, unsigned addr, const uint8_t *buf, size_t len) -{ - rtos_qspi_flash_t *qspi = (rtos_qspi_flash_t *)ctx; - - uint8_t *tmp_buf = rtos_osal_malloc( sizeof(uint8_t) * QSPI_FLASH_SECTOR_SIZE); - rtos_qspi_flash_lock(qspi); - { - rtos_qspi_flash_read( - qspi, - tmp_buf, - (unsigned)(addr), - (size_t)QSPI_FLASH_SECTOR_SIZE); - - memcpy(tmp_buf, buf, len); - - rtos_qspi_flash_erase( - qspi, - (unsigned)(addr), - (size_t)QSPI_FLASH_SECTOR_SIZE); - rtos_qspi_flash_write( - qspi, - (uint8_t *) tmp_buf, - (unsigned)(addr), - (size_t)QSPI_FLASH_SECTOR_SIZE); - } - rtos_qspi_flash_unlock(qspi); - - rtos_osal_free(tmp_buf); - - return len; -} -#endif diff --git a/examples/freertos/dfu/src/main.c b/examples/freertos/dfu/src/main.c index 206856b06..7893b2020 100644 --- a/examples/freertos/dfu/src/main.c +++ b/examples/freertos/dfu/src/main.c @@ -29,18 +29,12 @@ void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) { configASSERT(0); } -#include "demo_main.h" - void startup_task(void *arg) { rtos_printf("Startup task running from tile %d on core %d\n", THIS_XCORE_TILE, portGET_CORE_ID()); platform_start(); -#if ON_TILE(USB_TILE_NO) - create_tinyusb_demo(appconfSTARTUP_TASK_PRIORITY); -#endif - for (;;) { rtos_printf("Tile[%d]:\n\tMinimum heap free: %d\n\tCurrent heap free: %d\n", THIS_XCORE_TILE, xPortGetMinimumEverFreeHeapSize(), xPortGetFreeHeapSize()); vTaskDelay(pdMS_TO_TICKS(5000)); diff --git a/examples/freertos/dfu/src/tusb_config.h b/examples/freertos/dfu/src/tusb_config.h index 6acb2a953..21fe4c315 100644 --- a/examples/freertos/dfu/src/tusb_config.h +++ b/examples/freertos/dfu/src/tusb_config.h @@ -39,10 +39,9 @@ //------------- CLASS -------------// #define CFG_TUD_DFU 1 -#define CFG_TUD_DFU_RUNTIME 1 // DFU buffer size, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR -#define CFG_TUD_DFU_XFER_BUFSIZE ( OPT_MODE_HIGH_SPEED ? 512 : 64 ) +#define CFG_TUD_DFU_XFER_BUFSIZE 4096 #ifdef __cplusplus } diff --git a/examples/freertos/dfu/src/usb/app_dfu.c b/examples/freertos/dfu/src/usb/app_dfu.c new file mode 100644 index 000000000..95641911e --- /dev/null +++ b/examples/freertos/dfu/src/usb/app_dfu.c @@ -0,0 +1,249 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#include +#include +#include +#include + +#include "FreeRTOS.h" +#include "timers.h" +#include "platform/driver_instances.h" +#include "demo_main.h" +#include "tusb.h" + +/* + * After device is enumerated in dfu mode run the following commands + * + * To transfer firmware from host to device (best to test with text file) + * + * $ dfu-util -d cafe -a 0 -D [filename] + * $ dfu-util -d cafe -a 1 -D [filename] + * + * To transfer firmware from device to host: + * + * $ dfu-util -d cafe -a 0 -U [filename] + * $ dfu-util -d cafe -a 1 -U [filename] + * + */ + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ +static void reboot(void); + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) +{ + rtos_printf("mounted\n"); +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + rtos_printf("unmounted\n"); +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) +{ + (void) remote_wakeup_en; + rtos_printf("suspended\n"); +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + rtos_printf("resumed\n"); +} + +//--------------------------------------------------------------------+ +// DFU callbacks +// Note: alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. +//--------------------------------------------------------------------+ + +static size_t total_len = 0; +static size_t bytes_avail = 0; +static uint32_t dn_base_addr = 0; + +// Invoked right before tud_dfu_download_cb() (state=DFU_DNBUSY) or tud_dfu_manifest_cb() (state=DFU_MANIFEST) +// Application return timeout in milliseconds (bwPollTimeout) for the next download/manifest operation. +// During this period, USB host won't try to communicate with us. +uint32_t tud_dfu_get_timeout_cb(uint8_t alt, uint8_t state) +{ + if ( state == DFU_DNBUSY ) { + return 10; // 10 ms + } else if (state == DFU_MANIFEST) { + // since we don't buffer entire image and do any flashing in manifest stage + return 0; + } + + return 0; +} + +// Invoked when received DFU_DNLOAD (wLength>0) following by DFU_GETSTATUS (state=DFU_DNBUSY) requests +// This callback could be returned before flashing op is complete (async). +// Once finished flashing, application must call tud_dfu_finish_flashing() +void tud_dfu_download_cb(uint8_t alt, uint16_t block_num, uint8_t const* data, uint16_t length) +{ + rtos_printf("Received Alt %d BlockNum %d of length %d\n", alt, block_num, length); + + unsigned data_partition_base_addr = rtos_dfu_image_get_data_partition_addr(dfu_image_ctx); + switch(alt) { + default: + case 0: + tud_dfu_finish_flashing(DFU_STATUS_ERR_WRITE); + break; + case 1: + if (dn_base_addr == 0) { + total_len = 0; + dn_base_addr = rtos_dfu_image_get_upgrade_addr(dfu_image_ctx); + bytes_avail = data_partition_base_addr - dn_base_addr; + rtos_printf("Using addr 0x%x\nsize %u\n", dn_base_addr, bytes_avail); + } + if(length > 0) { + unsigned cur_addr = dn_base_addr + (block_num * CFG_TUD_DFU_XFER_BUFSIZE); + if((bytes_avail - total_len) >= length) { + rtos_printf("write %d at 0x%x\n", length, cur_addr); + + size_t sector_size = rtos_qspi_flash_sector_size_get(qspi_flash_ctx); + xassert(CFG_TUD_DFU_XFER_BUFSIZE == sector_size); + + uint8_t *tmp_buf = rtos_osal_malloc( sizeof(uint8_t) * sector_size); + rtos_qspi_flash_lock(qspi_flash_ctx); + { + rtos_qspi_flash_read( + qspi_flash_ctx, + tmp_buf, + cur_addr, + sector_size); + memcpy(tmp_buf, data, length); + rtos_qspi_flash_erase( + qspi_flash_ctx, + cur_addr, + sector_size); + rtos_qspi_flash_write( + qspi_flash_ctx, + (uint8_t *) tmp_buf, + cur_addr, + sector_size); + } + rtos_qspi_flash_unlock(qspi_flash_ctx); + rtos_osal_free(tmp_buf); + total_len += length; + } else { + rtos_printf("Insufficient space\n"); + tud_dfu_finish_flashing(DFU_STATUS_ERR_ADDRESS); + } + } + + tud_dfu_finish_flashing(DFU_STATUS_OK); + break; + } +} + +// Invoked when download process is complete, received DFU_DNLOAD (wLength=0) following by DFU_GETSTATUS (state=Manifest) +// Application can do checksum, or actual flashing if buffered entire image previously. +// Once finished flashing, application must call tud_dfu_finish_flashing() +void tud_dfu_manifest_cb(uint8_t alt) +{ + (void) alt; + rtos_printf("Download completed, enter manifestation\n"); + + /* Perform a read to ensure all writes have been flushed */ + uint32_t dummy = 0; + rtos_qspi_flash_read( + qspi_flash_ctx, + (uint8_t *)&dummy, + 0, + sizeof(dummy)); + + // flashing op for manifest is complete without error + // Application can perform checksum, should it fail, use appropriate status such as errVERIFY. + tud_dfu_finish_flashing(DFU_STATUS_OK); +} + +// Invoked when received DFU_UPLOAD request +// Application must populate data with up to length bytes and +// Return the number of written bytes +uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length) +{ + uint32_t endaddr = 0; + uint16_t retval = 0; + uint32_t addr = block_num * CFG_TUD_DFU_XFER_BUFSIZE; + + rtos_printf("Upload Alt %d BlockNum %d of length %d\n", alt, block_num, length); + + switch(alt) { + default: + break; + case 0: + if (rtos_dfu_image_get_factory_size(dfu_image_ctx) > 0) { + addr += rtos_dfu_image_get_factory_addr(dfu_image_ctx); + endaddr = rtos_dfu_image_get_factory_addr(dfu_image_ctx) + rtos_dfu_image_get_factory_size(dfu_image_ctx); + } + break; + case 1: + if (rtos_dfu_image_get_upgrade_size(dfu_image_ctx) > 0) { + addr += rtos_dfu_image_get_upgrade_addr(dfu_image_ctx); + endaddr = rtos_dfu_image_get_upgrade_addr(dfu_image_ctx) + rtos_dfu_image_get_upgrade_size(dfu_image_ctx); + } + break; + } + + if (addr < endaddr) { + rtos_qspi_flash_read(qspi_flash_ctx, data, addr, length); + retval = length; + } + return retval; +} + +// Invoked when the Host has terminated a download or upload transfer +void tud_dfu_abort_cb(uint8_t alt) +{ + (void) alt; + rtos_printf("Host aborted transfer\n"); +} + +// Invoked when a DFU_DETACH request is received +void tud_dfu_detach_cb(void) +{ + rtos_printf("Host detach, we should probably reboot\n"); + reboot(); +} + +static void reboot(void) +{ + rtos_printf("Reboot initiated by tile:0x%x\n", get_local_tile_id()); + write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_COUNT_NUM, 0x10000); + write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_CFG_NUM, (1 << XS1_WATCHDOG_COUNT_ENABLE_SHIFT) | (1 << XS1_WATCHDOG_TRIGGER_ENABLE_SHIFT) ); + while(1) {;} +} diff --git a/examples/freertos/dfu/src/usb/demo_main.c b/examples/freertos/dfu/src/usb/demo_main.c deleted file mode 100644 index f26218f9e..000000000 --- a/examples/freertos/dfu/src/usb/demo_main.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 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. - * - */ - -#include -#include -#include - -#include "FreeRTOS.h" -#include "timers.h" -#include "platform/driver_instances.h" -#include "demo_main.h" -#include "tusb.h" - -/* - * After device is enumerated in dfu mode run the following commands - * - * To transfer firmware from host to device (best to test with text file) - * - * $ dfu-util -d cafe -a 0 -D [filename] - * $ dfu-util -d cafe -a 1 -D [filename] - * - * To transfer firmware from device to host: - * - * $ dfu-util -d cafe -a 0 -U [filename] - * $ dfu-util -d cafe -a 1 -U [filename] - * - */ - -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF PROTYPES -//--------------------------------------------------------------------+ -const char* upload_image[2]= -{ - "Hello world from TinyUSB DFU! - Partition 0", - "Hello world from TinyUSB DFU! - Partition 1" -}; - -/* Blink pattern - * - 250 ms : device not mounted - * - 1000 ms : device mounted - * - 2500 ms : device is suspended - */ -enum { - BLINK_NOT_MOUNTED = 250, - BLINK_MOUNTED = 1000, - BLINK_SUSPENDED = 2500, -}; - -static TimerHandle_t blinky_timer_ctx = NULL; -static rtos_gpio_port_id_t led_port = 0; -static uint32_t led_val = 0; -static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; - - -static void reboot(void); - -//--------------------------------------------------------------------+ -// Device callbacks -//--------------------------------------------------------------------+ - -// Invoked when device is mounted -void tud_mount_cb(void) -{ - if(blinky_timer_ctx != NULL) - xTimerChangePeriod(blinky_timer_ctx, pdMS_TO_TICKS(BLINK_MOUNTED), 0); -} - -// Invoked when device is unmounted -void tud_umount_cb(void) -{ - if(blinky_timer_ctx != NULL) - xTimerChangePeriod(blinky_timer_ctx, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); -} - -// Invoked when usb bus is suspended -// remote_wakeup_en : if host allow us to perform remote wakeup -// Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en) -{ - (void) remote_wakeup_en; - if(blinky_timer_ctx != NULL) - xTimerChangePeriod(blinky_timer_ctx, pdMS_TO_TICKS(BLINK_SUSPENDED), 0); -} - -// Invoked when usb bus is resumed -void tud_resume_cb(void) -{ - if(blinky_timer_ctx != NULL) - xTimerChangePeriod(blinky_timer_ctx, pdMS_TO_TICKS(BLINK_MOUNTED), 0); -} - -//--------------------------------------------------------------------+ -// DFU callbacks -// Note: alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. -//--------------------------------------------------------------------+ - -static size_t total_len = 0; -static size_t bytes_avail = 0; -static uint32_t dn_base_addr = 0; - -// Invoked right before tud_dfu_download_cb() (state=DFU_DNBUSY) or tud_dfu_manifest_cb() (state=DFU_MANIFEST) -// Application return timeout in milliseconds (bwPollTimeout) for the next download/manifest operation. -// During this period, USB host won't try to communicate with us. -uint32_t tud_dfu_get_timeout_cb(uint8_t alt, uint8_t state) -{ - if ( state == DFU_DNBUSY ) - { - // For this example - // - Atl0 Flash is fast : 10 ms - // - Alt1 EEPROM is slow: 100 ms - return (alt == 0) ? 10 : 100; - } - else if (state == DFU_MANIFEST) - { - // since we don't buffer entire image and do any flashing in manifest stage - return 0; - } - - return 0; -} - -// Invoked when received DFU_DNLOAD (wLength>0) following by DFU_GETSTATUS (state=DFU_DNBUSY) requests -// This callback could be returned before flashing op is complete (async). -// Once finished flashing, application must call tud_dfu_finish_flashing() -void tud_dfu_download_cb(uint8_t alt, uint16_t block_num, uint8_t const* data, uint16_t length) -{ - // (void) alt; - // (void) block_num; - - rtos_printf("Received Alt %d BlockNum %d of length %d\n", alt, block_num, length); - - // if (dn_base_addr == 0) - // { - // uint32_t addr = 0; - // total_len = 0; - // int tmp = boot_image_locate_available_spot(bim_ctx_ptr, &addr, &bytes_avail); - // if(tmp == -1) - // { - // boot_image_t* imgptr = NULL; - // imgptr = boot_image_get_last_image(bim_ctx_ptr); - // addr = imgptr->startAddress; - // bytes_avail = bim_ctx_ptr->boot_partition_size - addr; - // } - // rtos_printf("Using addr 0x%x\nsize %u\n", addr, bytes_avail); - // dn_base_addr = addr; - // } - - // if(length > 0) - // { - // unsigned cur_addr = dn_base_addr + (block_num * bim_ctx_ptr->page_size); - // if((bytes_avail - total_len) >= length) - // { - // // rtos_printf("write %d at 0x%x\n", length, cur_addr); - // boot_image_write(bim_ctx_ptr->app_data, cur_addr, data, length); - // total_len += length; - // } else { - // rtos_printf("Insufficient space\n"); - // } - // } - - // flashing op for download complete without error - tud_dfu_finish_flashing(DFU_STATUS_OK); -} - -// Invoked when download process is complete, received DFU_DNLOAD (wLength=0) following by DFU_GETSTATUS (state=Manifest) -// Application can do checksum, or actual flashing if buffered entire image previously. -// Once finished flashing, application must call tud_dfu_finish_flashing() -void tud_dfu_manifest_cb(uint8_t alt) -{ - (void) alt; - rtos_printf("Download completed, enter manifestation\n"); - - // flashing op for manifest is complete without error - // Application can perform checksum, should it fail, use appropriate status such as errVERIFY. - tud_dfu_finish_flashing(DFU_STATUS_OK); - - // rtos_printf("Pass firmware validity check addr 0x%x size %u\n", dn_base_addr, total_len); - // set_rt_mode(); - // boot_image_read(bim_ctx_ptr->app_data, 0, &dummy, sizeof(dummy)); // dummy read to ensure flash writes have completed - // reboot(); -} - -// Invoked when received DFU_UPLOAD request -// Application must populate data with up to length bytes and -// Return the number of written bytes -uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length) -{ - (void) block_num; - (void) length; - - uint16_t const xfer_len = (uint16_t) strlen(upload_image[alt]); - memcpy(data, upload_image[alt], xfer_len); - - return xfer_len; - -// (void) alt; - -// memset(data, 0x00, length); -// uint32_t addr = block_num * FLASH_PAGE_SIZE; -// uint32_t endaddr; - -// #if 0 -// // Test code which will just read out all of flash rather than a specific image -// endaddr = 0x800000; -// #else -// boot_image_t* imgptr = NULL; -// imgptr = boot_image_get_last_image(bim_ctx_ptr); -// addr += imgptr->startAddress; -// endaddr = imgptr->startAddress + imgptr->size; -// #endif -// return (addr >= endaddr) ? 0 : (uint16_t)boot_image_read(bim_ctx_ptr->app_data, addr, data, length); - - -} - -// Invoked when the Host has terminated a download or upload transfer -void tud_dfu_abort_cb(uint8_t alt) -{ - (void) alt; - rtos_printf("Host aborted transfer\n"); - // set_rt_mode(); - // boot_image_read(bim_ctx_ptr->app_data, 0, &dummy, sizeof(dummy)); // dummy read to ensure flash writes have completed -} - -// Invoked when a DFU_DETACH request is received -void tud_dfu_detach_cb(void) -{ - rtos_printf("Host detach, we should probably reboot\n"); - // set_rt_mode(); - reboot(); -} - -void tud_dfu_runtime_reboot_to_dfu_cb(void) -{ - rtos_printf("Host detach, reboot\n"); - // set_dfu_mode(); - reboot(); -} - -static void reboot(void) -{ - rtos_printf("Reboot initiated by tile:0x%x\n", get_local_tile_id()); - write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_COUNT_NUM, 0x10000); - write_sswitch_reg_no_ack(get_local_tile_id(), XS1_SSWITCH_WATCHDOG_CFG_NUM, (1 << XS1_WATCHDOG_COUNT_ENABLE_SHIFT) | (1 << XS1_WATCHDOG_TRIGGER_ENABLE_SHIFT) ); - while(1) {;} -} - -//--------------------------------------------------------------------+ -// BLINKING TASK -//--------------------------------------------------------------------+ - -void led_blinky_cb(TimerHandle_t xTimer) -{ - (void) xTimer; - led_val ^= 1; - - rtos_gpio_port_out(gpio_ctx_t0, led_port, led_val); -} - -void create_tinyusb_demo(unsigned priority) -{ - led_port = rtos_gpio_port(PORT_LEDS); - rtos_gpio_port_enable(gpio_ctx_t0, led_port); - rtos_gpio_port_out(gpio_ctx_t0, led_port, led_val); - - blinky_timer_ctx = xTimerCreate("blinky", - pdMS_TO_TICKS(blink_interval_ms), - pdTRUE, - NULL, - led_blinky_cb); - xTimerStart(blinky_timer_ctx, 0); -} diff --git a/examples/freertos/dfu/src/usb/usb_descriptors.c b/examples/freertos/dfu/src/usb/usb_descriptors.c index bed671713..326ad4ce3 100644 --- a/examples/freertos/dfu/src/usb/usb_descriptors.c +++ b/examples/freertos/dfu/src/usb/usb_descriptors.c @@ -82,45 +82,27 @@ uint8_t const * tud_descriptor_device_cb(void) //--------------------------------------------------------------------+ // Number of Alternate Interface (each for 1 flash partition) -#define ALT_COUNT 1 +#define ALT_COUNT 2 enum { - ITF0_NUM_DFU_RT, - ITF0_NUM_TOTAL + ITF_NUM_DFU_MODE, + ITF_NUM_TOTAL }; -#define CONFIG_0_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_RT_DESC_LEN) - -enum -{ - ITF1_NUM_DFU_MODE, - ITF1_NUM_TOTAL -}; - -#define CONFIG_1_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_DESC_LEN(ALT_COUNT) ) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_DESC_LEN(ALT_COUNT)) #define FUNC_ATTRS (DFU_ATTR_CAN_UPLOAD | DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_WILL_DETACH | DFU_ATTR_MANIFESTATION_TOLERANT) -uint8_t const desc_configuration_rt[] = +uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF0_NUM_TOTAL, 0, CONFIG_0_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), - - // Interface number, string index, attributes, detach timeout, transfer size */ - TUD_DFU_RT_DESCRIPTOR(ITF0_NUM_DFU_RT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), - // TUD_DFU_RT_DESCRIPTOR(ITF0_NUM_DFU_RT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), + // Interface number, Alternate count, starting string index, attributes, detach timeout, transfer size + TUD_DFU_DESCRIPTOR(ITF_NUM_DFU_MODE, ALT_COUNT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), }; -uint8_t const desc_configuration_mode[] = -{ - // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF1_NUM_TOTAL, 0, CONFIG_1_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), - - // Interface number, alt count, string index, attributes, detach timeout, transfer size */ - TUD_DFU_DESCRIPTOR(ITF1_NUM_DFU_MODE, ALT_COUNT, 5, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), -}; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor @@ -128,9 +110,7 @@ uint8_t const desc_configuration_mode[] = uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations - return desc_configuration_mode; - // return check_dfu_mode() ? desc_configuration_rt : desc_configuration_mode; - + return desc_configuration; } //--------------------------------------------------------------------+ @@ -144,8 +124,8 @@ char const* string_desc_arr [] = "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product "123456", // 3: Serials, should use chip ID - "TinyUSB DFU runtime", // 4: DFU runtime - "TinyUSB DFU device", // 5: DFU device + "TinyUSB DFU device FACTORY", // 4: DFU device + "TinyUSB DFU device UPGRADE", // 5: DFU device }; static uint16_t _desc_str[32]; From 9e9b218b917ad8eede0ec39689edbd2313cc1300 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Thu, 10 Nov 2022 14:13:45 -0500 Subject: [PATCH 06/23] Add dfu cmake macros --- examples/freertos/dfu/dfu.cmake | 7 +++++-- examples/freertos/dfu/src/main.c | 4 ++++ examples/freertos/dfu/src/usb/app_dfu.c | 1 - modules/rtos | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/examples/freertos/dfu/dfu.cmake b/examples/freertos/dfu/dfu.cmake index 39f383081..374a4a075 100644 --- a/examples/freertos/dfu/dfu.cmake +++ b/examples/freertos/dfu/dfu.cmake @@ -31,7 +31,6 @@ set(APP_COMPILE_DEFINITIONS ) set(APP_LINK_OPTIONS - -lquadflash -fxscope -report ${CMAKE_CURRENT_LIST_DIR}/XCORE-AI-EXPLORER.xn @@ -77,4 +76,8 @@ merge_binaries(example_freertos_dfu tile0_example_freertos_dfu tile1_example_fre #********************** create_run_target(example_freertos_dfu) create_debug_target(example_freertos_dfu) -create_flash_app_target(example_freertos_dfu) +create_flash_app_dfu_target(example_freertos_dfu 0x100000) +query_tools_version() +create_upgrade_img_target(example_freertos_dfu ${XTC_VERSION_MAJOR} ${XTC_VERSION_MINOR}) +create_erase_all_target(XCORE-AI-EXPLORER) +create_install_target(example_freertos_dfu) diff --git a/examples/freertos/dfu/src/main.c b/examples/freertos/dfu/src/main.c index 7893b2020..91baa5a2d 100644 --- a/examples/freertos/dfu/src/main.c +++ b/examples/freertos/dfu/src/main.c @@ -35,6 +35,10 @@ void startup_task(void *arg) platform_start(); +#if ON_TILE(0) + rtos_dfu_image_print_debug(dfu_image_ctx); +#endif + for (;;) { rtos_printf("Tile[%d]:\n\tMinimum heap free: %d\n\tCurrent heap free: %d\n", THIS_XCORE_TILE, xPortGetMinimumEverFreeHeapSize(), xPortGetFreeHeapSize()); vTaskDelay(pdMS_TO_TICKS(5000)); diff --git a/examples/freertos/dfu/src/usb/app_dfu.c b/examples/freertos/dfu/src/usb/app_dfu.c index 95641911e..5ed81321d 100644 --- a/examples/freertos/dfu/src/usb/app_dfu.c +++ b/examples/freertos/dfu/src/usb/app_dfu.c @@ -31,7 +31,6 @@ #include "FreeRTOS.h" #include "timers.h" #include "platform/driver_instances.h" -#include "demo_main.h" #include "tusb.h" /* diff --git a/modules/rtos b/modules/rtos index 5bd462749..316ef42bc 160000 --- a/modules/rtos +++ b/modules/rtos @@ -1 +1 @@ -Subproject commit 5bd462749b334ab71938f611f978220dfb792dea +Subproject commit 316ef42bcd35ebcb015476fd1c22b5b7bee93223 From e50ff33b62c11ba18a53a56f255a9f778d566efa Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Thu, 10 Nov 2022 14:47:44 -0500 Subject: [PATCH 07/23] Add data partition to DFU --- examples/freertos/dfu/src/main.c | 8 ++++++++ examples/freertos/dfu/src/usb/app_dfu.c | 20 +++++++++++++++++-- .../freertos/dfu/src/usb/usb_descriptors.c | 7 ++++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/examples/freertos/dfu/src/main.c b/examples/freertos/dfu/src/main.c index 91baa5a2d..a433a2f93 100644 --- a/examples/freertos/dfu/src/main.c +++ b/examples/freertos/dfu/src/main.c @@ -37,6 +37,14 @@ void startup_task(void *arg) #if ON_TILE(0) rtos_dfu_image_print_debug(dfu_image_ctx); + + uint32_t data; + rtos_qspi_flash_read( + qspi_flash_ctx, + &data, + rtos_dfu_image_get_data_partition_addr(dfu_image_ctx), + sizeof(int32_t)); + rtos_printf("First word at data partition start is: 0x%x\n", data); #endif for (;;) { diff --git a/examples/freertos/dfu/src/usb/app_dfu.c b/examples/freertos/dfu/src/usb/app_dfu.c index 5ed81321d..316f72c8c 100644 --- a/examples/freertos/dfu/src/usb/app_dfu.c +++ b/examples/freertos/dfu/src/usb/app_dfu.c @@ -36,7 +36,7 @@ /* * After device is enumerated in dfu mode run the following commands * - * To transfer firmware from host to device (best to test with text file) + * To transfer firmware from host to device * * $ dfu-util -d cafe -a 0 -D [filename] * $ dfu-util -d cafe -a 1 -D [filename] @@ -126,8 +126,15 @@ void tud_dfu_download_cb(uint8_t alt, uint16_t block_num, uint8_t const* data, u total_len = 0; dn_base_addr = rtos_dfu_image_get_upgrade_addr(dfu_image_ctx); bytes_avail = data_partition_base_addr - dn_base_addr; - rtos_printf("Using addr 0x%x\nsize %u\n", dn_base_addr, bytes_avail); } + /* fallthrough */ + case 2: + if (dn_base_addr == 0) { + total_len = 0; + dn_base_addr = data_partition_base_addr; + bytes_avail = rtos_qspi_flash_size_get(qspi_flash_ctx) - dn_base_addr; + } + rtos_printf("Using addr 0x%x\nsize %u\n", dn_base_addr, bytes_avail); if(length > 0) { unsigned cur_addr = dn_base_addr + (block_num * CFG_TUD_DFU_XFER_BUFSIZE); if((bytes_avail - total_len) >= length) { @@ -184,6 +191,9 @@ void tud_dfu_manifest_cb(uint8_t alt) (uint8_t *)&dummy, 0, sizeof(dummy)); + + /* Reset download */ + dn_base_addr = 0; // flashing op for manifest is complete without error // Application can perform checksum, should it fail, use appropriate status such as errVERIFY. @@ -216,6 +226,12 @@ uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint1 endaddr = rtos_dfu_image_get_upgrade_addr(dfu_image_ctx) + rtos_dfu_image_get_upgrade_size(dfu_image_ctx); } break; + case 2: + if ((rtos_qspi_flash_size_get(qspi_flash_ctx) - rtos_dfu_image_get_data_partition_addr(dfu_image_ctx)) > 0) { + addr += rtos_dfu_image_get_data_partition_addr(dfu_image_ctx); + endaddr = rtos_qspi_flash_size_get(qspi_flash_ctx); /* End of flash */ + } + break; } if (addr < endaddr) { diff --git a/examples/freertos/dfu/src/usb/usb_descriptors.c b/examples/freertos/dfu/src/usb/usb_descriptors.c index 326ad4ce3..0b7486d8f 100644 --- a/examples/freertos/dfu/src/usb/usb_descriptors.c +++ b/examples/freertos/dfu/src/usb/usb_descriptors.c @@ -82,7 +82,7 @@ uint8_t const * tud_descriptor_device_cb(void) //--------------------------------------------------------------------+ // Number of Alternate Interface (each for 1 flash partition) -#define ALT_COUNT 2 +#define ALT_COUNT 3 enum { @@ -124,8 +124,9 @@ char const* string_desc_arr [] = "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product "123456", // 3: Serials, should use chip ID - "TinyUSB DFU device FACTORY", // 4: DFU device - "TinyUSB DFU device UPGRADE", // 5: DFU device + "DFU device FACTORY", // 4: DFU device + "DFU device UPGRADE", // 5: DFU device + "DFU device DATAPARTITION", // 6: DFU device }; static uint16_t _desc_str[32]; From 1c8a1368a44a4234dc2ec004886d6357848d5530 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Thu, 10 Nov 2022 15:41:53 -0500 Subject: [PATCH 08/23] Update rtos submodule to develop --- modules/rtos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/rtos b/modules/rtos index 316ef42bc..a2474ad6c 160000 --- a/modules/rtos +++ b/modules/rtos @@ -1 +1 @@ -Subproject commit 316ef42bcd35ebcb015476fd1c22b5b7bee93223 +Subproject commit a2474ad6c0c779d587df756e1f6e9dc7a72f6beb From c02114322563c82163f4dceb14b0b18e708d621b Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Thu, 10 Nov 2022 15:42:07 -0500 Subject: [PATCH 09/23] Fix warnings --- examples/freertos/dfu/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/freertos/dfu/src/main.c b/examples/freertos/dfu/src/main.c index a433a2f93..c20563aa6 100644 --- a/examples/freertos/dfu/src/main.c +++ b/examples/freertos/dfu/src/main.c @@ -41,7 +41,7 @@ void startup_task(void *arg) uint32_t data; rtos_qspi_flash_read( qspi_flash_ctx, - &data, + (uint8_t*)&data, rtos_dfu_image_get_data_partition_addr(dfu_image_ctx), sizeof(int32_t)); rtos_printf("First word at data partition start is: 0x%x\n", data); From 03c110df34452dcedf8346f448ea25cdaa389dee Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Thu, 10 Nov 2022 15:42:33 -0500 Subject: [PATCH 10/23] Update DFU example docs --- examples/freertos/dfu/README.rst | 164 +++++++++++++++++++++++++++++++ examples/freertos/dfu/dfu.cmake | 6 +- 2 files changed, 166 insertions(+), 4 deletions(-) diff --git a/examples/freertos/dfu/README.rst b/examples/freertos/dfu/README.rst index 803d733ac..aac2602d4 100644 --- a/examples/freertos/dfu/README.rst +++ b/examples/freertos/dfu/README.rst @@ -4,6 +4,18 @@ DFU This example application demonstrates a method to add DFU to a FreeRTOS application on XCORE. +********************** +Preparing the host +********************** + +This application supports any host host application that is capable of USB DFU Class V1.1. + +The application was verified using dfu-util. + +Installation instructions for respective operating system can be found `here `__ + +If on Linux/Mac the user may need to add the USB device to their udev rules. This example defaults to Vendor ID 0xCAFE with Product ID 0x4000. + ********************* Building the firmware ********************* @@ -26,11 +38,60 @@ Run the following commands in the xcore_sdk root folder to build the firmware: cd build nmake example_freertos_dfu +********************** +Preparing the hardware +********************** + +It is recommended to begin from an erased flash. From the xcore_sdk build folder run: + +.. tab:: Linux and Mac + + .. code-block:: console + + make erase_all_XCORE-AI-EXPLORER + +.. tab:: Windows + + .. code-block:: console + + nmake erase_all_XCORE-AI-EXPLORER + +After building the firmware and erasing the flash, the factory image must be flashed. From the xcore_sdk build folder run: + +.. tab:: Linux and Mac + + .. code-block:: console + + make flash_app_dfu_example_freertos_dfu + +.. tab:: Windows + + .. code-block:: console + + nmake flash_app_dfu_example_freertos_dfu + +The board may be power cycled and will boot up the application. + +Next, the user make create an upgrade image. From the xcore_sdk build folder run: + +.. tab:: Linux and Mac + + .. code-block:: console + + make create_upgrade_img_example_freertos_dfu + +.. tab:: Windows + + .. code-block:: console + + nmake create_upgrade_img_example_freertos_dfu ******************** Running the firmware ******************** +After flashed, the factory image will run by default. The user may opt to manually run via xrun to see debug messages. + From the xcore_sdk build folder run: .. tab:: Linux and Mac @@ -45,6 +106,109 @@ From the xcore_sdk build folder run: nmake run_example_freertos_dfu +******************** +Upgrading the firmware via DFU +******************** + +Once the application is running, a USB DFU v1.1 tool can be used to perform various actions. This example will demonstrate with dfu-util commands. + +To verify the device is running run: + +.. code-block:: console + + dfu-util -l + +This should result in an output containing: + +.. code-block:: console + + Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=2, name="DFU device DATAPARTITION", serial="123456" + Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=1, name="DFU device UPGRADE", serial="123456" + Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=0, name="DFU device FACTORY", serial="123456" + +The factory image can be read back by running: + +.. code-block:: console + + dfu-util -e -d 4000 -a 0 -U readback_factory_img.bin + +From the xcore_sdk build folder, the upgrade image can be written by running: + +.. code-block:: console + + dfu-util -e -d 4000 -a 1 -D example_freertos_dfu_upgrade.bin + +The upgrade image can be read back by running: + +.. code-block:: console + + dfu-util -e -d 4000 -a 1 -U readback_upgrade_img.bin + +The data partition image can be read back by running: + +.. code-block:: console + + dfu-util -e -d 4000 -a 2 -U readback_data_partition_img.bin + +The data partition image can be written by running: + +.. code-block:: console + + dfu-util -e -d 4000 -a 2 -D readback_data_partition_img.bin + +If running the application with the run_example_freertos_dfu target, information is printed to verify behavior. + +Initially, the debug prints will contain: + +.. code-block:: console + + DFU Image Info + Factory: + Addr:0x1C70 + Size:103108 + Version:0 + Upgrade: + Addr:0x1B000 + Size:0 + Version:0 + Data Partition + Addr:0x100000 + First word at data partition start is: 0xFFFFFFFF + +After writing an upgrade image the debug prints will contain: + +.. code-block:: console + + DFU Image Info + Factory: + Addr:0x1C70 + Size:103108 + Version:0 + Upgrade: + Addr:0x1B000 + Size:103108 + Version:0 + Data Partition + Addr:0x100000 + First word at data partition start is: 0xFFFFFFFF + +The debug prints include the value of the first word at the start of the data partition. Writing a text file containing "XMOS" will result in: + +.. code-block:: console + + DFU Image Info + Factory: + Addr:0x1C70 + Size:103108 + Version:0 + Upgrade: + Addr:0x1B000 + Size:103108 + Version:0 + Data Partition + Addr:0x100000 + First word at data partition start is: 0x534F4D58 + ******************************** Debugging the firmware with xgdb diff --git a/examples/freertos/dfu/dfu.cmake b/examples/freertos/dfu/dfu.cmake index 374a4a075..e6b8d69c7 100644 --- a/examples/freertos/dfu/dfu.cmake +++ b/examples/freertos/dfu/dfu.cmake @@ -51,8 +51,7 @@ target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES}) target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0) target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) -target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS} -"-Wm,--map,memory0.map") +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) unset(TARGET_NAME) set(TARGET_NAME tile1_example_freertos_dfu) @@ -62,8 +61,7 @@ target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES}) target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1) target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) -target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS} -"-Wm,--map,memory1.map") +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) unset(TARGET_NAME) #********************** From 021b33790d7f85eedefbe30e33fed93d184183e0 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Thu, 10 Nov 2022 15:49:11 -0500 Subject: [PATCH 11/23] Update CI --- tools/ci/build_rtos_core_examples.sh | 31 ++++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/tools/ci/build_rtos_core_examples.sh b/tools/ci/build_rtos_core_examples.sh index 4c87d6fea..957577a56 100755 --- a/tools/ci/build_rtos_core_examples.sh +++ b/tools/ci/build_rtos_core_examples.sh @@ -16,16 +16,17 @@ if [ -d "${DIST_HOST_DIR}" ]; then find ${DIST_HOST_DIR} -type f -exec chmod a+x {} + fi -# row format is: "target min_tools_version run_fs_target run_swmem_target board toolchain" +# row format is: "target min_tools_version run_fs_target run_swmem_target run_upgrade_img_target board toolchain" applications=( - "example_freertos_device_control 15.1.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" - "example_freertos_dispatcher 15.1.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" - "example_freertos_explorer_board 15.1.0 Yes No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" - "example_freertos_getting_started 15.1.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" - "example_freertos_l2_cache 15.1.0 No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" - "example_freertos_xlink_0 15.2.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" - "example_freertos_xlink_1 15.2.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" - "example_freertos_xscope_fileio 15.1.0 No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_device_control 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_dfu 15.1.0 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_dispatcher 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_explorer_board 15.1.0 Yes No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_getting_started 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_l2_cache 15.1.0 No Yes No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_xlink_0 15.2.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_xlink_1 15.2.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_xscope_fileio 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" ) # perform builds @@ -35,8 +36,9 @@ for ((i = 0; i < ${#applications[@]}; i += 1)); do min_tools_version="${FIELDS[1]}" run_fs_target="${FIELDS[2]}" run_swmem_target="${FIELDS[3]}" - board="${FIELDS[4]}" - toolchain_file="${XCORE_SDK_ROOT}/${FIELDS[5]}" + run_upgrade_img_target="${FIELDS[4]}" + board="${FIELDS[5]}" + toolchain_file="${XCORE_SDK_ROOT}/${FIELDS[6]}" path="${XCORE_SDK_ROOT}" if check_tools_version ${min_tools_version} @@ -62,5 +64,12 @@ for ((i = 0; i < ${#applications[@]}; i += 1)); do (cd ${path}/build_${board}; log_errors make make_swmem_${app_target} -j) (cd ${path}/build_${board}; cp ${app_target}.swmem ${DIST_DIR}) fi + if [ "$run_upgrade_img_target" = "Yes" ]; then + echo '======================================================' + echo '= Making upgrade image for' ${app_target} + echo '======================================================' + (cd ${path}/build_${board}; log_errors make create_upgrade_img_${app_target} -j) + (cd ${path}/build_${board}; cp ${app_target}_upgrade.bin ${DIST_DIR}) + fi fi done From 1203d6d7146f4af9d31cd59ae5abbe63869f6351 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Thu, 10 Nov 2022 15:49:34 -0500 Subject: [PATCH 12/23] Add dfu example to doc chain --- doc/tutorials/freertos/examples/dfu.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/tutorials/freertos/examples/dfu.rst diff --git a/doc/tutorials/freertos/examples/dfu.rst b/doc/tutorials/freertos/examples/dfu.rst new file mode 100644 index 000000000..1535f3263 --- /dev/null +++ b/doc/tutorials/freertos/examples/dfu.rst @@ -0,0 +1 @@ +.. include:: ../../../../examples/freertos/dfu/README.rst From 8b85ba9d9d0ba0b62a9d4157fa1724e83316a4bf Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Mon, 14 Nov 2022 09:54:09 -0500 Subject: [PATCH 13/23] Correct Tools version for DFU example --- examples/freertos/dfu/dfu.cmake | 8 +++++++- tools/ci/build_rtos_core_examples.sh | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/freertos/dfu/dfu.cmake b/examples/freertos/dfu/dfu.cmake index e6b8d69c7..e3f609166 100644 --- a/examples/freertos/dfu/dfu.cmake +++ b/examples/freertos/dfu/dfu.cmake @@ -1,3 +1,10 @@ +query_tools_version() + +if ((XTC_VERSION_MAJOR LESS 15) OR (XTC_VERSION_MINOR LESS 2)) + message(WARNING "XTC Tools version 15.2.0 or newer required for FreeRTOS dfu example") + return() +endif() + #********************** # Gather Sources #********************** @@ -75,7 +82,6 @@ merge_binaries(example_freertos_dfu tile0_example_freertos_dfu tile1_example_fre create_run_target(example_freertos_dfu) create_debug_target(example_freertos_dfu) create_flash_app_dfu_target(example_freertos_dfu 0x100000) -query_tools_version() create_upgrade_img_target(example_freertos_dfu ${XTC_VERSION_MAJOR} ${XTC_VERSION_MINOR}) create_erase_all_target(XCORE-AI-EXPLORER) create_install_target(example_freertos_dfu) diff --git a/tools/ci/build_rtos_core_examples.sh b/tools/ci/build_rtos_core_examples.sh index 2a5490f35..ddeba3399 100755 --- a/tools/ci/build_rtos_core_examples.sh +++ b/tools/ci/build_rtos_core_examples.sh @@ -19,7 +19,7 @@ fi # row format is: "target min_tools_version run_fs_target run_swmem_target run_upgrade_img_target board toolchain" applications=( "example_freertos_device_control 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" - "example_freertos_dfu 15.1.0 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_dfu 15.2.0 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" "example_freertos_dispatcher 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" "example_freertos_explorer_board 15.1.0 Yes No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" "example_freertos_getting_started 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" From e86560325cf9e34ecf06ebdd379cc0c8f23fa6cb Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Mon, 14 Nov 2022 12:28:18 -0500 Subject: [PATCH 14/23] Add DFU support to 15.1.3 and 15.1.4 --- .../platform/platform_conf.h | 52 +++++++++++++++++++ .../platform/platform_init.c | 16 ++++-- examples/freertos/dfu/dfu.cmake | 8 +-- modules/rtos | 2 +- 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_conf.h b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_conf.h index e6305f163..80d2d56aa 100644 --- a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_conf.h +++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_conf.h @@ -80,4 +80,56 @@ #define appconfQSPI_FLASH_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) #endif /* appconfQSPI_FLASH_TASK_PRIORITY */ +/*****************************************/ +/* DFU Settings */ +/*****************************************/ +#define FL_QUADDEVICE_AT25FF321A \ +{ \ + 0, /* UNKNOWN */ \ + 256, /* page size */ \ + 16384, /* num pages */ \ + 3, /* address size */ \ + 3, /* log2 clock divider */ \ + 0x9F, /* QSPI_RDID */ \ + 0, /* id dummy bytes */ \ + 3, /* id size in bytes */ \ + 0x1F4708, /* device id */ \ + 0x20, /* QSPI_SE */ \ + 4096, /* Sector erase is always 4KB */ \ + 0x06, /* QSPI_WREN */ \ + 0x04, /* QSPI_WRDI */ \ + PROT_TYPE_SR, /* Protection via SR */ \ + {{0x3C,0x00},{0,0}}, /* QSPI_SP, QSPI_SU */ \ + 0x02, /* QSPI_PP */ \ + 0xEB, /* QSPI_READ_FAST */ \ + 1, /* 1 read dummy byte */ \ + SECTOR_LAYOUT_REGULAR, /* mad sectors */ \ + {4096,{0,{0}}}, /* regular sector sizes */ \ + 0x05, /* QSPI_RDSR */ \ + 0x01, /* QSPI_WRSR */ \ + 0x01, /* QSPI_WIP_BIT_MASK */ \ +} + +#ifndef BOARD_QSPI_SPEC +/* Set up a default SPI spec if the app has not provided + * one explicitly. + * Note: The version checks only work in XTC Tools >15.3.0 + * By default FL_QUADDEVICE_AT25FF321A is used + */ +#ifdef __XMOS_XTC_VERSION_MAJOR__ +#if (__XMOS_XTC_VERSION_MAJOR__ == 15) \ + && (__XMOS_XTC_VERSION_MINOR__ >= 2) \ + && (__XMOS_XTC_VERSION_PATCH__ >= 0) +/* In XTC >15.2.0 some SFDP support enables a generic + * default spec + */ +#define BOARD_QSPI_SPEC FL_QUADDEVICE_DEFAULT +#else +#define BOARD_QSPI_SPEC FL_QUADDEVICE_AT25FF321A +#endif +#else +#define BOARD_QSPI_SPEC FL_QUADDEVICE_AT25FF321A +#endif /* __XMOS_XTC_VERSION_MAJOR__ */ +#endif /* BOARD_QSPI_SPEC */ + #endif /* PLATFORM_CONF_H_ */ diff --git a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c index b3b0d0f34..b9e722960 100644 --- a/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c +++ b/examples/freertos/dfu/bsp_config/XCORE-AI-EXPLORER_2V0/platform/platform_init.c @@ -8,15 +8,23 @@ #include "platform/driver_instances.h" #include #include + static void flash_init(void) { #if ON_TILE(FLASH_TILE_NO) + fl_QuadDeviceSpec qspi_spec = BOARD_QSPI_SPEC; + fl_QSPIPorts qspi_ports = { + .qspiCS = PORT_SQI_CS, + .qspiSCLK = PORT_SQI_SCLK, + .qspiSIO = PORT_SQI_SIO, + .qspiClkblk = FLASH_CLKBLK, + }; + rtos_dfu_image_init( dfu_image_ctx, - FLASH_CLKBLK, - PORT_SQI_CS, - PORT_SQI_SCLK, - PORT_SQI_SIO); + &qspi_ports, + &qspi_spec, + 1); qspi_flash_ctx->ctx.sfdp_skip = true; qspi_flash_ctx->ctx.sfdp_supported = false; diff --git a/examples/freertos/dfu/dfu.cmake b/examples/freertos/dfu/dfu.cmake index e3f609166..e6b8d69c7 100644 --- a/examples/freertos/dfu/dfu.cmake +++ b/examples/freertos/dfu/dfu.cmake @@ -1,10 +1,3 @@ -query_tools_version() - -if ((XTC_VERSION_MAJOR LESS 15) OR (XTC_VERSION_MINOR LESS 2)) - message(WARNING "XTC Tools version 15.2.0 or newer required for FreeRTOS dfu example") - return() -endif() - #********************** # Gather Sources #********************** @@ -82,6 +75,7 @@ merge_binaries(example_freertos_dfu tile0_example_freertos_dfu tile1_example_fre create_run_target(example_freertos_dfu) create_debug_target(example_freertos_dfu) create_flash_app_dfu_target(example_freertos_dfu 0x100000) +query_tools_version() create_upgrade_img_target(example_freertos_dfu ${XTC_VERSION_MAJOR} ${XTC_VERSION_MINOR}) create_erase_all_target(XCORE-AI-EXPLORER) create_install_target(example_freertos_dfu) diff --git a/modules/rtos b/modules/rtos index a2474ad6c..977f99473 160000 --- a/modules/rtos +++ b/modules/rtos @@ -1 +1 @@ -Subproject commit a2474ad6c0c779d587df756e1f6e9dc7a72f6beb +Subproject commit 977f994739538a5d72514140adc507f7bdbe53a7 From a2dee4caf7566f19a6f8bc80a332b97c081a1f1b Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Mon, 14 Nov 2022 12:32:27 -0500 Subject: [PATCH 15/23] Update CI --- tools/ci/build_rtos_core_examples.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/ci/build_rtos_core_examples.sh b/tools/ci/build_rtos_core_examples.sh index ddeba3399..655c0bc43 100755 --- a/tools/ci/build_rtos_core_examples.sh +++ b/tools/ci/build_rtos_core_examples.sh @@ -19,6 +19,7 @@ fi # row format is: "target min_tools_version run_fs_target run_swmem_target run_upgrade_img_target board toolchain" applications=( "example_freertos_device_control 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_dfu 15.1.3 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" "example_freertos_dfu 15.2.0 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" "example_freertos_dispatcher 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" "example_freertos_explorer_board 15.1.0 Yes No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" From b4ce28a0ed6e6be614097175ef9d57f6b283f50a Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Tue, 15 Nov 2022 10:54:37 -0500 Subject: [PATCH 16/23] Add blinky and multiple dfu builds --- examples/freertos/dfu/README.rst | 79 +++++++++---------- examples/freertos/dfu/dfu.cmake | 50 +++++++++--- examples/freertos/dfu/src/main.c | 22 ++++++ .../freertos/dfu/src/usb/usb_descriptors.c | 6 +- 4 files changed, 102 insertions(+), 55 deletions(-) diff --git a/examples/freertos/dfu/README.rst b/examples/freertos/dfu/README.rst index aac2602d4..ab6e26b13 100644 --- a/examples/freertos/dfu/README.rst +++ b/examples/freertos/dfu/README.rst @@ -28,7 +28,8 @@ Run the following commands in the xcore_sdk root folder to build the firmware: cmake -B build -DCMAKE_TOOLCHAIN_FILE=xmos_cmake_toolchain/xs3a.cmake cd build - make example_freertos_dfu + make example_freertos_dfu_v1 + make example_freertos_dfu_v2 .. tab:: Windows @@ -36,55 +37,41 @@ Run the following commands in the xcore_sdk root folder to build the firmware: cmake -G "NMake Makefiles" -B build -DCMAKE_TOOLCHAIN_FILE=xmos_cmake_toolchain/xs3a.cmake cd build - nmake example_freertos_dfu + nmake example_freertos_dfu_v1 + nmake example_freertos_dfu_v2 ********************** Preparing the hardware ********************** -It is recommended to begin from an erased flash. From the xcore_sdk build folder run: +It is recommended to begin from an erased flash. To erase flash run: -.. tab:: Linux and Mac - - .. code-block:: console - - make erase_all_XCORE-AI-EXPLORER - -.. tab:: Windows - - .. code-block:: console +.. code-block:: console - nmake erase_all_XCORE-AI-EXPLORER + xflash --erase-all --target=XCORE-AI-EXPLORER After building the firmware and erasing the flash, the factory image must be flashed. From the xcore_sdk build folder run: -.. tab:: Linux and Mac - - .. code-block:: console - - make flash_app_dfu_example_freertos_dfu - -.. tab:: Windows - - .. code-block:: console +.. code-block:: console - nmake flash_app_dfu_example_freertos_dfu + xflash --quad-spi-clock 50MHz --factory example_freertos_dfu_v1.xe --boot-partition-size 0x100000 -The board may be power cycled and will boot up the application. +The board may then be power cycled and will boot up the application. Next, the user make create an upgrade image. From the xcore_sdk build folder run: -.. tab:: Linux and Mac +.. code-block:: console - .. code-block:: console + xflash --factory-version . --upgrade 0 example_freertos_dfu_v2.xe -o example_freertos_dfu_v2_upgrade.bin - make create_upgrade_img_example_freertos_dfu +OR +.. code-block:: console -.. tab:: Windows + make create_upgrade_img_example_freertos_dfu_v1 - .. code-block:: console +This will create an upgrade image file. - nmake create_upgrade_img_example_freertos_dfu +Populating the version of tools you are running. ******************** Running the firmware @@ -98,13 +85,13 @@ From the xcore_sdk build folder run: .. code-block:: console - make run_example_freertos_dfu + make run_example_freertos_dfu_v1 .. tab:: Windows .. code-block:: console - nmake run_example_freertos_dfu + nmake run_example_freertos_dfu_v1 ******************** Upgrading the firmware via DFU @@ -112,19 +99,30 @@ Upgrading the firmware via DFU Once the application is running, a USB DFU v1.1 tool can be used to perform various actions. This example will demonstrate with dfu-util commands. +MacOS users may need to sudo the following commands. + To verify the device is running run: .. code-block:: console dfu-util -l -This should result in an output containing: +The output of this command will very based on which image is running. +For example_freertos_dfu_v1, the output should contain: .. code-block:: console - Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=2, name="DFU device DATAPARTITION", serial="123456" - Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=1, name="DFU device UPGRADE", serial="123456" - Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=0, name="DFU device FACTORY", serial="123456" + Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=2, name="DFU dev DATAPARTITION v1", serial="123456" + Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=1, name="DFU dev UPGRADE v1", serial="123456" + Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=0, name="DFU dev FACTORY v1", serial="123456" + +For example_freertos_dfu_v2, the output should contain: + +.. code-block:: console + + Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=2, name="DFU dev DATAPARTITION v2", serial="123456" + Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=1, name="DFU dev UPGRADE v2", serial="123456" + Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=0, name="DFU dev FACTORY v2", serial="123456" The factory image can be read back by running: @@ -136,7 +134,7 @@ From the xcore_sdk build folder, the upgrade image can be written by running: .. code-block:: console - dfu-util -e -d 4000 -a 1 -D example_freertos_dfu_upgrade.bin + dfu-util -e -d 4000 -a 1 -D example_freertos_dfu_v2_upgrade.bin The upgrade image can be read back by running: @@ -156,7 +154,7 @@ The data partition image can be written by running: dfu-util -e -d 4000 -a 2 -D readback_data_partition_img.bin -If running the application with the run_example_freertos_dfu target, information is printed to verify behavior. +If running the application with the run_example_freertos_dfu_v1 target, information is printed to verify behavior. Initially, the debug prints will contain: @@ -209,7 +207,6 @@ The debug prints include the value of the first word at the start of the data pa Addr:0x100000 First word at data partition start is: 0x534F4D58 - ******************************** Debugging the firmware with xgdb ******************************** @@ -220,10 +217,10 @@ From the xcore_sdk build folder run: .. code-block:: console - make debug_example_freertos_dfu + make debug_example_freertos_dfu_v1 .. tab:: Windows .. code-block:: console - nmake debug_example_freertos_dfu + nmake debug_example_freertos_dfu_v1 diff --git a/examples/freertos/dfu/dfu.cmake b/examples/freertos/dfu/dfu.cmake index e6b8d69c7..97a986143 100644 --- a/examples/freertos/dfu/dfu.cmake +++ b/examples/freertos/dfu/dfu.cmake @@ -44,21 +44,41 @@ set(APP_LINK_LIBRARIES #********************** # Tile Targets #********************** -set(TARGET_NAME tile0_example_freertos_dfu) +set(TARGET_NAME tile0_example_freertos_dfu_v1) add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES}) target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES}) -target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0 VERSION=1) target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) unset(TARGET_NAME) -set(TARGET_NAME tile1_example_freertos_dfu) +set(TARGET_NAME tile1_example_freertos_dfu_v1) add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES}) target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES}) -target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1 VERSION=1) +target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) +target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) +unset(TARGET_NAME) + +set(TARGET_NAME tile0_example_freertos_dfu_v2) +add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) +target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES}) +target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES}) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0 VERSION=2) +target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) +target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) +unset(TARGET_NAME) + +set(TARGET_NAME tile1_example_freertos_dfu_v2) +add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) +target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES}) +target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES}) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1 VERSION=2) target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) target_link_libraries(${TARGET_NAME} PUBLIC ${APP_LINK_LIBRARIES}) target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) @@ -67,15 +87,23 @@ unset(TARGET_NAME) #********************** # Merge binaries #********************** -merge_binaries(example_freertos_dfu tile0_example_freertos_dfu tile1_example_freertos_dfu 1) +merge_binaries(example_freertos_dfu_v1 tile0_example_freertos_dfu_v1 tile1_example_freertos_dfu_v1 1) +merge_binaries(example_freertos_dfu_v2 tile0_example_freertos_dfu_v2 tile1_example_freertos_dfu_v2 1) #********************** # Create run and debug targets #********************** -create_run_target(example_freertos_dfu) -create_debug_target(example_freertos_dfu) -create_flash_app_dfu_target(example_freertos_dfu 0x100000) -query_tools_version() -create_upgrade_img_target(example_freertos_dfu ${XTC_VERSION_MAJOR} ${XTC_VERSION_MINOR}) create_erase_all_target(XCORE-AI-EXPLORER) -create_install_target(example_freertos_dfu) + +create_run_target(example_freertos_dfu_v1) +create_debug_target(example_freertos_dfu_v1) +create_flash_app_dfu_target(example_freertos_dfu_v1 0x100000) +query_tools_version() +create_upgrade_img_target(example_freertos_dfu_v1 ${XTC_VERSION_MAJOR} ${XTC_VERSION_MINOR}) +create_install_target(example_freertos_dfu_v1) + +create_run_target(example_freertos_dfu_v2) +create_debug_target(example_freertos_dfu_v2) +create_flash_app_dfu_target(example_freertos_dfu_v2 0x100000) +create_upgrade_img_target(example_freertos_dfu_v2 ${XTC_VERSION_MAJOR} ${XTC_VERSION_MINOR}) +create_install_target(example_freertos_dfu_v2) diff --git a/examples/freertos/dfu/src/main.c b/examples/freertos/dfu/src/main.c index c20563aa6..176f24a21 100644 --- a/examples/freertos/dfu/src/main.c +++ b/examples/freertos/dfu/src/main.c @@ -29,6 +29,19 @@ void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) { configASSERT(0); } +void blinky_task(void *arg) { + uint32_t gpio_port = rtos_gpio_port(PORT_LEDS); + uint32_t led_val = 0; + + rtos_gpio_port_enable(gpio_ctx_t0, gpio_port); + + for (;;) { + rtos_gpio_port_out(gpio_ctx_t0, gpio_port, led_val); + led_val ^= 0x0000000f; + vTaskDelay(pdMS_TO_TICKS(1000)); + } +} + void startup_task(void *arg) { rtos_printf("Startup task running from tile %d on core %d\n", THIS_XCORE_TILE, portGET_CORE_ID()); @@ -71,6 +84,15 @@ void tile_common_init(chanend_t c) appconfSTARTUP_TASK_PRIORITY, NULL); +#if ON_TILE(0) + xTaskCreate((TaskFunction_t) blinky_task, + "blinky_task", + RTOS_THREAD_STACK_SIZE(blinky_task), + NULL, + appconfSTARTUP_TASK_PRIORITY / 2, + NULL); +#endif + rtos_printf("start scheduler on tile %d\n", THIS_XCORE_TILE); vTaskStartScheduler(); } diff --git a/examples/freertos/dfu/src/usb/usb_descriptors.c b/examples/freertos/dfu/src/usb/usb_descriptors.c index 0b7486d8f..503e0cc1c 100644 --- a/examples/freertos/dfu/src/usb/usb_descriptors.c +++ b/examples/freertos/dfu/src/usb/usb_descriptors.c @@ -124,9 +124,9 @@ char const* string_desc_arr [] = "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product "123456", // 3: Serials, should use chip ID - "DFU device FACTORY", // 4: DFU device - "DFU device UPGRADE", // 5: DFU device - "DFU device DATAPARTITION", // 6: DFU device + "DFU dev FACTORY v" XCORE_UTILS_STRINGIFY(VERSION), // 4: DFU device + "DFU dev UPGRADE v" XCORE_UTILS_STRINGIFY(VERSION), // 5: DFU device + "DFU dev DATAPARTITION v" XCORE_UTILS_STRINGIFY(VERSION), // 6: DFU device }; static uint16_t _desc_str[32]; From ea9ccb004a3be9b64c4d92f600d2d1683d8b680a Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Tue, 15 Nov 2022 10:57:50 -0500 Subject: [PATCH 17/23] Update CI build --- tools/ci/build_rtos_core_examples.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/ci/build_rtos_core_examples.sh b/tools/ci/build_rtos_core_examples.sh index 655c0bc43..3dcad32e0 100755 --- a/tools/ci/build_rtos_core_examples.sh +++ b/tools/ci/build_rtos_core_examples.sh @@ -19,8 +19,10 @@ fi # row format is: "target min_tools_version run_fs_target run_swmem_target run_upgrade_img_target board toolchain" applications=( "example_freertos_device_control 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" - "example_freertos_dfu 15.1.3 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" - "example_freertos_dfu 15.2.0 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_dfu_v1 15.1.3 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_dfu_v2 15.1.3 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_dfu_v1 15.2.0 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" + "example_freertos_dfu_v2 15.2.0 No No Yes XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" "example_freertos_dispatcher 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" "example_freertos_explorer_board 15.1.0 Yes No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" "example_freertos_getting_started 15.1.0 No No No XCORE-AI-EXPLORER xmos_cmake_toolchain/xs3a.cmake" From e8331c16e76c6f9ab3a12ab96f8b12f07b1550f2 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Tue, 15 Nov 2022 11:43:07 -0500 Subject: [PATCH 18/23] Update DFU docs for cmake utils --- examples/freertos/dfu/README.rst | 43 +++++++++++++++++++++++--------- examples/freertos/dfu/dfu.cmake | 18 ++++++++++--- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/examples/freertos/dfu/README.rst b/examples/freertos/dfu/README.rst index ab6e26b13..818fa0779 100644 --- a/examples/freertos/dfu/README.rst +++ b/examples/freertos/dfu/README.rst @@ -46,32 +46,51 @@ Preparing the hardware It is recommended to begin from an erased flash. To erase flash run: -.. code-block:: console +.. tab:: Linux and Mac + + .. code-block:: console - xflash --erase-all --target=XCORE-AI-EXPLORER + make erase_all_example_freertos_dfu_v1 + +.. tab:: Windows + + .. code-block:: console + + nmake erase_all_example_freertos_dfu_v1 + +This target will use `xflash` to erase the flash of the device specified by the provided target XN file. After building the firmware and erasing the flash, the factory image must be flashed. From the xcore_sdk build folder run: -.. code-block:: console +.. tab:: Linux and Mac + + .. code-block:: console + + make flash_app_example_freertos_dfu_v1 + +.. tab:: Windows + + .. code-block:: console + + nmake flash_app_example_freertos_dfu_v1 - xflash --quad-spi-clock 50MHz --factory example_freertos_dfu_v1.xe --boot-partition-size 0x100000 +This target will use `xflash` to flash the application as a factory image with a boot partition size specified in dfu.cmake. The board may then be power cycled and will boot up the application. -Next, the user make create an upgrade image. From the xcore_sdk build folder run: +.. tab:: Linux and Mac -.. code-block:: console + .. code-block:: console - xflash --factory-version . --upgrade 0 example_freertos_dfu_v2.xe -o example_freertos_dfu_v2_upgrade.bin + make create_upgrade_img_example_freertos_dfu_v2 -OR -.. code-block:: console +.. tab:: Windows - make create_upgrade_img_example_freertos_dfu_v1 + .. code-block:: console -This will create an upgrade image file. + nmake create_upgrade_img_example_freertos_dfu_v2 -Populating the version of tools you are running. +This target will use `xflash` to create an upgrade image for the specified target. ******************** Running the firmware diff --git a/examples/freertos/dfu/dfu.cmake b/examples/freertos/dfu/dfu.cmake index 97a986143..d63611f4b 100644 --- a/examples/freertos/dfu/dfu.cmake +++ b/examples/freertos/dfu/dfu.cmake @@ -93,17 +93,27 @@ merge_binaries(example_freertos_dfu_v2 tile0_example_freertos_dfu_v2 tile1_examp #********************** # Create run and debug targets #********************** -create_erase_all_target(XCORE-AI-EXPLORER) - create_run_target(example_freertos_dfu_v1) create_debug_target(example_freertos_dfu_v1) -create_flash_app_dfu_target(example_freertos_dfu_v1 0x100000) +create_flash_app_target( + #[[ Target ]] example_freertos_dfu_v1 + #[[ Boot Partition Size ]] 0x100000 + #[[ Data Parition Contents ]] + #[[ Dependencies ]] +) query_tools_version() create_upgrade_img_target(example_freertos_dfu_v1 ${XTC_VERSION_MAJOR} ${XTC_VERSION_MINOR}) create_install_target(example_freertos_dfu_v1) +create_erase_all_target(example_freertos_dfu_v1 ${CMAKE_CURRENT_LIST_DIR}/XCORE-AI-EXPLORER.xn) create_run_target(example_freertos_dfu_v2) create_debug_target(example_freertos_dfu_v2) -create_flash_app_dfu_target(example_freertos_dfu_v2 0x100000) +create_flash_app_target( + #[[ Target ]] example_freertos_dfu_v2 + #[[ Boot Partition Size ]] 0x100000 + #[[ Data Parition Contents ]] + #[[ Dependencies ]] +) create_upgrade_img_target(example_freertos_dfu_v2 ${XTC_VERSION_MAJOR} ${XTC_VERSION_MINOR}) create_install_target(example_freertos_dfu_v2) +create_erase_all_target(example_freertos_dfu_v2 ${CMAKE_CURRENT_LIST_DIR}/XCORE-AI-EXPLORER.xn) From 9648e96f1b6356dcceef873a1433a259925c6700 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Tue, 15 Nov 2022 11:43:37 -0500 Subject: [PATCH 19/23] Update explorer board for generic cmake macros --- examples/freertos/explorer_board/README.rst | 4 ++-- .../freertos/explorer_board/explorer_board.cmake | 12 +++++------- modules/rtos | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/examples/freertos/explorer_board/README.rst b/examples/freertos/explorer_board/README.rst index 85a47aef9..bcae400d5 100644 --- a/examples/freertos/explorer_board/README.rst +++ b/examples/freertos/explorer_board/README.rst @@ -44,13 +44,13 @@ From the xcore_sdk build folder, create the filesystem and flash the device with .. code-block:: console - make flash_fs_example_freertos_explorer_board + make flash_app_example_freertos_explorer_board .. tab:: Windows .. code-block:: console - nmake flash_fs_example_freertos_explorer_board + nmake flash_app_example_freertos_explorer_board ******************** Running the firmware diff --git a/examples/freertos/explorer_board/explorer_board.cmake b/examples/freertos/explorer_board/explorer_board.cmake index 23d53a091..a2e5010d4 100644 --- a/examples/freertos/explorer_board/explorer_board.cmake +++ b/examples/freertos/explorer_board/explorer_board.cmake @@ -103,11 +103,9 @@ else() endif() create_filesystem_target(example_freertos_explorer_board) - -add_custom_target(flash_fs_example_freertos_explorer_board - COMMAND xflash --quad-spi-clock 50MHz --factory example_freertos_explorer_board.xe --boot-partition-size 0x100000 --data example_freertos_explorer_board_fat.fs - DEPENDS make_fs_example_freertos_explorer_board - COMMENT - "Flash filesystem" - VERBATIM +create_flash_app_target( + #[[ Target ]] example_freertos_explorer_board + #[[ Boot Partition Size ]] 0x100000 + #[[ Data Parition Contents ]] example_freertos_explorer_board_fat.fs + #[[ Dependencies ]] make_fs_example_freertos_explorer_board ) diff --git a/modules/rtos b/modules/rtos index 977f99473..b9a3990bc 160000 --- a/modules/rtos +++ b/modules/rtos @@ -1 +1 @@ -Subproject commit 977f994739538a5d72514140adc507f7bdbe53a7 +Subproject commit b9a3990bcd97b55ba1cce1779b2315bdcd62861f From 0f8867689e5236e1ab236c1fb393791cd465706a Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Tue, 15 Nov 2022 11:45:24 -0500 Subject: [PATCH 20/23] Update rtos submodule to develop --- modules/rtos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/rtos b/modules/rtos index b9a3990bc..5c1e94444 160000 --- a/modules/rtos +++ b/modules/rtos @@ -1 +1 @@ -Subproject commit b9a3990bcd97b55ba1cce1779b2315bdcd62861f +Subproject commit 5c1e94444b023f07232b55a9b9971fb2f9271053 From 7da9df765ba1492f6cde3b891717e4eefcb5ca13 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Tue, 15 Nov 2022 12:06:19 -0500 Subject: [PATCH 21/23] Add unique blinky to dfu example apps --- examples/freertos/dfu/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/freertos/dfu/src/main.c b/examples/freertos/dfu/src/main.c index 176f24a21..e440adfe3 100644 --- a/examples/freertos/dfu/src/main.c +++ b/examples/freertos/dfu/src/main.c @@ -37,7 +37,7 @@ void blinky_task(void *arg) { for (;;) { rtos_gpio_port_out(gpio_ctx_t0, gpio_port, led_val); - led_val ^= 0x0000000f; + led_val ^= VERSION; vTaskDelay(pdMS_TO_TICKS(1000)); } } From 8f9323188f118c5509a34581c05c75b25e4a77ce Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Tue, 15 Nov 2022 12:16:45 -0500 Subject: [PATCH 22/23] Update readme --- examples/freertos/dfu/README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/freertos/dfu/README.rst b/examples/freertos/dfu/README.rst index 818fa0779..85d8e1b9c 100644 --- a/examples/freertos/dfu/README.rst +++ b/examples/freertos/dfu/README.rst @@ -155,6 +155,8 @@ From the xcore_sdk build folder, the upgrade image can be written by running: dfu-util -e -d 4000 -a 1 -D example_freertos_dfu_v2_upgrade.bin +After updating the upgrade image it may be necessary to unplug the USB device to initiate a host re-enumeration. + The upgrade image can be read back by running: .. code-block:: console From 8f6a6d227d15debb41e3cc1049474eca617a2b17 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Thu, 17 Nov 2022 15:54:31 -0500 Subject: [PATCH 23/23] Add Windows specific instructions to readme --- examples/freertos/dfu/README.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/freertos/dfu/README.rst b/examples/freertos/dfu/README.rst index 85d8e1b9c..a498269c0 100644 --- a/examples/freertos/dfu/README.rst +++ b/examples/freertos/dfu/README.rst @@ -14,7 +14,9 @@ The application was verified using dfu-util. Installation instructions for respective operating system can be found `here `__ -If on Linux/Mac the user may need to add the USB device to their udev rules. This example defaults to Vendor ID 0xCAFE with Product ID 0x4000. +If on Linux the user may need to add the USB device to their udev rules. This example defaults to Vendor ID 0xCAFE with Product ID 0x4000. + +If on Windows the user may need to use a tool such as Zadig to install USB drivers. ********************* Building the firmware