diff --git a/CHANGELOG.md b/CHANGELOG.md index 837efed5d..d62d479f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,22 +2,21 @@ ## Unreleased -### Bug Fixes +### Features -* patchsm: Corrected gate out pin assignment confusion added by (#417) as noted by [apbianco](https://forum.electro-smith.com/u/apbianco) and [tele_player](https://forum.electro-smith.com/u/tele_player) +* bootloader: added `System::BootloaderMode::DAISY` and `System::BootloaderMode::DAISY_SKIP_TIMEOUT` options to `System::ResetToBootloader` method for better firmware updating flexibility -## v5.3.0 +### Bug fixes -### Features +* bootloader: pins `D29` and `D30` are no longer stuck when using the Daisy bootloader -* driver: Software SPI transport `SSD130x4WireSoftSpiTransport` added for the OLED Display driver. (#551) +### Migrating -### Bug Fixes +#### Bootloader -* driver: Fixed a compiler error in `Max11300Driver::WriteAnalogPinVolts()` -* driver: Fixed error reading multiple registers at once from the MPC23x17 GPIO expanders (#550) -* seed: Fixed out of range pin definitions for extra GPIO on the Daisy Seed2 DFM (#544) -* patchsm: Fixed issue where updating the audio callback params didn't update control samplerate (#543) +* This version of libDaisy and greater will be compatible with any version of the Daisy bootloader, meaning you won't have to update the bootloader on your product if you want the latest changes to libDaisy. +* However, for newer versions of the bootloader, you must use a compatible version of libDaisy. + * Daisy bootloader v6.0 and up will only be compatible with libDaisy v5.3 and up. ## v5.2.0 @@ -46,7 +45,7 @@ * bootloader: Working with the bootloader has been simplified. See [the new guide for updates on usage](https://electro-smith.github.io/libDaisy/md_doc_md__a7__getting__started__daisy__bootloader.html) * usb: `USBHost` class has added support for user callbacks on device connection, disconnection, and when the MSC class becomes active. * uart: Adds DMA RX and TX modes, similar to how they work on the I2C and SPI. -* uart: Update function names to be more in line with the new DMA / Blocking scheme. +* uart: Update function names to be more in line with the new DMA / Blocking scheme. * The old methods are wrappers for the new ones to preserve backwards compatibility, but **will be removed in a future version**. * Affected functions: `PollReceive`, `PollTx`, `StartRx`, `RxActive`, `FlushRx`, `PopRx`, `Readable` @@ -91,7 +90,7 @@ * testing: debugging configuration now uses `lldb` debugging extension to support unit test debugging on macOS with Apple Silicon * driver: oled_ssd130x.h - Add the SpiHandle:Config struct to SSD130x4WireTransport:Config to allow full access to the SPI peripheral configuration. * hid: fixed issue in `AnalogControl` where computed coeff could be out of range with certain block sizes -* driver: added missing alternate function pin mappings for SPI2, and UART for pins available on the patch_sm hardware +* driver: added missing alternate function pin mappings for SPI2, and UART for pins available on the patch_sm hardware * usb: fixed issue with MIDI output from USB * driver: fixed off-by-one error in qspi erase function. @@ -240,7 +239,7 @@ max11300driver.ConfigurePinAsAnalogWrite(daisy::MAX11300::PIN_1, daisy::MAX11300 ### Other -* switch: Use `System::GetNow()` rather than the update rate to calculate `TimeHeldMs()`. +* switch: Use `System::GetNow()` rather than the update rate to calculate `TimeHeldMs()`. * This has also been applied to the `Encoder` class (since it uses `Switch` internally). * usb host: ST Middleware for USB Host support has been added to the Middlewares folder * fatfs: changed default `FS_LOCK` to 0, allowing for more simultaneously open FIL objects. @@ -434,7 +433,7 @@ sdram.Init(); ### Other -* test: add unit testing for midi parser. +* test: add unit testing for midi parser. * tests: add tests for `FIFO` * docs: Update TODO comment in `uart.h` to reflect most recent uart update. * ci: add filters to the workflows diff --git a/Makefile b/Makefile index 812d0bcc6..7c3764f8d 100644 --- a/Makefile +++ b/Makefile @@ -309,11 +309,11 @@ WARNINGS += -Wall -Wno-attributes -Wno-strict-aliasing -Wno-maybe-uninitialized CPP_WARNINGS += -Wno-register # compile gcc flags -ASFLAGS = $(MCU) $(AS_INCLUDES) $(AS_DEFS) -ggdb $(WARNINGS) $(OPT) -fdata-sections -ffunction-sections - -CFLAGS = $(MCU) $(C_INCLUDES) $(C_DEFS) -ggdb $(WARNINGS) $(OPT) -fasm -fdata-sections -ffunction-sections +ASFLAGS += $(MCU) $(AS_INCLUDES) $(AS_DEFS) $(WARNINGS) $(OPT) -fdata-sections -ffunction-sections +CFLAGS += $(MCU) $(C_INCLUDES) $(C_DEFS) $(WARNINGS) $(OPT) -fasm -fdata-sections -ffunction-sections ifeq ($(DEBUG), 1) +ASFLAGS += -g -ggdb CFLAGS += -g -ggdb OPT = -O0 C_DEFS += -DDEBUG=1 @@ -325,7 +325,7 @@ CFLAGS += \ -finline-functions # C++ Flags -CPPFLAGS = $(CFLAGS) $(CPP_WARNINGS) +CPPFLAGS += $(CFLAGS) $(CPP_WARNINGS) CPPFLAGS += \ -fno-exceptions \ -fno-rtti diff --git a/core/Makefile b/core/Makefile index 0bc22fed7..fc38b7daa 100644 --- a/core/Makefile +++ b/core/Makefile @@ -163,20 +163,18 @@ endif C_INCLUDES += -I$(FATFS_DIR) # compile gcc flags -ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections +ASFLAGS += $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections +CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -Wno-missing-attributes -fasm -fdata-sections -ffunction-sections -Wno-stringop-overflow ifeq ($(DEBUG), 1) ASFLAGS += -g -ggdb -endif - -CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -Wno-missing-attributes -fasm -fdata-sections -ffunction-sections -Wno-stringop-overflow - CFLAGS += -g -ggdb +endif # Generate dependency information CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" -CPPFLAGS = $(CFLAGS) +CPPFLAGS += $(CFLAGS) CPPFLAGS += \ -fno-exceptions \ -fasm \ diff --git a/core/STM32H750IB_flash.lds b/core/STM32H750IB_flash.lds index ce2fe8fad..0756574af 100644 --- a/core/STM32H750IB_flash.lds +++ b/core/STM32H750IB_flash.lds @@ -7,14 +7,15 @@ ENTRY(Reset_Handler) MEMORY { - FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 128K - DTCMRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 128K - SRAM (RWX) : ORIGIN = 0x24000000, LENGTH = 512K - RAM_D2 (RWX) : ORIGIN = 0x30000000, LENGTH = 288K - RAM_D3 (RWX) : ORIGIN = 0x38000000, LENGTH = 64K - ITCMRAM (RWX) : ORIGIN = 0x00000000, LENGTH = 64K - SDRAM (RWX) : ORIGIN = 0xc0000000, LENGTH = 64M - QSPIFLASH (RX) : ORIGIN = 0x90000000, LENGTH = 8M + FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 128K + DTCMRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 128K + SRAM (RWX) : ORIGIN = 0x24000000, LENGTH = 512K + RAM_D2 (RWX) : ORIGIN = 0x30000000, LENGTH = 288K + RAM_D3 (RWX) : ORIGIN = 0x38000000, LENGTH = 64K + BACKUP_SRAM (RWX) : ORIGIN = 0x38800000, LENGTH = 4K + ITCMRAM (RWX) : ORIGIN = 0x00000000, LENGTH = 64K + SDRAM (RWX) : ORIGIN = 0xc0000000, LENGTH = 64M + QSPIFLASH (RX) : ORIGIN = 0x90000000, LENGTH = 8M } _estack = 0x20020000; @@ -122,7 +123,7 @@ SECTIONS PROVIDE(__bss_end__ = _ebss); } > SRAM - PROVIDE(end = .); + PROVIDE(end = .); .dtcmram_bss (NOLOAD) : { @@ -183,8 +184,21 @@ SECTIONS PROVIDE(__sdram_bss_end = _esdram_bss); } > SDRAM + .backup_sram (NOLOAD) : + { + . = ALIGN(4); + _sbackup_sram = .; + + PROVIDE(__backup_sram_start = _sbackup_sram); + *(.backup_sram) + *(.backup_sram*) + . = ALIGN(4); + _ebackup_sram = .; + + PROVIDE(__backup_sram_end = _ebackup_sram); + } > BACKUP_SRAM - .qspiflash_text : + .qspiflash_text : { . = ALIGN(4); _sqspiflash_text = .; diff --git a/core/STM32H750IB_qspi.lds b/core/STM32H750IB_qspi.lds index fd48ed922..d772e9f32 100644 --- a/core/STM32H750IB_qspi.lds +++ b/core/STM32H750IB_qspi.lds @@ -8,15 +8,16 @@ ENTRY(Reset_Handler) MEMORY { - FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 128K - DTCMRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 128K - SRAM (RWX) : ORIGIN = 0x24000000, LENGTH = 512K - RAM_D2_DMA (RWX) : ORIGIN = 0x30000000, LENGTH = 32K - RAM_D2 (RWX) : ORIGIN = 0x30008000, LENGTH = 256K - RAM_D3 (RWX) : ORIGIN = 0x38000000, LENGTH = 64K - ITCMRAM (RWX) : ORIGIN = 0x00000000, LENGTH = 64K - SDRAM (RWX) : ORIGIN = 0xc0000000, LENGTH = 64M - QSPIFLASH (RX): ORIGIN = 0x90040000, LENGTH = 7936K + FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 128K + DTCMRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 128K + SRAM (RWX) : ORIGIN = 0x24000000, LENGTH = 512K + RAM_D2_DMA (RWX) : ORIGIN = 0x30000000, LENGTH = 32K + RAM_D2 (RWX) : ORIGIN = 0x30008000, LENGTH = 256K + RAM_D3 (RWX) : ORIGIN = 0x38000000, LENGTH = 64K + BACKUP_SRAM (RWX) : ORIGIN = 0x38800000, LENGTH = 4K + ITCMRAM (RWX) : ORIGIN = 0x00000000, LENGTH = 64K + SDRAM (RWX) : ORIGIN = 0xc0000000, LENGTH = 64M + QSPIFLASH (RX) : ORIGIN = 0x90040000, LENGTH = 7936K } _estack = 0x20020000; @@ -136,7 +137,7 @@ SECTIONS _ebss = .; PROVIDE(__bss_end__ = _ebss); - } > SRAM + } > SRAM .dtcmram_bss (NOLOAD) : { @@ -183,6 +184,20 @@ SECTIONS PROVIDE(__sdram_bss_end = _esdram_bss); } > SDRAM + .backup_sram (NOLOAD) : + { + . = ALIGN(4); + _sbackup_sram = .; + + PROVIDE(__backup_sram_start = _sbackup_sram); + *(.backup_sram) + *(.backup_sram*) + . = ALIGN(4); + _ebackup_sram = .; + + PROVIDE(__backup_sram_end = _ebackup_sram); + } > BACKUP_SRAM + /* .qspiflash_text : { diff --git a/core/STM32H750IB_sram.lds b/core/STM32H750IB_sram.lds index f84f05df3..a1de276bb 100644 --- a/core/STM32H750IB_sram.lds +++ b/core/STM32H750IB_sram.lds @@ -7,15 +7,16 @@ ENTRY(Reset_Handler) MEMORY { - FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 128K - DTCMRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 128K - SRAM (RWX) : ORIGIN = 0x24000000, LENGTH = 512K - 32K - RAM_D2_DMA (RWX) : ORIGIN = 0x30000000, LENGTH = 32K - RAM_D2 (RWX) : ORIGIN = 0x30008000, LENGTH = 256K - RAM_D3 (RWX) : ORIGIN = 0x38000000, LENGTH = 64K - ITCMRAM (RWX) : ORIGIN = 0x00000000, LENGTH = 64K - SDRAM (RWX) : ORIGIN = 0xc0000000, LENGTH = 64M - QSPIFLASH (RX): ORIGIN = 0x90040000, LENGTH = 7936K + FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 128K + DTCMRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 128K + SRAM (RWX) : ORIGIN = 0x24000000, LENGTH = 512K + RAM_D2_DMA (RWX) : ORIGIN = 0x30000000, LENGTH = 32K + RAM_D2 (RWX) : ORIGIN = 0x30008000, LENGTH = 256K - 32K + RAM_D3 (RWX) : ORIGIN = 0x38000000, LENGTH = 64K + BACKUP_SRAM (RWX) : ORIGIN = 0x38800000, LENGTH = 4K + ITCMRAM (RWX) : ORIGIN = 0x00000000, LENGTH = 64K + SDRAM (RWX) : ORIGIN = 0xc0000000, LENGTH = 64M + QSPIFLASH (RX) : ORIGIN = 0x90040000, LENGTH = 7936K } _estack = 0x20020000; @@ -135,7 +136,7 @@ SECTIONS _ebss = .; PROVIDE(__bss_end__ = _ebss); - } > DTCMRAM + } > DTCMRAM .dtcmram_bss (NOLOAD) : { @@ -182,8 +183,21 @@ SECTIONS PROVIDE(__sdram_bss_end = _esdram_bss); } > SDRAM + .backup_sram (NOLOAD) : + { + . = ALIGN(4); + _sbackup_sram = .; + + PROVIDE(__backup_sram_start = _sbackup_sram); + *(.backup_sram) + *(.backup_sram*) + . = ALIGN(4); + _ebackup_sram = .; + + PROVIDE(__backup_sram_end = _ebackup_sram); + } > BACKUP_SRAM - .qspiflash_text : + .qspiflash_text : { . = ALIGN(4); _sqspiflash_text = .; diff --git a/core/dsy_bootloader_v6_1.bin b/core/dsy_bootloader_v6_1.bin new file mode 100755 index 000000000..939a10a33 Binary files /dev/null and b/core/dsy_bootloader_v6_1.bin differ diff --git a/src/daisy.h b/src/daisy.h index 88a26795c..b0744046b 100644 --- a/src/daisy.h +++ b/src/daisy.h @@ -38,7 +38,6 @@ #include "hid/disp/display.h" #include "hid/disp/oled_display.h" #include "hid/disp/graphics_common.h" -#include "hid/wavplayer.h" #include "hid/led.h" #include "hid/rgb_led.h" #include "dev/sr_595.h" @@ -68,7 +67,12 @@ #include "util/PersistentStorage.h" #include "util/Stack.h" #include "util/VoctCalibration.h" + +#ifdef USE_FATFS +#include "hid/wavplayer.h" #include "util/WaveTableLoader.h" #include "util/WavWriter.h" +#endif + #endif #endif diff --git a/src/daisy_core.h b/src/daisy_core.h index db7c4f46d..672ee964f 100644 --- a/src/daisy_core.h +++ b/src/daisy_core.h @@ -230,7 +230,7 @@ FORCE_INLINE dsy_gpio_pin dsy_pin(dsy_gpio_port port, uint8_t pin) * * Please use Pin struct instead. */ -FORCE_INLINE uint8_t dsy_pin_cmp(dsy_gpio_pin *a, dsy_gpio_pin *b) +FORCE_INLINE uint8_t dsy_pin_cmp(const dsy_gpio_pin *a, const dsy_gpio_pin *b) { return ((a->port == b->port) && (a->pin == b->pin)); } diff --git a/src/daisy_patch_sm.cpp b/src/daisy_patch_sm.cpp index 07047a151..dfe08d3cd 100644 --- a/src/daisy_patch_sm.cpp +++ b/src/daisy_patch_sm.cpp @@ -41,8 +41,8 @@ namespace patch_sm DUMMYPIN, /**< B2 - Audio Out Left*/ DUMMYPIN, /**< B3 - Audio In Right */ DUMMYPIN, /**< B4 - Audio In Left */ - {DSY_GPIOC, 14}, /**< B5 - GATE OUT 1 */ - {DSY_GPIOC, 13}, /**< B6 - GATE OUT 2 */ + {DSY_GPIOC, 13}, /**< B5 - GATE OUT 1 */ + {DSY_GPIOC, 14}, /**< B6 - GATE OUT 2 */ {DSY_GPIOB, 8}, /**< B7 - I2C1 SCL */ {DSY_GPIOB, 9}, /**< B8 - I2C1 SDA */ {DSY_GPIOG, 14}, /**< B9 - GATE IN 2 */ @@ -216,7 +216,7 @@ namespace patch_sm } } - /** Actual DaisyPatchSM implementation + /** Actual DaisyPatchSM implementation * With the pimpl model in place, we can/should probably * move the rest of the implementation to the Impl class */ @@ -229,13 +229,22 @@ namespace patch_sm System::Config syscfg; syscfg.Boost(); - auto memory = System::GetProgramMemoryRegion(); - if(memory != System::MemoryRegion::INTERNAL_FLASH) + auto memory = System::GetProgramMemoryRegion(); + auto boot_version = System::GetBootloaderVersion(); + + // When using the bootloader prior to v6, clocks have been already configured + if(boot_version == System::BootInfo::Version::LT_v6_0 + && memory != System::MemoryRegion::INTERNAL_FLASH) + { syscfg.skip_clocks = true; + } system.Init(syscfg); /** Memories */ - if(memory == System::MemoryRegion::INTERNAL_FLASH) + // When using the bootloader priori to v6, SDRAM has been already configured + if(boot_version != System::BootInfo::Version::LT_v6_0 + || (boot_version == System::BootInfo::Version::LT_v6_0 + && memory == System::MemoryRegion::INTERNAL_FLASH)) { /** FMC SDRAM */ sdram.Init(); @@ -331,12 +340,12 @@ namespace patch_sm gate_out_1.mode = DSY_GPIO_MODE_OUTPUT_PP; gate_out_1.pull = DSY_GPIO_NOPULL; - gate_out_1.pin = B5; + gate_out_1.pin = B6; dsy_gpio_init(&gate_out_1); gate_out_2.mode = DSY_GPIO_MODE_OUTPUT_PP; gate_out_2.pull = DSY_GPIO_NOPULL; - gate_out_2.pin = B6; + gate_out_2.pin = B5; dsy_gpio_init(&gate_out_2); /** DAC init */ diff --git a/src/daisy_seed.cpp b/src/daisy_seed.cpp index 31ff0e213..1387875c8 100644 --- a/src/daisy_seed.cpp +++ b/src/daisy_seed.cpp @@ -14,7 +14,7 @@ using namespace daisy; #define SEED_TEST_POINT_PIN 14 #ifndef SEED_REV2 -const dsy_gpio_pin seedgpio[33] = { +const dsy_gpio_pin seedgpio[31] = { // GPIO 1-8 //{DSY_GPIOA, 8}, // removed on Rev4 {DSY_GPIOB, 12}, @@ -42,7 +42,7 @@ const dsy_gpio_pin seedgpio[33] = { {DSY_GPIOC, 1}, {DSY_GPIOC, 4}, {DSY_GPIOA, 5}, - // GPIO 25-31 + // GPIO 17-24 {DSY_GPIOA, 4}, {DSY_GPIOA, 1}, {DSY_GPIOA, 0}, @@ -51,10 +51,6 @@ const dsy_gpio_pin seedgpio[33] = { {DSY_GPIOA, 2}, {DSY_GPIOB, 14}, {DSY_GPIOB, 15}, - - // Seed2DFM exclusive pins - {DSY_GPIOC, 2}, - {DSY_GPIOC, 3}, }; #else const dsy_gpio_port seed_ports[32] = { @@ -113,17 +109,23 @@ void DaisySeed::Init(bool boost) testpoint.mode = DSY_GPIO_MODE_OUTPUT_PP; - auto memory = System::GetProgramMemoryRegion(); + auto memory = System::GetProgramMemoryRegion(); + auto boot_version = System::GetBootloaderVersion(); - if(memory != System::MemoryRegion::INTERNAL_FLASH) + if(boot_version == System::BootInfo::Version::LT_v6_0 + && memory != System::MemoryRegion::INTERNAL_FLASH) + { syscfg.skip_clocks = true; + } system.Init(syscfg); if(memory != System::MemoryRegion::QSPI) qspi.Init(qspi_config); - if(memory == System::MemoryRegion::INTERNAL_FLASH) + if(boot_version != System::BootInfo::Version::LT_v6_0 + || (boot_version == System::BootInfo::Version::LT_v6_0 + && memory == System::MemoryRegion::INTERNAL_FLASH)) { dsy_gpio_init(&led); dsy_gpio_init(&testpoint); @@ -163,7 +165,7 @@ void DaisySeed::DeInit() dsy_gpio_pin DaisySeed::GetPin(uint8_t pin_idx) { dsy_gpio_pin p; - pin_idx = pin_idx < sizeof(seedgpio) / sizeof(seedgpio[0]) ? pin_idx : 0; + pin_idx = pin_idx < 32 ? pin_idx : 0; #ifndef SEED_REV2 p = seedgpio[pin_idx]; #else diff --git a/src/dev/max11300.h b/src/dev/max11300.h index 281104582..12f8c3d70 100644 --- a/src/dev/max11300.h +++ b/src/dev/max11300.h @@ -513,7 +513,7 @@ class MAX11300Driver return WriteAnalogPinRaw( device_index, pin, - MAX11300Driver::VoltsTo12BitUint(voltage, pin_config.range.dac)); + MAX11300Driver::VoltsTo12BitUint(voltage, pin_config.range)); } /** diff --git a/src/dev/mcp23x17.h b/src/dev/mcp23x17.h index fcc4db790..06a48f81b 100644 --- a/src/dev/mcp23x17.h +++ b/src/dev/mcp23x17.h @@ -135,7 +135,7 @@ class Mcp23017Transport { uint8_t data[2]; i2c_.ReadDataAtAddress( - i2c_address_, static_cast(reg), 1, data, 2, timeout); + i2c_address_, static_cast(reg), 1, data, 1, timeout); portA = data[0]; portB = data[1]; diff --git a/src/per/qspi.cpp b/src/per/qspi.cpp index 17727910a..eceb7c784 100644 --- a/src/per/qspi.cpp +++ b/src/per/qspi.cpp @@ -49,7 +49,7 @@ class QSPIHandle::Impl QSPIHandle::Result Erase(uint32_t start_addr, uint32_t end_addr); - QSPIHandle::Result EraseSector(uint32_t address); + QSPIHandle::Result EraseCmd(uint32_t address, uint32_t instruction); uint32_t GetPin(size_t pin); @@ -330,39 +330,50 @@ QSPIHandle::Impl::Write(uint32_t address, uint32_t size, uint8_t* buffer) QSPIHandle::Result QSPIHandle::Impl::Erase(uint32_t start_addr, uint32_t end_addr) { - uint32_t block_addr; - uint32_t block_size = IS25LP080D_SECTOR_SIZE; // 4kB blocks for now. - // 64kB chunks for now. - start_addr = start_addr - (start_addr % block_size); - while(end_addr > start_addr) + if((end_addr - start_addr) >= IS25LP080D_BLOCK_SIZE + && ((end_addr - start_addr) % IS25LP080D_BLOCK_SIZE) == 0) { - block_addr = start_addr & 0x0FFFFFFF; - if(EraseSector(block_addr) != QSPIHandle::Result::OK) + uint32_t block_addr; + uint32_t block_size = IS25LP080D_BLOCK_SIZE; + start_addr = start_addr - (start_addr % block_size); + while(end_addr > start_addr) { - ERR_RECOVERY(Status::E_HAL_ERROR); + block_addr = start_addr & 0x0FFFFFFF; + if(EraseCmd(block_addr, BLOCK_ERASE_CMD) != QSPIHandle::Result::OK) + { + ERR_RECOVERY(Status::E_HAL_ERROR); + } + start_addr += block_size; + } + } + else + { + uint32_t block_addr; + uint32_t block_size = IS25LP080D_SECTOR_SIZE; // 4kB blocks for now. + // 64kB chunks for now. + start_addr = start_addr - (start_addr % block_size); + while(end_addr > start_addr) + { + block_addr = start_addr & 0x0FFFFFFF; + if(EraseCmd(block_addr, SECTOR_ERASE_CMD) != QSPIHandle::Result::OK) + { + ERR_RECOVERY(Status::E_HAL_ERROR); + } + start_addr += block_size; } - start_addr += block_size; } return QSPIHandle::Result::OK; } -QSPIHandle::Result QSPIHandle::Impl::EraseSector(uint32_t address) +QSPIHandle::Result QSPIHandle::Impl::EraseCmd(uint32_t address, + uint32_t instruction + = SECTOR_ERASE_CMD) { - uint8_t use_qpi = 0; QSPI_CommandTypeDef s_command; - if(use_qpi) - { - s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES; - s_command.Instruction = SECTOR_ERASE_QPI_CMD; - s_command.AddressMode = QSPI_ADDRESS_4_LINES; - } - else - { - s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; - s_command.Instruction = SECTOR_ERASE_CMD; - s_command.AddressMode = QSPI_ADDRESS_1_LINE; - } + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; + s_command.Instruction = instruction; + s_command.AddressMode = QSPI_ADDRESS_1_LINE; s_command.AddressSize = QSPI_ADDRESS_24_BITS; s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; s_command.DataMode = QSPI_DATA_NONE; @@ -898,7 +909,7 @@ QSPIHandle::Result QSPIHandle::Erase(uint32_t start_addr, uint32_t end_addr) QSPIHandle::Result QSPIHandle::EraseSector(uint32_t address) { - return pimpl_->EraseSector(address); + return pimpl_->EraseCmd(address, SECTOR_ERASE_CMD); } void* QSPIHandle::GetData(uint32_t offset) diff --git a/src/sys/ffconf.h b/src/sys/ffconf.h index 99fe4ffd1..53f79ff45 100644 --- a/src/sys/ffconf.h +++ b/src/sys/ffconf.h @@ -22,7 +22,7 @@ #define _FFCONF 68300 /**< Revision ID */ /*-----------------------------------------------------------------------------/ -/ Additional user header to be used +/ Additional user header to be used /-----------------------------------------------------------------------------*/ #include "util/bsp_sd_diskio.h" @@ -32,14 +32,14 @@ /-----------------------------------------------------------------------------*/ #define _FS_READONLY \ - 0 /**< 0:Read/Write or 1:Read only + 0 /**< 0:Read/Write or 1:Read only This option switches read-only configuration. (0:Read/Write or 1:Read-only) / Read-only configuration removes writing API functions, f_write(), f_sync(), / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() / and optional writing functions as well. */ #define _FS_MINIMIZE \ - 0 /**< 0 to 3 + 0 /**< 0 to 3 This option defines minimization level to remove some basic API functions. / / 0: All basic functions are enabled. @@ -49,7 +49,7 @@ / 3: f_lseek() function is removed in addition to 2. */ #define _USE_STRFUNC \ - 2 /**< 0:Disable or 1-2:Enable + 2 /**< 0:Disable or 1-2:Enable This option switches string functions, f_gets(), f_putc(), f_puts() and / f_printf(). / @@ -132,7 +132,7 @@ / ff_memfree(), must be added to the project. */ #define _LFN_UNICODE \ - 0 /**< 0:ANSI/OEM or 1:Unicode + 0 /**< 0:ANSI/OEM or 1:Unicode This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16) / To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1. / This option also affects behavior of string I/O functions. */ @@ -149,7 +149,7 @@ This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16) / This option has no effect when _LFN_UNICODE == 0. */ #define _FS_RPATH \ - 0 /**< 0 to 2 + 2 /**< 0 to 2 This option configures support of relative path. / / 0: Disable relative path and remove related functions. @@ -186,7 +186,7 @@ This option switches support of multi-partition on a physical drive. / funciton will be available. */ #define _MIN_SS 512 /**< 512, 1024, 2048 or 4096 */ #define _MAX_SS \ - 512 /**< 512, 1024, 2048 or 4096 + 512 /**< 512, 1024, 2048 or 4096 These options configure the range of sector size to be supported. (512, 1024, / 2048 or 4096) Always set both 512 for most systems, all type of memory cards and / harddisk. But a larger value may be required for on-board flash memory and some @@ -200,7 +200,7 @@ This option switches support of multi-partition on a physical drive. / disk_ioctl() function. */ #define _FS_NOFSINFO \ - 0 /**< 0,1,2 or 3 + 0 /**< 0,1,2 or 3 If you need to know correct free space on the FAT32 volume, set bit 0 of this / option, and f_getfree() function at first time after volume mount will force / a full FAT scan. Bit 1 controls the use of last allocated cluster number. @@ -216,7 +216,7 @@ This option switches support of multi-partition on a physical drive. /----------------------------------------------------------------------------*/ #define _FS_TINY \ - 0 /**< 0:Normal or 1:Tiny + 0 /**< 0:Normal or 1:Tiny This option switches tiny buffer configuration. (0:Normal or 1:Tiny) / At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes. / Instead of private sector buffer eliminated from the file object, common sector @@ -231,18 +231,18 @@ This option switches support of multi-partition on a physical drive. #define _NORTC_MON 6 /**< & */ #define _NORTC_MDAY 4 /**< & */ #define _NORTC_YEAR \ - 2015 /**< -The option _FS_NORTC switches timestamp functiton. If the system does not have + 2015 /**< +The option _FS_NORTC switches timestamp functiton. If the system does not have / any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable / the timestamp function. All objects modified by FatFs will have a fixed timestamp / defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time. / To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be / added to the project to get current time form real-time clock. _NORTC_MON, -/ _NORTC_MDAY and _NORTC_YEAR have no effect. +/ _NORTC_MDAY and _NORTC_YEAR have no effect. / These options have no effect at read-only configuration (_FS_READONLY = 1). */ #define _FS_LOCK \ - 0 /**< 0:Disable or >=1:Enable + 0 /**< 0:Disable or >=1:Enable The option _FS_LOCK switches file lock function to control duplicated file open / and illegal operation to open objects. This option must be 0 when _FS_READONLY / is 1. diff --git a/src/sys/system.cpp b/src/sys/system.cpp index acead70e2..4b7bd915a 100644 --- a/src/sys/system.cpp +++ b/src/sys/system.cpp @@ -15,6 +15,10 @@ extern "C" extern void dsy_uart_global_init(); } +// boot info struct declared in persistent backup SRAM +volatile daisy::System::BootInfo __attribute__((section(".backup_sram"))) +daisy::boot_info; + // Jump related stuff #define u32 uint32_t #define vu32 volatile uint32_t @@ -294,20 +298,42 @@ void System::DelayTicks(uint32_t delay_ticks) tim_.DelayTick(delay_ticks); } -void System::ResetToBootloader() +void System::ResetToBootloader(BootloaderMode mode) { - // Initialize Boot Pin - dsy_gpio_pin bootpin = {DSY_GPIOG, 3}; - dsy_gpio pin; - pin.mode = DSY_GPIO_MODE_OUTPUT_PP; - pin.pin = bootpin; - dsy_gpio_init(&pin); + if(mode == BootloaderMode::STM) + { + // Initialize Boot Pin + dsy_gpio_pin bootpin = {DSY_GPIOG, 3}; + dsy_gpio pin; + pin.mode = DSY_GPIO_MODE_OUTPUT_PP; + pin.pin = bootpin; + dsy_gpio_init(&pin); + + // Pull Pin HIGH + dsy_gpio_write(&pin, 1); + + // wait a few ms for cap to charge + HAL_Delay(10); + } + else if(mode == BootloaderMode::DAISY + || mode == BootloaderMode::DAISY_SKIP_TIMEOUT) + { + auto region = GetProgramMemoryRegion(); + if(region == MemoryRegion::INTERNAL_FLASH) + return; // Cannot return to Daisy bootloader if it's not present! - // Pull Pin HIGH - dsy_gpio_write(&pin, 1); + // Coming from a bootloaded program, the backup SRAM will already + // be initialized. If the bootloader is <= v5, then it will not + // be initialized, but a failed write will not cause a fault. - // wait a few ms for cap to charge - HAL_Delay(10); + boot_info.status = mode == BootloaderMode::DAISY + ? BootInfo::Type::INVALID + : BootInfo::Type::SKIP_TIMEOUT; + } + else + { + return; // Malformed mode + } // disable interupts RCC->CIER = 0x00000000; @@ -316,20 +342,47 @@ void System::ResetToBootloader() HAL_NVIC_SystemReset(); } +void System::InitBackupSram() +{ + PWR->CR1 |= PWR_CR1_DBP; + while((PWR->CR1 & PWR_CR1_DBP) == RESET) + ; + __HAL_RCC_BKPRAM_CLK_ENABLE(); +} + +System::BootInfo::Version System::GetBootloaderVersion() +{ + auto region = GetProgramMemoryRegion(); + if(region == MemoryRegion::INTERNAL_FLASH) + return BootInfo::Version::NONE; + + for(int i = 0; i < (int)BootInfo::Version::LAST; i++) + { + if(boot_info.version == (BootInfo::Version)i) + return (BootInfo::Version)i; + } + + // Otherwise, the version may be higher than this + // version of the library knows about. In that case, + // expecting backwards compatibility, we'll say it's + // at least the latest version. + return (BootInfo::Version)((int)BootInfo::Version::LAST - 1); +} + void System::ConfigureClocks() { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; - /** Supply configuration update enable + /** Supply configuration update enable */ HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); - /** Configure the main internal regulator output voltage + /** Configure the main internal regulator output voltage ** and set PLLN value, and flash-latency. ** - ** See page 159 of Reference manual for VOS/Freq relationship + ** See page 159 of Reference manual for VOS/Freq relationship ** and table for flash latency. */ @@ -350,10 +403,10 @@ void System::ConfigureClocks() } while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} - /** Macro to configure the PLL clock source + /** Macro to configure the PLL clock source */ __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE); - /** Initializes the CPU, AHB and APB busses clocks + /** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSE; @@ -374,7 +427,7 @@ void System::ConfigureClocks() { Error_Handler(); } - /** Initializes the CPU, AHB and APB busses clocks + /** Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 @@ -481,6 +534,16 @@ void System::ConfigureMpu() MPU_InitStruct.BaseAddress = 0xC0000000; HAL_MPU_ConfigRegion(&MPU_InitStruct); + // Configure the backup SRAM region as non-cacheable + MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; + MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; + MPU_InitStruct.Number = MPU_REGION_NUMBER2; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; + MPU_InitStruct.Size = MPU_REGION_SIZE_4KB; + MPU_InitStruct.BaseAddress = 0x38800000; + HAL_MPU_ConfigRegion(&MPU_InitStruct); + HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); } diff --git a/src/sys/system.h b/src/sys/system.h index 5aa3f3ebd..2ac151626 100644 --- a/src/sys/system.h +++ b/src/sys/system.h @@ -58,9 +58,7 @@ class System bool skip_clocks; }; - /** Describes the different regions of memory available to the Daisy - * - */ + /** Describes the different regions of memory available to the Daisy */ enum MemoryRegion { INTERNAL_FLASH = 0, @@ -74,6 +72,26 @@ class System INVALID_ADDRESS, }; + /** Bootloader struct for controlling bootloading parameters */ + struct BootInfo + { + enum class Type : uint32_t + { + INVALID = 0x00000000, + JUMP = 0xDEADBEEF, + SKIP_TIMEOUT = 0x5AFEB007, + } status; + uint32_t data; + enum class Version : uint32_t + { + LT_v6_0 = 0, // Less than v6.0 + NONE, // No bootloader present + v6_0, // v6.0 + v6_1, // v6.1 or greater + LAST + } version; + }; + System() {} ~System() {} @@ -127,9 +145,31 @@ class System ** \param delay_ticks Time to ddelay in microseconds */ static void DelayTicks(uint32_t delay_ticks); - /** Triggers a reset of the seed and starts in bootloarder + /** Specify how the Daisy should return to the bootloader + * \param STM return to the STM32-provided + * bootloader to program internal flash + * \param DAISY if the Daisy bootloader is used, + * this will return to it + * \param DAISY_NO_TIMEOUT if the Daisy bootloader + * is used, this will return to it and skip the + * timeout window + */ + enum BootloaderMode + { + STM = 0, + DAISY, + DAISY_SKIP_TIMEOUT + }; + + /** Triggers a reset of the seed and starts in bootloader ** mode to allow firmware update. */ - static void ResetToBootloader(); + static void ResetToBootloader(BootloaderMode mode = BootloaderMode::STM); + + /** Initializes the backup SRAM */ + static void InitBackupSram(); + + /** Checks Daisy Bootloader version, if present. */ + static BootInfo::Version GetBootloaderVersion(); /** Returns the tick rate in Hz with which GetTick() is incremented. */ static uint32_t GetTickFreq(); @@ -193,6 +233,9 @@ class System ** Maybe this whole class should be static.. */ static TimerHandle tim_; }; + +extern volatile daisy::System::BootInfo boot_info; + } // namespace daisy #else // ifndef UNIT_TEST diff --git a/src/usbd/usbd_conf.c b/src/usbd/usbd_conf.c index db98e50d2..6131e9ec1 100644 --- a/src/usbd/usbd_conf.c +++ b/src/usbd/usbd_conf.c @@ -41,10 +41,10 @@ PCD_HandleTypeDef hpcd_USB_OTG_FS; PCD_HandleTypeDef hpcd_USB_OTG_HS; -void Error_Handler(void) -{ - while(1) {} -} +// void Error_Handler(void) +// { +// while(1) {} +// } /* External functions --------------------------------------------------------*/ diff --git a/tests/MAX11300_gtest.cpp b/tests/MAX11300_gtest.cpp index f3a13f655..25776bab4 100644 --- a/tests/MAX11300_gtest.cpp +++ b/tests/MAX11300_gtest.cpp @@ -865,9 +865,8 @@ TEST_F(MAX11300TestFixture, verifyWriteAnalogPin) // byte patterns to be sent via the transport. MAX11300Types::Pin pin = MAX11300Types::PIN_3; - const auto range = MAX11300Types::DacVoltageRange::ZERO_TO_10; EXPECT_TRUE(ConfigurePinAsAnalogWriteAndVerify( - 1, pin, range)); + 1, pin, MAX11300Types::DacVoltageRange::ZERO_TO_10)); // Write two different values to a single DAC pin and verify // the transactions... @@ -891,10 +890,9 @@ TEST_F(MAX11300TestFixture, verifyWriteAnalogPin) EXPECT_EQ(update_complete_callback_count_, 1); update_complete_callback_count_ = 0; // reset - // Transaction 2, this time using the "voltage" API - const auto voltage = 1.2f; - dac_val = MAX11300Test::VoltsTo12BitUint(voltage, range); - max11300_.WriteAnalogPinVolts(1, pin, voltage); + // Transaction 2 + dac_val = 1421; + max11300_.WriteAnalogPinRaw(1, pin, dac_val); TxTransaction tx_write_dac2; tx_write_dac2.description = "Chip 1: DAC write value transaction";