Skip to content

Commit c9f8f6a

Browse files
committed
Added uart driver for stm32wb
1 parent 845eef7 commit c9f8f6a

6 files changed

Lines changed: 193 additions & 9 deletions

File tree

hal/uart/uart_drv_stm32wb.c

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/* uart_drv_stm32.c
2+
*
3+
* Driver for the back-end of the UART_FLASH module.
4+
*
5+
* Example implementation for stm32WB, using UART1.
6+
*
7+
* Pinout: RX=PD9, TX=PD8
8+
*
9+
* Copyright (C) 2020 wolfSSL Inc.
10+
*
11+
* This file is part of wolfBoot.
12+
*
13+
* wolfBoot is free software; you can redistribute it and/or modify
14+
* it under the terms of the GNU General Public License as published by
15+
* the Free Software Foundation; either version 2 of the License, or
16+
* (at your option) any later version.
17+
*
18+
* wolfBoot is distributed in the hope that it will be useful,
19+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21+
* GNU General Public License for more details.
22+
*
23+
* You should have received a copy of the GNU General Public License
24+
* along with this program; if not, write to the Free Software
25+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
26+
*/
27+
28+
#include <stdint.h>
29+
30+
/* Driver hardcoded to work on UART1 (PB6/PB7) */
31+
#define UART1 (0x40013800)
32+
#define UART1_PIN_AF 7
33+
#define UART1_RX_PIN 7
34+
#define UART1_TX_PIN 6
35+
36+
#define UART1_CR1 (*(volatile uint32_t *)(UART1 + 0x00))
37+
#define UART1_CR2 (*(volatile uint32_t *)(UART1 + 0x04))
38+
#define UART1_BRR (*(volatile uint32_t *)(UART1 + 0x0C))
39+
#define UART1_ISR (*(volatile uint32_t *)(UART1 + 0x1C))
40+
#define UART1_RDR (*(volatile uint32_t *)(UART1 + 0x24))
41+
#define UART1_TDR (*(volatile uint32_t *)(UART1 + 0x28))
42+
#define UART_CR1_UART_ENABLE (1 << 0)
43+
#define UART_CR1_TX_ENABLE (1 << 3)
44+
#define UART_CR1_RX_ENABLE (1 << 2)
45+
#define UART_CR1_SYMBOL_LEN (1 << 28)
46+
#define UART_CR1_FIFO_ENABLE (1 << 29)
47+
#define UART_CR1_PARITY_ENABLED (1 << 10)
48+
#define UART_CR1_PARITY_ODD (1 << 9)
49+
#define UART_ISR_TX_EMPTY (1 << 7)
50+
#define UART_ISR_RX_NOTEMPTY (1 << 5)
51+
52+
#define CLOCK_SPEED (64000000) /* 64 MHz (STM32WB55) */
53+
54+
#define APB2_CLOCK_ER (*(volatile uint32_t *)(0x58000060))
55+
#define UART1_APB2_CLOCK_ER_VAL (1 << 14)
56+
57+
#define AHB2_CLOCK_ER (*(volatile uint32_t *)(0x5800004c))
58+
#define GPIOB_AHB2_CLOCK_ER (1 << 1)
59+
#define GPIOB_BASE 0x48000400
60+
#define GPIOB_MODE (*(volatile uint32_t *)(GPIOB_BASE + 0x00))
61+
#define GPIOB_AFL (*(volatile uint32_t *)(GPIOB_BASE + 0x20))
62+
#define GPIOB_AFH (*(volatile uint32_t *)(GPIOB_BASE + 0x24))
63+
#define GPIO_MODE_AF (2)
64+
65+
static void uart_pins_setup(void)
66+
{
67+
uint32_t reg;
68+
AHB2_CLOCK_ER |= GPIOB_AHB2_CLOCK_ER;
69+
/* Set mode = AF */
70+
reg = GPIOB_MODE & ~ (0x03 << (UART1_RX_PIN * 2));
71+
GPIOB_MODE = reg | (2 << (UART1_RX_PIN * 2));
72+
reg = GPIOB_MODE & ~ (0x03 << (UART1_TX_PIN * 2));
73+
GPIOB_MODE = reg | (2 << (UART1_TX_PIN * 2));
74+
75+
/* Alternate function: use low pins (6 and 7) */
76+
reg = GPIOB_AFL & ~(0xf << ((UART1_TX_PIN) * 4));
77+
GPIOB_AFL = reg | (UART1_PIN_AF << ((UART1_TX_PIN) * 4));
78+
reg = GPIOB_AFL & ~(0xf << ((UART1_RX_PIN) * 4));
79+
GPIOB_AFL = reg | (UART1_PIN_AF << ((UART1_RX_PIN) * 4));
80+
}
81+
82+
int uart_tx(const uint8_t c)
83+
{
84+
uint32_t reg;
85+
do {
86+
reg = UART1_ISR;
87+
} while ((reg & UART_ISR_TX_EMPTY) == 0);
88+
UART1_TDR = c;
89+
return 1;
90+
}
91+
92+
int uart_rx(uint8_t *c)
93+
{
94+
volatile uint32_t reg = UART1_ISR;
95+
if ((reg & UART_ISR_RX_NOTEMPTY) != 0) {
96+
reg = UART1_RDR;
97+
*c = (uint8_t)(reg & 0xff);
98+
return 1;
99+
}
100+
return 0;
101+
}
102+
103+
int uart_init(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
104+
{
105+
uint32_t reg;
106+
/* Enable pins and configure for AF7 */
107+
uart_pins_setup();
108+
/* Turn on the device */
109+
APB2_CLOCK_ER |= UART1_APB2_CLOCK_ER_VAL;
110+
UART1_CR1 &= ~(UART_CR1_UART_ENABLE);
111+
UART1_CR1 &= ~(UART_CR1_FIFO_ENABLE);
112+
113+
/* Configure for TX + RX */
114+
UART1_CR1 |= (UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE);
115+
116+
/* Configure clock */
117+
UART1_BRR = CLOCK_SPEED / (2 * bitrate);
118+
119+
/* Configure data bits */
120+
if (data == 8)
121+
UART1_CR1 &= ~UART_CR1_SYMBOL_LEN;
122+
else
123+
UART1_CR1 |= UART_CR1_SYMBOL_LEN;
124+
125+
/* Configure parity */
126+
switch (parity) {
127+
case 'O':
128+
UART1_CR1 |= UART_CR1_PARITY_ODD;
129+
/* fall through to enable parity */
130+
/* FALL THROUGH */
131+
case 'E':
132+
UART1_CR1 |= UART_CR1_PARITY_ENABLED;
133+
break;
134+
default:
135+
UART1_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
136+
}
137+
/* Set stop bits (not supported) */
138+
(void)stop;
139+
140+
/* Turn on uart */
141+
UART1_CR1 |= UART_CR1_UART_ENABLE;
142+
return 0;
143+
}
144+

src/libwolfboot.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#define XMEMCPY memcpy
3737
#define XMEMCMP memcmp
3838
#endif
39+
#else
40+
#define XMEMCPY memcpy
3941
#endif
4042

4143
#ifndef NULL
@@ -612,6 +614,10 @@ int ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len)
612614
switch(part) {
613615
case PART_UPDATE:
614616
row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS) / ENCRYPT_BLOCK_SIZE;
617+
/* Do not encrypt last sector */
618+
if (row_number == (WOLFBOOT_PARTITION_SIZE - 1) / ENCRYPT_BLOCK_SIZE) {
619+
return ext_flash_write(address, data, len);
620+
}
615621
break;
616622
case PART_SWAP:
617623
row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS) / ENCRYPT_BLOCK_SIZE;
@@ -662,11 +668,15 @@ int ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len)
662668
if (!chacha_initialized)
663669
if (chacha_init() < 0)
664670
return -1;
665-
XMEMSET(iv, 0, ENCRYPT_BLOCK_SIZE);
666671
part = part_address(row_address);
672+
XMEMSET(iv, 0, ENCRYPT_BLOCK_SIZE);
667673
switch(part) {
668674
case PART_UPDATE:
669675
row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS) / ENCRYPT_BLOCK_SIZE;
676+
/* Do not decrypt last sector */
677+
if (row_number == (WOLFBOOT_PARTITION_SIZE - 1) / ENCRYPT_BLOCK_SIZE) {
678+
return ext_flash_read(address, data, len);
679+
}
670680
break;
671681
case PART_SWAP:
672682
row_number = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS) / ENCRYPT_BLOCK_SIZE;

