| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // The code is this file allows the user to enter DFU mode when the board
- // starts up, by connecting POS10 on the external connector to GND.
- // The code itself is taken from the LimiFrog software repository found at
- // https://github.com/LimiFrog/LimiFrog-SW, and the original license header
- // is copied below.
- #include STM32_HAL_H
- static void LBF_DFU_If_Needed(void);
- void LIMIFROG_board_early_init(void) {
- LBF_DFU_If_Needed();
- }
- /*******************************************************************************
- * LBF_DFU_If_Needed.c
- *
- * (c)2015 LimiFrog / CYMEYA
- * This program is licensed under the terms of the MIT License.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
- * Please refer to the License File LICENSE.txt located at the root of this
- * project for full licensing conditions,
- * or visit https://opensource.org/licenses/MIT.
- ******************************************************************************/
- #define __LIMIFROG_02
- /* ==== BTLE (excl UART) ======================================== */
- // PC9 = BT_RST (active high)
- #define BT_RST_PIN GPIO_PIN_9
- #define BT_RST_PORT GPIOC
- // Position 10
- #ifdef __LIMIFROG_01
- #define CONN_POS10_PIN GPIO_PIN_9
- #define CONN_POS10_PORT GPIOB
- #else
- #define CONN_POS10_PIN GPIO_PIN_8
- #define CONN_POS10_PORT GPIOB
- #endif
- static inline void GPIO_HIGH(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
- {
- GPIOx->BSRR = (uint32_t)GPIO_Pin;
- }
- static inline int IS_GPIO_RESET(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
- {
- GPIO_PinState bitstatus;
- if((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
- {
- bitstatus = GPIO_PIN_SET;
- }
- else
- {
- bitstatus = GPIO_PIN_RESET;
- }
- return (bitstatus==GPIO_PIN_RESET);
- }
- /**************************************************************
- RATIONALE FOR THIS FUNCTION :
- - The STM32 embeds in ROM a bootloader that allows to
- obtain code and boot from a number of different interfaces,
- including USB in a mode called "DFU" (Device Frimware Update)
- [see AN3606 from ST for full details]
- This bootloader code is executed instead of the regular
- application code when pin BOOT0 is pulled-up (which on
- LimiFrog0.2 is achieved by pressing the general-purpose
- pushbutton switch on the side.
- - The bootloader monitors a number of IOs of the STM32 to decide
- from which interface it should boot.
- - Problem in LimiFrog (up to versions 0.2a at least): upon
- power-up the BLE modules generates some activity on UART3,
- which is part of the pins monitored by the STM32.
- This misleads the bootloader in trying to boot from UART3
- and, as a result, not continuing with booting from USB.
- - This code implements an alternative solution to launch the
- bootloader while making sure UART3 remains stable.
- - The idea it to start application code with a check, prior to any
- other applicative code, of whether USB bootload is required (as
- flagged by a GPIO pulled low at reset, in the same way as BOOT0).
- The hadware reset pin of BLE is asserted (so that now it won't
- generate any acitivity on UART3), and if USB bootload is required :
- bootload ROM is remapped at address 0x0, stack pointer is
- updated and the code is branched to the start of the bootloader.
- - This code is run prior to any applicative configuration of clocks,
- IRQs etc. -- the STM32 is therefore still running from MSI
- THIS FUNCTION MAY BE SUPPRESSED IF YOU NEVER NEED TO BOOT DFU MODE
- ********************************************************************/
- static void LBF_DFU_If_Needed(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- // Initialize and assert pin BTLE_RST
- // (hw reset to BLE module, so it won't drive UART3)
- __HAL_RCC_GPIOC_CLK_ENABLE();
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- GPIO_InitStruct.Pin = BT_RST_PIN;
- HAL_GPIO_Init(BT_RST_PORT, &GPIO_InitStruct);
- GPIO_HIGH(BT_RST_PORT, BT_RST_PIN); // assert BTLE reset
- /* -- Bootloader will be called if position 10 on the extension port
- is actively pulled low -- */
- // Note - this is an arbitrary choice, code could be modified to
- // monitor another GPIO of the STM32 and/or decide that active level
- // is high rather than low
- // Initialize Extension Port Position 10 = PB8 (bears I2C1_SCL)
- // Use weak pull-up to detect if pin is externally pulled low
- __HAL_RCC_GPIOB_CLK_ENABLE();
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- GPIO_InitStruct.Pin = CONN_POS10_PIN;
- HAL_GPIO_Init(CONN_POS10_PORT, &GPIO_InitStruct);
- // If selection pin pulled low...
- if ( IS_GPIO_RESET(CONN_POS10_PORT, CONN_POS10_PIN ))
- {
- // Remap bootloader ROM (ie System Flash) to address 0x0
- SYSCFG->MEMRMP = 0x00000001;
- // Init stack pointer with value residing at ROM base
- asm (
- "LDR R0, =0x00000000\n\t" // load ROM base address"
- "LDR SP,[R0, #0]\n\t" // assign main stack pointer"
- );
- // Jump to address pointed by 0x00000004 -- */
- asm (
- "LDR R0,[R0, #4]\n\t" // load bootloader address
- "BX R0\n\t"
- );
- }
- }
|