Skip to content

Commit f53fbc7

Browse files
authored
Bootloader: R9MX (STM32L4xx) support added (uses same 32kB as R9MM) (ExpressLRS#138)
1 parent c3f4e5d commit f53fbc7

7 files changed

Lines changed: 131 additions & 20 deletions

File tree

src/bootloader/src/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
*.code-workspace
77
.vscode
88
__pycache__
9+
*.pyc

src/bootloader/src/Src/flash.c

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ flash_status flash_erase(uint32_t address)
3030
uint32_t error = 0u;
3131

3232
erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
33+
#if defined(STM32L4xx)
34+
erase_init.Page = (address - FLASH_BASE) / FLASH_PAGE_SIZE;
35+
#else
3336
erase_init.PageAddress = address;
37+
#endif
3438
#ifdef FLASH_BANK_1
3539
erase_init.Banks = FLASH_BANK_1;
3640
#endif
@@ -59,7 +63,11 @@ flash_status flash_erase_page(uint32_t address)
5963
uint32_t error = 0u;
6064

6165
erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
66+
#if defined(STM32L4xx)
67+
erase_init.Page = (address - FLASH_BASE) / FLASH_PAGE_SIZE;
68+
#else
6269
erase_init.PageAddress = address;
70+
#endif
6371
#ifdef FLASH_BANK_1
6472
erase_init.Banks = FLASH_BANK_1;
6573
#endif
@@ -83,8 +91,45 @@ flash_status flash_erase_page(uint32_t address)
8391
* @param *length: Size of the array.
8492
* @return status: Report about the success of the writing.
8593
*/
86-
flash_status flash_write(uint32_t address, uint32_t *data, uint32_t length)
87-
{
94+
#if defined(STM32L4xx)
95+
flash_status flash_write(uint32_t address, uint32_t *data, uint32_t length) {
96+
flash_status status = FLASH_OK;
97+
98+
length = (length + 1) >> 1; // roundup and convert to double words
99+
100+
HAL_FLASH_Unlock();
101+
102+
/* Loop through the array. */
103+
for (uint32_t i = 0u; (i < length) && (FLASH_OK == status); i++) {
104+
/* If we reached the end of the memory, then report an error and don't
105+
* do anything else.*/
106+
if (FLASH_APP_END_ADDRESS <= address) {
107+
status |= FLASH_ERROR_SIZE;
108+
} else {
109+
/* The actual flashing. If there is an error, then report it. */
110+
if (HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address,
111+
*(uint64_t *)data)) {
112+
status |= FLASH_ERROR_WRITE;
113+
}
114+
/* Read back the content of the memory. If it is wrong, then report an
115+
* error. */
116+
if (((*data++) != (*(volatile uint32_t *)address)) ||
117+
((*data++) != (*(volatile uint32_t *)(address + sizeof(uint32_t))))) {
118+
status |= FLASH_ERROR_READBACK;
119+
}
120+
121+
/* Shift the address by a double word. */
122+
address += sizeof(uint64_t);
123+
}
124+
}
125+
126+
HAL_FLASH_Lock();
127+
128+
return status;
129+
}
130+
131+
#else // !STM32L4xx
132+
flash_status flash_write(uint32_t address, uint32_t *data, uint32_t length) {
88133
flash_status status = FLASH_OK;
89134

90135
HAL_FLASH_Unlock();
@@ -101,9 +146,7 @@ flash_status flash_write(uint32_t address, uint32_t *data, uint32_t length)
101146
else
102147
{
103148
/* The actual flashing. If there is an error, then report it. */
104-
if (HAL_OK !=
105-
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data[i]))
106-
{
149+
if (HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data[i])) {
107150
status |= FLASH_ERROR_WRITE;
108151
}
109152
/* Read back the content of the memory. If it is wrong, then report an
@@ -122,6 +165,7 @@ flash_status flash_write(uint32_t address, uint32_t *data, uint32_t length)
122165

123166
return status;
124167
}
168+
#endif // STM32L4xx
125169

126170
/**
127171
* @brief This function flashes the memory.

src/bootloader/src/Src/flash.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "stm32l0xx_hal.h"
1515
#elif defined(STM32L1xx)
1616
#include "stm32l1xx_hal.h"
17+
#elif defined(STM32L4xx)
18+
#include "stm32l4xx_hal.h"
1719
#elif defined(STM32F1)
1820
#include "stm32f1xx_hal.h"
1921
#endif
@@ -29,12 +31,18 @@
2931
#define FLASH_APP_START_ADDRESS (FLASH_BASE + FLASH_APP_OFFSET)
3032
#define FLASH_APP_END_ADDRESS ((uint32_t)FLASH_BANK1_END - 0x10u) /**< Leave a little extra space at the end. */
3133

34+
#if !defined(FLASH_END) && defined(STM32L4xx)
35+
#define FLASH_END (FLASH_BASE + 0x20000) // default to 128kB just in case
36+
#endif
3237
#ifndef FLASH_BANK1_END
3338
#define FLASH_BANK1_END FLASH_END
3439
#endif
3540

3641
/* Status report for the functions. */
3742
#define FLASH_OK 0x00u /**< The action was successful. */
43+
#ifndef HAL_FLASH_ERROR_SIZE
44+
#define HAL_FLASH_ERROR_SIZE 0x01
45+
#endif
3846
#ifndef FLASH_ERROR_SIZE
3947
#define FLASH_ERROR_SIZE 0x01u /**< The binary is too big. */
4048
#endif

src/bootloader/src/Src/main.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ int main(void)
226226
boot_code();
227227
}
228228

229-
#ifdef STM32L0xx
229+
#if defined(STM32L0xx) || defined(STM32L4xx)
230230
void SysTick_Handler(void)
231231
{
232232
HAL_IncTick();
@@ -246,8 +246,7 @@ void SystemClock_Config(void)
246246
memset(&RCC_OscInitStruct, 0, sizeof(RCC_OscInitTypeDef));
247247
memset(&RCC_ClkInitStruct, 0, sizeof(RCC_ClkInitTypeDef));
248248

249-
250-
#ifdef STM32L0xx
249+
#if defined(STM32L0xx) || defined(STM32L4xx)
251250
/* Enable Power Control clock */
252251
__HAL_RCC_PWR_CLK_ENABLE();
253252

@@ -262,8 +261,16 @@ void SystemClock_Config(void)
262261
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
263262
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
264263
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
264+
#if defined(STM32L4xx)
265+
RCC_OscInitStruct.PLL.PLLM = 1; // 16MHz
266+
RCC_OscInitStruct.PLL.PLLN = 10; // 10 * 16MHz
267+
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; // 160MHz / 2
268+
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; // 160MHz / 7
269+
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; // 160MHz / 2
270+
#else
265271
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4;
266272
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV2;
273+
#endif
267274
RCC_OscInitStruct.HSICalibrationValue = 0x10;
268275
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
269276
Error_Handler();
@@ -275,7 +282,12 @@ void SystemClock_Config(void)
275282
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
276283
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
277284
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
278-
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
285+
#if defined(STM32L4xx)
286+
uint32_t flash_latency = FLASH_LATENCY_4;
287+
#else
288+
uint32_t flash_latency = FLASH_LATENCY_1;
289+
#endif
290+
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, flash_latency) != HAL_OK)
279291
Error_Handler();
280292

