From d8d200db6977485c3e6d9ab8ff31401ab730eb3f Mon Sep 17 00:00:00 2001 From: Dimitar Tomov Date: Thu, 14 Jan 2021 01:42:14 +0200 Subject: [PATCH] Add source code of the test-app Signed-off-by: Dimitar Tomov --- test-app-STM32F4-measured-boot/src/ARM.ld | 45 +++ .../src/app_stm32f4.c | 298 ++++++++++++++++ test-app-STM32F4-measured-boot/src/led.c | 180 ++++++++++ test-app-STM32F4-measured-boot/src/led.h | 35 ++ .../src/startup_arm.c | 337 ++++++++++++++++++ test-app-STM32F4-measured-boot/src/system.c | 147 ++++++++ test-app-STM32F4-measured-boot/src/system.h | 67 ++++ .../src/target-app.ld | 45 +++ test-app-STM32F4-measured-boot/src/timer.c | 171 +++++++++ test-app-STM32F4-measured-boot/src/timer.h | 30 ++ 10 files changed, 1355 insertions(+) create mode 100644 test-app-STM32F4-measured-boot/src/ARM.ld create mode 100644 test-app-STM32F4-measured-boot/src/app_stm32f4.c create mode 100644 test-app-STM32F4-measured-boot/src/led.c create mode 100644 test-app-STM32F4-measured-boot/src/led.h create mode 100644 test-app-STM32F4-measured-boot/src/startup_arm.c create mode 100644 test-app-STM32F4-measured-boot/src/system.c create mode 100644 test-app-STM32F4-measured-boot/src/system.h create mode 100644 test-app-STM32F4-measured-boot/src/target-app.ld create mode 100644 test-app-STM32F4-measured-boot/src/timer.c create mode 100644 test-app-STM32F4-measured-boot/src/timer.h diff --git a/test-app-STM32F4-measured-boot/src/ARM.ld b/test-app-STM32F4-measured-boot/src/ARM.ld new file mode 100644 index 0000000..24318ae --- /dev/null +++ b/test-app-STM32F4-measured-boot/src/ARM.ld @@ -0,0 +1,45 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K /* Run in lowmem */ +} + +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); + KEEP(*(.ramcode)) + . = 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-STM32F4-measured-boot/src/app_stm32f4.c b/test-app-STM32F4-measured-boot/src/app_stm32f4.c new file mode 100644 index 0000000..6b4fea2 --- /dev/null +++ b/test-app-STM32F4-measured-boot/src/app_stm32f4.c @@ -0,0 +1,298 @@ +/* stm32f4.c + * + * Test bare-metal blinking led application + * + * Copyright (C) 2020 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include +#include +#include "system.h" +#include "timer.h" +#include "led.h" +#include "hal.h" +#include "wolfboot/wolfboot.h" +#include "spi_flash.h" + +#ifdef PLATFORM_stm32f4 + +#define UART1 (0x40011000) + +#define UART1_SR (*(volatile uint32_t *)(UART1)) +#define UART1_DR (*(volatile uint32_t *)(UART1 + 0x04)) +#define UART1_BRR (*(volatile uint32_t *)(UART1 + 0x08)) +#define UART1_CR1 (*(volatile uint32_t *)(UART1 + 0x0c)) +#define UART1_CR2 (*(volatile uint32_t *)(UART1 + 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 APB2_CLOCK_ER (*(volatile uint32_t *)(0x40023844)) +#define UART1_APB2_CLOCK_ER (1 << 4) + +#define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830)) +#define GPIOB_AHB1_CLOCK_ER (1 << 1) +#define GPIOB_BASE 0x40020400 + +#define GPIOB_MODE (*(volatile uint32_t *)(GPIOB_BASE + 0x00)) +#define GPIOB_AFL (*(volatile uint32_t *)(GPIOB_BASE + 0x20)) +#define GPIOB_AFH (*(volatile uint32_t *)(GPIOB_BASE + 0x24)) +#define UART1_PIN_AF 7 +#define UART1_RX_PIN 7 +#define UART1_TX_PIN 6 + +#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 = UART1_SR; + } while ((reg & UART_SR_TX_EMPTY) == 0); + UART1_DR = c; +} + +static void uart_pins_setup(void) +{ + uint32_t reg; + AHB1_CLOCK_ER |= GPIOB_AHB1_CLOCK_ER; + /* Set mode = AF */ + reg = GPIOB_MODE & ~ (0x03 << (UART1_RX_PIN * 2)); + GPIOB_MODE = reg | (2 << (UART1_RX_PIN * 2)); + reg = GPIOB_MODE & ~ (0x03 << (UART1_TX_PIN * 2)); + GPIOB_MODE = reg | (2 << (UART1_TX_PIN * 2)); + + /* Alternate function: use low pins (6 and 7) */ + reg = GPIOB_AFL & ~(0xf << ((UART1_TX_PIN) * 4)); + GPIOB_AFL = reg | (UART1_PIN_AF << ((UART1_TX_PIN) * 4)); + reg = GPIOB_AFL & ~(0xf << ((UART1_RX_PIN) * 4)); + GPIOB_AFL = reg | (UART1_PIN_AF << ((UART1_RX_PIN) * 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 */ + APB2_CLOCK_ER |= UART1_APB2_CLOCK_ER; + + /* Configure for TX + RX */ + UART1_CR1 |= (UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE); + + /* Configure clock */ + UART1_BRR = CLOCK_SPEED / bitrate; + + /* Configure data bits */ + if (data == 8) + UART1_CR1 &= ~UART_CR1_SYMBOL_LEN; + else + UART1_CR1 |= UART_CR1_SYMBOL_LEN; + + /* Configure parity */ + switch (parity) { + case 'O': + UART1_CR1 |= UART_CR1_PARITY_ODD; + /* fall through to enable parity */ + case 'E': + UART1_CR1 |= UART_CR1_PARITY_ENABLED; + break; + default: + UART1_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD); + } + /* Set stop bits */ + reg = UART1_CR2 & ~UART_CR2_STOPBITS; + if (stop > 1) + UART1_CR2 = reg & (2 << 12); + else + UART1_CR2 = reg; + + /* Turn on uart */ + UART1_CR1 |= UART_CR1_UART_ENABLE; + + return 0; +} + +char uart_read(void) +{ + char c; + volatile uint32_t reg; + do { + reg = UART1_SR; + } while ((reg & UART_SR_RX_NOTEMPTY) == 0); + c = (char)(UART1_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; +} + +volatile uint32_t time_elapsed = 0; +void main(void) { + 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 + * in isr_tim2 (timer.c) + * + * Every 50ms, the duty cycle of the PWM connected + * to the blue led increases/decreases making a pulse + * effect. + */ + timer_init(CPU_FREQ, 1, 50); + uart_setup(115200, 8, 'N', 1); + memset(page, 0xFF, PAGESIZE); + asm volatile ("cpsie i"); + + while(time_elapsed == 0) + WFI(); + + + hal_flash_unlock(); + version = wolfBoot_current_firmware_version(); + if ((version & 0x01) == 0) + wolfBoot_success(); +#ifdef EXT_ENCRYPTED + wolfBoot_set_encrypt_key("0123456789abcdef0123456789abcdef", 32); +#endif + uart_write(START); + for (i = 3; i >= 0; i--) { + uart_write(v_array[i]); + } + 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; + 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 */ + spi_flash_probe(); + wolfBoot_update_trigger(); + spi_release(); + hal_flash_lock(); + break; + } + } + /* Wait for reboot */ + while(1) + ; +} +#endif /** PLATFORM_stm32f4 **/ + diff --git a/test-app-STM32F4-measured-boot/src/led.c b/test-app-STM32F4-measured-boot/src/led.c new file mode 100644 index 0000000..e183f6c --- /dev/null +++ b/test-app-STM32F4-measured-boot/src/led.c @@ -0,0 +1,180 @@ +/* led.c + * + * Test bare-metal blinking led application + * + * Copyright (C) 2020 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +#include +#include "wolfboot/wolfboot.h" + +#ifdef PLATFORM_stm32f4 + +#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_OTYPE (*(volatile uint32_t *)(GPIOD_BASE + 0x04)) +#define GPIOD_OSPD (*(volatile uint32_t *)(GPIOD_BASE + 0x08)) +#define GPIOD_PUPD (*(volatile uint32_t *)(GPIOD_BASE + 0x0c)) +#define GPIOD_ODR (*(volatile uint32_t *)(GPIOD_BASE + 0x14)) +#define GPIOD_BSRR (*(volatile uint32_t *)(GPIOD_BASE + 0x18)) +#define GPIOD_AFL (*(volatile uint32_t *)(GPIOD_BASE + 0x20)) +#define GPIOD_AFH (*(volatile uint32_t *)(GPIOD_BASE + 0x24)) +#define LED_PIN (15) +#define LED_BOOT_PIN (14) +#define GPIO_OSPEED_100MHZ (0x03) +void led_pwm_setup(void) +{ + uint32_t reg; + AHB1_CLOCK_ER |= GPIOD_AHB1_CLOCK_ER; + reg = GPIOD_MODE & ~ (0x03 << (LED_PIN * 2)); + GPIOD_MODE = reg | (2 << (LED_PIN * 2)); + + reg = GPIOD_OSPD & ~(0x03 << (LED_PIN * 2)); + GPIOD_OSPD = reg | (0x03 << (LED_PIN * 2)); + + reg = GPIOD_PUPD & ~(0x03 << (LED_PIN * 2)); + GPIOD_PUPD = reg | (0x02 << (LED_PIN * 2)); + + /* Alternate function: use high pin */ + reg = GPIOD_AFH & ~(0xf << ((LED_PIN - 8) * 4)); + GPIOD_AFH = reg | (0x2 << ((LED_PIN - 8) * 4)); +} + +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 << (pin * 2)); + GPIOD_MODE = reg | (1 << (pin * 2)); + reg = GPIOD_PUPD & ~(0x03 << (pin * 2)); + GPIOD_PUPD = reg | (1 << (pin * 2)); + GPIOD_BSRR |= (1 << pin); +} + +#endif /* PLATFORM_stm32f4 */ + +#ifdef PLATFORM_stm32l0 +#define LED_BOOT_PIN (5) + +#define RCC_IOPENR (*(volatile uint32_t *)(0x4002102C)) +#define IOPAEN (1 << 0) + + +#define GPIOA_BASE 0x50000000 +#define GPIOA_MODE (*(volatile uint32_t *)(GPIOA_BASE + 0x00)) +#define GPIOA_OTYPE (*(volatile uint32_t *)(GPIOA_BASE + 0x04)) +#define GPIOA_OSPD (*(volatile uint32_t *)(GPIOA_BASE + 0x08)) +#define GPIOA_PUPD (*(volatile uint32_t *)(GPIOA_BASE + 0x0c)) +#define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14)) +#define GPIOA_BSRR (*(volatile uint32_t *)(GPIOA_BASE + 0x18)) +#define GPIOA_AFL (*(volatile uint32_t *)(GPIOA_BASE + 0x20)) +#define GPIOA_AFH (*(volatile uint32_t *)(GPIOA_BASE + 0x24)) + + +void boot_led_on(void) +{ + uint32_t reg; + uint32_t pin = LED_BOOT_PIN; + RCC_IOPENR |= IOPAEN; + reg = GPIOA_MODE & ~(0x03 << (pin * 2)); + GPIOA_MODE = reg | (1 << (pin * 2)); + reg = GPIOA_PUPD & ~(0x03 << (pin * 2)); + GPIOA_PUPD = reg | (1 << (pin * 2)); + GPIOA_BSRR |= (1 << pin); +} + + +#endif /* PLATFORM_stm32l0 */ + +#ifdef PLATFORM_stm32g0 +#include +#include "wolfboot/wolfboot.h" + + +/*GPIOA5*/ +#define RCC_IOPENR (*(volatile uint32_t *)(0x40021034)) // 40021034 +#define RCC_IOPENR_GPIOAEN (1 << 0) + +#define GPIOA_BASE 0x50000000 +#define GPIOA_MODE (*(volatile uint32_t *)(GPIOA_BASE + 0x00)) +#define GPIOA_OTYPE (*(volatile uint32_t *)(GPIOA_BASE + 0x04)) +#define GPIOA_OSPD (*(volatile uint32_t *)(GPIOA_BASE + 0x08)) +#define GPIOA_PUPD (*(volatile uint32_t *)(GPIOA_BASE + 0x0c)) +#define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14)) +#define GPIOA_BSRR (*(volatile uint32_t *)(GPIOA_BASE + 0x18)) +#define GPIOA_AFL (*(volatile uint32_t *)(GPIOA_BASE + 0x20)) +#define GPIOA_AFH (*(volatile uint32_t *)(GPIOA_BASE + 0x24)) +#define LED_PIN (5) +#define LED_BOOT_PIN (5) +#define GPIO_OSPEED_100MHZ (0x03) + +void boot_led_on(void) +{ + uint32_t reg; + uint32_t pin = LED_BOOT_PIN; + RCC_IOPENR |= RCC_IOPENR_GPIOAEN; + reg = GPIOA_MODE & ~(0x03 << (pin * 2)); + GPIOA_MODE = reg | (1 << (pin * 2)); // general purpose output mode + reg = GPIOA_PUPD & ~(0x03 << (pin * 2)); + GPIOA_PUPD = reg | (1 << (pin * 2)); // pull-up + GPIOA_BSRR |= (1 << pin); // set pin +} + +#endif /** PLATFORM_stm32g0 **/ + +#ifdef PLATFORM_stm32wb +#define LED_BOOT_PIN (0) +#define RCC_AHB2_CLOCK_ER (*(volatile uint32_t *)(0x5800004C)) +#define GPIOB_AHB2_CLOCK_ER (1 << 1) + +#define GPIOB_BASE 0x48000400 +#define GPIOB_MODE (*(volatile uint32_t *)(GPIOB_BASE + 0x00)) +#define GPIOB_OTYPE (*(volatile uint32_t *)(GPIOB_BASE + 0x04)) +#define GPIOB_OSPD (*(volatile uint32_t *)(GPIOB_BASE + 0x08)) +#define GPIOB_PUPD (*(volatile uint32_t *)(GPIOB_BASE + 0x0c)) +#define GPIOB_ODR (*(volatile uint32_t *)(GPIOB_BASE + 0x14)) +#define GPIOB_BSRR (*(volatile uint32_t *)(GPIOB_BASE + 0x18)) +#define GPIOB_AFL (*(volatile uint32_t *)(GPIOB_BASE + 0x20)) +#define GPIOB_AFH (*(volatile uint32_t *)(GPIOB_BASE + 0x24)) + + +void boot_led_on(void) +{ + uint32_t reg; + uint32_t pin = LED_BOOT_PIN; + RCC_AHB2_CLOCK_ER |= GPIOB_AHB2_CLOCK_ER; + reg = GPIOB_MODE & ~(0x03 << (pin * 2)); + GPIOB_MODE = reg | (1 << (pin * 2)); + reg = GPIOB_PUPD & ~(0x03 << (pin * 2)); + GPIOB_PUPD = reg | (1 << (pin * 2)); + GPIOB_BSRR |= (1 << pin); +} + +void boot_led_off(void) +{ + uint32_t reg; + uint32_t pin = LED_BOOT_PIN; + GPIOB_BSRR |= (1 << (pin + 16)); +} + + +#endif /* PLATFORM_stm32wb */ diff --git a/test-app-STM32F4-measured-boot/src/led.h b/test-app-STM32F4-measured-boot/src/led.h new file mode 100644 index 0000000..3c40e4d --- /dev/null +++ b/test-app-STM32F4-measured-boot/src/led.h @@ -0,0 +1,35 @@ +/* led.h + * + * Test bare-metal blinking led application + * + * Copyright (C) 2020 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef GPIO_H_INCLUDED +#define GPIO_H_INCLUDED + +int led_setup(void); +void led_on(void); +void led_off(void); +void led_toggle(void); +void led_pwm_setup(void); +void boot_led_on(void); +void boot_led_off(void); + +#endif /* !GPIO_H_INCLUDED */ diff --git a/test-app-STM32F4-measured-boot/src/startup_arm.c b/test-app-STM32F4-measured-boot/src/startup_arm.c new file mode 100644 index 0000000..bb8bcd7 --- /dev/null +++ b/test-app-STM32F4-measured-boot/src/startup_arm.c @@ -0,0 +1,337 @@ +/* startup_arm.c + * + * Test bare-metal blinking led application + * + * Copyright (C) 2020 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +extern unsigned int _stored_data; +extern unsigned int _start_data; +extern unsigned int _end_data; +extern unsigned int _start_bss; +extern unsigned int _end_bss; +extern unsigned int _end_stack; +extern unsigned int _start_heap; + +static int zeroed_variable_in_bss; +static int initialized_variable_in_data = 42; + +extern void isr_tim2(void); + +#define STACK_PAINTING + +static volatile unsigned int avail_mem = 0; +static unsigned int sp; + +extern void main(void); + +void isr_reset(void) { + register unsigned int *src, *dst; + src = (unsigned int *) &_stored_data; + dst = (unsigned int *) &_start_data; + while (dst < (unsigned int *)&_end_data) { + *dst = *src; + dst++; + src++; + } + + dst = &_start_bss; + while (dst < (unsigned int *)&_end_bss) { + *dst = 0U; + dst++; + } + + avail_mem = &_end_stack - &_start_heap; +#ifdef STACK_PAINTING + { + asm volatile("mrs %0, msp" : "=r"(sp)); + dst = ((unsigned int *)(&_end_stack)) - (8192 / sizeof(unsigned int)); ; + while ((unsigned int)dst < sp) { + *dst = 0xDEADC0DE; + dst++; + } + } +#endif + + + main(); +} + +void isr_fault(void) +{ + /* Panic. */ + while(1) ;; + +} + +void isr_memfault(void) +{ + /* Panic. */ + while(1) ;; +} + +void isr_busfault(void) +{ + /* Panic. */ + while(1) ;; +} + +void isr_usagefault(void) +{ + /* Panic. */ + while(1) ;; +} + + +void isr_empty(void) +{ + +} + + + +__attribute__ ((section(".isr_vector"))) +void (* const IV[])(void) = +{ + (void (*)(void))(&_end_stack), + isr_reset, // Reset + isr_fault, // NMI + isr_fault, // HardFault + isr_memfault, // MemFault + isr_busfault, // BusFault + isr_usagefault, // UsageFault + 0, // SecureFault + 0, // reserved + 0, // reserved + 0, // reserved + isr_empty, // SVC + isr_empty, // DebugMonitor + 0, // reserved + isr_empty, // PendSV + isr_empty, // SysTick + +/* Device specific IRQs for LM3S */ + +#ifdef LM3S + isr_empty, // GPIO Port A + isr_empty, // GPIO Port B + isr_empty, // GPIO Port C + isr_empty, // GPIO Port D + isr_empty, // GPIO Port E + isr_empty, // UART0 Rx and Tx + isr_empty, // UART1 Rx and Tx + isr_empty, // SSI0 Rx and Tx + isr_empty, // I2C0 Master and Slave + isr_empty, // PWM Fault + isr_empty, // PWM Generator 0 + isr_empty, // PWM Generator 1 + isr_empty, // PWM Generator 2 + isr_empty, // Quadrature Encoder 0 + isr_empty, // ADC Sequence 0 + isr_empty, // ADC Sequence 1 + isr_empty, // ADC Sequence 2 + isr_empty, // ADC Sequence 3 + isr_empty, // Watchdog timer + isr_empty, // Timer 0 subtimer A + isr_empty, // Timer 0 subtimer B + isr_empty, // Timer 1 subtimer A + isr_empty, // Timer 1 subtimer B + isr_empty, // Timer 2 subtimer A + isr_empty, // Timer 3 subtimer B + isr_empty, // Analog Comparator 0 + isr_empty, // Analog Comparator 1 + isr_empty, // Analog Comparator 2 + isr_empty, // System Control (PLL, OSC, BO) + isr_empty, // FLASH Control + isr_empty, // GPIO Port F + isr_empty, // GPIO Port G + isr_empty, // GPIO Port H + isr_empty, // UART2 Rx and Tx + isr_empty, // SSI1 Rx and Tx + isr_empty, // Timer 3 subtimer A + isr_empty, // Timer 3 subtimer B + isr_empty, // I2C1 Master and Slave + isr_empty, // Quadrature Encoder 1 + isr_empty, // CAN0 + isr_empty, // CAN1 + isr_empty, // CAN2 + isr_empty, // Ethernet + isr_empty, // Hibernate +#elif PLATFORM_stm32l5 + isr_empty, // WWDG_IRQHandler + isr_empty, // PVD_PVM_IRQHandler + isr_empty, // RTC_IRQHandler + isr_empty, // RTC_S_IRQHandler + isr_empty, // TAMP_IRQHandler + isr_empty, // TAMP_S_IRQHandler + isr_empty, // FLASH_IRQHandler + isr_empty, // FLASH_S_IRQHandler + isr_empty, // GTZC_IRQHandler + isr_empty, // RCC_IRQHandler + isr_empty, // RCC_S_IRQHandler + isr_empty, // EXTI0_IRQHandler + isr_empty, // EXTI1_IRQHandler + isr_empty, // EXTI2_IRQHandler + isr_empty, // EXTI3_IRQHandler + isr_empty, // EXTI4_IRQHandler + isr_empty, // EXTI5_IRQHandler + isr_empty, // EXTI6_IRQHandler + isr_empty, // EXTI7_IRQHandler + isr_empty, // EXTI8_IRQHandler + isr_empty, // EXTI9_IRQHandler + isr_empty, // EXTI10_IRQHandler + isr_empty, // EXTI11_IRQHandler + isr_empty, // EXTI12_IRQHandler + isr_empty, // EXTI13_IRQHandler + isr_empty, // EXTI14_IRQHandler + isr_empty, // EXTI15_IRQHandler + isr_empty, // DMAMUX1_IRQHandler + isr_empty, // DMAMUX1_S_IRQHandler + isr_empty, // DMA1_Channel1_IRQHandler + isr_empty, // DMA1_Channel2_IRQHandler + isr_empty, // DMA1_Channel3_IRQHandler + isr_empty, // DMA1_Channel4_IRQHandler + isr_empty, // DMA1_Channel5_IRQHandler + isr_empty, // DMA1_Channel6_IRQHandler + isr_empty, // DMA1_Channel7_IRQHandler + isr_empty, // DMA1_Channel8_IRQHandler + isr_empty, // ADC1_2_IRQHandler + isr_empty, // DAC_IRQHandler + isr_empty, // FDCAN1_IT0_IRQHandler + isr_empty, // FDCAN1_IT1_IRQHandler + isr_empty, // TIM1_BRK_IRQHandler + isr_empty, // TIM1_UP_IRQHandler + isr_empty, // TIM1_TRG_COM_IRQHandler + isr_empty, // TIM1_CC_IRQHandler + isr_empty, // TIM2_IRQHandler + isr_empty, // TIM3_IRQHandler + isr_empty, // TIM4_IRQHandler + isr_empty, // TIM5_IRQHandler + isr_empty, // TIM6_IRQHandler + isr_empty, // TIM7_IRQHandler + isr_empty, // TIM8_BRK_IRQHandler + isr_empty, // TIM8_UP_IRQHandler + isr_empty, // TIM8_TRG_COM_IRQHandler + isr_empty, // TIM8_CC_IRQHandler + isr_empty, // I2C1_EV_IRQHandler + isr_empty, // I2C1_ER_IRQHandler + isr_empty, // I2C2_EV_IRQHandler + isr_empty, // I2C2_ER_IRQHandler + isr_empty, // SPI1_IRQHandler + isr_empty, // SPI2_IRQHandler + isr_empty, // USART1_IRQHandler + isr_empty, // USART2_IRQHandler + isr_empty, // USART3_IRQHandler + isr_empty, // UART4_IRQHandler + isr_empty, // UART5_IRQHandler + isr_empty, // LPUART1_IRQHandler + isr_empty, // LPTIM1_IRQHandler + isr_empty, // LPTIM2_IRQHandler + isr_empty, // TIM15_IRQHandler + isr_empty, // TIM16_IRQHandler + isr_empty, // TIM17_IRQHandler + isr_empty, // COMP_IRQHandler + isr_empty, // USB_FS_IRQHandler + isr_empty, // CRS_IRQHandler + isr_empty, // FMC_IRQHandler + isr_empty, // OCTOSPI1_IRQHandler + isr_empty, // 0 + isr_empty, // SDMMC1_IRQHandler + isr_empty, // 0 + isr_empty, // DMA2_Channel1_IRQHandler + isr_empty, // DMA2_Channel2_IRQHandler + isr_empty, // DMA2_Channel3_IRQHandler + isr_empty, // DMA2_Channel4_IRQHandler + isr_empty, // DMA2_Channel5_IRQHandler + isr_empty, // DMA2_Channel6_IRQHandler + isr_empty, // DMA2_Channel7_IRQHandler + isr_empty, // DMA2_Channel8_IRQHandler + isr_empty, // I2C3_EV_IRQHandler + isr_empty, // I2C3_ER_IRQHandler + isr_empty, // SAI1_IRQHandler + isr_empty, // SAI2_IRQHandler + isr_empty, // TSC_IRQHandler + isr_empty, // AES_IRQHandler + isr_empty, // RNG_IRQHandler + isr_empty, // FPU_IRQHandler + isr_empty, // HASH_IRQHandler + isr_empty, // PKA_IRQHandler + isr_empty, // LPTIM3_IRQHandler + isr_empty, // SPI3_IRQHandler + isr_empty, // I2C4_ER_IRQHandler + isr_empty, // I2C4_EV_IRQHandler + isr_empty, // DFSDM1_FLT0_IRQHandler + isr_empty, // DFSDM1_FLT1_IRQHandler + isr_empty, // DFSDM1_FLT2_IRQHandler + isr_empty, // DFSDM1_FLT3_IRQHandler + isr_empty, // UCPD1_IRQHandler + isr_empty, // ICACHE_IRQHandler + isr_empty, // OTFDEC1_IRQHandler +#else /* For STM32F4 */ + isr_empty, // NVIC_WWDG_IRQ 0 + isr_empty, // PVD_IRQ 1 + isr_empty, // TAMP_STAMP_IRQ 2 + isr_empty, // RTC_WKUP_IRQ 3 + isr_empty, // FLASH_IRQ 4 + isr_empty, // RCC_IRQ 5 + isr_empty, // EXTI0_IRQ 6 + isr_empty, // EXTI1_IRQ 7 + isr_empty, // EXTI2_IRQ 8 + isr_empty, // EXTI3_IRQ 9 + isr_empty, // EXTI4_IRQ 10 + isr_empty, // DMA1_STREAM0_IRQ 11 + isr_empty, // DMA1_STREAM1_IRQ 12 + isr_empty, // DMA1_STREAM2_IRQ 13 + isr_empty, // DMA1_STREAM3_IRQ 14 + isr_empty, // DMA1_STREAM4_IRQ 15 + isr_empty, // DMA1_STREAM5_IRQ 16 + isr_empty, // DMA1_STREAM6_IRQ 17 + isr_empty, // ADC_IRQ 18 + isr_empty, // CAN1_TX_IRQ 19 + isr_empty, // CAN1_RX0_IRQ 20 + isr_empty, // CAN1_RX1_IRQ 21 + isr_empty, // CAN1_SCE_IRQ 22 + isr_empty, // EXTI9_5_IRQ 23 + isr_empty, // TIM1_BRK_TIM9_IRQ 24 + isr_empty, // TIM1_UP_TIM10_IRQ 25 + isr_empty, // TIM1_TRG_COM_TIM11_IRQ 26 + isr_empty, // TIM1_CC_IRQ 27 + isr_tim2, // TIM2_IRQ 28 + isr_empty, // TIM3_IRQ 29 + isr_empty, // TIM4_IRQ 30 + isr_empty, // I2C1_EV_IRQ 31 + isr_empty, // I2C1_ER_IRQ 32 + isr_empty, // I2C2_EV_IRQ 33 + isr_empty, // I2C2_ER_IRQ 34 + isr_empty, // SPI1_IRQ 35 + isr_empty, // SPI2_IRQ 36 + isr_empty, // USART1_IRQ 37 + isr_empty, // USART2_IRQ 38 + isr_empty, // USART3_IRQ 39 + isr_empty, // EXTI15_10_IRQ 40 + isr_empty, // RTC_ALARM_IRQ 41 + isr_empty, // USB_FS_WKUP_IRQ 42 + isr_empty, // TIM8_BRK_TIM12_IRQ 43 + isr_empty, // TIM8_UP_TIM13_IRQ 44 + isr_empty, // TIM8_TRG_COM_TIM14_IRQ 45 + isr_empty, // TIM8_CC_IRQ 46 + isr_empty, // DMA1_STREAM7_IRQ 47 + +#endif +}; diff --git a/test-app-STM32F4-measured-boot/src/system.c b/test-app-STM32F4-measured-boot/src/system.c new file mode 100644 index 0000000..01d6c57 --- /dev/null +++ b/test-app-STM32F4-measured-boot/src/system.c @@ -0,0 +1,147 @@ +/* system.c + * + * Test bare-metal blinking led application + * + * Copyright (C) 2020 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +#if defined(PLATFORM_stm32f4) || defined(PLATFORM_stm32f7) +#include +#include "system.h" + +/*** FLASH ***/ +#define FLASH_BASE (0x40023C00) +#define FLASH_ACR (*(volatile uint32_t *)(FLASH_BASE + 0x00)) +#define FLASH_ACR_ENABLE_DATA_CACHE (1 << 10) +#define FLASH_ACR_ENABLE_INST_CACHE (1 << 9) + +/*** RCC ***/ + +#define RCC_BASE (0x40023800) +#define RCC_CR (*(volatile uint32_t *)(RCC_BASE + 0x00)) +#define RCC_PLLCFGR (*(volatile uint32_t *)(RCC_BASE + 0x04)) +#define RCC_CFGR (*(volatile uint32_t *)(RCC_BASE + 0x08)) +#define RCC_CR (*(volatile uint32_t *)(RCC_BASE + 0x00)) + +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_HSIRDY (1 << 1) +#define RCC_CR_HSION (1 << 0) + +#define RCC_CFGR_SW_HSI 0x0 +#define RCC_CFGR_SW_HSE 0x1 +#define RCC_CFGR_SW_PLL 0x2 + + +#define RCC_PLLCFGR_PLLSRC (1 << 22) + +#define RCC_PRESCALER_DIV_NONE 0 +#define RCC_PRESCALER_DIV_2 8 +#define RCC_PRESCALER_DIV_4 9 + + +/* STM32F4-Discovery, 168 MHz */ +#ifdef PLATFORM_stm32f4 +# define PLLM 8 +# define PLLN 336 +# define PLLP 2 +# define PLLQ 7 +# define PLLR 0 +# define TARGET_FLASH_WAITSTATES 5 +#endif + +/* STM32F7-Discovery, 216 MHz */ +#ifdef PLATFORM_stm32f7 +# define PLLM 25 +# define PLLN 432 +# define PLLP 2 +# define PLLQ 9 +# define PLLR 0 +# define TARGET_FLASH_WAITSTATES 7 +#endif + +void flash_set_waitstates(void) +{ + FLASH_ACR |= TARGET_FLASH_WAITSTATES | FLASH_ACR_ENABLE_DATA_CACHE | FLASH_ACR_ENABLE_INST_CACHE; +} + + +void clock_config(void) +{ + uint32_t reg32; + /* Enable internal high-speed oscillator. */ + RCC_CR |= RCC_CR_HSION; + DMB(); + while ((RCC_CR & RCC_CR_HSIRDY) == 0) {}; + + /* Select HSI as SYSCLK source. */ + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | RCC_CFGR_SW_HSI); + DMB(); + + /* Enable external high-speed oscillator 8MHz. */ + RCC_CR |= RCC_CR_HSEON; + DMB(); + while ((RCC_CR & RCC_CR_HSERDY) == 0) {}; + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + */ + reg32 = RCC_CFGR; + reg32 &= ~(0xF0); + RCC_CFGR = (reg32 | (RCC_PRESCALER_DIV_NONE << 4)); + DMB(); + reg32 = RCC_CFGR; + reg32 &= ~(0x1C00); + RCC_CFGR = (reg32 | (RCC_PRESCALER_DIV_2 << 10)); + DMB(); + reg32 = RCC_CFGR; + reg32 &= ~(0x07 << 13); + RCC_CFGR = (reg32 | (RCC_PRESCALER_DIV_4 << 13)); + DMB(); + + /* Set PLL config */ + reg32 = RCC_PLLCFGR; + reg32 &= ~(PLL_FULL_MASK); + RCC_PLLCFGR = reg32 | RCC_PLLCFGR_PLLSRC | PLLM | + (PLLN << 6) | (((PLLP >> 1) - 1) << 16) | + (PLLQ << 24); + DMB(); + /* Enable PLL oscillator and wait for it to stabilize. */ + RCC_CR |= RCC_CR_PLLON; + DMB(); + while ((RCC_CR & RCC_CR_PLLRDY) == 0) {}; + + /* Select PLL as SYSCLK source. */ + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | RCC_CFGR_SW_PLL); + DMB(); + + /* Wait for PLL clock to be selected. */ + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SW_PLL) {}; + + /* Disable internal high-speed oscillator. */ + RCC_CR &= ~RCC_CR_HSION; +} + +#endif /* PLATFORM_stm32f4 */ diff --git a/test-app-STM32F4-measured-boot/src/system.h b/test-app-STM32F4-measured-boot/src/system.h new file mode 100644 index 0000000..e8089c0 --- /dev/null +++ b/test-app-STM32F4-measured-boot/src/system.h @@ -0,0 +1,67 @@ +/* system.h + * + * + * Copyright (C) 2020 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef SYSTEM_H_INCLUDED +#define SYSTEM_H_INCLUDED + +/* System specific: PLL with 8 MHz external oscillator, CPU at 168MHz */ +#define CPU_FREQ (168000000) +#define PLL_FULL_MASK (0x7F037FFF) + +/* Assembly helpers */ +#define DMB() asm volatile ("dmb"); +#define WFI() asm volatile ("wfi"); + +/* Master clock setting */ +void clock_config(void); +void flash_set_waitstates(void); + + +/* NVIC */ +/* NVIC ISER Base register (Cortex-M) */ + +#define NVIC_TIM2_IRQN (28) +#define NVIC_ISER_BASE (0xE000E100) +#define NVIC_ICER_BASE (0xE000E180) +#define NVIC_IPRI_BASE (0xE000E400) + +static inline void nvic_irq_enable(uint8_t n) +{ + int i = n / 32; + volatile uint32_t *nvic_iser = ((volatile uint32_t *)(NVIC_ISER_BASE + 4 * i)); + *nvic_iser |= (1 << (n % 32)); +} + +static inline void nvic_irq_disable(uint8_t n) +{ + int i = n / 32; + volatile uint32_t *nvic_icer = ((volatile uint32_t *)(NVIC_ICER_BASE + 4 * i)); + *nvic_icer |= (1 << (n % 32)); +} + +static inline void nvic_irq_setprio(uint8_t n, uint8_t prio) +{ + volatile uint8_t *nvic_ipri = ((volatile uint8_t *)(NVIC_IPRI_BASE + n)); + *nvic_ipri = prio; +} + +#endif /* !SYSTEM_H_INCLUDED */ diff --git a/test-app-STM32F4-measured-boot/src/target-app.ld b/test-app-STM32F4-measured-boot/src/target-app.ld new file mode 100644 index 0000000..1047b51 --- /dev/null +++ b/test-app-STM32F4-measured-boot/src/target-app.ld @@ -0,0 +1,45 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x20100, LENGTH = 0x1FF00 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K /* Run in lowmem */ +} + +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); + KEEP(*(.ramcode)) + . = 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-STM32F4-measured-boot/src/timer.c b/test-app-STM32F4-measured-boot/src/timer.c new file mode 100644 index 0000000..0b73408 --- /dev/null +++ b/test-app-STM32F4-measured-boot/src/timer.c @@ -0,0 +1,171 @@ +/* timer.c + * + * Test bare-metal blinking led application + * + * Copyright (C) 2020 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef PLATFORM_stm32f4 +#include + +#include "system.h" +#include "led.h" + + +/* STM32 specific defines */ +#define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40023840)) +#define APB1_CLOCK_RST (*(volatile uint32_t *)(0x40023820)) +#define TIM4_APB1_CLOCK_ER_VAL (1 << 2) +#define TIM2_APB1_CLOCK_ER_VAL (1 << 0) + +#define TIM2_BASE (0x40000000) +#define TIM2_CR1 (*(volatile uint32_t *)(TIM2_BASE + 0x00)) +#define TIM2_DIER (*(volatile uint32_t *)(TIM2_BASE + 0x0c)) +#define TIM2_SR (*(volatile uint32_t *)(TIM2_BASE + 0x10)) +#define TIM2_PSC (*(volatile uint32_t *)(TIM2_BASE + 0x28)) +#define TIM2_ARR (*(volatile uint32_t *)(TIM2_BASE + 0x2c)) + +#define TIM4_BASE (0x40000800) +#define TIM4_CR1 (*(volatile uint32_t *)(TIM4_BASE + 0x00)) +#define TIM4_DIER (*(volatile uint32_t *)(TIM4_BASE + 0x0c)) +#define TIM4_SR (*(volatile uint32_t *)(TIM4_BASE + 0x10)) +#define TIM4_CCMR1 (*(volatile uint32_t *)(TIM4_BASE + 0x18)) +#define TIM4_CCMR2 (*(volatile uint32_t *)(TIM4_BASE + 0x1c)) +#define TIM4_CCER (*(volatile uint32_t *)(TIM4_BASE + 0x20)) +#define TIM4_PSC (*(volatile uint32_t *)(TIM4_BASE + 0x28)) +#define TIM4_ARR (*(volatile uint32_t *)(TIM4_BASE + 0x2c)) +#define TIM4_CCR4 (*(volatile uint32_t *)(TIM4_BASE + 0x40)) + +#define TIM_DIER_UIE (1 << 0) +#define TIM_SR_UIF (1 << 0) +#define TIM_CR1_CLOCK_ENABLE (1 << 0) +#define TIM_CR1_UPD_RS (1 << 2) +#define TIM_CR1_ARPE (1 << 7) + +#define TIM_CCER_CC4_ENABLE (1 << 12) +#define TIM_CCMR1_OC1M_PWM1 (0x06 << 4) +#define TIM_CCMR2_OC4M_PWM1 (0x06 << 12) + +#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_OTYPE (*(volatile uint32_t *)(GPIOD_BASE + 0x04)) +#define GPIOD_PUPD (*(volatile uint32_t *)(GPIOD_BASE + 0x0c)) +#define GPIOD_ODR (*(volatile uint32_t *)(GPIOD_BASE + 0x14)) + +static uint32_t master_clock = 0; + +/** Use TIM4_CH4, which is linked to PD15 AF1 **/ +int pwm_init(uint32_t clock, uint32_t threshold) +{ + uint32_t val = (clock / 100000); /* Frequency is 100 KHz */ + uint32_t lvl; + master_clock = clock; + + if (threshold > 100) + return -1; + + 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; + APB1_CLOCK_ER |= TIM4_APB1_CLOCK_ER_VAL; + + /* disable CC */ + TIM4_CCER &= ~TIM_CCER_CC4_ENABLE; + TIM4_CR1 = 0; + TIM4_PSC = 0; + TIM4_ARR = val - 1; + TIM4_CCR4 = lvl; + TIM4_CCMR1 &= ~(0x03 << 0); + TIM4_CCMR1 &= ~(0x07 << 4); + TIM4_CCMR1 |= TIM_CCMR1_OC1M_PWM1; + TIM4_CCMR2 &= ~(0x03 << 8); + TIM4_CCMR2 &= ~(0x07 << 12); + TIM4_CCMR2 |= TIM_CCMR2_OC4M_PWM1; + TIM4_CCER |= TIM_CCER_CC4_ENABLE; + TIM4_CR1 |= TIM_CR1_CLOCK_ENABLE | TIM_CR1_ARPE; + asm volatile ("dmb"); + return 0; +} + +int timer_init(uint32_t clock, uint32_t prescaler, uint32_t interval_ms) +{ + uint32_t val = 0; + uint32_t psc = 1; + uint32_t err = 0; + clock = ((clock * prescaler) / 1000) * interval_ms; + + while (psc < 65535) { + val = clock / psc; + err = clock % psc; + if ((val < 65535) && (err == 0)) { + val--; + break; + } + val = 0; + psc++; + } + if (val == 0) + return -1; + + nvic_irq_enable(NVIC_TIM2_IRQN); + nvic_irq_setprio(NVIC_TIM2_IRQN, 0); + APB1_CLOCK_RST |= TIM2_APB1_CLOCK_ER_VAL; + asm volatile ("dmb"); + APB1_CLOCK_RST &= ~TIM2_APB1_CLOCK_ER_VAL; + APB1_CLOCK_ER |= TIM2_APB1_CLOCK_ER_VAL; + + TIM2_CR1 = 0; + asm volatile ("dmb"); + TIM2_PSC = psc; + TIM2_ARR = val; + TIM2_CR1 |= TIM_CR1_CLOCK_ENABLE; + TIM2_DIER |= TIM_DIER_UIE; + asm volatile ("dmb"); + return 0; +} + +extern volatile uint32_t time_elapsed; +void isr_tim2(void) +{ + static volatile uint32_t tim2_ticks = 0; + TIM2_SR &= ~TIM_SR_UIF; + + /* Dim the led by altering the PWM duty-cicle */ + if (++tim2_ticks > 15) + tim2_ticks = 0; + if (tim2_ticks > 8) + pwm_init(master_clock, 10 * (16 - tim2_ticks)); + else + pwm_init(master_clock, 10 * tim2_ticks); + + time_elapsed++; +} +#else +void isr_tim2(void) +{ +} + +#endif /* PLATFORM_stm32f4 */ diff --git a/test-app-STM32F4-measured-boot/src/timer.h b/test-app-STM32F4-measured-boot/src/timer.h new file mode 100644 index 0000000..bd66dae --- /dev/null +++ b/test-app-STM32F4-measured-boot/src/timer.h @@ -0,0 +1,30 @@ +/* timer.h + * + * Test bare-metal blinking led application + * + * Copyright (C) 2020 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef TIMER_H_INCLUDED +#define TIMER_H_INCLUDED + +int pwm_init(uint32_t clock, uint32_t threshold); +int timer_init(uint32_t clock, uint32_t scaler, uint32_t interval); + +#endif /* !TIMER_H_INCLUDED */