diff --git a/test-app/Makefile b/test-app/Makefile index c66ab3ef..1b5a2d12 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -5,8 +5,8 @@ OBJS:=startup.o main.o timer.o led.o system.o ../src/libwolfboot.o ../hal/$(TARG TARGET?=none LSCRIPT:=app.ld OBJCOPY:=$(CROSS_COMPILE)objcopy -CFLAGS:=-mcpu=cortex-m3 -mthumb -g -ggdb -Wall -Wno-main -Wstack-usage=200 -ffreestanding -Wno-unused -nostdlib -DPLATFORM_$(TARGET) -I../include -LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=image.map -nostdlib +CFLAGS:=-mcpu=cortex-m3 -mthumb -g -ggdb -Wall -Wno-main -Wstack-usage=200 -ffreestanding -Wno-unused -DPLATFORM_$(TARGET) -I../include -nostartfiles +LDFLAGS:=$(CFLAGS) -T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=image.map ifeq ($(EXT_FLASH),1) CFLAGS+=-DEXT_FLASH=1 -DPART_UPDATE_EXT=1 diff --git a/test-app/app.ld b/test-app/app.ld index 04c5c6ae..9fd82900 100644 --- a/test-app/app.ld +++ b/test-app/app.ld @@ -1,41 +1,43 @@ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00020100, LENGTH = 0x001FF00 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000 -} - -SECTIONS -{ - .text : - { - _start_text = .; - KEEP(*(.isr_vector)) - *(.text*) - *(.rodata*) - . = ALIGN(4); - _end_text = .; - } > FLASH - - _stored_data = .; - - .data : AT (_stored_data) - { - _start_data = .; - KEEP(*(.data*)) - . = ALIGN(4); - _end_data = .; - } > RAM - - .bss : - { - _start_bss = .; - *(.bss*) - *(COMMON) - . = ALIGN(4); - _end_bss = .; - _end = .; - } > RAM -} - -PROVIDE(_start_heap = _end); -PROVIDE(_end_stack = ORIGIN(RAM) + LENGTH(RAM)); +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00020100, LENGTH = 0x001FF00 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000 +} + +SECTIONS +{ + .text : + { + _start_text = .; + KEEP(*(.isr_vector)) + *(.init) + *(.fini) + *(.text*) + *(.rodata*) + . = ALIGN(4); + _end_text = .; + } > FLASH + + _stored_data = .; + + .data : AT (_stored_data) + { + _start_data = .; + KEEP(*(.data*)) + . = ALIGN(4); + _end_data = .; + } > RAM + + .bss : + { + _start_bss = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + _end_bss = .; + _end = .; + } > RAM +} + +PROVIDE(_start_heap = _end); +PROVIDE(_end_stack = ORIGIN(RAM) + LENGTH(RAM)); diff --git a/test-app/led.c b/test-app/led.c index 67018832..bfe66e16 100644 --- a/test-app/led.c +++ b/test-app/led.c @@ -22,6 +22,7 @@ */ #include +#include "wolfboot/wolfboot.h" #define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830)) #define GPIOD_AHB1_CLOCK_ER (1 << 3) @@ -59,11 +60,12 @@ void led_pwm_setup(void) void boot_led_on(void) { uint32_t reg; + uint32_t pin = LED_BOOT_PIN - 2 * (wolfBoot_current_firmware_version() & 0x01); AHB1_CLOCK_ER |= GPIOD_AHB1_CLOCK_ER; - reg = GPIOD_MODE & ~(0x03 << (LED_BOOT_PIN * 2)); - GPIOD_MODE = reg | (1 << (LED_BOOT_PIN * 2)); - reg = GPIOD_PUPD & ~(0x03 << (LED_BOOT_PIN * 2)); - GPIOD_PUPD = reg | (1 << (LED_BOOT_PIN * 2)); - GPIOD_BSRR |= (1 << LED_BOOT_PIN); + reg = GPIOD_MODE & ~(0x03 << (pin * 2)); + GPIOD_MODE = reg | (1 << (pin * 2)); + reg = GPIOD_PUPD & ~(0x03 << (pin * 2)); + GPIOD_PUPD = reg | (1 << (pin * 2)); + GPIOD_BSRR |= (1 << pin); } diff --git a/test-app/main.c b/test-app/main.c index 2edb14fc..48758426 100644 --- a/test-app/main.c +++ b/test-app/main.c @@ -23,21 +23,182 @@ #include #include +#include #include "system.h" #include "timer.h" #include "led.h" +#include "hal.h" #include "wolfboot/wolfboot.h" #ifdef PLATFORM_stm32f4 +extern int update_started; + +#define UART3 (0x40004800) + +#define UART3_SR (*(volatile uint32_t *)(UART3)) +#define UART3_DR (*(volatile uint32_t *)(UART3 + 0x04)) +#define UART3_BRR (*(volatile uint32_t *)(UART3 + 0x08)) +#define UART3_CR1 (*(volatile uint32_t *)(UART3 + 0x0c)) +#define UART3_CR2 (*(volatile uint32_t *)(UART3 + 0x10)) + +#define UART_CR1_UART_ENABLE (1 << 13) +#define UART_CR1_SYMBOL_LEN (1 << 12) +#define UART_CR1_PARITY_ENABLED (1 << 10) +#define UART_CR1_PARITY_ODD (1 << 9) +#define UART_CR1_TX_ENABLE (1 << 3) +#define UART_CR1_RX_ENABLE (1 << 2) +#define UART_CR2_STOPBITS (3 << 12) +#define UART_SR_TX_EMPTY (1 << 7) +#define UART_SR_RX_NOTEMPTY (1 << 5) + + +#define CLOCK_SPEED (168000000) + +#define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40023840)) +#define UART3_APB1_CLOCK_ER_VAL (1 << 18) + +#define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830)) +#define GPIOD_AHB1_CLOCK_ER (1 << 3) +#define GPIOD_BASE 0x40020c00 +#define GPIOD_MODE (*(volatile uint32_t *)(GPIOD_BASE + 0x00)) +#define GPIOD_AFL (*(volatile uint32_t *)(GPIOD_BASE + 0x20)) +#define GPIOD_AFH (*(volatile uint32_t *)(GPIOD_BASE + 0x24)) +#define GPIO_MODE_AF (2) +#define UART3_PIN_AF 7 +#define UART3_RX_PIN 9 +#define UART3_TX_PIN 8 + +#define MSGSIZE 16 +#define PAGESIZE (256) +static uint8_t page[PAGESIZE]; +static const char ERR='!'; +static const char START='*'; +static const char UPDATE='U'; +static const char ACK='#'; +static uint8_t msg[MSGSIZE]; + + +void uart_write(const char c) +{ + uint32_t reg; + do { + reg = UART3_SR; + } while ((reg & UART_SR_TX_EMPTY) == 0); + UART3_DR = c; +} + +static void uart_pins_setup(void) +{ + uint32_t reg; + AHB1_CLOCK_ER |= GPIOD_AHB1_CLOCK_ER; + /* Set mode = AF */ + reg = GPIOD_MODE & ~ (0x03 << (UART3_RX_PIN * 2)); + GPIOD_MODE = reg | (2 << (UART3_RX_PIN * 2)); + reg = GPIOD_MODE & ~ (0x03 << (UART3_TX_PIN * 2)); + GPIOD_MODE = reg | (2 << (UART3_TX_PIN * 2)); + + /* Alternate function: use high pins (8 and 9) */ + reg = GPIOD_AFH & ~(0xf << ((UART3_TX_PIN - 8) * 4)); + GPIOD_AFH = reg | (UART3_PIN_AF << ((UART3_TX_PIN - 8) * 4)); + reg = GPIOD_AFH & ~(0xf << ((UART3_RX_PIN - 8) * 4)); + GPIOD_AFH = reg | (UART3_PIN_AF << ((UART3_RX_PIN - 8) * 4)); +} + +int uart_setup(uint32_t bitrate, uint8_t data, char parity, uint8_t stop) +{ + uint32_t reg; + /* Enable pins and configure for AF7 */ + uart_pins_setup(); + /* Turn on the device */ + APB1_CLOCK_ER |= UART3_APB1_CLOCK_ER_VAL; + + /* Configure for TX + RX */ + UART3_CR1 |= (UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE); + + /* Configure clock */ + UART3_BRR = CLOCK_SPEED / bitrate; + + /* Configure data bits */ + if (data == 8) + UART3_CR1 &= ~UART_CR1_SYMBOL_LEN; + else + UART3_CR1 |= UART_CR1_SYMBOL_LEN; + + /* Configure parity */ + switch (parity) { + case 'O': + UART3_CR1 |= UART_CR1_PARITY_ODD; + /* fall through to enable parity */ + case 'E': + UART3_CR1 |= UART_CR1_PARITY_ENABLED; + break; + default: + UART3_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD); + } + /* Set stop bits */ + reg = UART3_CR2 & ~UART_CR2_STOPBITS; + if (stop > 1) + UART3_CR2 = reg & (2 << 12); + else + UART3_CR2 = reg; + + /* Turn on uart */ + UART3_CR1 |= UART_CR1_UART_ENABLE; + + return 0; +} + +char uart_read(void) +{ + char c; + volatile uint32_t reg; + do { + reg = UART3_SR; + } while ((reg & UART_SR_RX_NOTEMPTY) == 0); + c = (char)(UART3_DR & 0xff); + return c; +} + +static void ack(uint32_t _off) +{ + uint8_t *off = (uint8_t *)(&_off); + int i; + uart_write(ACK); + for (i = 0; i < 4; i++) { + uart_write(off[i]); + } +} + +static int check(uint8_t *pkt, int size) +{ + int i; + uint16_t c = 0; + uint16_t c_rx = *((uint16_t *)(pkt + 2)); + uint16_t *p = (uint16_t *)(pkt + 4); + for (i = 0; i < ((size - 4) >> 1); i++) + c += p[i]; + if (c == c_rx) + return 0; + return -1; +} + void main(void) { - uint32_t version; + uint32_t tlen = 0; + volatile uint32_t recv_seq; + uint32_t r_total = 0; + uint32_t tot_len = 0; + uint32_t next_seq = 0; + uint32_t version = 0; + uint8_t *v_array = (uint8_t *)&version; + int i; + memset(page, 0xFF, PAGESIZE); boot_led_on(); flash_set_waitstates(); clock_config(); led_pwm_setup(); pwm_init(CPU_FREQ, 0); - /* Dim the led by altering the PWM duty-cicle + /* Dim the led by altering the PWM duty-cicle * in isr_tim2 (timer.c) * * Every 50ms, the duty cycle of the PWM connected @@ -45,18 +206,80 @@ void main(void) { * effect. */ timer_init(CPU_FREQ, 1, 50); - version = wolfBoot_current_firmware_version(); - if (version & 0x01) { - /* Odd version: unstable, trigger update */ - if (wolfBoot_update_firmware_version() != 0) - wolfBoot_update_trigger(); - } else { - /* Even version, stabilise */ - wolfBoot_success(); - } + uart_setup(115200, 8, 'N', 1); + memset(page, 0xFF, PAGESIZE); asm volatile ("cpsie i"); + /* Initiate update */ + + //wolfBoot_success(); + + hal_flash_unlock(); + uart_write(START); + while (1) { + r_total = 0; + do { + while(r_total < 2) { + msg[r_total++] = uart_read(); + if ((r_total == 2) && ((msg[0] != 0xA5) || msg[1] != 0x5A)) { + r_total = 0; + continue; + } + } + msg[r_total++] = uart_read(); + if ((tot_len == 0) && r_total == 2 + sizeof(uint32_t)) + break; + if ((r_total > 8) && (tot_len <= ((r_total - 8) + next_seq))) + break; + } while (r_total < MSGSIZE); + if (tot_len == 0) { + tlen = msg[2] + (msg[3] << 8) + (msg[4] << 16) + (msg[5] << 24); + if (tlen > WOLFBOOT_PARTITION_SIZE - 8) { + uart_write(ERR); + uart_write(ERR); + uart_write(ERR); + uart_write(ERR); + uart_write(START); + recv_seq = 0; + tot_len = 0; + update_started = 1; + continue; + } + tot_len = tlen; + ack(0); + continue; + } + if (check(msg, r_total) < 0) { + ack(next_seq); + continue; + } + recv_seq = msg[4] + (msg[5] << 8) + (msg[6] << 16) + (msg[7] << 24); + if (recv_seq == next_seq) + { + int psize = r_total - 8; + int page_idx = recv_seq % PAGESIZE; + memcpy(&page[recv_seq % PAGESIZE], msg + 8, psize); + page_idx += psize; + if ((page_idx == PAGESIZE) || (next_seq + psize >= tot_len)) { + uint32_t dst = (WOLFBOOT_PARTITION_UPDATE_ADDRESS + recv_seq + psize) - page_idx; + if ((dst % WOLFBOOT_SECTOR_SIZE) == 0) { + hal_flash_erase(dst, WOLFBOOT_SECTOR_SIZE); + } + hal_flash_write(dst, page, PAGESIZE); + memset(page, 0xFF, PAGESIZE); + } + next_seq += psize; + } + ack(next_seq); + if (next_seq >= tot_len) { + /* Update complete */ + wolfBoot_update_trigger(); + hal_flash_lock(); + break; + } + } + /* Wait for reboot */ while(1) - WFI(); + ; } #endif diff --git a/test-app/timer.c b/test-app/timer.c index f1517bb1..7f810390 100644 --- a/test-app/timer.c +++ b/test-app/timer.c @@ -84,7 +84,7 @@ int pwm_init(uint32_t clock, uint32_t threshold) lvl = (val * threshold) / 100; if (lvl != 0) lvl--; - + APB1_CLOCK_RST |= TIM4_APB1_CLOCK_ER_VAL; __asm__ volatile ("dmb"); APB1_CLOCK_RST &= ~TIM4_APB1_CLOCK_ER_VAL; @@ -145,7 +145,10 @@ int timer_init(uint32_t clock, uint32_t prescaler, uint32_t interval_ms) return 0; } -void isr_tim2(void) +int update_started = 0; +extern void uart_write(char c); + +void isr_tim2(void) { static volatile uint32_t tim2_ticks = 0; TIM2_SR &= ~TIM_SR_UIF; @@ -157,6 +160,9 @@ void isr_tim2(void) pwm_init(master_clock, 10 * (16 - tim2_ticks)); else pwm_init(master_clock, 10 * tim2_ticks); + + if (!update_started) + uart_write('*'); }