Skip to content

Commit 08d3d5d

Browse files
committed
stmhal: For LIMIFROG board, add early-init function to get to DFU mode.
1 parent 770f169 commit 08d3d5d

2 files changed

Lines changed: 157 additions & 0 deletions

File tree

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// The code is this file allows the user to enter DFU mode when the board
2+
// starts up, by connecting POS10 on the external connector to GND.
3+
// The code itself is taken from the LimiFrog software repository found at
4+
// https://github.com/LimiFrog/LimiFrog-SW, and the original license header
5+
// is copied below.
6+
7+
#include STM32_HAL_H
8+
9+
static void LBF_DFU_If_Needed(void);
10+
11+
void LIMIFROG_board_early_init(void) {
12+
LBF_DFU_If_Needed();
13+
}
14+
15+
/*******************************************************************************
16+
* LBF_DFU_If_Needed.c
17+
*
18+
* (c)2015 LimiFrog / CYMEYA
19+
* This program is licensed under the terms of the MIT License.
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
21+
* Please refer to the License File LICENSE.txt located at the root of this
22+
* project for full licensing conditions,
23+
* or visit https://opensource.org/licenses/MIT.
24+
******************************************************************************/
25+
26+
#define __LIMIFROG_02
27+
28+
/* ==== BTLE (excl UART) ======================================== */
29+
// PC9 = BT_RST (active high)
30+
31+
#define BT_RST_PIN GPIO_PIN_9
32+
#define BT_RST_PORT GPIOC
33+
34+
// Position 10
35+
#ifdef __LIMIFROG_01
36+
#define CONN_POS10_PIN GPIO_PIN_9
37+
#define CONN_POS10_PORT GPIOB
38+
#else
39+
#define CONN_POS10_PIN GPIO_PIN_8
40+
#define CONN_POS10_PORT GPIOB
41+
#endif
42+
43+
static inline void GPIO_HIGH(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
44+
{
45+
GPIOx->BSRR = (uint32_t)GPIO_Pin;
46+
}
47+
48+
static inline int IS_GPIO_RESET(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
49+
{
50+
GPIO_PinState bitstatus;
51+
if((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
52+
{
53+
bitstatus = GPIO_PIN_SET;
54+
}
55+
else
56+
{
57+
bitstatus = GPIO_PIN_RESET;
58+
}
59+
return (bitstatus==GPIO_PIN_RESET);
60+
}
61+
62+
/**************************************************************
63+
RATIONALE FOR THIS FUNCTION :
64+
65+
- The STM32 embeds in ROM a bootloader that allows to
66+
obtain code and boot from a number of different interfaces,
67+
including USB in a mode called "DFU" (Device Frimware Update)
68+
[see AN3606 from ST for full details]
69+
This bootloader code is executed instead of the regular
70+
application code when pin BOOT0 is pulled-up (which on
71+
LimiFrog0.2 is achieved by pressing the general-purpose
72+
pushbutton switch on the side.
73+
- The bootloader monitors a number of IOs of the STM32 to decide
74+
from which interface it should boot.
75+
- Problem in LimiFrog (up to versions 0.2a at least): upon
76+
power-up the BLE modules generates some activity on UART3,
77+
which is part of the pins monitored by the STM32.
78+
This misleads the bootloader in trying to boot from UART3
79+
and, as a result, not continuing with booting from USB.
80+
81+
- This code implements an alternative solution to launch the
82+
bootloader while making sure UART3 remains stable.
83+
- The idea it to start application code with a check, prior to any
84+
other applicative code, of whether USB bootload is required (as
85+
flagged by a GPIO pulled low at reset, in the same way as BOOT0).
86+
The hadware reset pin of BLE is asserted (so that now it won't
87+
generate any acitivity on UART3), and if USB bootload is required :
88+
bootload ROM is remapped at address 0x0, stack pointer is
89+
updated and the code is branched to the start of the bootloader.
90+
- This code is run prior to any applicative configuration of clocks,
91+
IRQs etc. -- the STM32 is therefore still running from MSI
92+
93+
THIS FUNCTION MAY BE SUPPRESSED IF YOU NEVER NEED TO BOOT DFU MODE
94+
95+
********************************************************************/
96+
97+
static void LBF_DFU_If_Needed(void)
98+
{
99+
100+
101+
GPIO_InitTypeDef GPIO_InitStruct;
102+
103+
104+
// Initialize and assert pin BTLE_RST
105+
// (hw reset to BLE module, so it won't drive UART3)
106+
107+
__GPIOC_CLK_ENABLE();
108+
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
109+
GPIO_InitStruct.Pull = GPIO_NOPULL;
110+
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
111+
GPIO_InitStruct.Pin = BT_RST_PIN;
112+
HAL_GPIO_Init(BT_RST_PORT, &GPIO_InitStruct);
113+
114+
GPIO_HIGH(BT_RST_PORT, BT_RST_PIN); // assert BTLE reset
115+
116+
117+
/* -- Bootloader will be called if position 10 on the extension port
118+
is actively pulled low -- */
119+
// Note - this is an arbitrary choice, code could be modified to
120+
// monitor another GPIO of the STM32 and/or decide that active level
121+
// is high rather than low
122+
123+
124+
// Initialize Extension Port Position 10 = PB8 (bears I2C1_SCL)
125+
// Use weak pull-up to detect if pin is externally pulled low
126+
127+
__GPIOB_CLK_ENABLE();
128+
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
129+
GPIO_InitStruct.Pull = GPIO_PULLUP;
130+
GPIO_InitStruct.Pin = CONN_POS10_PIN;
131+
HAL_GPIO_Init(CONN_POS10_PORT, &GPIO_InitStruct);
132+
133+
// If selection pin pulled low...
134+
if ( IS_GPIO_RESET(CONN_POS10_PORT, CONN_POS10_PIN ))
135+
136+
{
137+
// Remap bootloader ROM (ie System Flash) to address 0x0
138+
SYSCFG->MEMRMP = 0x00000001;
139+
140+
// Init stack pointer with value residing at ROM base
141+
asm (
142+
"LDR R0, =0x00000000\n\t" // load ROM base address"
143+
"LDR SP,[R0, #0]\n\t" // assign main stack pointer"
144+
);
145+
146+
// Jump to address pointed by 0x00000004 -- */
147+
148+
asm (
149+
"LDR R0,[R0, #4]\n\t" // load bootloader address
150+
"BX R0\n\t"
151+
);
152+
153+
}
154+
}

stmhal/boards/LIMIFROG/mpconfigboard.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
#define MICROPY_HW_ENABLE_DAC (0)
1717
#define MICROPY_HW_ENABLE_CAN (0)
1818

19+
#define MICROPY_BOARD_EARLY_INIT LIMIFROG_board_early_init
20+
void LIMIFROG_board_early_init(void);
21+
1922
// MSI is used and is 4MHz
2023
#define MICROPY_HW_CLK_PLLM (1)
2124
#define MICROPY_HW_CLK_PLLN (40)

0 commit comments

Comments
 (0)