diff --git a/.gitmodules b/.gitmodules index 9afa0d195..c7b396187 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,9 +7,6 @@ [submodule "tools/uf2"] path = tools/uf2 url = https://github.com/microsoft/uf2.git -[submodule "hw/mcu/nxp/lpc_driver"] - path = hw/mcu/nxp/lpc_driver - url = https://github.com/hathach/lpc_driver.git [submodule "hw/mcu/st/st_driver"] path = hw/mcu/st/st_driver url = https://github.com/hathach/st_driver.git @@ -19,3 +16,6 @@ [submodule "hw/mcu/ti"] path = hw/mcu/ti url = https://github.com/hathach/ti_driver.git +[submodule "hw/mcu/nxp"] + path = hw/mcu/nxp + url = https://github.com/hathach/nxp_driver.git diff --git a/.travis.yml b/.travis.yml index 6dfc507fc..2413e4225 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,11 @@ install: - gem install ceedling before_script: + - wget -O /tmp/riscv-toolchain.tgz https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v8.3.0-1.1/xpack-riscv-none-embed-gcc-8.3.0-1.1-linux-x64.tgz + - tar -xzf /tmp/riscv-toolchain.tgz + - export PATH=$PWD/xPacks/riscv-none-embed-gcc/8.3.0-1.1/bin:$PATH - arm-none-eabi-gcc --version + - riscv-none-embed-gcc --version script: # Build all examples diff --git a/README.md b/README.md index 02fb8257c..162b707d4 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,14 @@ TinyUSB is an open-source cross-platform USB Host/Device stack for embedded syst The stack supports the following MCUs -- **Nordic:** nRF52840 -- **NXP:** LPC Series: 11Uxx, 13xx, 175x_6x, 177x_8x, 18xx, 40xx, 43xx, 51Uxx, 54xxx, 55xx - **MicroChip:** SAMD21, SAMD51 (device only) +- **Nordic:** nRF52840, nRF52833 +- **NXP:** + - LPC Series: 11Uxx, 13xx, 175x_6x, 177x_8x, 18xx, 40xx, 43xx, 51Uxx, 54xxx, 55xx + - iMX RT Series: RT1011, RT1015, RT1021, RT1052, RT1062, RT1064 - **Sony:** CXD56 - **ST:** STM32 series: L0, F0, F1, F2, F3, F4, F7, H7 (device only) +- **[valentyusb](https://github.com/im-tomu/valentyusb)** eptri [Here is the list of supported Boards](docs/boards.md) that can be used with provided examples. diff --git a/docs/boards.md b/docs/boards.md index 608cbf4eb..7006aae5d 100644 --- a/docs/boards.md +++ b/docs/boards.md @@ -21,8 +21,19 @@ This code base already had supported for a handful of following boards - [Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062) - [Adafruit Circuit Playground Bluefruit](https://www.adafruit.com/product/4333) +- [Maker Diary nRF52840 MDK Dongle](https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle) - [Nordic nRF52840 Development Kit (aka pca10056)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) - [Nordic nRF52840 Dongle (aka pca10059)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) +- [Nordic nRF52833 Development Kit (aka pca10100)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52833-DK) + +### NXP iMX RT + +- [MIMX RT1010 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/i.mx-rt1010-evaluation-kit:MIMXRT1010-EVK) +- [MIMX RT1015 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/i.mx-rt1015-evaluation-kit:MIMXRT1015-EVK) +- [MIMX RT1020 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/i.mx-rt1020-evaluation-kit:MIMXRT1020-EVK) +- [MIMX RT1050 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/i.mx-rt1050-evaluation-kit:MIMXRT1050-EVK) +- [MIMX RT1060 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/mimxrt1060-evk-i.mx-rt1060-evaluation-kit:MIMXRT1060-EVK) +- [MIMX RT1064 Evaluation Kit](https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/mimxrt1064-evk-i.mx-rt1064-evaluation-kit:MIMXRT1064-EVK) ### NXP LPC @@ -45,7 +56,7 @@ This code base already had supported for a handful of following boards ### ST STM32 -- Adafruit Feather STM32F405 +- [Adafruit Feather STM32F405](https://www.adafruit.com/product/4382) - [Micro Python PyBoard v1.1](https://store.micropython.org/product/PYBv1.1) - [STM32 L035c8 Discovery](https://www.st.com/en/evaluation-tools/32l0538discovery.html) - [STM32 F070rb Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f070rb.html) @@ -59,6 +70,10 @@ This code base already had supported for a handful of following boards - [STM32 F767zi Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f767zi.html) - [STM32 H743zi Nucleo](https://www.st.com/en/evaluation-tools/nucleo-h743zi.html) +### Tomu + +- [Fomu](https://www.crowdsupply.com/sutajio-kosagi/fomu) + ## Add your own board If you don't possess any of supported board above. Don't worry you can easily implemented your own one by following this guide as long as the mcu is supported. diff --git a/docs/porting.md b/docs/porting.md index a38ff0192..deb1b9efb 100644 --- a/docs/porting.md +++ b/docs/porting.md @@ -1,6 +1,6 @@ # Porting -TinyUSB is designed to be a universal USB protocol stack for low-cost 32 bit microcontrollers. It +TinyUSB is designed to be a universal USB protocol stack for microcontrollers. It handles most of the high level USB protocol and relies on the microcontroller's USB peripheral for data transactions on different endpoints. Porting is the process of adding low-level support for the rest of the common stack. Once the low-level is implemented, it is very easy to add USB support @@ -25,8 +25,6 @@ Unless, you've read ahead, this will fail miserably. Now, lets get it to fail le One of the first things to change is the `-DCFG_TUSB_MCU` cflag in the `board.mk` file. This is used to tell TinyUSB what platform is being built. So, add an entry to `src/tusb_option.h` and update the CFLAG to match. -Also, add an entry for the board in `hw/bsp/board.h`. The CFLAG is auto-added. - Update `board.mk`'s VENDOR and CHIP_FAMILY values when creating the directory for the struct files. Duplicate one of the other sources from `src/portable` into `src/portable//` and delete all of the implementation internals. We'll cover what everything there does later. For now, get it compiling. ## Implementation @@ -104,7 +102,7 @@ Calls to this look like: dcd_event_setup_received(0, setup, true); -As before with `dcd_event_bus_signal` the first argument is the USB peripheral number and the third is true to signal its being called from an interrup handler. The middle argument is byte array of length 8 with the contents of the SETUP packet. It can be stack allocated because it is copied into the queue. +As before with `dcd_event_bus_signal` the first argument is the USB peripheral number and the third is true to signal its being called from an interrupt handler. The middle argument is byte array of length 8 with the contents of the SETUP packet. It can be stack allocated because it is copied into the queue. #### Endpoints diff --git a/examples/device/cdc_msc/src/main.c b/examples/device/cdc_msc/src/main.c index e1b9ab113..a407e2ddd 100644 --- a/examples/device/cdc_msc/src/main.c +++ b/examples/device/cdc_msc/src/main.c @@ -136,7 +136,7 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) if ( dtr && rts ) { // print initial message when connected - tud_cdc_write_str("\r\nTinyUSB CDC MSC HID device example\r\n"); + tud_cdc_write_str("\r\nTinyUSB CDC MSC device example\r\n"); } } diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index 4455f665e..5b7a1671e 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -39,7 +39,7 @@ #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE diff --git a/examples/device/cdc_msc_hid_freertos/src/tusb_config.h b/examples/device/cdc_msc_hid_freertos/src/tusb_config.h index f84874ab1..6788a7483 100644 --- a/examples/device/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_hid_freertos/src/tusb_config.h @@ -39,7 +39,7 @@ #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE diff --git a/examples/device/dfu_rt/src/tusb_config.h b/examples/device/dfu_rt/src/tusb_config.h index b4f7a5562..27afdb6b6 100644 --- a/examples/device/dfu_rt/src/tusb_config.h +++ b/examples/device/dfu_rt/src/tusb_config.h @@ -21,7 +21,7 @@ #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE diff --git a/examples/device/hid_composite/src/tusb_config.h b/examples/device/hid_composite/src/tusb_config.h index 8d29f10be..dd360741d 100644 --- a/examples/device/hid_composite/src/tusb_config.h +++ b/examples/device/hid_composite/src/tusb_config.h @@ -39,7 +39,7 @@ #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE diff --git a/examples/device/hid_generic_inout/src/tusb_config.h b/examples/device/hid_generic_inout/src/tusb_config.h index a7ce7acf8..0053a7d0a 100644 --- a/examples/device/hid_generic_inout/src/tusb_config.h +++ b/examples/device/hid_generic_inout/src/tusb_config.h @@ -39,7 +39,7 @@ #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE diff --git a/examples/device/midi_test/src/tusb_config.h b/examples/device/midi_test/src/tusb_config.h index fcd6b97c2..5837db4eb 100644 --- a/examples/device/midi_test/src/tusb_config.h +++ b/examples/device/midi_test/src/tusb_config.h @@ -39,7 +39,7 @@ #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE diff --git a/examples/device/msc_dual_lun/src/tusb_config.h b/examples/device/msc_dual_lun/src/tusb_config.h index b45e9c4dc..baf857b71 100644 --- a/examples/device/msc_dual_lun/src/tusb_config.h +++ b/examples/device/msc_dual_lun/src/tusb_config.h @@ -39,7 +39,7 @@ #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE diff --git a/examples/device/usbtmc/src/tusb_config.h b/examples/device/usbtmc/src/tusb_config.h index 9141e6a5a..2932ea4d1 100644 --- a/examples/device/usbtmc/src/tusb_config.h +++ b/examples/device/usbtmc/src/tusb_config.h @@ -21,7 +21,7 @@ #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE diff --git a/examples/device/webusb_serial/src/tusb_config.h b/examples/device/webusb_serial/src/tusb_config.h index 8a73e8353..30acdaccf 100644 --- a/examples/device/webusb_serial/src/tusb_config.h +++ b/examples/device/webusb_serial/src/tusb_config.h @@ -39,7 +39,7 @@ #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE diff --git a/examples/host/cdc_msc_hid/ses/lpc175x_6x/lpc175x_6x.emProject b/examples/host/cdc_msc_hid/ses/lpc175x_6x/lpc175x_6x.emProject index ecd2dc716..ba5a9cea7 100644 --- a/examples/host/cdc_msc_hid/ses/lpc175x_6x/lpc175x_6x.emProject +++ b/examples/host/cdc_msc_hid/ses/lpc175x_6x/lpc175x_6x.emProject @@ -29,7 +29,7 @@ linker_memory_map_file="LPC1769_MemoryMap.xml" linker_section_placement_file="flash_placement.xml" linker_section_placements_segments="FLASH RX 0x00000000 0x00080000;RAM RWX 0x10000000 0x00008000" - macros="DeviceFamily=LPC1700;DeviceSubFamily=LPC176x;Target=LPC1769;Placement=Flash;rootDir=../../../../..;lpcDir=../../../../../hw/mcu/nxp/lpc_chip_175x_6x" + macros="DeviceFamily=LPC1700;DeviceSubFamily=LPC176x;Target=LPC1769;Placement=Flash;rootDir=../../../../..;lpcDir=../../../../../hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x" project_directory="" project_type="Executable" target_reset_script="Reset();" @@ -46,40 +46,40 @@ - - + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + diff --git a/examples/host/cdc_msc_hid/ses/lpc18xx/lpc18xx.emProject b/examples/host/cdc_msc_hid/ses/lpc18xx/lpc18xx.emProject index 8e9123dc7..2dd7de552 100644 --- a/examples/host/cdc_msc_hid/ses/lpc18xx/lpc18xx.emProject +++ b/examples/host/cdc_msc_hid/ses/lpc18xx/lpc18xx.emProject @@ -24,7 +24,7 @@ gcc_entry_point="Reset_Handler" linker_memory_map_file="$(ProjectDir)/LPC1857_MemoryMap.xml" linker_section_placement_file="$(ProjectDir)/flash_placement.xml" - macros="DeviceFamily=LPC1800;DeviceSubFamily=LPC185x;Target=LPC1857;Placement=Flash;rootDir=../../../../..;lpcDir=../../../../../hw/mcu/nxp/lpc_chip_18xx" + macros="DeviceFamily=LPC1800;DeviceSubFamily=LPC185x;Target=LPC1857;Placement=Flash;rootDir=../../../../..;lpcDir=../../../../../hw/mcu/nxp/lpcopen/lpc18xx/lpc_chip_18xx" package_dependencies="LPC1800" project_directory="" project_type="Executable" @@ -51,52 +51,51 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - + + + + + diff --git a/examples/host/cdc_msc_hid/ses/lpc40xx/lpc40xx.emProject b/examples/host/cdc_msc_hid/ses/lpc40xx/lpc40xx.emProject index 63cf74840..bfb7922a3 100644 --- a/examples/host/cdc_msc_hid/ses/lpc40xx/lpc40xx.emProject +++ b/examples/host/cdc_msc_hid/ses/lpc40xx/lpc40xx.emProject @@ -26,7 +26,7 @@ gcc_entry_point="Reset_Handler" linker_memory_map_file="$(ProjectDir)/LPC4088FBD208_MemoryMap.xml" linker_section_placement_file="$(ProjectDir)/flash_placement.xml" - macros="DeviceFamily=LPC4000;DeviceSubFamily=LPC408x;Target=LPC4088FBD208;Placement=Flash;rootDir=../../../../..;lpcDir=../../../../../hw/mcu/nxp/lpc_chip_40xx" + macros="DeviceFamily=LPC4000;DeviceSubFamily=LPC408x;Target=LPC4088FBD208;Placement=Flash;rootDir=../../../../..;lpcDir=../../../../../hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx" package_dependencies="LPC4000" project_directory="" project_type="Executable" @@ -53,40 +53,39 @@ - - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + diff --git a/examples/host/cdc_msc_hid/ses/lpc43xx/lpc43xx.emProject b/examples/host/cdc_msc_hid/ses/lpc43xx/lpc43xx.emProject index 425f42a58..3b93c623c 100644 --- a/examples/host/cdc_msc_hid/ses/lpc43xx/lpc43xx.emProject +++ b/examples/host/cdc_msc_hid/ses/lpc43xx/lpc43xx.emProject @@ -29,7 +29,7 @@ linker_memory_map_file="LPC4357 Cortex-M4_MemoryMap.xml" linker_section_placement_file="flash_placement.xml" linker_section_placements_segments="FLASH RX 0x1a000000 0x00080000;RAM RWX 0x10000000 0x00008000" - macros="DeviceFamily=LPC4300;DeviceSubFamily=LPC435x;Target=LPC4357 Cortex-M4;Placement=Flash;rootDir=../../../../..;lpcDir=../../../../../hw/mcu/nxp/lpc_chip_43xx" + macros="DeviceFamily=LPC4300;DeviceSubFamily=LPC435x;Target=LPC4357 Cortex-M4;Placement=Flash;rootDir=../../../../..;lpcDir=../../../../../hw/mcu/nxp/lpcopen/lpc43xx/lpc_chip_43xx" project_directory="" project_type="Executable" target_reset_script="Reset();" @@ -46,8 +46,7 @@ - - + @@ -56,52 +55,52 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - + + + + + + + + diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 7a18c692b..7c1818109 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -40,7 +40,7 @@ #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST diff --git a/examples/make.mk b/examples/make.mk index c2e0559fb..12ce3fd0c 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -2,8 +2,12 @@ # Common make definition for all examples # -# Compiler +# Compiler +ifeq ($(BOARD), fomu) +CROSS_COMPILE = riscv-none-embed- +else CROSS_COMPILE = arm-none-eabi- +endif CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ OBJCOPY = $(CROSS_COMPILE)objcopy @@ -81,11 +85,7 @@ CFLAGS += \ ifeq ($(DEBUG), 1) CFLAGS += -Og -ggdb else - ifneq ($(BOARD),spresense) - CFLAGS += -flto -Os - else - CFLAGS += -Os - endif + CFLAGS += -Os endif # TUSB Logging option diff --git a/hw/bsp/circuitplayground_bluefruit/board.mk b/hw/bsp/circuitplayground_bluefruit/board.mk index 72b9ddfbe..bfeaa2355 100644 --- a/hw/bsp/circuitplayground_bluefruit/board.mk +++ b/hw/bsp/circuitplayground_bluefruit/board.mk @@ -1,11 +1,12 @@ CFLAGS += \ - -mthumb \ - -mabi=aapcs \ - -mcpu=cortex-m4 \ - -mfloat-abi=hard \ - -mfpu=fpv4-sp-d16 \ - -DCFG_TUSB_MCU=OPT_MCU_NRF5X \ - -DNRF52840_XXAA \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -DCFG_TUSB_MCU=OPT_MCU_NRF5X \ + -DNRF52840_XXAA \ -DCONFIG_GPIO_AS_PINRESET # nrfx issue undef _ARMCC_VERSION usage https://github.com/NordicSemiconductor/nrfx/issues/49 @@ -23,17 +24,17 @@ LD_FILE = hw/bsp/circuitplayground_bluefruit/nrf52840_s140_v6.ld LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk SRC_C += \ - hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \ - hw/mcu/nordic/nrfx/mdk/system_nrf52840.c \ + hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \ + hw/mcu/nordic/nrfx/mdk/system_nrf52840.c \ INC += \ - $(TOP)/hw/mcu/nordic/cmsis/Include \ - $(TOP)/hw/mcu/nordic \ - $(TOP)/hw/mcu/nordic/nrfx \ - $(TOP)/hw/mcu/nordic/nrfx/mdk \ - $(TOP)/hw/mcu/nordic/nrfx/hal \ - $(TOP)/hw/mcu/nordic/nrfx/drivers/include \ - $(TOP)/hw/mcu/nordic/nrfx/drivers/src \ + $(TOP)/hw/mcu/nordic/cmsis/Include \ + $(TOP)/hw/mcu/nordic \ + $(TOP)/hw/mcu/nordic/nrfx \ + $(TOP)/hw/mcu/nordic/nrfx/mdk \ + $(TOP)/hw/mcu/nordic/nrfx/hal \ + $(TOP)/hw/mcu/nordic/nrfx/drivers/include \ + $(TOP)/hw/mcu/nordic/nrfx/drivers/src \ SRC_S += hw/mcu/nordic/nrfx/mdk/gcc_startup_nrf52840.S diff --git a/hw/bsp/circuitplayground_express/board.mk b/hw/bsp/circuitplayground_express/board.mk index 158f543b3..115a81187 100644 --- a/hw/bsp/circuitplayground_express/board.mk +++ b/hw/bsp/circuitplayground_express/board.mk @@ -11,23 +11,23 @@ CFLAGS += \ LD_FILE = hw/bsp/circuitplayground_express/samd21g18a_flash.ld SRC_C += \ - hw/mcu/microchip/samd/asf4/samd21/gcc/gcc/startup_samd21.c \ - hw/mcu/microchip/samd/asf4/samd21/gcc/system_samd21.c \ - hw/mcu/microchip/samd/asf4/samd21/hpl/gclk/hpl_gclk.c \ - hw/mcu/microchip/samd/asf4/samd21/hpl/pm/hpl_pm.c \ - hw/mcu/microchip/samd/asf4/samd21/hpl/sysctrl/hpl_sysctrl.c \ - hw/mcu/microchip/samd/asf4/samd21/hal/src/hal_atomic.c + hw/mcu/microchip/samd/asf4/samd21/gcc/gcc/startup_samd21.c \ + hw/mcu/microchip/samd/asf4/samd21/gcc/system_samd21.c \ + hw/mcu/microchip/samd/asf4/samd21/hpl/gclk/hpl_gclk.c \ + hw/mcu/microchip/samd/asf4/samd21/hpl/pm/hpl_pm.c \ + hw/mcu/microchip/samd/asf4/samd21/hpl/sysctrl/hpl_sysctrl.c \ + hw/mcu/microchip/samd/asf4/samd21/hal/src/hal_atomic.c INC += \ - $(TOP)/hw/mcu/microchip/samd/asf4/samd21/ \ - $(TOP)/hw/mcu/microchip/samd/asf4/samd21/config \ - $(TOP)/hw/mcu/microchip/samd/asf4/samd21/include \ - $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/include \ - $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/utils/include \ - $(TOP)/hw/mcu/microchip/samd/asf4/samd51/hpl/pm/ \ - $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/port \ - $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hri \ - $(TOP)/hw/mcu/microchip/samd/asf4/samd21/CMSIS/Include + $(TOP)/hw/mcu/microchip/samd/asf4/samd21/ \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd21/config \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd21/include \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/include \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/utils/include \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd51/hpl/pm/ \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/port \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hri \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd21/CMSIS/Include # For TinyUSB port source VENDOR = microchip diff --git a/hw/bsp/ea4088qs/board.mk b/hw/bsp/ea4088qs/board.mk index 46625ca84..a88976d3a 100644 --- a/hw/bsp/ea4088qs/board.mk +++ b/hw/bsp/ea4088qs/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ @@ -11,14 +12,11 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=strict-prototypes -Wno-error=unused-parameter -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc40xx/lpc_chip_40xx +MCU_DIR = hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx # All source paths should be relative to the top level. LD_FILE = hw/bsp/ea4088qs/lpc4088.ld -# TODO remove later -SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c - SRC_C += \ $(MCU_DIR)/../gcc/cr_startup_lpc40xx.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ diff --git a/hw/bsp/ea4088qs/ea4088qs.c b/hw/bsp/ea4088qs/ea4088qs.c index 8adb61fda..83b2d6b1e 100644 --- a/hw/bsp/ea4088qs/ea4088qs.c +++ b/hw/bsp/ea4088qs/ea4088qs.c @@ -113,6 +113,21 @@ void board_init(void) LPC_USB->StCtrl = 0x3; } +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/ea4357/board.mk b/hw/bsp/ea4357/board.mk index 823481baf..098fb4c90 100644 --- a/hw/bsp/ea4357/board.mk +++ b/hw/bsp/ea4357/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ @@ -10,14 +11,11 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=strict-prototypes -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc43xx/lpc_chip_43xx +MCU_DIR = hw/mcu/nxp/lpcopen/lpc43xx/lpc_chip_43xx # All source paths should be relative to the top level. LD_FILE = hw/bsp/ea4357/lpc4357.ld -# TODO remove later -SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c - SRC_C += \ $(MCU_DIR)/../gcc/cr_startup_lpc43xx.c \ $(MCU_DIR)/src/chip_18xx_43xx.c \ @@ -34,7 +32,7 @@ INC += \ # For TinyUSB port source VENDOR = nxp -CHIP_FAMILY = lpc18_43 +CHIP_FAMILY = transdimension # For freeRTOS port source FREERTOS_PORT = ARM_CM4 diff --git a/hw/bsp/ea4357/ea4357.c b/hw/bsp/ea4357/ea4357.c index c276f10d3..f5d2a199e 100644 --- a/hw/bsp/ea4357/ea4357.c +++ b/hw/bsp/ea4357/ea4357.c @@ -166,19 +166,19 @@ void board_init(void) #if CFG_TUSB_RHPORT0_MODE Chip_USB0_Init(); - // Reset controller - LPC_USB0->USBCMD_D |= 0x02; - while( LPC_USB0->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - - LPC_USB0->PORTSC1_D |= (1<<24); // FIXME force full speed for debugging - #else // TODO OTG - LPC_USB0->USBMODE_D = USBMODE_DEVICE; - LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; - #endif +// // Reset controller +// LPC_USB0->USBCMD_D |= 0x02; +// while( LPC_USB0->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST +// LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// +// LPC_USB0->PORTSC1_D |= (1<<24); // FIXME force full speed for debugging +// #else // TODO OTG +// LPC_USB0->USBMODE_D = USBMODE_DEVICE; +// LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; +// #endif #endif /* USB1 @@ -202,19 +202,19 @@ void board_init(void) #if CFG_TUSB_RHPORT1_MODE Chip_USB1_Init(); - // Reset controller - LPC_USB1->USBCMD_D |= 0x02; - while( LPC_USB1->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST - LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - #else // TODO OTG - LPC_USB1->USBMODE_D = USBMODE_DEVICE; - #endif - - // USB1 as fullspeed - LPC_USB1->PORTSC1_D |= (1<<24); +// // Reset controller +// LPC_USB1->USBCMD_D |= 0x02; +// while( LPC_USB1->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST +// LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// #else // TODO OTG +// LPC_USB1->USBMODE_D = USBMODE_DEVICE; +// #endif +// +// // USB1 as fullspeed +// LPC_USB1->PORTSC1_D |= (1<<24); #endif // USB0 Vbus Power: P2_3 on EA4357 channel B U20 GPIO26 active low (base board) @@ -230,6 +230,31 @@ void board_init(void) // TODO Remove R170, R171, solder a pair of 15K to USB1 D+/D- to test with USB1 Host } +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB0_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + +void USB1_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST + tuh_isr(1); + #endif + + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE + tud_isr(1); + #endif +} + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/feather_m0_express/board.mk b/hw/bsp/feather_m0_express/board.mk index b7ba0b0e1..fe1913331 100644 --- a/hw/bsp/feather_m0_express/board.mk +++ b/hw/bsp/feather_m0_express/board.mk @@ -1,10 +1,11 @@ CFLAGS += \ - -DCONF_DFLL_OVERWRITE_CALIBRATION=0 \ - -D__SAMD21G18A__ \ + -flto \ -mthumb \ -mabi=aapcs-linux \ -mcpu=cortex-m0plus \ -nostdlib -nostartfiles \ + -D__SAMD21G18A__ \ + -DCONF_DFLL_OVERWRITE_CALIBRATION=0 \ -DCFG_TUSB_MCU=OPT_MCU_SAMD21 # All source paths should be relative to the top level. diff --git a/hw/bsp/feather_m4_express/board.mk b/hw/bsp/feather_m4_express/board.mk index c62d9bc33..010e4b868 100644 --- a/hw/bsp/feather_m4_express/board.mk +++ b/hw/bsp/feather_m4_express/board.mk @@ -1,11 +1,12 @@ CFLAGS += \ - -D__SAMD51J19A__ \ + -flto \ -mthumb \ -mabi=aapcs-linux \ -mcpu=cortex-m4 \ -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ -nostdlib -nostartfiles \ + -D__SAMD51J19A__ \ -DCFG_TUSB_MCU=OPT_MCU_SAMD51 CFLAGS += -Wno-error=undef diff --git a/hw/bsp/feather_nrf52840_express/board.mk b/hw/bsp/feather_nrf52840_express/board.mk index 1e077bac7..b4d6fbe9f 100644 --- a/hw/bsp/feather_nrf52840_express/board.mk +++ b/hw/bsp/feather_nrf52840_express/board.mk @@ -1,11 +1,12 @@ CFLAGS += \ - -mthumb \ - -mabi=aapcs \ - -mcpu=cortex-m4 \ - -mfloat-abi=hard \ - -mfpu=fpv4-sp-d16 \ - -DCFG_TUSB_MCU=OPT_MCU_NRF5X \ - -DNRF52840_XXAA \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -DCFG_TUSB_MCU=OPT_MCU_NRF5X \ + -DNRF52840_XXAA \ -DCONFIG_GPIO_AS_PINRESET # nrfx issue undef _ARMCC_VERSION usage https://github.com/NordicSemiconductor/nrfx/issues/49 @@ -23,17 +24,17 @@ LD_FILE = hw/bsp/feather_nrf52840_express/nrf52840_s140_v6.ld LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk SRC_C += \ - hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \ - hw/mcu/nordic/nrfx/mdk/system_nrf52840.c \ + hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \ + hw/mcu/nordic/nrfx/mdk/system_nrf52840.c \ INC += \ - $(TOP)/hw/mcu/nordic/cmsis/Include \ - $(TOP)/hw/mcu/nordic \ - $(TOP)/hw/mcu/nordic/nrfx \ - $(TOP)/hw/mcu/nordic/nrfx/mdk \ - $(TOP)/hw/mcu/nordic/nrfx/hal \ - $(TOP)/hw/mcu/nordic/nrfx/drivers/include \ - $(TOP)/hw/mcu/nordic/nrfx/drivers/src \ + $(TOP)/hw/mcu/nordic/cmsis/Include \ + $(TOP)/hw/mcu/nordic \ + $(TOP)/hw/mcu/nordic/nrfx \ + $(TOP)/hw/mcu/nordic/nrfx/mdk \ + $(TOP)/hw/mcu/nordic/nrfx/hal \ + $(TOP)/hw/mcu/nordic/nrfx/drivers/include \ + $(TOP)/hw/mcu/nordic/nrfx/drivers/src \ SRC_S += hw/mcu/nordic/nrfx/mdk/gcc_startup_nrf52840.S diff --git a/hw/bsp/feather_stm32f405/board.mk b/hw/bsp/feather_stm32f405/board.mk index ef9777976..1e68737b9 100644 --- a/hw/bsp/feather_stm32f405/board.mk +++ b/hw/bsp/feather_stm32f405/board.mk @@ -1,12 +1,13 @@ CFLAGS += \ - -DHSE_VALUE=12000000 \ - -DSTM32F405xx \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ -nostdlib -nostartfiles \ + -DSTM32F405xx \ + -DHSE_VALUE=12000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32F4 ST_HAL_DRIVER = hw/mcu/st/st_driver/STM32F4xx_HAL_Driver @@ -20,7 +21,8 @@ SRC_C += \ $(ST_HAL_DRIVER)/Src/stm32f4xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32f4xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32f4xx_hal_rcc.c \ - $(ST_HAL_DRIVER)/Src/stm32f4xx_hal_gpio.c + $(ST_HAL_DRIVER)/Src/stm32f4xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32f4xx_hal_uart.c SRC_S += \ $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f405xx.s @@ -46,5 +48,5 @@ JLINK_IF = swd STM32Prog = STM32_Programmer_CLI # flash target using on-board stlink -flash: $(BUILD)/$(BOARD)-firmware.elf - $(STM32Prog) --connect port=swd --write $< --go +flash: $(BUILD)/$(BOARD)-firmware.bin + dfu-util -R -a 0 --dfuse-address 0x08000000 -D $< diff --git a/hw/bsp/feather_stm32f405/feather_stm32f405.c b/hw/bsp/feather_stm32f405/feather_stm32f405.c index 0bc40ece0..aec779ea3 100644 --- a/hw/bsp/feather_stm32f405/feather_stm32f405.c +++ b/hw/bsp/feather_stm32f405/feather_stm32f405.c @@ -31,7 +31,7 @@ // Blue LED is chosen because the other LEDs are connected to ST-LINK lines. #define LED_PORT GPIOC -#define LED_PIN GPIO_PIN_4 +#define LED_PIN GPIO_PIN_1 #define LED_STATE_ON 1 // Pin D5 @@ -39,6 +39,24 @@ #define BUTTON_PIN GPIO_PIN_7 #define BUTTON_STATE_ACTIVE 0 +#define UARTx USART3 +#define UART_GPIO_PORT GPIOB +#define UART_GPIO_AF GPIO_AF7_USART3 +#define UART_TX_PIN GPIO_PIN_10 +#define UART_RX_PIN GPIO_PIN_11 + +UART_HandleTypeDef UartHandle; + + +// enable all LED, Button, Uart, USB clock +static void all_rcc_clk_enable(void) +{ + __HAL_RCC_GPIOA_CLK_ENABLE(); // USB D+, D- + __HAL_RCC_GPIOC_CLK_ENABLE(); // LED, Button + __HAL_RCC_GPIOB_CLK_ENABLE(); // Uart tx, rx + __HAL_RCC_USART3_CLK_ENABLE(); // Uart module +} + /** * @brief System Clock Configuration * The system Clock is configured as follow : @@ -104,14 +122,13 @@ void board_init(void) #endif SystemClock_Config(); - - // Notify runtime of frequency change. SystemCoreClockUpdate(); + all_rcc_clk_enable(); + GPIO_InitTypeDef GPIO_InitStruct; // LED - __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitStruct.Pin = LED_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; @@ -121,19 +138,25 @@ void board_init(void) board_led_write(false); // Button - //__HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitStruct.Pin = BUTTON_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + // Uart + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + // Enable USB OTG clock __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); // USB Pin Init // PA9- VUSB, PA10- ID, PA11- DM, PA12- DP - __HAL_RCC_GPIOA_CLK_ENABLE(); /* Configure DM DP Pins */ GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; @@ -180,8 +203,8 @@ int board_uart_read(uint8_t* buf, int len) int board_uart_write(void const * buf, int len) { - (void) buf; (void) len; - return 0; + HAL_UART_Transmit(&UartHandle, (uint8_t*) buf, len, 0xffff); + return len; } #if CFG_TUSB_OS == OPT_OS_NONE diff --git a/hw/bsp/feather_stm32f405/stm32f4xx_hal_conf.h b/hw/bsp/feather_stm32f405/stm32f4xx_hal_conf.h index dbef20e0a..b892df3b6 100644 --- a/hw/bsp/feather_stm32f405/stm32f4xx_hal_conf.h +++ b/hw/bsp/feather_stm32f405/stm32f4xx_hal_conf.h @@ -75,7 +75,7 @@ /* #define HAL_MMC_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ -/* #define HAL_UART_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ @@ -199,6 +199,8 @@ #define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ #define USE_HAL_SWPMI_REGISTER_CALLBACKS 0U /* SWPMI register callback disabled */ #define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ /* ########################## Assert Selection ############################## */ diff --git a/hw/bsp/fomu/board.mk b/hw/bsp/fomu/board.mk new file mode 100644 index 000000000..4e8101b7f --- /dev/null +++ b/hw/bsp/fomu/board.mk @@ -0,0 +1,30 @@ +CFLAGS += \ + -flto \ + -march=rv32i \ + -mabi=ilp32 \ + -nostdlib \ + -DCFG_TUSB_MCU=OPT_MCU_VALENTYUSB_EPTRI + +MCU_DIR = hw/mcu/fomu +BSP_DIR = hw/bsp/fomu + +# All source paths should be relative to the top level. +LD_FILE = hw/bsp/fomu/fomu.ld + +# TODO remove later +SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c + +SRC_C += + +SRC_S += hw/bsp/fomu/crt0-vexriscv.S + +INC += \ + $(TOP)/$(BSP_DIR)/include + +# For TinyUSB port source +VENDOR = valentyusb +CHIP_FAMILY = eptri + +# flash using dfu-util +flash: $(BUILD)/$(BOARD)-firmware.dfu + dfu-util -D $^ diff --git a/hw/bsp/fomu/crt0-vexriscv.S b/hw/bsp/fomu/crt0-vexriscv.S new file mode 100644 index 000000000..d80a29e06 --- /dev/null +++ b/hw/bsp/fomu/crt0-vexriscv.S @@ -0,0 +1,83 @@ +.global main +.global isr + +.section .text.start +.global _start + +_start: + j crt_init + +.section .text +.global trap_entry +trap_entry: + sw x1, - 1*4(sp) + sw x5, - 2*4(sp) + sw x6, - 3*4(sp) + sw x7, - 4*4(sp) + sw x10, - 5*4(sp) + sw x11, - 6*4(sp) + sw x12, - 7*4(sp) + sw x13, - 8*4(sp) + sw x14, - 9*4(sp) + sw x15, -10*4(sp) + sw x16, -11*4(sp) + sw x17, -12*4(sp) + sw x28, -13*4(sp) + sw x29, -14*4(sp) + sw x30, -15*4(sp) + sw x31, -16*4(sp) + addi sp,sp,-16*4 + call isr + lw x1 , 15*4(sp) + lw x5, 14*4(sp) + lw x6, 13*4(sp) + lw x7, 12*4(sp) + lw x10, 11*4(sp) + lw x11, 10*4(sp) + lw x12, 9*4(sp) + lw x13, 8*4(sp) + lw x14, 7*4(sp) + lw x15, 6*4(sp) + lw x16, 5*4(sp) + lw x17, 4*4(sp) + lw x28, 3*4(sp) + lw x29, 2*4(sp) + lw x30, 1*4(sp) + lw x31, 0*4(sp) + addi sp,sp,16*4 + mret + +.text +crt_init: + la sp, _estack - 4 + la a0, trap_entry + csrw mtvec, a0 + +bss_init: + la a0, _sbss + la a1, _ebss + 4 +bss_loop: + beq a0,a1,bss_done + sw zero,0(a0) + add a0,a0,4 + j bss_loop +bss_done: + + /* Load DATA */ + la t0, _etext + la t1, _srelocate + la t2, _erelocate + 4 +3: + lw t3, 0(t0) + sw t3, 0(t1) + /* _edata is aligned to 4 bytes. Use word-xfers. */ + addi t0, t0, 4 + addi t1, t1, 4 + bltu t1, t2, 3b + + li a0, 0x880 //880 enable timer + external interrupt sources (until mstatus.MIE is set, they will never trigger an interrupt) + csrw mie,a0 + + call main +infinite_loop: + j infinite_loop diff --git a/hw/bsp/fomu/fomu.c b/hw/bsp/fomu/fomu.c new file mode 100644 index 000000000..519c63630 --- /dev/null +++ b/hw/bsp/fomu/fomu.c @@ -0,0 +1,117 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + +#include +#include +#include "common/tusb_common.h" +#include "csr.h" +#include "irq.h" + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void hal_dcd_isr(uint8_t rhport); + +void fomu_error(uint32_t line) +{ + (void)line; + TU_BREAKPOINT(); +} + +volatile uint32_t system_ticks = 0; +static void timer_init(void) +{ + int t; + + timer0_en_write(0); + t = CONFIG_CLOCK_FREQUENCY / 1000; // 1000 kHz tick + timer0_reload_write(t); + timer0_load_write(t); + timer0_en_write(1); + timer0_ev_enable_write(1); + timer0_ev_pending_write(1); + irq_setmask(irq_getmask() | (1 << TIMER0_INTERRUPT)); +} + +void isr(void) +{ + unsigned int irqs; + + irqs = irq_pending() & irq_getmask(); + +#if CFG_TUSB_RHPORT0_MODE == OPT_MODE_DEVICE + if (irqs & (1 << USB_INTERRUPT)) { + hal_dcd_isr(0); + } +#endif + if (irqs & (1 << TIMER0_INTERRUPT)) { + system_ticks++; + timer0_ev_pending_write(1); + } +} + +void board_init(void) +{ + irq_setmask(0); + irq_setie(1); + timer_init(); + return; +} + +void board_led_write(bool state) +{ + rgb_ctrl_write(0xff); + rgb_raw_write(state); +} + +uint32_t board_button_read(void) +{ + return 0; +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + int32_t offset = 0; + for (offset = 0; offset < len; offset++) + if (! (messible_status_read() & CSR_MESSIBLE_STATUS_FULL_OFFSET)) + messible_in_write(((uint8_t *)buf)[offset]); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif \ No newline at end of file diff --git a/hw/bsp/fomu/fomu.ld b/hw/bsp/fomu/fomu.ld new file mode 100644 index 000000000..13278d2ad --- /dev/null +++ b/hw/bsp/fomu/fomu.ld @@ -0,0 +1,104 @@ +OUTPUT_FORMAT("elf32-littleriscv") +ENTRY(_start) + +__DYNAMIC = 0; + +MEMORY { + csr : ORIGIN = 0x60000000, LENGTH = 0x01000000 + vexriscv_debug : ORIGIN = 0xf00f0000, LENGTH = 0x00000100 + ram : ORIGIN = 0x10000000, LENGTH = 0x00020000 + rom : ORIGIN = 0x20040000, LENGTH = 0x00200000 - 0x40000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _ftext = .; + *(.text.start) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > rom + + . = ALIGN(4); + _etext = .; /* End of text section */ + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(.sbss .sbss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + end = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/hw/bsp/fomu/include/csr.h b/hw/bsp/fomu/include/csr.h new file mode 100644 index 000000000..a2f60ecf6 --- /dev/null +++ b/hw/bsp/fomu/include/csr.h @@ -0,0 +1,750 @@ +//-------------------------------------------------------------------------------- +// Auto-generated by Migen (f4fcd10) & LiteX (1425a68d) on 2019-11-12 19:41:49 +//-------------------------------------------------------------------------------- +#ifndef __GENERATED_CSR_H +#define __GENERATED_CSR_H +#include +#ifdef CSR_ACCESSORS_DEFINED +extern void csr_writeb(uint8_t value, unsigned long addr); +extern uint8_t csr_readb(unsigned long addr); +extern void csr_writew(uint16_t value, unsigned long addr); +extern uint16_t csr_readw(unsigned long addr); +extern void csr_writel(uint32_t value, unsigned long addr); +extern uint32_t csr_readl(unsigned long addr); +#else /* ! CSR_ACCESSORS_DEFINED */ +#include +#endif /* ! CSR_ACCESSORS_DEFINED */ + +/* ctrl */ +#define CSR_CTRL_BASE 0xe0000000L +#define CSR_CTRL_RESET_ADDR 0xe0000000L +#define CSR_CTRL_RESET_SIZE 1 +static inline unsigned char ctrl_reset_read(void) { + unsigned char r = csr_readl(0xe0000000L); + return r; +} +static inline void ctrl_reset_write(unsigned char value) { + csr_writel(value, 0xe0000000L); +} +#define CSR_CTRL_SCRATCH_ADDR 0xe0000004L +#define CSR_CTRL_SCRATCH_SIZE 4 +static inline unsigned int ctrl_scratch_read(void) { + unsigned int r = csr_readl(0xe0000004L); + r <<= 8; + r |= csr_readl(0xe0000008L); + r <<= 8; + r |= csr_readl(0xe000000cL); + r <<= 8; + r |= csr_readl(0xe0000010L); + return r; +} +static inline void ctrl_scratch_write(unsigned int value) { + csr_writel(value >> 24, 0xe0000004L); + csr_writel(value >> 16, 0xe0000008L); + csr_writel(value >> 8, 0xe000000cL); + csr_writel(value, 0xe0000010L); +} +#define CSR_CTRL_BUS_ERRORS_ADDR 0xe0000014L +#define CSR_CTRL_BUS_ERRORS_SIZE 4 +static inline unsigned int ctrl_bus_errors_read(void) { + unsigned int r = csr_readl(0xe0000014L); + r <<= 8; + r |= csr_readl(0xe0000018L); + r <<= 8; + r |= csr_readl(0xe000001cL); + r <<= 8; + r |= csr_readl(0xe0000020L); + return r; +} + +/* messible */ +#define CSR_MESSIBLE_BASE 0xe0008000L +#define CSR_MESSIBLE_IN_ADDR 0xe0008000L +#define CSR_MESSIBLE_IN_SIZE 1 +static inline unsigned char messible_in_read(void) { + unsigned char r = csr_readl(0xe0008000L); + return r; +} +static inline void messible_in_write(unsigned char value) { + csr_writel(value, 0xe0008000L); +} +#define CSR_MESSIBLE_OUT_ADDR 0xe0008004L +#define CSR_MESSIBLE_OUT_SIZE 1 +static inline unsigned char messible_out_read(void) { + unsigned char r = csr_readl(0xe0008004L); + return r; +} +#define CSR_MESSIBLE_STATUS_ADDR 0xe0008008L +#define CSR_MESSIBLE_STATUS_SIZE 1 +static inline unsigned char messible_status_read(void) { + unsigned char r = csr_readl(0xe0008008L); + return r; +} +#define CSR_MESSIBLE_STATUS_FULL_OFFSET 0 +#define CSR_MESSIBLE_STATUS_FULL_SIZE 1 +#define CSR_MESSIBLE_STATUS_HAVE_OFFSET 1 +#define CSR_MESSIBLE_STATUS_HAVE_SIZE 1 + +/* picorvspi */ +#define CSR_PICORVSPI_BASE 0xe0005000L +#define CSR_PICORVSPI_CFG1_ADDR 0xe0005000L +#define CSR_PICORVSPI_CFG1_SIZE 1 +static inline unsigned char picorvspi_cfg1_read(void) { + unsigned char r = csr_readl(0xe0005000L); + return r; +} +static inline void picorvspi_cfg1_write(unsigned char value) { + csr_writel(value, 0xe0005000L); +} +#define CSR_PICORVSPI_CFG1_BB_OUT_OFFSET 0 +#define CSR_PICORVSPI_CFG1_BB_OUT_SIZE 4 +#define CSR_PICORVSPI_CFG1_BB_CLK_OFFSET 4 +#define CSR_PICORVSPI_CFG1_BB_CLK_SIZE 1 +#define CSR_PICORVSPI_CFG1_BB_CS_OFFSET 5 +#define CSR_PICORVSPI_CFG1_BB_CS_SIZE 1 +#define CSR_PICORVSPI_CFG2_ADDR 0xe0005004L +#define CSR_PICORVSPI_CFG2_SIZE 1 +static inline unsigned char picorvspi_cfg2_read(void) { + unsigned char r = csr_readl(0xe0005004L); + return r; +} +static inline void picorvspi_cfg2_write(unsigned char value) { + csr_writel(value, 0xe0005004L); +} +#define CSR_PICORVSPI_CFG2_BB_OE_OFFSET 0 +#define CSR_PICORVSPI_CFG2_BB_OE_SIZE 4 +#define CSR_PICORVSPI_CFG3_ADDR 0xe0005008L +#define CSR_PICORVSPI_CFG3_SIZE 1 +static inline unsigned char picorvspi_cfg3_read(void) { + unsigned char r = csr_readl(0xe0005008L); + return r; +} +static inline void picorvspi_cfg3_write(unsigned char value) { + csr_writel(value, 0xe0005008L); +} +#define CSR_PICORVSPI_CFG3_RLAT_OFFSET 0 +#define CSR_PICORVSPI_CFG3_RLAT_SIZE 4 +#define CSR_PICORVSPI_CFG3_CRM_OFFSET 4 +#define CSR_PICORVSPI_CFG3_CRM_SIZE 1 +#define CSR_PICORVSPI_CFG3_QSPI_OFFSET 5 +#define CSR_PICORVSPI_CFG3_QSPI_SIZE 1 +#define CSR_PICORVSPI_CFG3_DDR_OFFSET 6 +#define CSR_PICORVSPI_CFG3_DDR_SIZE 1 +#define CSR_PICORVSPI_CFG4_ADDR 0xe000500cL +#define CSR_PICORVSPI_CFG4_SIZE 1 +static inline unsigned char picorvspi_cfg4_read(void) { + unsigned char r = csr_readl(0xe000500cL); + return r; +} +static inline void picorvspi_cfg4_write(unsigned char value) { + csr_writel(value, 0xe000500cL); +} +#define CSR_PICORVSPI_CFG4_MEMIO_OFFSET 7 +#define CSR_PICORVSPI_CFG4_MEMIO_SIZE 1 +#define CSR_PICORVSPI_STAT1_ADDR 0xe0005010L +#define CSR_PICORVSPI_STAT1_SIZE 1 +static inline unsigned char picorvspi_stat1_read(void) { + unsigned char r = csr_readl(0xe0005010L); + return r; +} +#define CSR_PICORVSPI_STAT1_BB_IN_OFFSET 0 +#define CSR_PICORVSPI_STAT1_BB_IN_SIZE 4 +#define CSR_PICORVSPI_STAT2_ADDR 0xe0005014L +#define CSR_PICORVSPI_STAT2_SIZE 1 +static inline unsigned char picorvspi_stat2_read(void) { + unsigned char r = csr_readl(0xe0005014L); + return r; +} +#define CSR_PICORVSPI_STAT3_ADDR 0xe0005018L +#define CSR_PICORVSPI_STAT3_SIZE 1 +static inline unsigned char picorvspi_stat3_read(void) { + unsigned char r = csr_readl(0xe0005018L); + return r; +} +#define CSR_PICORVSPI_STAT4_ADDR 0xe000501cL +#define CSR_PICORVSPI_STAT4_SIZE 1 +static inline unsigned char picorvspi_stat4_read(void) { + unsigned char r = csr_readl(0xe000501cL); + return r; +} + +/* reboot */ +#define CSR_REBOOT_BASE 0xe0006000L +#define CSR_REBOOT_CTRL_ADDR 0xe0006000L +#define CSR_REBOOT_CTRL_SIZE 1 +static inline unsigned char reboot_ctrl_read(void) { + unsigned char r = csr_readl(0xe0006000L); + return r; +} +static inline void reboot_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0006000L); +} +#define CSR_REBOOT_CTRL_IMAGE_OFFSET 0 +#define CSR_REBOOT_CTRL_IMAGE_SIZE 2 +#define CSR_REBOOT_CTRL_KEY_OFFSET 2 +#define CSR_REBOOT_CTRL_KEY_SIZE 6 +#define CSR_REBOOT_ADDR_ADDR 0xe0006004L +#define CSR_REBOOT_ADDR_SIZE 4 +static inline unsigned int reboot_addr_read(void) { + unsigned int r = csr_readl(0xe0006004L); + r <<= 8; + r |= csr_readl(0xe0006008L); + r <<= 8; + r |= csr_readl(0xe000600cL); + r <<= 8; + r |= csr_readl(0xe0006010L); + return r; +} +static inline void reboot_addr_write(unsigned int value) { + csr_writel(value >> 24, 0xe0006004L); + csr_writel(value >> 16, 0xe0006008L); + csr_writel(value >> 8, 0xe000600cL); + csr_writel(value, 0xe0006010L); +} + +/* rgb */ +#define CSR_RGB_BASE 0xe0006800L +#define CSR_RGB_DAT_ADDR 0xe0006800L +#define CSR_RGB_DAT_SIZE 1 +static inline unsigned char rgb_dat_read(void) { + unsigned char r = csr_readl(0xe0006800L); + return r; +} +static inline void rgb_dat_write(unsigned char value) { + csr_writel(value, 0xe0006800L); +} +#define CSR_RGB_ADDR_ADDR 0xe0006804L +#define CSR_RGB_ADDR_SIZE 1 +static inline unsigned char rgb_addr_read(void) { + unsigned char r = csr_readl(0xe0006804L); + return r; +} +static inline void rgb_addr_write(unsigned char value) { + csr_writel(value, 0xe0006804L); +} +#define CSR_RGB_CTRL_ADDR 0xe0006808L +#define CSR_RGB_CTRL_SIZE 1 +static inline unsigned char rgb_ctrl_read(void) { + unsigned char r = csr_readl(0xe0006808L); + return r; +} +static inline void rgb_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0006808L); +} +#define CSR_RGB_CTRL_EXE_OFFSET 0 +#define CSR_RGB_CTRL_EXE_SIZE 1 +#define CSR_RGB_CTRL_CURREN_OFFSET 1 +#define CSR_RGB_CTRL_CURREN_SIZE 1 +#define CSR_RGB_CTRL_RGBLEDEN_OFFSET 2 +#define CSR_RGB_CTRL_RGBLEDEN_SIZE 1 +#define CSR_RGB_CTRL_RRAW_OFFSET 3 +#define CSR_RGB_CTRL_RRAW_SIZE 1 +#define CSR_RGB_CTRL_GRAW_OFFSET 4 +#define CSR_RGB_CTRL_GRAW_SIZE 1 +#define CSR_RGB_CTRL_BRAW_OFFSET 5 +#define CSR_RGB_CTRL_BRAW_SIZE 1 +#define CSR_RGB_RAW_ADDR 0xe000680cL +#define CSR_RGB_RAW_SIZE 1 +static inline unsigned char rgb_raw_read(void) { + unsigned char r = csr_readl(0xe000680cL); + return r; +} +static inline void rgb_raw_write(unsigned char value) { + csr_writel(value, 0xe000680cL); +} +#define CSR_RGB_RAW_R_OFFSET 0 +#define CSR_RGB_RAW_R_SIZE 1 +#define CSR_RGB_RAW_G_OFFSET 1 +#define CSR_RGB_RAW_G_SIZE 1 +#define CSR_RGB_RAW_B_OFFSET 2 +#define CSR_RGB_RAW_B_SIZE 1 + +/* timer0 */ +#define CSR_TIMER0_BASE 0xe0002800L +#define CSR_TIMER0_LOAD_ADDR 0xe0002800L +#define CSR_TIMER0_LOAD_SIZE 4 +static inline unsigned int timer0_load_read(void) { + unsigned int r = csr_readl(0xe0002800L); + r <<= 8; + r |= csr_readl(0xe0002804L); + r <<= 8; + r |= csr_readl(0xe0002808L); + r <<= 8; + r |= csr_readl(0xe000280cL); + return r; +} +static inline void timer0_load_write(unsigned int value) { + csr_writel(value >> 24, 0xe0002800L); + csr_writel(value >> 16, 0xe0002804L); + csr_writel(value >> 8, 0xe0002808L); + csr_writel(value, 0xe000280cL); +} +#define CSR_TIMER0_RELOAD_ADDR 0xe0002810L +#define CSR_TIMER0_RELOAD_SIZE 4 +static inline unsigned int timer0_reload_read(void) { + unsigned int r = csr_readl(0xe0002810L); + r <<= 8; + r |= csr_readl(0xe0002814L); + r <<= 8; + r |= csr_readl(0xe0002818L); + r <<= 8; + r |= csr_readl(0xe000281cL); + return r; +} +static inline void timer0_reload_write(unsigned int value) { + csr_writel(value >> 24, 0xe0002810L); + csr_writel(value >> 16, 0xe0002814L); + csr_writel(value >> 8, 0xe0002818L); + csr_writel(value, 0xe000281cL); +} +#define CSR_TIMER0_EN_ADDR 0xe0002820L +#define CSR_TIMER0_EN_SIZE 1 +static inline unsigned char timer0_en_read(void) { + unsigned char r = csr_readl(0xe0002820L); + return r; +} +static inline void timer0_en_write(unsigned char value) { + csr_writel(value, 0xe0002820L); +} +#define CSR_TIMER0_UPDATE_VALUE_ADDR 0xe0002824L +#define CSR_TIMER0_UPDATE_VALUE_SIZE 1 +static inline unsigned char timer0_update_value_read(void) { + unsigned char r = csr_readl(0xe0002824L); + return r; +} +static inline void timer0_update_value_write(unsigned char value) { + csr_writel(value, 0xe0002824L); +} +#define CSR_TIMER0_VALUE_ADDR 0xe0002828L +#define CSR_TIMER0_VALUE_SIZE 4 +static inline unsigned int timer0_value_read(void) { + unsigned int r = csr_readl(0xe0002828L); + r <<= 8; + r |= csr_readl(0xe000282cL); + r <<= 8; + r |= csr_readl(0xe0002830L); + r <<= 8; + r |= csr_readl(0xe0002834L); + return r; +} +#define CSR_TIMER0_EV_STATUS_ADDR 0xe0002838L +#define CSR_TIMER0_EV_STATUS_SIZE 1 +static inline unsigned char timer0_ev_status_read(void) { + unsigned char r = csr_readl(0xe0002838L); + return r; +} +static inline void timer0_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0002838L); +} +#define CSR_TIMER0_EV_PENDING_ADDR 0xe000283cL +#define CSR_TIMER0_EV_PENDING_SIZE 1 +static inline unsigned char timer0_ev_pending_read(void) { + unsigned char r = csr_readl(0xe000283cL); + return r; +} +static inline void timer0_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe000283cL); +} +#define CSR_TIMER0_EV_ENABLE_ADDR 0xe0002840L +#define CSR_TIMER0_EV_ENABLE_SIZE 1 +static inline unsigned char timer0_ev_enable_read(void) { + unsigned char r = csr_readl(0xe0002840L); + return r; +} +static inline void timer0_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe0002840L); +} + +/* touch */ +#define CSR_TOUCH_BASE 0xe0005800L +#define CSR_TOUCH_O_ADDR 0xe0005800L +#define CSR_TOUCH_O_SIZE 1 +static inline unsigned char touch_o_read(void) { + unsigned char r = csr_readl(0xe0005800L); + return r; +} +static inline void touch_o_write(unsigned char value) { + csr_writel(value, 0xe0005800L); +} +#define CSR_TOUCH_O_O_OFFSET 0 +#define CSR_TOUCH_O_O_SIZE 4 +#define CSR_TOUCH_OE_ADDR 0xe0005804L +#define CSR_TOUCH_OE_SIZE 1 +static inline unsigned char touch_oe_read(void) { + unsigned char r = csr_readl(0xe0005804L); + return r; +} +static inline void touch_oe_write(unsigned char value) { + csr_writel(value, 0xe0005804L); +} +#define CSR_TOUCH_OE_OE_OFFSET 0 +#define CSR_TOUCH_OE_OE_SIZE 4 +#define CSR_TOUCH_I_ADDR 0xe0005808L +#define CSR_TOUCH_I_SIZE 1 +static inline unsigned char touch_i_read(void) { + unsigned char r = csr_readl(0xe0005808L); + return r; +} +#define CSR_TOUCH_I_I_OFFSET 0 +#define CSR_TOUCH_I_I_SIZE 4 + +/* usb */ +#define CSR_USB_BASE 0xe0004800L +#define CSR_USB_PULLUP_OUT_ADDR 0xe0004800L +#define CSR_USB_PULLUP_OUT_SIZE 1 +static inline unsigned char usb_pullup_out_read(void) { + unsigned char r = csr_readl(0xe0004800L); + return r; +} +static inline void usb_pullup_out_write(unsigned char value) { + csr_writel(value, 0xe0004800L); +} +#define CSR_USB_ADDRESS_ADDR 0xe0004804L +#define CSR_USB_ADDRESS_SIZE 1 +static inline unsigned char usb_address_read(void) { + unsigned char r = csr_readl(0xe0004804L); + return r; +} +static inline void usb_address_write(unsigned char value) { + csr_writel(value, 0xe0004804L); +} +#define CSR_USB_ADDRESS_ADDR_OFFSET 0 +#define CSR_USB_ADDRESS_ADDR_SIZE 7 +#define CSR_USB_NEXT_EV_ADDR 0xe0004808L +#define CSR_USB_NEXT_EV_SIZE 1 +static inline unsigned char usb_next_ev_read(void) { + unsigned char r = csr_readl(0xe0004808L); + return r; +} +#define CSR_USB_NEXT_EV_IN_OFFSET 0 +#define CSR_USB_NEXT_EV_IN_SIZE 1 +#define CSR_USB_NEXT_EV_OUT_OFFSET 1 +#define CSR_USB_NEXT_EV_OUT_SIZE 1 +#define CSR_USB_NEXT_EV_SETUP_OFFSET 2 +#define CSR_USB_NEXT_EV_SETUP_SIZE 1 +#define CSR_USB_NEXT_EV_RESET_OFFSET 3 +#define CSR_USB_NEXT_EV_RESET_SIZE 1 +#define CSR_USB_SETUP_DATA_ADDR 0xe000480cL +#define CSR_USB_SETUP_DATA_SIZE 1 +static inline unsigned char usb_setup_data_read(void) { + unsigned char r = csr_readl(0xe000480cL); + return r; +} +#define CSR_USB_SETUP_DATA_DATA_OFFSET 0 +#define CSR_USB_SETUP_DATA_DATA_SIZE 8 +#define CSR_USB_SETUP_CTRL_ADDR 0xe0004810L +#define CSR_USB_SETUP_CTRL_SIZE 1 +static inline unsigned char usb_setup_ctrl_read(void) { + unsigned char r = csr_readl(0xe0004810L); + return r; +} +static inline void usb_setup_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0004810L); +} +#define CSR_USB_SETUP_CTRL_RESET_OFFSET 5 +#define CSR_USB_SETUP_CTRL_RESET_SIZE 1 +#define CSR_USB_SETUP_STATUS_ADDR 0xe0004814L +#define CSR_USB_SETUP_STATUS_SIZE 1 +static inline unsigned char usb_setup_status_read(void) { + unsigned char r = csr_readl(0xe0004814L); + return r; +} +#define CSR_USB_SETUP_STATUS_EPNO_OFFSET 0 +#define CSR_USB_SETUP_STATUS_EPNO_SIZE 4 +#define CSR_USB_SETUP_STATUS_HAVE_OFFSET 4 +#define CSR_USB_SETUP_STATUS_HAVE_SIZE 1 +#define CSR_USB_SETUP_STATUS_PEND_OFFSET 5 +#define CSR_USB_SETUP_STATUS_PEND_SIZE 1 +#define CSR_USB_SETUP_STATUS_IS_IN_OFFSET 6 +#define CSR_USB_SETUP_STATUS_IS_IN_SIZE 1 +#define CSR_USB_SETUP_STATUS_DATA_OFFSET 7 +#define CSR_USB_SETUP_STATUS_DATA_SIZE 1 +#define CSR_USB_SETUP_EV_STATUS_ADDR 0xe0004818L +#define CSR_USB_SETUP_EV_STATUS_SIZE 1 +static inline unsigned char usb_setup_ev_status_read(void) { + unsigned char r = csr_readl(0xe0004818L); + return r; +} +static inline void usb_setup_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0004818L); +} +#define CSR_USB_SETUP_EV_PENDING_ADDR 0xe000481cL +#define CSR_USB_SETUP_EV_PENDING_SIZE 1 +static inline unsigned char usb_setup_ev_pending_read(void) { + unsigned char r = csr_readl(0xe000481cL); + return r; +} +static inline void usb_setup_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe000481cL); +} +#define CSR_USB_SETUP_EV_ENABLE_ADDR 0xe0004820L +#define CSR_USB_SETUP_EV_ENABLE_SIZE 1 +static inline unsigned char usb_setup_ev_enable_read(void) { + unsigned char r = csr_readl(0xe0004820L); + return r; +} +static inline void usb_setup_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe0004820L); +} +#define CSR_USB_IN_DATA_ADDR 0xe0004824L +#define CSR_USB_IN_DATA_SIZE 1 +static inline unsigned char usb_in_data_read(void) { + unsigned char r = csr_readl(0xe0004824L); + return r; +} +static inline void usb_in_data_write(unsigned char value) { + csr_writel(value, 0xe0004824L); +} +#define CSR_USB_IN_DATA_DATA_OFFSET 0 +#define CSR_USB_IN_DATA_DATA_SIZE 8 +#define CSR_USB_IN_CTRL_ADDR 0xe0004828L +#define CSR_USB_IN_CTRL_SIZE 1 +static inline unsigned char usb_in_ctrl_read(void) { + unsigned char r = csr_readl(0xe0004828L); + return r; +} +static inline void usb_in_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0004828L); +} +#define CSR_USB_IN_CTRL_EPNO_OFFSET 0 +#define CSR_USB_IN_CTRL_EPNO_SIZE 4 +#define CSR_USB_IN_CTRL_RESET_OFFSET 5 +#define CSR_USB_IN_CTRL_RESET_SIZE 1 +#define CSR_USB_IN_CTRL_STALL_OFFSET 6 +#define CSR_USB_IN_CTRL_STALL_SIZE 1 +#define CSR_USB_IN_STATUS_ADDR 0xe000482cL +#define CSR_USB_IN_STATUS_SIZE 1 +static inline unsigned char usb_in_status_read(void) { + unsigned char r = csr_readl(0xe000482cL); + return r; +} +#define CSR_USB_IN_STATUS_IDLE_OFFSET 0 +#define CSR_USB_IN_STATUS_IDLE_SIZE 1 +#define CSR_USB_IN_STATUS_HAVE_OFFSET 4 +#define CSR_USB_IN_STATUS_HAVE_SIZE 1 +#define CSR_USB_IN_STATUS_PEND_OFFSET 5 +#define CSR_USB_IN_STATUS_PEND_SIZE 1 +#define CSR_USB_IN_EV_STATUS_ADDR 0xe0004830L +#define CSR_USB_IN_EV_STATUS_SIZE 1 +static inline unsigned char usb_in_ev_status_read(void) { + unsigned char r = csr_readl(0xe0004830L); + return r; +} +static inline void usb_in_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0004830L); +} +#define CSR_USB_IN_EV_PENDING_ADDR 0xe0004834L +#define CSR_USB_IN_EV_PENDING_SIZE 1 +static inline unsigned char usb_in_ev_pending_read(void) { + unsigned char r = csr_readl(0xe0004834L); + return r; +} +static inline void usb_in_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe0004834L); +} +#define CSR_USB_IN_EV_ENABLE_ADDR 0xe0004838L +#define CSR_USB_IN_EV_ENABLE_SIZE 1 +static inline unsigned char usb_in_ev_enable_read(void) { + unsigned char r = csr_readl(0xe0004838L); + return r; +} +static inline void usb_in_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe0004838L); +} +#define CSR_USB_OUT_DATA_ADDR 0xe000483cL +#define CSR_USB_OUT_DATA_SIZE 1 +static inline unsigned char usb_out_data_read(void) { + unsigned char r = csr_readl(0xe000483cL); + return r; +} +#define CSR_USB_OUT_DATA_DATA_OFFSET 0 +#define CSR_USB_OUT_DATA_DATA_SIZE 8 +#define CSR_USB_OUT_CTRL_ADDR 0xe0004840L +#define CSR_USB_OUT_CTRL_SIZE 1 +static inline unsigned char usb_out_ctrl_read(void) { + unsigned char r = csr_readl(0xe0004840L); + return r; +} +static inline void usb_out_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0004840L); +} +#define CSR_USB_OUT_CTRL_EPNO_OFFSET 0 +#define CSR_USB_OUT_CTRL_EPNO_SIZE 4 +#define CSR_USB_OUT_CTRL_ENABLE_OFFSET 4 +#define CSR_USB_OUT_CTRL_ENABLE_SIZE 1 +#define CSR_USB_OUT_CTRL_RESET_OFFSET 5 +#define CSR_USB_OUT_CTRL_RESET_SIZE 1 +#define CSR_USB_OUT_CTRL_STALL_OFFSET 6 +#define CSR_USB_OUT_CTRL_STALL_SIZE 1 +#define CSR_USB_OUT_STATUS_ADDR 0xe0004844L +#define CSR_USB_OUT_STATUS_SIZE 1 +static inline unsigned char usb_out_status_read(void) { + unsigned char r = csr_readl(0xe0004844L); + return r; +} +#define CSR_USB_OUT_STATUS_EPNO_OFFSET 0 +#define CSR_USB_OUT_STATUS_EPNO_SIZE 4 +#define CSR_USB_OUT_STATUS_HAVE_OFFSET 4 +#define CSR_USB_OUT_STATUS_HAVE_SIZE 1 +#define CSR_USB_OUT_STATUS_PEND_OFFSET 5 +#define CSR_USB_OUT_STATUS_PEND_SIZE 1 +#define CSR_USB_OUT_EV_STATUS_ADDR 0xe0004848L +#define CSR_USB_OUT_EV_STATUS_SIZE 1 +static inline unsigned char usb_out_ev_status_read(void) { + unsigned char r = csr_readl(0xe0004848L); + return r; +} +static inline void usb_out_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0004848L); +} +#define CSR_USB_OUT_EV_PENDING_ADDR 0xe000484cL +#define CSR_USB_OUT_EV_PENDING_SIZE 1 +static inline unsigned char usb_out_ev_pending_read(void) { + unsigned char r = csr_readl(0xe000484cL); + return r; +} +static inline void usb_out_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe000484cL); +} +#define CSR_USB_OUT_EV_ENABLE_ADDR 0xe0004850L +#define CSR_USB_OUT_EV_ENABLE_SIZE 1 +static inline unsigned char usb_out_ev_enable_read(void) { + unsigned char r = csr_readl(0xe0004850L); + return r; +} +static inline void usb_out_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe0004850L); +} +#define CSR_USB_OUT_ENABLE_STATUS_ADDR 0xe0004854L +#define CSR_USB_OUT_ENABLE_STATUS_SIZE 1 +static inline unsigned char usb_out_enable_status_read(void) { + unsigned char r = csr_readl(0xe0004854L); + return r; +} +#define CSR_USB_OUT_STALL_STATUS_ADDR 0xe0004858L +#define CSR_USB_OUT_STALL_STATUS_SIZE 1 +static inline unsigned char usb_out_stall_status_read(void) { + unsigned char r = csr_readl(0xe0004858L); + return r; +} + +/* version */ +#define CSR_VERSION_BASE 0xe0007000L +#define CSR_VERSION_MAJOR_ADDR 0xe0007000L +#define CSR_VERSION_MAJOR_SIZE 1 +static inline unsigned char version_major_read(void) { + unsigned char r = csr_readl(0xe0007000L); + return r; +} +#define CSR_VERSION_MINOR_ADDR 0xe0007004L +#define CSR_VERSION_MINOR_SIZE 1 +static inline unsigned char version_minor_read(void) { + unsigned char r = csr_readl(0xe0007004L); + return r; +} +#define CSR_VERSION_REVISION_ADDR 0xe0007008L +#define CSR_VERSION_REVISION_SIZE 1 +static inline unsigned char version_revision_read(void) { + unsigned char r = csr_readl(0xe0007008L); + return r; +} +#define CSR_VERSION_GITREV_ADDR 0xe000700cL +#define CSR_VERSION_GITREV_SIZE 4 +static inline unsigned int version_gitrev_read(void) { + unsigned int r = csr_readl(0xe000700cL); + r <<= 8; + r |= csr_readl(0xe0007010L); + r <<= 8; + r |= csr_readl(0xe0007014L); + r <<= 8; + r |= csr_readl(0xe0007018L); + return r; +} +#define CSR_VERSION_GITEXTRA_ADDR 0xe000701cL +#define CSR_VERSION_GITEXTRA_SIZE 2 +static inline unsigned short int version_gitextra_read(void) { + unsigned short int r = csr_readl(0xe000701cL); + r <<= 8; + r |= csr_readl(0xe0007020L); + return r; +} +#define CSR_VERSION_DIRTY_ADDR 0xe0007024L +#define CSR_VERSION_DIRTY_SIZE 1 +static inline unsigned char version_dirty_read(void) { + unsigned char r = csr_readl(0xe0007024L); + return r; +} +#define CSR_VERSION_DIRTY_DIRTY_OFFSET 0 +#define CSR_VERSION_DIRTY_DIRTY_SIZE 1 +#define CSR_VERSION_MODEL_ADDR 0xe0007028L +#define CSR_VERSION_MODEL_SIZE 1 +static inline unsigned char version_model_read(void) { + unsigned char r = csr_readl(0xe0007028L); + return r; +} +#define CSR_VERSION_MODEL_MODEL_OFFSET 0 +#define CSR_VERSION_MODEL_MODEL_SIZE 8 +#define CSR_VERSION_SEED_ADDR 0xe000702cL +#define CSR_VERSION_SEED_SIZE 4 +static inline unsigned int version_seed_read(void) { + unsigned int r = csr_readl(0xe000702cL); + r <<= 8; + r |= csr_readl(0xe0007030L); + r <<= 8; + r |= csr_readl(0xe0007034L); + r <<= 8; + r |= csr_readl(0xe0007038L); + return r; +} + +/* constants */ +#define TIMER0_INTERRUPT 2 +static inline int timer0_interrupt_read(void) { + return 2; +} +#define USB_INTERRUPT 3 +static inline int usb_interrupt_read(void) { + return 3; +} +#define CONFIG_BITSTREAM_SYNC_HEADER1 2123999870 +static inline int config_bitstream_sync_header1_read(void) { + return 2123999870; +} +#define CONFIG_BITSTREAM_SYNC_HEADER2 2125109630 +static inline int config_bitstream_sync_header2_read(void) { + return 2125109630; +} +#define CONFIG_CLOCK_FREQUENCY 12000000 +static inline int config_clock_frequency_read(void) { + return 12000000; +} +#define CONFIG_CPU_RESET_ADDR 0 +static inline int config_cpu_reset_addr_read(void) { + return 0; +} +#define CONFIG_CPU_TYPE "VEXRISCV" +static inline const char * config_cpu_type_read(void) { + return "VEXRISCV"; +} +#define CONFIG_CPU_TYPE_VEXRISCV 1 +static inline int config_cpu_type_vexriscv_read(void) { + return 1; +} +#define CONFIG_CPU_VARIANT "MIN" +static inline const char * config_cpu_variant_read(void) { + return "MIN"; +} +#define CONFIG_CPU_VARIANT_MIN 1 +static inline int config_cpu_variant_min_read(void) { + return 1; +} +#define CONFIG_CSR_ALIGNMENT 32 +static inline int config_csr_alignment_read(void) { + return 32; +} +#define CONFIG_CSR_DATA_WIDTH 8 +static inline int config_csr_data_width_read(void) { + return 8; +} + +#endif diff --git a/hw/bsp/fomu/include/hw/common.h b/hw/bsp/fomu/include/hw/common.h new file mode 100644 index 000000000..6a97ca2e9 --- /dev/null +++ b/hw/bsp/fomu/include/hw/common.h @@ -0,0 +1,33 @@ +#ifndef _HW_COMMON_H_ +#define _HW_COMMON_H_ +#include +static inline void csr_writeb(uint8_t value, uint32_t addr) +{ + *((volatile uint8_t *)addr) = value; +} + +static inline uint8_t csr_readb(uint32_t addr) +{ + return *(volatile uint8_t *)addr; +} + +static inline void csr_writew(uint16_t value, uint32_t addr) +{ + *((volatile uint16_t *)addr) = value; +} + +static inline uint16_t csr_readw(uint32_t addr) +{ + return *(volatile uint16_t *)addr; +} + +static inline void csr_writel(uint32_t value, uint32_t addr) +{ + *((volatile uint32_t *)addr) = value; +} + +static inline uint32_t csr_readl(uint32_t addr) +{ + return *(volatile uint32_t *)addr; +} +#endif /* _HW_COMMON_H_ */ \ No newline at end of file diff --git a/hw/bsp/fomu/include/irq.h b/hw/bsp/fomu/include/irq.h new file mode 100644 index 000000000..a82218907 --- /dev/null +++ b/hw/bsp/fomu/include/irq.h @@ -0,0 +1,71 @@ +#ifndef __IRQ_H +#define __IRQ_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#define CSR_MSTATUS_MIE 0x8 + +#define CSR_IRQ_MASK 0xBC0 +#define CSR_IRQ_PENDING 0xFC0 + +#define CSR_DCACHE_INFO 0xCC0 + +#define csrr(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +#define csrw(reg, val) ({ \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ + else \ + asm volatile ("csrw " #reg ", %0" :: "r"(val)); }) + +#define csrs(reg, bit) ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrs x0, " #reg ", %0" :: "i"(bit)); \ + else \ + asm volatile ("csrrs x0, " #reg ", %0" :: "r"(bit)); }) + +#define csrc(reg, bit) ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrc x0, " #reg ", %0" :: "i"(bit)); \ + else \ + asm volatile ("csrrc x0, " #reg ", %0" :: "r"(bit)); }) + +static inline unsigned int irq_getie(void) +{ + return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; +} + +static inline void irq_setie(unsigned int ie) +{ + if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); +} + +static inline unsigned int irq_getmask(void) +{ + unsigned int mask; + asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK)); + return mask; +} + +static inline void irq_setmask(unsigned int mask) +{ + asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); +} + +static inline unsigned int irq_pending(void) +{ + unsigned int pending; + asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING)); + return pending; +} + +#ifdef __cplusplus +} +#endif + +#endif /* __IRQ_H */ \ No newline at end of file diff --git a/hw/bsp/fomu/output_format.ld b/hw/bsp/fomu/output_format.ld new file mode 100644 index 000000000..5e76f5f4e --- /dev/null +++ b/hw/bsp/fomu/output_format.ld @@ -0,0 +1 @@ +OUTPUT_FORMAT("elf32-littleriscv") diff --git a/hw/bsp/fomu/regions.ld b/hw/bsp/fomu/regions.ld new file mode 100644 index 000000000..51811f66e --- /dev/null +++ b/hw/bsp/fomu/regions.ld @@ -0,0 +1,6 @@ +MEMORY { + csr : ORIGIN = 0x60000000, LENGTH = 0x01000000 + vexriscv_debug : ORIGIN = 0xf00f0000, LENGTH = 0x00000100 + sram : ORIGIN = 0x10000000, LENGTH = 0x00020000 + rom : ORIGIN = 0x00000000, LENGTH = 0x00002000 +} diff --git a/hw/bsp/lpcxpresso11u37/board.mk b/hw/bsp/lpcxpresso11u37/board.mk index ced7ceefd..d3121ab95 100644 --- a/hw/bsp/lpcxpresso11u37/board.mk +++ b/hw/bsp/lpcxpresso11u37/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m0 \ @@ -13,7 +14,7 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=nested-externs -Wno-error=strict-prototypes -Wno-error=unused-parameter -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc11uxx/lpc_chip_11uxx +MCU_DIR = hw/mcu/nxp/lpcopen/lpc11uxx/lpc_chip_11uxx # All source paths should be relative to the top level. LD_FILE = hw/bsp/lpcxpresso11u37/lpc11u37.ld diff --git a/hw/bsp/lpcxpresso11u68/board.mk b/hw/bsp/lpcxpresso11u68/board.mk index 9396a599a..ba84b7d95 100644 --- a/hw/bsp/lpcxpresso11u68/board.mk +++ b/hw/bsp/lpcxpresso11u68/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m0plus \ @@ -10,7 +11,7 @@ CFLAGS += \ -DCFG_TUSB_MEM_SECTION='__attribute__((section(".data.$$RAM3")))' \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc11u6x/lpc_chip_11u6x +MCU_DIR = hw/mcu/nxp/lpcopen/lpc11u6x/lpc_chip_11u6x # All source paths should be relative to the top level. LD_FILE = hw/bsp/lpcxpresso11u68/lpc11u68.ld diff --git a/hw/bsp/lpcxpresso1347/board.mk b/hw/bsp/lpcxpresso1347/board.mk index 0f9be1b56..54a83a3b6 100644 --- a/hw/bsp/lpcxpresso1347/board.mk +++ b/hw/bsp/lpcxpresso1347/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m3 \ @@ -13,7 +14,7 @@ CFLAGS += \ # startup.c and lpc_types.h cause following errors CFLAGS += -Wno-error=nested-externs -Wno-error=strict-prototypes -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc13xx/lpc_chip_13xx +MCU_DIR = hw/mcu/nxp/lpcopen/lpc13xx/lpc_chip_13xx # All source paths should be relative to the top level. LD_FILE = hw/bsp/lpcxpresso1347/lpc1347.ld diff --git a/hw/bsp/lpcxpresso1549/board.mk b/hw/bsp/lpcxpresso1549/board.mk index 929c63a8d..18325c5f7 100644 --- a/hw/bsp/lpcxpresso1549/board.mk +++ b/hw/bsp/lpcxpresso1549/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m3 \ @@ -12,7 +13,7 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=strict-prototypes -Wno-error=unused-parameter -Wno-error=unused-variable -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc15xx/lpc_chip_15xx +MCU_DIR = hw/mcu/nxp/lpcopen/lpc15xx/lpc_chip_15xx # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/lpc1549.ld diff --git a/hw/bsp/lpcxpresso1769/board.mk b/hw/bsp/lpcxpresso1769/board.mk index 8bbc89138..b87d6afc9 100644 --- a/hw/bsp/lpcxpresso1769/board.mk +++ b/hw/bsp/lpcxpresso1769/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m3 \ @@ -11,14 +12,11 @@ CFLAGS += \ # lpc_types.h cause following errors CFLAGS += -Wno-error=strict-prototypes -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc175x_6x/lpc_chip_175x_6x +MCU_DIR = hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x # All source paths should be relative to the top level. LD_FILE = hw/bsp/lpcxpresso1769/lpc1769.ld -# TODO remove later -SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c - SRC_C += \ $(MCU_DIR)/../gcc/cr_startup_lpc175x_6x.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ diff --git a/hw/bsp/lpcxpresso1769/lpcxpresso1769.c b/hw/bsp/lpcxpresso1769/lpcxpresso1769.c index e2d5f6cf2..76755e89f 100644 --- a/hw/bsp/lpcxpresso1769/lpcxpresso1769.c +++ b/hw/bsp/lpcxpresso1769/lpcxpresso1769.c @@ -143,6 +143,20 @@ void board_init(void) #endif } +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/lpcxpresso51u68/board.mk b/hw/bsp/lpcxpresso51u68/board.mk index e5576c3c0..61fbc0623 100644 --- a/hw/bsp/lpcxpresso51u68/board.mk +++ b/hw/bsp/lpcxpresso51u68/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m0plus \ @@ -10,7 +11,7 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=nested-externs -Wno-error=unused-parameter -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc51u6x/devices/LPC51U68 +MCU_DIR = hw/mcu/nxp/sdk/devices/LPC51U68 # All source paths should be relative to the top level. LD_FILE = $(MCU_DIR)/gcc/LPC51U68_flash.ld diff --git a/hw/bsp/lpcxpresso54114/board.mk b/hw/bsp/lpcxpresso54114/board.mk index 21c8dfd32..474a1ac5b 100644 --- a/hw/bsp/lpcxpresso54114/board.mk +++ b/hw/bsp/lpcxpresso54114/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ @@ -12,7 +13,7 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc54xxx/devices/LPC54114 +MCU_DIR = hw/mcu/nxp/sdk/devices/LPC54114 # All source paths should be relative to the top level. LD_FILE = $(MCU_DIR)/gcc/LPC54114J256_cm4_flash.ld diff --git a/hw/bsp/lpcxpresso55s69/board.mk b/hw/bsp/lpcxpresso55s69/board.mk index 6f1afaac1..5977ce9f4 100644 --- a/hw/bsp/lpcxpresso55s69/board.mk +++ b/hw/bsp/lpcxpresso55s69/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m33 \ @@ -12,7 +13,7 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=float-equal -Wno-error=nested-externs -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc55xx/devices/LPC55S69 +MCU_DIR = hw/mcu/nxp/sdk/devices/LPC55S69 # All source paths should be relative to the top level. LD_FILE = $(MCU_DIR)/gcc/LPC55S69_cm33_core0_flash.ld diff --git a/hw/bsp/mbed1768/board.mk b/hw/bsp/mbed1768/board.mk index 4e4cd1d8f..60428bcb4 100644 --- a/hw/bsp/mbed1768/board.mk +++ b/hw/bsp/mbed1768/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m3 \ @@ -11,14 +12,11 @@ CFLAGS += \ # startup.c and lpc_types.h cause following errors CFLAGS += -Wno-error=nested-externs -Wno-error=strict-prototypes -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc175x_6x/lpc_chip_175x_6x +MCU_DIR = hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x # All source paths should be relative to the top level. LD_FILE = hw/bsp/mbed1768/lpc1768.ld -# TODO remove later -SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c - SRC_C += \ $(MCU_DIR)/../gcc/cr_startup_lpc175x_6x.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ @@ -43,5 +41,7 @@ FREERTOS_PORT = ARM_CM3 JLINK_DEVICE = LPC1768 JLINK_IF = swd -# flash using jlink -flash: flash-jlink +# flash using pyocd +flash: $(BUILD)/$(BOARD)-firmware.hex + pyocd flash -t lpc1768 $< + diff --git a/hw/bsp/mbed1768/mbed1768.c b/hw/bsp/mbed1768/mbed1768.c index 9f1ed12ef..66cf44a0e 100644 --- a/hw/bsp/mbed1768/mbed1768.c +++ b/hw/bsp/mbed1768/mbed1768.c @@ -135,6 +135,20 @@ void board_init(void) #endif } +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/mcb1800/board.mk b/hw/bsp/mcb1800/board.mk index 3b8ee2968..b05d4d71a 100644 --- a/hw/bsp/mcb1800/board.mk +++ b/hw/bsp/mcb1800/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m3 \ @@ -10,14 +11,11 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=strict-prototypes -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc18xx/lpc_chip_18xx +MCU_DIR = hw/mcu/nxp/lpcopen/lpc18xx/lpc_chip_18xx # All source paths should be relative to the top level. LD_FILE = hw/bsp/mcb1800/lpc1857.ld -# TODO remove later -SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c - SRC_C += \ $(MCU_DIR)/../gcc/cr_startup_lpc18xx.c \ $(MCU_DIR)/src/chip_18xx_43xx.c \ @@ -32,7 +30,7 @@ INC += \ # For TinyUSB port source VENDOR = nxp -CHIP_FAMILY = lpc18_43 +CHIP_FAMILY = transdimension # For freeRTOS port source FREERTOS_PORT = ARM_CM3 diff --git a/hw/bsp/mcb1800/mcb1800.c b/hw/bsp/mcb1800/mcb1800.c index deb17f113..6d5284869 100644 --- a/hw/bsp/mcb1800/mcb1800.c +++ b/hw/bsp/mcb1800/mcb1800.c @@ -139,39 +139,63 @@ void board_init(void) #if CFG_TUSB_RHPORT0_MODE Chip_USB0_Init(); - // Reset controller - LPC_USB0->USBCMD_D |= 0x02; - while( LPC_USB0->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - #else // TODO OTG - LPC_USB0->USBMODE_D = USBMODE_DEVICE; - LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; - #endif +// // Reset controller +// LPC_USB0->USBCMD_D |= 0x02; +// while( LPC_USB0->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST +// LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// #else // TODO OTG +// LPC_USB0->USBMODE_D = USBMODE_DEVICE; +// LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; +// #endif #endif // USB1 #if CFG_TUSB_RHPORT1_MODE Chip_USB1_Init(); - // Reset controller - LPC_USB1->USBCMD_D |= 0x02; - while( LPC_USB1->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST - LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - #else // TODO OTG - LPC_USB1->USBMODE_D = USBMODE_DEVICE; - #endif - - // USB1 as fullspeed - LPC_USB1->PORTSC1_D |= (1<<24); +// // Reset controller +// LPC_USB1->USBCMD_D |= 0x02; +// while( LPC_USB1->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST +// LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// #else // TODO OTG +// LPC_USB1->USBMODE_D = USBMODE_DEVICE; +// #endif +// +// // USB1 as fullspeed +// LPC_USB1->PORTSC1_D |= (1<<24); #endif } +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB0_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + +void USB1_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST + tuh_isr(1); + #endif + + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE + tud_isr(1); + #endif +} //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/metro_m0_express/board.mk b/hw/bsp/metro_m0_express/board.mk index 3ea672807..2039219a4 100644 --- a/hw/bsp/metro_m0_express/board.mk +++ b/hw/bsp/metro_m0_express/board.mk @@ -1,10 +1,11 @@ CFLAGS += \ - -DCONF_DFLL_OVERWRITE_CALIBRATION=0 \ - -D__SAMD21G18A__ \ + -flto \ -mthumb \ -mabi=aapcs-linux \ -mcpu=cortex-m0plus \ -nostdlib -nostartfiles \ + -D__SAMD21G18A__ \ + -DCONF_DFLL_OVERWRITE_CALIBRATION=0 \ -DCFG_TUSB_MCU=OPT_MCU_SAMD21 # All source paths should be relative to the top level. diff --git a/hw/bsp/metro_m4_express/board.mk b/hw/bsp/metro_m4_express/board.mk index c62d9bc33..010e4b868 100644 --- a/hw/bsp/metro_m4_express/board.mk +++ b/hw/bsp/metro_m4_express/board.mk @@ -1,11 +1,12 @@ CFLAGS += \ - -D__SAMD51J19A__ \ + -flto \ -mthumb \ -mabi=aapcs-linux \ -mcpu=cortex-m4 \ -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ -nostdlib -nostartfiles \ + -D__SAMD51J19A__ \ -DCFG_TUSB_MCU=OPT_MCU_SAMD51 CFLAGS += -Wno-error=undef diff --git a/hw/bsp/mimxrt1010_evk/board.h b/hw/bsp/mimxrt1010_evk/board.h new file mode 100644 index 000000000..7e4b57297 --- /dev/null +++ b/hw/bsp/mimxrt1010_evk/board.h @@ -0,0 +1,36 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "fsl_device_registers.h" + +// required since iMX RT10xx SDK include this file for board size +#define BOARD_FLASH_SIZE (0x1000000U) + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/mimxrt1010_evk/board.mk b/hw/bsp/mimxrt1010_evk/board.mk new file mode 100644 index 000000000..24a3dbdcd --- /dev/null +++ b/hw/bsp/mimxrt1010_evk/board.mk @@ -0,0 +1,52 @@ +CFLAGS += \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m7 \ + -mfloat-abi=hard \ + -mfpu=fpv5-d16 \ + -D__ARMVFP__=0 -D__ARMFPV5__=0\ + -DCPU_MIMXRT1011DAE5A \ + -DXIP_EXTERNAL_FLASH=1 \ + -DXIP_BOOT_HEADER_ENABLE=1 \ + -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX + +# mcu driver cause following warnings +CFLAGS += -Wno-error=unused-parameter -Wno-error=implicit-fallthrough= + +MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1011 + +# All source paths should be relative to the top level. +LD_FILE = $(MCU_DIR)/gcc/MIMXRT1011xxxxx_flexspi_nor.ld + +SRC_C += \ + $(MCU_DIR)/system_MIMXRT1011.c \ + $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ + $(MCU_DIR)/project_template/clock_config.c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(MCU_DIR)/drivers/fsl_gpio.c \ + $(MCU_DIR)/drivers/fsl_common.c \ + $(MCU_DIR)/drivers/fsl_lpuart.c + +INC += \ + $(TOP)/hw/bsp/$(BOARD) \ + $(TOP)/$(MCU_DIR)/../../CMSIS/Include \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/$(MCU_DIR)/drivers \ + $(TOP)/$(MCU_DIR)/project_template \ + +SRC_S += $(MCU_DIR)/gcc/startup_MIMXRT1011.S + +# For TinyUSB port source +VENDOR = nxp +CHIP_FAMILY = transdimension + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM7 + +# For flash-jlink target +JLINK_DEVICE = MIMXRT1011DAE5A +JLINK_IF = swd + +# flash by copying bin file to DAP Mass Storage +flash: $(BUILD)/$(BOARD)-firmware.bin + cp $< /media/$(USER)/RT1010-EVK/ diff --git a/hw/bsp/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.c b/hw/bsp/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.c new file mode 100644 index 000000000..cd50a93d1 --- /dev/null +++ b/hw/bsp/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.c @@ -0,0 +1,48 @@ +/* + * Copyright 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "evkmimxrt1010_flexspi_nor_config.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_100MHz, + .sflashA1Size = 16u * 1024u * 1024u, + .lookupTable = + { + // Read LUTs + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/hw/bsp/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.h b/hw/bsp/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.h new file mode 100644 index 000000000..4be2760be --- /dev/null +++ b/hw/bsp/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.h @@ -0,0 +1,267 @@ +/* + * Copyright 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +//!@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, +} flexspi_serial_clk_freq_t; + +//!@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, //!< Clock configure for SDR mode + kFlexSpiClk_DDR, //!< Clock configurat for DDR mode +}; + +//!@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +//!@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. +}; + +//!@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +//!@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +//!@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; //!< Sequence Number, valid number: 1-16 + uint8_t seqId; //!< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +//!@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, //!< Reset device command +}; + +//!@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + //! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + //! Generic configuration, etc. + uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + //! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + //! sequence number, [31:16] Reserved + uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + //! details + uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + //! Chapter for more details + uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + //! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 +#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 +#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 +#define NOR_CMD_INDEX_DUMMY 6 //!< 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ + CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ + 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ + CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ + 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ + CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ + 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ + 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI + uint32_t pageSize; //!< Page size of Serial NOR + uint32_t sectorSize; //!< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command + uint8_t isUniformBlockSize; //!< Sector/Block size is the same + uint8_t reserved0[2]; //!< Reserved for future use + uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; //!< Block size + uint32_t reserve2[11]; //!< Reserved for future use +} flexspi_nor_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ */ diff --git a/hw/bsp/mimxrt1010_evk/mimxrt1010_evk.c b/hw/bsp/mimxrt1010_evk/mimxrt1010_evk.c new file mode 100644 index 000000000..a76e2d9b6 --- /dev/null +++ b/hw/bsp/mimxrt1010_evk/mimxrt1010_evk.c @@ -0,0 +1,170 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "../board.h" +#include "fsl_device_registers.h" +#include "fsl_gpio.h" +#include "fsl_iomuxc.h" +#include "fsl_clock.h" +#include "fsl_lpuart.h" + +#include "clock_config.h" + +#define LED_PINMUX IOMUXC_GPIO_11_GPIOMUX_IO11 +#define LED_PORT GPIO1 +#define LED_PIN 11 +#define LED_STATE_ON 0 + +// SW8 button +#define BUTTON_PINMUX IOMUXC_GPIO_SD_05_GPIO2_IO05 +#define BUTTON_PORT GPIO2 +#define BUTTON_PIN 5 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_PORT LPUART1 +#define UART_RX_PINMUX IOMUXC_GPIO_09_LPUART1_RXD +#define UART_TX_PINMUX IOMUXC_GPIO_10_LPUART1_TXD + +const uint8_t dcd_data[] = { 0x00 }; + +void board_init(void) +{ + // Init clock + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + + // Enable IOCON clock + CLOCK_EnableClock(kCLOCK_Iomuxc); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) +// NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + // LED + IOMUXC_SetPinMux( LED_PINMUX, 0U); + IOMUXC_SetPinConfig( LED_PINMUX, 0x10B0U); + + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0, kGPIO_NoIntmode }; + GPIO_PinInit(LED_PORT, LED_PIN, &led_config); + board_led_write(true); + + // Button + IOMUXC_SetPinMux( BUTTON_PINMUX, 0U); + IOMUXC_SetPinConfig(BUTTON_PINMUX, 0x01B0A0U); + gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0, kGPIO_IntRisingEdge, }; + GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); + + // UART + IOMUXC_SetPinMux( UART_TX_PINMUX, 0U); + IOMUXC_SetPinMux( UART_RX_PINMUX, 0U); + IOMUXC_SetPinConfig( UART_TX_PINMUX, 0x10B0u); + IOMUXC_SetPinConfig( UART_RX_PINMUX, 0x10B0u); + + lpuart_config_t uart_config; + LPUART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; + uart_config.enableTx = true; + uart_config.enableRx = true; + LPUART_Init(UART_PORT, &uart_config, (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U)); + + //------------- USB0 -------------// + // Clock + CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); + CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U); + + USBPHY_Type* usb_phy = USBPHY; + + // Enable PHY support for Low speed device + LS via FS Hub + usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; + + // Enable all power for normal operation + usb_phy->PWD = 0; + + // TX Timing + uint32_t phytx = usb_phy->TX; + phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); + phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); + usb_phy->TX = phytx; +} + +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_OTG1_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + // active low + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + LPUART_ReadBlocking(UART_PORT, buf, len); + return len; +} + +int board_uart_write(void const * buf, int len) +{ + LPUART_WriteBlocking(UART_PORT, (uint8_t*)buf, len); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler(void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif diff --git a/hw/bsp/mimxrt1015_evk/board.h b/hw/bsp/mimxrt1015_evk/board.h new file mode 100644 index 000000000..5f3e31586 --- /dev/null +++ b/hw/bsp/mimxrt1015_evk/board.h @@ -0,0 +1,34 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef BOARD_H_ +#define BOARD_H_ + +// required since iMX RT10xx SDK include this file for board size +#define BOARD_FLASH_SIZE (0x1000000U) + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/mimxrt1015_evk/board.mk b/hw/bsp/mimxrt1015_evk/board.mk new file mode 100644 index 000000000..a538c7dc2 --- /dev/null +++ b/hw/bsp/mimxrt1015_evk/board.mk @@ -0,0 +1,52 @@ +CFLAGS += \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m7 \ + -mfloat-abi=hard \ + -mfpu=fpv5-d16 \ + -D__ARMVFP__=0 -D__ARMFPV5__=0\ + -DCPU_MIMXRT1015DAF5A \ + -DXIP_EXTERNAL_FLASH=1 \ + -DXIP_BOOT_HEADER_ENABLE=1 \ + -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX + +# mcu driver cause following warnings +CFLAGS += -Wno-error=unused-parameter -Wno-error=implicit-fallthrough= + +MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1015 + +# All source paths should be relative to the top level. +LD_FILE = $(MCU_DIR)/gcc/MIMXRT1015xxxxx_flexspi_nor.ld + +SRC_C += \ + $(MCU_DIR)/system_MIMXRT1015.c \ + $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ + $(MCU_DIR)/project_template/clock_config.c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(MCU_DIR)/drivers/fsl_gpio.c \ + $(MCU_DIR)/drivers/fsl_common.c \ + $(MCU_DIR)/drivers/fsl_lpuart.c + +INC += \ + $(TOP)/hw/bsp/$(BOARD) \ + $(TOP)/$(MCU_DIR)/../../CMSIS/Include \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/$(MCU_DIR)/drivers \ + $(TOP)/$(MCU_DIR)/project_template \ + +SRC_S += $(MCU_DIR)/gcc/startup_MIMXRT1015.S + +# For TinyUSB port source +VENDOR = nxp +CHIP_FAMILY = transdimension + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM7 + +# For flash-jlink target +JLINK_DEVICE = MIMXRT1015DAF5A +JLINK_IF = swd + +# flash by copying bin file to DAP Mass Storage +flash: $(BUILD)/$(BOARD)-firmware.bin + cp $< /media/$(USER)/RT1015-EVK/ diff --git a/hw/bsp/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.c b/hw/bsp/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.c new file mode 100644 index 000000000..a396fe60d --- /dev/null +++ b/hw/bsp/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.c @@ -0,0 +1,48 @@ +/* + * Copyright 2018-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "evkmimxrt1015_flexspi_nor_config.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_100MHz, + .sflashA1Size = 16u * 1024u * 1024u, + .lookupTable = + { + // Read LUTs + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/hw/bsp/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.h b/hw/bsp/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.h new file mode 100644 index 000000000..94af5a115 --- /dev/null +++ b/hw/bsp/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.h @@ -0,0 +1,268 @@ +/* + * Copyright 2018-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EVKMIMXRT1015_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1015_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +//!@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_133MHz = 7, + kFlexSpiSerialClk_166MHz = 8, + kFlexSpiSerialClk_200MHz = 9, +} flexspi_serial_clk_freq_t; + +//!@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, //!< Clock configure for SDR mode + kFlexSpiClk_DDR, //!< Clock configurat for DDR mode +}; + +//!@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +//!@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. +}; + +//!@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +//!@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +//!@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; //!< Sequence Number, valid number: 1-16 + uint8_t seqId; //!< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +//!@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, //!< Reset device command +}; + +//!@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + //! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + //! Generic configuration, etc. + uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + //! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + //! sequence number, [31:16] Reserved + uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + //! details + uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + //! Chapter for more details + uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + //! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 +#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 +#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 +#define NOR_CMD_INDEX_DUMMY 6 //!< 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ + CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ + 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ + CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ + 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ + CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ + 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ + 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI + uint32_t pageSize; //!< Page size of Serial NOR + uint32_t sectorSize; //!< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command + uint8_t isUniformBlockSize; //!< Sector/Block size is the same + uint8_t reserved0[2]; //!< Reserved for future use + uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; //!< Block size + uint32_t reserve2[11]; //!< Reserved for future use +} flexspi_nor_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1015_FLEXSPI_NOR_CONFIG__ */ diff --git a/hw/bsp/mimxrt1015_evk/mimxrt1015_evk.c b/hw/bsp/mimxrt1015_evk/mimxrt1015_evk.c new file mode 100644 index 000000000..955344884 --- /dev/null +++ b/hw/bsp/mimxrt1015_evk/mimxrt1015_evk.c @@ -0,0 +1,170 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "../board.h" +#include "fsl_device_registers.h" +#include "fsl_gpio.h" +#include "fsl_iomuxc.h" +#include "fsl_clock.h" +#include "fsl_lpuart.h" + +#include "clock_config.h" + +#define LED_PINMUX IOMUXC_GPIO_SD_B1_01_GPIO3_IO21 +#define LED_PORT GPIO3 +#define LED_PIN 21 +#define LED_STATE_ON 0 + +// SW8 button +#define BUTTON_PINMUX IOMUXC_GPIO_EMC_09_GPIO2_IO09 +#define BUTTON_PORT GPIO2 +#define BUTTON_PIN 9 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_PORT LPUART1 +#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_07_LPUART1_RX +#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_06_LPUART1_TX + +const uint8_t dcd_data[] = { 0x00 }; + +void board_init(void) +{ + // Init clock + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + + // Enable IOCON clock + CLOCK_EnableClock(kCLOCK_Iomuxc); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) +// NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + // LED + IOMUXC_SetPinMux( LED_PINMUX, 0U); + IOMUXC_SetPinConfig( LED_PINMUX, 0x10B0U); + + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0, kGPIO_NoIntmode }; + GPIO_PinInit(LED_PORT, LED_PIN, &led_config); + board_led_write(true); + + // Button + IOMUXC_SetPinMux( BUTTON_PINMUX, 0U); + IOMUXC_SetPinConfig(BUTTON_PINMUX, 0x01B0A0U); + gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0, kGPIO_IntRisingEdge, }; + GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); + + // UART + IOMUXC_SetPinMux( UART_TX_PINMUX, 0U); + IOMUXC_SetPinMux( UART_RX_PINMUX, 0U); + IOMUXC_SetPinConfig( UART_TX_PINMUX, 0x10B0u); + IOMUXC_SetPinConfig( UART_RX_PINMUX, 0x10B0u); + + lpuart_config_t uart_config; + LPUART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; + uart_config.enableTx = true; + uart_config.enableRx = true; + LPUART_Init(UART_PORT, &uart_config, (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U)); + + //------------- USB0 -------------// + // Clock + CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); + CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U); + + USBPHY_Type* usb_phy = USBPHY; + + // Enable PHY support for Low speed device + LS via FS Hub + usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; + + // Enable all power for normal operation + usb_phy->PWD = 0; + + // TX Timing + uint32_t phytx = usb_phy->TX; + phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); + phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); + usb_phy->TX = phytx; +} + +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_OTG1_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + // active low + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + LPUART_ReadBlocking(UART_PORT, buf, len); + return len; +} + +int board_uart_write(void const * buf, int len) +{ + LPUART_WriteBlocking(UART_PORT, (uint8_t*)buf, len); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler(void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif diff --git a/hw/bsp/mimxrt1020_evk/board.h b/hw/bsp/mimxrt1020_evk/board.h new file mode 100644 index 000000000..f1bd06369 --- /dev/null +++ b/hw/bsp/mimxrt1020_evk/board.h @@ -0,0 +1,34 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef BOARD_H_ +#define BOARD_H_ + +// required since iMX RT10xx SDK include this file for board size +#define BOARD_FLASH_SIZE (0x800000U) + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/mimxrt1020_evk/board.mk b/hw/bsp/mimxrt1020_evk/board.mk new file mode 100644 index 000000000..83a570858 --- /dev/null +++ b/hw/bsp/mimxrt1020_evk/board.mk @@ -0,0 +1,53 @@ +CFLAGS += \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m7 \ + -mfloat-abi=hard \ + -mfpu=fpv5-d16 \ + -D__ARMVFP__=0 -D__ARMFPV5__=0\ + -DCPU_MIMXRT1021DAG5A \ + -DXIP_EXTERNAL_FLASH=1 \ + -DXIP_BOOT_HEADER_ENABLE=1 \ + -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX + +# mcu driver cause following warnings +#CFLAGS += -Wno-error=float-equal -Wno-error=nested-externs +CFLAGS += -Wno-error=unused-parameter + +MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1021 + +# All source paths should be relative to the top level. +LD_FILE = $(MCU_DIR)/gcc/MIMXRT1021xxxxx_flexspi_nor.ld + +SRC_C += \ + $(MCU_DIR)/system_MIMXRT1021.c \ + $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ + $(MCU_DIR)/project_template/clock_config.c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(MCU_DIR)/drivers/fsl_gpio.c \ + $(MCU_DIR)/drivers/fsl_common.c \ + $(MCU_DIR)/drivers/fsl_lpuart.c + +INC += \ + $(TOP)/hw/bsp/$(BOARD) \ + $(TOP)/$(MCU_DIR)/../../CMSIS/Include \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/$(MCU_DIR)/drivers \ + $(TOP)/$(MCU_DIR)/project_template \ + +SRC_S += $(MCU_DIR)/gcc/startup_MIMXRT1021.S + +# For TinyUSB port source +VENDOR = nxp +CHIP_FAMILY = transdimension + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM7 + +# For flash-jlink target +JLINK_DEVICE = MIMXRT1021DAG5A +JLINK_IF = swd + +# flash by copying bin file to DAP Mass Storage +flash: $(BUILD)/$(BOARD)-firmware.bin + cp $< /media/$(USER)/RT1020-EVK/ diff --git a/hw/bsp/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.c b/hw/bsp/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.c new file mode 100644 index 000000000..6bafe195f --- /dev/null +++ b/hw/bsp/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.c @@ -0,0 +1,49 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "evkmimxrt1020_flexspi_nor_config.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_100MHz, + .sflashA1Size = 8u * 1024u * 1024u, + .lookupTable = + { + // Read LUTs + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/hw/bsp/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.h b/hw/bsp/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.h new file mode 100644 index 000000000..f5e1aca5c --- /dev/null +++ b/hw/bsp/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.h @@ -0,0 +1,268 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +//!@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_133MHz = 7, + kFlexSpiSerialClk_166MHz = 8, + kFlexSpiSerialClk_200MHz = 9, +} flexspi_serial_clk_freq_t; + +//!@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, //!< Clock configure for SDR mode + kFlexSpiClk_DDR, //!< Clock configurat for DDR mode +}; + +//!@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +//!@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. +}; + +//!@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +//!@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +//!@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; //!< Sequence Number, valid number: 1-16 + uint8_t seqId; //!< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +//!@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, //!< Reset device command +}; + +//!@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + //! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + //! Generic configuration, etc. + uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + //! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + //! sequence number, [31:16] Reserved + uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + //! details + uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + //! Chapter for more details + uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + //! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 +#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 +#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 +#define NOR_CMD_INDEX_DUMMY 6 //!< 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ + CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ + 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ + CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ + 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ + CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ + 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ + 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI + uint32_t pageSize; //!< Page size of Serial NOR + uint32_t sectorSize; //!< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command + uint8_t isUniformBlockSize; //!< Sector/Block size is the same + uint8_t reserved0[2]; //!< Reserved for future use + uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; //!< Block size + uint32_t reserve2[11]; //!< Reserved for future use +} flexspi_nor_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1020_FLEXSPI_NOR_CONFIG__ */ diff --git a/hw/bsp/mimxrt1020_evk/mimxrt1020_evk.c b/hw/bsp/mimxrt1020_evk/mimxrt1020_evk.c new file mode 100644 index 000000000..708397f7f --- /dev/null +++ b/hw/bsp/mimxrt1020_evk/mimxrt1020_evk.c @@ -0,0 +1,169 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "../board.h" +#include "fsl_device_registers.h" +#include "fsl_gpio.h" +#include "fsl_iomuxc.h" +#include "fsl_clock.h" +#include "fsl_lpuart.h" + +#include "clock_config.h" + +#define LED_PINMUX IOMUXC_GPIO_AD_B0_05_GPIO1_IO05 +#define LED_PORT GPIO1 +#define LED_PIN 5 +#define LED_STATE_ON 0 + +// SW8 button +#define BUTTON_PINMUX IOMUXC_SNVS_WAKEUP_GPIO5_IO00 +#define BUTTON_PORT GPIO5 +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_PORT LPUART1 +#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_07_LPUART1_RX +#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_06_LPUART1_TX + +const uint8_t dcd_data[] = { 0x00 }; + +void board_init(void) +{ + // Init clock + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + + // Enable IOCON clock + CLOCK_EnableClock(kCLOCK_Iomuxc); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) +// NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + // LED + IOMUXC_SetPinMux( LED_PINMUX, 0U); + IOMUXC_SetPinConfig( LED_PINMUX, 0x10B0U); + + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0, kGPIO_NoIntmode }; + GPIO_PinInit(LED_PORT, LED_PIN, &led_config); + board_led_write(true); + + // Button + IOMUXC_SetPinMux( BUTTON_PINMUX, 0U); + gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0, kGPIO_IntRisingEdge, }; + GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); + + // UART + IOMUXC_SetPinMux( UART_TX_PINMUX, 0U); + IOMUXC_SetPinMux( UART_RX_PINMUX, 0U); + IOMUXC_SetPinConfig( UART_TX_PINMUX, 0x10B0u); + IOMUXC_SetPinConfig( UART_RX_PINMUX, 0x10B0u); + + lpuart_config_t uart_config; + LPUART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; + uart_config.enableTx = true; + uart_config.enableRx = true; + LPUART_Init(UART_PORT, &uart_config, (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U)); + + //------------- USB0 -------------// + // Clock + CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); + CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U); + + USBPHY_Type* usb_phy = USBPHY; + + // Enable PHY support for Low speed device + LS via FS Hub + usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; + + // Enable all power for normal operation + usb_phy->PWD = 0; + + // TX Timing + uint32_t phytx = usb_phy->TX; + phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); + phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); + usb_phy->TX = phytx; +} + +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_OTG1_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + // active low + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + LPUART_ReadBlocking(UART_PORT, buf, len); + return len; +} + +int board_uart_write(void const * buf, int len) +{ + LPUART_WriteBlocking(UART_PORT, (uint8_t*)buf, len); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler(void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif diff --git a/hw/bsp/mimxrt1050_evkb/board.h b/hw/bsp/mimxrt1050_evkb/board.h new file mode 100644 index 000000000..3f660ac7d --- /dev/null +++ b/hw/bsp/mimxrt1050_evkb/board.h @@ -0,0 +1,34 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef BOARD_H_ +#define BOARD_H_ + +// required since iMX RT10xx SDK include this file for board size +#define BOARD_FLASH_SIZE (0x4000000U) + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/mimxrt1050_evkb/board.mk b/hw/bsp/mimxrt1050_evkb/board.mk new file mode 100644 index 000000000..2303df11a --- /dev/null +++ b/hw/bsp/mimxrt1050_evkb/board.mk @@ -0,0 +1,53 @@ +CFLAGS += \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m7 \ + -mfloat-abi=hard \ + -mfpu=fpv5-d16 \ + -D__ARMVFP__=0 -D__ARMFPV5__=0\ + -DCPU_MIMXRT1052DVL6B \ + -DXIP_EXTERNAL_FLASH=1 \ + -DXIP_BOOT_HEADER_ENABLE=1 \ + -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX + +# mcu driver cause following warnings +#CFLAGS += -Wno-error=float-equal -Wno-error=nested-externs +CFLAGS += -Wno-error=unused-parameter + +MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1052 + +# All source paths should be relative to the top level. +LD_FILE = $(MCU_DIR)/gcc/MIMXRT1052xxxxx_flexspi_nor.ld + +SRC_C += \ + $(MCU_DIR)/system_MIMXRT1052.c \ + $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ + $(MCU_DIR)/project_template/clock_config.c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(MCU_DIR)/drivers/fsl_gpio.c \ + $(MCU_DIR)/drivers/fsl_common.c \ + $(MCU_DIR)/drivers/fsl_lpuart.c + +INC += \ + $(TOP)/hw/bsp/$(BOARD) \ + $(TOP)/$(MCU_DIR)/../../CMSIS/Include \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/$(MCU_DIR)/drivers \ + $(TOP)/$(MCU_DIR)/project_template \ + +SRC_S += $(MCU_DIR)/gcc/startup_MIMXRT1052.S + +# For TinyUSB port source +VENDOR = nxp +CHIP_FAMILY = transdimension + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM7 + +# For flash-jlink target +JLINK_DEVICE = MIMXRT1052xxx6B +JLINK_IF = swd + +# flash by copying bin file to DAP Mass Storage +flash: $(BUILD)/$(BOARD)-firmware.bin + cp $< /media/$(USER)/RT1050-EVK/ diff --git a/hw/bsp/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.c b/hw/bsp/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.c new file mode 100644 index 000000000..af6eabc8e --- /dev/null +++ b/hw/bsp/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.c @@ -0,0 +1,55 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "evkbimxrt1050_flexspi_nor_config.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t hyperflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .columnAddressWidth = 3u, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .controllerMiscOption = + (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) | + (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable), + .sflashPadType = kSerialFlash_8Pads, + .serialClkFreq = kFlexSpiSerialClk_133MHz, + .sflashA1Size = 64u * 1024u * 1024u, + .dataValidTime = {16u, 16u}, + .lookupTable = + { + // Read LUTs + FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xA0, RADDR_DDR, FLEXSPI_8PAD, 0x18), + FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10, DUMMY_DDR, FLEXSPI_8PAD, 0x06), + FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0), + }, + }, + .pageSize = 512u, + .sectorSize = 256u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = true, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/hw/bsp/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.h b/hw/bsp/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.h new file mode 100644 index 000000000..fe40e7ed7 --- /dev/null +++ b/hw/bsp/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.h @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EVKBIMXRT1050_FLEXSPI_NOR_CONFIG__ +#define __EVKBIMXRT1050_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +//!@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_133MHz = 7, + kFlexSpiSerialClk_166MHz = 8, + kFlexSpiSerialClk_200MHz = 9, +} flexspi_serial_clk_freq_t; + +//!@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, //!< Clock configure for SDR mode + kFlexSpiClk_DDR, //!< Clock configurat for DDR mode +}; + +//!@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +//!@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. +}; + +//!@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +//!@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +//!@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; //!< Sequence Number, valid number: 1-16 + uint8_t seqId; //!< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +//!@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, //!< Reset device command +}; + +//!@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + //! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + //! Generic configuration, etc. + uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + //! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + //! sequence number, [31:16] Reserved + uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + //! details + uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + //! Chapter for more details + uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + //! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 +#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 +#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 +#define NOR_CMD_INDEX_DUMMY 6 //!< 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ + CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ + 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ + CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ + 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ + CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ + 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ + 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI + uint32_t pageSize; //!< Page size of Serial NOR + uint32_t sectorSize; //!< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command + uint8_t isUniformBlockSize; //!< Sector/Block size is the same + uint8_t reserved0[2]; //!< Reserved for future use + uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; //!< Block size + uint32_t reserve2[11]; //!< Reserved for future use +} flexspi_nor_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKBIMXRT1050_FLEXSPI_NOR_CONFIG__ */ diff --git a/hw/bsp/mimxrt1050_evkb/mimxrt1050_evkb.c b/hw/bsp/mimxrt1050_evkb/mimxrt1050_evkb.c new file mode 100644 index 000000000..a21dcdbfc --- /dev/null +++ b/hw/bsp/mimxrt1050_evkb/mimxrt1050_evkb.c @@ -0,0 +1,184 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "../board.h" +#include "fsl_device_registers.h" +#include "fsl_gpio.h" +#include "fsl_iomuxc.h" +#include "fsl_clock.h" +#include "fsl_lpuart.h" + +#include "clock_config.h" + +#define LED_PINMUX IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 +#define LED_PORT GPIO1 +#define LED_PIN 9 +#define LED_STATE_ON 0 + +// SW8 button +#define BUTTON_PINMUX IOMUXC_SNVS_WAKEUP_GPIO5_IO00 +#define BUTTON_PORT GPIO5 +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_PORT LPUART1 +#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_13_LPUART1_RX +#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_12_LPUART1_TX + +const uint8_t dcd_data[] = { 0x00 }; + +void board_init(void) +{ + // Init clock + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + + // Enable IOCON clock + CLOCK_EnableClock(kCLOCK_Iomuxc); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) +// NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + // LED + IOMUXC_SetPinMux( LED_PINMUX, 0U); + IOMUXC_SetPinConfig( LED_PINMUX, 0x10B0U); + + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0, kGPIO_NoIntmode }; + GPIO_PinInit(LED_PORT, LED_PIN, &led_config); + board_led_write(true); + + // Button + IOMUXC_SetPinMux( BUTTON_PINMUX, 0U); + gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0, kGPIO_IntRisingEdge, }; + GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); + + // UART + IOMUXC_SetPinMux( UART_TX_PINMUX, 0U); + IOMUXC_SetPinMux( UART_RX_PINMUX, 0U); + IOMUXC_SetPinConfig( UART_TX_PINMUX, 0x10B0u); + IOMUXC_SetPinConfig( UART_RX_PINMUX, 0x10B0u); + + lpuart_config_t uart_config; + LPUART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; + uart_config.enableTx = true; + uart_config.enableRx = true; + LPUART_Init(UART_PORT, &uart_config, (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U)); + + //------------- USB0 -------------// + // Clock + CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); + CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U); + + USBPHY_Type* usb_phy = USBPHY1; + + // Enable PHY support for Low speed device + LS via FS Hub + usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; + + // Enable all power for normal operation + usb_phy->PWD = 0; + + // TX Timing + uint32_t phytx = usb_phy->TX; + phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); + phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); + usb_phy->TX = phytx; + + // USB1 +// CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U); +// CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U); +} + +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_OTG1_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + +void USB_OTG2_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST + tuh_isr(1); + #endif + + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE + tud_isr(1); + #endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + // active low + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + LPUART_ReadBlocking(UART_PORT, buf, len); + return len; +} + +int board_uart_write(void const * buf, int len) +{ + LPUART_WriteBlocking(UART_PORT, (uint8_t*)buf, len); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler(void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif diff --git a/hw/bsp/mimxrt1060_evk/board.h b/hw/bsp/mimxrt1060_evk/board.h new file mode 100644 index 000000000..f1bd06369 --- /dev/null +++ b/hw/bsp/mimxrt1060_evk/board.h @@ -0,0 +1,34 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef BOARD_H_ +#define BOARD_H_ + +// required since iMX RT10xx SDK include this file for board size +#define BOARD_FLASH_SIZE (0x800000U) + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/mimxrt1060_evk/board.mk b/hw/bsp/mimxrt1060_evk/board.mk new file mode 100644 index 000000000..4bfc48bbf --- /dev/null +++ b/hw/bsp/mimxrt1060_evk/board.mk @@ -0,0 +1,53 @@ +CFLAGS += \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m7 \ + -mfloat-abi=hard \ + -mfpu=fpv5-d16 \ + -D__ARMVFP__=0 -D__ARMFPV5__=0\ + -DCPU_MIMXRT1062DVL6A \ + -DXIP_EXTERNAL_FLASH=1 \ + -DXIP_BOOT_HEADER_ENABLE=1 \ + -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX + +# mcu driver cause following warnings +#CFLAGS += -Wno-error=float-equal -Wno-error=nested-externs +CFLAGS += -Wno-error=unused-parameter + +MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1062 + +# All source paths should be relative to the top level. +LD_FILE = $(MCU_DIR)/gcc/MIMXRT1062xxxxx_flexspi_nor.ld + +SRC_C += \ + $(MCU_DIR)/system_MIMXRT1062.c \ + $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ + $(MCU_DIR)/project_template/clock_config.c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(MCU_DIR)/drivers/fsl_gpio.c \ + $(MCU_DIR)/drivers/fsl_common.c \ + $(MCU_DIR)/drivers/fsl_lpuart.c + +INC += \ + $(TOP)/hw/bsp/$(BOARD) \ + $(TOP)/$(MCU_DIR)/../../CMSIS/Include \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/$(MCU_DIR)/drivers \ + $(TOP)/$(MCU_DIR)/project_template \ + +SRC_S += $(MCU_DIR)/gcc/startup_MIMXRT1062.S + +# For TinyUSB port source +VENDOR = nxp +CHIP_FAMILY = transdimension + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM7 + +# For flash-jlink target +JLINK_DEVICE = MIMXRT1062xxx6A +JLINK_IF = swd + +# flash by copying bin file to DAP Mass Storage +flash: $(BUILD)/$(BOARD)-firmware.bin + cp $< /media/$(USER)/RT1060-EVK/ diff --git a/hw/bsp/mimxrt1060_evk/evkmimxrt1060_flexspi_nor_config.c b/hw/bsp/mimxrt1060_evk/evkmimxrt1060_flexspi_nor_config.c new file mode 100644 index 000000000..5df2b7c10 --- /dev/null +++ b/hw/bsp/mimxrt1060_evk/evkmimxrt1060_flexspi_nor_config.c @@ -0,0 +1,49 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "evkmimxrt1060_flexspi_nor_config.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_100MHz, + .sflashA1Size = 8u * 1024u * 1024u, + .lookupTable = + { + // Read LUTs + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/hw/bsp/mimxrt1060_evk/evkmimxrt1060_flexspi_nor_config.h b/hw/bsp/mimxrt1060_evk/evkmimxrt1060_flexspi_nor_config.h new file mode 100644 index 000000000..28d7db57d --- /dev/null +++ b/hw/bsp/mimxrt1060_evk/evkmimxrt1060_flexspi_nor_config.h @@ -0,0 +1,268 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +//!@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, + kFlexSpiSerialClk_166MHz = 9, +} flexspi_serial_clk_freq_t; + +//!@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, //!< Clock configure for SDR mode + kFlexSpiClk_DDR, //!< Clock configurat for DDR mode +}; + +//!@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +//!@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. +}; + +//!@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +//!@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +//!@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; //!< Sequence Number, valid number: 1-16 + uint8_t seqId; //!< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +//!@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, //!< Reset device command +}; + +//!@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + //! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + //! Generic configuration, etc. + uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + //! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + //! sequence number, [31:16] Reserved + uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + //! details + uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + //! Chapter for more details + uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + //! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 +#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 +#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 +#define NOR_CMD_INDEX_DUMMY 6 //!< 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ + CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ + 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ + CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ + 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ + CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ + 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ + 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI + uint32_t pageSize; //!< Page size of Serial NOR + uint32_t sectorSize; //!< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command + uint8_t isUniformBlockSize; //!< Sector/Block size is the same + uint8_t reserved0[2]; //!< Reserved for future use + uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; //!< Block size + uint32_t reserve2[11]; //!< Reserved for future use +} flexspi_nor_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ diff --git a/hw/bsp/mimxrt1060_evk/mimxrt1060_evk.c b/hw/bsp/mimxrt1060_evk/mimxrt1060_evk.c new file mode 100644 index 000000000..a21dcdbfc --- /dev/null +++ b/hw/bsp/mimxrt1060_evk/mimxrt1060_evk.c @@ -0,0 +1,184 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "../board.h" +#include "fsl_device_registers.h" +#include "fsl_gpio.h" +#include "fsl_iomuxc.h" +#include "fsl_clock.h" +#include "fsl_lpuart.h" + +#include "clock_config.h" + +#define LED_PINMUX IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 +#define LED_PORT GPIO1 +#define LED_PIN 9 +#define LED_STATE_ON 0 + +// SW8 button +#define BUTTON_PINMUX IOMUXC_SNVS_WAKEUP_GPIO5_IO00 +#define BUTTON_PORT GPIO5 +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_PORT LPUART1 +#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_13_LPUART1_RX +#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_12_LPUART1_TX + +const uint8_t dcd_data[] = { 0x00 }; + +void board_init(void) +{ + // Init clock + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + + // Enable IOCON clock + CLOCK_EnableClock(kCLOCK_Iomuxc); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) +// NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + // LED + IOMUXC_SetPinMux( LED_PINMUX, 0U); + IOMUXC_SetPinConfig( LED_PINMUX, 0x10B0U); + + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0, kGPIO_NoIntmode }; + GPIO_PinInit(LED_PORT, LED_PIN, &led_config); + board_led_write(true); + + // Button + IOMUXC_SetPinMux( BUTTON_PINMUX, 0U); + gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0, kGPIO_IntRisingEdge, }; + GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); + + // UART + IOMUXC_SetPinMux( UART_TX_PINMUX, 0U); + IOMUXC_SetPinMux( UART_RX_PINMUX, 0U); + IOMUXC_SetPinConfig( UART_TX_PINMUX, 0x10B0u); + IOMUXC_SetPinConfig( UART_RX_PINMUX, 0x10B0u); + + lpuart_config_t uart_config; + LPUART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; + uart_config.enableTx = true; + uart_config.enableRx = true; + LPUART_Init(UART_PORT, &uart_config, (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U)); + + //------------- USB0 -------------// + // Clock + CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); + CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U); + + USBPHY_Type* usb_phy = USBPHY1; + + // Enable PHY support for Low speed device + LS via FS Hub + usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; + + // Enable all power for normal operation + usb_phy->PWD = 0; + + // TX Timing + uint32_t phytx = usb_phy->TX; + phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); + phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); + usb_phy->TX = phytx; + + // USB1 +// CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U); +// CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U); +} + +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_OTG1_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + +void USB_OTG2_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST + tuh_isr(1); + #endif + + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE + tud_isr(1); + #endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + // active low + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + LPUART_ReadBlocking(UART_PORT, buf, len); + return len; +} + +int board_uart_write(void const * buf, int len) +{ + LPUART_WriteBlocking(UART_PORT, (uint8_t*)buf, len); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler(void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif diff --git a/hw/bsp/mimxrt1064_evk/board.h b/hw/bsp/mimxrt1064_evk/board.h new file mode 100644 index 000000000..3157e7d5e --- /dev/null +++ b/hw/bsp/mimxrt1064_evk/board.h @@ -0,0 +1,34 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef BOARD_H_ +#define BOARD_H_ + +// required since iMX RT10xx SDK include this file for board size +#define BOARD_FLASH_SIZE (0x400000U) + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/mimxrt1064_evk/board.mk b/hw/bsp/mimxrt1064_evk/board.mk new file mode 100644 index 000000000..7b992da3e --- /dev/null +++ b/hw/bsp/mimxrt1064_evk/board.mk @@ -0,0 +1,53 @@ +CFLAGS += \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m7 \ + -mfloat-abi=hard \ + -mfpu=fpv5-d16 \ + -D__ARMVFP__=0 -D__ARMFPV5__=0\ + -DCPU_MIMXRT1064DVL6A \ + -DXIP_EXTERNAL_FLASH=1 \ + -DXIP_BOOT_HEADER_ENABLE=1 \ + -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX + +# mcu driver cause following warnings +#CFLAGS += -Wno-error=float-equal -Wno-error=nested-externs +CFLAGS += -Wno-error=unused-parameter + +MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1064 + +# All source paths should be relative to the top level. +LD_FILE = $(MCU_DIR)/gcc/MIMXRT1064xxxxx_flexspi_nor.ld + +SRC_C += \ + $(MCU_DIR)/system_MIMXRT1064.c \ + $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ + $(MCU_DIR)/project_template/clock_config.c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(MCU_DIR)/drivers/fsl_gpio.c \ + $(MCU_DIR)/drivers/fsl_common.c \ + $(MCU_DIR)/drivers/fsl_lpuart.c + +INC += \ + $(TOP)/hw/bsp/$(BOARD) \ + $(TOP)/$(MCU_DIR)/../../CMSIS/Include \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/$(MCU_DIR)/drivers \ + $(TOP)/$(MCU_DIR)/project_template \ + +SRC_S += $(MCU_DIR)/gcc/startup_MIMXRT1064.S + +# For TinyUSB port source +VENDOR = nxp +CHIP_FAMILY = transdimension + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM7 + +# For flash-jlink target +JLINK_DEVICE = MIMXRT1064xxx6A +JLINK_IF = swd + +# flash by copying bin file to DAP Mass Storage +flash: $(BUILD)/$(BOARD)-firmware.bin + cp $< /media/$(USER)/RT1064-EVK/ diff --git a/hw/bsp/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.c b/hw/bsp/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.c new file mode 100644 index 000000000..bfb1c2d59 --- /dev/null +++ b/hw/bsp/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.c @@ -0,0 +1,49 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "evkmimxrt1064_flexspi_nor_config.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_100MHz, + .sflashA1Size = 8u * 1024u * 1024u, + .lookupTable = + { + // Read LUTs + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/hw/bsp/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.h b/hw/bsp/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.h new file mode 100644 index 000000000..efdfe583f --- /dev/null +++ b/hw/bsp/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.h @@ -0,0 +1,268 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +//!@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, + kFlexSpiSerialClk_166MHz = 9, +} flexspi_serial_clk_freq_t; + +//!@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, //!< Clock configure for SDR mode + kFlexSpiClk_DDR, //!< Clock configurat for DDR mode +}; + +//!@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +//!@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. +}; + +//!@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +//!@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +//!@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; //!< Sequence Number, valid number: 1-16 + uint8_t seqId; //!< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +//!@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, //!< Reset device command +}; + +//!@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + //! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + //! Generic configuration, etc. + uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + //! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + //! sequence number, [31:16] Reserved + uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + //! details + uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + //! Chapter for more details + uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + //! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 +#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 +#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 +#define NOR_CMD_INDEX_DUMMY 6 //!< 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ + CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ + 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ + CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ + 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ + CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ + 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ + 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI + uint32_t pageSize; //!< Page size of Serial NOR + uint32_t sectorSize; //!< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command + uint8_t isUniformBlockSize; //!< Sector/Block size is the same + uint8_t reserved0[2]; //!< Reserved for future use + uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; //!< Block size + uint32_t reserve2[11]; //!< Reserved for future use +} flexspi_nor_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1064_FLEXSPI_NOR_CONFIG__ */ diff --git a/hw/bsp/mimxrt1064_evk/mimxrt1064_evk.c b/hw/bsp/mimxrt1064_evk/mimxrt1064_evk.c new file mode 100644 index 000000000..a21dcdbfc --- /dev/null +++ b/hw/bsp/mimxrt1064_evk/mimxrt1064_evk.c @@ -0,0 +1,184 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "../board.h" +#include "fsl_device_registers.h" +#include "fsl_gpio.h" +#include "fsl_iomuxc.h" +#include "fsl_clock.h" +#include "fsl_lpuart.h" + +#include "clock_config.h" + +#define LED_PINMUX IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 +#define LED_PORT GPIO1 +#define LED_PIN 9 +#define LED_STATE_ON 0 + +// SW8 button +#define BUTTON_PINMUX IOMUXC_SNVS_WAKEUP_GPIO5_IO00 +#define BUTTON_PORT GPIO5 +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_PORT LPUART1 +#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_13_LPUART1_RX +#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_12_LPUART1_TX + +const uint8_t dcd_data[] = { 0x00 }; + +void board_init(void) +{ + // Init clock + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + + // Enable IOCON clock + CLOCK_EnableClock(kCLOCK_Iomuxc); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) +// NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + // LED + IOMUXC_SetPinMux( LED_PINMUX, 0U); + IOMUXC_SetPinConfig( LED_PINMUX, 0x10B0U); + + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0, kGPIO_NoIntmode }; + GPIO_PinInit(LED_PORT, LED_PIN, &led_config); + board_led_write(true); + + // Button + IOMUXC_SetPinMux( BUTTON_PINMUX, 0U); + gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0, kGPIO_IntRisingEdge, }; + GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); + + // UART + IOMUXC_SetPinMux( UART_TX_PINMUX, 0U); + IOMUXC_SetPinMux( UART_RX_PINMUX, 0U); + IOMUXC_SetPinConfig( UART_TX_PINMUX, 0x10B0u); + IOMUXC_SetPinConfig( UART_RX_PINMUX, 0x10B0u); + + lpuart_config_t uart_config; + LPUART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; + uart_config.enableTx = true; + uart_config.enableRx = true; + LPUART_Init(UART_PORT, &uart_config, (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U)); + + //------------- USB0 -------------// + // Clock + CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); + CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U); + + USBPHY_Type* usb_phy = USBPHY1; + + // Enable PHY support for Low speed device + LS via FS Hub + usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; + + // Enable all power for normal operation + usb_phy->PWD = 0; + + // TX Timing + uint32_t phytx = usb_phy->TX; + phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); + phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); + usb_phy->TX = phytx; + + // USB1 +// CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U); +// CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U); +} + +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_OTG1_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + +void USB_OTG2_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST + tuh_isr(1); + #endif + + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE + tud_isr(1); + #endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + // active low + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + LPUART_ReadBlocking(UART_PORT, buf, len); + return len; +} + +int board_uart_write(void const * buf, int len) +{ + LPUART_WriteBlocking(UART_PORT, (uint8_t*)buf, len); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler(void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif diff --git a/hw/bsp/ngx4330/board.mk b/hw/bsp/ngx4330/board.mk index b82ae9d5c..d95aaf056 100644 --- a/hw/bsp/ngx4330/board.mk +++ b/hw/bsp/ngx4330/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ @@ -10,14 +11,11 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=strict-prototypes -Wno-error=unused-parameter -MCU_DIR = hw/mcu/nxp/lpc_driver/lpc43xx/lpc_chip_43xx +MCU_DIR = hw/mcu/nxp/lpcopen/lpc43xx/lpc_chip_43xx # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/ngx4330.ld -# TODO remove later -SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c - SRC_C += \ $(MCU_DIR)/../gcc/cr_startup_lpc43xx.c \ $(MCU_DIR)/src/chip_18xx_43xx.c \ @@ -32,7 +30,7 @@ INC += \ # For TinyUSB port source VENDOR = nxp -CHIP_FAMILY = lpc18_43 +CHIP_FAMILY = transdimension # For freeRTOS port source FREERTOS_PORT = ARM_CM4 diff --git a/hw/bsp/ngx4330/ngx4330.c b/hw/bsp/ngx4330/ngx4330.c index 669180026..e1bafff8d 100644 --- a/hw/bsp/ngx4330/ngx4330.c +++ b/hw/bsp/ngx4330/ngx4330.c @@ -164,19 +164,19 @@ void board_init(void) #if CFG_TUSB_RHPORT0_MODE Chip_USB0_Init(); - // Reset controller - LPC_USB0->USBCMD_D |= 0x02; - while( LPC_USB0->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - - LPC_USB0->PORTSC1_D |= (1<<24); // FIXME force full speed for debugging - #else // TODO OTG - LPC_USB0->USBMODE_D = USBMODE_DEVICE; - LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; - #endif +// // Reset controller +// LPC_USB0->USBCMD_D |= 0x02; +// while( LPC_USB0->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST +// LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// +// LPC_USB0->PORTSC1_D |= (1<<24); // FIXME force full speed for debugging +// #else // TODO OTG +// LPC_USB0->USBMODE_D = USBMODE_DEVICE; +// LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; +// #endif #endif /* USB1 @@ -200,25 +200,50 @@ void board_init(void) #if CFG_TUSB_RHPORT1_MODE Chip_USB1_Init(); - // Reset controller - LPC_USB1->USBCMD_D |= 0x02; - while( LPC_USB1->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST - LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - #else // TODO OTG - LPC_USB1->USBMODE_D = USBMODE_DEVICE; - #endif - - // USB1 as fullspeed - LPC_USB1->PORTSC1_D |= (1<<24); +// // Reset controller +// LPC_USB1->USBCMD_D |= 0x02; +// while( LPC_USB1->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST +// LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// #else // TODO OTG +// LPC_USB1->USBMODE_D = USBMODE_DEVICE; +// #endif +// +// // USB1 as fullspeed +// LPC_USB1->PORTSC1_D |= (1<<24); // Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 5, 6); /* GPIO5[6] = USB1_PWR_EN */ // Chip_GPIO_SetPinState(LPC_GPIO_PORT, 5, 6, true); /* GPIO5[6] output high */ #endif } +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB0_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + +void USB1_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST + tuh_isr(1); + #endif + + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE + tud_isr(1); + #endif +} + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/nrf52840_mdk_dongle/board.mk b/hw/bsp/nrf52840_mdk_dongle/board.mk new file mode 100644 index 000000000..b92556002 --- /dev/null +++ b/hw/bsp/nrf52840_mdk_dongle/board.mk @@ -0,0 +1,62 @@ +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -DNRF52840_XXAA \ + -DCFG_TUSB_MCU=OPT_MCU_NRF5X + +# nrfx issue undef _ARMCC_VERSION usage https://github.com/NordicSemiconductor/nrfx/issues/49 +CFLAGS += -Wno-error=undef -Wno-error=unused-parameter + +# due to tusb_hal_nrf_power_event +GCCVERSION = $(firstword $(subst ., ,$(shell arm-none-eabi-gcc -dumpversion))) +ifeq ($(shell expr $(GCCVERSION) \>= 8), 1) +CFLAGS += -Wno-error=cast-function-type +endif + +# All source paths should be relative to the top level. +LD_FILE = hw/bsp/$(BOARD)/$(BOARD).ld + +LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk + +SRC_C += \ + hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \ + hw/mcu/nordic/nrfx/mdk/system_nrf52840.c \ + +INC += \ + $(TOP)/hw/mcu/nordic/cmsis/Include \ + $(TOP)/hw/mcu/nordic \ + $(TOP)/hw/mcu/nordic/nrfx \ + $(TOP)/hw/mcu/nordic/nrfx/mdk \ + $(TOP)/hw/mcu/nordic/nrfx/hal \ + $(TOP)/hw/mcu/nordic/nrfx/drivers/include \ + $(TOP)/hw/mcu/nordic/nrfx/drivers/src \ + +SRC_S += hw/mcu/nordic/nrfx/mdk/gcc_startup_nrf52840.S + +ASFLAGS += -D__HEAP_SIZE=0 + +# For TinyUSB port source +VENDOR = nordic +CHIP_FAMILY = nrf5x + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM4F + +# For flash-jlink target +JLINK_DEVICE = nRF52840_xxAA +JLINK_IF = swd + +# flash using Nordic nrfutil (pip2 install nrfutil) +# make BOARD=nrf52840_mdk_dongle SERIAL=/dev/ttyACM0 all flash +NRFUTIL = nrfutil + +$(BUILD)/$(BOARD)-firmware.zip: $(BUILD)/$(BOARD)-firmware.hex + $(NRFUTIL) pkg generate --hw-version 52 --sd-req 0x0000 --debug-mode --application $^ $@ + +flash: $(BUILD)/$(BOARD)-firmware.zip + @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) + $(NRFUTIL) dfu usb-serial --package $^ -p $(SERIAL) -b 115200 diff --git a/hw/bsp/nrf52840_mdk_dongle/nrf52840_mdk_dongle.c b/hw/bsp/nrf52840_mdk_dongle/nrf52840_mdk_dongle.c new file mode 100644 index 000000000..86f02d3e7 --- /dev/null +++ b/hw/bsp/nrf52840_mdk_dongle/nrf52840_mdk_dongle.c @@ -0,0 +1,190 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + +#include "bsp/board.h" + +#include "nrfx.h" +#include "nrfx/hal/nrf_gpio.h" +#include "nrfx/drivers/include/nrfx_power.h" + +#ifdef SOFTDEVICE_PRESENT +#include "nrf_sdm.h" +#include "nrf_soc.h" +#endif + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ +#define LED_PIN 23 +#define LED_STATE_ON 0 + +// Button 1 +#define BUTTON_PIN 18 +#define BUTTON_STATE_ACTIVE 0 + +// tinyusb function that handles power event (detected, ready, removed) +// We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. +extern void tusb_hal_nrf_power_event(uint32_t event); + +void board_init(void) +{ + // Config clock source: XTAL or RC in sdk_config.h + NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); + NRF_CLOCK->TASKS_LFCLKSTART = 1UL; + + // LED + nrf_gpio_cfg_output(LED_PIN); + board_led_write(false); + + // Button + nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock/1000); +#endif + +#if TUSB_OPT_DEVICE_ENABLED + // Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice + // 2 is highest for application + NVIC_SetPriority(USBD_IRQn, 2); + + // USB power may already be ready at this time -> no event generated + // We need to invoke the handler based on the status initially + uint32_t usb_reg; + +#ifdef SOFTDEVICE_PRESENT + uint8_t sd_en = false; + sd_softdevice_is_enabled(&sd_en); + + if ( sd_en ) { + sd_power_usbdetected_enable(true); + sd_power_usbpwrrdy_enable(true); + sd_power_usbremoved_enable(true); + + sd_power_usbregstatus_get(&usb_reg); + }else +#endif + { + // Power module init + const nrfx_power_config_t pwr_cfg = { 0 }; + nrfx_power_init(&pwr_cfg); + + // Register tusb function as USB power handler + const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event }; + nrfx_power_usbevt_init(&config); + + nrfx_power_usbevt_enable(); + + usb_reg = NRF_POWER->USBREGSTATUS; + } + + if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED); + if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY); +#endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + nrf_gpio_pin_write(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == nrf_gpio_pin_read(BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +#ifdef SOFTDEVICE_PRESENT +// process SOC event from SD +uint32_t proc_soc(void) +{ + uint32_t soc_evt; + uint32_t err = sd_evt_get(&soc_evt); + + if (NRF_SUCCESS == err) + { + /*------------- usb power event handler -------------*/ + int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED: + (soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY : + (soc_evt == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1; + + if ( usbevt >= 0) tusb_hal_nrf_power_event(usbevt); + } + + return err; +} + +uint32_t proc_ble(void) +{ + // do nothing with ble + return NRF_ERROR_NOT_FOUND; +} + +void SD_EVT_IRQHandler(void) +{ + // process BLE and SOC until there is no more events + while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) ) + { + + } +} + +void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info) +{ + (void) id; + (void) pc; + (void) info; +} +#endif diff --git a/hw/bsp/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld b/hw/bsp/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld new file mode 100644 index 000000000..78eddc9c3 --- /dev/null +++ b/hw/bsp/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld @@ -0,0 +1,13 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0xE0000-0x1000 + RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 0x3fff8 +} + + +INCLUDE "nrf_common.ld" diff --git a/hw/bsp/pca10056/board.mk b/hw/bsp/pca10056/board.mk index abe0d642c..b4031844e 100644 --- a/hw/bsp/pca10056/board.mk +++ b/hw/bsp/pca10056/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ diff --git a/hw/bsp/pca10056/pca10056.c b/hw/bsp/pca10056/pca10056.c index 31fd5e9be..b9cc9fc36 100644 --- a/hw/bsp/pca10056/pca10056.c +++ b/hw/bsp/pca10056/pca10056.c @@ -84,10 +84,12 @@ void board_init(void) .pselcts = NRF_UARTE_PSEL_DISCONNECTED, .pselrts = NRF_UARTE_PSEL_DISCONNECTED, .p_context = NULL, - .hwfc = NRF_UARTE_HWFC_DISABLED, - .parity = NRF_UARTE_PARITY_EXCLUDED, .baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE - .interrupt_priority = 7 + .interrupt_priority = 7, + .hal_cfg = { + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED, + } }; nrfx_uarte_init(&_uart_id, &uart_cfg, NULL); //uart_handler); diff --git a/hw/bsp/pca10059/board.mk b/hw/bsp/pca10059/board.mk index 15801054c..19ec3eaea 100644 --- a/hw/bsp/pca10059/board.mk +++ b/hw/bsp/pca10059/board.mk @@ -1,4 +1,5 @@ CFLAGS += \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ diff --git a/hw/bsp/pca10100/board.mk b/hw/bsp/pca10100/board.mk new file mode 100644 index 000000000..d7ac7ec4f --- /dev/null +++ b/hw/bsp/pca10100/board.mk @@ -0,0 +1,56 @@ +CFLAGS += \ + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -DNRF52833_XXAA \ + -DCONFIG_GPIO_AS_PINRESET \ + -DCFG_TUSB_MCU=OPT_MCU_NRF5X + +# nrfx issue undef _ARMCC_VERSION usage https://github.com/NordicSemiconductor/nrfx/issues/49 +CFLAGS += -Wno-error=undef -Wno-error=unused-parameter + +# due to tusb_hal_nrf_power_event +GCCVERSION = $(firstword $(subst ., ,$(shell arm-none-eabi-gcc -dumpversion))) +ifeq ($(shell expr $(GCCVERSION) \>= 8), 1) +CFLAGS += -Wno-error=cast-function-type +endif + +# All source paths should be relative to the top level. +LD_FILE = hw/mcu/nordic/nrfx/mdk/nrf52833_xxaa.ld + +LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk + +SRC_C += \ + hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \ + hw/mcu/nordic/nrfx/drivers/src/nrfx_uarte.c \ + hw/mcu/nordic/nrfx/mdk/system_nrf52833.c \ + +INC += \ + $(TOP)/hw/mcu/nordic/cmsis/Include \ + $(TOP)/hw/mcu/nordic \ + $(TOP)/hw/mcu/nordic/nrfx \ + $(TOP)/hw/mcu/nordic/nrfx/mdk \ + $(TOP)/hw/mcu/nordic/nrfx/hal \ + $(TOP)/hw/mcu/nordic/nrfx/drivers/include \ + $(TOP)/hw/mcu/nordic/nrfx/drivers/src \ + +SRC_S += hw/mcu/nordic/nrfx/mdk/gcc_startup_nrf52833.S + +ASFLAGS += -D__HEAP_SIZE=0 + +# For TinyUSB port source +VENDOR = nordic +CHIP_FAMILY = nrf5x + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM4F + +# For flash-jlink target +JLINK_DEVICE = nRF52833_XXAA +JLINK_IF = swd + +# flash using jlink +flash: flash-jlink diff --git a/hw/bsp/pca10100/pca10100.c b/hw/bsp/pca10100/pca10100.c new file mode 100644 index 000000000..b9cc9fc36 --- /dev/null +++ b/hw/bsp/pca10100/pca10100.c @@ -0,0 +1,223 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + +#include "bsp/board.h" + +#include "nrfx.h" +#include "nrfx/hal/nrf_gpio.h" +#include "nrfx/drivers/include/nrfx_power.h" +#include "nrfx/drivers/include/nrfx_uarte.h" + +#ifdef SOFTDEVICE_PRESENT +#include "nrf_sdm.h" +#include "nrf_soc.h" +#endif + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ +#define LED_PIN 13 +#define LED_STATE_ON 0 + +#define BUTTON_PIN 11 +#define BUTTON_STATE_ACTIVE 0 + +#define UART_RX_PIN 8 +#define UART_TX_PIN 6 + +static nrfx_uarte_t _uart_id = NRFX_UARTE_INSTANCE(0); +//static void uart_handler(nrfx_uart_event_t const * p_event, void* p_context); + +// tinyusb function that handles power event (detected, ready, removed) +// We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. +extern void tusb_hal_nrf_power_event(uint32_t event); + +void board_init(void) +{ + // stop LF clock just in case we jump from application without reset + NRF_CLOCK->TASKS_LFCLKSTOP = 1UL; + + // Use Internal OSC to compatible with all boards + NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_RC; + NRF_CLOCK->TASKS_LFCLKSTART = 1UL; + + // LED + nrf_gpio_cfg_output(LED_PIN); + board_led_write(false); + + // Button + nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock/1000); +#endif + + // UART + nrfx_uarte_config_t uart_cfg = + { + .pseltxd = UART_TX_PIN, + .pselrxd = UART_RX_PIN, + .pselcts = NRF_UARTE_PSEL_DISCONNECTED, + .pselrts = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = NULL, + .baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE + .interrupt_priority = 7, + .hal_cfg = { + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED, + } + }; + + nrfx_uarte_init(&_uart_id, &uart_cfg, NULL); //uart_handler); + +#if TUSB_OPT_DEVICE_ENABLED + // Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice + // 2 is highest for application + NVIC_SetPriority(USBD_IRQn, 2); + + // USB power may already be ready at this time -> no event generated + // We need to invoke the handler based on the status initially + uint32_t usb_reg; + +#ifdef SOFTDEVICE_PRESENT + uint8_t sd_en = false; + sd_softdevice_is_enabled(&sd_en); + + if ( sd_en ) { + sd_power_usbdetected_enable(true); + sd_power_usbpwrrdy_enable(true); + sd_power_usbremoved_enable(true); + + sd_power_usbregstatus_get(&usb_reg); + }else +#endif + { + // Power module init + const nrfx_power_config_t pwr_cfg = { 0 }; + nrfx_power_init(&pwr_cfg); + + // Register tusb function as USB power handler + // cause cast-function-type warning + const nrfx_power_usbevt_config_t config = { .handler = ((nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event) }; + nrfx_power_usbevt_init(&config); + + nrfx_power_usbevt_enable(); + + usb_reg = NRF_POWER->USBREGSTATUS; + } + + if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED); + if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY); +#endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + nrf_gpio_pin_write(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == nrf_gpio_pin_read(BUTTON_PIN); +} + +//static void uart_handler(nrfx_uart_event_t const * p_event, void* p_context) +//{ +// +//} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +// return NRFX_SUCCESS == nrfx_uart_rx(&_uart_id, buf, (size_t) len) ? len : 0; +} + +int board_uart_write(void const * buf, int len) +{ + return (NRFX_SUCCESS == nrfx_uarte_tx(&_uart_id, (uint8_t const*) buf, (size_t) len)) ? len : 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +#ifdef SOFTDEVICE_PRESENT +// process SOC event from SD +uint32_t proc_soc(void) +{ + uint32_t soc_evt; + uint32_t err = sd_evt_get(&soc_evt); + + if (NRF_SUCCESS == err) + { + /*------------- usb power event handler -------------*/ + int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED: + (soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY : + (soc_evt == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1; + + if ( usbevt >= 0) tusb_hal_nrf_power_event(usbevt); + } + + return err; +} + +uint32_t proc_ble(void) +{ + // do nothing with ble + return NRF_ERROR_NOT_FOUND; +} + +void SD_EVT_IRQHandler(void) +{ + // process BLE and SOC until there is no more events + while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) ) + { + + } +} + +void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info) +{ + (void) id; + (void) pc; + (void) info; +} +#endif diff --git a/hw/bsp/pyboardv11/board.mk b/hw/bsp/pyboardv11/board.mk index ef9777976..0118b54a4 100644 --- a/hw/bsp/pyboardv11/board.mk +++ b/hw/bsp/pyboardv11/board.mk @@ -1,12 +1,13 @@ CFLAGS += \ - -DHSE_VALUE=12000000 \ - -DSTM32F405xx \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ -nostdlib -nostartfiles \ + -DSTM32F405xx \ + -DHSE_VALUE=12000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32F4 ST_HAL_DRIVER = hw/mcu/st/st_driver/STM32F4xx_HAL_Driver diff --git a/hw/bsp/spresense/board.mk b/hw/bsp/spresense/board.mk index 16421686a..2e88cf994 100644 --- a/hw/bsp/spresense/board.mk +++ b/hw/bsp/spresense/board.mk @@ -1,12 +1,3 @@ -SPRESENSE_SDK = $(TOP)/hw/mcu/sony/cxd56/spresense-exported-sdk - -INC += \ - $(SPRESENSE_SDK)/nuttx/include \ - $(SPRESENSE_SDK)/nuttx/arch \ - $(SPRESENSE_SDK)/nuttx/arch/chip \ - $(SPRESENSE_SDK)/sdk/bsp/include \ - $(SPRESENSE_SDK)/sdk/bsp/include/sdk \ - CFLAGS += \ -DCONFIG_WCHAR_BUILTIN \ -DCONFIG_HAVE_DOUBLE \ @@ -23,6 +14,15 @@ CFLAGS += \ -fomit-frame-pointer \ -DCFG_TUSB_MCU=OPT_MCU_CXD56 \ +SPRESENSE_SDK = $(TOP)/hw/mcu/sony/cxd56/spresense-exported-sdk + +INC += \ + $(SPRESENSE_SDK)/nuttx/include \ + $(SPRESENSE_SDK)/nuttx/arch \ + $(SPRESENSE_SDK)/nuttx/arch/chip \ + $(SPRESENSE_SDK)/sdk/bsp/include \ + $(SPRESENSE_SDK)/sdk/bsp/include/sdk \ + LIBS += \ $(SPRESENSE_SDK)/sdk/libs/libapps.a \ $(SPRESENSE_SDK)/sdk/libs/libsdk.a \ diff --git a/hw/bsp/stm32f070rbnucleo/board.mk b/hw/bsp/stm32f070rbnucleo/board.mk index f930f6a85..6e52b8141 100644 --- a/hw/bsp/stm32f070rbnucleo/board.mk +++ b/hw/bsp/stm32f070rbnucleo/board.mk @@ -1,13 +1,14 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32F070xB \ - -mthumb \ - -mabi=aapcs-linux \ - -mcpu=cortex-m0 \ - -mfloat-abi=soft \ - -nostdlib -nostartfiles \ - -DCFG_EXAMPLE_MSC_READONLY \ - -DCFG_TUSB_MCU=OPT_MCU_STM32F0 + -flto \ + -mthumb \ + -mabi=aapcs-linux \ + -mcpu=cortex-m0 \ + -mfloat-abi=soft \ + -nostdlib -nostartfiles \ + -DHSE_VALUE=8000000 \ + -DSTM32F070xB \ + -DCFG_EXAMPLE_MSC_READONLY \ + -DCFG_TUSB_MCU=OPT_MCU_STM32F0 # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter @@ -19,21 +20,21 @@ ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32F0xx LD_FILE = hw/bsp/$(BOARD)/stm32F070rbtx_flash.ld SRC_C += \ - $(ST_CMSIS)/Source/Templates/system_stm32f0xx.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_cortex.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_rcc.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_rcc_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_gpio.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_uart.c + $(ST_CMSIS)/Source/Templates/system_stm32f0xx.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_uart.c SRC_S += \ - $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f070xb.s + $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f070xb.s INC += \ - $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ - $(TOP)/$(ST_CMSIS)/Include \ - $(TOP)/$(ST_HAL_DRIVER)/Inc \ - $(TOP)/hw/bsp/$(BOARD) + $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc \ + $(TOP)/hw/bsp/$(BOARD) # For TinyUSB port source VENDOR = st diff --git a/hw/bsp/stm32f072disco/board.mk b/hw/bsp/stm32f072disco/board.mk index 39715e83f..5ed87cfa8 100644 --- a/hw/bsp/stm32f072disco/board.mk +++ b/hw/bsp/stm32f072disco/board.mk @@ -1,13 +1,14 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32F072xB \ - -mthumb \ - -mabi=aapcs \ - -mcpu=cortex-m0 \ - -mfloat-abi=soft \ - -nostdlib -nostartfiles \ - -DCFG_EXAMPLE_MSC_READONLY \ - -DCFG_TUSB_MCU=OPT_MCU_STM32F0 + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m0 \ + -mfloat-abi=soft \ + -nostdlib -nostartfiles \ + -DSTM32F072xB \ + -DHSE_VALUE=8000000 \ + -DCFG_EXAMPLE_MSC_READONLY \ + -DCFG_TUSB_MCU=OPT_MCU_STM32F0 # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter @@ -19,22 +20,22 @@ ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32F0xx LD_FILE = hw/bsp/$(BOARD)/STM32F072RBTx_FLASH.ld SRC_C += \ - $(ST_CMSIS)/Source/Templates/system_stm32f0xx.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_cortex.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_rcc.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_rcc_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_gpio.c \ - $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_uart.c + $(ST_CMSIS)/Source/Templates/system_stm32f0xx.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32f0xx_hal_uart.c SRC_S += \ - $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f072xb.s + $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f072xb.s INC += \ - $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ - $(TOP)/$(ST_CMSIS)/Include \ - $(TOP)/$(ST_HAL_DRIVER)/Inc \ - $(TOP)/hw/bsp/$(BOARD) + $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc \ + $(TOP)/hw/bsp/$(BOARD) # For TinyUSB port source VENDOR = st diff --git a/hw/bsp/stm32f072disco/stm32f072disco.c b/hw/bsp/stm32f072disco/stm32f072disco.c index aac1c5534..e26c5628a 100644 --- a/hw/bsp/stm32f072disco/stm32f072disco.c +++ b/hw/bsp/stm32f072disco/stm32f072disco.c @@ -43,9 +43,9 @@ #define UART_TX_PIN GPIO_PIN_9 #define UART_RX_PIN GPIO_PIN_10 - UART_HandleTypeDef UartHandle; + // enable all LED, Button, Uart, USB clock static void all_rcc_clk_enable(void) { diff --git a/hw/bsp/stm32f103bluepill/board.mk b/hw/bsp/stm32f103bluepill/board.mk index 26ad07b74..f464fa298 100644 --- a/hw/bsp/stm32f103bluepill/board.mk +++ b/hw/bsp/stm32f103bluepill/board.mk @@ -1,12 +1,13 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32F103xB \ - -mthumb \ - -mabi=aapcs \ - -mcpu=cortex-m3 \ - -mfloat-abi=soft \ - -nostdlib -nostartfiles \ - -DCFG_TUSB_MCU=OPT_MCU_STM32F1 + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m3 \ + -mfloat-abi=soft \ + -nostdlib -nostartfiles \ + -DSTM32F103xB \ + -DHSE_VALUE=8000000 \ + -DCFG_TUSB_MCU=OPT_MCU_STM32F1 # mcu driver cause following warnings #CFLAGS += -Wno-error=unused-parameter @@ -18,21 +19,21 @@ ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32F1xx LD_FILE = hw/bsp/$(BOARD)/STM32F103XB_FLASH.ld SRC_C += \ - $(ST_CMSIS)/Source/Templates/system_stm32f1xx.c \ - $(ST_HAL_DRIVER)/Src/stm32f1xx_hal.c \ - $(ST_HAL_DRIVER)/Src/stm32f1xx_hal_cortex.c \ - $(ST_HAL_DRIVER)/Src/stm32f1xx_hal_rcc.c \ - $(ST_HAL_DRIVER)/Src/stm32f1xx_hal_rcc_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32f1xx_hal_gpio.c + $(ST_CMSIS)/Source/Templates/system_stm32f1xx.c \ + $(ST_HAL_DRIVER)/Src/stm32f1xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32f1xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32f1xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32f1xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32f1xx_hal_gpio.c SRC_S += \ - $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f103xb.s + $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f103xb.s INC += \ - $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ - $(TOP)/$(ST_CMSIS)/Include \ - $(TOP)/$(ST_HAL_DRIVER)/Inc \ - $(TOP)/hw/bsp/$(BOARD) + $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc \ + $(TOP)/hw/bsp/$(BOARD) # For TinyUSB port source VENDOR = st diff --git a/hw/bsp/stm32f207nucleo/board.mk b/hw/bsp/stm32f207nucleo/board.mk index cd2b26204..003a3dd41 100644 --- a/hw/bsp/stm32f207nucleo/board.mk +++ b/hw/bsp/stm32f207nucleo/board.mk @@ -1,12 +1,13 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32F207xx \ - -mthumb \ - -mabi=aapcs \ - -mcpu=cortex-m3 \ - -mfloat-abi=soft \ - -nostdlib -nostartfiles \ - -DCFG_TUSB_MCU=OPT_MCU_STM32F2 + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m3 \ + -mfloat-abi=soft \ + -nostdlib -nostartfiles \ + -DSTM32F207xx \ + -DHSE_VALUE=8000000 \ + -DCFG_TUSB_MCU=OPT_MCU_STM32F2 # mcu driver cause following warnings CFLAGS += -Wno-error=sign-compare @@ -18,21 +19,21 @@ ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32F2xx LD_FILE = hw/bsp/$(BOARD)/STM32F207ZGTx_FLASH.ld SRC_C += \ - $(ST_CMSIS)/Source/Templates/system_stm32f2xx.c \ - $(ST_HAL_DRIVER)/Src/stm32f2xx_hal.c \ - $(ST_HAL_DRIVER)/Src/stm32f2xx_hal_cortex.c \ - $(ST_HAL_DRIVER)/Src/stm32f2xx_hal_rcc.c \ - $(ST_HAL_DRIVER)/Src/stm32f2xx_hal_rcc_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32f2xx_hal_gpio.c + $(ST_CMSIS)/Source/Templates/system_stm32f2xx.c \ + $(ST_HAL_DRIVER)/Src/stm32f2xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32f2xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32f2xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32f2xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32f2xx_hal_gpio.c SRC_S += \ - $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f207xx.s + $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f207xx.s INC += \ - $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ - $(TOP)/$(ST_CMSIS)/Include \ - $(TOP)/$(ST_HAL_DRIVER)/Inc \ - $(TOP)/hw/bsp/$(BOARD) + $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc \ + $(TOP)/hw/bsp/$(BOARD) # For TinyUSB port source VENDOR = st diff --git a/hw/bsp/stm32f303disco/board.mk b/hw/bsp/stm32f303disco/board.mk index ab77c55c4..fbe034144 100644 --- a/hw/bsp/stm32f303disco/board.mk +++ b/hw/bsp/stm32f303disco/board.mk @@ -1,13 +1,14 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32F303xC \ - -mthumb \ - -mabi=aapcs \ - -mcpu=cortex-m4 \ - -mfloat-abi=hard \ - -mfpu=fpv4-sp-d16 \ - -nostdlib -nostartfiles \ - -DCFG_TUSB_MCU=OPT_MCU_STM32F3 + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -nostdlib -nostartfiles \ + -DSTM32F303xC \ + -DHSE_VALUE=8000000 \ + -DCFG_TUSB_MCU=OPT_MCU_STM32F3 # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter @@ -19,21 +20,21 @@ ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32F3xx LD_FILE = hw/bsp/$(BOARD)/STM32F303VCTx_FLASH.ld SRC_C += \ - $(ST_CMSIS)/Source/Templates/system_stm32f3xx.c \ - $(ST_HAL_DRIVER)/Src/stm32f3xx_hal.c \ - $(ST_HAL_DRIVER)/Src/stm32f3xx_hal_cortex.c \ - $(ST_HAL_DRIVER)/Src/stm32f3xx_hal_rcc.c \ - $(ST_HAL_DRIVER)/Src/stm32f3xx_hal_rcc_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32f3xx_hal_gpio.c + $(ST_CMSIS)/Source/Templates/system_stm32f3xx.c \ + $(ST_HAL_DRIVER)/Src/stm32f3xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32f3xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32f3xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32f3xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32f3xx_hal_gpio.c SRC_S += \ - $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f303xc.s + $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f303xc.s INC += \ - $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ - $(TOP)/$(ST_CMSIS)/Include \ - $(TOP)/$(ST_HAL_DRIVER)/Inc \ - $(TOP)/hw/bsp/$(BOARD) + $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc \ + $(TOP)/hw/bsp/$(BOARD) # For TinyUSB port source VENDOR = st diff --git a/hw/bsp/stm32f407disco/board.mk b/hw/bsp/stm32f407disco/board.mk index 4f4c10091..216b51bf9 100644 --- a/hw/bsp/stm32f407disco/board.mk +++ b/hw/bsp/stm32f407disco/board.mk @@ -1,12 +1,13 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32F407xx \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ -nostdlib -nostartfiles \ + -DSTM32F407xx \ + -DHSE_VALUE=8000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32F4 ST_HAL_DRIVER = hw/mcu/st/st_driver/STM32F4xx_HAL_Driver diff --git a/hw/bsp/stm32f411disco/board.mk b/hw/bsp/stm32f411disco/board.mk index dcfee33cf..63aa76154 100644 --- a/hw/bsp/stm32f411disco/board.mk +++ b/hw/bsp/stm32f411disco/board.mk @@ -1,12 +1,13 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32F411xE \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ -nostdlib -nostartfiles \ + -DSTM32F411xE \ + -DHSE_VALUE=8000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32F4 ST_HAL_DRIVER = hw/mcu/st/st_driver/STM32F4xx_HAL_Driver diff --git a/hw/bsp/stm32f412disco/board.mk b/hw/bsp/stm32f412disco/board.mk index e059c81d1..ddb8402ec 100644 --- a/hw/bsp/stm32f412disco/board.mk +++ b/hw/bsp/stm32f412disco/board.mk @@ -1,12 +1,13 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32F412Zx \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ -nostdlib -nostartfiles \ + -DSTM32F412Zx \ + -DHSE_VALUE=8000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32F4 # mcu driver cause following warnings diff --git a/hw/bsp/stm32f767nucleo/board.mk b/hw/bsp/stm32f767nucleo/board.mk index 46023334c..5d9645379 100644 --- a/hw/bsp/stm32f767nucleo/board.mk +++ b/hw/bsp/stm32f767nucleo/board.mk @@ -1,12 +1,13 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32F767xx \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m7 \ -mfloat-abi=hard \ -mfpu=fpv5-d16 \ -nostdlib -nostartfiles \ + -DSTM32F767xx \ + -DHSE_VALUE=8000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32F7 # mcu driver cause following warnings diff --git a/hw/bsp/stm32h743nucleo/board.mk b/hw/bsp/stm32h743nucleo/board.mk index 40b36413f..cfea7f57b 100644 --- a/hw/bsp/stm32h743nucleo/board.mk +++ b/hw/bsp/stm32h743nucleo/board.mk @@ -1,12 +1,13 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32H743xx \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m7 \ -mfloat-abi=hard \ -mfpu=fpv5-d16 \ -nostdlib -nostartfiles \ + -DSTM32H743xx \ + -DHSE_VALUE=8000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32H7 # mcu driver cause following warnings diff --git a/hw/bsp/stm32l0538disco/board.mk b/hw/bsp/stm32l0538disco/board.mk index 7e11fa6cd..d81b2d887 100644 --- a/hw/bsp/stm32l0538disco/board.mk +++ b/hw/bsp/stm32l0538disco/board.mk @@ -1,13 +1,14 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32L053xx \ - -mthumb \ - -mabi=aapcs \ - -mcpu=cortex-m0plus \ - -mfloat-abi=soft \ - -nostdlib -nostartfiles \ - -DCFG_EXAMPLE_MSC_READONLY \ - -DCFG_TUSB_MCU=OPT_MCU_STM32L0 + -flto \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m0plus \ + -mfloat-abi=soft \ + -nostdlib -nostartfiles \ + -DSTM32L053xx \ + -DHSE_VALUE=8000000 \ + -DCFG_EXAMPLE_MSC_READONLY \ + -DCFG_TUSB_MCU=OPT_MCU_STM32L0 # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=maybe-uninitialized @@ -19,21 +20,21 @@ ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32L0xx LD_FILE = hw/bsp/$(BOARD)/STM32L053C8Tx_FLASH.ld SRC_C += \ - $(ST_CMSIS)/Source/Templates/system_stm32l0xx.c \ - $(ST_HAL_DRIVER)/Src/stm32l0xx_hal.c \ - $(ST_HAL_DRIVER)/Src/stm32l0xx_hal_cortex.c \ - $(ST_HAL_DRIVER)/Src/stm32l0xx_hal_rcc.c \ - $(ST_HAL_DRIVER)/Src/stm32l0xx_hal_rcc_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32l0xx_hal_gpio.c + $(ST_CMSIS)/Source/Templates/system_stm32l0xx.c \ + $(ST_HAL_DRIVER)/Src/stm32l0xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32l0xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32l0xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32l0xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32l0xx_hal_gpio.c SRC_S += \ - $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l053xx.s + $(ST_CMSIS)/Source/Templates/gcc/startup_stm32l053xx.s INC += \ - $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ - $(TOP)/$(ST_CMSIS)/Include \ - $(TOP)/$(ST_HAL_DRIVER)/Inc \ - $(TOP)/hw/bsp/$(BOARD) + $(TOP)/hw/mcu/st/st_driver/CMSIS/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc \ + $(TOP)/hw/bsp/$(BOARD) # For TinyUSB port source VENDOR = st diff --git a/hw/bsp/stm32l476disco/board.mk b/hw/bsp/stm32l476disco/board.mk index c987fea64..3432ac2e5 100644 --- a/hw/bsp/stm32l476disco/board.mk +++ b/hw/bsp/stm32l476disco/board.mk @@ -1,12 +1,13 @@ CFLAGS += \ - -DHSE_VALUE=8000000 \ - -DSTM32L476xx \ + -flto \ -mthumb \ -mabi=aapcs \ -mcpu=cortex-m4 \ -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ -nostdlib -nostartfiles \ + -DSTM32L476xx \ + -DHSE_VALUE=8000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32L4 ST_HAL_DRIVER = hw/mcu/st/st_driver/STM32L4xx_HAL_Driver diff --git a/hw/mcu/nordic/nrfx b/hw/mcu/nordic/nrfx index 9d68726e4..7a4c9d946 160000 --- a/hw/mcu/nordic/nrfx +++ b/hw/mcu/nordic/nrfx @@ -1 +1 @@ -Subproject commit 9d68726e41c321f1772c187bd12d82f5b13104f1 +Subproject commit 7a4c9d946cf1801771fc180acdbf7b878f270093 diff --git a/hw/mcu/nordic/nrfx_config.h b/hw/mcu/nordic/nrfx_config.h index 8f9aeffe5..6a974ba70 100644 --- a/hw/mcu/nordic/nrfx_config.h +++ b/hw/mcu/nordic/nrfx_config.h @@ -1,10 +1,18 @@ #ifndef NRFX_CONFIG_H__ #define NRFX_CONFIG_H__ -#define NRFX_POWER_ENABLED 1 -#define NRFX_POWER_CONFIG_IRQ_PRIORITY 7 +#define NRFX_POWER_ENABLED 1 +#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY 7 + +#define NRFX_CLOCK_ENABLED 0 #define NRFX_UARTE_ENABLED 1 #define NRFX_UARTE0_ENABLED 1 +#define NRFX_UARTE1_ENABLED 0 +#define NRFX_UARTE2_ENABLED 0 +#define NRFX_UARTE3_ENABLED 0 + +#define NRFX_PRS_ENABLED 0 + #endif // NRFX_CONFIG_H__ diff --git a/hw/mcu/nxp b/hw/mcu/nxp new file mode 160000 index 000000000..b618cb1d5 --- /dev/null +++ b/hw/mcu/nxp @@ -0,0 +1 @@ +Subproject commit b618cb1d521cc9e133bdcd0fca154dee2d925dfe diff --git a/hw/mcu/nxp/lpc_driver b/hw/mcu/nxp/lpc_driver deleted file mode 160000 index fa206508e..000000000 --- a/hw/mcu/nxp/lpc_driver +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fa206508e9ea289ceeb9c35442dd8002002f9316 diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index a77282ed5..cec76b110 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -533,7 +533,18 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } break; - case MSC_STAGE_STATUS: break; // processed immediately after this switch + case MSC_STAGE_STATUS: + // Wait for the command status wrapper complete event + if( (ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t)) ) + { + // Move to default CMD stage + p_msc->stage = MSC_STAGE_CMD; + + // Queue for the next CBW + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) ); + } + break; + default : break; } @@ -543,32 +554,30 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t if ( usbd_edpt_stalled(rhport, p_msc->ep_in) || usbd_edpt_stalled(rhport, p_msc->ep_out) ) { // simulate an transfer complete with adjusted parameters --> this driver callback will fired again + // and response with status phase after halted endpoints are cleared. + // note: use ep_out to prevent confusing with STATUS complete dcd_event_xfer_complete(rhport, p_msc->ep_out, 0, XFER_RESULT_SUCCESS, false); } else { - // Move to default CMD stage when sending status - p_msc->stage = MSC_STAGE_CMD; - // Send SCSI Status - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in , (uint8_t*) &p_msc->csw, sizeof(msc_csw_t)) ); + TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_in , (uint8_t*) &p_msc->csw, sizeof(msc_csw_t))); // Invoke complete callback if defined - if ( SCSI_CMD_READ_10 == p_cbw->command[0]) + switch(p_cbw->command[0]) { - if ( tud_msc_read10_complete_cb ) tud_msc_read10_complete_cb(p_cbw->lun); - } - else if ( SCSI_CMD_WRITE_10 == p_cbw->command[0] ) - { - if ( tud_msc_write10_complete_cb ) tud_msc_write10_complete_cb(p_cbw->lun); - } - else - { - if ( tud_msc_scsi_complete_cb ) tud_msc_scsi_complete_cb(p_cbw->lun, p_cbw->command); - } + case SCSI_CMD_READ_10: + if ( tud_msc_read10_complete_cb ) tud_msc_read10_complete_cb(p_cbw->lun); + break; - // Queue for the next CBW - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) ); + case SCSI_CMD_WRITE_10: + if ( tud_msc_write10_complete_cb ) tud_msc_write10_complete_cb(p_cbw->lun); + break; + + default: + if ( tud_msc_scsi_complete_cb ) tud_msc_scsi_complete_cb(p_cbw->lun, p_cbw->command); + break; + } } } @@ -583,7 +592,11 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) msc_cbw_t const * p_cbw = &p_msc->cbw; msc_csw_t * p_csw = &p_msc->csw; - uint16_t const block_sz = p_cbw->total_bytes / rdwr10_get_blockcount(p_cbw->command); + uint16_t const block_cnt = rdwr10_get_blockcount(p_cbw->command); + TU_ASSERT(block_cnt, ); // prevent div by zero + + uint16_t const block_sz = p_cbw->total_bytes / block_cnt; + TU_ASSERT(block_sz, ); // prevent div by zero // Adjust lba with transferred bytes uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index e59481352..1ad6d3fb0 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -73,10 +73,11 @@ //--------------------------------------------------------------------+ // TU_VERIFY Helper //--------------------------------------------------------------------+ + #if CFG_TUSB_DEBUG #include - #define _MESS_ERR(_err) printf("%s: %d: failed, error = %s\n", __func__, __LINE__, tusb_strerr[_err]) - #define _MESS_FAILED() printf("%s: %d: failed\n", __func__, __LINE__) + #define _MESS_ERR(_err) printf("%s %d: failed, error = %s\n", __func__, __LINE__, tusb_strerr[_err]) + #define _MESS_FAILED() printf("%s %d: assert failed\n", __func__, __LINE__) #else #define _MESS_ERR(_err) #define _MESS_FAILED() @@ -89,9 +90,13 @@ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if ( (*ARM_CM_DHCSR) & 1UL ) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */ \ } while(0) +#else +#if defined(__riscv) + #define TU_BREAKPOINT() do { __asm("ebreak\n"); } while(0) #else #define TU_BREAKPOINT() #endif +#endif /*------------------------------------------------------------------*/ /* Macro Generator diff --git a/src/device/dcd.h b/src/device/dcd.h index 6e43ab3e9..dca289e78 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -88,6 +88,9 @@ typedef struct TU_ATTR_ALIGNED(4) // Initialize controller to device mode void dcd_init (uint8_t rhport); +// Interrupt Handler +void dcd_isr (uint8_t rhport); + // Enable device interrupt void dcd_int_enable (uint8_t rhport); diff --git a/src/device/usbd.h b/src/device/usbd.h index b3665d7f2..9d39af13a 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -47,6 +47,9 @@ bool tud_init (void); // Task function should be called in main/rtos loop void tud_task (void); +// Interrupt handler, name alias to DCD +#define tud_isr dcd_isr + // Check if device is connected and configured bool tud_mounted(void); diff --git a/src/host/ehci/ehci.c b/src/host/ehci/ehci.c index 63e87dd54..18123a497 100644 --- a/src/host/ehci/ehci.c +++ b/src/host/ehci/ehci.c @@ -170,7 +170,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) list_remove_qhd_by_addr( (ehci_link_t*) qhd_async_head(rhport), dev_addr ); // Remove from all interval period list - for(uint8_t i = 0; i < TU_ARRAY_SZIE(ehci_data.period_head_arr); i++) + for(uint8_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++) { list_remove_qhd_by_addr( (ehci_link_t*) &ehci_data.period_head_arr[i], dev_addr); } @@ -623,7 +623,7 @@ static void xfer_error_isr(uint8_t hostid) } //------------- Host Controller Driver's Interrupt Handler -------------// -void hal_hcd_isr(uint8_t rhport) +void hcd_isr(uint8_t rhport) { ehci_registers_t* regs = ehci_data.regs; diff --git a/src/host/hcd.h b/src/host/hcd.h index 86e7d664b..97dc3ebfd 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -87,6 +87,7 @@ enum { // HCD API //--------------------------------------------------------------------+ bool hcd_init(void); +void hcd_isr(uint8_t hostid); void hcd_int_enable (uint8_t rhport); void hcd_int_disable(uint8_t rhport); diff --git a/src/host/ohci/ohci.c b/src/host/ohci/ohci.c index ea553baa2..9fa861ac9 100644 --- a/src/host/ohci/ohci.c +++ b/src/host/ohci/ohci.c @@ -599,7 +599,7 @@ static void done_queue_isr(uint8_t hostid) } } -void hal_hcd_isr(uint8_t hostid) +void hcd_isr(uint8_t hostid) { uint32_t const int_en = OHCI_REG->interrupt_enable; uint32_t const int_status = OHCI_REG->interrupt_status & int_en; diff --git a/src/host/usbh.c b/src/host/usbh.c index 42a99f3d2..9e1861f87 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -95,7 +95,7 @@ static host_class_driver_t const usbh_class_drivers[] = #endif }; -enum { USBH_CLASS_DRIVER_COUNT = TU_ARRAY_SZIE(usbh_class_drivers) }; +enum { USBH_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION diff --git a/src/host/usbh.h b/src/host/usbh.h index 311b2514d..42a2bd095 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -68,6 +68,9 @@ typedef struct { //--------------------------------------------------------------------+ void tuh_task(void); +// Interrupt handler, name alias to HCD +#define tuh_isr hcd_isr + tusb_device_state_t tuh_device_get_state (uint8_t dev_addr); static inline bool tuh_device_is_configured(uint8_t dev_addr) { diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 17140ee75..59c2f36aa 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -31,7 +31,6 @@ #include "nrf.h" #include "nrf_clock.h" #include "nrf_power.h" -#include "nrf_usbd.h" #include "nrfx_usbd_errata.h" #ifdef SOFTDEVICE_PRESENT @@ -498,7 +497,8 @@ void USBD_IRQHandler(void) if ( int_status & (USBD_INTEN_EPDATA_Msk | USBD_INTEN_EP0DATADONE_Msk) ) { uint32_t data_status = NRF_USBD->EPDATASTATUS; - nrf_usbd_epdatastatus_clear(data_status); + NRF_USBD->EPDATASTATUS = data_status; + __ISB(); __DSB(); // EP0DATADONE is set with either Control Out on IN Data // Since EPDATASTATUS cannot be used to determine whether it is control OUT or IN. @@ -572,7 +572,7 @@ static bool hfclk_running(void) } #endif - return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); + return nrf_clock_hf_is_running(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY); } static void hfclk_enable(void) @@ -588,8 +588,8 @@ static void hfclk_enable(void) } #endif - nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); - nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); + nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED); + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); } static void hfclk_disable(void) @@ -602,7 +602,7 @@ static void hfclk_disable(void) } #endif - nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); } // Power & Clock Peripheral on nRF5x to manage USB @@ -630,7 +630,8 @@ void tusb_hal_nrf_power_event (uint32_t event) if ( !NRF_USBD->ENABLE ) { /* Prepare for READY event receiving */ - nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK); + NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; + __ISB(); __DSB(); // for sync /* Enable the peripheral */ // ERRATA 171, 187, 166 @@ -667,7 +668,8 @@ void tusb_hal_nrf_power_event (uint32_t event) // CRITICAL_REGION_EXIT(); } - nrf_usbd_enable(); + NRF_USBD->ENABLE = 1; + __ISB(); __DSB(); // for sync // Enable HFCLK hfclk_enable(); @@ -678,8 +680,8 @@ void tusb_hal_nrf_power_event (uint32_t event) /* Waiting for USBD peripheral enabled */ while ( !(USBD_EVENTCAUSE_READY_Msk & NRF_USBD->EVENTCAUSE) ) { } - nrf_usbd_eventcause_clear(USBD_EVENTCAUSE_READY_Msk); - nrf_usbd_event_clear(USBD_EVENTCAUSE_READY_Msk); + NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; + __ISB(); __DSB(); // for sync if ( nrfx_usbd_errata_171() ) { @@ -719,11 +721,11 @@ void tusb_hal_nrf_power_event (uint32_t event) *((volatile uint32_t *) (NRF_USBD_BASE + 0x800)) = 0x7E3; *((volatile uint32_t *) (NRF_USBD_BASE + 0x804)) = 0x40; - __ISB(); - __DSB(); + __ISB(); __DSB(); } - nrf_usbd_isosplit_set(USBD_ISOSPLIT_SPLIT_HalfIN); + // ISO buffer Lower half for IN, upper half for OUT + NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN; // Enable interrupt NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk | USBD_INTEN_EPDATA_Msk | @@ -737,7 +739,8 @@ void tusb_hal_nrf_power_event (uint32_t event) while ( !hfclk_running() ) { } // Enable pull up - nrf_usbd_pullup_enable(); + NRF_USBD->USBPULLUP = 1; + __ISB(); __DSB(); // for sync break; case USB_EVT_REMOVED: @@ -746,7 +749,8 @@ void tusb_hal_nrf_power_event (uint32_t event) // Abort all transfers // Disable pull up - nrf_usbd_pullup_disable(); + NRF_USBD->USBPULLUP = 0; + __ISB(); __DSB(); // for sync // Disable Interrupt NVIC_DisableIRQ(USBD_IRQn); @@ -754,7 +758,9 @@ void tusb_hal_nrf_power_event (uint32_t event) // disable all interrupt NRF_USBD->INTENCLR = NRF_USBD->INTEN; - nrf_usbd_disable(); + NRF_USBD->ENABLE = 0; + __ISB(); __DSB(); // for sync + hfclk_disable(); dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index 8c439616a..89a4ba3f8 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -495,7 +495,7 @@ static void dd_complete_isr(uint8_t rhport, uint8_t ep_id) } // main USB IRQ handler -void hal_dcd_isr(uint8_t rhport) +void dcd_isr(uint8_t rhport) { uint32_t const dev_int_status = LPC_USB->DevIntSt & LPC_USB->DevIntEn; LPC_USB->DevIntClr = dev_int_status;// Acknowledge handled interrupt diff --git a/src/portable/nxp/lpc17_40/hal_lpc17_40.c b/src/portable/nxp/lpc17_40/hcd_lpc17_40.c similarity index 81% rename from src/portable/nxp/lpc17_40/hal_lpc17_40.c rename to src/portable/nxp/lpc17_40/hcd_lpc17_40.c index e83e3e9a4..537b3daba 100644 --- a/src/portable/nxp/lpc17_40/hal_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/hcd_lpc17_40.c @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019 Ha Thach (tinyusb.org) + * 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 @@ -24,27 +24,12 @@ * This file is part of the TinyUSB stack. */ -#include "common/tusb_common.h" +#include "tusb_option.h" #if (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC40XX) #include "chip.h" -extern void hal_hcd_isr(uint8_t hostid); -extern void hal_dcd_isr(uint8_t rhport); - -void USB_IRQHandler(void) -{ - #if TUSB_OPT_HOST_ENABLED - hal_hcd_isr(0); - #endif - - #if TUSB_OPT_DEVICE_ENABLED - hal_dcd_isr(0); - #endif -} - -//FIXME move later void hcd_int_enable(uint8_t rhport) { (void) rhport; @@ -57,5 +42,5 @@ void hcd_int_disable(uint8_t rhport) NVIC_DisableIRQ(USB_IRQn); } - #endif + diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c deleted file mode 100644 index 3619a7c2b..000000000 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ /dev/null @@ -1,356 +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. - * - * This file is part of the TinyUSB stack. - */ - -#include "tusb_option.h" - -#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX) - -//--------------------------------------------------------------------+ -// INCLUDE -//--------------------------------------------------------------------+ -#include "common/tusb_common.h" -#include "device/dcd.h" -#include "dcd_lpc18_43.h" - -#include "chip.h" - -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF -//--------------------------------------------------------------------+ - -#define QHD_MAX 12 -#define QTD_NEXT_INVALID 0x01 - -typedef struct { - // Must be at 2K alignment - dcd_qhd_t qhd[QHD_MAX] TU_ATTR_ALIGNED(64); - dcd_qtd_t qtd[QHD_MAX] TU_ATTR_ALIGNED(32); -}dcd_data_t; - -#if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) -CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048) static dcd_data_t dcd_data0; -#endif - -#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) -CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048) static dcd_data_t dcd_data1; -#endif - -static LPC_USBHS_T * const LPC_USB[2] = { LPC_USB0, LPC_USB1 }; - -static dcd_data_t* const dcd_data_ptr[2] = -{ -#if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) - &dcd_data0, -#else - NULL, -#endif - -#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) - &dcd_data1 -#else - NULL -#endif -}; - -//--------------------------------------------------------------------+ -// CONTROLLER API -//--------------------------------------------------------------------+ - -/// follows LPC43xx User Manual 23.10.3 -static void bus_reset(uint8_t rhport) -{ - LPC_USBHS_T* lpc_usb = LPC_USB[rhport]; - - // The reset value for all endpoint types is the control endpoint. If one endpoint - // direction is enabled and the paired endpoint of opposite direction is disabled, then the - // endpoint type of the unused direction must bechanged from the control type to any other - // type (e.g. bulk). Leaving an unconfigured endpoint control will cause undefined behavior - // for the data PID tracking on the active endpoint. - - // USB0 has 5 but USB1 only has 3 non-control endpoints - for( int i=1; i < (rhport ? 6 : 4); i++) - { - lpc_usb->ENDPTCTRL[i] = (TUSB_XFER_BULK << 2) | (TUSB_XFER_BULK << 18); - } - - //------------- Clear All Registers -------------// - lpc_usb->ENDPTNAK = lpc_usb->ENDPTNAK; - lpc_usb->ENDPTNAKEN = 0; - lpc_usb->USBSTS_D = lpc_usb->USBSTS_D; - lpc_usb->ENDPTSETUPSTAT = lpc_usb->ENDPTSETUPSTAT; - lpc_usb->ENDPTCOMPLETE = lpc_usb->ENDPTCOMPLETE; - - while (lpc_usb->ENDPTPRIME); - lpc_usb->ENDPTFLUSH = 0xFFFFFFFF; - while (lpc_usb->ENDPTFLUSH); - - // read reset bit in portsc - - //------------- Queue Head & Queue TD -------------// - dcd_data_t* p_dcd = dcd_data_ptr[rhport]; - tu_memclr(p_dcd, sizeof(dcd_data_t)); - - //------------- Set up Control Endpoints (0 OUT, 1 IN) -------------// - p_dcd->qhd[0].zero_length_termination = p_dcd->qhd[1].zero_length_termination = 1; - p_dcd->qhd[0].max_package_size = p_dcd->qhd[1].max_package_size = CFG_TUD_ENDPOINT0_SIZE; - p_dcd->qhd[0].qtd_overlay.next = p_dcd->qhd[1].qtd_overlay.next = QTD_NEXT_INVALID; - - p_dcd->qhd[0].int_on_setup = 1; // OUT only -} - -void dcd_init(uint8_t rhport) -{ - LPC_USBHS_T* const lpc_usb = LPC_USB[rhport]; - dcd_data_t* p_dcd = dcd_data_ptr[rhport]; - - tu_memclr(p_dcd, sizeof(dcd_data_t)); - - lpc_usb->ENDPOINTLISTADDR = (uint32_t) p_dcd->qhd; // Endpoint List Address has to be 2K alignment - lpc_usb->USBSTS_D = lpc_usb->USBSTS_D; - lpc_usb->USBINTR_D = INT_MASK_USB | INT_MASK_ERROR | INT_MASK_PORT_CHANGE | INT_MASK_RESET | INT_MASK_SUSPEND | INT_MASK_SOF; - - lpc_usb->USBCMD_D &= ~0x00FF0000; // Interrupt Threshold Interval = 0 - lpc_usb->USBCMD_D |= TU_BIT(0); // connect -} - -void dcd_int_enable(uint8_t rhport) -{ - NVIC_EnableIRQ(rhport ? USB1_IRQn : USB0_IRQn); -} - -void dcd_int_disable(uint8_t rhport) -{ - NVIC_DisableIRQ(rhport ? USB1_IRQn : USB0_IRQn); -} - -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -{ - // Response with status first before changing device address - dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); - - LPC_USB[rhport]->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); -} - -void dcd_set_config(uint8_t rhport, uint8_t config_num) -{ - (void) rhport; - (void) config_num; - // nothing to do -} - -void dcd_remote_wakeup(uint8_t rhport) -{ - (void) rhport; -} - -//--------------------------------------------------------------------+ -// HELPER -//--------------------------------------------------------------------+ -// index to bit position in register -static inline uint8_t ep_idx2bit(uint8_t ep_idx) -{ - return ep_idx/2 + ( (ep_idx%2) ? 16 : 0); -} - -static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes) -{ - tu_memclr(p_qtd, sizeof(dcd_qtd_t)); - - p_qtd->next = QTD_NEXT_INVALID; - p_qtd->active = 1; - p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; - - if (data_ptr != NULL) - { - p_qtd->buffer[0] = (uint32_t) data_ptr; - for(uint8_t i=1; i<5; i++) - { - p_qtd->buffer[i] |= tu_align4k( p_qtd->buffer[i-1] ) + 4096; - } - } -} - -//--------------------------------------------------------------------+ -// DCD Endpoint Port -//--------------------------------------------------------------------+ -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - LPC_USB[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_MASK_STALL << (dir ? 16 : 0); -} - -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - // data toggle also need to be reset - LPC_USB[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_MASK_TOGGLE_RESET << ( dir ? 16 : 0 ); - LPC_USB[rhport]->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_MASK_STALL << ( dir ? 16 : 0)); -} - -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) -{ - // TODO not support ISO yet - TU_VERIFY ( p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); - - uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); - uint8_t const ep_idx = 2*epnum + dir; - - // USB0 has 5, USB1 has 3 non-control endpoints - TU_ASSERT( epnum <= (rhport ? 3 : 5) ); - - //------------- Prepare Queue Head -------------// - dcd_qhd_t * p_qhd = &dcd_data_ptr[rhport]->qhd[ep_idx]; - tu_memclr(p_qhd, sizeof(dcd_qhd_t)); - - p_qhd->zero_length_termination = 1; - p_qhd->max_package_size = p_endpoint_desc->wMaxPacketSize.size; - p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; - - // Enable EP Control - LPC_USB[rhport]->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_MASK_ENABLE | ENDPTCTRL_MASK_TOGGLE_RESET) << (dir ? 16 : 0); - - return true; -} - -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - uint8_t const ep_idx = 2*epnum + dir; - - if ( epnum == 0 ) - { - // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism - // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out - while(LPC_USB[rhport]->ENDPTSETUPSTAT & TU_BIT(0)) {} - } - - dcd_qhd_t * p_qhd = &dcd_data_ptr[rhport]->qhd[ep_idx]; - dcd_qtd_t * p_qtd = &dcd_data_ptr[rhport]->qtd[ep_idx]; - - //------------- Prepare qtd -------------// - qtd_init(p_qtd, buffer, total_bytes); - p_qtd->int_on_complete = true; - p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd - - // start transfer - LPC_USB[rhport]->ENDPTPRIME = TU_BIT( ep_idx2bit(ep_idx) ) ; - - return true; -} - -//--------------------------------------------------------------------+ -// ISR -//--------------------------------------------------------------------+ -void hal_dcd_isr(uint8_t rhport) -{ - LPC_USBHS_T* const lpc_usb = LPC_USB[rhport]; - - uint32_t const int_enable = lpc_usb->USBINTR_D; - uint32_t const int_status = lpc_usb->USBSTS_D & int_enable; - lpc_usb->USBSTS_D = int_status; // Acknowledge handled interrupt - - if (int_status == 0) return;// disabled interrupt sources - - - if (int_status & INT_MASK_RESET) - { - bus_reset(rhport); - dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); - } - - if (int_status & INT_MASK_SUSPEND) - { - if (lpc_usb->PORTSC1_D & PORTSC_SUSPEND_MASK) - { - // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. - if ((lpc_usb->DEVICEADDR >> 25) & 0x0f) - { - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); - } - } - } - - // TODO disconnection does not generate interrupt !!!!!! -// if (int_status & INT_MASK_PORT_CHANGE) -// { -// if ( !(lpc_usb->PORTSC1_D & PORTSC_CURRENT_CONNECT_STATUS_MASK) ) -// { -// dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_UNPLUGGED }; -// dcd_event_handler(&event, true); -// } -// } - - if (int_status & INT_MASK_USB) - { - uint32_t const edpt_complete = lpc_usb->ENDPTCOMPLETE; - lpc_usb->ENDPTCOMPLETE = edpt_complete; // acknowledge - - dcd_data_t* const p_dcd = dcd_data_ptr[rhport]; - - if (lpc_usb->ENDPTSETUPSTAT) - { - //------------- Set up Received -------------// - // 23.10.10.2 Operational model for setup transfers - lpc_usb->ENDPTSETUPSTAT = lpc_usb->ENDPTSETUPSTAT;// acknowledge - - dcd_event_setup_received(rhport, (uint8_t*) &p_dcd->qhd[0].setup_request, true); - } - - if ( edpt_complete ) - { - for(uint8_t ep_idx = 0; ep_idx < QHD_MAX; ep_idx++) - { - if ( tu_bit_test(edpt_complete, ep_idx2bit(ep_idx)) ) - { - // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set - dcd_qtd_t * p_qtd = &dcd_data_ptr[rhport]->qtd[ep_idx]; - - uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED : - ( p_qtd->xact_err ||p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS; - - uint8_t const ep_addr = (ep_idx/2) | ( (ep_idx & 0x01) ? TUSB_DIR_IN_MASK : 0 ); - dcd_event_xfer_complete(rhport, ep_addr, p_qtd->expected_bytes - p_qtd->total_bytes, result, true); // only number of bytes in the IOC qtd - } - } - } - } - - if (int_status & INT_MASK_SOF) - { - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); - } - - if (int_status & INT_MASK_NAK) {} - if (int_status & INT_MASK_ERROR) TU_ASSERT(false, ); -} - -#endif diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.h b/src/portable/nxp/lpc18_43/dcd_lpc18_43.h deleted file mode 100644 index 00f4854b1..000000000 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.h +++ /dev/null @@ -1,144 +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. - * - * This file is part of the TinyUSB stack. - */ - -/** \ingroup group_dcd - * \defgroup group_dcd_lpc143xx LPC43xx - * @{ */ - -#ifndef _TUSB_DCD_LPC43XX_H_ -#define _TUSB_DCD_LPC43XX_H_ - -#include "common/tusb_common.h" - -#ifdef __cplusplus - extern "C" { -#endif - -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF -//--------------------------------------------------------------------+ - -/*---------- ENDPTCTRL ----------*/ -enum { - ENDPTCTRL_MASK_STALL = TU_BIT(0), - ENDPTCTRL_MASK_TOGGLE_INHIBIT = TU_BIT(5), ///< used for test only - ENDPTCTRL_MASK_TOGGLE_RESET = TU_BIT(6), - ENDPTCTRL_MASK_ENABLE = TU_BIT(7) -}; - -/*---------- USBCMD ----------*/ -enum { - USBCMD_MASK_RUN_STOP = TU_BIT(0), - USBCMD_MASK_RESET = TU_BIT(1), - USBCMD_MASK_SETUP_TRIPWIRE = TU_BIT(13), - USBCMD_MASK_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD -}; -// Interrupt Threshold bit 23:16 - -/*---------- USBSTS, USBINTR ----------*/ -enum { - INT_MASK_USB = TU_BIT(0), - INT_MASK_ERROR = TU_BIT(1), - INT_MASK_PORT_CHANGE = TU_BIT(2), - INT_MASK_RESET = TU_BIT(6), - INT_MASK_SOF = TU_BIT(7), - INT_MASK_SUSPEND = TU_BIT(8), - INT_MASK_NAK = TU_BIT(16) -}; - -//------------- PORTSC -------------// -enum { - PORTSC_CURRENT_CONNECT_STATUS_MASK = TU_BIT(0), - PORTSC_FORCE_PORT_RESUME_MASK = TU_BIT(6), - PORTSC_SUSPEND_MASK = TU_BIT(7) -}; - -typedef struct -{ - // Word 0: Next QTD Pointer - uint32_t next; ///< Next link pointer This field contains the physical memory address of the next dTD to be processed - - // Word 1: qTQ Token - uint32_t : 3 ; - volatile uint32_t xact_err : 1 ; - uint32_t : 1 ; - volatile uint32_t buffer_err : 1 ; - volatile uint32_t halted : 1 ; - volatile uint32_t active : 1 ; - uint32_t : 2 ; - uint32_t iso_mult_override : 2 ; ///< This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. - uint32_t : 3 ; - uint32_t int_on_complete : 1 ; - volatile uint32_t total_bytes : 15 ; - uint32_t : 0 ; - - // Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page - uint32_t buffer[5]; ///< buffer1 has frame_n for TODO Isochronous - - //------------- DCD Area -------------// - uint16_t expected_bytes; - uint8_t reserved[2]; -} dcd_qtd_t; - -TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct"); - -typedef struct -{ - // Word 0: Capabilities and Characteristics - uint32_t : 15 ; ///< Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. - uint32_t int_on_setup : 1 ; ///< Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. - uint32_t max_package_size : 11 ; ///< This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) - uint32_t : 2 ; - uint32_t zero_length_termination : 1 ; ///< This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. - uint32_t iso_mult : 2 ; ///< - uint32_t : 0 ; - - // Word 1: Current qTD Pointer - volatile uint32_t qtd_addr; - - // Word 2-9: Transfer Overlay - volatile dcd_qtd_t qtd_overlay; - - // Word 10-11: Setup request (control OUT only) - volatile tusb_control_request_t setup_request; - - //--------------------------------------------------------------------+ - /// Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes - /// thus there are 16 bytes padding free that we can make use of. - //--------------------------------------------------------------------+ - uint8_t reserved[16]; -} dcd_qhd_t; - -TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct"); - - -#ifdef __cplusplus - } -#endif - -#endif /* _TUSB_DCD_LPC43XX_H_ */ - -/** @} */ diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c new file mode 100644 index 000000000..2ec7ae51c --- /dev/null +++ b/src/portable/nxp/transdimension/dcd_transdimension.c @@ -0,0 +1,539 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC18XX || \ + CFG_TUSB_MCU == OPT_MCU_LPC43XX || \ + CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "common/tusb_common.h" +#include "device/dcd.h" + +#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #include "fsl_device_registers.h" + +// RT1010 and RT1020 only has 1 USB controller +#if FSL_FEATURE_SOC_USBHS_COUNT == 1 + #define DCD_REGS_BASE { (dcd_registers_t*) USB_BASE } + IRQn_Type DCD_IRQn[] = { USB_OTG1_IRQn }; + +// RT1050, RT1060 has 2 USB controllers +#else + #define DCD_REGS_BASE { (dcd_registers_t*) USB1_BASE, (dcd_registers_t*) USB2_BASE } + IRQn_Type DCD_IRQn[] = { USB_OTG1_IRQn, USB_OTG2_IRQn }; +#endif + +#else + #include "chip.h" + #define DCD_REGS_BASE { (dcd_registers_t*) LPC_USB0_BASE, (dcd_registers_t*) LPC_USB1_BASE } + IRQn_Type DCD_IRQn[] = { USB0_IRQn, USB1_IRQn }; +#endif + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +// ENDPTCTRL +enum { + ENDPTCTRL_STALL = TU_BIT(0), + ENDPTCTRL_TOGGLE_INHIBIT = TU_BIT(5), ///< used for test only + ENDPTCTRL_TOGGLE_RESET = TU_BIT(6), + ENDPTCTRL_ENABLE = TU_BIT(7) +}; + +// USBCMD +enum { + USBCMD_RUN_STOP = TU_BIT(0), + USBCMD_RESET = TU_BIT(1), + USBCMD_SETUP_TRIPWIRE = TU_BIT(13), + USBCMD_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD +}; +// Interrupt Threshold bit 23:16 + +// USBSTS, USBINTR +enum { + INTR_USB = TU_BIT(0), + INTR_ERROR = TU_BIT(1), + INTR_PORT_CHANGE = TU_BIT(2), + INTR_RESET = TU_BIT(6), + INTR_SOF = TU_BIT(7), + INTR_SUSPEND = TU_BIT(8), + INTR_NAK = TU_BIT(16) +}; + +// PORTSC1 +enum { + PORTSC1_CURRENT_CONNECT_STATUS = TU_BIT(0), + PORTSC1_FORCE_PORT_RESUME = TU_BIT(6), + PORTSC1_SUSPEND = TU_BIT(7), + PORTSC1_FORCE_FULL_SPEED = TU_BIT(24), +}; + +// OTGSC +enum { + OTGSC_VBUS_DISCHARGE = TU_BIT(0), + OTGSC_VBUS_CHARGE = TU_BIT(1), +// OTGSC_HWASSIST_AUTORESET = TU_BIT(2), + OTGSC_OTG_TERMINATION = TU_BIT(3), ///< Must set to 1 when OTG go to device mode + OTGSC_DATA_PULSING = TU_BIT(4), + OTGSC_ID_PULLUP = TU_BIT(5), +// OTGSC_HWASSIT_DATA_PULSE = TU_BIT(6), +// OTGSC_HWASSIT_BDIS_ACONN = TU_BIT(7), + OTGSC_ID = TU_BIT(8), ///< 0 = A device, 1 = B Device + OTGSC_A_VBUS_VALID = TU_BIT(9), + OTGSC_A_SESSION_VALID = TU_BIT(10), + OTGSC_B_SESSION_VALID = TU_BIT(11), + OTGSC_B_SESSION_END = TU_BIT(12), + OTGSC_1MS_TOGGLE = TU_BIT(13), + OTGSC_DATA_BUS_PULSING_STATUS = TU_BIT(14), +}; + +// USBMode +enum { + USBMODE_CM_DEVICE = 2, + USBMODE_CM_HOST = 3, + + USBMODE_SLOM = TU_BIT(3), + USBMODE_SDIS = TU_BIT(4), + + USBMODE_VBUS_POWER_SELCT = TU_BIT(5), // Enable for LPC18XX/43XX in host most only +}; + +// Device Registers +typedef struct +{ + //------------- ID + HW Parameter Registers-------------// + __I uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX + + //------------- Capability Registers-------------// + __I uint8_t CAPLENGTH; ///< Capability Registers Length + __I uint8_t TU_RESERVED[1]; + __I uint16_t HCIVERSION; ///< Host Controller Interface Version + + __I uint32_t HCSPARAMS; ///< Host Controller Structural Parameters + __I uint32_t HCCPARAMS; ///< Host Controller Capability Parameters + __I uint32_t TU_RESERVED[5]; + + __I uint16_t DCIVERSION; ///< Device Controller Interface Version + __I uint8_t TU_RESERVED[2]; + + __I uint32_t DCCPARAMS; ///< Device Controller Capability Parameters + __I uint32_t TU_RESERVED[6]; + + //------------- Operational Registers -------------// + __IO uint32_t USBCMD; ///< USB Command Register + __IO uint32_t USBSTS; ///< USB Status Register + __IO uint32_t USBINTR; ///< Interrupt Enable Register + __IO uint32_t FRINDEX; ///< USB Frame Index + __I uint32_t TU_RESERVED; + __IO uint32_t DEVICEADDR; ///< Device Address + __IO uint32_t ENDPTLISTADDR; ///< Endpoint List Address + __I uint32_t TU_RESERVED; + __IO uint32_t BURSTSIZE; ///< Programmable Burst Size + __IO uint32_t TXFILLTUNING; ///< TX FIFO Fill Tuning + uint32_t TU_RESERVED[4]; + __IO uint32_t ENDPTNAK; ///< Endpoint NAK + __IO uint32_t ENDPTNAKEN; ///< Endpoint NAK Enable + __I uint32_t TU_RESERVED; + __IO uint32_t PORTSC1; ///< Port Status & Control + __I uint32_t TU_RESERVED[7]; + __IO uint32_t OTGSC; ///< On-The-Go Status & control + __IO uint32_t USBMODE; ///< USB Device Mode + __IO uint32_t ENDPTSETUPSTAT; ///< Endpoint Setup Status + __IO uint32_t ENDPTPRIME; ///< Endpoint Prime + __IO uint32_t ENDPTFLUSH; ///< Endpoint Flush + __I uint32_t ENDPTSTAT; ///< Endpoint Status + __IO uint32_t ENDPTCOMPLETE; ///< Endpoint Complete + __IO uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7 +} dcd_registers_t; + + +// Queue Transfer Descriptor +typedef struct +{ + // Word 0: Next QTD Pointer + uint32_t next; ///< Next link pointer This field contains the physical memory address of the next dTD to be processed + + // Word 1: qTQ Token + uint32_t : 3 ; + volatile uint32_t xact_err : 1 ; + uint32_t : 1 ; + volatile uint32_t buffer_err : 1 ; + volatile uint32_t halted : 1 ; + volatile uint32_t active : 1 ; + uint32_t : 2 ; + uint32_t iso_mult_override : 2 ; ///< This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. + uint32_t : 3 ; + uint32_t int_on_complete : 1 ; + volatile uint32_t total_bytes : 15 ; + uint32_t : 0 ; + + // Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page + uint32_t buffer[5]; ///< buffer1 has frame_n for TODO Isochronous + + //------------- DCD Area -------------// + uint16_t expected_bytes; + uint8_t reserved[2]; +} dcd_qtd_t; + +TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct"); + +// Queue Head +typedef struct +{ + // Word 0: Capabilities and Characteristics + uint32_t : 15 ; ///< Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. + uint32_t int_on_setup : 1 ; ///< Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. + uint32_t max_package_size : 11 ; ///< This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) + uint32_t : 2 ; + uint32_t zero_length_termination : 1 ; ///< This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. + uint32_t iso_mult : 2 ; ///< + uint32_t : 0 ; + + // Word 1: Current qTD Pointer + volatile uint32_t qtd_addr; + + // Word 2-9: Transfer Overlay + volatile dcd_qtd_t qtd_overlay; + + // Word 10-11: Setup request (control OUT only) + volatile tusb_control_request_t setup_request; + + //--------------------------------------------------------------------+ + /// Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes + /// thus there are 16 bytes padding free that we can make use of. + //--------------------------------------------------------------------+ + uint8_t reserved[16]; +} dcd_qhd_t; + +TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct"); + +//--------------------------------------------------------------------+ +// Variables +//--------------------------------------------------------------------+ + +#define QHD_MAX 12 +#define QTD_NEXT_INVALID 0x01 + +typedef struct { + // Must be at 2K alignment + dcd_qhd_t qhd[QHD_MAX] TU_ATTR_ALIGNED(64); + dcd_qtd_t qtd[QHD_MAX] TU_ATTR_ALIGNED(32); +}dcd_data_t; + +static dcd_data_t _dcd_data CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048); +static dcd_registers_t* DCD_REGS[] = DCD_REGS_BASE; + +//--------------------------------------------------------------------+ +// CONTROLLER API +//--------------------------------------------------------------------+ + +/// follows LPC43xx User Manual 23.10.3 +static void bus_reset(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = DCD_REGS[rhport]; + + // The reset value for all endpoint types is the control endpoint. If one endpoint + // direction is enabled and the paired endpoint of opposite direction is disabled, then the + // endpoint type of the unused direction must bechanged from the control type to any other + // type (e.g. bulk). Leaving an unconfigured endpoint control will cause undefined behavior + // for the data PID tracking on the active endpoint. + + // USB0 has 5 but USB1 only has 3 non-control endpoints + for( int i=1; i < (rhport ? 6 : 4); i++) + { + dcd_reg->ENDPTCTRL[i] = (TUSB_XFER_BULK << 2) | (TUSB_XFER_BULK << 18); + } + + //------------- Clear All Registers -------------// + dcd_reg->ENDPTNAK = dcd_reg->ENDPTNAK; + dcd_reg->ENDPTNAKEN = 0; + dcd_reg->USBSTS = dcd_reg->USBSTS; + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; + dcd_reg->ENDPTCOMPLETE = dcd_reg->ENDPTCOMPLETE; + + while (dcd_reg->ENDPTPRIME); + dcd_reg->ENDPTFLUSH = 0xFFFFFFFF; + while (dcd_reg->ENDPTFLUSH); + + // read reset bit in portsc + + //------------- Queue Head & Queue TD -------------// + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + + //------------- Set up Control Endpoints (0 OUT, 1 IN) -------------// + _dcd_data.qhd[0].zero_length_termination = _dcd_data.qhd[1].zero_length_termination = 1; + _dcd_data.qhd[0].max_package_size = _dcd_data.qhd[1].max_package_size = CFG_TUD_ENDPOINT0_SIZE; + _dcd_data.qhd[0].qtd_overlay.next = _dcd_data.qhd[1].qtd_overlay.next = QTD_NEXT_INVALID; + + _dcd_data.qhd[0].int_on_setup = 1; // OUT only +} + +void dcd_init(uint8_t rhport) +{ + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + + dcd_registers_t* const dcd_reg = DCD_REGS[rhport]; + + // Reset controller + dcd_reg->USBCMD |= USBCMD_RESET; + while( dcd_reg->USBCMD & USBCMD_RESET ) {} + + // Set mode to device, must be set immediately after reset + dcd_reg->USBMODE = USBMODE_CM_DEVICE; + dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION; + + // TODO Force fullspeed on non-highspeed port + // dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED; + + dcd_reg->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment + dcd_reg->USBSTS = dcd_reg->USBSTS; + dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_RESET | INTR_SUSPEND | INTR_SOF; + + dcd_reg->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0 + dcd_reg->USBCMD |= TU_BIT(0); // connect +} + +void dcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(DCD_IRQn[rhport]); +} + +void dcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(DCD_IRQn[rhport]); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + // Response with status first before changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + + DCD_REGS[rhport]->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); +} + +void dcd_set_config(uint8_t rhport, uint8_t config_num) +{ + (void) rhport; + (void) config_num; + // nothing to do +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; +} + +//--------------------------------------------------------------------+ +// HELPER +//--------------------------------------------------------------------+ +// index to bit position in register +static inline uint8_t ep_idx2bit(uint8_t ep_idx) +{ + return ep_idx/2 + ( (ep_idx%2) ? 16 : 0); +} + +static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes) +{ + tu_memclr(p_qtd, sizeof(dcd_qtd_t)); + + p_qtd->next = QTD_NEXT_INVALID; + p_qtd->active = 1; + p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; + + if (data_ptr != NULL) + { + p_qtd->buffer[0] = (uint32_t) data_ptr; + for(uint8_t i=1; i<5; i++) + { + p_qtd->buffer[i] |= tu_align4k( p_qtd->buffer[i-1] ) + 4096; + } + } +} + +//--------------------------------------------------------------------+ +// DCD Endpoint Port +//--------------------------------------------------------------------+ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // data toggle also need to be reset + DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); + DCD_REGS[rhport]->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + // TODO not support ISO yet + TU_VERIFY ( p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); + + uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + uint8_t const ep_idx = 2*epnum + dir; + + // USB0 has 5, USB1 has 3 non-control endpoints + TU_ASSERT( epnum <= (rhport ? 3 : 5) ); + + //------------- Prepare Queue Head -------------// + dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx]; + tu_memclr(p_qhd, sizeof(dcd_qhd_t)); + + p_qhd->zero_length_termination = 1; + p_qhd->max_package_size = p_endpoint_desc->wMaxPacketSize.size; + p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; + + // Enable EP Control + DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0); + + return true; +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_idx = 2*epnum + dir; + + if ( epnum == 0 ) + { + // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism + // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out + while(DCD_REGS[rhport]->ENDPTSETUPSTAT & TU_BIT(0)) {} + } + + dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx]; + dcd_qtd_t * p_qtd = &_dcd_data.qtd[ep_idx]; + + //------------- Prepare qtd -------------// + qtd_init(p_qtd, buffer, total_bytes); + p_qtd->int_on_complete = true; + p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd + + // start transfer + DCD_REGS[rhport]->ENDPTPRIME = TU_BIT( ep_idx2bit(ep_idx) ) ; + + return true; +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ +void dcd_isr(uint8_t rhport) +{ + dcd_registers_t* const dcd_reg = DCD_REGS[rhport]; + + uint32_t const int_enable = dcd_reg->USBINTR; + uint32_t const int_status = dcd_reg->USBSTS & int_enable; + dcd_reg->USBSTS = int_status; // Acknowledge handled interrupt + + // disabled interrupt sources + if (int_status == 0) return; + + if (int_status & INTR_RESET) + { + bus_reset(rhport); + dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); + } + + if (int_status & INTR_SUSPEND) + { + if (dcd_reg->PORTSC1 & PORTSC1_SUSPEND) + { + // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. + if ((dcd_reg->DEVICEADDR >> 25) & 0x0f) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + } + } + + // TODO disconnection does not generate interrupt !!!!!! +// if (int_status & INTR_PORT_CHANGE) +// { +// if ( !(dcd_reg->PORTSC1 & PORTSC1_CURRENT_CONNECT_STATUS) ) +// { +// dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_UNPLUGGED }; +// dcd_event_handler(&event, true); +// } +// } + + if (int_status & INTR_USB) + { + uint32_t const edpt_complete = dcd_reg->ENDPTCOMPLETE; + dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge + + if (dcd_reg->ENDPTSETUPSTAT) + { + //------------- Set up Received -------------// + // 23.10.10.2 Operational model for setup transfers + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT;// acknowledge + + dcd_event_setup_received(rhport, (uint8_t*) &_dcd_data.qhd[0].setup_request, true); + } + + if ( edpt_complete ) + { + for(uint8_t ep_idx = 0; ep_idx < QHD_MAX; ep_idx++) + { + if ( tu_bit_test(edpt_complete, ep_idx2bit(ep_idx)) ) + { + // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set + dcd_qtd_t * p_qtd = &_dcd_data.qtd[ep_idx]; + + uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED : + ( p_qtd->xact_err ||p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS; + + uint8_t const ep_addr = (ep_idx/2) | ( (ep_idx & 0x01) ? TUSB_DIR_IN_MASK : 0 ); + dcd_event_xfer_complete(rhport, ep_addr, p_qtd->expected_bytes - p_qtd->total_bytes, result, true); // only number of bytes in the IOC qtd + } + } + } + } + + if (int_status & INTR_SOF) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + + if (int_status & INTR_NAK) {} + if (int_status & INTR_ERROR) TU_ASSERT(false, ); +} + +#endif diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c new file mode 100644 index 000000000..e555fb0b1 --- /dev/null +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -0,0 +1,638 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef DEBUG +#define DEBUG 0 +#endif + +#ifndef LOG_USB +#define LOG_USB 0 +#endif + +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) + +#include "device/dcd.h" +#include "dcd_eptri.h" +#include "csr.h" +#include "irq.h" +void fomu_error(uint32_t line); + +#if LOG_USB +struct usb_log { + uint8_t ep_num; + uint8_t size; + uint8_t data[66]; +}; +__attribute__((used)) +struct usb_log usb_log[128]; +__attribute__((used)) +uint8_t usb_log_offset; + +struct xfer_log { + uint8_t ep_num; + uint16_t size; +}; +__attribute__((used)) +struct xfer_log xfer_log[64]; +__attribute__((used)) +uint8_t xfer_log_offset; + +__attribute__((used)) +struct xfer_log queue_log[64]; +__attribute__((used)) +uint8_t queue_log_offset; +#endif + +//--------------------------------------------------------------------+ +// SIE Command +//--------------------------------------------------------------------+ + +#define EP_SIZE 64 + +uint16_t volatile rx_buffer_offset[16]; +uint8_t volatile * rx_buffer[16]; +uint16_t volatile rx_buffer_max[16]; + +volatile uint8_t tx_ep; +volatile bool tx_active; +volatile uint16_t tx_buffer_offset[16]; +uint8_t volatile * tx_buffer[16]; +volatile uint16_t tx_buffer_max[16]; +volatile uint8_t reset_count; + +#if DEBUG +__attribute__((used)) uint8_t volatile * last_tx_buffer; +__attribute__((used)) volatile uint8_t last_tx_ep; +uint8_t setup_packet_bfr[10]; +#endif + +//--------------------------------------------------------------------+ +// PIPE HELPER +//--------------------------------------------------------------------+ + +static bool advance_tx_ep(void) { + // Move on to the next transmit buffer in a round-robin manner + uint8_t prev_tx_ep = tx_ep; + for (tx_ep = (tx_ep + 1) & 0xf; tx_ep != prev_tx_ep; tx_ep = ((tx_ep + 1) & 0xf)) { + if (tx_buffer[tx_ep]) + return true; + } + if (!tx_buffer[tx_ep]) + return false; + return true; +} + +#if LOG_USB +void xfer_log_append(uint8_t ep_num, uint16_t sz) { + xfer_log[xfer_log_offset].ep_num = ep_num; + xfer_log[xfer_log_offset].size = sz; + xfer_log_offset++; + if (xfer_log_offset >= sizeof(xfer_log)/sizeof(*xfer_log)) + xfer_log_offset = 0; +} + +void queue_log_append(uint8_t ep_num, uint16_t sz) { + queue_log[queue_log_offset].ep_num = ep_num; + queue_log[queue_log_offset].size = sz; + queue_log_offset++; + if (queue_log_offset >= sizeof(queue_log)/sizeof(*queue_log)) + queue_log_offset = 0; +} +#endif + +static void tx_more_data(void) { + // Send more data + uint8_t added_bytes; + for (added_bytes = 0; (added_bytes < EP_SIZE) && (tx_buffer_offset[tx_ep] < tx_buffer_max[tx_ep]); added_bytes++) { +#if LOG_USB + usb_log[usb_log_offset].data[added_bytes] = tx_buffer[tx_ep][tx_buffer_offset[tx_ep]]; +#endif + usb_in_data_write(tx_buffer[tx_ep][tx_buffer_offset[tx_ep]++]); + } + +#if LOG_USB + usb_log[usb_log_offset].ep_num = tu_edpt_addr(tx_ep, TUSB_DIR_IN); + usb_log[usb_log_offset].size = added_bytes; + usb_log_offset++; + if (usb_log_offset >= sizeof(usb_log)/sizeof(*usb_log)) + usb_log_offset = 0; +#endif + + // Updating the epno queues the data + usb_in_ctrl_write(tx_ep & 0xf); +} + +static void process_tx(void) { +#if DEBUG + // If the system isn't idle, then something is very wrong. + uint8_t in_status = usb_in_status_read(); + if (!(in_status & (1 << CSR_USB_IN_STATUS_IDLE_OFFSET))) + fomu_error(__LINE__); +#endif + + // If the buffer is now empty, search for the next buffer to fill. + if (!tx_buffer[tx_ep]) { + if (advance_tx_ep()) + tx_more_data(); + else + tx_active = false; + return; + } + + if (tx_buffer_offset[tx_ep] >= tx_buffer_max[tx_ep]) { +#if DEBUG + last_tx_buffer = tx_buffer[tx_ep]; + last_tx_ep = tx_ep; +#endif + tx_buffer[tx_ep] = NULL; + uint16_t xferred_bytes = tx_buffer_max[tx_ep]; + uint8_t xferred_ep = tx_ep; + + if (!advance_tx_ep()) + tx_active = false; +#if LOG_USB + xfer_log_append(tu_edpt_addr(xferred_ep, TUSB_DIR_IN), xferred_bytes); +#endif + dcd_event_xfer_complete(0, tu_edpt_addr(xferred_ep, TUSB_DIR_IN), xferred_bytes, XFER_RESULT_SUCCESS, true); + if (!tx_active) + return; + } + + tx_more_data(); + return; +} + +static void process_rx(void) { + uint8_t out_status = usb_out_status_read(); +#if DEBUG + // If the OUT handler is still waiting to send, don't do anything. + if (!(out_status & (1 << CSR_USB_OUT_STATUS_HAVE_OFFSET))) + fomu_error(__LINE__); + // return; +#endif + uint8_t rx_ep = (out_status >> CSR_USB_OUT_STATUS_EPNO_OFFSET) & 0xf; + + // If the destination buffer doesn't exist, don't drain the hardware + // fifo. Note that this can cause deadlocks if the host is waiting + // on some other endpoint's data! +#if DEBUG + if (rx_buffer[rx_ep] == NULL) { + fomu_error(__LINE__); + return; + } +#endif + + // Drain the FIFO into the destination buffer + uint32_t total_read = 0; + uint32_t current_offset = rx_buffer_offset[rx_ep]; +#if DEBUG + uint8_t test_buffer[256]; + memset(test_buffer, 0, sizeof(test_buffer)); + if (current_offset > rx_buffer_max[rx_ep]) + fomu_error(__LINE__); +#endif +#if LOG_USB + usb_log[usb_log_offset].ep_num = tu_edpt_addr(rx_ep, TUSB_DIR_OUT); + usb_log[usb_log_offset].size = 0; +#endif + while (usb_out_status_read() & (1 << CSR_USB_OUT_STATUS_HAVE_OFFSET)) { + uint8_t c = usb_out_data_read(); +#if DEBUG + test_buffer[total_read] = c; +#endif + total_read++; + if ((rx_buffer_offset[rx_ep] + current_offset) < rx_buffer_max[rx_ep]) { +#if LOG_USB + usb_log[usb_log_offset].data[usb_log[usb_log_offset].size++] = c; +#endif + if (rx_buffer[rx_ep] != (volatile uint8_t *)0xffffffff) + rx_buffer[rx_ep][current_offset++] = c; + } + } +#if LOG_USB + usb_log_offset++; + if (usb_log_offset >= sizeof(usb_log)/sizeof(*usb_log)) + usb_log_offset = 0; +#endif +#if DEBUG + if (total_read > 66) + fomu_error(__LINE__); + if (total_read < 2) + total_read = 2; + // fomu_error(__LINE__); +#endif + + // Strip off the CRC16 + rx_buffer_offset[rx_ep] += (total_read - 2); + if (rx_buffer_offset[rx_ep] > rx_buffer_max[rx_ep]) + rx_buffer_offset[rx_ep] = rx_buffer_max[rx_ep]; + + // If there's no more data, complete the transfer to tinyusb + if ((rx_buffer_max[rx_ep] == rx_buffer_offset[rx_ep]) + // ZLP with less than the total amount of data + || ((total_read == 2) && ((rx_buffer_offset[rx_ep] & 63) == 0)) + // Short read, but not a full packet + || (((rx_buffer_offset[rx_ep] & 63) != 0) && (total_read < 66))) { +#if DEBUG + if (rx_buffer[rx_ep] == NULL) + fomu_error(__LINE__); +#endif + + // Free up this buffer. + rx_buffer[rx_ep] = NULL; + uint16_t len = rx_buffer_offset[rx_ep]; + +#if DEBUG + // Validate that all enabled endpoints have buffers, + // and no disabled endpoints have buffers. + uint16_t ep_en_mask = usb_out_enable_status_read(); + int i; + for (i = 0; i < 16; i++) { + if ((!!(ep_en_mask & (1 << i))) ^ (!!(rx_buffer[i]))) { + uint8_t new_status = usb_out_status_read(); + // Another IRQ came in while we were processing, so ignore this endpoint. + if ((new_status & 0x20) && ((new_status & 0xf) == i)) + continue; + fomu_error(__LINE__); + } + } +#endif +#if LOG_USB + xfer_log_append(tu_edpt_addr(rx_ep, TUSB_DIR_OUT), len); +#endif + dcd_event_xfer_complete(0, tu_edpt_addr(rx_ep, TUSB_DIR_OUT), len, XFER_RESULT_SUCCESS, true); + } + else { + // If there's more data, re-enable data reception on this endpoint + usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | rx_ep); + } + + // Now that the buffer is drained, clear the pending IRQ. + usb_out_ev_pending_write(usb_out_ev_pending_read()); +} + +//--------------------------------------------------------------------+ +// CONTROLLER API +//--------------------------------------------------------------------+ + +static void dcd_reset(void) +{ + reset_count++; + usb_setup_ev_enable_write(0); + usb_in_ev_enable_write(0); + usb_out_ev_enable_write(0); + + usb_address_write(0); + + // Reset all three FIFO handlers + usb_setup_ctrl_write(1 << CSR_USB_SETUP_CTRL_RESET_OFFSET); + usb_in_ctrl_write(1 << CSR_USB_IN_CTRL_RESET_OFFSET); + usb_out_ctrl_write(1 << CSR_USB_OUT_CTRL_RESET_OFFSET); + + memset((void *)rx_buffer, 0, sizeof(rx_buffer)); + memset((void *)rx_buffer_max, 0, sizeof(rx_buffer_max)); + memset((void *)rx_buffer_offset, 0, sizeof(rx_buffer_offset)); + + memset((void *)tx_buffer, 0, sizeof(tx_buffer)); + memset((void *)tx_buffer_max, 0, sizeof(tx_buffer_max)); + memset((void *)tx_buffer_offset, 0, sizeof(tx_buffer_offset)); + tx_ep = 0; + tx_active = false; + + // Enable all event handlers and clear their contents + usb_setup_ev_pending_write(0xff); + usb_in_ev_pending_write(0xff); + usb_out_ev_pending_write(0xff); + usb_in_ev_enable_write(1); + usb_out_ev_enable_write(1); + usb_setup_ev_enable_write(3); + + dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); +} + +// Initializes the USB peripheral for device mode and enables it. +void dcd_init(uint8_t rhport) +{ + (void) rhport; + + usb_pullup_out_write(0); + + // Enable all event handlers and clear their contents + usb_setup_ev_pending_write(usb_setup_ev_pending_read()); + usb_in_ev_pending_write(usb_in_ev_pending_read()); + usb_out_ev_pending_write(usb_out_ev_pending_read()); + usb_in_ev_enable_write(1); + usb_out_ev_enable_write(1); + usb_setup_ev_enable_write(3); + + // Turn on the external pullup + usb_pullup_out_write(1); +} + +// Enables or disables the USB device interrupt(s). May be used to +// prevent concurrency issues when mutating data structures shared +// between main code and the interrupt handler. +void dcd_int_enable(uint8_t rhport) +{ + (void) rhport; + irq_setmask(irq_getmask() | (1 << USB_INTERRUPT)); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void) rhport; + irq_setmask(irq_getmask() & ~(1 << USB_INTERRUPT)); +} + +// Called when the device is given a new bus address. +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + // Respond with ACK status first before changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + + // Wait for the response packet to get sent + while (tx_active) + ; + + // Activate the new address + usb_address_write(dev_addr); +} + +// Called when the device received SET_CONFIG request, you can leave this +// empty if your peripheral does not require any specific action. +void dcd_set_config(uint8_t rhport, uint8_t config_num) +{ + (void) rhport; + (void) config_num; +} + +// Called to remote wake up host when suspended (e.g hid keyboard) +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; +} + +//--------------------------------------------------------------------+ +// DCD Endpoint Port +//--------------------------------------------------------------------+ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + (void) rhport; + uint8_t ep_num = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t ep_dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + + if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) + return false; // Not supported + + if (ep_dir == TUSB_DIR_OUT) { + rx_buffer_offset[ep_num] = 0; + rx_buffer_max[ep_num] = 0; + rx_buffer[ep_num] = NULL; + } + + else if (ep_dir == TUSB_DIR_IN) { + tx_buffer_offset[ep_num] = 0; + tx_buffer_max[ep_num] = 0; + tx_buffer[ep_num] = NULL; + } + + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + if (tu_edpt_dir(ep_addr) == TUSB_DIR_OUT) { + uint8_t enable = 0; + if (rx_buffer[ep_addr]) + enable = 1; + usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_STALL_OFFSET) | (enable << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | tu_edpt_number(ep_addr)); + } + else + usb_in_ctrl_write((1 << CSR_USB_IN_CTRL_STALL_OFFSET) | tu_edpt_number(ep_addr)); +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + if (tu_edpt_dir(ep_addr) == TUSB_DIR_OUT) { + uint8_t enable = 0; + if (rx_buffer[ep_addr]) + enable = 1; + usb_out_ctrl_write((0 << CSR_USB_OUT_CTRL_STALL_OFFSET) | (enable << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | tu_edpt_number(ep_addr)); + } + // IN endpoints will get unstalled when more data is written. +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) +{ + (void)rhport; + uint8_t ep_num = tu_edpt_number(ep_addr); + uint8_t ep_dir = tu_edpt_dir(ep_addr); + TU_ASSERT(ep_num < 16); + + // Give a nonzero buffer when we transmit 0 bytes, so that the + // system doesn't think the endpoint is idle. + if ((buffer == NULL) && (total_bytes == 0)) { + buffer = (uint8_t *)0xffffffff; + } + + TU_ASSERT(buffer != NULL); + + if (ep_dir == TUSB_DIR_IN) { + // Wait for the tx pipe to free up + uint8_t previous_reset_count = reset_count; + // Continue until the buffer is empty, the system is idle, and the fifo is empty. + while (tx_buffer[ep_num] != NULL) + ; + + dcd_int_disable(0); +#if LOG_USB + queue_log_append(ep_addr, total_bytes); +#endif + // If a reset happens while we're waiting, abort the transfer + if (previous_reset_count != reset_count) + return true; + + TU_ASSERT(tx_buffer[ep_num] == NULL); + tx_buffer_offset[ep_num] = 0; + tx_buffer_max[ep_num] = total_bytes; + tx_buffer[ep_num] = buffer; + + // If the current buffer is NULL, then that means the tx logic is idle. + // Update the tx_ep to point to our endpoint number and queue the data. + // Otherwise, let it be and it'll get picked up after the next transfer + // finishes. + if (!tx_active) { + tx_ep = ep_num; + tx_active = true; + tx_more_data(); + } + dcd_int_enable(0); + } + + else if (ep_dir == TUSB_DIR_OUT) { + while (rx_buffer[ep_num] != NULL) + ; + + TU_ASSERT(rx_buffer[ep_num] == NULL); + dcd_int_disable(0); +#if LOG_USB + queue_log_append(ep_addr, total_bytes); +#endif + rx_buffer[ep_num] = buffer; + rx_buffer_offset[ep_num] = 0; + rx_buffer_max[ep_num] = total_bytes; + + // Enable receiving on this particular endpoint + usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | ep_num); +#if DEBUG + uint16_t ep_en_mask = usb_out_enable_status_read(); + int i; + for (i = 0; i < 16; i++) { + if ((!!(ep_en_mask & (1 << i))) ^ (!!(rx_buffer[i]))) { + if (rx_buffer[i] && usb_out_ev_pending_read() && (usb_out_status_read() & 0xf) == i) + continue; + fomu_error(__LINE__); + } + } +#endif + dcd_int_enable(0); + } + return true; +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ + +static void handle_out(void) +{ + // An "OUT" transaction just completed so we have new data. + // (But only if we can accept the data) +#if DEBUG + if (!usb_out_ev_pending_read()) + fomu_error(__LINE__); + if (!usb_out_ev_enable_read()) + fomu_error(__LINE__); +#endif + process_rx(); +} + +static void handle_in(void) +{ +#if DEBUG + if (!usb_in_ev_pending_read()) + fomu_error(__LINE__); + if (!usb_in_ev_enable_read()) + fomu_error(__LINE__); +#endif + usb_in_ev_pending_write(usb_in_ev_pending_read()); + process_tx(); +} + +static void handle_reset(void) +{ +#if DEBUG + uint8_t setup_pending = usb_setup_ev_pending_read() & usb_setup_ev_enable_read(); + if (!(setup_pending & 2)) + fomu_error(__LINE__); +#endif + usb_setup_ev_pending_write(2); + + // This event means a bus reset occurred. Reset everything, and + // abandon any further processing. + dcd_reset(); +} + +static void handle_setup(void) +{ +#if !DEBUG + uint8_t setup_packet_bfr[10]; +#endif + +#if DEBUG + uint8_t setup_pending = usb_setup_ev_pending_read() & usb_setup_ev_enable_read(); + if (!(setup_pending & 1)) + fomu_error(__LINE__); +#endif + + // We got a SETUP packet. Copy it to the setup buffer and clear + // the "pending" bit. + // Setup packets are always 8 bytes, plus two bytes of crc16. + uint32_t setup_length = 0; + +#if DEBUG + if (!(usb_setup_status_read() & (1 << CSR_USB_SETUP_STATUS_HAVE_OFFSET))) + fomu_error(__LINE__); +#endif + + while (usb_setup_status_read() & (1 << CSR_USB_SETUP_STATUS_HAVE_OFFSET)) { + uint8_t c = usb_setup_data_read(); + if (setup_length < sizeof(setup_packet_bfr)) + setup_packet_bfr[setup_length] = c; + setup_length++; + } + + // If we have 10 bytes, that's a full SETUP packet plus CRC16. + // Otherwise, it was an RX error. + if (setup_length == 10) { + dcd_event_setup_received(0, setup_packet_bfr, true); + } +#if DEBUG + else { + fomu_error(__LINE__); + } +#endif + + usb_setup_ev_pending_write(1); +} +void hal_dcd_isr(uint8_t rhport) +{ + (void)rhport; + uint8_t next_ev; + while ((next_ev = usb_next_ev_read())) { + switch (next_ev) { + case 1 << CSR_USB_NEXT_EV_IN_OFFSET: + handle_in(); + break; + case 1 << CSR_USB_NEXT_EV_OUT_OFFSET: + handle_out(); + break; + case 1 << CSR_USB_NEXT_EV_SETUP_OFFSET: + handle_setup(); + break; + case 1 << CSR_USB_NEXT_EV_RESET_OFFSET: + handle_reset(); + break; + } + } +} + +#endif diff --git a/src/portable/nxp/lpc18_43/hal_lpc18_43.c b/src/portable/valentyusb/eptri/dcd_eptri.h similarity index 68% rename from src/portable/nxp/lpc18_43/hal_lpc18_43.c rename to src/portable/valentyusb/eptri/dcd_eptri.h index 3f4e9c23d..0fa6ecc64 100644 --- a/src/portable/nxp/lpc18_43/hal_lpc18_43.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.h @@ -24,39 +24,16 @@ * This file is part of the TinyUSB stack. */ -#include "tusb.h" +#ifndef _TUSB_DCD_VALENTYUSB_EPTRI_H_ +#define _TUSB_DCD_VALENTYUSB_EPTRI_H_ -#if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX) - -#include "chip.h" - -extern void hal_dcd_isr(uint8_t rhport); -extern void hal_hcd_isr(uint8_t hostid); - -#if CFG_TUSB_RHPORT0_MODE -void USB0_IRQHandler(void) -{ - #if TUSB_OPT_HOST_ENABLED - hal_hcd_isr(0); - #endif - - #if TUSB_OPT_DEVICE_ENABLED - hal_dcd_isr(0); - #endif -} +#include "common/tusb_common.h" +#ifdef __cplusplus + extern "C" { #endif -#if CFG_TUSB_RHPORT1_MODE -void USB1_IRQHandler(void) -{ - #if TUSB_OPT_HOST_ENABLED - hal_hcd_isr(1); - #endif - - #if TUSB_OPT_DEVICE_ENABLED - hal_dcd_isr(1); - #endif -} +#ifdef __cplusplus + } #endif -#endif +#endif /* _TUSB_DCD_VALENTYUSB_EPTRI_H_ */ diff --git a/src/portable/valentyusb/eptri/hal_eptri.c b/src/portable/valentyusb/eptri/hal_eptri.c new file mode 100644 index 000000000..72453affa --- /dev/null +++ b/src/portable/valentyusb/eptri/hal_eptri.c @@ -0,0 +1,33 @@ +/* + * 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. + * + * This file is part of the TinyUSB stack. + */ + +#include "common/tusb_common.h" + +#if (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) + +// No HAL-specific stuff here! + +#endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 5700bc8a5..281d44029 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -39,38 +39,42 @@ #define OPT_MCU_NONE 0 // LPC -#define OPT_MCU_LPC11UXX 1 ///< NXP LPC11Uxx -#define OPT_MCU_LPC13XX 2 ///< NXP LPC13xx -#define OPT_MCU_LPC15XX 3 ///< NXP LPC15xx -#define OPT_MCU_LPC175X_6X 4 ///< NXP LPC175x, LPC176x -#define OPT_MCU_LPC177X_8X 5 ///< NXP LPC177x, LPC178x -#define OPT_MCU_LPC18XX 6 ///< NXP LPC18xx -#define OPT_MCU_LPC40XX 7 ///< NXP LPC40xx -#define OPT_MCU_LPC43XX 8 ///< NXP LPC43xx -#define OPT_MCU_LPC51UXX 9 ///< NXP LPC51U6x -#define OPT_MCU_LPC54XXX 10 ///< NXP LPC54xxx -#define OPT_MCU_LPC55XX 11 ///< NXP LPC55xx +#define OPT_MCU_LPC11UXX 1 ///< NXP LPC11Uxx +#define OPT_MCU_LPC13XX 2 ///< NXP LPC13xx +#define OPT_MCU_LPC15XX 3 ///< NXP LPC15xx +#define OPT_MCU_LPC175X_6X 4 ///< NXP LPC175x, LPC176x +#define OPT_MCU_LPC177X_8X 5 ///< NXP LPC177x, LPC178x +#define OPT_MCU_LPC18XX 6 ///< NXP LPC18xx +#define OPT_MCU_LPC40XX 7 ///< NXP LPC40xx +#define OPT_MCU_LPC43XX 8 ///< NXP LPC43xx +#define OPT_MCU_LPC51UXX 9 ///< NXP LPC51U6x +#define OPT_MCU_LPC54XXX 10 ///< NXP LPC54xxx +#define OPT_MCU_LPC55XX 11 ///< NXP LPC55xx // NRF -#define OPT_MCU_NRF5X 100 ///< Nordic nRF5x series +#define OPT_MCU_NRF5X 100 ///< Nordic nRF5x series // SAM -#define OPT_MCU_SAMD21 200 ///< MicroChip SAMD21 -#define OPT_MCU_SAMD51 201 ///< MicroChip SAMD51 +#define OPT_MCU_SAMD21 200 ///< MicroChip SAMD21 +#define OPT_MCU_SAMD51 201 ///< MicroChip SAMD51 // STM32 -#define OPT_MCU_STM32F0 300 ///< ST STM32F0 -#define OPT_MCU_STM32F1 301 ///< ST STM32F1 -#define OPT_MCU_STM32F2 302 ///< ST STM32F2 -#define OPT_MCU_STM32F3 303 ///< ST STM32F3 -#define OPT_MCU_STM32F4 304 ///< ST STM32F4 -#define OPT_MCU_STM32F7 305 ///< ST STM32F7 -#define OPT_MCU_STM32H7 306 ///< ST STM32H7 -#define OPT_MCU_STM32L0 307 ///< ST STM32L0 -#define OPT_MCU_STM32L1 308 ///< ST STM32L1 -#define OPT_MCU_STM32L4 309 ///< ST STM32L4 +#define OPT_MCU_STM32F0 300 ///< ST STM32F0 +#define OPT_MCU_STM32F1 301 ///< ST STM32F1 +#define OPT_MCU_STM32F2 302 ///< ST STM32F2 +#define OPT_MCU_STM32F3 303 ///< ST STM32F3 +#define OPT_MCU_STM32F4 304 ///< ST STM32F4 +#define OPT_MCU_STM32F7 305 ///< ST STM32F7 +#define OPT_MCU_STM32H7 306 ///< ST STM32H7 +#define OPT_MCU_STM32L0 307 ///< ST STM32L0 +#define OPT_MCU_STM32L1 308 ///< ST STM32L1 +#define OPT_MCU_STM32L4 309 ///< ST STM32L4 -#define OPT_MCU_CXD56 400 ///< SONY CXD56 +#define OPT_MCU_CXD56 400 ///< SONY CXD56 + +#define OPT_MCU_VALENTYUSB_EPTRI 600 ///< Fomu eptri config + +#define OPT_MCU_MIMXRT10XX 700 ///< NXP iMX RT10xx /** @} */ diff --git a/test/project.yml b/test/project.yml index 8ceaf63ce..dc4a9cb28 100644 --- a/test/project.yml +++ b/test/project.yml @@ -7,6 +7,7 @@ :project: :use_exceptions: TRUE + :use_mocks: TRUE :use_test_preprocessor: TRUE :use_auxiliary_dependencies: TRUE :use_deep_dependencies: TRUE @@ -17,6 +18,9 @@ :default_tasks: - test:all +#:test_build: +# :use_assembly: TRUE + #:release_build: # :output: MyApp.out # :use_assembly: FALSE @@ -39,13 +43,12 @@ # in order to add common defines: # 1) remove the trailing [] from the :common: section # 2) add entries to the :common: section (e.g. :test: has TEST defined) - :commmon: &common_defines [] + :common: &common_defines + - _UNITY_TEST_ :test: - *common_defines - - _TEST_ :test_preprocess: - *common_defines - - _TEST_ :cmock: :mock_prefix: mock_ @@ -53,6 +56,8 @@ :enforce_strict_ordering: TRUE :plugins: - :ignore + - :ignore_arg + - :return_thru_ptr - :callback - :array :treat_as: @@ -62,8 +67,15 @@ int8: INT8 bool: UINT8 +# Add -gcov to the plugins list to make sure of the gcov plugin +# You will need to have gcov and gcovr both installed to make it work. +# For more information on these options, see docs in plugins/gcov :gcov: - :html_report_type: basic + :html_report: TRUE + :html_report_type: detailed + :html_medium_threshold: 75 + :html_high_threshold: 90 + :xml_report: FALSE #:tools: # Ceedling defaults to using gcc for compiling, linking, etc. @@ -90,4 +102,5 @@ - stdout_pretty_tests_report - module_generator - raw_output_report + - colour_report ... diff --git a/test/test/device/msc/test_msc_device.c b/test/test/device/msc/test_msc_device.c new file mode 100644 index 000000000..5003ac839 --- /dev/null +++ b/test/test/device/msc/test_msc_device.c @@ -0,0 +1,273 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019, hathach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + + +#include "unity.h" + +// Files to test +#include "tusb_fifo.h" +#include "tusb.h" +#include "usbd.h" +TEST_FILE("usbd_control.c") +TEST_FILE("msc_device.c") + +// Mock File +#include "mock_dcd.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +enum +{ + EDPT_CTRL_OUT = 0x00, + EDPT_CTRL_IN = 0x80, + + EDPT_MSC_OUT = 0x01, + EDPT_MSC_IN = 0x81, +}; + +uint8_t const rhport = 0; + +enum +{ + ITF_NUM_MSC, + ITF_NUM_TOTAL +}; + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN) + +uint8_t const data_desc_configuration[] = +{ + // Interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EDPT_MSC_OUT, EDPT_MSC_IN, (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64), +}; + +tusb_control_request_t const request_set_configuration = +{ + .bmRequestType = 0x00, + .bRequest = TUSB_REQ_SET_CONFIGURATION, + .wValue = 1, + .wIndex = 0, + .wLength = 0 +}; + +uint8_t const* desc_configuration; + + +enum +{ + DISK_BLOCK_NUM = 16, // 8KB is the smallest size that windows allow to mount + DISK_BLOCK_SIZE = 512 +}; + +uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE]; + +// Invoked when received SCSI_CMD_INQUIRY +// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively +void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) +{ + (void) lun; + + const char vid[] = "TinyUSB"; + const char pid[] = "Mass Storage"; + const char rev[] = "1.0"; + + memcpy(vendor_id , vid, strlen(vid)); + memcpy(product_id , pid, strlen(pid)); + memcpy(product_rev, rev, strlen(rev)); +} + +// Invoked when received Test Unit Ready command. +// return true allowing host to read/write this LUN e.g SD card inserted +bool tud_msc_test_unit_ready_cb(uint8_t lun) +{ + (void) lun; + + return true; // RAM disk is always ready +} + +// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size +// Application update block count and block size +void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) +{ + (void) lun; + + *block_count = DISK_BLOCK_NUM; + *block_size = DISK_BLOCK_SIZE; +} + +// Invoked when received Start Stop Unit command +// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage +// - Start = 1 : active mode, if load_eject = 1 : load disk storage +bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) +{ + (void) lun; + (void) power_condition; + + return true; +} + +// Callback invoked when received READ10 command. +// Copy disk's data to buffer (up to bufsize) and return number of copied bytes. +int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) +{ + (void) lun; + + uint8_t const* addr = msc_disk[lba] + offset; + memcpy(buffer, addr, bufsize); + + return bufsize; +} + +// Callback invoked when received WRITE10 command. +// Process data in buffer to disk's storage and return number of written bytes +int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) +{ + (void) lun; + + uint8_t* addr = msc_disk[lba] + offset; + memcpy(addr, buffer, bufsize); + + return bufsize; +} + +// Callback invoked when received an SCSI command not in built-in list below +// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE +// - READ10 and WRITE10 has their own callbacks +int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) +{ + // read10 & write10 has their own callback and MUST not be handled here + + void const* response = NULL; + uint16_t resplen = 0; + + return resplen; +} + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ +uint8_t const * tud_descriptor_device_cb(void) +{ + return NULL; +} + +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + return desc_configuration; +} + +uint16_t const* tud_descriptor_string_cb(uint8_t index) +{ + return NULL; +} + +void setUp(void) +{ + dcd_int_disable_Ignore(); + dcd_int_enable_Ignore(); + + if ( !tusb_inited() ) + { + dcd_init_Expect(rhport); + tusb_init(); + } + + dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, false); + tud_task(); +} + +void tearDown(void) +{ +} + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ +void test_msc(void) +{ + // Read 1 LBA = 0, Block count = 1 + msc_cbw_t cbw_read10 = + { + .signature = MSC_CBW_SIGNATURE, + .tag = 0xCAFECAFE, + .total_bytes = 512, + .lun = 0, + .dir = TUSB_DIR_IN_MASK, + .cmd_len = sizeof(scsi_read10_t) + }; + + scsi_read10_t cmd_read10 = + { + .cmd_code = SCSI_CMD_READ_10, + .lba = tu_htonl(0), + .block_count = tu_htons(1) + }; + + memcpy(cbw_read10.command, &cmd_read10, cbw_read10.cmd_len); + + desc_configuration = data_desc_configuration; + uint8_t const* desc_ep = tu_desc_next(tu_desc_next(desc_configuration)); + + dcd_event_setup_received(rhport, (uint8_t*) &request_set_configuration, false); + + dcd_set_config_Expect(rhport, 1); + + // open endpoints + dcd_edpt_open_ExpectAndReturn(rhport, (tusb_desc_endpoint_t const *) desc_ep, true); + dcd_edpt_open_ExpectAndReturn(rhport, (tusb_desc_endpoint_t const *) tu_desc_next(desc_ep), true); + + // Prepare SCSI command + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_OUT, NULL, sizeof(msc_cbw_t), true); + dcd_edpt_xfer_IgnoreArg_buffer(); + dcd_edpt_xfer_ReturnMemThruPtr_buffer( (uint8_t*) &cbw_read10, sizeof(msc_cbw_t)); + + // command received + dcd_event_xfer_complete(rhport, EDPT_MSC_OUT, sizeof(msc_cbw_t), 0, true); + + // control status + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_IN, NULL, 0, true); + + // SCSI Data transfer + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_IN, NULL, 512, true); + dcd_edpt_xfer_IgnoreArg_buffer(); + dcd_event_xfer_complete(rhport, EDPT_MSC_IN, 512, 0, true); // complete + + // SCSI Status + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_IN, NULL, 13, true); + dcd_edpt_xfer_IgnoreArg_buffer(); + dcd_event_xfer_complete(rhport, EDPT_MSC_IN, 13, 0, true); + + // Prepare for next command + dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_MSC_OUT, NULL, sizeof(msc_cbw_t), true); + dcd_edpt_xfer_IgnoreArg_buffer(); + + tud_task(); +} diff --git a/test/test/device/usbd/test_usbd.c b/test/test/device/usbd/test_usbd.c index c1139d3cc..c59d94c2c 100644 --- a/test/test/device/usbd/test_usbd.c +++ b/test/test/device/usbd/test_usbd.c @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019, hathach (tinyusb.org) + * 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 @@ -20,11 +20,8 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. */ - #include "unity.h" // Files to test @@ -32,10 +29,10 @@ #include "tusb.h" #include "usbd.h" TEST_FILE("usbd_control.c") -//TEST_FILE("usb_descriptors.c") // Mock File #include "mock_dcd.h" +#include "mock_msc_device.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION @@ -126,6 +123,7 @@ void setUp(void) if ( !tusb_inited() ) { + mscd_init_Expect(); dcd_init_Expect(rhport); tusb_init(); } diff --git a/test/test/support/tusb_config.h b/test/test/support/tusb_config.h index 0a1608a64..5e7b70e0d 100644 --- a/test/test/support/tusb_config.h +++ b/test/test/support/tusb_config.h @@ -26,6 +26,9 @@ #ifndef _TUSB_CONFIG_H_ #define _TUSB_CONFIG_H_ +// testing framework +#include "unity.h" + #ifdef __cplusplus extern "C" { #endif @@ -40,7 +43,7 @@ #define CFG_TUSB_MCU OPT_MCU_NRF5X #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE @@ -75,7 +78,7 @@ //------------- CLASS -------------// //#define CFG_TUD_CDC 0 -//#define CFG_TUD_MSC 0 +#define CFG_TUD_MSC 1 //#define CFG_TUD_HID 0 //#define CFG_TUD_MIDI 0 //#define CFG_TUD_VENDOR 0 diff --git a/test/vendor/ceedling/bin/ceedling b/test/vendor/ceedling/bin/ceedling index 20943f664..fa099590a 100644 --- a/test/vendor/ceedling/bin/ceedling +++ b/test/vendor/ceedling/bin/ceedling @@ -31,95 +31,111 @@ unless (project_found) include Thor::Actions desc "new PROJECT_NAME", "create a new ceedling project" - method_option :no_docs, :type => :boolean, :default => false, :desc => "No docs in vendor directory" - method_option :nodocs, :type => :boolean, :default => false - method_option :as_gem, :type => :boolean, :default => false, :desc => "Create the scaffold using Ceedling as a gem instead of filling in the vendor directory. Implies --no-docs." - method_option :asgem, :type => :boolean, :default => false - method_option :with_ignore, :type => :boolean, :default => false, :desc => "Create a gitignore file for ignoring ceedling generated files." - method_option :withignore, :type => :boolean, :default => false - method_option :no_configs, :type => :boolean, :default => false, :desc => "Don't install starter configuration files." + method_option :docs, :type => :boolean, :default => false, :desc => "Add docs in project vendor directory" + method_option :local, :type => :boolean, :default => false, :desc => "Create a copy of Ceedling in the project vendor directory" + method_option :gitignore, :type => :boolean, :default => false, :desc => "Create a gitignore file for ignoring ceedling generated files" + method_option :no_configs, :type => :boolean, :default => false, :desc => "Don't install starter configuration files" method_option :noconfigs, :type => :boolean, :default => false + + #deprecated: + method_option :no_docs, :type => :boolean, :default => false + method_option :nodocs, :type => :boolean, :default => false + method_option :as_gem, :type => :boolean, :default => false + method_option :asgem, :type => :boolean, :default => false + method_option :with_ignore, :type => :boolean, :default => false + method_option :withignore, :type => :boolean, :default => false def new(name, silent = false) copy_assets_and_create_structure(name, silent, false, options) end desc "upgrade PROJECT_NAME", "upgrade ceedling for a project (not req'd if gem used)" - method_option :no_docs, :type => :boolean, :default => false, :desc => "No docs in vendor directory" - method_option :nodocs, :type => :boolean, :default => false - method_option :no_configs, :type => :boolean, :default => true, :desc => "Don't install starter configuration files." + method_option :docs, :type => :boolean, :default => false, :desc => "Add docs in project vendor directory" + method_option :local, :type => :boolean, :default => false, :desc => "Create a copy of Ceedling in the project vendor directory" + method_option :no_configs, :type => :boolean, :default => false, :desc => "Don't install starter configuration files" method_option :noconfigs, :type => :boolean, :default => false + + #deprecated: + method_option :no_docs, :type => :boolean, :default => false + method_option :nodocs, :type => :boolean, :default => false def upgrade(name, silent = false) - copy_assets_and_create_structure(name, silent, true, options) + copy_assets_and_create_structure(name, silent, true, options || {:upgrade => true}) end no_commands do def copy_assets_and_create_structure(name, silent=false, force=false, options = {}) - no_docs = options[:no_docs] || options[:nodocs] || false - no_configs = options[:no_configs] || options[:noconfigs] || false - as_gem = options[:as_gem] || options[:asgem] || false - with_ignore = options[:with_ignore] || options[:withignore] || false + puts "WARNING: --no_docs deprecated. It is now the default. Specify -docs if you want docs installed." if (options[:no_docs] || options[:nodocs]) + puts "WARNING: --as_gem deprecated. It is now the default. Specify -local if you want ceedling installed to this project." if (options[:as_gem] || options[:asgem]) + puts "WARNING: --with_ignore deprecated. It is now called -gitignore" if (options[:with_ignore] || options[:with_ignore]) + + use_docs = options[:docs] || false + use_configs = !(options[:no_configs] || options[:noconfigs] || false) + use_gem = !(options[:local]) + use_ignore = options[:gitignore] || false + is_upgrade = options[:upgrade] || false ceedling_path = File.join(name, 'vendor', 'ceedling') source_path = File.join(name, 'src') test_path = File.join(name, 'test') test_support_path = File.join(name, 'test/support') - [source_path, test_path, test_support_path].each do |d| - FileUtils.mkdir_p d + # If it's not an upgrade, make sure we have the paths we expect + if (!is_upgrade) + [source_path, test_path, test_support_path].each do |d| + FileUtils.mkdir_p d + end end - unless as_gem + # Genarate gitkeep in test support path + FileUtils.touch(File.join(test_support_path, '.gitkeep')) + + # If documentation requested, create a place to dump them and do so + if use_docs + doc_path = File.join(ceedling_path, 'docs') + FileUtils.mkdir_p doc_path + + in_doc_path = lambda {|f| File.join(doc_path, f)} + + doc_files = [ + 'docs/CeedlingPacket.md', + 'vendor/c_exception/docs/CException.md', + 'vendor/cmock/docs/CMock_Summary.md', + 'vendor/unity/docs/UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf', + 'vendor/unity/docs/UnityAssertionsReference.md', + 'vendor/unity/docs/UnityConfigurationGuide.md', + 'vendor/unity/docs/UnityGettingStartedGuide.md', + 'vendor/unity/docs/UnityHelperScriptsGuide.md', + 'vendor/unity/docs/ThrowTheSwitchCodingStandard.md', + ] + + doc_files.each do |f| + copy_file(f, in_doc_path.call(File.basename(f)), :force => force) + end + end + + # If installed locally to project, copy ceedling, unity, cmock, & supports to vendor + unless use_gem FileUtils.mkdir_p ceedling_path - unless no_docs - doc_path = File.join(ceedling_path, 'docs') - FileUtils.mkdir_p doc_path - - in_doc_path = lambda {|f| File.join(doc_path, f)} - - doc_files = [ - 'docs/CeedlingPacket.md', - 'vendor/c_exception/docs/CException.md', - 'vendor/cmock/docs/CMock_Summary.md', - 'vendor/unity/docs/UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf', - 'vendor/unity/docs/UnityAssertionsReference.md', - 'vendor/unity/docs/UnityConfigurationGuide.md', - 'vendor/unity/docs/UnityGettingStartedGuide.md', - 'vendor/unity/docs/UnityHelperScriptsGuide.md', - 'vendor/unity/docs/ThrowTheSwitchCodingStandard.md', - ] - - doc_files.each do |f| - copy_file(f, in_doc_path.call(File.basename(f)), :force => force) - end - end - - folders = if as_gem - %w{plugins lib} - else - %w{plugins lib bin} - end - #copy full folders from ceedling gem into project - folders.map do |f| + %w{plugins lib bin}.map do |f| {:src => f, :dst => File.join(ceedling_path, f)} end.each do |f| directory(f[:src], f[:dst], :force => force) end + # mark ceedling as an executable + File.chmod(0755, File.join(ceedling_path, 'bin', 'ceedling')) unless is_windows? + #copy necessary subcomponents from ceedling gem into project sub_components = [ {:src => 'vendor/c_exception/lib/', :dst => 'vendor/c_exception/lib'}, - {:src => 'vendor/c_exception/release/', :dst => 'vendor/c_exception/release'}, {:src => 'vendor/cmock/config/', :dst => 'vendor/cmock/config'}, {:src => 'vendor/cmock/lib/', :dst => 'vendor/cmock/lib'}, - {:src => 'vendor/cmock/release/', :dst => 'vendor/cmock/release'}, {:src => 'vendor/cmock/src/', :dst => 'vendor/cmock/src'}, {:src => 'vendor/deep_merge/lib/', :dst => 'vendor/deep_merge/lib'}, {:src => 'vendor/diy/lib', :dst => 'vendor/diy/lib'}, {:src => 'vendor/unity/auto/', :dst => 'vendor/unity/auto'}, - {:src => 'vendor/unity/release/', :dst => 'vendor/unity/release'}, {:src => 'vendor/unity/src/', :dst => 'vendor/unity/src'}, ] @@ -128,8 +144,9 @@ unless (project_found) end end - unless (no_configs) - if as_gem + # We're copying in a configuration file if we haven't said not to + if (use_configs) + if use_gem copy_file(File.join('assets', 'project_as_gem.yml'), File.join(name, 'project.yml'), :force => force) else copy_file(File.join('assets', 'project_with_guts.yml'), File.join(name, 'project.yml'), :force => force) @@ -137,18 +154,20 @@ unless (project_found) copy_file(File.join('assets', 'ceedling.cmd'), File.join(name, 'ceedling.cmd'), :force => force) else copy_file(File.join('assets', 'ceedling'), File.join(name, 'ceedling'), :force => force) + File.chmod(0755, File.join(name, 'ceedling')) end end end - if (with_ignore) + # Copy the gitignore file if requested + if (use_ignore) copy_file(File.join('assets', 'default_gitignore'), File.join(name, '.gitignore'), :force => force) end unless silent puts "\n" puts "Project '#{name}' #{force ? "upgraded" : "created"}!" - puts " - Tool documentation is located in vendor/ceedling/docs" if (not no_docs) and (not as_gem) + puts " - Tool documentation is located in vendor/ceedling/docs" if use_docs puts " - Execute 'ceedling help' to view available test & build tasks" puts '' end @@ -167,7 +186,7 @@ unless (project_found) def example(proj_name, dest=nil) if dest.nil? then dest = proj_name end - invoke :new, [dest, true] + copy_assets_and_create_structure(dest, true, false, {:local=>true, :docs=>true}) dest_src = File.join(dest,'src') dest_test = File.join(dest,'test') @@ -266,6 +285,8 @@ else abort when /^help$/ options[:list_tasks] = true + when /^-T$/ + options[:list_tasks] = true when /^project:(\w+)/ ENV['CEEDLING_USER_PROJECT_FILE'] = "#{$1}.yml" else diff --git a/test/vendor/ceedling/lib/ceedling/cacheinator.rb b/test/vendor/ceedling/lib/ceedling/cacheinator.rb index 47953dd99..519a4aab4 100644 --- a/test/vendor/ceedling/lib/ceedling/cacheinator.rb +++ b/test/vendor/ceedling/lib/ceedling/cacheinator.rb @@ -26,16 +26,21 @@ class Cacheinator return cached_filepath end - def diff_cached_test_config?(hash) cached_filepath = @file_path_utils.form_test_build_cache_path(INPUT_CONFIGURATION_CACHE_FILE) - + return @cacheinator_helper.diff_cached_config?( cached_filepath, hash ) end + def diff_cached_test_defines?(files) + cached_filepath = @file_path_utils.form_test_build_cache_path(DEFINES_DEPENDENCY_CACHE_FILE) + + return @cacheinator_helper.diff_cached_defines?( cached_filepath, files ) + end + def diff_cached_release_config?(hash) cached_filepath = @file_path_utils.form_release_build_cache_path(INPUT_CONFIGURATION_CACHE_FILE) - + return @cacheinator_helper.diff_cached_config?( cached_filepath, hash ) end diff --git a/test/vendor/ceedling/lib/ceedling/cacheinator_helper.rb b/test/vendor/ceedling/lib/ceedling/cacheinator_helper.rb index cb0ef7813..2a161854b 100644 --- a/test/vendor/ceedling/lib/ceedling/cacheinator_helper.rb +++ b/test/vendor/ceedling/lib/ceedling/cacheinator_helper.rb @@ -8,5 +8,24 @@ class CacheinatorHelper return true if ( (@file_wrapper.exist?(cached_filepath)) and (!(@yaml_wrapper.load(cached_filepath) == hash)) ) return false end - + + def diff_cached_defines?(cached_filepath, files) + current_defines = COLLECTION_DEFINES_TEST_AND_VENDOR.reject(&:empty?) + + current_dependency = Hash[files.collect { |source| [source, current_defines.dup] }] + if not @file_wrapper.exist?(cached_filepath) + @yaml_wrapper.dump(cached_filepath, current_dependency) + return false + end + + dependencies = @yaml_wrapper.load(cached_filepath) + if dependencies.values_at(*current_dependency.keys) != current_dependency.values + dependencies.merge!(current_dependency) + @yaml_wrapper.dump(cached_filepath, dependencies) + return true + end + + return false + end + end diff --git a/test/vendor/ceedling/lib/ceedling/configurator.rb b/test/vendor/ceedling/lib/ceedling/configurator.rb index 672609b3b..b5ad8982e 100644 --- a/test/vendor/ceedling/lib/ceedling/configurator.rb +++ b/test/vendor/ceedling/lib/ceedling/configurator.rb @@ -64,6 +64,8 @@ class Configurator end + # The default values defined in defaults.rb (eg. DEFAULT_TOOLS_TEST) are populated + # into @param config def populate_defaults(config) new_config = DEFAULT_CEEDLING_CONFIG.deep_clone new_config.deep_merge!(config) @@ -184,7 +186,8 @@ class Configurator plugin_defaults = @configurator_plugins.find_plugin_defaults(config, paths_hash) config_plugins.each do |plugin| - config.deep_merge!( @yaml_wrapper.load(plugin) ) + plugin_config = @yaml_wrapper.load(plugin) + config.deep_merge(plugin_config) end plugin_defaults.each do |defaults| @@ -346,6 +349,10 @@ class Configurator end def eval_path_list( paths ) + if paths.kind_of?(Array) + paths = Array.new(paths) + end + paths.flatten.each do |path| path.replace( @system_wrapper.module_eval( path ) ) if (path =~ RUBY_STRING_REPLACEMENT_PATTERN) end diff --git a/test/vendor/ceedling/lib/ceedling/configurator_builder.rb b/test/vendor/ceedling/lib/ceedling/configurator_builder.rb index cd7d3eb8b..da8a816f5 100644 --- a/test/vendor/ceedling/lib/ceedling/configurator_builder.rb +++ b/test/vendor/ceedling/lib/ceedling/configurator_builder.rb @@ -274,10 +274,17 @@ class ConfiguratorBuilder return {:collection_all_assembly => all_assembly} if ((not in_hash[:release_build_use_assembly]) && (not in_hash[:test_build_use_assembly])) + # Sprinkle in all assembly files we can find in the source folders in_hash[:collection_paths_source].each do |path| all_assembly.include( File.join(path, "*#{in_hash[:extension_assembly]}") ) end + # Also add all assembly files we can find in the support folders + in_hash[:collection_paths_support].each do |path| + all_assembly.include( File.join(path, "*#{in_hash[:extension_assembly]}") ) + end + + # Also add files that we are explicitly adding via :files:assembly: section @file_system_utils.revise_file_list( all_assembly, in_hash[:files_assembly] ) return {:collection_all_assembly => all_assembly} diff --git a/test/vendor/ceedling/lib/ceedling/constants.rb b/test/vendor/ceedling/lib/ceedling/constants.rb index 5df68368b..993ce8db2 100644 --- a/test/vendor/ceedling/lib/ceedling/constants.rb +++ b/test/vendor/ceedling/lib/ceedling/constants.rb @@ -63,7 +63,7 @@ DEFAULT_CEEDLING_MAIN_PROJECT_FILE = 'project.yml' unless defined?(DEFAULT_CEEDL DEFAULT_CEEDLING_USER_PROJECT_FILE = 'user.yml' unless defined?(DEFAULT_CEEDLING_USER_PROJECT_FILE) # supplemental user config file INPUT_CONFIGURATION_CACHE_FILE = 'input.yml' unless defined?(INPUT_CONFIGURATION_CACHE_FILE) # input configuration file dump - +DEFINES_DEPENDENCY_CACHE_FILE = 'defines_dependency.yml' unless defined?(DEFINES_DEPENDENCY_CACHE_FILE) # preprocessor definitions for files TEST_ROOT_NAME = 'test' unless defined?(TEST_ROOT_NAME) TEST_TASK_ROOT = TEST_ROOT_NAME + ':' unless defined?(TEST_TASK_ROOT) diff --git a/test/vendor/ceedling/lib/ceedling/dependinator.rb b/test/vendor/ceedling/lib/ceedling/dependinator.rb index dd6b92737..ebd123772 100644 --- a/test/vendor/ceedling/lib/ceedling/dependinator.rb +++ b/test/vendor/ceedling/lib/ceedling/dependinator.rb @@ -38,20 +38,23 @@ class Dependinator def enhance_runner_dependencies(runner_filepath) - @rake_wrapper[runner_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed) + @rake_wrapper[runner_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) end def enhance_shallow_include_lists_dependencies(include_lists) include_lists.each do |include_list_filepath| - @rake_wrapper[include_list_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed) + @rake_wrapper[include_list_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) end end def enhance_preprocesed_file_dependencies(files) files.each do |filepath| - @rake_wrapper[filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed) + @rake_wrapper[filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) end end @@ -59,7 +62,8 @@ class Dependinator def enhance_mock_dependencies(mocks_list) # if input configuration or ceedling changes, make sure these guys get rebuilt mocks_list.each do |mock_filepath| - @rake_wrapper[mock_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed) + @rake_wrapper[mock_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) @rake_wrapper[mock_filepath].enhance( @configurator.cmock_unity_helper ) if (@configurator.cmock_unity_helper) end end @@ -67,25 +71,28 @@ class Dependinator def enhance_dependencies_dependencies(dependencies) dependencies.each do |dependencies_filepath| - @rake_wrapper[dependencies_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed) + @rake_wrapper[dependencies_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) end end def enhance_test_build_object_dependencies(objects) objects.each do |object_filepath| - @rake_wrapper[object_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed) + @rake_wrapper[object_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) end end def enhance_results_dependencies(result_filepath) - @rake_wrapper[result_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed) + @rake_wrapper[result_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed || + @project_config_manager.test_defines_changed) end def setup_test_executable_dependencies(test, objects) - @rake_wrapper.create_file_task( @file_path_utils.form_test_executable_filepath(test), objects) + @rake_wrapper.create_file_task( @file_path_utils.form_test_executable_filepath(test), objects ) end end diff --git a/test/vendor/ceedling/lib/ceedling/generator.rb b/test/vendor/ceedling/lib/ceedling/generator.rb index a2c94ec5e..828a0c025 100644 --- a/test/vendor/ceedling/lib/ceedling/generator.rb +++ b/test/vendor/ceedling/lib/ceedling/generator.rb @@ -19,6 +19,7 @@ class Generator def generate_shallow_includes_list(context, file) + @streaminator.stdout_puts("Generating include list for #{File.basename(file)}...", Verbosity::NORMAL) @preprocessinator.preprocess_shallow_includes(file) end @@ -92,6 +93,8 @@ class Generator arg_hash[:list], arg_hash[:dependencies]) + @streaminator.stdout_puts("Command: #{command}", Verbosity::DEBUG) + begin shell_result = @tool_executor.exec( command[:line], command[:options] ) rescue ShellExecutionException => ex @@ -124,6 +127,7 @@ class Generator arg_hash[:map], arg_hash[:libraries] ) + @streaminator.stdout_puts("Command: #{command}", Verbosity::DEBUG) begin shell_result = @tool_executor.exec( command[:line], command[:options] ) @@ -157,9 +161,12 @@ class Generator # Unity's exit code is equivalent to the number of failed tests, so we tell @tool_executor not to fail out if there are failures # so that we can run all tests and collect all results command = @tool_executor.build_command_line(arg_hash[:tool], [], arg_hash[:executable]) + @streaminator.stdout_puts("Command: #{command}", Verbosity::DEBUG) command[:options][:boom] = false shell_result = @tool_executor.exec( command[:line], command[:options] ) - shell_result[:exit_code] = 0 #Don't Let The Failure Count Make Us Believe Things Aren't Working + + #Don't Let The Failure Count Make Us Believe Things Aren't Working + shell_result[:exit_code] = 0 @generator_helper.test_results_error_handler(executable, shell_result) processed = @generator_test_results.process_and_write_results( shell_result, diff --git a/test/vendor/ceedling/lib/ceedling/generator_test_results.rb b/test/vendor/ceedling/lib/ceedling/generator_test_results.rb index 67bfce130..1d0c5201f 100644 --- a/test/vendor/ceedling/lib/ceedling/generator_test_results.rb +++ b/test/vendor/ceedling/lib/ceedling/generator_test_results.rb @@ -7,7 +7,7 @@ class GeneratorTestResults constructor :configurator, :generator_test_results_sanity_checker, :yaml_wrapper def process_and_write_results(unity_shell_result, results_file, test_file) - output_file = results_file + output_file = results_file results = get_results_structure @@ -17,10 +17,10 @@ class GeneratorTestResults # process test statistics if (unity_shell_result[:output] =~ TEST_STDOUT_STATISTICS_PATTERN) - results[:counts][:total] = $1.to_i - results[:counts][:failed] = $2.to_i + results[:counts][:total] = $1.to_i + results[:counts][:failed] = $2.to_i results[:counts][:ignored] = $3.to_i - results[:counts][:passed] = (results[:counts][:total] - results[:counts][:failed] - results[:counts][:ignored]) + results[:counts][:passed] = (results[:counts][:total] - results[:counts][:failed] - results[:counts][:ignored]) end # remove test statistics lines @@ -31,16 +31,16 @@ class GeneratorTestResults case line when /(:IGNORE)/ elements = extract_line_elements(line, results[:source][:file]) - results[:ignores] << elements[0] - results[:stdout] << elements[1] if (!elements[1].nil?) + results[:ignores] << elements[0] + results[:stdout] << elements[1] if (!elements[1].nil?) when /(:PASS$)/ elements = extract_line_elements(line, results[:source][:file]) results[:successes] << elements[0] - results[:stdout] << elements[1] if (!elements[1].nil?) + results[:stdout] << elements[1] if (!elements[1].nil?) when /(:FAIL)/ elements = extract_line_elements(line, results[:source][:file]) - results[:failures] << elements[0] - results[:stdout] << elements[1] if (!elements[1].nil?) + results[:failures] << elements[0] + results[:stdout] << elements[1] if (!elements[1].nil?) else # collect up all other results[:stdout] << line.chomp end diff --git a/test/vendor/ceedling/lib/ceedling/generator_test_runner.rb b/test/vendor/ceedling/lib/ceedling/generator_test_runner.rb index d3f0a92bc..6999faf96 100644 --- a/test/vendor/ceedling/lib/ceedling/generator_test_runner.rb +++ b/test/vendor/ceedling/lib/ceedling/generator_test_runner.rb @@ -15,7 +15,9 @@ class GeneratorTestRunner pre_test_file = @file_path_utils.form_preprocessed_file_filepath(test_file) #actually look for the tests using Unity's test runner generator - tests_and_line_numbers = @test_runner_generator.find_tests(@file_wrapper.read(pre_test_file)) + contents = @file_wrapper.read(pre_test_file) + tests_and_line_numbers = @test_runner_generator.find_tests(contents) + @test_runner_generator.find_setup_and_teardown(contents) #look up the line numbers in the original file source_lines = @file_wrapper.read(test_file).split("\n") @@ -31,7 +33,9 @@ class GeneratorTestRunner end else #Just look for the tests using Unity's test runner generator - tests_and_line_numbers = @test_runner_generator.find_tests(@file_wrapper.read(test_file)) + contents = @file_wrapper.read(test_file) + tests_and_line_numbers = @test_runner_generator.find_tests(contents) + @test_runner_generator.find_setup_and_teardown(contents) end return tests_and_line_numbers diff --git a/test/vendor/ceedling/lib/ceedling/objects.yml b/test/vendor/ceedling/lib/ceedling/objects.yml index a6f189b6c..2e2e9b9d2 100644 --- a/test/vendor/ceedling/lib/ceedling/objects.yml +++ b/test/vendor/ceedling/lib/ceedling/objects.yml @@ -41,7 +41,9 @@ project_file_loader: project_config_manager: compose: - cacheinator + - configurator - yaml_wrapper + - file_wrapper cacheinator: compose: @@ -172,6 +174,7 @@ task_invoker: - dependinator - rake_utils - rake_wrapper + - project_config_manager flaginator: compose: diff --git a/test/vendor/ceedling/lib/ceedling/preprocessinator.rb b/test/vendor/ceedling/lib/ceedling/preprocessinator.rb index e5c46c373..f07750dd2 100644 --- a/test/vendor/ceedling/lib/ceedling/preprocessinator.rb +++ b/test/vendor/ceedling/lib/ceedling/preprocessinator.rb @@ -28,8 +28,7 @@ class Preprocessinator end def preprocess_shallow_includes(filepath) - dependencies_rule = @preprocessinator_includes_handler.form_shallow_dependencies_rule(filepath) - includes = @preprocessinator_includes_handler.extract_shallow_includes(dependencies_rule) + includes = @preprocessinator_includes_handler.extract_includes(filepath) @preprocessinator_includes_handler.write_shallow_includes_list( @file_path_utils.form_preprocessed_includes_list_filepath(filepath), includes) diff --git a/test/vendor/ceedling/lib/ceedling/preprocessinator_includes_handler.rb b/test/vendor/ceedling/lib/ceedling/preprocessinator_includes_handler.rb index 686add0e0..703c84f3c 100644 --- a/test/vendor/ceedling/lib/ceedling/preprocessinator_includes_handler.rb +++ b/test/vendor/ceedling/lib/ceedling/preprocessinator_includes_handler.rb @@ -3,6 +3,7 @@ class PreprocessinatorIncludesHandler constructor :configurator, :tool_executor, :task_invoker, :file_path_utils, :yaml_wrapper, :file_wrapper + @@makefile_cache = {} # shallow includes: only those headers a source file explicitly includes @@ -20,6 +21,9 @@ class PreprocessinatorIncludesHandler # === Return # _String_:: The text of the dependency rule generated by the preprocessor. def form_shallow_dependencies_rule(filepath) + if @@makefile_cache.has_key?(filepath) + return @@makefile_cache[filepath] + end # change filename (prefix of '_') to prevent preprocessor from finding # include files in temp directory containing file it's scanning temp_filepath = @file_path_utils.form_temp_path(filepath, '_') @@ -44,6 +48,7 @@ class PreprocessinatorIncludesHandler command = @tool_executor.build_command_line(@configurator.tools_test_includes_preprocessor, [], temp_filepath) shell_result = @tool_executor.exec(command[:line], command[:options]) + @@makefile_cache[filepath] = shell_result[:output] return shell_result[:output] end @@ -52,19 +57,52 @@ class PreprocessinatorIncludesHandler # provided, annotated Make dependency rule. # # === Arguments - # +make_rule+ _String_:: Annotated Make dependency rule. + # +filepath+ _String_:: C source or header file to extract includes for. # # === Return # _Array_ of _String_:: Array of the direct dependencies for the source file. - def extract_shallow_includes(make_rule) + def extract_includes(filepath) + to_process = [filepath] + ignore_list = [] + list = [] + + include_paths = @configurator.project_config_hash[:collection_paths_include] + include_paths = [] if include_paths.nil? + include_paths.map! {|path| File.expand_path(path)} + + while to_process.length > 0 + target = to_process.shift() + ignore_list << target + # puts "[HELL] Processing: \t\t#{target}" + new_deps, new_to_process = extract_includes_helper(target, include_paths, ignore_list) + list += new_deps + to_process += new_to_process + if (!@configurator.project_config_hash.has_key?(:project_auto_link_deep_dependencies) or + !@configurator.project_config_hash[:project_auto_link_deep_dependencies]) + break + else + list = list.uniq() + to_process = to_process.uniq() + end + end + + return list + end + + def extract_includes_helper(filepath, include_paths, ignore_list) # Extract the dependencies from the make rule hdr_ext = @configurator.extension_header + make_rule = self.form_shallow_dependencies_rule(filepath) dependencies = make_rule.split.find_all {|path| path.end_with?(hdr_ext) }.uniq dependencies.map! {|hdr| hdr.gsub('\\','/') } # Separate the real files form the annotated ones and remove the '@@@@' annotated_headers, real_headers = dependencies.partition {|hdr| hdr =~ /^@@@@/ } annotated_headers.map! {|hdr| hdr.gsub('@@@@','') } + # Matching annotated_headers values against real_headers to ensure that + # annotated_headers contain full path entries (as returned by make rule) + annotated_headers.map! {|hdr| real_headers.find {|real_hdr| !real_hdr.match(/(.*\/)?#{Regexp.escape(hdr)}/).nil? } } + annotated_headers = annotated_headers.compact # Find which of our annotated headers are "real" dependencies. This is # intended to weed out dependencies that have been removed due to build @@ -87,7 +125,54 @@ class PreprocessinatorIncludesHandler sdependencies.map! {|hdr| hdr.gsub('\\','/') } list += sdependencies - list + to_process = [] + + if @configurator.project_config_hash.has_key?(:project_auto_link_deep_dependencies) && @configurator.project_config_hash[:project_auto_link_deep_dependencies] + # Creating list of mocks + mocks = annotated_headers.find_all do |annotated_header| + File.basename(annotated_header) =~ /^#{@configurator.project_config_hash[:cmock_mock_prefix]}.*$/ + end.compact + + # Creating list of headers that should be recursively pre-processed + # Skipping mocks and unity.h + headers_to_deep_link = annotated_headers.select do |annotated_header| + !(mocks.include? annotated_header) and (annotated_header.match(/^(.*\/)?unity\.h$/).nil?) + end + headers_to_deep_link.map! {|hdr| File.expand_path(hdr)} + + mocks.each do |mock| + dirname = File.dirname(mock) + #basename = File.basename(mock).delete_prefix(@configurator.project_config_hash[:cmock_mock_prefix]) + basename = File.basename(mock).sub(@configurator.project_config_hash[:cmock_mock_prefix], '') + if dirname != "." + ignore_list << File.join(dirname, basename) + else + ignore_list << basename + end + end.compact + + # Filtering list of final includes to only include mocks and anything that is NOT in the ignore_list + list = list.select do |item| + mocks.include? item or !(ignore_list.any? { |ignore_item| !item.match(/^(.*\/)?#{Regexp.escape(ignore_item)}$/).nil? }) + end + + headers_to_deep_link.each do |hdr| + if (ignore_list.none? {|ignore_header| hdr.match(/^(.*\/)?#{Regexp.escape(ignore_header)}$/)} and + include_paths.none? {|include_path| hdr =~ /^#{include_path}\.*/}) + if File.exist?(hdr) + to_process << hdr + #source_file = hdr.delete_suffix(hdr_ext) + src_ext + source_file = hdr.chomp(hdr_ext) + src_ext + if source_file != hdr and File.exist?(source_file) + to_process << source_file + end + end + end + end + end + + return list, to_process + end def write_shallow_includes_list(filepath, list) diff --git a/test/vendor/ceedling/lib/ceedling/project_config_manager.rb b/test/vendor/ceedling/lib/ceedling/project_config_manager.rb index 801c206d8..31f7e3a68 100644 --- a/test/vendor/ceedling/lib/ceedling/project_config_manager.rb +++ b/test/vendor/ceedling/lib/ceedling/project_config_manager.rb @@ -3,16 +3,17 @@ require 'ceedling/constants' class ProjectConfigManager - attr_reader :options_files, :release_config_changed, :test_config_changed + attr_reader :options_files, :release_config_changed, :test_config_changed, :test_defines_changed attr_accessor :config_hash - constructor :cacheinator, :yaml_wrapper + constructor :cacheinator, :configurator, :yaml_wrapper, :file_wrapper def setup @options_files = [] @release_config_changed = false @test_config_changed = false + @test_defines_changed = false end @@ -34,4 +35,12 @@ class ProjectConfigManager @test_config_changed = @cacheinator.diff_cached_test_config?( @config_hash ) end + def process_test_defines_change(files) + # has definitions changed since last test build + @test_defines_changed = @cacheinator.diff_cached_test_defines?( files ) + if @test_defines_changed + # update timestamp for rake task prerequisites + @file_wrapper.touch( @configurator.project_test_force_rebuild_filepath ) + end + end end diff --git a/test/vendor/ceedling/lib/ceedling/rules_tests.rake b/test/vendor/ceedling/lib/ceedling/rules_tests.rake index 67d8a500c..2b8f7af5b 100644 --- a/test/vendor/ceedling/lib/ceedling/rules_tests.rake +++ b/test/vendor/ceedling/lib/ceedling/rules_tests.rake @@ -35,8 +35,7 @@ end rule(/#{PROJECT_TEST_BUILD_OUTPUT_PATH}\/#{'.+\\'+EXTENSION_EXECUTABLE}$/) do |bin_file| - lib_args = ((defined? LIBRARIES_SYSTEM) ? LIBRARIES_SYSTEM : []) - lib_args.map! {|v| LIBRARIES_FLAG.gsub(/\$\{1\}/, v) } if (defined? LIBRARIES_FLAG) + lib_args = @ceedling[:test_invoker].convert_libraries_to_arguments() @ceedling[:generator].generate_executable_file( TOOLS_TEST_LINKER, @@ -67,6 +66,7 @@ namespace TEST_SYM do @ceedling[:file_finder].find_test_from_file_path(test) end ]) do |test| + @ceedling[:rake_wrapper][:directories].reenable if @ceedling[:task_invoker].first_run == false && @ceedling[:project_config_manager].test_defines_changed @ceedling[:rake_wrapper][:directories].invoke @ceedling[:test_invoker].setup_and_invoke([test.source]) end diff --git a/test/vendor/ceedling/lib/ceedling/stream_wrapper.rb b/test/vendor/ceedling/lib/ceedling/stream_wrapper.rb index 33d3c10b1..7e160527f 100644 --- a/test/vendor/ceedling/lib/ceedling/stream_wrapper.rb +++ b/test/vendor/ceedling/lib/ceedling/stream_wrapper.rb @@ -1,8 +1,16 @@ class StreamWrapper + def stdout_override(&fnc) + @stdout_overide_fnc = fnc + end + def stdout_puts(string) - $stdout.puts(string) + if @stdout_overide_fnc + @stdout_overide_fnc.call(string) + else + $stdout.puts(string) + end end def stdout_flush diff --git a/test/vendor/ceedling/lib/ceedling/task_invoker.rb b/test/vendor/ceedling/lib/ceedling/task_invoker.rb index 4e91b2ea1..642695c46 100644 --- a/test/vendor/ceedling/lib/ceedling/task_invoker.rb +++ b/test/vendor/ceedling/lib/ceedling/task_invoker.rb @@ -2,11 +2,14 @@ require 'ceedling/par_map' class TaskInvoker - constructor :dependinator, :rake_utils, :rake_wrapper + attr_accessor :first_run + + constructor :dependinator, :rake_utils, :rake_wrapper, :project_config_manager def setup @test_regexs = [/^#{TEST_ROOT_NAME}:/] @release_regexs = [/^#{RELEASE_ROOT_NAME}(:|$)/] + @first_run = true end def add_test_task_regex(regex) @@ -46,17 +49,22 @@ class TaskInvoker def invoke_test_mocks(mocks) @dependinator.enhance_mock_dependencies( mocks ) - mocks.each { |mock| @rake_wrapper[mock].invoke } + mocks.each { |mock| + @rake_wrapper[mock].reenable if @first_run == false && @project_config_manager.test_defines_changed + @rake_wrapper[mock].invoke + } end def invoke_test_runner(runner) @dependinator.enhance_runner_dependencies( runner ) + @rake_wrapper[runner].reenable if @first_run == false && @project_config_manager.test_defines_changed @rake_wrapper[runner].invoke end def invoke_test_shallow_include_lists(files) @dependinator.enhance_shallow_include_lists_dependencies( files ) par_map(PROJECT_COMPILE_THREADS, files) do |file| + @rake_wrapper[file].reenable if @first_run == false && @project_config_manager.test_defines_changed @rake_wrapper[file].invoke end end @@ -64,6 +72,7 @@ class TaskInvoker def invoke_test_preprocessed_files(files) @dependinator.enhance_preprocesed_file_dependencies( files ) par_map(PROJECT_COMPILE_THREADS, files) do |file| + @rake_wrapper[file].reenable if @first_run == false && @project_config_manager.test_defines_changed @rake_wrapper[file].invoke end end @@ -71,30 +80,37 @@ class TaskInvoker def invoke_test_dependencies_files(files) @dependinator.enhance_dependencies_dependencies( files ) par_map(PROJECT_COMPILE_THREADS, files) do |file| + @rake_wrapper[file].reenable if @first_run == false && @project_config_manager.test_defines_changed @rake_wrapper[file].invoke end end def invoke_test_objects(objects) par_map(PROJECT_COMPILE_THREADS, objects) do |object| - @rake_wrapper[object].invoke + @rake_wrapper[object].reenable if @first_run == false && @project_config_manager.test_defines_changed + @rake_wrapper[object].invoke end end + def invoke_test_executable(file) + @rake_wrapper[file].invoke + end + def invoke_test_results(result) @dependinator.enhance_results_dependencies( result ) + @rake_wrapper[result].reenable if @first_run == false && @project_config_manager.test_defines_changed @rake_wrapper[result].invoke end def invoke_release_dependencies_files(files) par_map(PROJECT_COMPILE_THREADS, files) do |file| - @rake_wrapper[file].invoke + @rake_wrapper[file].invoke end end def invoke_release_objects(objects) par_map(PROJECT_COMPILE_THREADS, objects) do |object| - @rake_wrapper[object].invoke + @rake_wrapper[object].invoke end end diff --git a/test/vendor/ceedling/lib/ceedling/tasks_base.rake b/test/vendor/ceedling/lib/ceedling/tasks_base.rake index 29074534e..8c8253099 100644 --- a/test/vendor/ceedling/lib/ceedling/tasks_base.rake +++ b/test/vendor/ceedling/lib/ceedling/tasks_base.rake @@ -89,7 +89,6 @@ namespace :options do desc "Merge #{option} project options." task option.downcase.to_sym do - # @ceedling[:setupinator].reset_defaults( @ceedling[:setupinator].config_hash ) hash = @ceedling[:project_config_manager].merge_options( @ceedling[:setupinator].config_hash, option_path ) @ceedling[:setupinator].do_setup( hash ) if @ceedling[:configurator].project_release_build diff --git a/test/vendor/ceedling/lib/ceedling/tasks_filesystem.rake b/test/vendor/ceedling/lib/ceedling/tasks_filesystem.rake index 4c9172979..58fa6511f 100644 --- a/test/vendor/ceedling/lib/ceedling/tasks_filesystem.rake +++ b/test/vendor/ceedling/lib/ceedling/tasks_filesystem.rake @@ -81,7 +81,10 @@ namespace :files do ['source', COLLECTION_ALL_SOURCE], ['header', COLLECTION_ALL_HEADERS] ] - categories << ['assembly', COLLECTION_ALL_ASSEMBLY] if (RELEASE_BUILD_USE_ASSEMBLY) + + using_assembly = (defined?(TEST_BUILD_USE_ASSEMBLY) && TEST_BUILD_USE_ASSEMBLY) || + (defined?(RELEASE_BUILD_USE_ASSEMBLY) && RELEASE_BUILD_USE_ASSEMBLY) + categories << ['assembly', COLLECTION_ALL_ASSEMBLY] if using_assembly categories.each do |category| name = category[0] diff --git a/test/vendor/ceedling/lib/ceedling/tasks_tests.rake b/test/vendor/ceedling/lib/ceedling/tasks_tests.rake index 13e97133e..5d09c1aff 100644 --- a/test/vendor/ceedling/lib/ceedling/tasks_tests.rake +++ b/test/vendor/ceedling/lib/ceedling/tasks_tests.rake @@ -1,7 +1,7 @@ require 'ceedling/constants' task :test => [:directories] do - @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS) + Rake.application['test:all'].invoke end namespace TEST_SYM do @@ -25,6 +25,11 @@ namespace TEST_SYM do @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, TEST_SYM, {:force_run => false}) end + desc "Just build tests without running." + task :build_only => [:directories] do + @ceedling[:test_invoker].setup_and_invoke(COLLECTION_ALL_TESTS, TEST_SYM, {:build_only => true}) + end + desc "Run tests by matching regular expression pattern." task :pattern, [:regex] => [:directories] do |t, args| matches = [] diff --git a/test/vendor/ceedling/lib/ceedling/test_invoker.rb b/test/vendor/ceedling/lib/ceedling/test_invoker.rb index 01287ef89..652cb318b 100644 --- a/test/vendor/ceedling/lib/ceedling/test_invoker.rb +++ b/test/vendor/ceedling/lib/ceedling/test_invoker.rb @@ -54,7 +54,20 @@ class TestInvoker end end - def setup_and_invoke(tests, context=TEST_SYM, options={:force_run => true}) + # Convert libraries configuration form YAML configuration + # into a string that can be given to the compiler. + def convert_libraries_to_arguments() + if @configurator.project_config_hash.has_key?(:libraries_test) + lib_args = @configurator.project_config_hash[:libraries_test] + lib_args.flatten! + lib_flag = @configurator.project_config_hash[:libraries_flag] + lib_args.map! {|v| lib_flag.gsub(/\$\{1\}/, v) } if (defined? lib_flag) + return lib_args + end + end + + + def setup_and_invoke(tests, context=TEST_SYM, options={:force_run => true, :build_only => false}) @tests = tests @@ -68,7 +81,7 @@ class TestInvoker begin @plugin_manager.pre_test( test ) test_name ="#{File.basename(test)}".chomp('.c') - def_test_key="defines_#{test_name}" + def_test_key="defines_#{test_name.downcase}" # Re-define the project out path and pre-processor defines. if @configurator.project_config_hash.has_key?(def_test_key.to_sym) @@ -94,6 +107,8 @@ class TestInvoker results_pass = @file_path_utils.form_pass_results_filepath( test ) results_fail = @file_path_utils.form_fail_results_filepath( test ) + @project_config_manager.process_test_defines_change(sources) + # add the definition value in the build option for the unit test if @configurator.defines_use_test_definition add_test_definition(test) @@ -119,8 +134,15 @@ class TestInvoker # build test objects @task_invoker.invoke_test_objects( objects ) - # 3, 2, 1... launch - @task_invoker.invoke_test_results( results_pass ) + # if the option build_only has been specified, build only the executable + # but don't run the test + if (options[:build_only]) + executable = @file_path_utils.form_test_executable_filepath( test ) + @task_invoker.invoke_test_executable( executable ) + else + # 3, 2, 1... launch + @task_invoker.invoke_test_results( results_pass ) + end rescue => e @build_invoker_utils.process_exception( e, context ) ensure @@ -142,6 +164,8 @@ class TestInvoker # store away what's been processed @mocks.concat( mock_list ) @sources.concat( sources ) + + @task_invoker.first_run = false end # post-process collected mock list diff --git a/test/vendor/ceedling/lib/ceedling/tool_executor.rb b/test/vendor/ceedling/lib/ceedling/tool_executor.rb index a5b3f579e..0ab5ddcac 100644 --- a/test/vendor/ceedling/lib/ceedling/tool_executor.rb +++ b/test/vendor/ceedling/lib/ceedling/tool_executor.rb @@ -18,6 +18,8 @@ class ToolExecutor end # build up a command line from yaml provided config + + # @param extra_params is an array of parameters to append to executable def build_command_line(tool_config, extra_params, *args) @tool_name = tool_config[:name] @executable = tool_config[:executable] @@ -50,7 +52,6 @@ class ToolExecutor options[:boom] = true if (options[:boom].nil?) options[:stderr_redirect] = StdErrRedirect::NONE if (options[:stderr_redirect].nil?) options[:background_exec] = BackgroundExec::NONE if (options[:background_exec].nil?) - # build command line command_line = [ @tool_executor_helper.background_exec_cmdline_prepend( options ), @@ -60,6 +61,8 @@ class ToolExecutor @tool_executor_helper.background_exec_cmdline_append( options ), ].flatten.compact.join(' ') + @streaminator.stderr_puts("Verbose: #{__method__.to_s}(): #{command_line}", Verbosity::DEBUG) + shell_result = {} # depending on background exec option, we shell out differently @@ -73,7 +76,10 @@ class ToolExecutor shell_result[:time] = time #scrub the string for illegal output - shell_result[:output].scrub! unless (!("".respond_to? :scrub!) || (shell_result[:output].nil?)) + unless shell_result[:output].nil? + shell_result[:output] = shell_result[:output].scrub if "".respond_to?(:scrub) + shell_result[:output].gsub!(/\033\[\d\dm/,'') + end @tool_executor_helper.print_happy_results( command_line, shell_result, options[:boom] ) @tool_executor_helper.print_error_results( command_line, shell_result, options[:boom] ) diff --git a/test/vendor/ceedling/lib/ceedling/version.rb b/test/vendor/ceedling/lib/ceedling/version.rb index 3dfdf3624..ba917df5a 100644 --- a/test/vendor/ceedling/lib/ceedling/version.rb +++ b/test/vendor/ceedling/lib/ceedling/version.rb @@ -1,15 +1,36 @@ + # @private module Ceedling module Version - # @private - GEM = "0.28.3" - # @private + # Check for local or global version of vendor directory in order to look up versions + { + "CEXCEPTION" => File.join("vendor","c_exception","lib","CException.h"), + "CMOCK" => File.join("vendor","cmock","src","cmock.h"), + "UNITY" => File.join("vendor","unity","src","unity.h"), + }.each_pair do |name, path| + filename = if (File.exist?(File.join("..","..",path))) + File.join("..","..",path) + elsif (File.exist?(File.join(File.dirname(__FILE__),"..","..",path))) + File.join(File.dirname(__FILE__),"..","..",path) + else + eval "#{name} = 'unknown'" + continue + end + + # Actually look up the versions + a = [0,0,0] + File.readlines(filename) do |line| + ["VERSION_MAJOR", "VERSION_MINOR", "VERSION_BUILD"].each_with_index do |field, i| + m = line.match(/#{name}_#{field}\s+(\d+)/) + a[i] = m[1] unless (m.nil?) + end + end + + # Make a constant from each, so that we can use it elsewhere + eval "#{name} = '#{a.join(".")}'" + end + + GEM = "0.29.0" CEEDLING = GEM - # @private - CEXCEPTION = "1.3.1" - # @private - CMOCK = "2.4.5" - # @private - UNITY = "2.4.2" end end diff --git a/test/vendor/ceedling/plugins/colour_report/lib/colour_report.rb b/test/vendor/ceedling/plugins/colour_report/lib/colour_report.rb new file mode 100644 index 000000000..1211eab4d --- /dev/null +++ b/test/vendor/ceedling/plugins/colour_report/lib/colour_report.rb @@ -0,0 +1,16 @@ +require 'ceedling/plugin' +require 'ceedling/streaminator' +require 'ceedling/constants' + +class ColourReport < Plugin + + def setup + @ceedling[:stream_wrapper].stdout_override(&ColourReport.method(:colour_stdout)) + end + + def self.colour_stdout(string) + require 'colour_reporter.rb' + report string + end + +end diff --git a/test/vendor/ceedling/plugins/command_hooks/README.md b/test/vendor/ceedling/plugins/command_hooks/README.md index 9fcbbba69..8ac64afce 100644 --- a/test/vendor/ceedling/plugins/command_hooks/README.md +++ b/test/vendor/ceedling/plugins/command_hooks/README.md @@ -15,7 +15,6 @@ Define any of these sections in :tools: to provide additional hooks to be called :pre_link_execute :post_link_execute :pre_test_fixture_execute - :pre_test_fixture_execute :pre_test :post_test :pre_release @@ -24,13 +23,13 @@ Define any of these sections in :tools: to provide additional hooks to be called :post_build ``` -Each of these tools can support an :executable string and an :args list, like so: +Each of these tools can support an :executable string and an :arguments list, like so: ``` :tools: :post_link_execute: :executable: objcopy.exe - :args: + :arguments: - ${1} #This is replaced with the executable name - output.srec - --strip-all @@ -42,11 +41,13 @@ You may also specify an array of executables to be called in a particular place, :tools: :post_test: - :executable: echo - :args: "${1} was glorious!" + :arguments: "${1} was glorious!" - :executable: echo - :args: + :arguments: - it kinda made me cry a little. - you? ``` +Please note that it varies which arguments are being parsed down to the +hooks. For now see `command_hooks.rb` to figure out which suits you best. Happy Tweaking! diff --git a/test/vendor/ceedling/plugins/command_hooks/lib/command_hooks.rb b/test/vendor/ceedling/plugins/command_hooks/lib/command_hooks.rb index d8525b037..4bf8b5312 100644 --- a/test/vendor/ceedling/plugins/command_hooks/lib/command_hooks.rb +++ b/test/vendor/ceedling/plugins/command_hooks/lib/command_hooks.rb @@ -1,6 +1,5 @@ require 'ceedling/plugin' require 'ceedling/constants' - class CommandHooks < Plugin attr_reader :config @@ -23,7 +22,6 @@ class CommandHooks < Plugin :post_release => ((defined? TOOLS_POST_RELEASE) ? TOOLS_POST_RELEASE : nil ), :pre_build => ((defined? TOOLS_PRE_BUILD) ? TOOLS_PRE_BUILD : nil ), :post_build => ((defined? TOOLS_POST_BUILD) ? TOOLS_POST_BUILD : nil ), - :post_build => ((defined? TOOLS_POST_BUILD) ? TOOLS_POST_BUILD : nil ), :post_error => ((defined? TOOLS_POST_ERROR) ? TOOLS_POST_ERROR : nil ), } @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) @@ -49,14 +47,33 @@ class CommandHooks < Plugin private + ## + # Run a hook if its available. + # + # :args: + # - hook: Name of the hook to run + # - name: Name of file (default: "") + # + # :return: + # shell_result. + # def run_hook_step(hook, name="") if (hook[:executable]) - args = ( (hook[:args].is_a? Array) ? hook[:args] : [] ) - cmd = @ceedling[:tool_executor].build_command_line( hook, args, name ) - shell_result = @ceedling[:tool_executor].exec( cmd[:line], cmd[:options] ) + # Handle argument replacemant ({$1}), and get commandline + cmd = @ceedling[:tool_executor].build_command_line( hook, [], name ) + shell_result = @ceedling[:tool_executor].exec(cmd[:line], cmd[:options]) end end + ## + # Run a hook if its available. + # + # If __which_hook__ is an array, run each of them sequentially. + # + # :args: + # - which_hook: Name of the hook to run + # - name: Name of file + # def run_hook(which_hook, name="") if (@config[which_hook]) @ceedling[:streaminator].stdout_puts("Running Hook #{which_hook}...", Verbosity::NORMAL) diff --git a/test/vendor/ceedling/plugins/gcov/README.md b/test/vendor/ceedling/plugins/gcov/README.md index 3ed992cb5..096ffa100 100644 --- a/test/vendor/ceedling/plugins/gcov/README.md +++ b/test/vendor/ceedling/plugins/gcov/README.md @@ -1,13 +1,16 @@ ceedling-gcov ============= +# Plugin Overview + Plugin for integrating GNU GCov code coverage tool into Ceedling projects. Currently only designed for the gcov command (like LCOV for example). In the future we could configure this to work with other code coverage tools. +This plugin currently uses `gcovr` to generate HTML and/or XML reports as a +utility. The normal gcov plugin _must_ be run first for this report to generate. -This plugin currently uses `gcovr` to generate HTML reports as a utility. The -normal gcov plugin _must_ be run first for this report to generate. +## Installation Gcovr can be installed via pip like so: @@ -15,27 +18,83 @@ Gcovr can be installed via pip like so: pip install gcovr ``` +## Configuration + +The gcov plugin supports configuration options via your `project.yml` provided +by Ceedling. + +Generation of HTML reports may be enabled or disabled with the following +config. Set to `true` to enable or set to `false` to disable. + +``` +:gcov: + :html_report: true +``` + +Generation of XML reports may be enabled or disabled with the following +config. Set to `true` to enable or set to `false` to disable. + +``` +:gcov: + :xml_report: true +``` + There are two types of gcovr HTML reports that can be configured in your -`project.yml`. To create a basic HTML report with only the overall file -information use the following config. +`project.yml`. To create a basic HTML report, with only the overall file +information, use the following config. ``` :gcov: :html_report_type: basic ``` -To create a detailed HTML report with line by line breakdown of the coverage use -the following config. + +To create a detailed HTML report, with line by line breakdown of the +coverage, use the following config. ``` :gcov: :html_report_type: detailed ``` -These reports will be found in `build/artifacts/gcov`. +There are a number of options to control which files are considered part of +the coverage report. Most often, we only care about coverage on our source code, and not +on tests or automatically generated mocks, runners, etc. However, there are times +where this isn't true... or there are times where we've moved ceedling's directory +structure so that the project file isn't at the root of the project anymore. In these +cases, you may need to tweak the following: +``` +:gcov: + :report_root: "." + :report_exclude: "^build|^vendor|^test|^support" + :report_include: "^src" +``` +One important note about html_report_root: gcovr will only take a single root folder, unlike +Ceedling's ability to take as many as you like. So you will need to choose a folder which is +a superset of ALL the folders you want, and then use the include or exclude options to set up +patterns of files to pay attention to or ignore. It's not ideal, but it works. -# To-Do list +Finally, there are a number of settings which can be specified in order to adjust the +default behaviors of gcov: + +``` +:gcov: + :html_medium_threshold: 75 + :html_high_threshold: 90 + :fail_under_line: 30 + :fail_under_branch: 30 +``` + +These HTML and XML reports will be found in `build/artifacts/gcov`. + +## Example Usage + +``` +ceedling gcov:all utils:gcov +``` + +## To-Do list - Generate overall report (combined statistics from all files with coverage) - Generate coverage output files diff --git a/test/vendor/ceedling/plugins/gcov/config/defaults.yml b/test/vendor/ceedling/plugins/gcov/config/defaults.yml index cb11a7dd4..13bac556e 100644 --- a/test/vendor/ceedling/plugins/gcov/config/defaults.yml +++ b/test/vendor/ceedling/plugins/gcov/config/defaults.yml @@ -11,6 +11,7 @@ - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR - -DGCOV_COMPILER + - -DCODE_COVERAGE - -c "${1}" - -o "${2}" :gcov_linker: @@ -20,6 +21,7 @@ - -ftest-coverage - ${1} - -o ${2} + - ${3} :gcov_fixture: :executable: ${1} :gcov_report: @@ -36,9 +38,8 @@ :arguments: - -p - -b - - -e "${1}" + - ${1} - --html - - -r . - -o GcovCoverageResults.html :gcov_post_report_basic: :executable: gcovr @@ -46,9 +47,8 @@ :arguments: - -p - -b - - -e "${1}" + - ${1} - --html - - -r . - -o "$": GCOV_ARTIFACTS_FILE :gcov_post_report_advanced: :executable: gcovr @@ -56,11 +56,18 @@ :arguments: - -p - -b - - -e "${1}" + - ${1} - --html - --html-details - - -r . - -o "$": GCOV_ARTIFACTS_FILE - + :gcov_post_report_xml: + :executable: gcovr + :optional: TRUE + :arguments: + - -p + - -b + - ${1} + - --xml + - -o "$": GCOV_ARTIFACTS_FILE_XML ... diff --git a/test/vendor/ceedling/plugins/gcov/gcov.rake b/test/vendor/ceedling/plugins/gcov/gcov.rake index 997a0cd99..3acab8566 100644 --- a/test/vendor/ceedling/plugins/gcov/gcov.rake +++ b/test/vendor/ceedling/plugins/gcov/gcov.rake @@ -31,11 +31,14 @@ rule(/#{GCOV_BUILD_OUTPUT_PATH}\/#{'.+\\' + EXTENSION_OBJECT}$/ => [ end rule(/#{GCOV_BUILD_OUTPUT_PATH}\/#{'.+\\' + EXTENSION_EXECUTABLE}$/) do |bin_file| + lib_args = @ceedling[:test_invoker].convert_libraries_to_arguments() + @ceedling[:generator].generate_executable_file( TOOLS_GCOV_LINKER, GCOV_SYM, bin_file.prerequisites, bin_file.name, + lib_args, @ceedling[:file_path_utils].form_test_build_map_filepath(bin_file.name) ) end @@ -151,6 +154,17 @@ if PROJECT_USE_DEEP_DEPENDENCIES end namespace UTILS_SYM do + def gcov_args_builder(opts) + args = "" + args += "-r \"#{opts[:gcov_report_root] || '.'}\" " + args += "-f \"#{opts[:gcov_report_include]}\" " unless opts[:gcov_report_include].nil? + args += "-e \"#{opts[:gcov_report_exclude] || GCOV_FILTER_EXCLUDE}\" " + [ :gcov_fail_under_line, :gcov_fail_under_branch, :gcov_html_medium_threshold, :gcov_html_high_threshold].each do |opt| + args += "--#{opt.to_s.gsub('_','-').sub(/:?gcov-/,'')} #{opts[opt]} " unless opts[opt].nil? + end + return args + end + desc 'Create gcov code coverage html report (must run ceedling gcov first)' task GCOV_SYM do @@ -158,23 +172,49 @@ namespace UTILS_SYM do FileUtils.mkdir_p GCOV_ARTIFACTS_PATH end - filter = @ceedling[:configurator].project_config_hash[:gcov_html_report_filter] || GCOV_FILTER_EXPR + args = gcov_args_builder(@ceedling[:configurator].project_config_hash) - if @ceedling[:configurator].project_config_hash[:gcov_html_report_type] == 'basic' - puts "Creating a basic html report of gcov results in #{GCOV_ARTIFACTS_FILE}..." - command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_POST_REPORT_BASIC, [], filter) - @ceedling[:tool_executor].exec(command[:line], command[:options]) - elsif @ceedling[:configurator].project_config_hash[:gcov_html_report_type] == 'detailed' - puts "Creating a detailed html report of gcov results in #{GCOV_ARTIFACTS_FILE}..." - command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_POST_REPORT_ADVANCED, [], filter) - @ceedling[:tool_executor].exec(command[:line], command[:options]) + if @ceedling[:configurator].project_config_hash[:gcov_html_report].nil? + puts "In your project.yml, define: \n\n:gcov:\n :html_report:\n\n to true or false to refine this feature." + puts "For now, assumimg you want an html report generated." + html_enabled = true else - puts "In your project.yml, define: \n\n:gcov:\n :html_report_type:\n\n to basic or detailed to refine this feature." - puts "For now, just creating basic." - puts "Creating a basic html report of gcov results in #{GCOV_ARTIFACTS_FILE}..." - command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_POST_REPORT_BASIC, [], filter) + html_enabled = @ceedling[:configurator].project_config_hash[:gcov_html_report] + end + + if @ceedling[:configurator].project_config_hash[:gcov_xml_report].nil? + puts "In your project.yml, define: \n\n:gcov:\n :xml_report:\n\n to true or false to refine this feature." + puts "For now, assumimg you do not want an xml report generated." + xml_enabled = false + else + xml_enabled = @ceedling[:configurator].project_config_hash[:gcov_xml_report] + end + + if html_enabled + if @ceedling[:configurator].project_config_hash[:gcov_html_report_type] == 'basic' + puts "Creating a basic html report of gcov results in #{GCOV_ARTIFACTS_FILE}..." + command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_POST_REPORT_BASIC, [], args) + @ceedling[:tool_executor].exec(command[:line], command[:options]) + elsif @ceedling[:configurator].project_config_hash[:gcov_html_report_type] == 'detailed' + puts "Creating a detailed html report of gcov results in #{GCOV_ARTIFACTS_FILE}..." + command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_POST_REPORT_ADVANCED, [], args) + @ceedling[:tool_executor].exec(command[:line], command[:options]) + + else + puts "In your project.yml, define: \n\n:gcov:\n :html_report_type:\n\n to basic or detailed to refine this feature." + puts "For now, just creating basic." + puts "Creating a basic html report of gcov results in #{GCOV_ARTIFACTS_FILE}..." + command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_POST_REPORT_BASIC, [], args) + @ceedling[:tool_executor].exec(command[:line], command[:options]) + end + end + + if xml_enabled + puts "Creating an xml report of gcov results in #{GCOV_ARTIFACTS_FILE_XML}..." + command = @ceedling[:tool_executor].build_command_line(TOOLS_GCOV_POST_REPORT_XML, [], filter) @ceedling[:tool_executor].exec(command[:line], command[:options]) end + puts "Done." end end diff --git a/test/vendor/ceedling/plugins/gcov/lib/gcov.rb b/test/vendor/ceedling/plugins/gcov/lib/gcov.rb index 9a93d5bd5..15a1b4cfa 100644 --- a/test/vendor/ceedling/plugins/gcov/lib/gcov.rb +++ b/test/vendor/ceedling/plugins/gcov/lib/gcov.rb @@ -14,8 +14,7 @@ class Gcov < Plugin project_test_results_path: GCOV_RESULTS_PATH, project_test_dependencies_path: GCOV_DEPENDENCIES_PATH, defines_test: DEFINES_TEST + ['CODE_COVERAGE'], - collection_defines_test_and_vendor: COLLECTION_DEFINES_TEST_AND_VENDOR + ['CODE_COVERAGE'], - gcov_html_report_filter: GCOV_FILTER_EXPR + gcov_html_report_filter: GCOV_FILTER_EXCLUDE } @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) @@ -23,13 +22,15 @@ class Gcov < Plugin end def generate_coverage_object_file(source, object) + lib_args = @ceedling[:test_invoker].convert_libraries_to_arguments() compile_command = @ceedling[:tool_executor].build_command_line( TOOLS_GCOV_COMPILER, @ceedling[:flaginator].flag_down(OPERATION_COMPILE_SYM, GCOV_SYM, source), source, object, - @ceedling[:file_path_utils].form_test_build_list_filepath(object) + @ceedling[:file_path_utils].form_test_build_list_filepath(object), + lib_args ) @ceedling[:streaminator].stdout_puts("Compiling #{File.basename(source)} with coverage...") @ceedling[:tool_executor].exec(compile_command[:line], compile_command[:options]) @@ -96,6 +97,12 @@ class Gcov < Plugin @ceedling[:streaminator].stdout_puts(report + "\n\n") end end + + COLLECTION_ALL_SOURCE.each do |source| + unless coverage_sources.include?(source) + @ceedling[:streaminator].stdout_puts("Could not find coverage results for " + source + "\n") + end + end end end diff --git a/test/vendor/ceedling/plugins/gcov/lib/gcov_constants.rb b/test/vendor/ceedling/plugins/gcov/lib/gcov_constants.rb index 84c91d3ba..539d46f75 100644 --- a/test/vendor/ceedling/plugins/gcov/lib/gcov_constants.rb +++ b/test/vendor/ceedling/plugins/gcov/lib/gcov_constants.rb @@ -10,9 +10,10 @@ GCOV_DEPENDENCIES_PATH = File.join(GCOV_BUILD_PATH, "dependencies") GCOV_ARTIFACTS_PATH = File.join(PROJECT_BUILD_ARTIFACTS_ROOT, GCOV_ROOT_NAME) GCOV_ARTIFACTS_FILE = File.join(GCOV_ARTIFACTS_PATH, "GcovCoverageResults.html") +GCOV_ARTIFACTS_FILE_XML = File.join(GCOV_ARTIFACTS_PATH, "GcovCoverageResults.xml") GCOV_IGNORE_SOURCES = %w(unity cmock cexception).freeze -GCOV_FILTER_EXPR = '^vendor.*|^build.*|^test.*|^lib.*' +GCOV_FILTER_EXCLUDE = '^vendor.*|^build.*|^test.*|^lib.*' diff --git a/test/vendor/ceedling/plugins/junit_tests_report/README.md b/test/vendor/ceedling/plugins/junit_tests_report/README.md new file mode 100644 index 000000000..1259fd668 --- /dev/null +++ b/test/vendor/ceedling/plugins/junit_tests_report/README.md @@ -0,0 +1,36 @@ +junit_tests_report +==================== + +## Overview + +The junit_tests_report plugin creates an XML file of test results in JUnit +format, which is handy for Continuous Integration build servers or as input +into other reporting tools. The XML file is output to the appropriate +`/artifacts/` directory (e.g. `artifacts/test/` for test tasks, +`artifacts/gcov/` for gcov, or `artifacts/bullseye/` for bullseye runs). + +## Setup + +Enable the plugin in your project.yml by adding `junit_tests_report` +to the list of enabled plugins. + +``` YAML +:plugins: + :enabled: + - junit_tests_report +``` + +## Configuration + +Optionally configure the output / artifact filename in your project.yml with +the `artifact_filename` configuration option. The default filename is +`report.xml`. + +You can also configure the path that this artifact is stored. This can be done +by setting `path`. The default is that it will be placed in a subfolder under +the `build` directory. + +``` YAML +:junit_tests_report: + :artifact_filename: report_junit.xml +``` diff --git a/test/vendor/ceedling/plugins/junit_tests_report/lib/junit_tests_report.rb b/test/vendor/ceedling/plugins/junit_tests_report/lib/junit_tests_report.rb index 4612b2202..a777d07d7 100644 --- a/test/vendor/ceedling/plugins/junit_tests_report/lib/junit_tests_report.rb +++ b/test/vendor/ceedling/plugins/junit_tests_report/lib/junit_tests_report.rb @@ -22,7 +22,10 @@ class JunitTestsReport < Plugin def post_build @results_list.each_key do |context| results = @ceedling[:plugin_reportinator].assemble_test_results(@results_list[context]) - file_path = File.join( PROJECT_BUILD_ARTIFACTS_ROOT, context.to_s, 'report.xml' ) + + artifact_filename = @ceedling[:configurator].project_config_hash[:junit_tests_report_artifact_filename] || 'report.xml' + artifact_fullpath = @ceedling[:configurator].project_config_hash[:junit_tests_report_path] || File.join(PROJECT_BUILD_ARTIFACTS_ROOT, context.to_s) + file_path = File.join(artifact_fullpath, artifact_filename) @ceedling[:file_wrapper].open( file_path, 'w' ) do |f| @testsuite_counter = 0 @@ -90,7 +93,14 @@ class JunitTestsReport < Plugin unless suite[:stdout].empty? stream.puts(' ') - suite[:stdout].each{|line| stream.puts line } + suite[:stdout].each do |line| + line.gsub!(/&/, '&') + line.gsub!(//, '>') + line.gsub!(/"/, '"') + line.gsub!(/'/, ''') + stream.puts(line) + end stream.puts(' ') end @@ -98,6 +108,7 @@ class JunitTestsReport < Plugin end def write_test( test, stream ) + test[:test].gsub!('"', '"') case test[:result] when :success stream.puts(' ' % test) diff --git a/test/vendor/ceedling/plugins/module_generator/lib/module_generator.rb b/test/vendor/ceedling/plugins/module_generator/lib/module_generator.rb index ab0f0f107..b2fac006d 100644 --- a/test/vendor/ceedling/plugins/module_generator/lib/module_generator.rb +++ b/test/vendor/ceedling/plugins/module_generator/lib/module_generator.rb @@ -39,10 +39,29 @@ class ModuleGenerator < Plugin :update_svn => ((defined? MODULE_GENERATOR_UPDATE_SVN ) ? MODULE_GENERATOR_UPDATE_SVN : false ), } + # Read Boilerplate template file. + if (defined? MODULE_GENERATOR_BOILERPLATE_FILES) + + bf = MODULE_GENERATOR_BOILERPLATE_FILES + + if !bf[:src].nil? && File.exists?(bf[:src]) + unity_generator_options[:boilerplates][:src] = File.read(bf[:src]) + end + + if !bf[:inc].nil? && File.exists?(bf[:inc]) + unity_generator_options[:boilerplates][:inc] = File.read(bf[:inc]) + end + + if !bf[:tst].nil? && File.exists?(bf[:tst]) + unity_generator_options[:boilerplates][:tst] = File.read(bf[:tst]) + end + end + + # If using "create[:]" option from command line. unless optz[:module_root_path].to_s.empty? - unity_generator_options[:path_src] = File.join(optz[:module_root_path], unity_generator_options[:path_src]) - unity_generator_options[:path_inc] = File.join(optz[:module_root_path], unity_generator_options[:path_inc]) - unity_generator_options[:path_tst] = File.join(optz[:module_root_path], unity_generator_options[:path_tst]) + unity_generator_options[:path_src] = File.join(optz[:module_root_path], unity_generator_options[:path_src]) + unity_generator_options[:path_inc] = File.join(optz[:module_root_path], unity_generator_options[:path_inc]) + unity_generator_options[:path_tst] = File.join(optz[:module_root_path], unity_generator_options[:path_tst]) end return unity_generator_options diff --git a/test/vendor/ceedling/plugins/module_generator/module_generator.rake b/test/vendor/ceedling/plugins/module_generator/module_generator.rake index 7a7a1a988..e88e346aa 100644 --- a/test/vendor/ceedling/plugins/module_generator/module_generator.rake +++ b/test/vendor/ceedling/plugins/module_generator/module_generator.rake @@ -10,15 +10,20 @@ namespace :module do p = files.delete(pat) optz[:pattern] = p unless p.nil? end - files.each { - |v| + files.each do |v| module_root_path, module_name = v.split(module_root_separator, 2) if module_name optz[:module_root_path] = module_root_path v = module_name end - @ceedling[:module_generator].create(v, optz) - } + if (v =~ /^test_?/i) + # If the name of the file starts with test, automatically treat it as one + @ceedling[:module_generator].create(v.sub(/^test_?/i,''), optz.merge({:pattern => 'test'})) + else + # Otherwise, go through the normal procedure + @ceedling[:module_generator].create(v, optz) + end + end end desc "Destroy module (source, header and test files)" @@ -29,15 +34,14 @@ namespace :module do p = files.delete(pat) optz[:pattern] = p unless p.nil? end - files.each { - |v| + files.each do |v| module_root_path, module_name = v.split(module_root_separator, 2) if module_name optz[:module_root_path] = module_root_path v = module_name end @ceedling[:module_generator].create(v, optz) - } + end end end diff --git a/test/vendor/ceedling/plugins/xml_tests_report/README.md b/test/vendor/ceedling/plugins/xml_tests_report/README.md new file mode 100644 index 000000000..ce81eadf3 --- /dev/null +++ b/test/vendor/ceedling/plugins/xml_tests_report/README.md @@ -0,0 +1,36 @@ +xml_tests_report +==================== + +## Overview + +The xml_tests_report plugin creates an XML file of test results in xUnit +format, which is handy for Continuous Integration build servers or as input +into other reporting tools. The XML file is output to the appropriate +`/artifacts/` directory (e.g. `artifacts/test/` for test tasks, +`artifacts/gcov/` for gcov, or `artifacts/bullseye/` for bullseye runs). + +## Setup + +Enable the plugin in your project.yml by adding `xml_tests_report` to the list +of enabled plugins. + +``` YAML +:plugins: + :enabled: + - xml_tests_report +``` + +## Configuration + +Optionally configure the output / artifact filename in your project.yml with +the `artifact_filename` configuration option. The default filename is +`report.xml`. + +You can also configure the path that this artifact is stored. This can be done +by setting `path`. The default is that it will be placed in a subfolder under +the `build` directory. + +``` YAML +:xml_tests_report: + :artifact_filename: report_xunit.xml +``` diff --git a/test/vendor/ceedling/plugins/xml_tests_report/lib/xml_tests_report.rb b/test/vendor/ceedling/plugins/xml_tests_report/lib/xml_tests_report.rb index abe52dd22..ed4e99603 100644 --- a/test/vendor/ceedling/plugins/xml_tests_report/lib/xml_tests_report.rb +++ b/test/vendor/ceedling/plugins/xml_tests_report/lib/xml_tests_report.rb @@ -19,7 +19,9 @@ class XmlTestsReport < Plugin @results_list.each_key do |context| results = @ceedling[:plugin_reportinator].assemble_test_results(@results_list[context]) - file_path = File.join(PROJECT_BUILD_ARTIFACTS_ROOT, context.to_s, 'report.xml') + artifact_filename = @ceedling[:configurator].project_config_hash[:xml_tests_report_artifact_filename] || 'report.xml' + artifact_fullpath = @ceedling[:configurator].project_config_hash[:xml_tests_report_path] || File.join(PROJECT_BUILD_ARTIFACTS_ROOT, context.to_s) + file_path = File.join(artifact_fullpath, artifact_filename) @ceedling[:file_wrapper].open(file_path, 'w') do |f| @test_counter = 1 diff --git a/test/vendor/ceedling/vendor/c_exception/lib/CException.h b/test/vendor/ceedling/vendor/c_exception/lib/CException.h index 06ecf5252..78f2f940c 100644 --- a/test/vendor/ceedling/vendor/c_exception/lib/CException.h +++ b/test/vendor/ceedling/vendor/c_exception/lib/CException.h @@ -9,6 +9,11 @@ extern "C" #endif +#define CEXCEPTION_VERSION_MAJOR 1 +#define CEXCEPTION_VERSION_MINOR 3 +#define CEXCEPTION_VERSION_BUILD 2 +#define CEXCEPTION_VERSION ((CEXCEPTION_VERSION_MAJOR << 16) | (CEXCEPTION_VERSION_MINOR << 8) | CEXCEPTION_VERSION_BUILD) + //To Use CException, you have a number of options: //1. Just include it and run with the defaults //2. Define any of the following symbols at the command line to override them diff --git a/test/vendor/ceedling/vendor/cmock/lib/cmock_config.rb b/test/vendor/ceedling/vendor/cmock/lib/cmock_config.rb index 398c582a6..b21b61ed2 100644 --- a/test/vendor/ceedling/vendor/cmock/lib/cmock_config.rb +++ b/test/vendor/ceedling/vendor/cmock/lib/cmock_config.rb @@ -22,6 +22,7 @@ class CMockConfig :fail_on_unexpected_calls => true, :unity_helper_path => false, :treat_as => {}, + :treat_as_array => {}, :treat_as_void => [], :memcmp_if_unknown => true, :when_no_prototypes => :warn, #the options being :ignore, :warn, or :error @@ -36,6 +37,8 @@ class CMockConfig :includes_c_pre_header => nil, :includes_c_post_header => nil, :orig_header_include_fmt => "#include \"%s\"", + :array_size_type => [], + :array_size_name => 'size|len', } def initialize(options=nil) @@ -61,6 +64,7 @@ class CMockConfig end options[:unity_helper_path] ||= options[:unity_helper] options[:unity_helper_path] = [options[:unity_helper_path]] if options[:unity_helper_path].is_a? String + options[:includes_c_post_header] = ((options[:includes_c_post_header] || []) + (options[:unity_helper_path] || [])).uniq options[:plugins].compact! options[:plugins].map! {|p| p.to_sym} @options = options @@ -69,7 +73,11 @@ class CMockConfig treat_as_map.merge!(@options[:treat_as]) @options[:treat_as] = treat_as_map - @options.each_key { |key| eval("def #{key.to_s}() return @options[:#{key.to_s}] end") } + @options.each_key do |key| + unless methods.include?(key) + eval("def #{key.to_s}() return @options[:#{key.to_s}] end") + end + end end def load_config_file_from_yaml yaml_filename diff --git a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb index 8cfe07b1a..42725a60d 100644 --- a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb +++ b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb @@ -57,9 +57,7 @@ class CMockGenerator private if $ThisIsOnlyATest.nil? ############################## def create_mock_subdir() - if @subdir - @file_writer.create_subdir(@subdir) - end + @file_writer.create_subdir(@subdir) end def create_mock_header_file(parsed_stuff) @@ -95,6 +93,7 @@ class CMockGenerator file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n" file << "#ifndef _#{define_name}_H\n" file << "#define _#{define_name}_H\n\n" + file << "#include \"#{@framework}.h\"\n" @includes_h_pre_orig_header.each {|inc| file << "#include #{inc}\n"} file << @config.orig_header_include_fmt.gsub(/%s/, "#{orig_filename}") + "\n" @includes_h_post_orig_header.each {|inc| file << "#include #{inc}\n"} @@ -144,7 +143,6 @@ class CMockGenerator file << "#include \n" file << "#include \n" file << "#include \n" - file << "#include \"#{@framework}.h\"\n" file << "#include \"cmock.h\"\n" @includes_c_pre_header.each {|inc| file << "#include #{inc}\n"} file << "#include \"#{header_file}\"\n" @@ -190,9 +188,15 @@ class CMockGenerator def create_mock_verify_function(file, functions) file << "void #{@clean_mock_name}_Verify(void)\n{\n" - verifications = functions.collect {|function| @plugins.run(:mock_verify, function)}.join - file << " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n" unless verifications.empty? - file << verifications + verifications = functions.collect do |function| + v = @plugins.run(:mock_verify, function) + v.empty? ? v : [" call_instance = Mock.#{function[:name]}_CallInstance;\n", v] + end.join + unless verifications.empty? + file << " UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;\n" + file << " CMOCK_MEM_INDEX_TYPE call_instance;\n" + file << verifications + end file << "}\n\n" end diff --git a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_callback.rb b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_callback.rb index da5508592..564e0ac2b 100644 --- a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_callback.rb +++ b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_callback.rb @@ -16,83 +16,73 @@ class CMockGeneratorPluginCallback @priority = 6 @include_count = @config.callback_include_count - if (@config.callback_after_arg_check) - alias :mock_implementation :mock_implementation_for_callbacks_after_arg_check - alias :mock_implementation_precheck :nothing - else - alias :mock_implementation_precheck :mock_implementation_for_callbacks_without_arg_check - alias :mock_implementation :nothing - end end def instance_structure(function) func_name = function[:name] - " CMOCK_#{func_name}_CALLBACK #{func_name}_CallbackFunctionPointer;\n" + + " int #{func_name}_CallbackBool;\n" \ + " CMOCK_#{func_name}_CALLBACK #{func_name}_CallbackFunctionPointer;\n" \ " int #{func_name}_CallbackCalls;\n" end def mock_function_declarations(function) func_name = function[:name] return_type = function[:return][:type] + action = @config.callback_after_arg_check ? 'AddCallback' : 'Stub' style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2) styles = [ "void", "int cmock_num_calls", function[:args_string], "#{function[:args_string]}, int cmock_num_calls" ] - "typedef #{return_type} (* CMOCK_#{func_name}_CALLBACK)(#{styles[style]});\nvoid #{func_name}_StubWithCallback(CMOCK_#{func_name}_CALLBACK Callback);\n" + "typedef #{return_type} (* CMOCK_#{func_name}_CALLBACK)(#{styles[style]});\n" \ + "void #{func_name}_AddCallback(CMOCK_#{func_name}_CALLBACK Callback);\n" \ + "void #{func_name}_Stub(CMOCK_#{func_name}_CALLBACK Callback);\n" \ + "#define #{func_name}_StubWithCallback #{func_name}_#{action}\n" end - def mock_implementation_for_callbacks_after_arg_check(function) - func_name = function[:name] - style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2) | (function[:return][:void?] ? 0 : 4) - " if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n {\n" + - case(style) - when 0 then " Mock.#{func_name}_CallbackFunctionPointer();\n }\n" - when 1 then " Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n }\n" - when 2 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n }\n" - when 3 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n }\n" - when 4 then " cmock_call_instance->ReturnVal = Mock.#{func_name}_CallbackFunctionPointer();\n }\n" - when 5 then " cmock_call_instance->ReturnVal = Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n }\n" - when 6 then " cmock_call_instance->ReturnVal = Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n }\n" - when 7 then " cmock_call_instance->ReturnVal = Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n }\n" - end + def generate_call(function) + args = function[:args].map { |m| m[:name] } + args << "Mock.#{function[:name]}_CallbackCalls++" if @include_count + "Mock.#{function[:name]}_CallbackFunctionPointer(#{args.join(', ')})" end - def mock_implementation_for_callbacks_without_arg_check(function) - func_name = function[:name] - style = (@include_count ? 1 : 0) | (function[:args].empty? ? 0 : 2) | (function[:return][:void?] ? 0 : 4) - " if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n {\n" + - case(style) - when 0 then " Mock.#{func_name}_CallbackFunctionPointer();\n return;\n }\n" - when 1 then " Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n return;\n }\n" - when 2 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n return;\n }\n" - when 3 then " Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n return;\n }\n" - when 4 then " return Mock.#{func_name}_CallbackFunctionPointer();\n }\n" - when 5 then " return Mock.#{func_name}_CallbackFunctionPointer(Mock.#{func_name}_CallbackCalls++);\n }\n" - when 6 then " return Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')});\n }\n" - when 7 then " return Mock.#{func_name}_CallbackFunctionPointer(#{function[:args].map{|m| m[:name]}.join(', ')}, Mock.#{func_name}_CallbackCalls++);\n }\n" - end + def mock_implementation(function) + " if (Mock.#{function[:name]}_CallbackFunctionPointer != NULL)\n {\n" + + if function[:return][:void?] + " #{generate_call(function)};\n }\n" + else + " cmock_call_instance->ReturnVal = #{generate_call(function)};\n }\n" + end end - def nothing(function) - return "" + def mock_implementation_precheck(function) + " if (!Mock.#{function[:name]}_CallbackBool &&\n" \ + " Mock.#{function[:name]}_CallbackFunctionPointer != NULL)\n {\n" + + if function[:return][:void?] + " #{generate_call(function)};\n" \ + " UNITY_CLR_DETAILS();\n" \ + " return;\n }\n" + else + " #{function[:return][:type]} ret = #{generate_call(function)};\n" \ + " UNITY_CLR_DETAILS();\n" \ + " return ret;\n }\n" + end end def mock_interfaces(function) func_name = function[:name] + has_ignore = @config.plugins.include? :ignore lines = "" - lines << "void #{func_name}_StubWithCallback(CMOCK_#{func_name}_CALLBACK Callback)\n{\n" - if @config.plugins.include? :ignore - lines << " Mock.#{func_name}_IgnoreBool = (int)0;\n" - end + lines << "void #{func_name}_AddCallback(CMOCK_#{func_name}_CALLBACK Callback)\n{\n" + lines << " Mock.#{func_name}_IgnoreBool = (int)0;\n" if has_ignore + lines << " Mock.#{func_name}_CallbackBool = (int)1;\n" + lines << " Mock.#{func_name}_CallbackFunctionPointer = Callback;\n}\n\n" + lines << "void #{func_name}_Stub(CMOCK_#{func_name}_CALLBACK Callback)\n{\n" + lines << " Mock.#{func_name}_IgnoreBool = (int)0;\n" if has_ignore + lines << " Mock.#{func_name}_CallbackBool = (int)0;\n" lines << " Mock.#{func_name}_CallbackFunctionPointer = Callback;\n}\n\n" - end - - def mock_destroy(function) - " Mock.#{function[:name]}_CallbackFunctionPointer = NULL;\n" + - " Mock.#{function[:name]}_CallbackCalls = 0;\n" end def mock_verify(function) func_name = function[:name] - " if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n Mock.#{func_name}_CallInstance = CMOCK_GUTS_NONE;\n" + " if (Mock.#{func_name}_CallbackFunctionPointer != NULL)\n call_instance = CMOCK_GUTS_NONE;\n" end end diff --git a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb index 19fb41b6b..dcf96f2ed 100644 --- a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb +++ b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb @@ -64,7 +64,7 @@ class CMockGeneratorPluginExpect def mock_implementation_might_check_args(function) return "" if (function[:args].empty?) - lines = " if (cmock_call_instance->IgnoreMode != CMOCK_ARG_NONE)\n {\n" + lines = " if (!cmock_call_instance->ExpectAnyArgsBool)\n {\n" function[:args].each do |arg| lines << @utils.code_verify_an_arg_expectation(function, arg) end @@ -91,14 +91,13 @@ class CMockGeneratorPluginExpect lines << @utils.code_add_base_expectation(func_name) lines << @utils.code_call_argument_loader(function) lines << @utils.code_assign_argument_quickly("cmock_call_instance->ReturnVal", function[:return]) unless (function[:return][:void?]) - lines << " UNITY_CLR_DETAILS();\n" lines << "}\n\n" end def mock_verify(function) - func_name = function[:name] " UNITY_SET_DETAIL(CMockString_#{function[:name]});\n" + - " UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.#{func_name}_CallInstance, cmock_line, CMockStringCalledLess);\n" + " UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == call_instance, cmock_line, CMockStringCalledLess);\n" + + " UNITY_CLR_DETAILS();\n" end end diff --git a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect_any_args.rb b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect_any_args.rb index 0e80844b2..0c1c74e95 100644 --- a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect_any_args.rb +++ b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect_any_args.rb @@ -15,40 +15,39 @@ class CMockGeneratorPluginExpectAnyArgs @priority = 3 end - def instance_structure(function) - if (function[:return][:void?]) || (@config.plugins.include? :ignore) - "" - else - " #{function[:return][:type]} #{function[:name]}_FinalReturn;\n" - end - end - def instance_typedefs(function) - " CMOCK_ARG_MODE IgnoreMode;\n" + " int ExpectAnyArgsBool;\n" end def mock_function_declarations(function) - if (function[:return][:void?]) - return "#define #{function[:name]}_ExpectAnyArgs() #{function[:name]}_CMockExpectAnyArgs(__LINE__)\n" + - "void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line);\n" + unless (function[:args].empty?) + if (function[:return][:void?]) + return "#define #{function[:name]}_ExpectAnyArgs() #{function[:name]}_CMockExpectAnyArgs(__LINE__)\n" + + "void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line);\n" + else + return "#define #{function[:name]}_ExpectAnyArgsAndReturn(cmock_retval) #{function[:name]}_CMockExpectAnyArgsAndReturn(__LINE__, cmock_retval)\n" + + "void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n" + end else - return "#define #{function[:name]}_ExpectAnyArgsAndReturn(cmock_retval) #{function[:name]}_CMockExpectAnyArgsAndReturn(__LINE__, cmock_retval)\n" + - "void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n" + "" end end def mock_interfaces(function) lines = "" - if (function[:return][:void?]) - lines << "void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line)\n{\n" - else - lines << "void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n" + unless (function[:args].empty?) + if (function[:return][:void?]) + lines << "void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line)\n{\n" + else + lines << "void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n" + end + lines << @utils.code_add_base_expectation(function[:name], true) + unless (function[:return][:void?]) + lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n" + end + lines << " cmock_call_instance->ExpectAnyArgsBool = (int)1;\n" + lines << "}\n\n" end - lines << @utils.code_add_base_expectation(function[:name], true) - unless (function[:return][:void?]) - lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n" - end - lines << " cmock_call_instance->IgnoreMode = CMOCK_ARG_NONE;\n" - lines << "}\n\n" + return lines end end diff --git a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore.rb b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore.rb index a291dd4cc..8f31967a1 100644 --- a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore.rb +++ b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_ignore.rb @@ -70,6 +70,6 @@ class CMockGeneratorPluginIgnore def mock_verify(function) func_name = function[:name] - " if (Mock.#{func_name}_IgnoreBool)\n Mock.#{func_name}_CallInstance = CMOCK_GUTS_NONE;\n" + " if (Mock.#{func_name}_IgnoreBool)\n call_instance = CMOCK_GUTS_NONE;\n" end end diff --git a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_return_thru_ptr.rb b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_return_thru_ptr.rb index 5c3a9597f..1c1af0610 100644 --- a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_return_thru_ptr.rb +++ b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_return_thru_ptr.rb @@ -24,7 +24,13 @@ class CMockGeneratorPluginReturnThruPtr function[:args].each do |arg| if (@utils.ptr_or_str?(arg[:type]) and not arg[:const?]) lines << "#define #{function[:name]}_ReturnThruPtr_#{arg[:name]}(#{arg[:name]})" - lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(*#{arg[:name]}))\n" + # If the pointer type actually contains an asterisk, we can do sizeof the type (super safe), otherwise + # we need to do a sizeof the dereferenced pointer (which could be a problem if give the wrong size + if (arg[:type][-1] == '*') + lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(#{arg[:type][0..-2]}))\n" + else + lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(*#{arg[:name]}))\n" + end lines << "#define #{function[:name]}_ReturnArrayThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_len)" lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, (int)(cmock_len * (int)sizeof(*#{arg[:name]})))\n" lines << "#define #{function[:name]}_ReturnMemThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_size)" diff --git a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_utils.rb b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_utils.rb index eb12e2363..994e85c5d 100644 --- a/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_utils.rb +++ b/test/vendor/ceedling/vendor/cmock/lib/cmock_generator_utils.rb @@ -19,7 +19,7 @@ class CMockGeneratorUtils @ignore_arg = @config.plugins.include? :ignore_arg @ignore = @config.plugins.include? :ignore @treat_as = @config.treat_as - @helpers = helpers + @helpers = helpers end def self.arg_type_with_const(arg) @@ -57,7 +57,7 @@ class CMockGeneratorUtils lines << " cmock_call_instance->LineNumber = cmock_line;\n" lines << " cmock_call_instance->CallOrder = ++GlobalExpectCount;\n" if (@ordered and global_ordering_supported) lines << " cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n" if (@cexception) - lines << " cmock_call_instance->IgnoreMode = CMOCK_ARG_ALL;\n" if (@expect_any) + lines << " cmock_call_instance->ExpectAnyArgsBool = (int)0;\n" if (@expect_any) lines end @@ -73,7 +73,10 @@ class CMockGeneratorUtils if (arg[:ptr?] or @treat_as.include?(arg[:type])) " #{dest} = #{arg[:name]};\n" else - " memcpy(&#{dest}, &#{arg[:name]}, sizeof(#{arg[:type]}));\n" + assert_expr = "sizeof(#{arg[:name]}) == sizeof(#{arg[:type]}) ? 1 : -1" + comment = "/* add #{arg[:type]} to :treat_as_array if this causes an error */" + " memcpy((void*)(&#{dest}), (void*)(&#{arg[:name]}),\n" + + " sizeof(#{arg[:type]}[#{assert_expr}])); #{comment}\n" end end @@ -84,10 +87,12 @@ class CMockGeneratorUtils type = arg_type_with_const(m) m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{type} #{m[:name]}" end.join(', ') + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string});\n" + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string})\n{\n" + function[:args].inject("") { |all, arg| all + code_add_an_arg_expectation(arg, (arg[:ptr?] ? "#{arg[:name]}_Depth" : 1) ) } + "}\n\n" else + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]});\n" + "void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]})\n{\n" + function[:args].inject("") { |all, arg| all + code_add_an_arg_expectation(arg) } + "}\n\n" @@ -100,7 +105,13 @@ class CMockGeneratorUtils def code_call_argument_loader(function) if (function[:args_string] != "void") args = function[:args].map do |m| - (@arrays and m[:ptr?]) ? "#{m[:name]}, 1" : m[:name] + if (@arrays and m[:ptr?] and not m[:array_data?]) + "#{m[:name]}, 1" + elsif (@arrays and m[:array_size?]) + "#{m[:name]}, #{m[:name]}" + else + m[:name] + end end " CMockExpectParameters_#{function[:name]}(cmock_call_instance, #{args.join(', ')});\n" else @@ -170,6 +181,7 @@ class CMockGeneratorUtils lines << " if (!#{ignore})\n" if @ignore_arg lines << " {\n" lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n" + lines << " if (#{pre}#{expected} != #{pre}#{arg_name}) {\n" case(unity_func) when "UNITY_TEST_ASSERT_EQUAL_MEMORY" c_type_local = c_type.gsub(/\*$/,'') @@ -195,7 +207,7 @@ class CMockGeneratorUtils else lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n" end - lines << " }\n" + lines << " }\n }\n" lines end @@ -206,6 +218,7 @@ class CMockGeneratorUtils lines << " if (!#{ignore})\n" if @ignore_arg lines << " {\n" lines << " UNITY_SET_DETAILS(CMockString_#{function[:name]},CMockString_#{arg_name});\n" + lines << " if (#{pre}#{expected} != #{pre}#{arg_name}) {\n" case(unity_func) when "UNITY_TEST_ASSERT_EQUAL_MEMORY" c_type_local = c_type.gsub(/\*$/,'') @@ -233,7 +246,7 @@ class CMockGeneratorUtils else lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, CMockStringMismatch);\n" end - lines << " }\n" + lines << " }\n }\n" lines end diff --git a/test/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb b/test/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb index ee0fe6ab1..0cf19478d 100644 --- a/test/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb +++ b/test/vendor/ceedling/vendor/cmock/lib/cmock_header_parser.rb @@ -14,9 +14,12 @@ class CMockHeaderParser @c_attr_noconst = cfg.attributes.uniq - ['const'] @c_attributes = ['const'] + c_attr_noconst @c_calling_conventions = cfg.c_calling_conventions.uniq + @treat_as_array = cfg.treat_as_array @treat_as_void = (['void'] + cfg.treat_as_void).uniq - @declaration_parse_matcher = /([\d\w\s\*\(\),\[\]]+??)\(([\d\w\s\*\(\),\.\[\]+-]*)\)$/m + @declaration_parse_matcher = /([\w\s\*\(\),\[\]]+??)\(([\w\s\*\(\),\.\[\]+-]*)\)$/m @standards = (['int','short','char','long','unsigned','signed'] + cfg.treat_as.keys).uniq + @array_size_name = cfg.array_size_name + @array_size_type = (['int', 'size_t'] + cfg.array_size_type).uniq @when_no_prototypes = cfg.when_no_prototypes @local_as_void = @treat_as_void @verbosity = cfg.verbosity @@ -54,7 +57,7 @@ class CMockHeaderParser # void must be void for cmock _ExpectAndReturn calls to process properly, not some weird typedef which equates to void # to a certain extent, this action assumes we're chewing on pre-processed header files, otherwise we'll most likely just get stuff from @treat_as_void @local_as_void = @treat_as_void - void_types = source.scan(/typedef\s+(?:\(\s*)?void(?:\s*\))?\s+([\w\d]+)\s*;/) + void_types = source.scan(/typedef\s+(?:\(\s*)?void(?:\s*\))?\s+([\w]+)\s*;/) if void_types @local_as_void += void_types.flatten.uniq.compact end @@ -63,9 +66,9 @@ class CMockHeaderParser source.gsub!(/\s*\\\s*/m, ' ') #remove comments (block and line, in three steps to ensure correct precedence) - source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks - source.gsub!(/\/\*.*?\*\//m, '') # remove block comments - source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain) + source.gsub!(/(? * , <@array_size_type> <@array_size_name> + args.each_with_index {|val, index| + next_index = index + 1 + if (args.length > next_index) + if (val[:ptr?] == true and args[next_index][:name].match(@array_size_name) and @array_size_type.include?(args[next_index][:type])) + val[:array_data?] = true + args[next_index][:array_size?] = true + end + end + } + return args end @@ -220,7 +247,7 @@ class CMockHeaderParser return 'void' else c=0 - arg_list.gsub!(/(\w+)(?:\s*\[\s*\(*[\s\d\w+-]*\)*\s*\])+/,'*\1') # magically turn brackets into asterisks, also match for parentheses that come from macros + arg_list.gsub!(/(\w+)(?:\s*\[\s*\(*[\s\w+-]*\)*\s*\])+/,'*\1') # magically turn brackets into asterisks, also match for parentheses that come from macros arg_list.gsub!(/\s+\*/,'*') # remove space to place asterisks with type (where they belong) arg_list.gsub!(/\*(\w)/,'* \1') # pull asterisks away from arg to place asterisks with type (where they belong) diff --git a/test/vendor/ceedling/vendor/cmock/src/cmock.c b/test/vendor/ceedling/vendor/cmock/src/cmock.c index 318f4c7a3..5e5cb6c72 100644 --- a/test/vendor/ceedling/vendor/cmock/src/cmock.c +++ b/test/vendor/ceedling/vendor/cmock/src/cmock.c @@ -4,13 +4,12 @@ [Released under MIT License. Please refer to license.txt for details] ========================================== */ -#include "unity.h" #include "cmock.h" //public constants to be used by mocks const char* CMockStringOutOfMemory = "CMock has run out of memory. Please allocate more."; const char* CMockStringCalledMore = "Called more times than expected."; -const char* CMockStringCalledLess = "Called less times than expected."; +const char* CMockStringCalledLess = "Called fewer times than expected."; const char* CMockStringCalledEarly = "Called earlier than expected."; const char* CMockStringCalledLate = "Called later than expected."; const char* CMockStringCallOrder = "Called out of order."; @@ -24,12 +23,11 @@ const char* CMockStringMismatch = "Function called with unexpected argument v #ifdef CMOCK_MEM_DYNAMIC static unsigned char* CMock_Guts_Buffer = NULL; static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_ALIGN_SIZE; -static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr; +static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; #else -static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferArray[(CMOCK_MEM_SIZE + CMOCK_MEM_INDEX_SIZE - 1) / CMOCK_MEM_INDEX_SIZE]; -#define CMock_Guts_Buffer ((unsigned char*)CMock_Guts_BufferArray) +static unsigned char CMock_Guts_Buffer[CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE]; static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE; -static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr; +static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; #endif //------------------------------------------------------- @@ -169,6 +167,14 @@ void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index) } } +//------------------------------------------------------- +// CMock_Guts_MemBytesCapacity +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void) +{ + return (sizeof(CMock_Guts_Buffer) - CMOCK_MEM_ALIGN_SIZE); +} + //------------------------------------------------------- // CMock_Guts_MemBytesFree //------------------------------------------------------- diff --git a/test/vendor/ceedling/vendor/cmock/src/cmock.h b/test/vendor/ceedling/vendor/cmock/src/cmock.h index a31344807..e96546dab 100644 --- a/test/vendor/ceedling/vendor/cmock/src/cmock.h +++ b/test/vendor/ceedling/vendor/cmock/src/cmock.h @@ -9,6 +9,11 @@ #include "cmock_internals.h" +#define CMOCK_VERSION_MAJOR 2 +#define CMOCK_VERSION_MINOR 5 +#define CMOCK_VERSION_BUILD 0 +#define CMOCK_VERSION ((CMOCK_VERSION_MAJOR << 16) | (CMOCK_VERSION_MINOR << 8) | CMOCK_VERSION_BUILD) + //should be big enough to index full range of CMOCK_MEM_MAX #ifndef CMOCK_MEM_INDEX_TYPE #define CMOCK_MEM_INDEX_TYPE unsigned int @@ -16,10 +21,6 @@ #define CMOCK_GUTS_NONE (0) -#define CMOCK_ARG_MODE CMOCK_MEM_INDEX_TYPE -#define CMOCK_ARG_ALL 0 -#define CMOCK_ARG_NONE ((CMOCK_MEM_INDEX_TYPE)(~0U)) - //------------------------------------------------------- // Memory API //------------------------------------------------------- @@ -30,6 +31,7 @@ CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index); void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void); CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void); CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void); void CMock_Guts_MemFreeAll(void); diff --git a/test/vendor/ceedling/vendor/cmock/src/cmock_internals.h b/test/vendor/ceedling/vendor/cmock/src/cmock_internals.h index 5c922adf1..ae2e4962f 100644 --- a/test/vendor/ceedling/vendor/cmock/src/cmock_internals.h +++ b/test/vendor/ceedling/vendor/cmock/src/cmock_internals.h @@ -7,6 +7,8 @@ #ifndef CMOCK_FRAMEWORK_INTERNALS_H #define CMOCK_FRAMEWORK_INTERNALS_H +#include "unity.h" + //These are constants that the generated mocks have access to extern const char* CMockStringOutOfMemory; extern const char* CMockStringCalledMore; diff --git a/test/vendor/ceedling/vendor/cmock/src/meson.build b/test/vendor/ceedling/vendor/cmock/src/meson.build new file mode 100644 index 000000000..e375e81a1 --- /dev/null +++ b/test/vendor/ceedling/vendor/cmock/src/meson.build @@ -0,0 +1,17 @@ +################################################################################### +# # +# NAME: meson.build # +# # +# AUTHOR: Mike Karlesky, Mark VanderVoord, Greg Williams. # +# WRITTEN BY: Michael Brockus. # +# # +# License: MIT # +# # +################################################################################### + +cmock_dir = include_directories('.') + +cmock_lib = static_library(meson.project_name(), + sources: ['cmock.c'], + dependencies: [unity_dep], + include_directories: cmock_dir) diff --git a/test/vendor/ceedling/vendor/unity/auto/colour_prompt.rb b/test/vendor/ceedling/vendor/unity/auto/colour_prompt.rb index 0f1dc4e02..85cbfd80c 100644 --- a/test/vendor/ceedling/vendor/unity/auto/colour_prompt.rb +++ b/test/vendor/ceedling/vendor/unity/auto/colour_prompt.rb @@ -22,9 +22,10 @@ end class ColourCommandLine def initialize return unless RUBY_PLATFORM =~ /(win|w)32$/ + get_std_handle = Win32API.new('kernel32', 'GetStdHandle', ['L'], 'L') @set_console_txt_attrb = - Win32API.new('kernel32', 'SetConsoleTextAttribute', %w(L N), 'I') + Win32API.new('kernel32', 'SetConsoleTextAttribute', %w[L N], 'I') @hout = get_std_handle.call(-11) end @@ -107,7 +108,7 @@ class ColourCommandLine $stdout.print("#{change_to(colour)}#{str}\033[0m") if mode == :print end end -end # ColourCommandLine +end def colour_puts(role, str) ColourCommandLine.new.out_c(:puts, role, str) diff --git a/test/vendor/ceedling/vendor/unity/auto/colour_reporter.rb b/test/vendor/ceedling/vendor/unity/auto/colour_reporter.rb index bb1fbfce3..1c3bc2162 100644 --- a/test/vendor/ceedling/vendor/unity/auto/colour_reporter.rb +++ b/test/vendor/ceedling/vendor/unity/auto/colour_reporter.rb @@ -4,7 +4,7 @@ # [Released under MIT License. Please refer to license.txt for details] # ========================================== -require "#{File.expand_path(File.dirname(__FILE__))}/colour_prompt" +require_relative 'colour_prompt' $colour_output = true diff --git a/test/vendor/ceedling/vendor/unity/auto/generate_module.rb b/test/vendor/ceedling/vendor/unity/auto/generate_module.rb index 13b4cc74d..eb2cebd47 100644 --- a/test/vendor/ceedling/vendor/unity/auto/generate_module.rb +++ b/test/vendor/ceedling/vendor/unity/auto/generate_module.rb @@ -14,6 +14,7 @@ require 'pathname' # TEMPLATE_TST TEMPLATE_TST ||= '#include "unity.h" + %2$s#include "%1$s.h" void setUp(void) @@ -35,18 +36,16 @@ TEMPLATE_SRC ||= '%2$s#include "%1$s.h" '.freeze # TEMPLATE_INC -TEMPLATE_INC ||= '#ifndef _%3$s_H -#define _%3$s_H +TEMPLATE_INC ||= '#ifndef %3$s_H +#define %3$s_H %2$s -#endif // _%3$s_H +#endif // %3$s_H '.freeze class UnityModuleGenerator ############################ def initialize(options = nil) - here = File.expand_path(File.dirname(__FILE__)) + '/' - @options = UnityModuleGenerator.default_options case options when NilClass then @options @@ -56,9 +55,9 @@ class UnityModuleGenerator end # Create default file paths if none were provided - @options[:path_src] = here + '../src/' if @options[:path_src].nil? - @options[:path_inc] = @options[:path_src] if @options[:path_inc].nil? - @options[:path_tst] = here + '../test/' if @options[:path_tst].nil? + @options[:path_src] = "#{__dir__}/../src/" if @options[:path_src].nil? + @options[:path_inc] = @options[:path_src] if @options[:path_inc].nil? + @options[:path_tst] = "#{__dir__}/../test/" if @options[:path_tst].nil? @options[:path_src] += '/' unless @options[:path_src][-1] == 47 @options[:path_inc] += '/' unless @options[:path_inc][-1] == 47 @options[:path_tst] += '/' unless @options[:path_tst][-1] == 47 @@ -265,6 +264,7 @@ if $0 == __FILE__ when /^-y\"?(.+)\"?/ then options = UnityModuleGenerator.grab_config(Regexp.last_match(1)) when /^(\w+)/ raise "ERROR: You can't have more than one Module name specified!" unless module_name.nil? + module_name = arg when /^-(h|-help)/ ARGV = [].freeze @@ -299,6 +299,7 @@ if $0 == __FILE__ end raise 'ERROR: You must have a Module name specified! (use option -h for help)' if module_name.nil? + if destroy UnityModuleGenerator.new(options).destroy(module_name) else diff --git a/test/vendor/ceedling/vendor/unity/auto/generate_test_runner.rb b/test/vendor/ceedling/vendor/unity/auto/generate_test_runner.rb index 84daa42de..5053210d0 100644 --- a/test/vendor/ceedling/vendor/unity/auto/generate_test_runner.rb +++ b/test/vendor/ceedling/vendor/unity/auto/generate_test_runner.rb @@ -4,18 +4,25 @@ # [Released under MIT License. Please refer to license.txt for details] # ========================================== -File.expand_path(File.join(File.dirname(__FILE__), 'colour_prompt')) - class UnityTestRunnerGenerator def initialize(options = nil) @options = UnityTestRunnerGenerator.default_options case options - when NilClass then @options - when String then @options.merge!(UnityTestRunnerGenerator.grab_config(options)) - when Hash then @options.merge!(options) - else raise 'If you specify arguments, it should be a filename or a hash of options' + when NilClass + @options + when String + @options.merge!(UnityTestRunnerGenerator.grab_config(options)) + when Hash + # Check if some of these have been specified + @options[:has_setup] = !options[:setup_name].nil? + @options[:has_teardown] = !options[:teardown_name].nil? + @options[:has_suite_setup] = !options[:suite_setup].nil? + @options[:has_suite_teardown] = !options[:suite_teardown].nil? + @options.merge!(options) + else + raise 'If you specify arguments, it should be a filename or a hash of options' end - require "#{File.expand_path(File.dirname(__FILE__))}/type_sanitizer" + require_relative 'type_sanitizer' end def self.default_options @@ -29,9 +36,12 @@ class UnityTestRunnerGenerator mock_suffix: '', setup_name: 'setUp', teardown_name: 'tearDown', + test_reset_name: 'resetTest', + test_verify_name: 'verifyTest', main_name: 'main', # set to :auto to automatically generate each time main_export_decl: '', cmdline_args: false, + omit_begin_end: false, use_param_tests: false } end @@ -53,12 +63,13 @@ class UnityTestRunnerGenerator # pull required data from source file source = File.read(input_file) source = source.force_encoding('ISO-8859-1').encode('utf-8', replace: nil) - tests = find_tests(source) - headers = find_includes(source) - testfile_includes = (headers[:local] + headers[:system]) - used_mocks = find_mocks(testfile_includes) - testfile_includes = (testfile_includes - used_mocks) + tests = find_tests(source) + headers = find_includes(source) + testfile_includes = (headers[:local] + headers[:system]) + used_mocks = find_mocks(testfile_includes) + testfile_includes = (testfile_includes - used_mocks) testfile_includes.delete_if { |inc| inc =~ /(unity|cmock)/ } + find_setup_and_teardown(source) # build runner file generate(input_file, output_file, tests, used_mocks, testfile_includes) @@ -76,9 +87,13 @@ class UnityTestRunnerGenerator create_header(output, used_mocks, testfile_includes) create_externs(output, tests, used_mocks) create_mock_management(output, used_mocks) + create_setup(output) + create_teardown(output) create_suite_setup(output) create_suite_teardown(output) - create_reset(output, used_mocks) + create_reset(output) + create_run_test(output) + create_args_wrappers(output, tests) create_main(output, input_file, tests, used_mocks) end @@ -92,27 +107,43 @@ class UnityTestRunnerGenerator def find_tests(source) tests_and_line_numbers = [] + # contains characters which will be substituted from within strings, doing + # this prevents these characters from interferring with scrubbers + # @ is not a valid C character, so there should be no clashes with files genuinely containing these markers + substring_subs = { '{' => '@co@', '}' => '@cc@', ';' => '@ss@', '/' => '@fs@' } + substring_re = Regexp.union(substring_subs.keys) + substring_unsubs = substring_subs.invert # the inverse map will be used to fix the strings afterwords + substring_unsubs['@quote@'] = '\\"' + substring_unsubs['@apos@'] = '\\\'' + substring_unre = Regexp.union(substring_unsubs.keys) source_scrubbed = source.clone - source_scrubbed = source_scrubbed.gsub(/"[^"\n]*"/, '') # remove things in strings - source_scrubbed = source_scrubbed.gsub(/\/\/.*$/, '') # remove line comments - source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments - lines = source_scrubbed.split(/(^\s*\#.*$) # Treat preprocessor directives as a logical line - | (;|\{|\}) /x) # Match ;, {, and } as end of lines + source_scrubbed = source_scrubbed.gsub(/\\"/, '@quote@') # hide escaped quotes to allow capture of the full string/char + source_scrubbed = source_scrubbed.gsub(/\\'/, '@apos@') # hide escaped apostrophes to allow capture of the full string/char + source_scrubbed = source_scrubbed.gsub(/("[^"\n]*")|('[^'\n]*')/) { |s| s.gsub(substring_re, substring_subs) } # temporarily hide problematic characters within strings + source_scrubbed = source_scrubbed.gsub(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks + source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments + source_scrubbed = source_scrubbed.gsub(/\/\/.*$/, '') # remove line comments (all that remain) + lines = source_scrubbed.split(/(^\s*\#.*$) | (;|\{|\}) /x) # Treat preprocessor directives as a logical line. Match ;, {, and } as end of lines + .map { |line| line.gsub(substring_unre, substring_unsubs) } # unhide the problematic characters previously removed lines.each_with_index do |line, _index| # find tests - next unless line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/ + next unless line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/m + arguments = Regexp.last_match(1) name = Regexp.last_match(2) call = Regexp.last_match(3) params = Regexp.last_match(4) args = nil + if @options[:use_param_tests] && !arguments.empty? args = [] arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) { |a| args << a[0] } end + tests_and_line_numbers << { test: name, args: args, call: call, params: params, line_number: 0 } end + tests_and_line_numbers.uniq! { |v| v[:test] } # determine line numbers and create tests to run @@ -121,6 +152,7 @@ class UnityTestRunnerGenerator tests_and_line_numbers.size.times do |i| source_lines[source_index..-1].each_with_index do |line, index| next unless line =~ /\s+#{tests_and_line_numbers[i][:test]}(?:\s|\()/ + source_index += index tests_and_line_numbers[i][:line_number] = source_index + 1 break @@ -154,21 +186,20 @@ class UnityTestRunnerGenerator mock_headers end + def find_setup_and_teardown(source) + @options[:has_setup] = source =~ /void\s+#{@options[:setup_name]}\s*\(/ + @options[:has_teardown] = source =~ /void\s+#{@options[:teardown_name]}\s*\(/ + @options[:has_suite_setup] ||= (source =~ /void\s+suiteSetUp\s*\(/) + @options[:has_suite_teardown] ||= (source =~ /void\s+suiteTearDown\s*\(/) + end + def create_header(output, mocks, testfile_includes = []) output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */') - create_runtest(output, mocks) output.puts("\n/*=======Automagically Detected Files To Include=====*/") - output.puts('#ifdef __WIN32__') - output.puts('#define UNITY_INCLUDE_SETUP_STUBS') - output.puts('#endif') output.puts("#include \"#{@options[:framework]}.h\"") output.puts('#include "cmock.h"') unless mocks.empty? - output.puts('#ifndef UNITY_EXCLUDE_SETJMP_H') - output.puts('#include ') - output.puts("#endif") - output.puts('#include ') if @options[:defines] && !@options[:defines].empty? - @options[:defines].each { |d| output.puts("#define #{d}") } + @options[:defines].each { |d| output.puts("#ifndef #{d}\n#define #{d}\n#endif /* #{d} */") } end if @options[:header_file] && !@options[:header_file].empty? output.puts("#include \"#{File.basename(@options[:header_file])}\"") @@ -197,15 +228,15 @@ class UnityTestRunnerGenerator output.puts("\n/*=======External Functions This Runner Calls=====*/") output.puts("extern void #{@options[:setup_name]}(void);") output.puts("extern void #{@options[:teardown_name]}(void);") + output.puts("\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif") if @options[:externc] tests.each do |test| output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});") end + output.puts("#ifdef __cplusplus\n}\n#endif") if @options[:externc] output.puts('') end def create_mock_management(output, mock_headers) - return if mock_headers.empty? - output.puts("\n/*=======Mock Management=====*/") output.puts('static void CMock_Init(void)') output.puts('{') @@ -240,84 +271,78 @@ class UnityTestRunnerGenerator output.puts("}\n") end + def create_setup(output) + return if @options[:has_setup] + + output.puts("\n/*=======Setup (stub)=====*/") + output.puts("void #{@options[:setup_name]}(void) {}") + end + + def create_teardown(output) + return if @options[:has_teardown] + + output.puts("\n/*=======Teardown (stub)=====*/") + output.puts("void #{@options[:teardown_name]}(void) {}") + end + def create_suite_setup(output) + return if @options[:suite_setup].nil? + output.puts("\n/*=======Suite Setup=====*/") - output.puts('static void suite_setup(void)') + output.puts('void suiteSetUp(void)') output.puts('{') - if @options[:suite_setup].nil? - # New style, call suiteSetUp() if we can use weak symbols - output.puts('#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA)') - output.puts(' suiteSetUp();') - output.puts('#endif') - else - # Old style, C code embedded in the :suite_setup option - output.puts(@options[:suite_setup]) - end + output.puts(@options[:suite_setup]) output.puts('}') end def create_suite_teardown(output) + return if @options[:suite_teardown].nil? + output.puts("\n/*=======Suite Teardown=====*/") - output.puts('static int suite_teardown(int num_failures)') + output.puts('int suiteTearDown(int num_failures)') output.puts('{') - if @options[:suite_teardown].nil? - # New style, call suiteTearDown() if we can use weak symbols - output.puts('#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA)') - output.puts(' return suiteTearDown(num_failures);') - output.puts('#else') - output.puts(' return num_failures;') - output.puts('#endif') - else - # Old style, C code embedded in the :suite_teardown option - output.puts(@options[:suite_teardown]) - end + output.puts(@options[:suite_teardown]) output.puts('}') end - def create_runtest(output, used_mocks) - cexception = @options[:plugins].include? :cexception - va_args1 = @options[:use_param_tests] ? ', ...' : '' - va_args2 = @options[:use_param_tests] ? '__VA_ARGS__' : '' - output.puts("\n/*=======Test Runner Used To Run Each Test Below=====*/") - output.puts('#define RUN_TEST_NO_ARGS') if @options[:use_param_tests] - output.puts("#define RUN_TEST(TestFunc, TestLineNum#{va_args1}) \\") - output.puts('{ \\') - output.puts(" Unity.CurrentTestName = #TestFunc#{va_args2.empty? ? '' : " \"(\" ##{va_args2} \")\""}; \\") - output.puts(' Unity.CurrentTestLineNumber = TestLineNum; \\') - output.puts(' if (UnityTestMatches()) { \\') if @options[:cmdline_args] - output.puts(' Unity.NumberOfTests++; \\') - output.puts(' CMock_Init(); \\') unless used_mocks.empty? - output.puts(' UNITY_CLR_DETAILS(); \\') unless used_mocks.empty? - output.puts(' if (TEST_PROTECT()) \\') - output.puts(' { \\') - output.puts(' CEXCEPTION_T e; \\') if cexception - output.puts(' Try { \\') if cexception - output.puts(" #{@options[:setup_name]}(); \\") - output.puts(" TestFunc(#{va_args2}); \\") - output.puts(' } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, "Unhandled Exception!"); } \\') if cexception - output.puts(' } \\') - output.puts(' if (TEST_PROTECT()) \\') - output.puts(' { \\') - output.puts(" #{@options[:teardown_name]}(); \\") - output.puts(' CMock_Verify(); \\') unless used_mocks.empty? - output.puts(' } \\') - output.puts(' CMock_Destroy(); \\') unless used_mocks.empty? - output.puts(' UnityConcludeTest(); \\') - output.puts(' } \\') if @options[:cmdline_args] - output.puts("}\n") - end - - def create_reset(output, used_mocks) - output.puts("\n/*=======Test Reset Option=====*/") - output.puts('void resetTest(void);') - output.puts('void resetTest(void)') + def create_reset(output) + output.puts("\n/*=======Test Reset Options=====*/") + output.puts("void #{@options[:test_reset_name]}(void);") + output.puts("void #{@options[:test_reset_name]}(void)") output.puts('{') - output.puts(' CMock_Verify();') unless used_mocks.empty? - output.puts(' CMock_Destroy();') unless used_mocks.empty? output.puts(" #{@options[:teardown_name]}();") - output.puts(' CMock_Init();') unless used_mocks.empty? + output.puts(' CMock_Verify();') + output.puts(' CMock_Destroy();') + output.puts(' CMock_Init();') output.puts(" #{@options[:setup_name]}();") output.puts('}') + output.puts("void #{@options[:test_verify_name]}(void);") + output.puts("void #{@options[:test_verify_name]}(void)") + output.puts('{') + output.puts(' CMock_Verify();') + output.puts('}') + end + + def create_run_test(output) + require 'erb' + template = ERB.new(File.read(File.join(__dir__, 'run_test.erb'))) + output.puts(template.result(binding)) + end + + def create_args_wrappers(output, tests) + return unless @options[:use_param_tests] + + output.puts("\n/*=======Parameterized Test Wrappers=====*/") + tests.each do |test| + next if test[:args].nil? || test[:args].empty? + + test[:args].each.with_index(1) do |args, idx| + output.puts("static void runner_args#{idx}_#{test[:test]}(void)") + output.puts('{') + output.puts(" #{test[:test]}(#{args});") + output.puts("}\n") + end + end end def create_main(output, filename, tests, used_mocks) @@ -336,48 +361,57 @@ class UnityTestRunnerGenerator output.puts(' {') output.puts(" UnityPrint(\"#{filename.gsub('.c', '')}.\");") output.puts(' UNITY_PRINT_EOL();') - if @options[:use_param_tests] - tests.each do |test| - if test[:args].nil? || test[:args].empty? - output.puts(" UnityPrint(\" #{test[:test]}(RUN_TEST_NO_ARGS)\");") + tests.each do |test| + if (!@options[:use_param_tests]) || test[:args].nil? || test[:args].empty? + output.puts(" UnityPrint(\" #{test[:test]}\");") + output.puts(' UNITY_PRINT_EOL();') + else + test[:args].each do |args| + output.puts(" UnityPrint(\" #{test[:test]}(#{args})\");") output.puts(' UNITY_PRINT_EOL();') - else - test[:args].each do |args| - output.puts(" UnityPrint(\" #{test[:test]}(#{args})\");") - output.puts(' UNITY_PRINT_EOL();') - end end end - else - tests.each { |test| output.puts(" UnityPrint(\" #{test[:test]}\");\n UNITY_PRINT_EOL();") } end - output.puts(' return 0;') + output.puts(' return 0;') output.puts(' }') - output.puts(' return parse_status;') + output.puts(' return parse_status;') output.puts(' }') else + main_return = @options[:omit_begin_end] ? 'void' : 'int' if main_name != 'main' - output.puts("#{@options[:main_export_decl]} int #{main_name}(void);") + output.puts("#{@options[:main_export_decl]} #{main_return} #{main_name}(void);") end - output.puts("int #{main_name}(void)") + output.puts("#{main_return} #{main_name}(void)") output.puts('{') end - output.puts(' suite_setup();') - output.puts(" UnityBegin(\"#{filename.gsub(/\\/, '\\\\\\')}\");") - if @options[:use_param_tests] - tests.each do |test| - if test[:args].nil? || test[:args].empty? - output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, RUN_TEST_NO_ARGS);") - else - test[:args].each { |args| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, #{args});") } + output.puts(' suiteSetUp();') if @options[:has_suite_setup] + if @options[:omit_begin_end] + output.puts(" UnitySetTestFile(\"#{filename.gsub(/\\/, '\\\\\\')}\");") + else + output.puts(" UnityBegin(\"#{filename.gsub(/\\/, '\\\\\\')}\");") + end + tests.each do |test| + if (!@options[:use_param_tests]) || test[:args].nil? || test[:args].empty? + output.puts(" run_test(#{test[:test]}, \"#{test[:test]}\", #{test[:line_number]});") + else + test[:args].each.with_index(1) do |args, idx| + wrapper = "runner_args#{idx}_#{test[:test]}" + testname = "#{test[:test]}(#{args})".dump + output.puts(" run_test(#{wrapper}, #{testname}, #{test[:line_number]});") end end - else - tests.each { |test| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]});") } end output.puts output.puts(' CMock_Guts_MemFreeFinal();') unless used_mocks.empty? - output.puts(" return suite_teardown(UnityEnd());") + if @options[:has_suite_teardown] + if @options[:omit_begin_end] + output.puts(' (void) suite_teardown(0);') + else + output.puts(' return suiteTearDown(UnityEnd());') + end + else + output.puts(' return UnityEnd();') if not @options[:omit_begin_end] + end output.puts('}') end @@ -439,13 +473,17 @@ if $0 == __FILE__ ' *.h - header files are added as #includes in runner', ' options:', ' -cexception - include cexception support', + ' -externc - add extern "C" for cpp support', ' --setup_name="" - redefine setUp func name to something else', ' --teardown_name="" - redefine tearDown func name to something else', ' --main_name="" - redefine main func name to something else', ' --test_prefix="" - redefine test prefix from default test|spec|should', + ' --test_reset_name="" - redefine resetTest func name to something else', + ' --test_verify_name="" - redefine verifyTest func name to something else', ' --suite_setup="" - code to execute for setup of entire suite', ' --suite_teardown="" - code to execute for teardown of entire suite', ' --use_param_tests=1 - enable parameterized tests (disabled by default)', + ' --omit_begin_end=1 - omit calls to UnityBegin and UnityEnd (disabled by default)', ' --header_file="" - path/name of test header file to generate too'].join("\n") exit 1 end diff --git a/test/vendor/ceedling/vendor/unity/auto/parse_output.rb b/test/vendor/ceedling/vendor/unity/auto/parse_output.rb index f04508fb0..d72c6e8b2 100644 --- a/test/vendor/ceedling/vendor/unity/auto/parse_output.rb +++ b/test/vendor/ceedling/vendor/unity/auto/parse_output.rb @@ -34,9 +34,9 @@ class ParseOutput # current suite name and statistics @test_suite = nil - @total_tests = 0 - @test_passed = 0 - @test_failed = 0 + @total_tests = 0 + @test_passed = 0 + @test_failed = 0 @test_ignored = 0 end @@ -210,7 +210,7 @@ class ParseOutput # Adjusts the os specific members according to the current path style # (Windows or Unix based) - def set_os_specifics(line) + def detect_os_specifics(line) if line.include? '\\' # Windows X:\Y\Z @class_name_idx = 1 @@ -254,43 +254,42 @@ class ParseOutput # TEST() PASS # # Note: Where path is different on Unix vs Windows devices (Windows leads with a drive letter)! - set_os_specifics(line) + detect_os_specifics(line) line_array = line.split(':') # If we were able to split the line then we can look to see if any of our target words # were found. Case is important. - if (line_array.size >= 4) || (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(') + next unless (line_array.size >= 4) || (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(') - # check if the output is fixture output (with verbose flag "-v") - if (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(') - line_array = prepare_fixture_line(line) - if line.include? ' PASS' - test_passed_unity_fixture(line_array) - @test_passed += 1 - elsif line.include? 'FAIL' - test_failed_unity_fixture(line_array) - @test_failed += 1 - elsif line.include? 'IGNORE' - test_ignored_unity_fixture(line_array) - @test_ignored += 1 - end - # normal output / fixture output (without verbose "-v") - elsif line.include? ':PASS' - test_passed(line_array) + # check if the output is fixture output (with verbose flag "-v") + if (line.start_with? 'TEST(') || (line.start_with? 'IGNORE_TEST(') + line_array = prepare_fixture_line(line) + if line.include? ' PASS' + test_passed_unity_fixture(line_array) @test_passed += 1 - elsif line.include? ':FAIL' - test_failed(line_array) + elsif line.include? 'FAIL' + test_failed_unity_fixture(line_array) @test_failed += 1 - elsif line.include? ':IGNORE:' - test_ignored(line_array) - @test_ignored += 1 - elsif line.include? ':IGNORE' - line_array.push('No reason given') - test_ignored(line_array) + elsif line.include? 'IGNORE' + test_ignored_unity_fixture(line_array) @test_ignored += 1 end - @total_tests = @test_passed + @test_failed + @test_ignored + # normal output / fixture output (without verbose "-v") + elsif line.include? ':PASS' + test_passed(line_array) + @test_passed += 1 + elsif line.include? ':FAIL' + test_failed(line_array) + @test_failed += 1 + elsif line.include? ':IGNORE:' + test_ignored(line_array) + @test_ignored += 1 + elsif line.include? ':IGNORE' + line_array.push('No reason given') + test_ignored(line_array) + @test_ignored += 1 end + @total_tests = @test_passed + @test_failed + @test_ignored end puts '' puts '=================== SUMMARY =====================' diff --git a/test/vendor/ceedling/vendor/unity/auto/run_test.erb b/test/vendor/ceedling/vendor/unity/auto/run_test.erb new file mode 100644 index 000000000..3d3b6d1e8 --- /dev/null +++ b/test/vendor/ceedling/vendor/unity/auto/run_test.erb @@ -0,0 +1,36 @@ +/*=======Test Runner Used To Run Each Test=====*/ +static void run_test(UnityTestFunction func, const char* name, int line_num) +{ + Unity.CurrentTestName = name; + Unity.CurrentTestLineNumber = line_num; +#ifdef UNITY_USE_COMMAND_LINE_ARGS + if (!UnityTestMatches()) + return; +#endif + Unity.NumberOfTests++; + UNITY_CLR_DETAILS(); + UNITY_EXEC_TIME_START(); + CMock_Init(); + if (TEST_PROTECT()) + { +<% if @options[:plugins].include?(:cexception) %> + CEXCEPTION_T e; + Try { +<% end %> + <%= @options[:setup_name] %>(); + func(); +<% if @options[:plugins].include?(:cexception) %> + } Catch(e) { + TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, "Unhandled Exception!"); + } +<% end %> + } + if (TEST_PROTECT()) + { + <%= @options[:teardown_name] %>(); + CMock_Verify(); + } + CMock_Destroy(); + UNITY_EXEC_TIME_STOP(); + UnityConcludeTest(); +} diff --git a/test/vendor/ceedling/vendor/unity/auto/stylize_as_junit.rb b/test/vendor/ceedling/vendor/unity/auto/stylize_as_junit.rb index b3d8f4097..e01f7912a 100644 --- a/test/vendor/ceedling/vendor/unity/auto/stylize_as_junit.rb +++ b/test/vendor/ceedling/vendor/unity/auto/stylize_as_junit.rb @@ -61,8 +61,8 @@ class ArgvParser opts.parse!(args) options - end # parse() -end # class OptparseExample + end +end class UnityToJUnit include FileUtils::Verbose @@ -152,11 +152,8 @@ class UnityToJUnit def parse_test_summary(summary) raise "Couldn't parse test results: #{summary}" unless summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ } - [Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i] - end - def here - File.expand_path(File.dirname(__FILE__)) + [Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i] end private @@ -221,9 +218,9 @@ class UnityToJUnit def write_suites_footer(stream) stream.puts '' end -end # UnityToJUnit +end -if __FILE__ == $0 +if $0 == __FILE__ # parse out the command options options = ArgvParser.parse(ARGV) @@ -234,7 +231,9 @@ if __FILE__ == $0 targets = "#{options.results_dir.tr('\\', '/')}**/*.test*" results = Dir[targets] + raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty? + utj.targets = results # set the root path diff --git a/test/vendor/ceedling/vendor/unity/auto/test_file_filter.rb b/test/vendor/ceedling/vendor/unity/auto/test_file_filter.rb index aad28e38e..5c3a79fc6 100644 --- a/test/vendor/ceedling/vendor/unity/auto/test_file_filter.rb +++ b/test/vendor/ceedling/vendor/unity/auto/test_file_filter.rb @@ -11,8 +11,8 @@ module RakefileHelpers def initialize(all_files = false) @all_files = all_files - return false unless @all_files - return false unless File.exist?('test_file_filter.yml') + return unless @all_files + return unless File.exist?('test_file_filter.yml') filters = YAML.load_file('test_file_filter.yml') @all_files = filters[:all_files] diff --git a/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py b/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py index 4c20e528d..00c0da8cc 100644 --- a/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py +++ b/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py @@ -121,7 +121,7 @@ if __name__ == '__main__': targets_dir = sys.argv[1] else: targets_dir = './' - targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*'))) + targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '**/*.test*', recursive=True))) if len(targets) == 0: raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir) uts.set_targets(targets) diff --git a/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.rb b/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.rb index b37dc5fa7..b3fe8a699 100644 --- a/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.rb +++ b/test/vendor/ceedling/vendor/unity/auto/unity_test_summary.rb @@ -99,11 +99,8 @@ class UnityTestSummary def parse_test_summary(summary) raise "Couldn't parse test results: #{summary}" unless summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ } - [Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i] - end - def here - File.expand_path(File.dirname(__FILE__)) + [Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i] end end @@ -121,7 +118,9 @@ if $0 == __FILE__ args[0] ||= './' targets = "#{ARGV[0].tr('\\', '/')}**/*.test*" results = Dir[targets] + raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty? + uts.targets = results # set the root path diff --git a/test/vendor/ceedling/vendor/unity/src/CMakeLists.txt b/test/vendor/ceedling/vendor/unity/src/CMakeLists.txt new file mode 100644 index 000000000..c747cb0ae --- /dev/null +++ b/test/vendor/ceedling/vendor/unity/src/CMakeLists.txt @@ -0,0 +1,22 @@ +################################################################################### +# # +# NAME: CMakeLists.txt # +# # +# AUTHOR: Mike Karlesky, Mark VanderVoord, Greg Williams. # +# WRITTEN BY: Michael Brockus. # +# # +# License: MIT # +# # +################################################################################### +cmake_minimum_required(VERSION 3.0 FATAL_ERROR) + + +add_library(unity STATIC "unity.c") + +install(TARGETS unity EXPORT unityConfig + ARCHIVE DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_LIBDIR}") + + diff --git a/test/vendor/ceedling/vendor/unity/src/meson.build b/test/vendor/ceedling/vendor/unity/src/meson.build new file mode 100644 index 000000000..f5e014653 --- /dev/null +++ b/test/vendor/ceedling/vendor/unity/src/meson.build @@ -0,0 +1,16 @@ +################################################################################### +# # +# NAME: meson.build # +# # +# AUTHOR: Mike Karlesky, Mark VanderVoord, Greg Williams. # +# WRITTEN BY: Michael Brockus. # +# # +# License: MIT # +# # +################################################################################### + +unity_dir = include_directories('.') + +unity_lib = static_library(meson.project_name(), + sources: ['unity.c'], + include_directories: unity_dir) diff --git a/test/vendor/ceedling/vendor/unity/src/unity.c b/test/vendor/ceedling/vendor/unity/src/unity.c index 103bde21b..c7be02cc6 100644 --- a/test/vendor/ceedling/vendor/unity/src/unity.c +++ b/test/vendor/ceedling/vendor/unity/src/unity.c @@ -1,13 +1,18 @@ /* ========================================================================= Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + Copyright (c) 2007-19 Mike Karlesky, Mark VanderVoord, Greg Williams [Released under MIT License. Please refer to license.txt for details] ============================================================================ */ -#define UNITY_INCLUDE_SETUP_STUBS #include "unity.h" #include +#ifdef AVR +#include +#else +#define PROGMEM +#endif + /* If omitted from header, declare overrideable prototypes here so they're ready for use */ #ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION void UNITY_OUTPUT_CHAR(int); @@ -21,52 +26,105 @@ void UNITY_OUTPUT_CHAR(int); struct UNITY_STORAGE_T Unity; #ifdef UNITY_OUTPUT_COLOR -static const char UnityStrOk[] = "\033[42mOK\033[00m"; -static const char UnityStrPass[] = "\033[42mPASS\033[00m"; -static const char UnityStrFail[] = "\033[41mFAIL\033[00m"; -static const char UnityStrIgnore[] = "\033[43mIGNORE\033[00m"; +const char PROGMEM UnityStrOk[] = "\033[42mOK\033[00m"; +const char PROGMEM UnityStrPass[] = "\033[42mPASS\033[00m"; +const char PROGMEM UnityStrFail[] = "\033[41mFAIL\033[00m"; +const char PROGMEM UnityStrIgnore[] = "\033[43mIGNORE\033[00m"; #else -static const char UnityStrOk[] = "OK"; -static const char UnityStrPass[] = "PASS"; -static const char UnityStrFail[] = "FAIL"; -static const char UnityStrIgnore[] = "IGNORE"; +const char PROGMEM UnityStrOk[] = "OK"; +const char PROGMEM UnityStrPass[] = "PASS"; +const char PROGMEM UnityStrFail[] = "FAIL"; +const char PROGMEM UnityStrIgnore[] = "IGNORE"; #endif -static const char UnityStrNull[] = "NULL"; -static const char UnityStrSpacer[] = ". "; -static const char UnityStrExpected[] = " Expected "; -static const char UnityStrWas[] = " Was "; -static const char UnityStrGt[] = " to be greater than "; -static const char UnityStrLt[] = " to be less than "; -static const char UnityStrOrEqual[] = "or equal to "; -static const char UnityStrElement[] = " Element "; -static const char UnityStrByte[] = " Byte "; -static const char UnityStrMemory[] = " Memory Mismatch."; -static const char UnityStrDelta[] = " Values Not Within Delta "; -static const char UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; -static const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; -static const char UnityStrNullPointerForActual[] = " Actual pointer was NULL"; +static const char PROGMEM UnityStrNull[] = "NULL"; +static const char PROGMEM UnityStrSpacer[] = ". "; +static const char PROGMEM UnityStrExpected[] = " Expected "; +static const char PROGMEM UnityStrWas[] = " Was "; +static const char PROGMEM UnityStrGt[] = " to be greater than "; +static const char PROGMEM UnityStrLt[] = " to be less than "; +static const char PROGMEM UnityStrOrEqual[] = "or equal to "; +static const char PROGMEM UnityStrElement[] = " Element "; +static const char PROGMEM UnityStrByte[] = " Byte "; +static const char PROGMEM UnityStrMemory[] = " Memory Mismatch."; +static const char PROGMEM UnityStrDelta[] = " Values Not Within Delta "; +static const char PROGMEM UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; +static const char PROGMEM UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; +static const char PROGMEM UnityStrNullPointerForActual[] = " Actual pointer was NULL"; #ifndef UNITY_EXCLUDE_FLOAT -static const char UnityStrNot[] = "Not "; -static const char UnityStrInf[] = "Infinity"; -static const char UnityStrNegInf[] = "Negative Infinity"; -static const char UnityStrNaN[] = "NaN"; -static const char UnityStrDet[] = "Determinate"; -static const char UnityStrInvalidFloatTrait[] = "Invalid Float Trait"; +static const char PROGMEM UnityStrNot[] = "Not "; +static const char PROGMEM UnityStrInf[] = "Infinity"; +static const char PROGMEM UnityStrNegInf[] = "Negative Infinity"; +static const char PROGMEM UnityStrNaN[] = "NaN"; +static const char PROGMEM UnityStrDet[] = "Determinate"; +static const char PROGMEM UnityStrInvalidFloatTrait[] = "Invalid Float Trait"; #endif -const char UnityStrErrFloat[] = "Unity Floating Point Disabled"; -const char UnityStrErrDouble[] = "Unity Double Precision Disabled"; -const char UnityStrErr64[] = "Unity 64-bit Support Disabled"; -static const char UnityStrBreaker[] = "-----------------------"; -static const char UnityStrResultsTests[] = " Tests "; -static const char UnityStrResultsFailures[] = " Failures "; -static const char UnityStrResultsIgnored[] = " Ignored "; -static const char UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; -static const char UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; +const char PROGMEM UnityStrErrShorthand[] = "Unity Shorthand Support Disabled"; +const char PROGMEM UnityStrErrFloat[] = "Unity Floating Point Disabled"; +const char PROGMEM UnityStrErrDouble[] = "Unity Double Precision Disabled"; +const char PROGMEM UnityStrErr64[] = "Unity 64-bit Support Disabled"; +static const char PROGMEM UnityStrBreaker[] = "-----------------------"; +static const char PROGMEM UnityStrResultsTests[] = " Tests "; +static const char PROGMEM UnityStrResultsFailures[] = " Failures "; +static const char PROGMEM UnityStrResultsIgnored[] = " Ignored "; +static const char PROGMEM UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; +static const char PROGMEM UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; /*----------------------------------------------- * Pretty Printers & Test Result Output Handlers *-----------------------------------------------*/ +/*-----------------------------------------------*/ +/* Local helper function to print characters. */ +static void UnityPrintChar(const char* pch) +{ + /* printable characters plus CR & LF are printed */ + if ((*pch <= 126) && (*pch >= 32)) + { + UNITY_OUTPUT_CHAR(*pch); + } + /* write escaped carriage returns */ + else if (*pch == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + /* write escaped line feeds */ + else if (*pch == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + /* unprintable characters are shown as codes */ + else + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)*pch, 2); + } +} + +/*-----------------------------------------------*/ +/* Local helper function to print ANSI escape strings e.g. "\033[42m". */ +#ifdef UNITY_OUTPUT_COLOR +static UNITY_UINT UnityPrintAnsiEscapeString(const char* string) +{ + const char* pch = string; + UNITY_UINT count = 0; + + while (*pch && (*pch != 'm')) + { + UNITY_OUTPUT_CHAR(*pch); + pch++; + count++; + } + UNITY_OUTPUT_CHAR('m'); + count++; + + return count; +} +#endif + +/*-----------------------------------------------*/ void UnityPrint(const char* string) { const char* pch = string; @@ -75,54 +133,142 @@ void UnityPrint(const char* string) { while (*pch) { - /* printable characters plus CR & LF are printed */ - if ((*pch <= 126) && (*pch >= 32)) - { - UNITY_OUTPUT_CHAR(*pch); - } - /* write escaped carriage returns */ - else if (*pch == 13) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('r'); - } - /* write escaped line feeds */ - else if (*pch == 10) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('n'); - } #ifdef UNITY_OUTPUT_COLOR /* print ANSI escape code */ - else if (*pch == 27 && *(pch + 1) == '[') + if ((*pch == 27) && (*(pch + 1) == '[')) { - while (*pch && *pch != 'm') - { - UNITY_OUTPUT_CHAR(*pch); - pch++; - } - UNITY_OUTPUT_CHAR('m'); + pch += UnityPrintAnsiEscapeString(pch); + continue; } #endif - /* unprintable characters are shown as codes */ - else - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('x'); - UnityPrintNumberHex((UNITY_UINT)*pch, 2); - } + UnityPrintChar(pch); pch++; } } } +/*-----------------------------------------------*/ +#ifdef UNITY_INCLUDE_PRINT_FORMATTED +void UnityPrintFormatted(const char* format, ...) +{ + const char* pch = format; + va_list va; + va_start(va, format); + + if (pch != NULL) + { + while (*pch) + { + /* format identification character */ + if (*pch == '%') + { + pch++; + + if (pch != NULL) + { + switch (*pch) + { + case 'd': + case 'i': + { + const int number = va_arg(va, int); + UnityPrintNumber((UNITY_INT)number); + break; + } +#ifndef UNITY_EXCLUDE_FLOAT_PRINT + case 'f': + case 'g': + { + const double number = va_arg(va, double); + UnityPrintFloat((UNITY_DOUBLE)number); + break; + } +#endif + case 'u': + { + const unsigned int number = va_arg(va, unsigned int); + UnityPrintNumberUnsigned((UNITY_UINT)number); + break; + } + case 'b': + { + const unsigned int number = va_arg(va, unsigned int); + const UNITY_UINT mask = (UNITY_UINT)0 - (UNITY_UINT)1; + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('b'); + UnityPrintMask(mask, (UNITY_UINT)number); + break; + } + case 'x': + case 'X': + case 'p': + { + const unsigned int number = va_arg(va, unsigned int); + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)number, 8); + break; + } + case 'c': + { + const int ch = va_arg(va, int); + UnityPrintChar((const char *)&ch); + break; + } + case 's': + { + const char * string = va_arg(va, const char *); + UnityPrint(string); + break; + } + case '%': + { + UnityPrintChar(pch); + break; + } + default: + { + /* print the unknown format character */ + UNITY_OUTPUT_CHAR('%'); + UnityPrintChar(pch); + break; + } + } + } + } +#ifdef UNITY_OUTPUT_COLOR + /* print ANSI escape code */ + else if ((*pch == 27) && (*(pch + 1) == '[')) + { + pch += UnityPrintAnsiEscapeString(pch); + continue; + } +#endif + else if (*pch == '\n') + { + UNITY_PRINT_EOL(); + } + else + { + UnityPrintChar(pch); + } + + pch++; + } + } + + va_end(va); +} +#endif /* ! UNITY_INCLUDE_PRINT_FORMATTED */ + +/*-----------------------------------------------*/ void UnityPrintLen(const char* string, const UNITY_UINT32 length) { const char* pch = string; if (pch != NULL) { - while (*pch && (UNITY_UINT32)(pch - string) < length) + while (*pch && ((UNITY_UINT32)(pch - string) < length)) { /* printable characters plus CR & LF are printed */ if ((*pch <= 126) && (*pch >= 32)) @@ -158,7 +304,39 @@ void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T { if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) { - UnityPrintNumber(number); + if (style == UNITY_DISPLAY_STYLE_CHAR) + { + /* printable characters plus CR & LF are printed */ + UNITY_OUTPUT_CHAR('\''); + if ((number <= 126) && (number >= 32)) + { + UNITY_OUTPUT_CHAR((int)number); + } + /* write escaped carriage returns */ + else if (number == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + /* write escaped line feeds */ + else if (number == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + /* unprintable characters are shown as codes */ + else + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)number, 2); + } + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrintNumber(number); + } } else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) { @@ -181,7 +359,7 @@ void UnityPrintNumber(const UNITY_INT number_to_print) { /* A negative number, including MIN negative */ UNITY_OUTPUT_CHAR('-'); - number = (UNITY_UINT)(-number_to_print); + number = (~number) + 1; } UnityPrintNumberUnsigned(number); } @@ -211,8 +389,11 @@ void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print) { int nibble; char nibbles = nibbles_to_print; - if ((unsigned)nibbles > (2 * sizeof(number))) - nibbles = 2 * sizeof(number); + + if ((unsigned)nibbles > UNITY_MAX_NIBBLES) + { + nibbles = UNITY_MAX_NIBBLES; + } while (nibbles > 0) { @@ -258,53 +439,118 @@ void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number) /*-----------------------------------------------*/ #ifndef UNITY_EXCLUDE_FLOAT_PRINT -/* This function prints a floating-point value in a format similar to - * printf("%.6g"). It can work with either single- or double-precision, - * but for simplicity, it prints only 6 significant digits in either case. - * Printing more than 6 digits accurately is hard (at least in the single- - * precision case) and isn't attempted here. */ +/* + * This function prints a floating-point value in a format similar to + * printf("%.7g") on a single-precision machine or printf("%.9g") on a + * double-precision machine. The 7th digit won't always be totally correct + * in single-precision operation (for that level of accuracy, a more + * complicated algorithm would be needed). + */ void UnityPrintFloat(const UNITY_DOUBLE input_number) { +#ifdef UNITY_INCLUDE_DOUBLE + static const int sig_digits = 9; + static const UNITY_INT32 min_scaled = 100000000; + static const UNITY_INT32 max_scaled = 1000000000; +#else + static const int sig_digits = 7; + static const UNITY_INT32 min_scaled = 1000000; + static const UNITY_INT32 max_scaled = 10000000; +#endif + UNITY_DOUBLE number = input_number; - /* print minus sign (including for negative zero) */ - if (number < 0.0f || (number == 0.0f && 1.0f / number < 0.0f)) + /* print minus sign (does not handle negative zero) */ + if (number < 0.0f) { UNITY_OUTPUT_CHAR('-'); number = -number; } /* handle zero, NaN, and +/- infinity */ - if (number == 0.0f) UnityPrint("0"); - else if (isnan(number)) UnityPrint("nan"); - else if (isinf(number)) UnityPrint("inf"); + if (number == 0.0f) + { + UnityPrint("0"); + } + else if (isnan(number)) + { + UnityPrint("nan"); + } + else if (isinf(number)) + { + UnityPrint("inf"); + } else { + UNITY_INT32 n_int = 0, n; int exponent = 0; int decimals, digits; - UNITY_INT32 n; - char buf[16]; + char buf[16] = {0}; - /* scale up or down by powers of 10 */ - while (number < 100000.0f / 1e6f) { number *= 1e6f; exponent -= 6; } - while (number < 100000.0f) { number *= 10.0f; exponent--; } - while (number > 1000000.0f * 1e6f) { number /= 1e6f; exponent += 6; } - while (number > 1000000.0f) { number /= 10.0f; exponent++; } + /* + * Scale up or down by powers of 10. To minimize rounding error, + * start with a factor/divisor of 10^10, which is the largest + * power of 10 that can be represented exactly. Finally, compute + * (exactly) the remaining power of 10 and perform one more + * multiplication or division. + */ + if (number < 1.0f) + { + UNITY_DOUBLE factor = 1.0f; + + while (number < (UNITY_DOUBLE)max_scaled / 1e10f) { number *= 1e10f; exponent -= 10; } + while (number * factor < (UNITY_DOUBLE)min_scaled) { factor *= 10.0f; exponent--; } + + number *= factor; + } + else if (number > (UNITY_DOUBLE)max_scaled) + { + UNITY_DOUBLE divisor = 1.0f; + + while (number > (UNITY_DOUBLE)min_scaled * 1e10f) { number /= 1e10f; exponent += 10; } + while (number / divisor > (UNITY_DOUBLE)max_scaled) { divisor *= 10.0f; exponent++; } + + number /= divisor; + } + else + { + /* + * In this range, we can split off the integer part before + * doing any multiplications. This reduces rounding error by + * freeing up significant bits in the fractional part. + */ + UNITY_DOUBLE factor = 1.0f; + n_int = (UNITY_INT32)number; + number -= (UNITY_DOUBLE)n_int; + + while (n_int < min_scaled) { n_int *= 10; factor *= 10.0f; exponent--; } + + number *= factor; + } /* round to nearest integer */ n = ((UNITY_INT32)(number + number) + 1) / 2; - if (n > 999999) + +#ifndef UNITY_ROUND_TIES_AWAY_FROM_ZERO + /* round to even if exactly between two integers */ + if ((n & 1) && (((UNITY_DOUBLE)n - number) == 0.5f)) + n--; +#endif + + n += n_int; + + if (n >= max_scaled) { - n = 100000; + n = min_scaled; exponent++; } /* determine where to place decimal point */ - decimals = (exponent <= 0 && exponent >= -9) ? -exponent : 5; + decimals = ((exponent <= 0) && (exponent >= -(sig_digits + 3))) ? (-exponent) : (sig_digits - 1); exponent += decimals; /* truncate trailing zeroes after decimal point */ - while (decimals > 0 && n % 10 == 0) + while ((decimals > 0) && ((n % 10) == 0)) { n /= 10; decimals--; @@ -312,14 +558,14 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number) /* build up buffer in reverse order */ digits = 0; - while (n != 0 || digits < decimals + 1) + while ((n != 0) || (digits < (decimals + 1))) { buf[digits++] = (char)('0' + n % 10); n /= 10; } while (digits > 0) { - if(digits == decimals) UNITY_OUTPUT_CHAR('.'); + if (digits == decimals) { UNITY_OUTPUT_CHAR('.'); } UNITY_OUTPUT_CHAR(buf[--digits]); } @@ -328,7 +574,7 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number) { UNITY_OUTPUT_CHAR('e'); - if(exponent < 0) + if (exponent < 0) { UNITY_OUTPUT_CHAR('-'); exponent = -exponent; @@ -339,7 +585,7 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number) } digits = 0; - while (exponent != 0 || digits < 2) + while ((exponent != 0) || (digits < 2)) { buf[digits++] = (char)('0' + exponent % 10); exponent /= 10; @@ -356,12 +602,44 @@ void UnityPrintFloat(const UNITY_DOUBLE input_number) /*-----------------------------------------------*/ static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) { +#ifdef UNITY_OUTPUT_FOR_ECLIPSE + UNITY_OUTPUT_CHAR('('); + UnityPrint(file); + UNITY_OUTPUT_CHAR(':'); + UnityPrintNumber((UNITY_INT)line); + UNITY_OUTPUT_CHAR(')'); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(Unity.CurrentTestName); + UNITY_OUTPUT_CHAR(':'); +#else +#ifdef UNITY_OUTPUT_FOR_IAR_WORKBENCH + UnityPrint("'); + UnityPrint(Unity.CurrentTestName); + UnityPrint(" "); +#else +#ifdef UNITY_OUTPUT_FOR_QT_CREATOR + UnityPrint("file://"); + UnityPrint(file); + UNITY_OUTPUT_CHAR(':'); + UnityPrintNumber((UNITY_INT)line); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(Unity.CurrentTestName); + UNITY_OUTPUT_CHAR(':'); +#else UnityPrint(file); UNITY_OUTPUT_CHAR(':'); UnityPrintNumber((UNITY_INT)line); UNITY_OUTPUT_CHAR(':'); UnityPrint(Unity.CurrentTestName); UNITY_OUTPUT_CHAR(':'); +#endif +#endif +#endif } /*-----------------------------------------------*/ @@ -391,7 +669,7 @@ void UnityConcludeTest(void) Unity.CurrentTestFailed = 0; Unity.CurrentTestIgnored = 0; - UNITY_EXEC_TIME_RESET(); + UNITY_PRINT_EXEC_TIME(); UNITY_PRINT_EOL(); UNITY_FLUSH_CALL(); } @@ -479,12 +757,14 @@ static void UnityPrintExpectedAndActualStringsLen(const char* expected, * Assertion & Control Helpers *-----------------------------------------------*/ +/*-----------------------------------------------*/ static int UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected, UNITY_INTERNAL_PTR actual, const UNITY_LINE_TYPE lineNumber, const char* msg) { - if (expected == actual) return 0; /* Both are NULL or same pointer */ + /* Both are NULL or same pointer */ + if (expected == actual) { return 0; } /* print and return true if just expected is NULL */ if (expected == NULL) @@ -511,6 +791,7 @@ static int UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected, * Assertion Functions *-----------------------------------------------*/ +/*-----------------------------------------------*/ void UnityAssertBits(const UNITY_INT mask, const UNITY_INT expected, const UNITY_INT actual, @@ -563,18 +844,18 @@ void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold, int failed = 0; RETURN_IF_FAIL_OR_IGNORE; - if (threshold == actual && compare & UNITY_EQUAL_TO) return; - if (threshold == actual) failed = 1; + if ((threshold == actual) && (compare & UNITY_EQUAL_TO)) { return; } + if ((threshold == actual)) { failed = 1; } if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) { - if (actual > threshold && compare & UNITY_SMALLER_THAN) failed = 1; - if (actual < threshold && compare & UNITY_GREATER_THAN) failed = 1; + if ((actual > threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } + if ((actual < threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } } else /* UINT or HEX */ { - if ((UNITY_UINT)actual > (UNITY_UINT)threshold && compare & UNITY_SMALLER_THAN) failed = 1; - if ((UNITY_UINT)actual < (UNITY_UINT)threshold && compare & UNITY_GREATER_THAN) failed = 1; + if (((UNITY_UINT)actual > (UNITY_UINT)threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } + if (((UNITY_UINT)actual < (UNITY_UINT)threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } } if (failed) @@ -582,9 +863,9 @@ void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold, UnityTestResultsFailBegin(lineNumber); UnityPrint(UnityStrExpected); UnityPrintNumberByStyle(actual, style); - if (compare & UNITY_GREATER_THAN) UnityPrint(UnityStrGt); - if (compare & UNITY_SMALLER_THAN) UnityPrint(UnityStrLt); - if (compare & UNITY_EQUAL_TO) UnityPrint(UnityStrOrEqual); + if (compare & UNITY_GREATER_THAN) { UnityPrint(UnityStrGt); } + if (compare & UNITY_SMALLER_THAN) { UnityPrint(UnityStrLt); } + if (compare & UNITY_EQUAL_TO) { UnityPrint(UnityStrOrEqual); } UnityPrintNumberByStyle(threshold, style); UnityAddMsgIfSpecified(msg); UNITY_FAIL_AND_BAIL; @@ -607,8 +888,9 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, const UNITY_DISPLAY_STYLE_T style, const UNITY_FLAGS_T flags) { - UNITY_UINT32 elements = num_elements; - unsigned int length = style & 0xF; + UNITY_UINT32 elements = num_elements; + unsigned int length = style & 0xF; + unsigned int increment = 0; RETURN_IF_FAIL_OR_IGNORE; @@ -617,40 +899,55 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, UnityPrintPointlessAndBail(); } - if (expected == actual) return; /* Both are NULL or same pointer */ - if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) - UNITY_FAIL_AND_BAIL; + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } - while ((elements > 0) && elements--) + if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + while ((elements > 0) && (elements--)) { UNITY_INT expect_val; UNITY_INT actual_val; + switch (length) { case 1: expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected; actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual; + increment = sizeof(UNITY_INT8); break; + case 2: expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected; actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual; + increment = sizeof(UNITY_INT16); break; + #ifdef UNITY_SUPPORT_64 case 8: expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected; actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual; + increment = sizeof(UNITY_INT64); break; #endif - default: /* length 4 bytes */ + + default: /* default is length 4 bytes */ + case 4: expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected; actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual; + increment = sizeof(UNITY_INT32); length = 4; break; } if (expect_val != actual_val) { - if (style & UNITY_DISPLAY_RANGE_UINT && length < sizeof(expect_val)) + if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8))) { /* For UINT, remove sign extension (padding 1's) from signed type casts above */ UNITY_INT mask = 1; mask = (mask << 8 * length) - 1; @@ -667,11 +964,12 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, UnityAddMsgIfSpecified(msg); UNITY_FAIL_AND_BAIL; } + /* Walk through array by incrementing the pointers */ if (flags == UNITY_ARRAY_TO_ARRAY) { - expected = (UNITY_INTERNAL_PTR)(length + (const char*)expected); + expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment); } - actual = (UNITY_INTERNAL_PTR)(length + (const char*)actual); + actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment); } } @@ -704,12 +1002,14 @@ void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, UnityPrint(UnityStrDelta) #endif /* UNITY_EXCLUDE_FLOAT_PRINT */ +/*-----------------------------------------------*/ static int UnityFloatsWithin(UNITY_FLOAT delta, UNITY_FLOAT expected, UNITY_FLOAT actual) { UNITY_FLOAT diff; UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); } +/*-----------------------------------------------*/ void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected, UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual, const UNITY_UINT32 num_elements, @@ -728,9 +1028,15 @@ void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected, UnityPrintPointlessAndBail(); } - if (expected == actual) return; /* Both are NULL or same pointer */ + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) + { UNITY_FAIL_AND_BAIL; + } while (elements--) { @@ -815,14 +1121,18 @@ void UnityAssertFloatSpecial(const UNITY_FLOAT actual, UnityTestResultsFailBegin(lineNumber); UnityPrint(UnityStrExpected); if (!should_be_trait) + { UnityPrint(UnityStrNot); + } UnityPrint(trait_names[trait_index]); UnityPrint(UnityStrWas); #ifndef UNITY_EXCLUDE_FLOAT_PRINT UnityPrintFloat((UNITY_DOUBLE)actual); #else if (should_be_trait) + { UnityPrint(UnityStrNot); + } UnityPrint(trait_names[trait_index]); #endif UnityAddMsgIfSpecified(msg); @@ -840,6 +1150,7 @@ static int UnityDoublesWithin(UNITY_DOUBLE delta, UNITY_DOUBLE expected, UNITY_D UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); } +/*-----------------------------------------------*/ void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected, UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual, const UNITY_UINT32 num_elements, @@ -858,9 +1169,15 @@ void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expecte UnityPrintPointlessAndBail(); } - if (expected == actual) return; /* Both are NULL or same pointer */ + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) + { UNITY_FAIL_AND_BAIL; + } while (elements--) { @@ -900,7 +1217,6 @@ void UnityAssertDoublesWithin(const UNITY_DOUBLE delta, } /*-----------------------------------------------*/ - void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual, const char* msg, const UNITY_LINE_TYPE lineNumber, @@ -945,14 +1261,18 @@ void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual, UnityTestResultsFailBegin(lineNumber); UnityPrint(UnityStrExpected); if (!should_be_trait) + { UnityPrint(UnityStrNot); + } UnityPrint(trait_names[trait_index]); UnityPrint(UnityStrWas); #ifndef UNITY_EXCLUDE_FLOAT_PRINT UnityPrintFloat(actual); #else if (should_be_trait) + { UnityPrint(UnityStrNot); + } UnityPrint(trait_names[trait_index]); #endif UnityAddMsgIfSpecified(msg); @@ -975,16 +1295,24 @@ void UnityAssertNumbersWithin(const UNITY_UINT delta, if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) { if (actual > expected) - Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(actual - expected) > delta); + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta); + } else - Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(expected - actual) > delta); + { + Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta); + } } else { if ((UNITY_UINT)actual > (UNITY_UINT)expected) - Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(actual - expected) > delta); + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta); + } else - Unity.CurrentTestFailed = (UNITY_UINT)((UNITY_UINT)(expected - actual) > delta); + { + Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta); + } } if (Unity.CurrentTestFailed) @@ -1001,6 +1329,126 @@ void UnityAssertNumbersWithin(const UNITY_UINT delta, } } +/*-----------------------------------------------*/ +void UnityAssertNumbersArrayWithin(const UNITY_UINT delta, + UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags) +{ + UNITY_UINT32 elements = num_elements; + unsigned int length = style & 0xF; + unsigned int increment = 0; + + RETURN_IF_FAIL_OR_IGNORE; + + if (num_elements == 0) + { + UnityPrintPointlessAndBail(); + } + + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + while ((elements > 0) && (elements--)) + { + UNITY_INT expect_val; + UNITY_INT actual_val; + + switch (length) + { + case 1: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual; + increment = sizeof(UNITY_INT8); + break; + + case 2: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual; + increment = sizeof(UNITY_INT16); + break; + +#ifdef UNITY_SUPPORT_64 + case 8: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual; + increment = sizeof(UNITY_INT64); + break; +#endif + + default: /* default is length 4 bytes */ + case 4: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual; + increment = sizeof(UNITY_INT32); + length = 4; + break; + } + + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if (actual_val > expect_val) + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta); + } + else + { + Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta); + } + } + else + { + if ((UNITY_UINT)actual_val > (UNITY_UINT)expect_val) + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta); + } + else + { + Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta); + } + } + + if (Unity.CurrentTestFailed) + { + if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8))) + { /* For UINT, remove sign extension (padding 1's) from signed type casts above */ + UNITY_INT mask = 1; + mask = (mask << 8 * length) - 1; + expect_val &= mask; + actual_val &= mask; + } + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrDelta); + UnityPrintNumberByStyle((UNITY_INT)delta, style); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expect_val, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual_val, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + /* Walk through array by incrementing the pointers */ + if (flags == UNITY_ARRAY_TO_ARRAY) + { + expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment); + } + actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment); + } +} + /*-----------------------------------------------*/ void UnityAssertEqualString(const char* expected, const char* actual, @@ -1180,9 +1628,15 @@ void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected, UnityPrintPointlessAndBail(); } - if (expected == actual) return; /* Both are NULL or same pointer */ + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) + { UNITY_FAIL_AND_BAIL; + } while (elements--) { @@ -1240,25 +1694,27 @@ UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size) switch(size) { case 1: - UnityQuickCompare.i8 = (UNITY_INT8)num; - return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8); + UnityQuickCompare.i8 = (UNITY_INT8)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8); case 2: - UnityQuickCompare.i16 = (UNITY_INT16)num; - return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16); + UnityQuickCompare.i16 = (UNITY_INT16)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16); #ifdef UNITY_SUPPORT_64 case 8: - UnityQuickCompare.i64 = (UNITY_INT64)num; - return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64); + UnityQuickCompare.i64 = (UNITY_INT64)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64); #endif + default: /* 4 bytes */ - UnityQuickCompare.i32 = (UNITY_INT32)num; - return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32); + UnityQuickCompare.i32 = (UNITY_INT32)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32); } } #ifndef UNITY_EXCLUDE_FLOAT +/*-----------------------------------------------*/ UNITY_INTERNAL_PTR UnityFloatToPtr(const float num) { UnityQuickCompare.f = num; @@ -1267,6 +1723,7 @@ UNITY_INTERNAL_PTR UnityFloatToPtr(const float num) #endif #ifndef UNITY_EXCLUDE_DOUBLE +/*-----------------------------------------------*/ UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num) { UnityQuickCompare.d = num; @@ -1278,6 +1735,7 @@ UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num) * Control Functions *-----------------------------------------------*/ +/*-----------------------------------------------*/ void UnityFail(const char* msg, const UNITY_LINE_TYPE line) { RETURN_IF_FAIL_OR_IGNORE; @@ -1327,6 +1785,20 @@ void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) UNITY_IGNORE_AND_BAIL; } +/*-----------------------------------------------*/ +void UnityMessage(const char* msg, const UNITY_LINE_TYPE line) +{ + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint("INFO"); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(msg); + } + UNITY_PRINT_EOL(); +} + /*-----------------------------------------------*/ void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) { @@ -1334,6 +1806,7 @@ void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; Unity.NumberOfTests++; UNITY_CLR_DETAILS(); + UNITY_EXEC_TIME_START(); if (TEST_PROTECT()) { setUp(); @@ -1343,9 +1816,16 @@ void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int { tearDown(); } + UNITY_EXEC_TIME_STOP(); UnityConcludeTest(); } +/*-----------------------------------------------*/ +void UnitySetTestFile(const char* filename) +{ + Unity.TestFile = filename; +} + /*-----------------------------------------------*/ void UnityBegin(const char* filename) { @@ -1357,7 +1837,6 @@ void UnityBegin(const char* filename) Unity.TestIgnores = 0; Unity.CurrentTestFailed = 0; Unity.CurrentTestIgnored = 0; - UNITY_EXEC_TIME_RESET(); UNITY_CLR_DETAILS(); UNITY_OUTPUT_START(); @@ -1402,12 +1881,14 @@ char* UnityOptionIncludeNamed = NULL; char* UnityOptionExcludeNamed = NULL; int UnityVerbosity = 1; +/*-----------------------------------------------*/ int UnityParseOptions(int argc, char** argv) { + int i; UnityOptionIncludeNamed = NULL; UnityOptionExcludeNamed = NULL; - for (int i = 1; i < argc; i++) + for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { @@ -1418,9 +1899,13 @@ int UnityParseOptions(int argc, char** argv) case 'n': /* include tests with name including this string */ case 'f': /* an alias for -n */ if (argv[i][2] == '=') + { UnityOptionIncludeNamed = &argv[i][3]; + } else if (++i < argc) + { UnityOptionIncludeNamed = argv[i]; + } else { UnityPrint("ERROR: No Test String to Include Matches For"); @@ -1436,9 +1921,13 @@ int UnityParseOptions(int argc, char** argv) break; case 'x': /* exclude tests with name including this string */ if (argv[i][2] == '=') + { UnityOptionExcludeNamed = &argv[i][3]; + } else if (++i < argc) + { UnityOptionExcludeNamed = argv[i]; + } else { UnityPrint("ERROR: No Test String to Exclude Matches For"); @@ -1458,6 +1947,7 @@ int UnityParseOptions(int argc, char** argv) return 0; } +/*-----------------------------------------------*/ int IsStringInBiggerString(const char* longstring, const char* shortstring) { const char* lptr = longstring; @@ -1465,7 +1955,9 @@ int IsStringInBiggerString(const char* longstring, const char* shortstring) const char* lnext = lptr; if (*sptr == '*') + { return 1; + } while (*lptr) { @@ -1496,9 +1988,11 @@ int IsStringInBiggerString(const char* longstring, const char* shortstring) lptr = lnext; sptr = shortstring; } + return 0; } +/*-----------------------------------------------*/ int UnityStringArgumentMatches(const char* str) { int retval; @@ -1511,7 +2005,9 @@ int UnityStringArgumentMatches(const char* str) while (ptr1[0] != 0) { if ((ptr1[0] == '"') || (ptr1[0] == '\'')) + { ptr1++; + } /* look for the start of the next partial */ ptr2 = ptr1; @@ -1520,26 +2016,37 @@ int UnityStringArgumentMatches(const char* str) { ptr2++; if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')) + { ptrf = &ptr2[1]; + } } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')); + while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ','))) + { ptr2++; + } /* done if complete filename match */ retval = IsStringInBiggerString(Unity.TestFile, ptr1); if (retval == 1) + { return retval; + } /* done if testname match after filename partial match */ if ((retval == 2) && (ptrf != 0)) { if (IsStringInBiggerString(Unity.CurrentTestName, ptrf)) + { return 1; + } } /* done if complete testname match */ if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1) + { return 1; + } ptr1 = ptr2; } @@ -1548,6 +2055,7 @@ int UnityStringArgumentMatches(const char* str) return 0; } +/*-----------------------------------------------*/ int UnityTestMatches(void) { /* Check if this test name matches the included test pattern */ @@ -1557,14 +2065,19 @@ int UnityTestMatches(void) retval = UnityStringArgumentMatches(UnityOptionIncludeNamed); } else + { retval = 1; + } /* Check if this test name matches the excluded test pattern */ if (UnityOptionExcludeNamed) { if (UnityStringArgumentMatches(UnityOptionExcludeNamed)) + { retval = 0; + } } + return retval; } diff --git a/test/vendor/ceedling/vendor/unity/src/unity.h b/test/vendor/ceedling/vendor/unity/src/unity.h index a0c301d25..34d7f93aa 100644 --- a/test/vendor/ceedling/vendor/unity/src/unity.h +++ b/test/vendor/ceedling/vendor/unity/src/unity.h @@ -1,6 +1,6 @@ /* ========================================== Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + Copyright (c) 2007-19 Mike Karlesky, Mark VanderVoord, Greg Williams [Released under MIT License. Please refer to license.txt for details] ========================================== */ @@ -8,6 +8,11 @@ #define UNITY_FRAMEWORK_H #define UNITY +#define UNITY_VERSION_MAJOR 2 +#define UNITY_VERSION_MINOR 5 +#define UNITY_VERSION_BUILD 0 +#define UNITY_VERSION ((UNITY_VERSION_MAJOR << 16) | (UNITY_VERSION_MINOR << 8) | UNITY_VERSION_BUILD) + #ifdef __cplusplus extern "C" { @@ -19,38 +24,33 @@ extern "C" * Test Setup / Teardown *-------------------------------------------------------*/ -/* These functions are intended to be called before and after each test. */ +/* These functions are intended to be called before and after each test. + * If using unity directly, these will need to be provided for each test + * executable built. If you are using the test runner generator and/or + * Ceedling, these are optional. */ void setUp(void); void tearDown(void); /* These functions are intended to be called at the beginning and end of an * entire test suite. suiteTearDown() is passed the number of tests that - * failed, and its return value becomes the exit code of main(). */ + * failed, and its return value becomes the exit code of main(). If using + * Unity directly, you're in charge of calling these if they are desired. + * If using Ceedling or the test runner generator, these will be called + * automatically if they exist. */ void suiteSetUp(void); int suiteTearDown(int num_failures); -/* If the compiler supports it, the following block provides stub - * implementations of the above functions as weak symbols. Note that on - * some platforms (MinGW for example), weak function implementations need - * to be in the same translation unit they are called from. This can be - * achieved by defining UNITY_INCLUDE_SETUP_STUBS before including unity.h. */ -#ifdef UNITY_INCLUDE_SETUP_STUBS - #ifdef UNITY_WEAK_ATTRIBUTE - UNITY_WEAK_ATTRIBUTE void setUp(void) { } - UNITY_WEAK_ATTRIBUTE void tearDown(void) { } - UNITY_WEAK_ATTRIBUTE void suiteSetUp(void) { } - UNITY_WEAK_ATTRIBUTE int suiteTearDown(int num_failures) { return num_failures; } - #elif defined(UNITY_WEAK_PRAGMA) - #pragma weak setUp - void setUp(void) { } - #pragma weak tearDown - void tearDown(void) { } - #pragma weak suiteSetUp - void suiteSetUp(void) { } - #pragma weak suiteTearDown - int suiteTearDown(int num_failures) { return num_failures; } - #endif -#endif +/*------------------------------------------------------- + * Test Reset and Verify + *-------------------------------------------------------*/ + +/* These functions are intended to be called before during tests in order + * to support complex test loops, etc. Both are NOT built into Unity. Instead + * the test runner generator will create them. resetTest will run teardown and + * setup again, verifying any end-of-test needs between. verifyTest will only + * run the verification. */ +void resetTest(void); +void verifyTest(void); /*------------------------------------------------------- * Configuration Options @@ -102,11 +102,13 @@ int suiteTearDown(int num_failures); #define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL) #define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, (message)) #define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL) +#define TEST_MESSAGE(message) UnityMessage((message), __LINE__) #define TEST_ONLY() /* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails. * This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */ #define TEST_PASS() TEST_ABORT() +#define TEST_PASS_MESSAGE(message) do { UnityMessage((message), __LINE__); TEST_ABORT(); } while(0) /* This macro does nothing, but it is useful for build tools (like Ceedling) to make use of this to figure out * which files should be linked to in order to perform a test. Use it like TEST_FILE("sandwiches.c") */ @@ -130,18 +132,18 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL) #define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL) #define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") #define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_size_t(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT((expected), (actual), __LINE__, NULL) #define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) #define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL) #define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) #define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_CHAR(expected, actual) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, NULL) #define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(-1), (actual), __LINE__, NULL) #define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, NULL) @@ -160,10 +162,12 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_THAN(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL) @@ -176,10 +180,12 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_LESS_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) @@ -192,10 +198,12 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) @@ -208,10 +216,12 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_LESS_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL) #define TEST_ASSERT_LESS_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL) /* Integer Ranges (of all sizes) */ #define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL) @@ -224,11 +234,33 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_size_t_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) #define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_CHAR_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, NULL) + +/* Integer Array Ranges (of all sizes) */ +#define TEST_ASSERT_INT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_size_t_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_CHAR_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) + /* Structs and Strings */ #define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL) @@ -247,6 +279,7 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_size_t_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) @@ -255,6 +288,7 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_CHAR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) /* Arrays Compared To Single Value */ #define TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, NULL) @@ -267,6 +301,7 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_size_t(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EACH_EQUAL_HEX(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, NULL) @@ -275,6 +310,7 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, NULL) #define TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_CHAR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, NULL) /* Floating Point (If Enabled) */ #define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL) @@ -304,6 +340,28 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL) #define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL) +/* Shorthand */ +#ifdef UNITY_SHORTHAND_AS_OLD +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") +#endif +#ifdef UNITY_SHORTHAND_AS_INT +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_MEM +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_RAW +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, " Expected Equal") +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") +#endif +#ifdef UNITY_SHORTHAND_AS_NONE +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif + /*------------------------------------------------------- * Test Asserts (with additional messages) *-------------------------------------------------------*/ @@ -322,13 +380,12 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, (message)) #define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, (message)) #define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message)) #define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_size_t_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) #define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, (message)) @@ -339,6 +396,7 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, (message)) #define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, (message)) #define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_CHAR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, (message)) /* Integer Greater Than/ Less Than (of all sizes) */ #define TEST_ASSERT_GREATER_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message)) @@ -352,10 +410,12 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_GREATER_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message)) @@ -368,10 +428,12 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_LESS_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) @@ -384,10 +446,12 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_GREATER_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_GREATER_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) @@ -400,10 +464,12 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_LESS_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message)) #define TEST_ASSERT_LESS_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message)) /* Integer Ranges (of all sizes) */ #define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message)) @@ -416,11 +482,33 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_size_t_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) #define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_CHAR_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, (message)) + +/* Integer Array Ranges (of all sizes) */ +#define TEST_ASSERT_INT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_size_t_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_CHAR_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) + /* Structs and Strings */ #define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, (message)) @@ -439,6 +527,7 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_size_t_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) @@ -447,6 +536,7 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_CHAR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) /* Arrays Compared To Single Value*/ #define TEST_ASSERT_EACH_EQUAL_INT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, (message)) @@ -459,6 +549,7 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_size_t_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_HEX_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message)) @@ -467,6 +558,7 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_EACH_EQUAL_PTR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_STRING_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_MEMORY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_CHAR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, (message)) /* Floating Point (If Enabled) */ #define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message)) @@ -496,6 +588,28 @@ int suiteTearDown(int num_failures); #define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message)) #define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message)) +/* Shorthand */ +#ifdef UNITY_SHORTHAND_AS_OLD +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message)) +#endif +#ifdef UNITY_SHORTHAND_AS_INT +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_MEM +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, message) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_RAW +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, message) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, message) +#endif +#ifdef UNITY_SHORTHAND_AS_NONE +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif + /* end of UNITY_FRAMEWORK_H */ #ifdef __cplusplus } diff --git a/test/vendor/ceedling/vendor/unity/src/unity_internals.h b/test/vendor/ceedling/vendor/unity/src/unity_internals.h index 351d9fe67..a9a7ea237 100644 --- a/test/vendor/ceedling/vendor/unity/src/unity_internals.h +++ b/test/vendor/ceedling/vendor/unity/src/unity_internals.h @@ -1,6 +1,6 @@ /* ========================================== Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + Copyright (c) 2007-19 Mike Karlesky, Mark VanderVoord, Greg Williams [Released under MIT License. Please refer to license.txt for details] ========================================== */ @@ -19,6 +19,14 @@ #include #endif +#ifndef UNITY_EXCLUDE_STDDEF_H +#include +#endif + +#ifdef UNITY_INCLUDE_PRINT_FORMATTED +#include +#endif + /* Unity Attempts to Auto-Detect Integer Types * Attempt 1: UINT_MAX, ULONG_MAX in , or default to 32 bits * Attempt 2: UINTPTR_MAX in , or default to same size as long @@ -32,10 +40,6 @@ #include #endif -#ifndef UNITY_EXCLUDE_TIME_H -#include -#endif - /*------------------------------------------------------- * Guess Widths If Not Specified *-------------------------------------------------------*/ @@ -43,6 +47,8 @@ /* Determine the size of an int, if not already specified. * We cannot use sizeof(int), because it is not yet defined * at this stage in the translation of the C program. + * Also sizeof(int) does return the size in addressable units on all platforms, + * which may not necessarily be the size in bytes. * Therefore, infer it from UINT_MAX if possible. */ #ifndef UNITY_INT_WIDTH #ifdef UINT_MAX @@ -114,19 +120,21 @@ * 64-bit Support *-------------------------------------------------------*/ +/* Auto-detect 64 Bit Support */ #ifndef UNITY_SUPPORT_64 #if UNITY_LONG_WIDTH == 64 || UNITY_POINTER_WIDTH == 64 #define UNITY_SUPPORT_64 #endif #endif +/* 64-Bit Support Dependent Configuration */ #ifndef UNITY_SUPPORT_64 /* No 64-bit Support */ typedef UNITY_UINT32 UNITY_UINT; - typedef UNITY_INT32 UNITY_INT; + typedef UNITY_INT32 UNITY_INT; + #define UNITY_MAX_NIBBLES (8) /* Maximum number of nibbles in a UNITY_(U)INT */ #else - - /* 64-bit Support */ + /* 64-bit Support */ #if (UNITY_LONG_WIDTH == 32) typedef unsigned long long UNITY_UINT64; typedef signed long long UNITY_INT64; @@ -137,8 +145,8 @@ #error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported) #endif typedef UNITY_UINT64 UNITY_UINT; - typedef UNITY_INT64 UNITY_INT; - + typedef UNITY_INT64 UNITY_INT; + #define UNITY_MAX_NIBBLES (16) /* Maximum number of nibbles in a UNITY_(U)INT */ #endif /*------------------------------------------------------- @@ -146,24 +154,24 @@ *-------------------------------------------------------*/ #if (UNITY_POINTER_WIDTH == 32) -#define UNITY_PTR_TO_INT UNITY_INT32 -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32 + #define UNITY_PTR_TO_INT UNITY_INT32 + #define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32 #elif (UNITY_POINTER_WIDTH == 64) -#define UNITY_PTR_TO_INT UNITY_INT64 -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64 + #define UNITY_PTR_TO_INT UNITY_INT64 + #define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64 #elif (UNITY_POINTER_WIDTH == 16) -#define UNITY_PTR_TO_INT UNITY_INT16 -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16 + #define UNITY_PTR_TO_INT UNITY_INT16 + #define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16 #else - #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported) + #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported) #endif #ifndef UNITY_PTR_ATTRIBUTE -#define UNITY_PTR_ATTRIBUTE + #define UNITY_PTR_ATTRIBUTE #endif #ifndef UNITY_INTERNAL_PTR -#define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const void* + #define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const void* #endif /*------------------------------------------------------- @@ -289,42 +297,67 @@ typedef UNITY_FLOAT_TYPE UNITY_FLOAT; #define UNITY_OUTPUT_COMPLETE() #endif -#ifndef UNITY_EXEC_TIME_RESET #ifdef UNITY_INCLUDE_EXEC_TIME -#define UNITY_EXEC_TIME_RESET()\ - Unity.CurrentTestStartTime = 0;\ - Unity.CurrentTestStopTime = 0; -#else -#define UNITY_EXEC_TIME_RESET() -#endif + #if !defined(UNITY_EXEC_TIME_START) && \ + !defined(UNITY_EXEC_TIME_STOP) && \ + !defined(UNITY_PRINT_EXEC_TIME) && \ + !defined(UNITY_TIME_TYPE) + /* If none any of these macros are defined then try to provide a default implementation */ + + #if defined(UNITY_CLOCK_MS) + /* This is a simple way to get a default implementation on platforms that support getting a millisecond counter */ + #define UNITY_TIME_TYPE UNITY_UINT + #define UNITY_EXEC_TIME_START() Unity.CurrentTestStartTime = UNITY_CLOCK_MS() + #define UNITY_EXEC_TIME_STOP() Unity.CurrentTestStopTime = UNITY_CLOCK_MS() + #define UNITY_PRINT_EXEC_TIME() { \ + UNITY_UINT execTimeMs = (Unity.CurrentTestStopTime - Unity.CurrentTestStartTime); \ + UnityPrint(" ("); \ + UnityPrintNumberUnsigned(execTimeMs); \ + UnityPrint(" ms)"); \ + } + #elif defined(_WIN32) + #include + #define UNITY_TIME_TYPE clock_t + #define UNITY_GET_TIME(t) t = (clock_t)((clock() * 1000) / CLOCKS_PER_SEC) + #define UNITY_EXEC_TIME_START() UNITY_GET_TIME(Unity.CurrentTestStartTime) + #define UNITY_EXEC_TIME_STOP() UNITY_GET_TIME(Unity.CurrentTestStopTime) + #define UNITY_PRINT_EXEC_TIME() { \ + UNITY_UINT execTimeMs = (Unity.CurrentTestStopTime - Unity.CurrentTestStartTime); \ + UnityPrint(" ("); \ + UnityPrintNumberUnsigned(execTimeMs); \ + UnityPrint(" ms)"); \ + } + #elif defined(__unix__) + #include + #define UNITY_TIME_TYPE struct timespec + #define UNITY_GET_TIME(t) clock_gettime(CLOCK_MONOTONIC, &t) + #define UNITY_EXEC_TIME_START() UNITY_GET_TIME(Unity.CurrentTestStartTime) + #define UNITY_EXEC_TIME_STOP() UNITY_GET_TIME(Unity.CurrentTestStopTime) + #define UNITY_PRINT_EXEC_TIME() { \ + UNITY_UINT execTimeMs = ((Unity.CurrentTestStopTime.tv_sec - Unity.CurrentTestStartTime.tv_sec) * 1000L); \ + execTimeMs += ((Unity.CurrentTestStopTime.tv_nsec - Unity.CurrentTestStartTime.tv_nsec) / 1000000L); \ + UnityPrint(" ("); \ + UnityPrintNumberUnsigned(execTimeMs); \ + UnityPrint(" ms)"); \ + } + #endif + #endif #endif #ifndef UNITY_EXEC_TIME_START -#ifdef UNITY_INCLUDE_EXEC_TIME -#define UNITY_EXEC_TIME_START() Unity.CurrentTestStartTime = UNITY_CLOCK_MS(); -#else -#define UNITY_EXEC_TIME_START() -#endif +#define UNITY_EXEC_TIME_START() do{}while(0) #endif #ifndef UNITY_EXEC_TIME_STOP -#ifdef UNITY_INCLUDE_EXEC_TIME -#define UNITY_EXEC_TIME_STOP() Unity.CurrentTestStopTime = UNITY_CLOCK_MS(); -#else -#define UNITY_EXEC_TIME_STOP() +#define UNITY_EXEC_TIME_STOP() do{}while(0) #endif + +#ifndef UNITY_TIME_TYPE +#define UNITY_TIME_TYPE UNITY_UINT #endif #ifndef UNITY_PRINT_EXEC_TIME -#ifdef UNITY_INCLUDE_EXEC_TIME -#define UNITY_PRINT_EXEC_TIME() \ - UnityPrint(" (");\ - UNITY_COUNTER_TYPE execTimeMs = (Unity.CurrentTestStopTime - Unity.CurrentTestStartTime); - UnityPrintNumberUnsigned(execTimeMs);\ - UnityPrint(" ms)"); -#else -#define UNITY_PRINT_EXEC_TIME() -#endif +#define UNITY_PRINT_EXEC_TIME() do{}while(0) #endif /*------------------------------------------------------- @@ -339,23 +372,6 @@ typedef UNITY_FLOAT_TYPE UNITY_FLOAT; #define UNITY_COUNTER_TYPE UNITY_UINT #endif -/*------------------------------------------------------- - * Language Features Available - *-------------------------------------------------------*/ -#if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA) -# if defined(__GNUC__) || defined(__ghs__) /* __GNUC__ includes clang */ -# if !(defined(__WIN32__) && defined(__clang__)) && !defined(__TMS470__) -# define UNITY_WEAK_ATTRIBUTE __attribute__((weak)) -# endif -# endif -#endif - -#ifdef UNITY_NO_WEAK -# undef UNITY_WEAK_ATTRIBUTE -# undef UNITY_WEAK_PRAGMA -#endif - - /*------------------------------------------------------- * Internal Structs Needed *-------------------------------------------------------*/ @@ -365,10 +381,11 @@ typedef void (*UnityTestFunction)(void); #define UNITY_DISPLAY_RANGE_INT (0x10) #define UNITY_DISPLAY_RANGE_UINT (0x20) #define UNITY_DISPLAY_RANGE_HEX (0x40) +#define UNITY_DISPLAY_RANGE_CHAR (0x80) typedef enum { -UNITY_DISPLAY_STYLE_INT = sizeof(int)+ UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT = (UNITY_INT_WIDTH / 8) + UNITY_DISPLAY_RANGE_INT, UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT, UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT, UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT, @@ -376,7 +393,7 @@ UNITY_DISPLAY_STYLE_INT = sizeof(int)+ UNITY_DISPLAY_RANGE_INT, UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT, #endif -UNITY_DISPLAY_STYLE_UINT = sizeof(unsigned) + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT = (UNITY_INT_WIDTH / 8) + UNITY_DISPLAY_RANGE_UINT, UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT, UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT, UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT, @@ -391,16 +408,20 @@ UNITY_DISPLAY_STYLE_UINT = sizeof(unsigned) + UNITY_DISPLAY_RANGE_UINT, UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX, #endif + UNITY_DISPLAY_STYLE_CHAR = 1 + UNITY_DISPLAY_RANGE_CHAR + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_UNKNOWN } UNITY_DISPLAY_STYLE_T; typedef enum { - UNITY_EQUAL_TO = 1, - UNITY_GREATER_THAN = 2, - UNITY_GREATER_OR_EQUAL = 2 + UNITY_EQUAL_TO, - UNITY_SMALLER_THAN = 4, - UNITY_SMALLER_OR_EQUAL = 4 + UNITY_EQUAL_TO + UNITY_WITHIN = 0x0, + UNITY_EQUAL_TO = 0x1, + UNITY_GREATER_THAN = 0x2, + UNITY_GREATER_OR_EQUAL = 0x2 + UNITY_EQUAL_TO, + UNITY_SMALLER_THAN = 0x4, + UNITY_SMALLER_OR_EQUAL = 0x4 + UNITY_EQUAL_TO, + UNITY_UNKNOWN } UNITY_COMPARISON_T; #ifndef UNITY_EXCLUDE_FLOAT @@ -421,7 +442,8 @@ typedef enum UNITY_FLOAT_TRAIT typedef enum { UNITY_ARRAY_TO_VAL = 0, - UNITY_ARRAY_TO_ARRAY + UNITY_ARRAY_TO_ARRAY, + UNITY_ARRAY_UNKNOWN } UNITY_FLAGS_T; struct UNITY_STORAGE_T @@ -439,8 +461,8 @@ struct UNITY_STORAGE_T UNITY_COUNTER_TYPE CurrentTestFailed; UNITY_COUNTER_TYPE CurrentTestIgnored; #ifdef UNITY_INCLUDE_EXEC_TIME - UNITY_COUNTER_TYPE CurrentTestStartTime; - UNITY_COUNTER_TYPE CurrentTestStopTime; + UNITY_TIME_TYPE CurrentTestStartTime; + UNITY_TIME_TYPE CurrentTestStopTime; #endif #ifndef UNITY_EXCLUDE_SETJMP_H jmp_buf AbortFrame; @@ -455,6 +477,7 @@ extern struct UNITY_STORAGE_T Unity; void UnityBegin(const char* filename); int UnityEnd(void); +void UnitySetTestFile(const char* filename); void UnityConcludeTest(void); void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum); @@ -485,6 +508,11 @@ void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int *-------------------------------------------------------*/ void UnityPrint(const char* string); + +#ifdef UNITY_INCLUDE_PRINT_FORMATTED +void UnityPrintFormatted(const char* format, ...); +#endif + void UnityPrintLen(const char* string, const UNITY_UINT32 length); void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number); void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style); @@ -564,9 +592,18 @@ void UnityAssertNumbersWithin(const UNITY_UINT delta, const UNITY_LINE_TYPE lineNumber, const UNITY_DISPLAY_STYLE_T style); -void UnityFail(const char* msg, const UNITY_LINE_TYPE line); +void UnityAssertNumbersArrayWithin(const UNITY_UINT delta, + UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags); -void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line); +void UnityFail(const char* message, const UNITY_LINE_TYPE line); +void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); +void UnityMessage(const char* message, const UNITY_LINE_TYPE line); #ifndef UNITY_EXCLUDE_FLOAT void UnityAssertFloatsWithin(const UNITY_FLOAT delta, @@ -624,9 +661,15 @@ UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num); * Error Strings We Might Need *-------------------------------------------------------*/ +extern const char UnityStrOk[]; +extern const char UnityStrPass[]; +extern const char UnityStrFail[]; +extern const char UnityStrIgnore[]; + extern const char UnityStrErrFloat[]; extern const char UnityStrErrDouble[]; extern const char UnityStrErr64[]; +extern const char UnityStrErrShorthand[]; /*------------------------------------------------------- * Test Running Macros @@ -640,16 +683,14 @@ extern const char UnityStrErr64[]; #define TEST_ABORT() return #endif -#ifndef UNITY_EXCLUDE_TIME_H -#define UNITY_CLOCK_MS() (UNITY_COUNTER_TYPE)((clock() * 1000) / CLOCKS_PER_SEC) -#else -#define UNITY_CLOCK_MS() -#endif - /* This tricky series of macros gives us an optional line argument to treat it as RUN_TEST(func, num=__LINE__) */ #ifndef RUN_TEST #ifdef __STDC_VERSION__ #if __STDC_VERSION__ >= 199901L +#define UNITY_SUPPORT_VARIADIC_MACROS +#endif +#endif +#ifdef UNITY_SUPPORT_VARIADIC_MACROS #define RUN_TEST(...) UnityDefaultTestRun(RUN_TEST_FIRST(__VA_ARGS__), RUN_TEST_SECOND(__VA_ARGS__)) #define RUN_TEST_FIRST(...) RUN_TEST_FIRST_HELPER(__VA_ARGS__, throwaway) #define RUN_TEST_FIRST_HELPER(first, ...) (first), #first @@ -657,7 +698,6 @@ extern const char UnityStrErr64[]; #define RUN_TEST_SECOND_HELPER(first, second, ...) (second) #endif #endif -#endif /* If we can't do the tricky version, we'll just have to require them to always include the line number */ #ifndef RUN_TEST @@ -683,6 +723,16 @@ extern const char UnityStrErr64[]; #define UNITY_END() UnityEnd() #endif +#ifndef UNITY_SHORTHAND_AS_INT +#ifndef UNITY_SHORTHAND_AS_MEM +#ifndef UNITY_SHORTHAND_AS_NONE +#ifndef UNITY_SHORTHAND_AS_RAW +#define UNITY_SHORTHAND_AS_OLD +#endif +#endif +#endif +#endif + /*----------------------------------------------- * Command Line Argument Support *-----------------------------------------------*/ @@ -718,6 +768,7 @@ int UnityTestMatches(void); #define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) #define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) #define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_EQUAL_CHAR(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) #define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((UNITY_INT)(mask), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line)) #define UNITY_TEST_ASSERT_GREATER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) @@ -731,6 +782,7 @@ int UnityTestMatches(void); #define UNITY_TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) #define UNITY_TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) #define UNITY_TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_GREATER_THAN_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) #define UNITY_TEST_ASSERT_SMALLER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) #define UNITY_TEST_ASSERT_SMALLER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) @@ -743,42 +795,60 @@ int UnityTestMatches(void); #define UNITY_TEST_ASSERT_SMALLER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) #define UNITY_TEST_ASSERT_SMALLER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) #define UNITY_TEST_ASSERT_SMALLER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_SMALLER_THAN_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) -#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 ) (threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16) (threshold), (UNITY_INT)(UNITY_INT16) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32) (threshold), (UNITY_INT)(UNITY_INT32) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) #define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) #define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) #define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) #define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) #define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) #define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 ) (threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) -#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) -#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin( (delta), (UNITY_INT) (expected), (UNITY_INT) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_INT8 ) (expected), (UNITY_INT)(UNITY_INT8 ) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_INT16) (expected), (UNITY_INT)(UNITY_INT16) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_INT32) (expected), (UNITY_INT)(UNITY_INT32) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin( (delta), (UNITY_INT) (expected), (UNITY_INT) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) #define UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) #define UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) #define UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) #define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) #define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) #define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_CHAR_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_INT8 ) (expected), (UNITY_INT)(UNITY_INT8 ) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_INT_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin( (delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT8 )(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT16)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT32)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin( (delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin( (UNITY_UINT16)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT16)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT32)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT8 )(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT16)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT32)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT8 )(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR, UNITY_ARRAY_TO_ARRAY) + #define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((UNITY_PTR_TO_INT)(expected), (UNITY_PTR_TO_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER) #define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)(line)) @@ -799,21 +869,23 @@ int UnityTestMatches(void); #define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_ARRAY) #define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) #define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR, UNITY_ARRAY_TO_ARRAY) -#define UNITY_TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) (expected), sizeof(int)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) (expected), sizeof(unsigned int)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT16)(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT32)(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_PTR_TO_INT) (expected), sizeof(int*)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) (expected), (UNITY_INT_WIDTH / 8)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) (expected), (UNITY_INT_WIDTH / 8)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT16)(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT32)(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_PTR_TO_INT) (expected), (UNITY_POINTER_WIDTH / 8)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_VAL) #define UNITY_TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) #define UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_CHAR(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR, UNITY_ARRAY_TO_VAL) #ifdef UNITY_SUPPORT_64 #define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) @@ -822,9 +894,9 @@ int UnityTestMatches(void); #define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY) #define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY) #define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY) -#define UNITY_TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_VAL) -#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)(expected), 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT64)(expected), 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)(expected), 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_VAL) #define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) #define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) #define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) @@ -840,6 +912,9 @@ int UnityTestMatches(void); #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT64)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT64)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT64)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY) #else #define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) #define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) @@ -862,6 +937,9 @@ int UnityTestMatches(void); #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) #define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) #endif #ifdef UNITY_EXCLUDE_FLOAT @@ -906,10 +984,10 @@ int UnityTestMatches(void); #define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) #define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) #else -#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((UNITY_DOUBLE)(delta), (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)line) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((UNITY_DOUBLE)(expected) * (UNITY_DOUBLE)UNITY_DOUBLE_PRECISION, (UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual, (UNITY_LINE_TYPE)(line), message) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((UNITY_DOUBLE*)(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_ARRAY_TO_ARRAY) -#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray(UnityDoubleToPtr(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((UNITY_DOUBLE)(delta), (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((UNITY_DOUBLE)(expected) * (UNITY_DOUBLE)UNITY_DOUBLE_PRECISION, (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((UNITY_DOUBLE*)(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray(UnityDoubleToPtr(expected), (UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) #define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) #define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) #define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) diff --git a/tools/build_all.py b/tools/build_all.py index b20785049..9f35aac63 100644 --- a/tools/build_all.py +++ b/tools/build_all.py @@ -15,12 +15,17 @@ exit_status = 0 total_time = time.monotonic() all_examples = [] -for entry in os.scandir("examples/device"): - if entry.is_dir(): - all_examples.append(entry.name) -# TODO update freeRTOS example to work with all boards (only nrf52840 now) -all_examples.remove("cdc_msc_hid_freertos") +# build all example if input not existed +if len(sys.argv) > 1: + all_examples.append(sys.argv[1]) +else: + for entry in os.scandir("examples/device"): + if entry.is_dir(): + all_examples.append(entry.name) + + # TODO update freeRTOS example to work with all boards (only nrf52840 now) + all_examples.remove("cdc_msc_hid_freertos") all_boards = [] for entry in os.scandir("hw/bsp"): @@ -31,7 +36,7 @@ for entry in os.scandir("hw/bsp"): def build_example(example, board): subprocess.run("make -C examples/device/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - return subprocess.run("make -j 4 -C examples/device/{} BOARD={} all".format(example, board), shell=True, + return subprocess.run("make -j 8 -C examples/device/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)