diff --git a/bootloader_hk32f030m_uart_xmodem/.cproject b/bootloader_hk32f030m_uart_xmodem/.cproject
index 4d7db8e..882a62b 100644
--- a/bootloader_hk32f030m_uart_xmodem/.cproject
+++ b/bootloader_hk32f030m_uart_xmodem/.cproject
@@ -26,7 +26,7 @@
-
+
-
+
+
@@ -125,20 +126,23 @@
+
@@ -147,6 +151,9 @@
+
diff --git a/bootloader_hk32f030m_uart_xmodem/.settings/language.settings.xml b/bootloader_hk32f030m_uart_xmodem/.settings/language.settings.xml
index ea8a9be..b89d454 100644
--- a/bootloader_hk32f030m_uart_xmodem/.settings/language.settings.xml
+++ b/bootloader_hk32f030m_uart_xmodem/.settings/language.settings.xml
@@ -5,7 +5,7 @@
-
+
@@ -16,7 +16,7 @@
-
+
diff --git a/bootloader_hk32f030m_uart_xmodem/code/inc/flash.h b/bootloader_hk32f030m_uart_xmodem/code/inc/flash.h
index 7c430ec..42d9cb3 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/inc/flash.h
+++ b/bootloader_hk32f030m_uart_xmodem/code/inc/flash.h
@@ -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();
diff --git a/bootloader_hk32f030m_uart_xmodem/code/inc/hk32f030m_conf.h b/bootloader_hk32f030m_uart_xmodem/code/inc/hk32f030m_conf.h
index 6cfdcb2..60e21cb 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/inc/hk32f030m_conf.h
+++ b/bootloader_hk32f030m_uart_xmodem/code/inc/hk32f030m_conf.h
@@ -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"
diff --git a/bootloader_hk32f030m_uart_xmodem/code/inc/led_sk.h b/bootloader_hk32f030m_uart_xmodem/code/inc/led_sk.h
new file mode 100644
index 0000000..18466f3
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/code/inc/led_sk.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
+#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_ */
diff --git a/bootloader_hk32f030m_uart_xmodem/code/inc/user_io.h b/bootloader_hk32f030m_uart_xmodem/code/inc/user_io.h
index 5808a18..01d9949 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/inc/user_io.h
+++ b/bootloader_hk32f030m_uart_xmodem/code/inc/user_io.h
@@ -28,7 +28,6 @@
void user_io_init();
-void user_led_init();
diff --git a/bootloader_hk32f030m_uart_xmodem/code/inc/xmodem.h b/bootloader_hk32f030m_uart_xmodem/code/inc/xmodem.h
index c9029c2..18546c7 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/inc/xmodem.h
+++ b/bootloader_hk32f030m_uart_xmodem/code/inc/xmodem.h
@@ -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;
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/flash.c b/bootloader_hk32f030m_uart_xmodem/code/src/flash.c
index e54b261..63107e0 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/src/flash.c
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/flash.c
@@ -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();
+ }
}
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/hk32f030m_it.c b/bootloader_hk32f030m_uart_xmodem/code/src/hk32f030m_it.c
index f5ce4d7..826320c 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/src/hk32f030m_it.c
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/hk32f030m_it.c
@@ -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
}
/******************************************************************************/
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/led_sk.c b/bootloader_hk32f030m_uart_xmodem/code/src/led_sk.c
new file mode 100644
index 0000000..9fab330
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/led_sk.c
@@ -0,0 +1,100 @@
+/*
+ * sk_led.c
+ *
+ * Created on: July 17, 2023
+ * Author: true
+ *
+ * communicates with SK68xx LEDs using bitbang.
+ *
+ * not yet implemented.
+ */
+
+
+#include
+#include
+
+#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
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/main.c b/bootloader_hk32f030m_uart_xmodem/code/src/main.c
index 4297186..2b5650d 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/src/main.c
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/main.c
@@ -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");
+ }
}
}
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/usart.c b/bootloader_hk32f030m_uart_xmodem/code/src/usart.c
index d47d0a3..dae9f4d 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/src/usart.c
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/usart.c
@@ -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;
}
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/user_io.c b/bootloader_hk32f030m_uart_xmodem/code/src/user_io.c
index d0f41f7..8df2568 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/src/user_io.c
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/user_io.c
@@ -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);
-}
-
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/xmodem.c b/bootloader_hk32f030m_uart_xmodem/code/src/xmodem.c
index 8c2143e..e3059f6 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/src/xmodem.c
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/xmodem.c
@@ -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. */
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/HK32F030M/Source/system_hk32f030m.c b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/HK32F030M/Source/system_hk32f030m.c
index 587273c..25ce14b 100644
--- a/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/HK32F030M/Source/system_hk32f030m.c
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/HK32F030M/Source/system_hk32f030m.c
@@ -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)
diff --git a/bootloader_hk32f030m_uart_xmodem/hk32f030mf4p6.ld b/bootloader_hk32f030m_uart_xmodem/hk32f030mf4p6.ld
index 19b05cc..eb8dc21 100644
--- a/bootloader_hk32f030m_uart_xmodem/hk32f030mf4p6.ld
+++ b/bootloader_hk32f030m_uart_xmodem/hk32f030mf4p6.ld
@@ -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 :