From 62bfaf3973e4c87513576d55eb7671ae6b6eef73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Sun, 18 Feb 2018 15:21:18 +0100 Subject: [PATCH] cherry-pick from busvoodoo branch, part 4 --- Rakefile | 8 +- application.ld | 10 +- bootloader.ld | 10 +- global.h | 66 +++++++- lib/flash_internal.c | 64 ++++++-- lib/i2c_master.c | 371 ++++++++++++++++++++++++++----------------- lib/i2c_master.h | 51 +++++- lib/menu.c | 2 + lib/terminal.c | 2 +- lib/usb_dfu.c | 5 + 10 files changed, 410 insertions(+), 179 deletions(-) diff --git a/Rakefile b/Rakefile index 8216fd0..dca4d69 100644 --- a/Rakefile +++ b/Rakefile @@ -161,12 +161,12 @@ end desc "export binary" rule '.bin' => '.elf' do |t| - sh "#{OBJCOPY} --strip-all --strip-debug --output-target binary #{t.source} #{t.name}" + sh "#{OBJCOPY} --output-target binary #{t.source} #{t.name}" end desc "export intel hex file" rule '.hex' => '.elf' do |t| - sh "#{OBJCOPY} --strip-all --strip-debug --output-target ihex #{t.source} #{t.name}" + sh "#{OBJCOPY} --output-target ihex #{t.source} #{t.name}" end desc "export list" @@ -227,9 +227,9 @@ task :debug => APPLICATION+".elf" do |t| case SWD_ADAPTER when "STLINKV2" # for GDB to work with openOCD the firmware needs to be reloaded - sh "#{GDB} --eval-command='target remote | #{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --file target/#{OOCD_TARGET}.cfg --command \"gdb_port pipe; log_output /dev/null; init\"' --eval-command='monitor reset halt' --eval-command='load' --eval-command='monitor reset init' #{t.source}" + excec("#{GDB} --eval-command='target remote | #{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --file target/#{OOCD_TARGET}.cfg --command \"gdb_port pipe; log_output /dev/null; init\"' --eval-command='monitor reset halt' --eval-command='load' --eval-command='monitor reset init' #{t.source}") when "BMP" - sh "#{GDB} --eval-command='target extended-remote #{BMP_PORT}' --eval-command='monitor version' --eval-command='monitor swdp_scan' --eval-command='attach 1' #{t.source}" + exec("#{GDB} --eval-command='target extended-remote #{BMP_PORT}' --eval-command='monitor version' --eval-command='monitor swdp_scan' --eval-command='attach 1' #{t.source}") end end diff --git a/application.ld b/application.ld index ac7d270..47e104b 100644 --- a/application.ld +++ b/application.ld @@ -1,16 +1,20 @@ /* linker script for application running on STM32F103x8 micro-controller - * the STM32F103x8 has 64kB of flash starting at 0x0800 0000, and 20kB of RAM starting at 0x2000 0000 - * the USB DFU bootloader will take the first 8 kB of flash, followed by the application + * the STM32F103xC has 256 KB of flash starting at 0x0800 0000, and 20 KB of RAM starting at 0x2000 0000 + * the USB DFU bootloader will take the first 8 KB of flash, followed by the application */ /* Define memory regions. */ MEMORY { - rom (rx) : ORIGIN = 0x08000000 + 8K, LENGTH = 56K + rom (rx) : ORIGIN = 0x08000000 + 8K, LENGTH = 248K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K } PROVIDE(__application_beginning = ORIGIN(rom)); +/* only provide application end if you want to force a flash size + i.e. STM32F103x8 most often have if fact 128 KB instead of the specified and advertised 64 KB PROVIDE(__application_end = ORIGIN(rom) + LENGTH(rom)); +PROVIDE(__flash_end = ORIGIN(rom) + LENGTH(rom)); +*/ /* include rest of the definitions for the STM32F1 family */ INCLUDE libopencm3_stm32f1.ld diff --git a/bootloader.ld b/bootloader.ld index 1fa0ad3..a0535f8 100644 --- a/bootloader.ld +++ b/bootloader.ld @@ -1,6 +1,6 @@ /* linker script for application running on STM32F103x8 micro-controller - * the STM32F103x8 has 64kB of flash starting at 0x0800 0000, and 20kB of RAM starting at 0x2000 0000 - * the USB DFU bootloader will take the first 8 kB of flash, followed by the application + * the STM32F103xC has 256 KB of flash starting at 0x0800 0000, and 20 KB of RAM starting at 0x2000 0000 + * the USB DFU bootloader will take the first 8 KB of flash, followed by the application */ /* Define memory regions. */ @@ -10,7 +10,11 @@ MEMORY ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K } PROVIDE(__application_beginning = ORIGIN(rom) + LENGTH(rom)); -PROVIDE(__application_end = __application_beginning + 56K); +/* only provide application end if you want to force a flash size + i.e. STM32F103x8 most often have if fact 128 KB instead of the specified and advertised 64 KB +PROVIDE(__application_end = __application_beginning + 248K); +PROVIDE(__flash_end = __application_beginning + 248K); +*/ /* include rest of the definitions for the STM32F1 family */ INCLUDE libopencm3_stm32f1.ld diff --git a/global.h b/global.h index 88c1c77..f4fb894 100644 --- a/global.h +++ b/global.h @@ -31,6 +31,70 @@ /** concatenate 4 arguments */ #define CAT4(w,x,y,z) w##x##y##z +/** build year as number */ +#define COMPUTE_BUILD_YEAR \ + ( \ + (__DATE__[ 7] - '0') * 1000 + \ + (__DATE__[ 8] - '0') * 100 + \ + (__DATE__[ 9] - '0') * 10 + \ + (__DATE__[10] - '0') \ + ) +/** build day as number */ +#define COMPUTE_BUILD_DAY \ + ( \ + ((__DATE__[4] >= '0') ? (__DATE__[4] - '0') * 10 : 0) + \ + (__DATE__[5] - '0') \ + ) +/** check if build month is January */ +#define BUILD_MONTH_IS_JAN (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n') +/** check if build month is February */ +#define BUILD_MONTH_IS_FEB (__DATE__[0] == 'F') +/** check if build month is March */ +#define BUILD_MONTH_IS_MAR (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r') +/** check if build month is April */ +#define BUILD_MONTH_IS_APR (__DATE__[0] == 'A' && __DATE__[1] == 'p') +/** check if build month is May */ +#define BUILD_MONTH_IS_MAY (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y') +/** check if build month is June */ +#define BUILD_MONTH_IS_JUN (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n') +/** check if build month is July */ +#define BUILD_MONTH_IS_JUL (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l') +/** check if build month is August */ +#define BUILD_MONTH_IS_AUG (__DATE__[0] == 'A' && __DATE__[1] == 'u') +/** check if build month is September */ +#define BUILD_MONTH_IS_SEP (__DATE__[0] == 'S') +/** check if build month is October */ +#define BUILD_MONTH_IS_OCT (__DATE__[0] == 'O') +/** check if build month is November */ +#define BUILD_MONTH_IS_NOV (__DATE__[0] == 'N') +/** check if build month is December */ +#define BUILD_MONTH_IS_DEC (__DATE__[0] == 'D') +/** build month as number */ +#define COMPUTE_BUILD_MONTH \ + ( \ + (BUILD_MONTH_IS_JAN) ? 1 : \ + (BUILD_MONTH_IS_FEB) ? 2 : \ + (BUILD_MONTH_IS_MAR) ? 3 : \ + (BUILD_MONTH_IS_APR) ? 4 : \ + (BUILD_MONTH_IS_MAY) ? 5 : \ + (BUILD_MONTH_IS_JUN) ? 6 : \ + (BUILD_MONTH_IS_JUL) ? 7 : \ + (BUILD_MONTH_IS_AUG) ? 8 : \ + (BUILD_MONTH_IS_SEP) ? 9 : \ + (BUILD_MONTH_IS_OCT) ? 10 : \ + (BUILD_MONTH_IS_NOV) ? 11 : \ + (BUILD_MONTH_IS_DEC) ? 12 : \ + /* error default */ 99 \ + ) +/** check if build date is unknown */ +#define BUILD_DATE_IS_BAD (__DATE__[0] == '?') +/** build year as number if known, or 0 if unknown */ +#define BUILD_YEAR ((BUILD_DATE_IS_BAD) ? 0 : COMPUTE_BUILD_YEAR) +/** build month as number if known, or 0 if unknown */ +#define BUILD_MONTH ((BUILD_DATE_IS_BAD) ? 99 : COMPUTE_BUILD_MONTH) +/** build day as number if known, or 0 if unknown */ +#define BUILD_DAY ((BUILD_DATE_IS_BAD) ? 99 : COMPUTE_BUILD_DAY) + /** @defgroup reg_macro macros to define values based on other defines values * @note used when the value is calculated or isn't a value * @{ @@ -298,8 +362,6 @@ #define DMA_CHANNEL_ISR_SPI1_RX dma1_channel4_isr /**< SPI1 RX is on DMA 1 channel 4 */ #define DMA_CHANNEL_ISR_SPI2_RX dma1_channel2_isr /**< SPI2 RX is on DMA 1 channel 2 */ #define DMA_CHANNEL_ISR_SPI3_RX dma2_channel1_isr /**< SPI3 RX is on DMA 2 channel 1 */ - -/** get DMA channel based on SPI identifier */ /** @} */ /** @defgroup board_led board LED GPIO diff --git a/lib/flash_internal.c b/lib/flash_internal.c index f149cf0..540ba10 100644 --- a/lib/flash_internal.c +++ b/lib/flash_internal.c @@ -23,19 +23,27 @@ #include // general utilities /* STM32 (including CM3) libraries */ -#include // device signature utilities #include // flash utilities +#include // device signature definitions +#include // debug definitions #include "flash_internal.h" // flash storage library API #include "global.h" // global definitions -/** the flash page size (medium-density devices have 1KiB page size) */ -#define PAGE_SIZE 1024 - bool flash_internal_read(uint32_t address, uint8_t *buffer, size_t size) { - // verify it's in the flash area and do other sanity checks - if (address(UINT32_MAX-size) || (address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024) || buffer==NULL || size==0) { + // sanity checks + if (address(UINT32_MAX-size) || buffer==NULL || size==0) { + return false; + } + + // verify if it's in the flash area +#if defined(__flash_end) + if (address(uint32_t)&__flash_end) +#else + if (address(FLASH_BASE+DESIG_FLASH_SIZE*1024)) +#endif + { return false; } @@ -49,36 +57,60 @@ bool flash_internal_read(uint32_t address, uint8_t *buffer, size_t size) bool flash_internal_write(uint32_t address, uint8_t *buffer, size_t size) { - // verify it's in the flash area and do other sanity checks - if (address(UINT32_MAX-size) || (address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024) || buffer==NULL || size==0 || size%2) { + // sanity checks + if (address(UINT32_MAX-size) || buffer==NULL || size==0 || size%2) { return false; } + // verify if it's in the flash area +#if defined(__flash_end) + if (address(uint32_t)&__flash_end) +#else + if (address(FLASH_BASE+DESIG_FLASH_SIZE*1024)) +#endif + { + return false; + } + + // get page size + uint16_t page_size = 0; + if ((0x412==(DBGMCU_IDCODE&DBGMCU_IDCODE_DEV_ID_MASK)) || (0x412==(DBGMCU_IDCODE&DBGMCU_IDCODE_DEV_ID_MASK))) { // low-density (16-32 KB flash) and medium-density (64-128 KB flash) devices have 1 KB flash pages + page_size = 1024; + } else if ((0x414==(DBGMCU_IDCODE&DBGMCU_IDCODE_DEV_ID_MASK)) || (0x430==(DBGMCU_IDCODE&DBGMCU_IDCODE_DEV_ID_MASK)) || (0x418==(DBGMCU_IDCODE&DBGMCU_IDCODE_DEV_ID_MASK))) { // high-density (256-512 KB flash), XL-density (768-1024 KB flash) devices and connectivity line have 2 KB flash pages + page_size = 2048; + } else { // unknown device type (or unreadable type, see errata), deduce page size from flash size + if (DESIG_FLASH_SIZE<256) { + page_size = 1024; + } else { + page_size = 2048; + } + } + flash_unlock(); // unlock flash to be able to write it while (size) { // write page by page until all data has been written - uint32_t page_start = address-(address%PAGE_SIZE); // get start of the current page + uint32_t page_start = address-(address%page_size); // get start of the current page bool erase = false; // verify if the flash to write is erased of if we need to erase the page - for (uint32_t flash=address; flash<(address+size) && flash<(page_start+PAGE_SIZE); flash += 2) { // go through page + for (uint32_t flash=address; flash<(address+size) && flash<(page_start+page_size); flash += 2) { // go through page if (*(uint16_t*)(flash)!=0xffff) { // is flash not erased erase = true; // the erase flash } } if (erase) { // make copy of the page to erase and erase it - uint8_t page_data[PAGE_SIZE]; // a copy of the complete page before the erase it + uint8_t page_data[page_size]; // a copy of the complete page before the erase it uint16_t page_i = 0; // index for page data // copy page before address - for (uint32_t flash=page_start; flash
0 && page_i0 && page_i0 && address<(page_start+PAGE_SIZE)) { + while (size>0 && address<(page_start+page_size)) { flash_program_half_word(address, *((uint16_t*)(buffer))); if (flash_get_status_flags()!=FLASH_SR_EOP) { // operation went wrong flash_lock(); // lock back flash to protect it diff --git a/lib/i2c_master.c b/lib/i2c_master.c index 879b72c..317ec84 100644 --- a/lib/i2c_master.c +++ b/lib/i2c_master.c @@ -15,13 +15,13 @@ /** library to communicate using I2C as master (code) * @file i2c_master.c * @author King Kévin - * @date 2017 + * @date 2017-2018 * @note peripherals used: I2C @ref i2c_master_i2c, timer @ref i2c_master_timer */ /* standard libraries */ #include // standard integer types -#include // standard I/O facilities +//#include // standard I/O facilities #include // general utilities /* STM32 (including CM3) libraries */ @@ -30,13 +30,14 @@ #include // I2C library #include // timer utilities +/* own libraries */ #include "global.h" // global utilities #include "i2c_master.h" // I2C header and definitions /** @defgroup i2c_master_i2c I2C peripheral used to communicate * @{ */ -#define I2C_MASTER_I2C 2 /**< I2C peripheral */ +#define I2C_MASTER_I2C 1 /**< I2C peripheral */ /** @} */ /** @defgroup i2c_master_timer timer peripheral used for timeouts @@ -46,7 +47,6 @@ #define I2C_MASTER_TIMEOUT 4 /**< timeout factor (compared to expected time) */ /** @} */ - void i2c_master_setup(bool fast) { // configure I2C peripheral @@ -94,89 +94,72 @@ void i2c_master_setup(bool fast) timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag } -bool i2c_master_read(uint8_t slave, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size) +bool i2c_master_start(void) { - // sanity check - if (address==NULL || address_size==0 || data==NULL || data_size==0) { // input data is erroneous - return false; - } - if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // I2C device is busy - return false; - } - if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) { // I2C device is already in master mode - return false; - } - - bool to_return = false; // return if read succeeded - - // send start condition + // send (re-)start condition i2c_send_start(I2C(I2C_MASTER_I2C)); // send start condition to start transaction - timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer + timer_set_counter(TIM(I2C_MASTER_TIMER), 0); // restart timer timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_SB) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until start condition is transmitted timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag - goto error; + return false; } if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL)) { // verify if in master mode - goto error; + return false; + } + + return true; +} + +bool i2c_master_select_slave(uint8_t slave, bool write) +{ + if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY)) { // I2C device is not busy (start condition has not been sent) + if (!i2c_master_start()) { // send start condition + return false; // could not send start condition + } + } + if (!(I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL)) { // I2C device is already not master mode + return false; } // select slave - i2c_send_7bit_address(I2C(I2C_MASTER_I2C), slave, I2C_WRITE); // select slave - timer_set_counter(TIM(I2C_MASTER_TIMER),0); // restart timer + i2c_send_7bit_address(I2C(I2C_MASTER_I2C), slave, write ? I2C_WRITE : I2C_READ); // select slave, with read/write flag + timer_set_counter(TIM(I2C_MASTER_TIMER), 0); // restart timer timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag timer_enable_counter(TIM(I2C_MASTER_TIMER)); // enable timer for timeouts while (!(I2C_SR1(I2C(I2C_MASTER_I2C)) & I2C_SR1_ADDR) && !timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)); // wait until address is transmitted timer_disable_counter(TIM(I2C_MASTER_TIMER)); // disable timer for timeouts - if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred + if (timer_get_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF)) { // timeout occurred (no ACK received) timer_clear_flag(TIM(I2C_MASTER_TIMER), TIM_SR_UIF); // clear flag - goto error; + return false; } - if (!((I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR) - goto error; - } - - // send address - for (size_t i=0; i0) { + // read data + if (!i2c_master_read(data, data_size)) { + goto error; + } + } + + success = true; +error: + i2c_master_stop(); // sent stop condition + return success; +} + +bool i2c_master_slave_write(uint8_t slave, const uint8_t* data, size_t data_size) +{ + // sanity check + if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // I2C device is busy + return false; + } + if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) { // I2C device is already in master mode + return false; + } + + bool success = false; // return if read succeeded + + // send start condition + if (!i2c_master_start()) { + goto error; + } + // select slave to write + if (!i2c_master_select_slave(slave, true)) { + goto error; + } + // write data + if (NULL!=data && data_size>0) { + if (!i2c_master_write(data, data_size)) { + goto error; + } + } + + success = true; +error: + i2c_master_stop(); // sent stop condition + return success; +} + +bool i2c_master_address_read(uint8_t slave, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size) +{ + // sanity check + if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // I2C device is busy + return false; + } + if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) { // I2C device is already in master mode + return false; + } + + bool success = false; // return if read succeeded + + // write address + if (NULL!=address && address_size>0) { + // send start condition + if (!i2c_master_start()) { + goto error; + } + // select slave to write + if (!i2c_master_select_slave(slave, true)) { + goto error; + } + // send address + if (!i2c_master_write(address, address_size)) { + goto error; + } + } + // read data + if (NULL!=data && data_size>0) { + // send re-start condition + if (!i2c_master_start()) { + goto error; + } + // select slave to read + if (!i2c_master_select_slave(slave, false)) { + goto error; + } + // read data + if (!i2c_master_read(data, data_size)) { + goto error; + } + } + + success = true; +error: + i2c_master_stop(); // sent stop condition + return success; +} + +bool i2c_master_address_write(uint8_t slave, const uint8_t* address, size_t address_size, const uint8_t* data, size_t data_size) +{ + // sanity check + if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_BUSY) { // I2C device is busy + return false; + } + if (I2C_SR2(I2C(I2C_MASTER_I2C)) & I2C_SR2_MSL) { // I2C device is already in master mode + return false; + } + + bool success = false; // return if read succeeded + + // send start condition + if (!i2c_master_start()) { + goto error; + } + // select slave to write + if (!i2c_master_select_slave(slave, true)) { + goto error; + } + // write address + if (NULL!=address && address_size>0) { + // send address + if (!i2c_master_write(address, address_size)) { + goto error; + } + } + // write data + if (NULL!=data && data_size>0) { + if (!i2c_master_write(data, data_size)) { + goto error; + } + } + + success = true; +error: + i2c_master_stop(); // sent stop condition + return success; } diff --git a/lib/i2c_master.h b/lib/i2c_master.h index 1380b13..a42cdd6 100644 --- a/lib/i2c_master.h +++ b/lib/i2c_master.h @@ -15,8 +15,9 @@ /** library to communicate using I2C as master (API) * @file i2c_master.h * @author King Kévin - * @date 2017 + * @date 2017-2018 * @note peripherals used: I2C @ref i2c_master_i2c, timer @ref i2c_master_timer + * @warning only 7-byte I2C slave addresses are supported */ #pragma once @@ -24,7 +25,46 @@ * @param[in] fast use standard (100 kHz) or fast (400 kHz) mode */ void i2c_master_setup(bool fast); -/** read from I2C slave +/** send start condition + * @return if start condition was sent successfully (true) or error occurred (false) + */ +bool i2c_master_start(void); +/** select slave device + * @warning a start condition should be sent before this operation + * @param[in] slave 7-bit I2C address of slave device to select + * @param[in] write this transaction will be followed by a read (false) or write (true) operation + * @return if slave was selected successfully (true) or error occurred (false) + */ +bool i2c_master_select_slave(uint8_t slave, bool write); +/** read data + * @warning the slave device must be selected before this operation + * @param[out] data array to store bytes read + * @param[in] data_size number of bytes to read + */ +bool i2c_master_read(uint8_t* data, size_t data_size); +/** write data + * @warning the slave device must be selected before this operation + * @param[in] data array of byte to write to slave + * @param[in] data_size number of bytes to write + */ +bool i2c_master_write(const uint8_t* data, size_t data_size); +/** sent stop condition */ +void i2c_master_stop(void); +/** read from date from an I2C slave + * @param[in] slave 7-bit I2C salve device address to read from + * @param[out] data array to store bytes read + * @param[in] data_size number of bytes to read + * @return if read succeeded + */ +bool i2c_master_slave_read(uint8_t slave, uint8_t* data, size_t data_size); +/** write data to an I2C slave + * @param[in] slave 7-bit I2C salve device address to write to + * @param[in] data array of byte to write to slave + * @param[in] data_size number of bytes to write + * @return if write succeeded + */ +bool i2c_master_slave_write(uint8_t slave, const uint8_t* data, size_t data_size); +/** read data at specific address from an I2C memory slave * @param[in] slave 7-bit I2C salve device address to read from * @param[in] address memory address of slave to read from * @param[in] address_size address size in bytes @@ -32,8 +72,8 @@ void i2c_master_setup(bool fast); * @param[in] data_size number of bytes to read * @return if read succeeded */ -bool i2c_master_read(uint8_t slave, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size); -/** write to I2C slave +bool i2c_master_address_read(uint8_t slave, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size); +/** write data at specific address on an I2C memory slave * @param[in] slave 7-bit I2C salve device address to write to * @param[in] address memory address of slave to write to * @param[in] address_size address size in bytes @@ -41,5 +81,4 @@ bool i2c_master_read(uint8_t slave, const uint8_t* address, size_t address_size, * @param[in] data_size number of bytes to write * @return if write succeeded */ -bool i2c_master_write(uint8_t slave, const uint8_t* address, size_t address_size, const uint8_t* data, size_t data_size); - +bool i2c_master_address_write(uint8_t slave, const uint8_t* address, size_t address_size, const uint8_t* data, size_t data_size); diff --git a/lib/menu.c b/lib/menu.c index 1320519..0665149 100644 --- a/lib/menu.c +++ b/lib/menu.c @@ -107,6 +107,8 @@ void menu_print_commands(const struct menu_command_t* command_list, size_t comma printf("%s", command.name); if (MENU_ARGUMENT_NONE!=command.argument && command.argument_description) { printf(" %s", command.argument_description); + } else { + printf("\t"); } if (command.command_description) { printf("\t%s", command.command_description); diff --git a/lib/terminal.c b/lib/terminal.c index d200a45..44394d3 100644 --- a/lib/terminal.c +++ b/lib/terminal.c @@ -33,7 +33,7 @@ char* terminal_prefix = NULL; void (*terminal_process)(char* line) = NULL; /** buffer to store user input and keep history */ -static char terminal_buffer[16] = {0}; +static char terminal_buffer[1024] = {0}; /** how much of the buffer is user */ static uint16_t terminal_end = 0; /** current position in the buffer */ diff --git a/lib/usb_dfu.c b/lib/usb_dfu.c index 03ceef6..bcfa5b9 100644 --- a/lib/usb_dfu.c +++ b/lib/usb_dfu.c @@ -27,6 +27,7 @@ #include // reset utilities #include // real-time control clock library #include // general purpose input output library +#include // flash size definition #include // USB library #include // USB DFU library @@ -223,7 +224,11 @@ static int usb_dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data // we can only write half words usb_dfu_status = DFU_STATUS_ERR_PROG; usb_dfu_state = STATE_DFU_ERROR; +#if defined(__application_end) } else if (flash_pointer+*len>=(uint32_t)&__application_end) { +#else + } else if (flash_pointer+*len>=(uint32_t)(FLASH_BASE+DESIG_FLASH_SIZE*1024)) { +#endif // application data is too large usb_dfu_status = DFU_STATUS_ERR_ADDRESS; usb_dfu_state = STATE_DFU_ERROR;