281293
RCC_PeriphCLKInitTypeDef PeriphClkInit = {};
@@ -288,6 +300,7 @@ void SystemClock_Config(void)
288300
HAL_ResumeTick();
289301

290302
#elif defined(STM32L1xx)
303+
#warning "Clock setup is missing! Should use HSI!"
291304

292305
#elif defined(STM32F1)
293306

src/bootloader/src/Src/main.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
#elif defined(STM32F1)
3232
#include "stm32f1xx.h"
3333
#include "stm32f1xx_hal.h"
34+
#elif defined(STM32L4xx)
35+
#include "stm32l4xx.h"
36+
#include "stm32l4xx_hal.h"
3437
#else
3538
#error "Not supported CPU type!"
3639
#endif
@@ -58,8 +61,13 @@ int8_t timer_end(void);
5861

5962
/* Private defines -----------------------------------------------------------*/
6063
#ifdef BUTTON
64+
#if TARGET_R9MX
65+
#define BTN_Pin GPIO_PIN_0
66+
#define BTN_GPIO_Port GPIOB
67+
#elif TARGET_R9MM
6168
#define BTN_Pin GPIO_PIN_13
6269
#define BTN_GPIO_Port GPIOC
70+
#endif
6371
#endif /* BUTTON */
6472
#ifdef LED_GRN
6573
#if TARGET_R9MM
@@ -68,6 +76,9 @@ int8_t timer_end(void);
6876
#elif TARGET_R9M
6977
#define LED_GRN_Pin GPIO_PIN_12
7078
#define LED_GRN_GPIO_Port GPIOA
79+
#elif TARGET_R9MX
80+
#define LED_GRN_Pin GPIO_PIN_3
81+
#define LED_GRN_GPIO_Port GPIOB
7182
#endif
7283
#endif /* LED_GRN */
7384
#ifdef LED_RED
@@ -85,6 +96,12 @@ int8_t timer_end(void);
8596
#define LED_RED_GPIO_Port GPIOA
8697
#elif TARGET_RAK811
8798

