diff --git a/bootloader_hk32f030m_uart_xmodem/.cproject b/bootloader_hk32f030m_uart_xmodem/.cproject
index c45870e..4d7db8e 100644
--- a/bootloader_hk32f030m_uart_xmodem/.cproject
+++ b/bootloader_hk32f030m_uart_xmodem/.cproject
@@ -22,7 +22,7 @@
-
+
diff --git a/bootloader_hk32f030m_uart_xmodem/_bin/bootloader_hk32f030m_uart_xmodem_v0.0.2.bin b/bootloader_hk32f030m_uart_xmodem/_bin/bootloader_hk32f030m_uart_xmodem_v0.0.2.bin
new file mode 100644
index 0000000..5cd410c
Binary files /dev/null and b/bootloader_hk32f030m_uart_xmodem/_bin/bootloader_hk32f030m_uart_xmodem_v0.0.2.bin differ
diff --git a/bootloader_hk32f030m_uart_xmodem/_bin/bootloader_hk32f030m_uart_xmodem_v0.0.2.hex b/bootloader_hk32f030m_uart_xmodem/_bin/bootloader_hk32f030m_uart_xmodem_v0.0.2.hex
new file mode 100644
index 0000000..f78211f
--- /dev/null
+++ b/bootloader_hk32f030m_uart_xmodem/_bin/bootloader_hk32f030m_uart_xmodem_v0.0.2.hex
@@ -0,0 +1,134 @@
+:020000040800F2
+:100000000010002091060008E0060008E006000845
+:1000100000000000000000000000000000000000E0
+:10002000000000000000000000000000E0060008E2
+:100030000000000000000000E006000805000020AD
+:1000400010B5064C2378002B07D1054B002B02D0AE
+:10005000044800E000BF0123237010BD28000020E9
+:10006000000000002C070008044B10B5002B03D043
+:100070000349044800E000BF10BDC0460000000076
+:100080002C0000202C07000870B5002220250B4C06
+:1000900093B299420AD8002070BD013B9BB2E66939
+:1000A0002E4205D1002BF8D1FF20F5E7044BF6E7EF
+:1000B000002BF9D0636A83540132E9E7003801402C
+:1000C000FFFF0000044B1A69120603D5034A5A6069
+:1000D000034A5A607047C04600200240230167452A
+:1000E000AB89EFCD0120054BDA68024204D1DB6811
+:1000F0000018DB0600D402307047C04600200240E2
+:1001000010B5B024FFF7EEFF2403012807D1002C1F
+:1001100001D1043010BDFFF7E5FF013CF5E7002CED
+:10012000F8D10520F6E7F0B56B4CA544012826D0A0
+:10013000022827D00027FF24022105A8FFF7A4FFEB
+:100140003900050006A8FFF79FFF0221054304A818
+:10015000FFF79AFFEDB20543EBB29C4606AB1800E1
+:1001600000933A0000235D4D002A0ED16246002A1A
+:100170001DD004231C432000594B9D44F0BD802713
+:100180000024D9E78027FF00FAE70178013A090245
+:100190004B40082192B21EB25B009BB2002E00DAE7
+:1001A0006B400139C9B20029F5D10130DCE7002CE0
+:1001B00000D089E001204B4904AA08704A4804A9EC
+:1001C0000078097912880190814200D0023404A895
+:1001D000407952BA411892B20291FF2978D19A42DD
+:1001E00001D00123C6E70026B442C4D1B74218D8D3
+:1001F000002CC0D13B4B5D68FFF764FF7F19AF4215
+:1002000001D0002C37D08023384A11690B43136189
+:10021000002C5BD1019B344A01331370314B5F607A
+:10022000A9E7304B314D5B680393FFF74BFFFFF7B6
+:1002300067FF029B042815D102222B6913432B610F
+:10024000039B9B196B6140232A6913432B61FFF7C2
+:1002500057FF02222B6993432B61031F5A1E9341C0
+:100260005B42DBB2802229690A432A61002B00D05D
+:1002700008248036BAE71E4B9D4223D8009B1B788A
+:100280000293FFF73DFF04280CD00224009A2B783C
+:1002900012789A4201D004231C43009B013501339C
+:1002A0000093ACE70122114E336F13433367029B77
+:1002B0002B70FFF725FF0122336F93433367042828
+:1002C000E4D0E2E701249EE7FF2454E7082452E744
+:1002D00002249A4285D14EE7E4FBFFFF2110000083
+:1002E0001C04000044000020000000200020024008
+:1002F000FF3F00088022034B9862D9691142FCD06D
+:100300007047C0460038014010B503780133DBB2B6
+:100310000370022B07D91820FFF7ECFF1820FFF716
+:10032000E9FFFF2010BD1520FFF7E4FF0020F9E7EB
+:1003300070B5050000F09EF8002486B2A64205D8EC
+:1003400040230549CA691A42FCD070BD285D0134BA
+:10035000FFF7D0FFE4B2F1E70038014001223D4B46
+:1003600010B5196886B00A431A605A683A490A40BB
+:1003700013215A601A6B8A431A6300229A60374A23
+:100380001168080C8AB201420BD1FC24D200A401EE
+:100390002240FF24C9001868214018680A4302431C
+:1003A0001A60002201920292039204920592196847
+:1003B00001320A431A602A4A2A4811680140116032
+:1003C00080211068C90101430220116026491A6882
+:1003D00002400292019A01320192029A002A02D14D
+:1003E000019A8A42F3D11968022208001040114292
+:1003F0002DD0013A029202991C4A012923D10720EB
+:10040000116803910399814303910399E9301160C5
+:1004100059680491049981430491902104980143FF
+:1004200059605968124805910599014003200591CA
+:1004300005995960596881435960596859600C2180
+:1004400058680842FCD10023536706B010BD0290E3
+:10045000D1E7C046001002401CB8FFF820F8FF1F8B
+:10046000E8100240FF81FFFFFFFF00000020024074
+:10047000FFF8FFFF0023C25C0133002AFBD1581EA6
+:1004800070470000B0236D495B034A69F0B5134320
+:1004900090224B6104200023D2051360684DD06088
+:1004A00068486B60AB602860A020E024664E0001C5
+:1004B00030601269654A664F1268664A66487A601B
+:1004C000026A24061202120A224302620722F02064
+:1004D000BB603A602A6A614C82432A621022286A11
+:1004E00085B002432A62326A5D480240326280224D
+:1004F000306A52020243326280228869D20102438A
+:100500008A610C22236022606360A3604533E3604C
+:100510002268443B13430D202360FFF7EBFE0A20C3
+:10052000FFF7E8FE1F263D20013EFFF7E3FE002E09
+:10053000F9D14C48FFF7FCFE1F363D20013EFFF786
+:10054000D9FE002EF9D14848FFF7F2FE02AB5E1D3E
+:10055000002302AA9371454A337013700122444B61
+:100560001A70424B394A5A603378002B06D03378E0
+:10057000002B40D03F48FFF7DBFEE4E702AA012151
+:10058000D01DD371FFF780FD0190002806D0374BB6
+:100590001B78002B0FD14320FFF7ACFE02ABD879BC
+:1005A000042825D00DD8431E012B0FD9019B002B09
+:1005B000DAD102AB17E002AB981DFFF7A5FE307051
+:1005C000ECE71828F2D1FF233370CDE7FFF7ABFD3E
+:1005D000002803D10630FFF78DFEC5E702AB0828DF
+:1005E00001D103229A71981DFFF78EFE3070BBE790
+:1005F0000620FFF77FFE00261F48FFF799FE1F4BDE
+:100600003E607B60BB6090231D4ADB052660266050
+:10061000E660DA601A601B4B0B4A13602B600B4AD2
+:10062000194B1B68126882F308888021174A090158
+:1006300051679847300005B0F0BDC0460010024039
+:10064000000C0048084800000004004800080008AA
+:1006500010E000E07F1A060000ED00E000380140E5
+:10066000FFFFF0FF4407000868070008440000206F
+:1006700000000020AE07000890070008FFFFFF0001
+:10068000FFFF0000FFFB00000408000800200240FC
+:100690000D4885460D480E490E4A002302E0D45805
+:1006A000C4500433C4188C42F9D30B4A0B4C0023BA
+:1006B00001E013600432A242FBD3FFF74FFE00F0CB
+:1006C00011F8FFF7DFFEFEE7001000200000002019
+:1006D00028000020D8070008280000205000002033
+:1006E000FEE7000070B500260C4D0D4C641BA410F5
+:1006F000A64209D1002600F019F80A4D0A4C641BE5
+:10070000A410A64205D170BDB300EB58984701363E
+:10071000EEE7B300EB5898470136F2E7D007000840
+:10072000D0070008D0070008D4070008F8B5C04675
+:10073000F8BC08BC9E467047F8B5C046F8BC08BC7B
+:040740009E4670471A
+:100744000D0A74727565436F6E74726F6C20484B3A
+:10075400333246204C6F616465722076302E302E21
+:10076400320D0A000D0A0D0A73656E642066697203
+:100774006D776172652066696C65207573696E6753
+:1007840020584D4F44454D0D0A0D0A000D0A666C64
+:1007940061736820757064617465643B20626F6F77
+:1007A40074696E672E0D0A0D0A000D0A6661696C84
+:1007B400656420746F207570646174653B20747285
+:0C07C4007920616761696E2E0D0A00004B
+:0407D00069000008B4
+:0407D40041000008D8
+:1007D800010000000123064A117A4B40137280225F
+:1007E800044B012901D09A6270479A61FCE7C04620
+:0807F80044000020000C004841
+:040000050800069158
+:00000001FF
diff --git a/bootloader_hk32f030m_uart_xmodem/bootloader_hk32f030m_uart_xmodem _dbg.launch b/bootloader_hk32f030m_uart_xmodem/bootloader_hk32f030m_uart_xmodem _dbg.launch
index 42f2959..764fbfc 100644
--- a/bootloader_hk32f030m_uart_xmodem/bootloader_hk32f030m_uart_xmodem _dbg.launch
+++ b/bootloader_hk32f030m_uart_xmodem/bootloader_hk32f030m_uart_xmodem _dbg.launch
@@ -2,12 +2,13 @@
-
+
+
@@ -22,7 +23,7 @@
-
+
@@ -34,7 +35,7 @@
-
+
@@ -76,7 +77,7 @@
-
+
@@ -86,5 +87,6 @@
+
diff --git a/bootloader_hk32f030m_uart_xmodem/code/inc/flash.h b/bootloader_hk32f030m_uart_xmodem/code/inc/flash.h
index 8ab675e..7c430ec 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/inc/flash.h
+++ b/bootloader_hk32f030m_uart_xmodem/code/inc/flash.h
@@ -15,8 +15,9 @@
#define FLASH_SIZE 16384 // size of overall flash available on MCU
#define FLASH_ERASE_PAGE_SIZE ((uint16_t)0x80) // erase page size
+#define FLASH_ERASE_PAGE_MASK 0x7f // bitmask of page size
-#define USER_APP_START_ADDR ((uint32_t)FLASH_BASE + 0xa00) // 2560 bytes (20 pages) rsvd for bootloader
+#define USER_APP_START_ADDR ((uint32_t)FLASH_BASE + 0x800) // 2048 bytes (16 pages) rsvd for bootloader
#define USER_APP_END_ADDR ((uint32_t)FLASH_BASE + FLASH_SIZE)
@@ -32,7 +33,7 @@ typedef enum {
-BL_flash_status flash_erase_user_app();
+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/usart.h b/bootloader_hk32f030m_uart_xmodem/code/inc/usart.h
index c327542..8cb5716 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/inc/usart.h
+++ b/bootloader_hk32f030m_uart_xmodem/code/inc/usart.h
@@ -9,7 +9,7 @@
#define CODE_INC_USART_H_
-#define COMM_TIMEOUT 512000;
+#define COMM_TIMEOUT 0xffff;
@@ -24,7 +24,7 @@ typedef enum {
void comm_init();
BL_comm_status comm_rx(uint8_t *data, uint16_t length);
-BL_comm_status comm_tx_str(uint8_t *data);
+BL_comm_status comm_tx_str(char *data);
BL_comm_status comm_tx_byte(uint8_t data);
diff --git a/bootloader_hk32f030m_uart_xmodem/code/inc/user_io.h b/bootloader_hk32f030m_uart_xmodem/code/inc/user_io.h
index 45231d7..5808a18 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/inc/user_io.h
+++ b/bootloader_hk32f030m_uart_xmodem/code/inc/user_io.h
@@ -29,7 +29,6 @@
void user_io_init();
void user_led_init();
-void user_led_set(uint8_t lit);
diff --git a/bootloader_hk32f030m_uart_xmodem/code/inc/xmodem.h b/bootloader_hk32f030m_uart_xmodem/code/inc/xmodem.h
index 7cf11f6..c9029c2 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/inc/xmodem.h
+++ b/bootloader_hk32f030m_uart_xmodem/code/inc/xmodem.h
@@ -72,7 +72,9 @@ typedef enum {
X_ERROR = 0xFFu /**< Generic error. */
} BL_xmodem_status;
-void xmodem_receive(void);
+
+
+BL_xmodem_status xmodem_receive(void);
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/flash.c b/bootloader_hk32f030m_uart_xmodem/code/src/flash.c
index 3e61a87..e54b261 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/src/flash.c
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/flash.c
@@ -11,49 +11,22 @@
/**
- * @brief This function erases the user application area, from start to end of flash.
+ * @brief This function erases a single flash page.
* @return status: Report about the success of the erasing.
*/
-__attribute__ ((long_call, section(".ramfunc"))) BL_flash_status flash_erase_user_app()
+__attribute__ ((long_call, section(".ramfunc"))) BL_flash_status flash_erase_page(uint32_t addr)
{
- // uint32_t timeout;
- uint32_t page;
+ BL_flash_status status = FLASH_ERROR;
FLASH_Unlock();
- for (page = USER_APP_START_ADDR; page < USER_APP_END_ADDR; page += FLASH_ERASE_PAGE_SIZE) {
- if (FLASH_ErasePage(page) != FLASH_COMPLETE) {
- FLASH_Lock();
- return FLASH_ERROR;
- }
-
- /*
- // clear end of operation bit
- FLASH->SR &= ~FLASH_FLAG_EOP;
-
- // start erasing page
- FLASH->CR |= FLASH_CR_PER;
- FLASH->AR = page;
- FLASH->CR |= FLASH_CR_STRT;
-
- // wait wait for operation to complete
- timeout = FLASH_ER_PRG_TIMEOUT;
- while ((FLASH->SR & FLASH_FLAG_BSY)) {
- timeout--;
- if (!timeout) {
- FLASH_Lock();
- return FLASH_ERROR;
- }
- }
-
- // disable page erase bit
- FLASH->CR &= ~FLASH_CR_PER;
- */
+ if (FLASH_ErasePage(addr) == FLASH_COMPLETE) {
+ status = FLASH_OK;
}
FLASH_Lock();
- return FLASH_OK;
+ return status;
}
/**
@@ -71,23 +44,23 @@ __attribute__ ((long_call, section(".ramfunc"))) BL_flash_status flash_write(uin
/* Loop through the data. */
for (uint32_t i = 0u; (i < length) && (status == FLASH_OK); i++) {
- if (addr >= USER_APP_END_ADDR) {
- status = FLASH_ERROR_SIZE;
- break;
- } else {
- /* The actual flashing. If there is an error, then report it. */
- if (FLASH_ProgramByte(addr, data[i]) != FLASH_COMPLETE) {
- status |= FLASH_ERROR_WRITE;
- }
+ if (addr >= USER_APP_END_ADDR) {
+ status = FLASH_ERROR_SIZE;
+ break;
+ } else {
+ /* The actual flashing. If there is an error, then report it. */
+ if (FLASH_ProgramByte(addr, data[i]) != FLASH_COMPLETE) {
+ status |= FLASH_ERROR_WRITE;
+ }
- /* Read back the content of the memory. If it is wrong, then report an error. */
- if (data[i] != (*(volatile uint8_t *)addr)) {
- status |= FLASH_ERROR_VERIFY;
- }
+ /* Read back the content of the memory. If it is wrong, then report an error. */
+ if (data[i] != (*(volatile uint8_t *)addr)) {
+ status |= FLASH_ERROR_VERIFY;
+ }
- /* Shift the address by a word. */
- addr++;
- }
+ /* Shift the address by a word. */
+ addr++;
+ }
}
FLASH_Lock();
@@ -109,6 +82,12 @@ void jump_to_user_app()
USART1->CR1 = 0;
USART1->BRR = 0;
+ // 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;
+
// disable configured interrupts
// NVIC->ICER[0] = 0;
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/main.c b/bootloader_hk32f030m_uart_xmodem/code/src/main.c
index f1ab262..4297186 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/src/main.c
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/main.c
@@ -22,8 +22,8 @@
int main(void)
{
- uint8_t btn;
- //volatile uint16_t timeout = 0xffff;
+ uint32_t i;
+ uint32_t btn;
// ensure the bootloader is write protected
// TODO
@@ -31,9 +31,6 @@ int main(void)
// configure button and LED
user_io_init();
- // need a small delay to ensure the button pullup/down will charge/discharge pin capacitance
- //while (--timeout);
-
// get button state
btn = BTN_PORT->IDR & (1 << BTN_PIN);
#if BTN_ACT_DIR == 0
@@ -41,34 +38,45 @@ int main(void)
#endif
// bootloader activation methods
- if (btn // button pushed
- || (*(volatile uint32_t *)USER_APP_START_ADDR) == 0x00000000 // flash empty
- || (*(volatile uint32_t *)USER_APP_START_ADDR) == 0xFFFFFFFF) { // flash empty
-
- // bootloader is activated, show it
+ 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?
comm_init();
- const uint8_t *banner_bar = (uint8_t *)"\r\n================================================\r\n";
- comm_tx_str((uint8_t *)banner_bar);
- comm_tx_str((uint8_t *)"trueControl HK32F XMODEM Flash Bootloader v0.0.1");
- comm_tx_str((uint8_t *)banner_bar);
+ 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('=');
+ }
// wait for firmware load or reset
while(1) {
- comm_tx_str((uint8_t*)"\r\nsend binary file using XMODEM to update firmware");
- comm_tx_str((uint8_t*)"\r\nthe first data block will take time. it's normal\r\n\r\n");
- xmodem_receive();
+ // announce bootloader start
+ comm_tx_str("\r\n\r\nsend firmware 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");
+ break;
+ }
// if xmodem exits, there was a failure. repeat the process.
- comm_tx_str((uint8_t*)"\r\nfailed to update. try again.\r\n");
+ comm_tx_str("\r\nfailed to update; try again.\r\n");
}
}
- // bootloader is not activated; jump to user code
+ // bootloader is either done not activated; jump to user code
jump_to_user_app();
}
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/usart.c b/bootloader_hk32f030m_uart_xmodem/code/src/usart.c
index 9d96e44..d47d0a3 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/src/usart.c
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/usart.c
@@ -41,16 +41,14 @@ uint16_t rxlen = 0;
*/
void comm_init()
{
- // USART_InitTypeDef usart;
- // NVIC_InitTypeDef nvic;
-
// enable GPIO clock
- RCC_AHBPeriphClockCmd(USART_TX_GPIO_CLK | USART_RX_GPIO_CLK, ENABLE);
+ // 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);
+ /* these have been configured in user_io.c to save space
USART_RX_PORT->MODER &= ~(GPIO_MODER_MODER0 << 2 * USART_RX_PIN);
USART_RX_PORT->MODER |= (GPIO_Mode_AF << 2 * USART_RX_PIN); // alt function
@@ -58,46 +56,25 @@ void comm_init()
USART_TX_PORT->OTYPER &= ~(GPIO_OTYPER_OT_0 << USART_TX_PIN); // push pull
USART_TX_PORT->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0 << 2 * USART_TX_PIN); // slow
USART_TX_PORT->MODER |= (GPIO_Mode_AF << 2 * USART_TX_PIN); // alt function
-
- // configure NVIC
- /*
- nvic.NVIC_IRQChannel = USART1_IRQn;
- nvic.NVIC_IRQChannelPriority = 1;
- nvic.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&nvic);
*/
// enable USART clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- /*
- // configure USART peripheral
- usart.USART_BaudRate = BAUDRATE;
- usart.USART_WordLength = USART_WordLength_8b;
- usart.USART_StopBits = USART_StopBits_1;
- usart.USART_Parity = USART_Parity_No;
- usart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_Init(USART1, &usart);
- */
-
// configure USART peripheral manually
- // we do this as the library uses division which bloats flash space
+ // 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->BRR = 0x45; // 115200 baud rate @8MHz (per datasheet)
- // enable USART interrupts
- // USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
-
// enable USART
USART1->CR1 |= USART_CR1_UE;
}
/**
- * @brief Receives data from USART.
+ * @brief Receives data from USART in a polling manner.
* @param *data: Array to save the received data.
* @param length: Size of the data.
* @return status: Report about the success of the receiving.
@@ -107,24 +84,8 @@ BL_comm_status comm_rx(uint8_t *data, uint16_t length)
uint16_t i;
uint16_t timeout;
- /*
- // wait for more data to arrive
- timeout = COMM_TIMEOUT;
- while (rxlen < length) {
- timeout--;
- if (!timeout) return COMM_RX_TIMEOUT;
- }
-
- // copy data to final buffer
for (i = 0; i < length; i++) {
- data[i] = rxbuf[rxptr++];
- if (rxptr >= RX_BUF_LEN) rxptr = 0;
- rxlen--;
- }
- */
-
- for (i = 0; i < length; i++) {
- timeout = 0xffff;
+ timeout = COMM_TIMEOUT;
while (!(USART1->ISR & USART_ISR_RXNE_Msk) && timeout) {
timeout--;
}
@@ -160,40 +121,19 @@ BL_comm_status comm_tx_byte(uint8_t data)
* @param *data: String array.
* @return status: Report about the success of the transmission.
*/
-BL_comm_status comm_tx_str(uint8_t *data)
+BL_comm_status comm_tx_str(char *data)
{
uint8_t i;
uint16_t len = 0;
len = strlen((const char *)data);
- for(i = 0; i < len; i++) {
+ for (i = 0; i < len; i++) {
comm_tx_byte(data[i]);
}
- while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
+ while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
return COMM_OK;
}
-/*
-void USART1_IRQHandler()
-{
- uint8_t data;
-
- if (USART1->ISR & USART_ISR_RXNE_Msk) {
- // read data
- data = USART1->RDR;
-
- // only add data if there is room
- if (rxlen >= RX_BUF_LEN) return;
- rxlen++;
-
- // next position
- if (++rxptr >= RX_BUF_LEN) rxptr = 0;
-
- // save data
- rxbuf[rxptr] = data;
- }
-}
-*/
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/user_io.c b/bootloader_hk32f030m_uart_xmodem/code/src/user_io.c
index c144808..d0f41f7 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/src/user_io.c
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/user_io.c
@@ -14,8 +14,9 @@
void user_io_init()
{
// enable gpio clocks
- RCC_AHBPeriphClockCmd(BTN_CLK | LED_CLK, ENABLE);
+ RCC_AHBPeriphClockCmd(BTN_CLK | LED_CLK | RCC_AHBPeriph_GPIOB, ENABLE);
+ /* --original method, not space efficient
// configure led
#if LED_ACT_DIR == 0
LED_PORT->BSRR = (1 << LED_PIN); // idle high
@@ -25,16 +26,44 @@ void user_io_init()
LED_PORT->OTYPER &= ~(GPIO_OTYPER_OT_0 << LED_PIN); // push pull
LED_PORT->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0 << 2 * LED_PIN); // slow
LED_PORT->MODER &= ~(GPIO_MODER_MODER0 << 2 * LED_PIN);
- LED_PORT->MODER |= (GPIO_Mode_OUT << 2 * LED_PIN); // output
+ LED_PORT->MODER = (GPIO_Mode_OUT << 2 * LED_PIN); // output
// configure button
BTN_PORT->MODER &= ~(GPIO_MODER_MODER0 << 2 * BTN_PIN); // input
BTN_PORT->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << 2 * BTN_PIN);
#if BTN_ACT_DIR == 0
- BTN_PORT->PUPDR |= (GPIO_PuPd_UP << 2 * BTN_PIN); // pulled high
+ //BTN_PORT->PUPDR |= (GPIO_PuPd_UP << 2 * BTN_PIN); // pulled high
+ BTN_PORT->PUPDR = (GPIO_PuPd_UP << 2 * BTN_PIN); // pulled high
#else
- BTN_PORT->PUPDR |= (GPIO_PuPd_DOWN << 2 * BTN_PIN); // pulled low
+ //BTN_PORT->PUPDR |= (GPIO_PuPd_DOWN << 2 * BTN_PIN); // pulled low
+ BTN_PORT->PUPDR = (GPIO_PuPd_DOWN << 2 * BTN_PIN); // pulled low
#endif
+ */
+
+ /* new method, configure USART pins at the same time as LED and btn
+ * at they are on the same ports
+ */
+
+ // default MODER for GPIOB and GPIOD are 0xFBFF
+ // pin 5 _must_ be configured as AF, otherwise you'll kill debugging!
+
+ // configure button as input
+ BTN_PORT->MODER = 0x0;
+#if BTN_ACT_DIR == 0
+ //BTN_PORT->PUPDR |= (GPIO_PuPd_UP << 2 * BTN_PIN); // pulled high
+ BTN_PORT->PUPDR = (GPIO_PuPd_UP << 2 * BTN_PIN); // pulled high
+#else
+ //BTN_PORT->PUPDR |= (GPIO_PuPd_DOWN << 2 * BTN_PIN); // pulled low
+ BTN_PORT->PUPDR = (GPIO_PuPd_DOWN << 2 * BTN_PIN); // pulled low
+#endif
+
+ // 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));
+
+ // configure USART RX as AF
+ GPIOB->MODER = 0x800 | (GPIO_Mode_AF << (2 * 4));
}
void user_led_init()
@@ -43,14 +72,3 @@ void user_led_init()
SysTick_Config(8000000 / 20);
}
-void user_led_set(uint8_t lit)
-{
-#if LED_ACT_DIR == 0
- if (lit) LED_PORT->BRR = (1 << LED_PIN);
- else LED_PORT->BSRR = (1 << LED_PIN);
-#else
- if (lit) LED_PORT->BSRR = (1 << LED_PIN);
- else LED_PORT->BRR = (1 << LED_PIN);
-#endif
-}
-
diff --git a/bootloader_hk32f030m_uart_xmodem/code/src/xmodem.c b/bootloader_hk32f030m_uart_xmodem/code/src/xmodem.c
index b1af977..8c2143e 100644
--- a/bootloader_hk32f030m_uart_xmodem/code/src/xmodem.c
+++ b/bootloader_hk32f030m_uart_xmodem/code/src/xmodem.c
@@ -34,7 +34,7 @@ static BL_xmodem_status xmodem_error_handler(uint8_t *error_number, uint8_t max_
* @param void
* @return void
*/
-void xmodem_receive(void)
+BL_xmodem_status xmodem_receive(void)
{
volatile BL_xmodem_status status = X_OK;
uint8_t error_number = 0u;
@@ -51,7 +51,7 @@ void xmodem_receive(void)
BL_comm_status status_c = comm_rx(&header, 1);
/* 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 == false)) {
+ if ((status_c != COMM_OK) && (x_first_packet_rcvd == 0)) {
comm_tx_byte(X_C);
}
@@ -96,9 +96,7 @@ void xmodem_receive(void)
case X_EOT: {
/* ACK, feedback to user (as a text), then jump to user application. */
comm_tx_byte(X_ACK);
- comm_tx_str((uint8_t*)"\r\nfirmware updated.\r\nstarting firmware.\r\n\r\n");
- jump_to_user_app();
- break;
+ return X_OK;
}
/* Abort from host. */
@@ -116,6 +114,8 @@ void xmodem_receive(void)
}
}
}
+
+ return status;
}
/**
@@ -127,22 +127,19 @@ void xmodem_receive(void)
static uint16_t xmodem_calc_crc(uint8_t *data, uint16_t length)
{
uint16_t crc = 0u;
- while (length)
- {
+
+ while (length) {
length--;
crc = crc ^ ((uint16_t)*data++ << 8u);
- for (uint8_t i = 0u; i < 8u; i++)
- {
- if (crc & 0x8000u)
- {
+ for (uint8_t i = 0u; i < 8u; i++) {
+ if (crc & 0x8000u) {
crc = (crc << 1u) ^ 0x1021u;
- }
- else
- {
+ } else {
crc = crc << 1u;
}
}
}
+
return crc;
}
@@ -154,7 +151,8 @@ static uint16_t xmodem_calc_crc(uint8_t *data, uint16_t length)
static BL_xmodem_status xmodem_handle_packet(uint8_t header)
{
BL_xmodem_status status = X_OK;
- uint16_t size = 0u;
+ uint16_t size = 0;
+ uint32_t i;
/* 2 bytes for packet number, 1024 for data, 2 for CRC*/
uint8_t rcvd_packet_number[X_PACKET_NUMBER_SIZE];
@@ -190,13 +188,9 @@ static BL_xmodem_status xmodem_handle_packet(uint8_t header)
status |= X_ERROR_UART;
}
- /* If it is the first packet, then erase the memory. */
- if ((status == X_OK) && (x_first_packet_rcvd == false)) {
- if (flash_erase_user_app() == FLASH_OK) {
- x_first_packet_rcvd = true;
- } else {
- status |= X_ERROR_FLASH;
- }
+ /* If it is the first packet, then mark it. If you want to erase all flash, do it here. */
+ if ((status == X_OK)) { // && (x_first_packet_rcvd == 0)) {
+ x_first_packet_rcvd = 1;
}
/* Error handling and flashing. */
@@ -219,11 +213,22 @@ static BL_xmodem_status xmodem_handle_packet(uint8_t header)
}
/* Do the actual flashing if there weren't any errors. */
- if ((status == X_OK) &&
- (flash_write(xmodem_flash_w_addr, rcvd_packet_data, size)) != FLASH_OK) {
+ if (status == X_OK) {
+ /* first, erase pages depending on size */
+ for (i = 0; i < size; i += FLASH_ERASE_PAGE_SIZE) {
+ if (flash_erase_page(xmodem_flash_w_addr + i) != FLASH_OK) {
+ /* Flashing error. */
+ status |= X_ERROR_FLASH;
+ }
+ }
- /* Flashing error. */
- status |= X_ERROR_FLASH;
+ /* then write data to these cleared pages */
+ if (status == X_OK) {
+ if (flash_write(xmodem_flash_w_addr, rcvd_packet_data, size) != FLASH_OK) {
+ /* Flashing error. */
+ status |= X_ERROR_FLASH;
+ }
+ }
}
/* Raise the packet number and the address counters (if there weren't any errors). */
diff --git a/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/HK32F030M/Source/startup_hk32f030mf4p6.s b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/HK32F030M/Source/startup_hk32f030mf4p6.s
index ed9f0ab..9e2eaea 100644
--- a/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/HK32F030M/Source/startup_hk32f030mf4p6.s
+++ b/bootloader_hk32f030m_uart_xmodem/driver/CMSIS/HK32F030M/Source/startup_hk32f030mf4p6.s
@@ -112,8 +112,8 @@ Infinite_Loop:
g_pfnVectors:
.word _estack
.word Reset_Handler
- .word NMI_Handler
- .word HardFault_Handler
+ .word Default_Handler // NMI_Handler
+ .word Default_Handler // HardFault_Handler
.word 0
.word 0
.word 0
@@ -121,43 +121,43 @@ g_pfnVectors:
.word 0
.word 0
.word 0
- .word SVC_Handler
+ .word Default_Handler // SVC_Handler
.word 0
.word 0
- .word PendSV_Handler
+ .word Default_Handler // PendSV_Handler
.word SysTick_Handler
- .word WWDG_IRQHandler /* Window WatchDog */
- .word 0 /* Reserved */
- .word EXTI11_IRQHandler /* EXTI Line 11 interrupt(AWU_WKP) */
- .word FLASH_IRQHandler /* FLASH */
- .word RCC_IRQHandler /* RCC */
- .word EXTI0_IRQHandler /* EXTI Line 0 */
- .word EXTI1_IRQHandler /* EXTI Line 1 */
- .word EXTI2_IRQHandler /* EXTI Line 2 */
- .word EXTI3_IRQHandler /* EXTI Line 3 */
- .word EXTI4_IRQHandler /* EXTI Line 4 */
- .word EXTI5_IRQHandler /* EXTI Line 5 */
- .word TIM1_BRK_IRQHandler /* TIM1 break interrupt */
- .word ADC1_IRQHandler /* ADC1 interrupt, combined with EXTI line 8 */
- .word TIM1_UP_TRG_COM_IRQHandler /* TIM1 Update, Trigger and Commutation */
- .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
- .word TIM2_IRQHandler /* TIM2 */
- .word 0 /* Reserved */
- .word TIM6_IRQHandler /* TIM6 */
- .word 0 /* Reserved */
- .word 0 /* Reserved */
- .word 0 /* Reserved */
- .word EXTI6_IRQHandler /* EXTI Line 6 */
- .word EXTI7_IRQHandler /* EXTI Line 7 */
- .word I2C1_IRQHandler /* I2C1 global interrupt, combined with EXTI Line 10 */
- .word 0 /* Reserved */
- .word SPI1_IRQHandler /* SPI1 */
- .word 0 /* Reserved */
- .word USART1_IRQHandler /* USART1 global interrupt, combined with EXTI Line 9 */
- .word 0 /* Reserved */
- .word 0 /* Reserved */
- .word 0 /* Reserved */
- .word 0 /* Reserved */
+// .word WWDG_IRQHandler /* Window WatchDog */
+// .word 0 /* Reserved */
+// .word EXTI11_IRQHandler /* EXTI Line 11 interrupt(AWU_WKP) */
+// .word FLASH_IRQHandler /* FLASH */
+// .word RCC_IRQHandler /* RCC */
+// .word EXTI0_IRQHandler /* EXTI Line 0 */
+// .word EXTI1_IRQHandler /* EXTI Line 1 */
+// .word EXTI2_IRQHandler /* EXTI Line 2 */
+// .word EXTI3_IRQHandler /* EXTI Line 3 */
+// .word EXTI4_IRQHandler /* EXTI Line 4 */
+// .word EXTI5_IRQHandler /* EXTI Line 5 */
+// .word TIM1_BRK_IRQHandler /* TIM1 break interrupt */
+// .word ADC1_IRQHandler /* ADC1 interrupt, combined with EXTI line 8 */
+// .word TIM1_UP_TRG_COM_IRQHandler /* TIM1 Update, Trigger and Commutation */
+// .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
+// .word TIM2_IRQHandler /* TIM2 */
+// .word 0 /* Reserved */
+// .word TIM6_IRQHandler /* TIM6 */
+// .word 0 /* Reserved */
+// .word 0 /* Reserved */
+// .word 0 /* Reserved */
+// .word EXTI6_IRQHandler /* EXTI Line 6 */
+// .word EXTI7_IRQHandler /* EXTI Line 7 */
+// .word I2C1_IRQHandler /* I2C1 global interrupt, combined with EXTI Line 10 */
+// .word 0 /* Reserved */
+// .word SPI1_IRQHandler /* SPI1 */
+// .word 0 /* Reserved */
+// .word USART1_IRQHandler /* USART1 global interrupt, combined with EXTI Line 9 */
+// .word 0 /* Reserved */
+// .word 0 /* Reserved */
+// .word 0 /* Reserved */
+// .word 0 /* Reserved */
/*******************************************************************************
*
@@ -182,6 +182,7 @@ g_pfnVectors:
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
+/*
.weak WWDG_IRQHandler
.thumb_set WWDG_IRQHandler,Default_Handler
@@ -244,3 +245,4 @@ g_pfnVectors:
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
+*/
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 11bdcba..587273c 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
@@ -170,7 +170,7 @@ static void SetSysClockToHSI(void)
* Datasheet and RM was updated in 2023 which derated flash programming from 4MHz
* 0x07 = 4MHz, 0x08 = 2MHz. change as you see fit */
RCC->CFGR4 &= ~(RCC_RCC_CFGR4_FLITFCLK_PRE | RCC_RCC_CFGR4_FLITFCLK_SE);
- RCC->CFGR4 |= (((uint32_t)0x07) << RCC_RCC_CFGR4_FLITFCLK_PRE_Pos);
+ RCC->CFGR4 |= (((uint32_t)0x08) << RCC_RCC_CFGR4_FLITFCLK_PRE_Pos);
/* Wait until HSI is ready; if timeout is reached, then exit */
do {
@@ -386,33 +386,30 @@ static void SetSysClockToEXTCLK(void)
*/
void SystemCoreClockUpdate (void)
{
- uint32_t tmp = 0, presc = 0;
+ uint32_t tmp = 0, presc = 0;
- /* Get SYSCLK source -------------------------------------------------------*/
- tmp = RCC->CFGR & RCC_CFGR_SWS;
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
- switch (tmp)
- {
- case RCC_CFGR_SWS_HSI: /* HSI used as system clock */
- SystemCoreClock = HCLK_FREQ;
- break;
- case RCC_CFGR_SWS_EXTCLK: /* EXTCLK used as system clock */
- SystemCoreClock = EXTCLK_VALUE;
- break;
- case RCC_CFGR_SWS_LSI: /* LSI used as system clock */
- SystemCoreClock = LSI_VALUE;
- break;
+ switch (tmp) {
+ case RCC_CFGR_SWS_EXTCLK: // EXTCLK used as system clock
+ SystemCoreClock = EXTCLK_VALUE;
+ break;
+ case RCC_CFGR_SWS_LSI: // LSI used as system clock
+ SystemCoreClock = LSI_VALUE;
+ break;
- default: /* HSI used as system clock */
- SystemCoreClock = HCLK_FREQ;
- break;
- }
+ case RCC_CFGR_SWS_HSI: // HSI used as system clock
+ default:
+ SystemCoreClock = HCLK_FREQ;
+ break;
+ }
- /* Compute HCLK clock frequency ----------------*/
- /* Get HCLK prescaler */
- tmp = RCC->CFGR & RCC_CFGR_HPRE;
- tmp = tmp >> 4;
- presc = AHBPrescTable[tmp];
- /* HCLK clock frequency */
- SystemCoreClock = SystemCoreClock/presc;
+ /* Compute HCLK clock frequency ----------------*/
+ /* Get HCLK prescaler */
+ tmp = RCC->CFGR & RCC_CFGR_HPRE;
+ tmp = tmp >> 4;
+ presc = AHBPrescTable[tmp];
+ /* HCLK clock frequency */
+ SystemCoreClock = SystemCoreClock/presc;
}