test-app/app_stm32wb.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,44 @@
2727
#include "led.h"
2828
#include "hal.h"
2929
#include "wolfboot/wolfboot.h"
30+
#include "update.c"
3031

3132
#ifdef PLATFORM_stm32wb
32-
char enc_key[33] = "01234566789abcdef0123456789abcdef";
33+
char enc_key[33] = "0123456789abcdef0123456789abcdef";
3334

3435
volatile uint32_t time_elapsed = 0;
3536
void main(void) {
37+
uint32_t version;
38+
uint32_t l = 0;
39+
uint32_t updv;
3640
hal_init();
3741
boot_led_on();
38-
wolfBoot_success();
42+
#ifdef SPI_FLASH
43+
spi_flash_probe();
44+
#endif
45+
version = wolfBoot_current_firmware_version();
46+
updv = wolfBoot_update_firmware_version();
47+
if ((version == 1) && (updv != 8)) {
48+
uint32_t sz;
49+
boot_led_off();
50+
ext_flash_erase(WOLFBOOT_PARTITION_UPDATE_ADDRESS, WOLFBOOT_PARTITION_SIZE);
51+
while (l < firmware_update_len) {
52+
sz = firmware_update_len - l;
53+
if (sz > WOLFBOOT_SECTOR_SIZE)
54+
sz = WOLFBOOT_SECTOR_SIZE;
55+
ext_flash_write(WOLFBOOT_PARTITION_UPDATE_ADDRESS + l, firmware_update + l, sz);
56+
l += sz;
57+
}
3958
#if EXT_ENCRYPTED
40-
wolfBoot_set_encrypt_key((uint8_t *)enc_key, 32);
59+
wolfBoot_set_encrypt_key((uint8_t *)enc_key, 32);
4160
#endif
42-
43-
61+
wolfBoot_update_trigger();
62+
boot_led_on();
63+
} else {
64+
wolfBoot_success();
65+
}
4466
/* Wait for reboot */
4567
while(1)
46-
;
68+
asm volatile("wfi");
4769
}
4870
#endif /** PLATFROM_stm32wb **/

test-app/led.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,5 +169,12 @@ void boot_led_on(void)
169169
GPIOB_BSRR |= (1 << pin);
170170
}
171171

172+
void boot_led_off(void)
173+
{
174+
uint32_t reg;
175+
uint32_t pin = LED_BOOT_PIN;
176+
GPIOB_BSRR |= (1 << (pin + 16));
177+
}
178+
172179

173180
#endif /* PLATFORM_stm32wb */

test-app/led.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ void led_off(void);
3030
void led_toggle(void);
3131
void led_pwm_setup(void);
3232
void boot_led_on(void);
33+
void boot_led_off(void);
3334

3435
#endif /* !GPIO_H_INCLUDED */

tools/uart-flash-server/ufserver.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@
5050
#define CMD_HDR_ERASE 0x03
5151
#define CMD_ACK 0x06
5252

53-
#define FIRMWARE_PARTITION_SIZE 0x4000
54-
#define SWAP_SIZE 0x4000
53+
#define FIRMWARE_PARTITION_SIZE 0x20000
54+
#define SWAP_SIZE 0x1000
5555
#define UART_BITRATE 460800
5656

5757
const char msgSha[] = "Verifying SHA digest...";

0 commit comments

Comments
 (0)