Bootloader fixes and updates
- Add canary value for bootloader entry - Fix initial GPIO config for this application
This commit is contained in:
parent
60bd8d88b7
commit
00e0dcecf3
|
@ -26,7 +26,7 @@
|
|||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.1731985094" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
|
||||
<builder buildPath="${workspace_loc:/HK32F030}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.2105898051" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
|
||||
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.1554269278" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
|
||||
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.1585453989" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.value.g3" valueType="enumerated"/>
|
||||
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.1585453989" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.value.g" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols.1865848605" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="HK32F030MF4P6"/>
|
||||
<listOptionValue builtIn="false" value="DEBUG"/>
|
||||
|
@ -34,7 +34,7 @@
|
|||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.442647076" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.1307943124" name="MCU GCC Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler">
|
||||
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.275567753" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.value.g3" valueType="enumerated"/>
|
||||
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.275567753" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.value.g" valueType="enumerated"/>
|
||||
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.107146637" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.value.os" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths.1426651896" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="../code/Inc"/>
|
||||
|
@ -67,6 +67,7 @@
|
|||
<listOptionValue builtIn="false" value="-Wl,--print-memory-usage "/>
|
||||
<listOptionValue builtIn="false" value="-flto"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.additionalobjs.1911493690" name="Additional object files" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.additionalobjs" useByScannerDiscovery="false" valueType="userObjs"/>
|
||||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input.126424436" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
@ -125,20 +126,23 @@
|
|||
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.1732678459" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.value.g0" valueType="enumerated"/>
|
||||
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.255812759" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.value.os" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths.1226273585" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="../Core/Inc"/>
|
||||
<listOptionValue builtIn="false" value="../Driver"/>
|
||||
<listOptionValue builtIn="false" value="../Driver/CMSIS"/>
|
||||
<listOptionValue builtIn="false" value="../Driver/CMSIS/CM0"/>
|
||||
<listOptionValue builtIn="false" value="../Driver/CMSIS/CM0/Core"/>
|
||||
<listOptionValue builtIn="false" value="../Driver/CMSIS/HK32F030M"/>
|
||||
<listOptionValue builtIn="false" value="../Driver/CMSIS/HK32F030M/Include"/>
|
||||
<listOptionValue builtIn="false" value="../Driver/HK32F030M_Driver"/>
|
||||
<listOptionValue builtIn="false" value="../Driver/HK32F030M_Driver/inc"/>
|
||||
<listOptionValue builtIn="false" value="../Driver/Debug"/>
|
||||
<listOptionValue builtIn="false" value="../code/inc"/>
|
||||
<listOptionValue builtIn="false" value="../driver"/>
|
||||
<listOptionValue builtIn="false" value="../driver/CMSIS"/>
|
||||
<listOptionValue builtIn="false" value="../driver/CMSIS/CM0"/>
|
||||
<listOptionValue builtIn="false" value="../driver/CMSIS/CM0/Core"/>
|
||||
<listOptionValue builtIn="false" value="../driver/CMSIS/HK32F030M"/>
|
||||
<listOptionValue builtIn="false" value="../driver/CMSIS/HK32F030M/Include"/>
|
||||
<listOptionValue builtIn="false" value="../driver/HK32F030M_Driver"/>
|
||||
<listOptionValue builtIn="false" value="../driver/HK32F030M_Driver/inc"/>
|
||||
<listOptionValue builtIn="false" value="../driver/Debug"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols.961335129" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="HK32F030MF4P6"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.otherflags.1089769918" name="Other flags" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.otherflags" useByScannerDiscovery="true" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="-flto"/>
|
||||
</option>
|
||||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.2142076333" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
|
||||
</tool>
|
||||
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.658452460" name="MCU G++ Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler">
|
||||
|
@ -147,6 +151,9 @@
|
|||
</tool>
|
||||
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.1697196118" name="MCU GCC Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker">
|
||||
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script.1268634419" name="Linker Script (-T)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.script" value="../hk32f030mf4p6.ld" valueType="string"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.otherflags.1190913368" name="Other flags" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.option.otherflags" useByScannerDiscovery="false" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="-flto"/>
|
||||
</option>
|
||||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input.14629567" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-1638107307847132480" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-654819543574176800" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
|
@ -16,7 +16,7 @@
|
|||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-1732493928911893298" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-654819543574176800" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
|
|
|
@ -33,8 +33,13 @@ typedef enum {
|
|||
|
||||
|
||||
|
||||
extern uint32_t bootcheck;
|
||||
|
||||
|
||||
|
||||
BL_flash_status flash_erase_page(uint32_t addr);
|
||||
BL_flash_status flash_write(uint32_t addr, uint8_t *data, uint16_t length);
|
||||
|
||||
void jump_to_user_app();
|
||||
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
//#include "hk32f030m_i2c.h"
|
||||
//#include "hk32f030m_iwdg.h"
|
||||
#include "hk32f030m_pwr.h"
|
||||
//#include "hk32f030m_spi.h"
|
||||
#include "hk32f030m_spi.h"
|
||||
//#include "hk32f030m_tim.h"
|
||||
#include "hk32f030m_usart.h"
|
||||
//#include "hk32f030m_iwdg.h"
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* sk_led.h
|
||||
*
|
||||
* Created on: Jul 17, 2023
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
#ifndef CODE_INC_LED_SK_H_
|
||||
#define CODE_INC_LED_SK_H_
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hk32f030m.h"
|
||||
|
||||
|
||||
|
||||
#define SK6X_PORT GPIOD
|
||||
#define SK6X_PIN (1 << 4)
|
||||
|
||||
#define SK6X_LED_COUNT 5
|
||||
|
||||
|
||||
|
||||
#ifdef USE_SK_LEDS
|
||||
|
||||
void led_init();
|
||||
|
||||
void led_set(uint8_t idx, uint8_t r, uint8_t g, uint8_t b);
|
||||
void led_set_all(uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
void led_tx();
|
||||
|
||||
#else
|
||||
|
||||
#define led_init()
|
||||
|
||||
#define led_set(i, r, g, b)
|
||||
#define led_set_all(r, g, b)
|
||||
|
||||
#define led_tx()
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* CODE_INC_LED_SK_H_ */
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
|
||||
void user_io_init();
|
||||
void user_led_init();
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -64,12 +64,13 @@
|
|||
|
||||
/* Status report for the functions. */
|
||||
typedef enum {
|
||||
X_OK = 0x00u, /**< The action was successful. */
|
||||
X_ERROR_CRC = 0x01u, /**< CRC calculation error. */
|
||||
X_ERROR_NUMBER = 0x02u, /**< Packet number mismatch error. */
|
||||
X_ERROR_UART = 0x04u, /**< UART communication error. */
|
||||
X_ERROR_FLASH = 0x08u, /**< Flash related error. */
|
||||
X_ERROR = 0xFFu /**< Generic error. */
|
||||
X_OK = 0x00u, /**< The action was successful. */
|
||||
X_ERROR_CRC = 0x01u, /**< CRC calculation error. */
|
||||
X_ERROR_NUMBER = 0x02u, /**< Packet number mismatch error. */
|
||||
X_ERROR_UART = 0x04u, /**< UART communication error. */
|
||||
X_ERROR_FLASH = 0x08u, /**< Flash related error. */
|
||||
X_TIMEOUT = 0xfe,
|
||||
X_ERROR = 0xFFu /**< Generic error. */
|
||||
} BL_xmodem_status;
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "hk32f030m.h"
|
||||
#include "flash.h"
|
||||
|
||||
#include "led_sk.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -42,6 +44,10 @@ __attribute__ ((long_call, section(".ramfunc"))) BL_flash_status flash_write(uin
|
|||
|
||||
FLASH_Unlock();
|
||||
|
||||
// note: using the halfword programming method instead of the byte method
|
||||
// uses approximately 20 more bytes of program space, and might only
|
||||
// be slightly faster.
|
||||
|
||||
/* Loop through the data. */
|
||||
for (uint32_t i = 0u; (i < length) && (status == FLASH_OK); i++) {
|
||||
if (addr >= USER_APP_END_ADDR) {
|
||||
|
@ -72,39 +78,28 @@ void jump_to_user_app()
|
|||
{
|
||||
void (*user_app)(void);
|
||||
|
||||
// stop systick interrupt; reset to defaults
|
||||
SysTick->CTRL = 0;
|
||||
SysTick->LOAD = 0xffffff;
|
||||
SysTick->VAL = 0xffffff;
|
||||
// check reset key to know what to do
|
||||
if (bootcheck == 0x1337b007) {
|
||||
// configure jump location
|
||||
user_app = (void (*)(void))(*(volatile uint32_t *)(USER_APP_START_ADDR + 4));
|
||||
|
||||
// stop USART; reset to defaults
|
||||
USART1->CR1 = 0;
|
||||
USART1->CR1 = 0;
|
||||
USART1->BRR = 0;
|
||||
// configure stack pointer
|
||||
__set_MSP(*(volatile uint32_t*)USER_APP_START_ADDR);
|
||||
|
||||
// configure GPIO back to default
|
||||
GPIOA->PUPDR = (uint32_t)0xffff; // although marked as reserved, it is the default per datasheet
|
||||
GPIOA->MODER = (uint32_t)0xffff;
|
||||
GPIOB->MODER = (uint32_t)0xfbff;
|
||||
GPIOD->MODER = (uint32_t)0xfbff;
|
||||
// configure interrupt vector table
|
||||
// SCB->VTOR = USER_APP_START_ADDR;
|
||||
|
||||
// disable configured interrupts
|
||||
// NVIC->ICER[0] = 0;
|
||||
// cortex m0 doesn't have VTOR to remap vector table.
|
||||
// to address this, HK MCU has a flash offset thing which
|
||||
// remaps 256 bytes specified by an offset, to to 0x08000000
|
||||
FLASH->INT_VEC_OFFSET = USER_APP_START_ADDR & 0x3ffc;
|
||||
|
||||
// configure jump location
|
||||
user_app = (void (*)(void))(*(volatile uint32_t *)(USER_APP_START_ADDR + 4));
|
||||
|
||||
// configure stack pointer
|
||||
__set_MSP(*(volatile uint32_t*)USER_APP_START_ADDR);
|
||||
|
||||
// configure interrupt vector table
|
||||
// SCB->VTOR = USER_APP_START_ADDR;
|
||||
|
||||
// cortex m0 doesn't have VTOR to remap vector table.
|
||||
// to address this, HK MCU has a flash offset thing which
|
||||
// remaps 256 bytes specified by an offset, to to 0x08000000
|
||||
FLASH->INT_VEC_OFFSET = USER_APP_START_ADDR & 0x3ffc;
|
||||
|
||||
// let's do this
|
||||
user_app();
|
||||
// let's do this
|
||||
user_app();
|
||||
} else {
|
||||
// we want the MCU to be at default settings
|
||||
// so set our flag, then reboot
|
||||
bootcheck = 0x1337b007;
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,13 +120,8 @@ __attribute__ ((long_call, section(".ramfunc"))) void SysTick_Handler(void)
|
|||
|
||||
led ^= 1;
|
||||
|
||||
#if LED_ACT_DIR == 0
|
||||
if (led) LED_PORT->BRR = (1 << LED_PIN);
|
||||
else LED_PORT->BSRR = (1 << LED_PIN);
|
||||
#else
|
||||
if (led) LED_PORT->BSRR = (1 << LED_PIN);
|
||||
else LED_PORT->BRR = (1 << LED_PIN);
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* sk_led.c
|
||||
*
|
||||
* Created on: July 17, 2023
|
||||
* Author: true
|
||||
*
|
||||
* communicates with SK68xx LEDs using bitbang.
|
||||
*
|
||||
* not yet implemented.
|
||||
*/
|
||||
|
||||
|
||||
#include <led_sk.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hk32f030m.h"
|
||||
|
||||
|
||||
|
||||
#define SPI_TX_PORT GPIOD
|
||||
#define SPI_MOSI_PINSRC GPIO_PinSource2
|
||||
#define SK_SET() SK6X_PORT->BSRR = SK6X_PIN;
|
||||
#define SK_CLR() SK6X_PORT->BRR = SK6X_PIN;
|
||||
|
||||
#define SK_SEND_BIT1() __NOP(); __NOP(); SK_CLR(); __NOP();
|
||||
#define SK_SEND_BIT0() SK_CLR(); __NOP(); __NOP(); __NOP();
|
||||
|
||||
|
||||
|
||||
uint8_t sk6x_led[SK6X_LED_COUNT][3] = {0}; // G-R-B order
|
||||
|
||||
const uint8_t adxl_cmds[] = {0x80, 0x80, 0x80};
|
||||
|
||||
|
||||
|
||||
#ifdef USE_SK_LEDS
|
||||
|
||||
void led_init()
|
||||
{
|
||||
uint8_t idx;
|
||||
|
||||
// enable SPI with appropriate settings to talk to ADXL
|
||||
GPIO_PinAFConfig(SPI_TX_PORT, SPI_MOSI_PINSRC, GPIO_AF_2);
|
||||
|
||||
// disable ADXL interrupts, configure INT1 pin active low (so idle high)
|
||||
volatile uint8_t *spi_dr = (volatile uint8_t *)((uint32_t)SPI1 + 0x0c);
|
||||
|
||||
// transfer all of our data
|
||||
idx = 0;
|
||||
while (idx < sizeof(adxl_cmds)) {
|
||||
// transmit FIFO has space? if so, send byte
|
||||
if ((SPI1->SR & SPI_SR_FTLVL) != SPI_SR_FTLVL) {
|
||||
*spi_dr = adxl_cmds[idx];
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void led_tx()
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t j;
|
||||
|
||||
uint8_t b;
|
||||
uint8_t *p;
|
||||
|
||||
p = sk6x_led[0];
|
||||
|
||||
for (i = 0; i < SK6X_LED_COUNT; i++) {
|
||||
b = *p;
|
||||
p++;
|
||||
|
||||
j = 0x100;
|
||||
|
||||
do {
|
||||
j >>= 1;
|
||||
SK_SET();
|
||||
if (!(b & j)) { SK_SEND_BIT0(); } else { SK_SEND_BIT1(); }
|
||||
} while (j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void led_set(uint8_t idx, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
sk6x_led[idx][0] = g;
|
||||
sk6x_led[idx][1] = r;
|
||||
sk6x_led[idx][2] = b;
|
||||
}
|
||||
|
||||
void led_set_all(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < SK6X_LED_COUNT; i++) {
|
||||
led_set(i, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -20,15 +20,90 @@
|
|||
|
||||
|
||||
|
||||
__attribute__((section(".noinit"))) uint32_t bootcheck;
|
||||
|
||||
|
||||
void welcome_banner()
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
comm_tx_str("\r\n\r\n");
|
||||
|
||||
for (i = 0; i < 31; i++) {
|
||||
comm_tx_byte('=');
|
||||
}
|
||||
|
||||
comm_tx_str("\r\ntrueControl HK32F Loader v0.0.3\r\n");
|
||||
|
||||
for (i = 0; i < 31; i++) {
|
||||
comm_tx_byte('=');
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t x;
|
||||
uint32_t btn;
|
||||
uint8_t flash_empty = 0;
|
||||
|
||||
// ensure the bootloader is write protected
|
||||
// TODO
|
||||
x = *(volatile uint32_t *)USER_APP_START_ADDR; // first byte of user flash
|
||||
if ((x == 0x00000000) || (x == 0xffffffff)) {
|
||||
flash_empty = 1;
|
||||
}
|
||||
|
||||
// configure button and LED
|
||||
// if we software reset, but have contents in flash
|
||||
if (!flash_empty && (RCC->CSR & RCC_CSR_SFTRSTF)) {
|
||||
// and have the bootload done key loaded,
|
||||
if (bootcheck == 0x1337b007) {
|
||||
// then forego all of this shit and jump to the user app
|
||||
jump_to_user_app();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// set with a debugger to enable this codepath (testing)
|
||||
volatile uint8_t do_this = 0;
|
||||
// make sure bootloader is write protected before we write anything to main flash
|
||||
const uint8_t pages = (uint8_t)(OB_WRP_Pages0to3 | OB_WRP_Pages4to7);
|
||||
uint8_t pagecheck = (uint8_t)(~FLASH_OB_GetWRP());
|
||||
if (do_this && (pagecheck & pages) != pages) {
|
||||
uint32_t flash_cr;
|
||||
uint16_t wrp0;
|
||||
uint32_t wrp_addr = FLASH_OB_WRP_ADDRESS;
|
||||
uint16_t i;
|
||||
|
||||
wrp0 = (uint16_t)((pages << 8) | (~pages & 0xff));
|
||||
|
||||
FLASH_Unlock();
|
||||
FLASH_OB_Unlock();
|
||||
flash_cr = FLASH->CR;
|
||||
|
||||
for(i = 0; i < 2; i++) {
|
||||
FLASH->CR = flash_cr | FLASH_CR_OPTER;
|
||||
FLASH->AR = wrp_addr;
|
||||
FLASH->CR = flash_cr | FLASH_CR_OPTER | FLASH_CR_STRT;
|
||||
|
||||
FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
|
||||
|
||||
wrp_addr++;
|
||||
}
|
||||
|
||||
FLASH->CR = flash_cr | FLASH_CR_OPTPG;
|
||||
OB->WRP0 = wrp0;
|
||||
FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);
|
||||
|
||||
FLASH->CR = flash_cr;
|
||||
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
*/
|
||||
|
||||
// start clocks used by peripherals
|
||||
RCC->AHBENR = RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | \
|
||||
RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD;
|
||||
RCC->APB2ENR = RCC_APB2Periph_USART1;
|
||||
|
||||
// set up user IO
|
||||
user_io_init();
|
||||
|
||||
// get button state
|
||||
|
@ -38,41 +113,39 @@ int main(void)
|
|||
#endif
|
||||
|
||||
// bootloader activation methods
|
||||
i = *(volatile uint32_t *)USER_APP_START_ADDR; // first byte of user flash
|
||||
if (btn || (i == 0x00000000) || (i = 0xffffffff)) { // is button pushed, or flash empty?
|
||||
// bootloader is activated; configure systick to flash LED
|
||||
user_led_init();
|
||||
|
||||
// configure serial comms and print welcome banner
|
||||
// todo: implement autobaud?
|
||||
if (btn || flash_empty) { // is button pushed, or flash empty or null?
|
||||
// bootloader is activated
|
||||
// this is where you can can blink an LED... at least
|
||||
// when you don't fuck up your circuit so the LED doesn't work
|
||||
// in our case we start up systick to do the blinker for us
|
||||
SysTick_Config(8000000 / 20);
|
||||
|
||||
// configure serial comms
|
||||
comm_init();
|
||||
|
||||
comm_tx_byte('\r');
|
||||
comm_tx_byte('\n');
|
||||
|
||||
for (i = 0; i < 31; i++) {
|
||||
comm_tx_byte('=');
|
||||
}
|
||||
|
||||
comm_tx_str("\r\ntrueControl HK32F Loader v0.0.2\r\n");
|
||||
|
||||
for (i = 0; i < 31; i++) {
|
||||
comm_tx_byte('=');
|
||||
}
|
||||
welcome_banner();
|
||||
|
||||
// wait for firmware load or reset
|
||||
while(1) {
|
||||
while (1) {
|
||||
// announce bootloader start
|
||||
comm_tx_str("\r\n\r\nsend firmware file using XMODEM\r\n\r\n");
|
||||
comm_tx_str("\r\n\r\nsend firm.bin file using XMODEM\r\n\r\n");
|
||||
|
||||
// start listening for data and letting user know to send XMODEM data
|
||||
if (xmodem_receive() == X_OK) {
|
||||
comm_tx_str("\r\nflash updated; booting.\r\n\r\n");
|
||||
x = xmodem_receive();
|
||||
|
||||
if (x == X_OK) {
|
||||
comm_tx_str("\r\nfw updated; starting...\r\n\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// if xmodem exits, there was a failure. repeat the process.
|
||||
comm_tx_str("\r\nfailed to update; try again.\r\n");
|
||||
// if we've spammed enough, then reboot so the banner is shown again
|
||||
if (x == X_TIMEOUT) {
|
||||
welcome_banner();
|
||||
} else {
|
||||
// if xmodem_receive exits, there was a failure. repeat the process.
|
||||
comm_tx_str("\r\nfailed to update. try again.\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,9 +44,11 @@ void comm_init()
|
|||
// enable GPIO clock
|
||||
// RCC_AHBPeriphClockCmd(USART_TX_GPIO_CLK | USART_RX_GPIO_CLK, ENABLE);
|
||||
|
||||
// configure USART GPIO
|
||||
GPIO_PinAFConfig(USART_TX_PORT, USART_TX_PINSRC, GPIO_AF_1);
|
||||
GPIO_PinAFConfig(USART_RX_PORT, USART_RX_PINSRC, GPIO_AF_1);
|
||||
// attach USART peripheral to pins
|
||||
// GPIO_PinAFConfig(USART_TX_PORT, USART_TX_PINSRC, GPIO_AF_1);
|
||||
// GPIO_PinAFConfig(USART_RX_PORT, USART_RX_PINSRC, GPIO_AF_1);
|
||||
GPIOB->AFR[0] = 0x00010000;
|
||||
GPIOD->AFR[0] = 0x00000010;
|
||||
|
||||
/* these have been configured in user_io.c to save space
|
||||
USART_RX_PORT->MODER &= ~(GPIO_MODER_MODER0 << 2 * USART_RX_PIN);
|
||||
|
@ -59,18 +61,18 @@ void comm_init()
|
|||
*/
|
||||
|
||||
// enable USART clock
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
|
||||
// configure USART peripheral manually
|
||||
// we do this as the library bloats flash space (division, verbose, ...)
|
||||
USART1->CR1 = 0; // disable USART
|
||||
USART1->CR1 = USART_Mode_Rx | USART_Mode_Tx; // 8 bits, no parity, tx/rx enabled
|
||||
USART1->CR2 = 0; // 1 stop bit
|
||||
USART1->CR3 = 0;
|
||||
USART1->CR1 = USART_Mode_Rx | USART_Mode_Tx; // 8 bits, no parity, tx/rx enabled
|
||||
USART1->BRR = 0x45; // 115200 baud rate @8MHz (per datasheet)
|
||||
|
||||
// enable USART
|
||||
USART1->CR1 |= USART_CR1_UE;
|
||||
USART1->CR1 = USART_Mode_Rx | USART_Mode_Tx | USART_CR1_UE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,15 +88,15 @@ BL_comm_status comm_rx(uint8_t *data, uint16_t length)
|
|||
|
||||
for (i = 0; i < length; i++) {
|
||||
timeout = COMM_TIMEOUT;
|
||||
while (!(USART1->ISR & USART_ISR_RXNE_Msk) && timeout) {
|
||||
while (!(USART1->ISR & USART_ISR_RXNE) && timeout) {
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
// there is new data waiting for us
|
||||
// we didn't time out and now there is new data waiting for us
|
||||
data[i] = USART1->RDR;
|
||||
} else {
|
||||
// there is no data returned in time
|
||||
// no data returned in time
|
||||
return COMM_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +113,7 @@ BL_comm_status comm_tx_byte(uint8_t data)
|
|||
{
|
||||
USART_SendData(USART1, data);
|
||||
|
||||
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
|
||||
while (!(USART1->ISR & USART_ISR_TXE));
|
||||
|
||||
return COMM_OK;
|
||||
}
|
||||
|
@ -132,7 +134,7 @@ BL_comm_status comm_tx_str(char *data)
|
|||
comm_tx_byte(data[i]);
|
||||
}
|
||||
|
||||
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
|
||||
while (!(USART1->ISR & USART_ISR_TC));
|
||||
|
||||
return COMM_OK;
|
||||
}
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
|
||||
void user_io_init()
|
||||
{
|
||||
// enable gpio clocks
|
||||
RCC_AHBPeriphClockCmd(BTN_CLK | LED_CLK | RCC_AHBPeriph_GPIOB, ENABLE);
|
||||
|
||||
/* --original method, not space efficient
|
||||
// enable gpio clocks
|
||||
// RCC_AHBPeriphClockCmd(BTN_CLK | LED_CLK | RCC_AHBPeriph_GPIOB, ENABLE);
|
||||
|
||||
// configure led
|
||||
#if LED_ACT_DIR == 0
|
||||
LED_PORT->BSRR = (1 << LED_PIN); // idle high
|
||||
|
@ -59,16 +59,15 @@ void user_io_init()
|
|||
|
||||
// configure LED as PP output, USART TX as AF
|
||||
LED_PORT->OTYPER = 0;
|
||||
LED_PORT->OSPEEDR = 0;
|
||||
LED_PORT->MODER = 0x800 | (GPIO_Mode_OUT << (2 * LED_PIN)) | (GPIO_Mode_AF << (2 * 1));
|
||||
LED_PORT->ODR = 0;
|
||||
LED_PORT->MODER = 0x800
|
||||
| (GPIO_Mode_OUT << (2 * 7))
|
||||
| (GPIO_Mode_AF << (2 * 1));
|
||||
|
||||
// configure I2C SCK as low PP output
|
||||
GPIOC->ODR = 0;
|
||||
GPIOC->MODER = (GPIO_Mode_OUT << (2 * 6));
|
||||
|
||||
// configure USART RX as AF
|
||||
GPIOB->MODER = 0x800 | (GPIO_Mode_AF << (2 * 4));
|
||||
GPIOB->MODER = 0x800 | (GPIO_Mode_AF << (2 * 4));
|
||||
}
|
||||
|
||||
void user_led_init()
|
||||
{
|
||||
// led blinking timer; set LED flash rate here
|
||||
SysTick_Config(8000000 / 20);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
|
||||
|
||||
/* Global variables. */
|
||||
static uint8_t xmodem_packet_number = 1u; /**< Packet number counter. */
|
||||
static uint32_t xmodem_flash_w_addr = 0u; /**< Address where we have to write. */
|
||||
static uint8_t x_first_packet_rcvd = 0; /**< First packet or not. */
|
||||
static uint8_t xmodem_packet_number; /**< Packet number counter. */
|
||||
static uint32_t xmodem_flash_w_addr; /**< Address where we have to write. */
|
||||
static uint8_t x_first_packet_rcvd; /**< First packet or not. */
|
||||
|
||||
|
||||
/* Local functions. */
|
||||
static uint16_t xmodem_calc_crc(uint8_t *data, uint16_t length);
|
||||
|
@ -43,6 +44,8 @@ BL_xmodem_status xmodem_receive(void)
|
|||
xmodem_packet_number = 1u;
|
||||
xmodem_flash_w_addr = USER_APP_START_ADDR;
|
||||
|
||||
uint8_t x_c_sent = 0;
|
||||
|
||||
/* Loop until there isn't any error (or until we jump to the user application). */
|
||||
while (status == X_OK) {
|
||||
uint8_t header = 0x00u;
|
||||
|
@ -52,6 +55,13 @@ BL_xmodem_status xmodem_receive(void)
|
|||
|
||||
/* Spam the host (until we receive something) with ACSII "C", to notify it, we want to use CRC-16. */
|
||||
if ((status_c != COMM_OK) && (x_first_packet_rcvd == 0)) {
|
||||
// return with timeout if we've tried too many times
|
||||
// this is so main can repeat our banner
|
||||
x_c_sent++;
|
||||
if (x_c_sent >= 240) {
|
||||
return X_TIMEOUT;
|
||||
}
|
||||
|
||||
comm_tx_byte(X_C);
|
||||
}
|
||||
|
||||
|
@ -101,8 +111,7 @@ BL_xmodem_status xmodem_receive(void)
|
|||
|
||||
/* Abort from host. */
|
||||
case X_CAN: {
|
||||
status = X_ERROR;
|
||||
break;
|
||||
return X_ERROR;
|
||||
}
|
||||
|
||||
/* Wrong header. */
|
||||
|
|
|
@ -121,47 +121,49 @@ void SystemInit(void)
|
|||
*/
|
||||
static void SetSysClock(void)
|
||||
{
|
||||
/*reload the hsi trimming value to the bit3~bit13 of RCC_CR register */
|
||||
uint32_t u32HSIFLASH = 0;
|
||||
uint32_t u32RCC_CR = 0;
|
||||
uint32_t u32HSITemp = 0;
|
||||
uint16_t u16HSITempH = 0;
|
||||
uint16_t u16HSITempL = 0;
|
||||
|
||||
u32HSIFLASH = *(uint32_t *) 0x1FFFF820;
|
||||
u16HSITempH = (uint16_t)(u32HSIFLASH>>16);
|
||||
u16HSITempL = (uint16_t)(u32HSIFLASH);
|
||||
|
||||
if(!(u16HSITempH & u16HSITempL))
|
||||
{
|
||||
u32HSITemp = RCC->CR;
|
||||
u32HSITemp &= (uint32_t)((uint32_t)~(RCC_CR_HSITRIM|RCC_CR_HSICAL));
|
||||
u32RCC_CR = (uint32_t)(((u16HSITempL & 0x001F) <<3) | (((u16HSITempL>>5) & 0x003F)<<8));
|
||||
RCC->CR |= u32RCC_CR;
|
||||
}
|
||||
/*end*/
|
||||
#if(SYSCLK_SOURCE==SYSCLK_SRC_HSI8M)
|
||||
// reload the HSI trimming value to bits 3~13 of RCC_CR register
|
||||
// note: cannot find documentation for the actual values of this register
|
||||
// but upon looking it appears to be inverted nybbles
|
||||
// no idea what the high 5 bits are for...
|
||||
uint32_t u32HSIFLASH = 0;
|
||||
uint32_t u32HSITemp = 0;
|
||||
uint16_t u16HSITempH = 0;
|
||||
uint16_t u16HSITempL = 0;
|
||||
|
||||
u32HSIFLASH = *(uint32_t *)0x1FFFF820;
|
||||
u16HSITempH = (uint16_t)(u32HSIFLASH >> 16);
|
||||
u16HSITempL = (uint16_t)(u32HSIFLASH);
|
||||
|
||||
if((u16HSITempH ^ u16HSITempL) == 0xffff) {
|
||||
// valid constants found; load to registers
|
||||
u32HSITemp = RCC->CR & ~(RCC_CR_HSITRIM | RCC_CR_HSICAL);
|
||||
u32HSITemp |= (uint32_t)(
|
||||
((u16HSITempL & 0x001F) << 3) | // HSITRIM (RCC_CR[7:3], 5 bits)
|
||||
(((u16HSITempL) & 0x07e0) << 3)); // HSICAL (RCC_RC[13:8], 6 bits)
|
||||
RCC->CR = u32HSITemp;
|
||||
}
|
||||
|
||||
// set system clock
|
||||
#if (SYSCLK_SOURCE == SYSCLK_SRC_HSI8M)
|
||||
SetSysClockToHSI();
|
||||
#elif(SYSCLK_SOURCE == SYSCLK_SRC_HSI16M)
|
||||
#elif (SYSCLK_SOURCE == SYSCLK_SRC_HSI16M)
|
||||
SetSysClockToHSI();
|
||||
#elif(SYSCLK_SOURCE == SYSCLK_SRC_HSI32M)
|
||||
#elif (SYSCLK_SOURCE == SYSCLK_SRC_HSI32M)
|
||||
SetSysClockToHSI();
|
||||
#elif(SYSCLK_SOURCE == SYSCLK_SRC_LSI)
|
||||
#elif (SYSCLK_SOURCE == SYSCLK_SRC_LSI)
|
||||
SetSysClockToLSI();
|
||||
#elif(SYSCLK_SOURCE == SYSCLK_SCR_EXTCLK_IO)
|
||||
#elif (SYSCLK_SOURCE == SYSCLK_SCR_EXTCLK_IO)
|
||||
SetSysClockToEXTCLK();
|
||||
#endif
|
||||
|
||||
/* If none of the define above is enabled, the HSI is used as System clock source (default after reset) */
|
||||
// If none of the define above is enabled, the HSI is used as System clock source (default after reset)
|
||||
}
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSI
|
||||
static void SetSysClockToHSI(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSIStatus = 0;
|
||||
__IO uint32_t ACRreg = 0;
|
||||
__IO uint32_t RCCHCLKReg = 0;
|
||||
__IO uint32_t RCCPCLKReg = 0;
|
||||
uint32_t work;
|
||||
|
||||
/* Enable HSI */
|
||||
RCC->CR |= RCC_CR_HSION;
|
||||
|
@ -179,26 +181,14 @@ static void SetSysClockToHSI(void)
|
|||
} while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CR & RCC_CR_HSIRDY) != RESET) {
|
||||
HSIStatus = (uint32_t)0x01;
|
||||
} else {
|
||||
HSIStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSIStatus == (uint32_t)0x01) {
|
||||
/* Flash wait state */
|
||||
ACRreg = FLASH->ACR;
|
||||
ACRreg &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
|
||||
FLASH->ACR = (uint32_t)(SET_FLASH_LATENCY | ACRreg);
|
||||
FLASH->ACR = SET_FLASH_LATENCY;
|
||||
|
||||
/* HCLK = configured divided value from SYSCLK (which will later be set to HSI32M) */
|
||||
RCCHCLKReg = RCC->CFGR;
|
||||
RCCHCLKReg &= (uint32_t)((uint32_t)~RCC_CFGR_HPRE_Msk);
|
||||
RCC->CFGR = (uint32_t)(SET_HPRE_DIV | RCCHCLKReg);
|
||||
|
||||
/* PCLK = HCLK */
|
||||
RCCPCLKReg = RCC->CFGR;
|
||||
RCCPCLKReg &= (uint32_t)((uint32_t)~RCC_CFGR_PPRE_Msk);
|
||||
RCC->CFGR = (uint32_t)(RCC_CFGR_PPRE_DIV1|RCCPCLKReg);
|
||||
work = RCC->CFGR;
|
||||
work &= (uint32_t)((uint32_t)~(RCC_CFGR_HPRE | RCC_CFGR_PPRE));
|
||||
RCC->CFGR = (uint32_t)(SET_HPRE_DIV | RCC_CFGR_PPRE_DIV1 | work);
|
||||
|
||||
/* Select HSI32M as system clock source */
|
||||
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
|
||||
|
@ -210,7 +200,7 @@ static void SetSysClockToHSI(void)
|
|||
/* If clock fails to start, the application will have wrong clock configuration.
|
||||
* User can add some code here to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif (SYSCLK_SOURCE == SYSCLK_SRC_LSI)
|
||||
|
|
|
@ -29,8 +29,9 @@ _Min_Stack_Size = 0x800; /* required amount of stack: 2048 bytes */
|
|||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 4K
|
||||
RAM (rwx) : ORIGIN = 0x20000004, LENGTH = 4K - 4
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K
|
||||
NOINIT (rwx) : ORIGIN = 0x20000000, LENGTH = 4
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
|
@ -100,6 +101,13 @@ SECTIONS
|
|||
|
||||
/* used by the startup to initialize data */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
/* Uninitialized, non-zeroed data */
|
||||
.noinit (NOLOAD):
|
||||
{
|
||||
/* place all symbols in input sections that start with .noinit */
|
||||
KEEP(*(*.noinit*))
|
||||
} > NOINIT
|
||||
|
||||
/* Initialized data sections goes into RAM, load LMA copy after code */
|
||||
.data :
|
||||
|
|
Loading…
Reference in New Issue