From 0ce2452a088bd7f1397a8f55d736e4e0100cb32f Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Fri, 30 Dec 2022 19:21:53 -0500 Subject: [PATCH 01/11] Add non-bus-powered MSP430 re-enumeration support. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 80 +++++++++++++++++++-- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index b4dfda575c..60aa23b98c 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -131,11 +131,17 @@ void dcd_init (uint8_t rhport) USBVECINT = 0; - // Enable reset and wait for it before continuing. - USBIE |= RSTRIE; - - // Enable pullup. - USBCNF |= PUR_EN; + if(USBPWRCTL & USBBGVBV) // Bus power detected? + { + USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. + USBIE |= RSTRIE; // Enable reset and wait for it before continuing. + USBCNF |= PUR_EN; // Enable pullup. + } + else + { + USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. + USBCNF &= ~USB_EN; // Disable USB module until bus power is detected. + } USBKEYPID = 0; } @@ -618,6 +624,48 @@ static void handle_setup_packet(void) dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } +static void handle_bus_power_event(void *param) +{ + (void) param; + + osal_task_delay(2); // Bus power settling delay. + + USBKEYPID = USBKEY; + + if(USBPWRCTL & USBBGVBV) // Event caused by application of bus power. + { + USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. + USBPLLDIVB = USBPLLDIVB; // For some reason the PLL will *NOT* lock unless the divider + // register is re-written. The assumption here is that this + // register was already properly configured during board-level + // initialization. + USBPLLCTL |= (UPLLEN | UPFDEN); // Enable the PLL. + + uint16_t attempts = 0; + + do // Poll the PLL to check for a successful lock. + { + USBPLLIR = 0; + osal_task_delay(1); + attempts++; + } while ((attempts < 10) && (USBPLLIR != 0)); + + if(!USBPLLIR) // A successful lock is indicated by all PLL-related interrupt + { // flags being cleared. + dcd_init(0); // Re-initialize the USB module. + } + } + else // Event caused by removal of bus power. + { + USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. + USBPLLCTL &= ~(UPLLEN | UPFDEN); // Disable the PLL. + USBCNF = 0; // Disable the USB module. + dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, false); + } + + USBKEYPID = 0; +} + void dcd_int_handler(uint8_t rhport) { (void) rhport; @@ -646,11 +694,32 @@ void dcd_int_handler(uint8_t rhport) switch(curr_vector) { + case USBVECINT_NONE: + break; + case USBVECINT_RSTR: bus_reset(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); break; + case USBVECINT_PWR_VBUSOn: + case USBVECINT_PWR_VBUSOff: + USBKEYPID = USBKEY; + // Prevent (possibly) unstable power from generating spurious interrupts. + USBPWRCTL &= ~(VBONIE | VBOFFIE); + USBKEYPID = 0; + + { + dcd_event_t event; + + event.rhport = 0; + event.event_id = USBD_EVENT_FUNC_CALL; + event.func_call.func = handle_bus_power_event; + + dcd_event_handler(&event, true); + } + break; + // Clear the (hardware-enforced) NAK on EP 0 after a SETUP packet // is received. At this point, even though the hardware is no longer // forcing NAKs, the EP0 NAK bits should still be set to avoid @@ -710,7 +779,6 @@ void dcd_int_handler(uint8_t rhport) default: while(true); - break; } } From 87905d30ab8c94999bd69d0ae32f91ebdfef39d3 Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Tue, 3 Jan 2023 10:33:49 -0500 Subject: [PATCH 02/11] Increase bus powe stabilization delay. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 60aa23b98c..c1bef86fab 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -628,7 +628,7 @@ static void handle_bus_power_event(void *param) { (void) param; - osal_task_delay(2); // Bus power settling delay. + osal_task_delay(5); // Bus power settling delay. USBKEYPID = USBKEY; From 5a9b3eab6f3aa5e9fc71b902bfdbfef1acb29b44 Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Tue, 3 Jan 2023 11:58:22 -0500 Subject: [PATCH 03/11] Resolve erroneous data on enumeration. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index c1bef86fab..46b7d6458d 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -616,11 +616,20 @@ static void handle_setup_packet(void) _setup_packet[i] = setup_buf[i]; } - // Clearing SETUPIFG by reading USBVECINT does not set NAK, so now that we - // have a SETUP packet, force NAKs until tinyusb can handle the SETUP - // packet and prepare for a new xfer. + // Force NAKs until tinyusb can handle the SETUP packet and prepare + // for a new xfer. USBIEPCNT_0 |= NAK; USBOEPCNT_0 |= NAK; + + // Clear SETUPIFG to avoid handling in the USBVECINT switch statement. + // When handled there the NAKs applied to the endpoints above are + // cleared by hardware and the host will receive stale/duplicate data. + // + // Excerpt from MSP430x5xx and MSP430x6xx Family User's Guide: + // + // "...the SETUPIFG is cleared upon reading USBIV. In addition, the NAK on + // input endpoint 0 and output endpoint 0 is also cleared." + USBIFG &= ~SETUPIFG; dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } From b8b22b929e1bbbbae7c7337972129ae6f7192bc6 Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Tue, 3 Jan 2023 15:56:14 -0500 Subject: [PATCH 04/11] Allow re-enumeration on host power cycle. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 46b7d6458d..a0d9b3ea5e 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -94,7 +94,12 @@ static void bus_reset(void) USBOEPCNT_0 &= ~NAK; USBIEPCNT_0 &= ~NAK; - USBCTL |= FEN; // Enable responding to packets. + // Disable (subsequent) bus reset events from causing a functional + // reset of the USB module. + USBCTL &= ~FRSTE; + + // Enable responding to packets. + USBCTL |= FEN; // Dedicated buffers in hardware for SETUP and EP0, no setup needed. // Now safe to respond to SETUP packets. @@ -334,6 +339,10 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t if(epnum == 0) { + // Enables a bus reset to cause a functional reset of the USB + // module. + USBCTL |= FRSTE; + if(dir == TUSB_DIR_OUT) { // Interrupt will notify us when data was received. From a3286932add7c8142b94160522f19e5544e27c0a Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Sat, 8 Jul 2023 17:21:19 -0400 Subject: [PATCH 05/11] Correctly implementing recommended workarounds for erratas USB4 and USB10. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 40 ++++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index a0d9b3ea5e..25c2fb301f 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -94,10 +94,6 @@ static void bus_reset(void) USBOEPCNT_0 &= ~NAK; USBIEPCNT_0 &= ~NAK; - // Disable (subsequent) bus reset events from causing a functional - // reset of the USB module. - USBCTL &= ~FRSTE; - // Enable responding to packets. USBCTL |= FEN; @@ -108,6 +104,28 @@ static void bus_reset(void) USBKEYPID = 0; } +// Controls reset behavior of the USB module on receipt of a bus reset event. +// - enable: When true, bus reset events will cause a reset the USB module. +static void enable_functional_reset(const bool enable) +{ + // Check whether or not the USB configuration registers were + // locked prior to this function being called so that, if + // necessary, the lock state can be restored on exit. + bool unlocked = (USBKEYPID == 0xA528) ? true : false; + + if(!unlocked) USBKEYPID = USBKEY; + + if(enable) + { + USBCTL |= FRSTE; + } + else + { + USBCTL &= ~FRSTE; + } + + if(!unlocked) USBKEYPID = 0; +} /*------------------------------------------------------------------*/ /* Controller API @@ -339,10 +357,6 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t if(epnum == 0) { - // Enables a bus reset to cause a functional reset of the USB - // module. - USBCTL |= FRSTE; - if(dir == TUSB_DIR_OUT) { // Interrupt will notify us when data was received. @@ -638,7 +652,11 @@ static void handle_setup_packet(void) // // "...the SETUPIFG is cleared upon reading USBIV. In addition, the NAK on // input endpoint 0 and output endpoint 0 is also cleared." + USBIEPCNF_0 &= ~UBME; // Errata USB10 workaround. + USBOEPCNF_0 &= ~UBME; // Errata USB10 workaround. USBIFG &= ~SETUPIFG; + USBIEPCNF_0 |= UBME; // Errata USB10 workaround. + USBOEPCNF_0 |= UBME; // Errata USB10 workaround. dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } @@ -661,7 +679,7 @@ static void handle_bus_power_event(void *param) uint16_t attempts = 0; - do // Poll the PLL to check for a successful lock. + do // Poll the PLL, checking for a successful lock. { USBPLLIR = 0; osal_task_delay(1); @@ -694,6 +712,7 @@ void dcd_int_handler(uint8_t rhport) if(setup_status) { + enable_functional_reset(true); handle_setup_packet(); } @@ -716,6 +735,7 @@ void dcd_int_handler(uint8_t rhport) break; case USBVECINT_RSTR: + enable_functional_reset(false); // Errata USB4 workaround. bus_reset(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); break; @@ -762,10 +782,12 @@ void dcd_int_handler(uint8_t rhport) break; case USBVECINT_INPUT_ENDPOINT0: + enable_functional_reset(true); transmit_packet(0); break; case USBVECINT_OUTPUT_ENDPOINT0: + enable_functional_reset(true); receive_packet(0); break; From 5d3b0896e1eeb1bd45bcb4f2031c7a571f1a16cb Mon Sep 17 00:00:00 2001 From: Clifroy Henry Date: Sat, 8 Jul 2023 17:36:08 -0400 Subject: [PATCH 06/11] Removed trailing whitespace. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 25c2fb301f..870cd725d9 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -688,7 +688,7 @@ static void handle_bus_power_event(void *param) if(!USBPLLIR) // A successful lock is indicated by all PLL-related interrupt { // flags being cleared. - dcd_init(0); // Re-initialize the USB module. + dcd_init(0); // Re-initialize the USB module. } } else // Event caused by removal of bus power. From abddc850ac8bc1377d8c1785a76bbba22405c5e8 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Apr 2024 21:49:55 +0700 Subject: [PATCH 07/11] add cmake support for msp430 --- .idea/cmake.xml | 12 ++- examples/build_system/cmake/cpu/msp430.cmake | 7 ++ .../cmake/toolchain/msp430_gcc.cmake | 52 ++++++++++++ hw/bsp/family_support.cmake | 15 ++++ .../boards/msp_exp430f5529lp/board.cmake | 9 ++ hw/bsp/msp430/family.cmake | 84 +++++++++++++++++++ hw/bsp/msp430/family.mk | 9 +- 7 files changed, 180 insertions(+), 8 deletions(-) create mode 100644 examples/build_system/cmake/cpu/msp430.cmake create mode 100644 examples/build_system/cmake/toolchain/msp430_gcc.cmake create mode 100644 hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake create mode 100644 hw/bsp/msp430/family.cmake diff --git a/.idea/cmake.xml b/.idea/cmake.xml index ebc6a05708..c361e237d9 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -2,8 +2,9 @@ - - + + + @@ -44,7 +45,7 @@ - + @@ -57,8 +58,10 @@ - + + + @@ -82,6 +85,7 @@ + \ No newline at end of file diff --git a/examples/build_system/cmake/cpu/msp430.cmake b/examples/build_system/cmake/cpu/msp430.cmake new file mode 100644 index 0000000000..b4b47a2e86 --- /dev/null +++ b/examples/build_system/cmake/cpu/msp430.cmake @@ -0,0 +1,7 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(FREERTOS_PORT GCC_MSP430F449 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + set(FREERTOS_PORT IAR_MSP430 CACHE INTERNAL "") + +endif () diff --git a/examples/build_system/cmake/toolchain/msp430_gcc.cmake b/examples/build_system/cmake/toolchain/msp430_gcc.cmake new file mode 100644 index 0000000000..6291ce5a4f --- /dev/null +++ b/examples/build_system/cmake/toolchain/msp430_gcc.cmake @@ -0,0 +1,52 @@ +set(CMAKE_SYSTEM_NAME Generic) + +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "msp430-elf-gcc") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "msp430-elf-g++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) + +set(CMAKE_SIZE "msp430-elf-size" CACHE FILEPATH "") +set(CMAKE_OBJCOPY "msp430-elf-objcopy" CACHE FILEPATH "") +set(CMAKE_OBJDUMP "msp430-elf-objdump" CACHE FILEPATH "") + +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) + +# Look for includes and libraries only in the target system prefix. +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# pass TOOLCHAIN_CPU to +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR) + +include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake) + +# enable all possible warnings for building examples +list(APPEND TOOLCHAIN_COMMON_FLAGS + -fdata-sections + -ffunction-sections + -fsingle-precision-constant + -fno-strict-aliasing + ) + +list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS + -Wl,--print-memory-usage + -Wl,--gc-sections + -Wl,--cref + ) + +include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake) + +# try_compile is cmake test compiling its own example, +# pass -nostdlib to skip stdlib linking +get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) +if (IS_IN_TRY_COMPILE) + set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") +endif () diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 4ccd6e4f28..d4f355e0c8 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -460,6 +460,21 @@ function(family_flash_dfu_util TARGET OPTION) ) endfunction() +function(family_flash_msp430flasher TARGET) + if (NOT DEFINED MSP430Flasher) + set(MSP430FLASHER MSP430Flasher) + endif () + + # set LD_LIBRARY_PATH to find libmsp430.so (directory containing MSP430Flasher) + find_program(MSP430FLASHER_PATH MSP430Flasher) + get_filename_component(MSP430FLASHER_PARENT_DIR "${MSP430FLASHER_PATH}" DIRECTORY) + add_custom_target(${TARGET}-msp430flasher + DEPENDS ${TARGET} + COMMAND ${CMAKE_COMMAND} -E env LD_LIBRARY_PATH=${MSP430FLASHER_PARENT_DIR} + ${MSP430FLASHER} -w $/${TARGET}.hex -z [VCC] + ) +endfunction() + #---------------------------------- # Family specific #---------------------------------- diff --git a/hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake new file mode 100644 index 0000000000..59f5912634 --- /dev/null +++ b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake @@ -0,0 +1,9 @@ +set(MCU_VARIANT msp430f5529) +set(LD_FILE_GNU ${SDK_DIR}/msp430f5529.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} INTERFACE + __MSP430F5529__ + ) + +endfunction() diff --git a/hw/bsp/msp430/family.cmake b/hw/bsp/msp430/family.cmake new file mode 100644 index 0000000000..e0b4ed28af --- /dev/null +++ b/hw/bsp/msp430/family.cmake @@ -0,0 +1,84 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/ti/msp430/msp430-gcc-support-files/include) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR msp430 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/msp430_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS MSP430x5xx CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (NOT TARGET ${BOARD_TARGET}) + add_library(${BOARD_TARGET} INTERFACE) + target_compile_definitions(${BOARD_TARGET} INTERFACE + CFG_TUD_ENDPOINT0_SIZE=8 + CFG_EXAMPLE_VIDEO_READONLY + CFG_EXAMPLE_MSC_READONLY + ) + target_include_directories(${BOARD_TARGET} INTERFACE + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${SDK_DIR} + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} INTERFACE + "LINKER:--script=${LD_FILE_GNU}" + -L${SDK_DIR} + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} INTERFACE + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_MSP430x5xx ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_msp430flasher(${TARGET}) +endfunction() diff --git a/hw/bsp/msp430/family.mk b/hw/bsp/msp430/family.mk index ceafa6ec12..f1c6f9cf2d 100644 --- a/hw/bsp/msp430/family.mk +++ b/hw/bsp/msp430/family.mk @@ -2,6 +2,8 @@ CROSS_COMPILE = msp430-elf- DEPS_SUBMODULES += hw/mcu/ti SKIP_NANOLIB = 1 +SDK_DIR = hw/mcu/ti/msp430/msp430-gcc-support-files/include + CFLAGS += \ -D__MSP430F5529__ \ -DCFG_TUSB_MCU=OPT_MCU_MSP430x5xx \ @@ -9,14 +11,13 @@ CFLAGS += \ -DCFG_TUD_ENDPOINT0_SIZE=8 # All source paths should be relative to the top level. -LD_FILE = hw/mcu/ti/msp430/msp430-gcc-support-files/include/msp430f5529.ld -LDINC += $(TOP)/hw/mcu/ti/msp430/msp430-gcc-support-files/include -LDFLAGS += $(addprefix -L,$(LDINC)) +LD_FILE = ${SDK_DIR}/msp430f5529.ld +LDFLAGS += -L${TOP}/${SDK_DIR} SRC_C += src/portable/ti/msp430x5xx/dcd_msp430x5xx.c INC += \ - $(TOP)/hw/mcu/ti/msp430/msp430-gcc-support-files/include \ + ${TOP}/${SDK_DIR} \ $(TOP)/$(BOARD_PATH) # export for libmsp430.so to same installation From bf649988ef8ffd39435dddc747f953faf78db471 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Apr 2024 12:06:13 +0700 Subject: [PATCH 08/11] add blocking delay for msp430 with max 25mhz --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 4 +- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 59 ++++++++++--------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 7bf726f3ff..bb96b4937d 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -544,14 +544,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) { * - Software should ensure that a small delay is included before accessing the SRAM contents. This delay * should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode * - Since H5 can run up to 250Mhz -> 1 cycle = 4ns. Per errata, we need to wait 200 cycles. Though executing code - * also takes time, so we'll wait 40 cycles (count = 20). + * also takes time, so we'll wait 60 cycles (count = 20). * - Since Low Speed mode is not supported/popular, we will ignore it for now. * * Note: this errata also seems to apply to G0, U5, H5 etc. */ volatile uint32_t cycle_count = 20; // defined as PCD_RX_PMA_CNT in stm32 hal_driver while (cycle_count > 0U) { - cycle_count--; // each count take 2 cycle (1 cycle for sub, 1 cycle for compare/jump) + cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare) } #endif diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 870cd725d9..8005f5f7be 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -154,14 +154,11 @@ void dcd_init (uint8_t rhport) USBVECINT = 0; - if(USBPWRCTL & USBBGVBV) // Bus power detected? - { + if(USBPWRCTL & USBBGVBV) {// Bus power detected? USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. USBIE |= RSTRIE; // Enable reset and wait for it before continuing. USBCNF |= PUR_EN; // Enable pullup. - } - else - { + } else { USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. USBCNF &= ~USB_EN; // Disable USB module until bus power is detected. } @@ -639,8 +636,7 @@ static void handle_setup_packet(void) _setup_packet[i] = setup_buf[i]; } - // Force NAKs until tinyusb can handle the SETUP packet and prepare - // for a new xfer. + // Force NAKs until tinyusb can handle the SETUP packet and prepare for a new xfer. USBIEPCNT_0 |= NAK; USBOEPCNT_0 |= NAK; @@ -660,16 +656,28 @@ static void handle_setup_packet(void) dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } -static void handle_bus_power_event(void *param) -{ +#if CFG_TUSB_OS == OPT_OS_NONE +TU_ATTR_ALWAYS_INLINE static inline void tu_delay(uint32_t ms) { + // msp430 can run up to 25Mhz -> 40ns per cycle. 1 ms = 25000 cycles + // each loop need 4 cycle: 1 sub, 1 cmp, 1 jump, 1 nop + volatile uint32_t cycles = (25000 * ms) >> 2; + while (cycles > 0) { + cycles--; + asm("nop"); + } +} +#else +#define tu_delay(ms) osal_task_delay(ms) +#endif + +static void handle_bus_power_event(void *param) { (void) param; - osal_task_delay(5); // Bus power settling delay. + tu_delay(5); // Bus power settling delay. USBKEYPID = USBKEY; - if(USBPWRCTL & USBBGVBV) // Event caused by application of bus power. - { + if(USBPWRCTL & USBBGVBV) { // Event caused by application of bus power. USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. USBPLLDIVB = USBPLLDIVB; // For some reason the PLL will *NOT* lock unless the divider // register is re-written. The assumption here is that this @@ -678,21 +686,17 @@ static void handle_bus_power_event(void *param) USBPLLCTL |= (UPLLEN | UPFDEN); // Enable the PLL. uint16_t attempts = 0; - - do // Poll the PLL, checking for a successful lock. - { + do { // Poll the PLL, checking for a successful lock. USBPLLIR = 0; - osal_task_delay(1); + tu_delay(1); attempts++; } while ((attempts < 10) && (USBPLLIR != 0)); - if(!USBPLLIR) // A successful lock is indicated by all PLL-related interrupt - { // flags being cleared. + // A successful lock is indicated by all PLL-related interrupt flags being cleared. + if(!USBPLLIR) { dcd_init(0); // Re-initialize the USB module. } - } - else // Event caused by removal of bus power. - { + } else { // Event caused by removal of bus power. USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. USBPLLCTL &= ~(UPLLEN | UPFDEN); // Disable the PLL. USBCNF = 0; // Disable the USB module. @@ -741,20 +745,19 @@ void dcd_int_handler(uint8_t rhport) break; case USBVECINT_PWR_VBUSOn: - case USBVECINT_PWR_VBUSOff: + case USBVECINT_PWR_VBUSOff: { USBKEYPID = USBKEY; // Prevent (possibly) unstable power from generating spurious interrupts. USBPWRCTL &= ~(VBONIE | VBOFFIE); USBKEYPID = 0; - { - dcd_event_t event; + dcd_event_t event; - event.rhport = 0; - event.event_id = USBD_EVENT_FUNC_CALL; - event.func_call.func = handle_bus_power_event; + event.rhport = 0; + event.event_id = USBD_EVENT_FUNC_CALL; + event.func_call.func = handle_bus_power_event; - dcd_event_handler(&event, true); + dcd_event_handler(&event, true); } break; From b2acbd305d29cea15fb4bd8e5cbc464546fdd8b7 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Apr 2024 12:52:10 +0700 Subject: [PATCH 09/11] use cmake to build msp430 --- .github/workflows/build_msp430.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml index f913df913e..53921b3087 100644 --- a/.github/workflows/build_msp430.yml +++ b/.github/workflows/build_msp430.yml @@ -63,8 +63,7 @@ jobs: - name: Set Toolchain Path run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} - - name: Build - run: python3 tools/build_make.py ${{ matrix.family }} + run: | + python3 tools/get_deps.py ${{ matrix.family }} + python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel From 9561e3826700c872ccde111d52cb381da939a25c Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Apr 2024 22:35:52 +0700 Subject: [PATCH 10/11] install ninja build for msp430 --- .github/workflows/build_msp430.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml index 53921b3087..95d2127082 100644 --- a/.github/workflows/build_msp430.yml +++ b/.github/workflows/build_msp430.yml @@ -61,7 +61,9 @@ jobs: tar -C ~/cache/toolchain -xaf toolchain.tar.bz2 - name: Set Toolchain Path - run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + run: | + echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + sudo apt install -y ninja-build - name: Build run: | From afb66a955c51f6ef36d0e544c44ee06a88eb2b2b Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Apr 2024 22:49:08 +0700 Subject: [PATCH 11/11] update msp430 make build --- examples/build_system/make/cpu/msp430.mk | 8 ++++++++ hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk | 4 ++++ hw/bsp/msp430/family.mk | 5 ++--- 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 examples/build_system/make/cpu/msp430.mk create mode 100644 hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk diff --git a/examples/build_system/make/cpu/msp430.mk b/examples/build_system/make/cpu/msp430.mk new file mode 100644 index 0000000000..06340d23b2 --- /dev/null +++ b/examples/build_system/make/cpu/msp430.mk @@ -0,0 +1,8 @@ +ifeq ($(TOOLCHAIN),gcc) + # nothing to add +else ifeq ($(TOOLCHAIN),iar) + # nothing to add +endif + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/GCC_MSP430F449 diff --git a/hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk new file mode 100644 index 0000000000..b45c62e830 --- /dev/null +++ b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk @@ -0,0 +1,4 @@ +CFLAGS += \ + -D__MSP430F5529__ \ + +LD_FILE = ${SDK_DIR}/msp430f5529.ld diff --git a/hw/bsp/msp430/family.mk b/hw/bsp/msp430/family.mk index f1c6f9cf2d..06508ab2cd 100644 --- a/hw/bsp/msp430/family.mk +++ b/hw/bsp/msp430/family.mk @@ -4,14 +4,13 @@ SKIP_NANOLIB = 1 SDK_DIR = hw/mcu/ti/msp430/msp430-gcc-support-files/include +include $(TOP)/$(BOARD_PATH)/board.mk + CFLAGS += \ - -D__MSP430F5529__ \ -DCFG_TUSB_MCU=OPT_MCU_MSP430x5xx \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_TUD_ENDPOINT0_SIZE=8 -# All source paths should be relative to the top level. -LD_FILE = ${SDK_DIR}/msp430f5529.ld LDFLAGS += -L${TOP}/${SDK_DIR} SRC_C += src/portable/ti/msp430x5xx/dcd_msp430x5xx.c