|
| 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 | +} |
0 commit comments