99+
#elif TARGET_SX1280_RX_v02
100+
#define LED_RED_Pin GPIO_PIN_15
101+
#define LED_RED_GPIO_Port GPIOB
102+
#elif TARGET_R9MX
103+
#define LED_RED_Pin GPIO_PIN_2
104+
#define LED_RED_GPIO_Port GPIOB
88105
#endif
89106
#endif /* LED_RED */
90107

src/bootloader/src/Src/uart.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -250,16 +250,16 @@ void uart_init(void)
250250
GPIO_InitStruct.Pin = (1 << pin_rx);
251251
GPIO_InitStruct.Pull = GPIO_PULLUP;
252252
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
253-
#ifdef STM32L0xx
253+
#if defined(STM32L0xx)
254254
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
255-
if (huart1.Instance == USART1 && pin_rx == 7)
256-
{
255+
if (huart1.Instance == USART1 && pin_rx == 7) {
257256
GPIO_InitStruct.Alternate = GPIO_AF0_USART1;
258-
}
259-
else
260-
{
257+
} else {
261258
GPIO_InitStruct.Alternate = GPIO_AF4_USART1;
262259
}
260+
#elif defined(STM32L4xx)
261+
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
262+
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
263263
#else
264264
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
265265
#endif
@@ -270,14 +270,14 @@ void uart_init(void)
270270
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
271271
GPIO_InitStruct.Pull = GPIO_PULLUP;
272272
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
273-
#ifdef STM32L0xx
273+
#if defined(STM32L0xx)
274274
if (huart1.Instance == USART1 && pin_tx == 6) {
275275
GPIO_InitStruct.Alternate = GPIO_AF0_USART1;
276-
}
277-
else
278-
{
276+
} else {
279277
GPIO_InitStruct.Alternate = GPIO_AF4_USART1;
280278
}
279+
#elif defined(STM32L4xx)
280+
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
281281
#endif
282282
HAL_GPIO_Init(gpio_ptr, &GPIO_InitStruct);
283283

src/bootloader/src/platformio.ini

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[platformio]
2-
#default_envs = RHF76_052
2+
#default_envs = R9MX
33
src_dir = Src
44
lib_dir = Drivers
55

@@ -140,3 +140,31 @@ build_flags =
140140
-Wl,--defsym=FLASH_APP_OFFSET=16K
141141
-D FLASH_APP_OFFSET=0x4000u
142142
src_filter = +<*.c>
143+
144+
[env:R9MX]
145+
146+
framework = stm32cube
147+
board = nucleo_l433rc_p
148+
board_build.mcu = stm32l433cby6
149+
#board_build.f_cpu = 80000000L
150+
#board_upload.maximum_size = 16384
151+
board_upload.maximum_size = 32768
152+
build_unflags = ${generic.unflags}
153+
build_flags =
154+
-D STM32L4xx=1
155+
-D TARGET_XMODEM=1
156+
-D TARGET_R9MX=1
157+
-D BUTTON=1
158+
-D LED_GRN=1
159+
-D LED_RED=1
160+
-D UART_NUM=1
161+
-D UART_BAUD=420000
162+
-D HSI_VALUE=16000000
163+
-Wl,--defsym=FLASH_APP_OFFSET=32K
164+
-D FLASH_APP_OFFSET=0x8000u
165+
src_filter = +<*.c>
166+
debug_build_flags = -O0 -ggdb3 -g3
167+
upload_protocol = custom
168+
extra_scripts =
169+
python/upload_stlink.py
170+
debug_tool = stlink

0 commit comments

Comments
 (0)