├── src ├── .DS_Store ├── config.h ├── flash.h ├── uart.h ├── startup_sim3u1xx.S ├── flash.c ├── uart.c └── main.c ├── sim3u1xx_Blinky.bin ├── myLinkerOptions_p32.ld ├── bootloader_link.ld ├── .project ├── sim32loader.py ├── README.md └── .cproject /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkDing/sim3u1xx_Bootloader/HEAD/src/.DS_Store -------------------------------------------------------------------------------- /sim3u1xx_Blinky.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkDing/sim3u1xx_Bootloader/HEAD/sim3u1xx_Blinky.bin -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | #define USER_CODE_ADDRESS 0x1000 4 | #define TOP_CODE_ADDRESS 0x3fffc 5 | 6 | #define UART_UPDATE_ENABLE 1 7 | #define UART_BAUD_RATE 115200 8 | #endif 9 | -------------------------------------------------------------------------------- /myLinkerOptions_p32.ld: -------------------------------------------------------------------------------- 1 | 2 | 3 | /****************** C LIBRARY SUPPORT ***************/ 4 | /*GROUP(libgcc.a libc.a libm.a libcr_newlib_nohost.a)*/ 5 | /*GROUP(libgcc.a libc.a libm.a libcr_newlib_semihost.a)*/ 6 | /*GROUP(libcr_semihost.a libcr_c.a libcr_eabihelpers.a)*/ 7 | GROUP(libcr_nohost.a libcr_c.a libcr_eabihelpers.a) 8 | -------------------------------------------------------------------------------- /bootloader_link.ld: -------------------------------------------------------------------------------- 1 | GROUP(libcr_nohost.a libcr_c.a libcr_eabihelpers.a) 2 | MEMORY 3 | { 4 | /* Define each memory region */ 5 | MFlash256 (rx) : ORIGIN = 0x0, LENGTH = 0x3fffc /* 255k */ 6 | StandardRam28 (rwx) : ORIGIN = 0x20001000, LENGTH = 0x7000 /* 28k */ 7 | RetentionRam4 (rwx) : ORIGIN = 0x20000000, LENGTH = 0x1000 /* 4k */ 8 | 9 | } 10 | /* Define a symbol for the top of each memory region */ 11 | __top_MFlash256 = 0x0 + 0x3fffc; 12 | __top_StandardRam28 = 0x20001000 + 0x7000; 13 | __top_RetentionRam4 = 0x20000000 + 0x1000; 14 | 15 | ENTRY(ResetISR) 16 | SECTIONS 17 | { 18 | .text 0x20000000 : AT (0x00000000) 19 | { 20 | . = ALIGN(4); 21 | _text = .; 22 | KEEP(*(.isr_vector)) 23 | *(.text*) 24 | *(.rodata*) 25 | _etext = .; 26 | } 27 | 28 | .data 0x20000000 + SIZEOF(.text) : AT (LOADADDR(.text) + SIZEOF(.text)) 29 | { 30 | _data = .; 31 | *(.data*) 32 | _edata = .; 33 | } 34 | 35 | .bss 0x20000000 + SIZEOF(.text) + SIZEOF(.data) : 36 | AT (LOADADDR(.data) + SIZEOF(.data)) 37 | { 38 | _bss = .; 39 | *(.bss*) 40 | *(COMMON) 41 | _ebss = .; 42 | } 43 | 44 | PROVIDE(_pvHeapStart = .); 45 | PROVIDE(_vStackTop = __top_StandardRam28 - 0); 46 | } 47 | -------------------------------------------------------------------------------- /src/flash.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (c) 2011 by Silicon Laboratories Inc. All rights reserved. 3 | // The program contained in this listing is proprietary to Silicon Laboratories, 4 | // headquartered in Austin, Texas, U.S.A. and is subject to worldwide copyright 5 | // protection, including protection under the United States Copyright Act of 1976 6 | // as an unpublished work, pursuant to Section 104 and Section 408 of Title XVII 7 | // of the United States code. Unauthorized copying, adaptation, distribution, 8 | // use, or display is prohibited by this law. 9 | // 10 | // Silicon Laboratories provides this software solely and exclusively 11 | // for use on Silicon Laboratories' microcontroller products. 12 | // 13 | // This software is provided "as is". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 14 | // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 15 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 16 | // SILICON LABORATORIES SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, 17 | // INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 18 | //------------------------------------------------------------------------------ 19 | /// @file myUart0.h 20 | 21 | #ifndef __FLASH_H__ 22 | #define __FLASH_H__ 23 | 24 | #include 25 | 26 | void flash_erase_page(unsigned int addr); 27 | int flash_write_data(unsigned char* buf,unsigned int addr, unsigned int num); 28 | void flash_initialize(void); 29 | #endif 30 | //-eof-------------------------------------------------------------------------- 31 | -------------------------------------------------------------------------------- /src/uart.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (c) 2011 by Silicon Laboratories Inc. All rights reserved. 3 | // The program contained in this listing is proprietary to Silicon Laboratories, 4 | // headquartered in Austin, Texas, U.S.A. and is subject to worldwide copyright 5 | // protection, including protection under the United States Copyright Act of 1976 6 | // as an unpublished work, pursuant to Section 104 and Section 408 of Title XVII 7 | // of the United States code. Unauthorized copying, adaptation, distribution, 8 | // use, or display is prohibited by this law. 9 | // 10 | // Silicon Laboratories provides this software solely and exclusively 11 | // for use on Silicon Laboratories' microcontroller products. 12 | // 13 | // This software is provided "as is". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 14 | // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 15 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 16 | // SILICON LABORATORIES SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, 17 | // INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 18 | //------------------------------------------------------------------------------ 19 | /// @file myUart0.h 20 | 21 | #ifndef __UART_H__ 22 | #define __UART_H__ 23 | 24 | #include 25 | 26 | 27 | // Sends a byte via UART 28 | void UART0_send_char(uint8_t); 29 | int8_t UART0_get_char(uint8_t *c); 30 | void print_hex(unsigned int code); 31 | void UART0_initialize(void); 32 | void uart_send_data(unsigned char *data, unsigned int count); 33 | int uart_get_data(unsigned char *data, unsigned int count); 34 | #endif //__myUart0_H__ 35 | //-eof-------------------------------------------------------------------------- 36 | -------------------------------------------------------------------------------- /src/startup_sim3u1xx.S: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | .syntax unified 3 | .thumb 4 | 5 | //***************************************************************************** 6 | // 7 | // The vector table. 8 | // This relies on the linker script to place at correct location in memory. 9 | // 10 | //***************************************************************************** 11 | .section .isr_vector 12 | Vectors: 13 | .word 0x20008000 // The initial stack pointer 14 | .word ResetISR - 0x20000000 // The reset handler 15 | .word NMI_Handler // The NMI handler 16 | .word HardFault_Handler // The hard fault handler 17 | .word Default_Handler // The MPU fault handler 18 | .word Default_Handler // The bus fault handler 19 | .word Default_Handler // The usage fault handler 20 | .word 0 // Reserved 21 | .word 0 // Reserved 22 | .word 0 // Reserved 23 | .word 0 // Reserved 24 | .word Default_Handler // SVCall handler 25 | .word Default_Handler // Debug monitor handler 26 | .word 0 // Reserved 27 | .word Default_Handler // The PendSV handler 28 | .extern SysTick_Handler 29 | .word SysTick_Handler // The SysTick handler 30 | 31 | .text 32 | .thumb_func 33 | CopyCode2SRAM: 34 | // Copy the text and data sections from flash to SRAM. 35 | movs r0, #0x00000000 36 | ldr r1, =0x20000000 37 | .extern _bss 38 | ldr r2, =_bss 39 | copy_loop: 40 | ldr r3, [r0], #4 41 | str r3, [r1], #4 42 | cmp r1, r2 43 | blt copy_loop 44 | 45 | // Zero fill the bss segment 46 | movs r0, #0x00000000 47 | .extern _ebss 48 | ldr r2, =_ebss 49 | zero_loop: 50 | str r0, [r1], #4 51 | cmp r1, r2 52 | blt zero_loop 53 | 54 | // Set the vector table pointer to SRAM. 55 | ldr r0, =0xe000ed08 56 | ldr r1, =0x20000000 57 | str r1, [r0] 58 | // set return address to SRAM and return 59 | orr lr, lr, #0x20000000 60 | bx lr 61 | 62 | //***************************************************************************** 63 | // 64 | // The reset handler, which gets called when the processor starts. 65 | // 66 | //***************************************************************************** 67 | .globl ResetISR 68 | .thumb_func 69 | ResetISR: 70 | // Copy code from flash to SRAM 71 | bl CopyCode2SRAM 72 | .extern SystemInit 73 | bl SystemInit 74 | // Check if update is needed 75 | .extern check_update_requirement 76 | bl check_update_requirement 77 | cbz r0, RunUserCode 78 | 79 | .extern main 80 | bl main 81 | 82 | .thumb_func 83 | RunUserCode: 84 | // Set the vector table address to user code address. 85 | ldr r0, =USER_CODE_ADDRESS 86 | ldr r1, =0xe000ed08 87 | str r0, [r1] 88 | 89 | // Update stack pointer from user code vector table 90 | ldr r1, [r0] 91 | mov sp, r1 92 | 93 | // Load user code reset handler and jump to the user code 94 | ldr r0, [r0, #4] 95 | bx r0 96 | 97 | .thumb_func 98 | NMI_Handler: 99 | b . 100 | 101 | .thumb_func 102 | HardFault_Handler: 103 | b . 104 | 105 | .thumb_func 106 | Default_Handler: 107 | b . 108 | 109 | .end 110 | -------------------------------------------------------------------------------- /src/flash.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (c) 2011 by Silicon Laboratories Inc. All rights reserved. 3 | // The program contained in this listing is proprietary to Silicon Laboratories, 4 | // headquartered in Austin, Texas, U.S.A. and is subject to worldwide copyright 5 | // protection, including protection under the United States Copyright Act of 1976 6 | // as an unpublished work, pursuant to Section 104 and Section 408 of Title XVII 7 | // of the United States code. Unauthorized copying, adaptation, distribution, 8 | // use, or display is prohibited by this law. 9 | // 10 | // Silicon Laboratories provides this software solely and exclusively 11 | // for use on Silicon Laboratories' microcontroller products. 12 | // 13 | // This software is provided "as is". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 14 | // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 15 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 16 | // SILICON LABORATORIES SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, 17 | // INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 18 | //------------------------------------------------------------------------------ 19 | 20 | //============================================================================== 21 | // WARNING: 22 | // 23 | // This file is auto-generated by AppBuilder and should not be modified. 24 | // Any hand modifications will be lost if the project is regenerated. 25 | //============================================================================== 26 | // library 27 | #include 28 | // hal 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | // application 38 | #include "config.h" 39 | #include "flash.h" 40 | 41 | //============================================================================== 42 | //SUPPORT FUNCTIONS 43 | //============================================================================== 44 | 45 | //============================================================================== 46 | //MODE FUNCTIONS 47 | //============================================================================== 48 | void flash_erase_page(unsigned int addr) 49 | { 50 | SI32_FLASHCTRL_A_exit_multi_byte_write_mode(SI32_FLASHCTRL_0); 51 | // 2. Write the address of the Flash page to WRADDR 52 | SI32_FLASHCTRL_A_write_wraddr(SI32_FLASHCTRL_0, addr); 53 | // 3. Enter Flash Erase Mode 54 | SI32_FLASHCTRL_A_enter_flash_erase_mode(SI32_FLASHCTRL_0); 55 | // 5. Write the inital unlock value to KEY 56 | SI32_FLASHCTRL_A_write_flash_key(SI32_FLASHCTRL_0, 0xA5); 57 | // 6. Write the single unlock value to KEY 58 | SI32_FLASHCTRL_A_write_flash_key(SI32_FLASHCTRL_0, 0xF1); 59 | // 7. Write any value to WRDATA in right-justified format to 60 | // initiate the page erase 61 | SI32_FLASHCTRL_A_write_wrdata(SI32_FLASHCTRL_0, 0x0000); 62 | // 8. (optional) poll BUSYF if executing code from other than Flash Memory 63 | // We are executing code from Flash, so no need to poll. 64 | while(SI32_FLASHCTRL_A_is_buffer_full(SI32_FLASHCTRL_0)); 65 | // 9. Enable Interrupts 66 | } 67 | 68 | //------------------------------------------------------------------------------ 69 | // myFLASHCTRL0_run_write_flash_mode() 70 | // 71 | // 72 | //------------------------------------------------------------------------------ 73 | int flash_write_data(unsigned char * c,unsigned int addr, unsigned int num) 74 | { 75 | int i; 76 | unsigned short *buf = (unsigned short*)c; 77 | // 2. Disable Flash Erase Operations 78 | SI32_FLASHCTRL_A_exit_flash_erase_mode(SI32_FLASHCTRL_0); 79 | // 3. Write the address of the half-word to WRADDR 80 | SI32_FLASHCTRL_A_write_wraddr(SI32_FLASHCTRL_0, addr); 81 | SI32_FLASHCTRL_A_enter_multi_byte_write_mode(SI32_FLASHCTRL_0); 82 | // 5. Write the inital unlock value to KEY 83 | SI32_FLASHCTRL_A_write_flash_key(SI32_FLASHCTRL_0, 0xA5); 84 | // 6. Write the multiple unlock value to KEY 85 | SI32_FLASHCTRL_A_write_flash_key(SI32_FLASHCTRL_0, 0xF2); 86 | // Write all the half-words in the array 87 | for(i = 0; i < num / 2; i++) 88 | { 89 | // 7. Write the data to WRDATA in right-justified format to 90 | // initiate the write 91 | SI32_FLASHCTRL_A_write_wrdata(SI32_FLASHCTRL_0, buf[i]); 92 | while(SI32_FLASHCTRL_A_is_flash_busy(SI32_FLASHCTRL_0)); 93 | } 94 | // 8. (optional) poll BUSYF if executing code from other than Flash Memory 95 | // We are executing code from Flash, so no need to poll. 96 | while(SI32_FLASHCTRL_A_is_buffer_full(SI32_FLASHCTRL_0)); 97 | SI32_FLASHCTRL_A_write_flash_key(SI32_FLASHCTRL_0, 0x5A); 98 | return 0; 99 | } 100 | 101 | 102 | //------------------------------------------------------------------------------ 103 | void flash_initialize(void) 104 | { 105 | // ENABLE FLASH CLOCK 106 | SI32_CLKCTRL_A_enable_apb_to_modules_0(SI32_CLKCTRL_0, 107 | SI32_CLKCTRL_A_APBCLKG0_FLCTRLCEN_ENABLED_U32); 108 | // 1. Enable VDD Supply Monitor and set as a reset source 109 | SI32_VMON_A_enable_vdd_supply_monitor(SI32_VMON_0); 110 | SI32_RSTSRC_A_enable_vdd_monitor_reset_source(SI32_RSTSRC_0); 111 | } 112 | 113 | //-eof-------------------------------------------------------------------------- 114 | -------------------------------------------------------------------------------- /src/uart.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (c) 2011 by Silicon Laboratories Inc. All rights reserved. 3 | // The program contained in this listing is proprietary to Silicon Laboratories, 4 | // headquartered in Austin, Texas, U.S.A. and is subject to worldwide copyright 5 | // protection, including protection under the United States Copyright Act of 1976 6 | // as an unpublished work, pursuant to Section 104 and Section 408 of Title XVII 7 | // of the United States code. Unauthorized copying, adaptation, distribution, 8 | // use, or display is prohibited by this law. 9 | // 10 | // Silicon Laboratories provides this software solely and exclusively 11 | // for use on Silicon Laboratories' microcontroller products. 12 | // 13 | // This software is provided "as is". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 14 | // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 15 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 16 | // SILICON LABORATORIES SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, 17 | // INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 18 | //------------------------------------------------------------------------------ 19 | 20 | //============================================================================== 21 | // WARNING: 22 | // 23 | // This file is auto-generated by AppBuilder and should not be modified. 24 | // Any hand modifications will be lost if the project is regenerated. 25 | //============================================================================== 26 | // library 27 | #include 28 | // hal 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | // application 35 | #include "config.h" 36 | #include "uart.h" 37 | extern volatile uint32_t msTicks; 38 | #define UART_TIME_OUT 1000 // 1 second time out 39 | //============================================================================== 40 | //SUPPORT FUNCTIONS 41 | //============================================================================== 42 | #if 0 43 | //------------------------------------------------------------------------------ 44 | // UART0_send_char() 45 | // 46 | // Outputs a single character to UART0. This function is called by 47 | // a modified version of fputc() defined in "retarget_arm.c". 48 | //------------------------------------------------------------------------------ 49 | void UART0_send_char(uint8_t val) 50 | { 51 | // Block if the output buffer is full 52 | while (SI32_UART_A_read_tx_fifo_count(SI32_UART_0) >= 4); 53 | 54 | // Write character to the output buffer 55 | SI32_UART_A_write_data_u8(SI32_UART_0, val); 56 | } 57 | 58 | //------------------------------------------------------------------------------ 59 | // UART0_get_char() 60 | // 61 | // Returns a single character received from UART0. This function is called by 62 | // a modified version of fgetc() defined in "retarget_arm.c". 63 | // 64 | // Note: This is a blocking function. 65 | //------------------------------------------------------------------------------ 66 | int8_t UART0_get_char(uint8_t *c) 67 | { 68 | // Block if input buffer is empty 69 | if (SI32_UART_A_read_rx_fifo_count(SI32_UART_0) != 0) 70 | { 71 | // Read character from the input buffer 72 | *c = SI32_UART_A_read_data_u8(SI32_UART_0); 73 | return 0; 74 | } 75 | return -1; 76 | } 77 | #endif 78 | 79 | void uart_send_data(unsigned char *data, unsigned int count) 80 | { 81 | while(count--) 82 | { 83 | // Block if the output buffer is full 84 | while (SI32_UART_A_read_tx_fifo_count(SI32_UART_0) >= 4); 85 | // Write character to the output buffer 86 | SI32_UART_A_write_data_u8(SI32_UART_0, *data++); 87 | } 88 | } 89 | 90 | int uart_get_data(unsigned char *data, unsigned int count) 91 | { 92 | unsigned int time_out; 93 | while(count--) 94 | { 95 | time_out = msTicks + UART_TIME_OUT; 96 | while(SI32_UART_A_read_rx_fifo_count(SI32_UART_0) == 0) 97 | { 98 | if(time_out < msTicks) 99 | { 100 | return -1; 101 | } 102 | } 103 | *data++ = SI32_UART_A_read_data_u8(SI32_UART_0); 104 | } 105 | return 0; 106 | } 107 | #if 0 108 | void print_hex(unsigned int code) 109 | { 110 | int i; 111 | unsigned int tmp; 112 | UART0_send_char('0'); 113 | UART0_send_char('x'); 114 | for(i = 0; i < 8; i++) 115 | { 116 | tmp = (code & 0xF0000000) >> 28; 117 | code <<= 4; 118 | if (tmp <= 9) 119 | { 120 | tmp +=0x30; 121 | } 122 | else 123 | { 124 | tmp += (0x41 - 10); 125 | } 126 | UART0_send_char(tmp); 127 | } 128 | UART0_send_char(0x0a); // LF 129 | UART0_send_char(0x0d); // CR 130 | } 131 | #endif 132 | //------------------------------------------------------------------------------ 133 | void UART0_initialize(void) 134 | { 135 | SI32_PBCFG_A_enable_crossbar_0(SI32_PBCFG_0); 136 | // UART PINS TO PROPER CONFIG (TX = PB1.12, RX = PB1.13) 137 | SI32_PBSTD_A_set_pins_push_pull_output(SI32_PBSTD_1, 0x0001000); 138 | SI32_PBSTD_A_set_pins_digital_input(SI32_PBSTD_1, 0x00002000); 139 | SI32_PBSTD_A_write_pbskipen(SI32_PBSTD_0, 0x0000FFFF); 140 | SI32_PBSTD_A_write_pbskipen(SI32_PBSTD_1, 0x00000FFF); 141 | // BRING OUT UART 142 | SI32_PBCFG_A_enable_xbar0h_peripherals(SI32_PBCFG_0, SI32_PBCFG_A_XBAR0H_UART0EN); 143 | 144 | // ENABLE UART0 CLOCK 145 | SI32_CLKCTRL_A_enable_apb_to_modules_0(SI32_CLKCTRL_0, 146 | SI32_CLKCTRL_A_APBCLKG0_UART0); 147 | 148 | // SETUP UART. BAUD RATE (9600 baud, APB = System Clock) 149 | SI32_UART_A_enter_full_duplex_mode(SI32_UART_0); 150 | SI32_UART_A_set_tx_baudrate(SI32_UART_0, (SystemCoreClock / (2 * UART_BAUD_RATE)) - 1); 151 | SI32_UART_A_set_rx_baudrate(SI32_UART_0, (SystemCoreClock / (2 * UART_BAUD_RATE)) - 1); 152 | 153 | // SETUP TX (8-bit, 1stop, no-parity) 154 | SI32_UART_A_select_tx_data_length(SI32_UART_0, 8); 155 | SI32_UART_A_enable_tx_start_bit(SI32_UART_0); 156 | SI32_UART_A_enable_tx_stop_bit(SI32_UART_0); 157 | SI32_UART_A_disable_tx_parity_bit(SI32_UART_0); 158 | SI32_UART_A_select_tx_stop_bits(SI32_UART_0, SI32_UART_A_STOP_BITS_1_BIT); 159 | SI32_UART_A_disable_tx_signal_inversion(SI32_UART_0); 160 | SI32_UART_A_enable_tx(SI32_UART_0); 161 | 162 | // SETUP RX 163 | SI32_UART_A_select_rx_data_length(SI32_UART_0, 8); 164 | SI32_UART_A_enable_rx_start_bit(SI32_UART_0); 165 | SI32_UART_A_enable_rx_stop_bit(SI32_UART_0); 166 | SI32_UART_A_select_rx_stop_bits(SI32_UART_0, SI32_UART_A_STOP_BITS_1_BIT); 167 | SI32_UART_A_disable_rx_signal_inversion(SI32_UART_0); 168 | SI32_UART_A_select_rx_fifo_threshold_1(SI32_UART_0); 169 | SI32_UART_A_enable_rx(SI32_UART_0); 170 | } 171 | 172 | //-eof-------------------------------------------------------------------------- 173 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (c) 2011 by Silicon Laboratories Inc. All rights reserved. 3 | // The program contained in this listing is proprietary to Silicon Laboratories, 4 | // headquartered in Austin, Texas, U.S.A. and is subject to worldwide copyright 5 | // protection, including protection under the United States Copyright Act of 1976 6 | // as an unpublished work, pursuant to Section 104 and Section 408 of Title XVII 7 | // of the United States code. Unauthorized copying, adaptation, distribution, 8 | // use, or display is prohibited by this law. 9 | // 10 | // Silicon Laboratories provides this software solely and exclusively 11 | // for use on Silicon Laboratories' microcontroller products. 12 | // 13 | // This software is provided "as is". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 14 | // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 15 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 16 | // SILICON LABORATORIES SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, 17 | // INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 18 | //------------------------------------------------------------------------------ 19 | // library 20 | #include 21 | // hal 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "config.h" 28 | #include "uart.h" 29 | #include "flash.h" 30 | volatile uint32_t msTicks; 31 | #define RECV_BUFFER_SIZE 512 32 | unsigned char data_buf[RECV_BUFFER_SIZE]; 33 | 34 | /* other code*/ 35 | //============================================================================== 36 | //1st LEVEL INTERRUPT HANDLERS 37 | //============================================================================== 38 | void SysTick_Handler(void) 39 | { 40 | msTicks++; 41 | /*NO SENCOND LEVEL HANDERL SPESIFIED*/ 42 | } 43 | 44 | void mySystemInit(void) 45 | { 46 | SI32_WDTIMER_A_stop_counter (SI32_WDTIMER_0); 47 | // Enable the APB clock to the PB registers 48 | SI32_CLKCTRL_A_enable_apb_to_modules_0(SI32_CLKCTRL_0, SI32_CLKCTRL_A_APBCLKG0_PB0); 49 | SI32_PBSTD_A_set_pins_push_pull_output(SI32_PBSTD_1, 0x00000008); 50 | 51 | SI32_PBCFG_A_enable_crossbar_1(SI32_PBCFG_0); 52 | SI32_PBSTD_A_set_pins_digital_input(SI32_PBSTD_2,0x00000300); 53 | // Enable the LED drivers (P2.10, P2.11) 54 | SI32_PBSTD_A_set_pins_push_pull_output(SI32_PBSTD_2, 0x00000C00); 55 | SysTick_Config(SystemCoreClock / 1000); 56 | // set Priority for Cortex-M0 System Interrupts. 57 | NVIC_SetPriority(SysTick_IRQn, (1 << __NVIC_PRIO_BITS) - 1); 58 | 59 | } 60 | 61 | // Returns a non-zero value if an update is needed 62 | unsigned int check_update_requirement(void) 63 | { 64 | // PB2.8 high require update, low -- run application. 65 | if (SI32_PBSTD_A_read_pin(SI32_PBSTD_2,8)) 66 | { 67 | return 1; 68 | } 69 | else 70 | { 71 | return 0; 72 | } 73 | } 74 | 75 | #define FLASH_SECTOR_SIZE 0x400 76 | 77 | #define CMD_WRITE_FLASH 0x31 78 | #define CMD_READ_FLASH 0x11 79 | #define CMD_ERASE_FLASH 0x43 80 | #define CMD_UNKNOW 0xFF 81 | 82 | #define RES_ACK 0x79 83 | #define RES_NACK 0x1F 84 | #define RES_UNKNOW 0xEE 85 | 86 | void bl_send_ack(unsigned char ack) 87 | { 88 | unsigned char res = ack; 89 | uart_send_data(&res, 1); 90 | } 91 | 92 | int bl_get_cmd(void) 93 | { 94 | unsigned char *ptr = data_buf; 95 | if (uart_get_data(ptr, 2) == 0) 96 | { 97 | if (ptr[0] != (ptr[1] ^ 0xFF)) 98 | { 99 | bl_send_ack(RES_NACK); 100 | return -2; 101 | } 102 | else 103 | { 104 | bl_send_ack(RES_ACK); 105 | return 0; 106 | } 107 | } 108 | return -1; 109 | } 110 | 111 | void bl_write_flash() 112 | { 113 | int i; 114 | unsigned int addr, len; 115 | unsigned char crc; 116 | unsigned char *ptr = data_buf; 117 | // get address 118 | if (uart_get_data(ptr, 5) == 0) 119 | { 120 | crc = ptr[0] ^ ptr[1] ^ ptr[2] ^ ptr[3]; 121 | if (crc == ptr[4]) 122 | { 123 | addr = ptr[3] | (ptr[2] << 8) | (ptr[1] << 16) | (ptr[0] << 24); 124 | } 125 | } 126 | // send ack 127 | bl_send_ack(RES_ACK); 128 | // get data len 129 | uart_get_data(ptr, 1); 130 | len = ptr[0] + 1; 131 | // get data and crc 132 | if (uart_get_data(ptr, len + 1) == 0) 133 | { 134 | crc = 0xFF; 135 | for (i = 0; i < len; i++) 136 | { 137 | crc = crc ^ ptr[i]; 138 | } 139 | } 140 | //write flash 141 | if (crc == ptr[len]) 142 | { 143 | if ((addr >= USER_CODE_ADDRESS) && addr < TOP_CODE_ADDRESS) 144 | { 145 | flash_write_data(ptr, addr, len); 146 | } 147 | } 148 | // send ack 149 | bl_send_ack(RES_ACK); 150 | } 151 | 152 | void bl_read_flash() 153 | { 154 | int i; 155 | unsigned int addr, len = 0; 156 | unsigned char crc; 157 | unsigned char *ptr = data_buf; 158 | // get address 159 | if (uart_get_data(ptr, 5) == 0) 160 | { 161 | crc = ptr[0] ^ ptr[1] ^ ptr[2] ^ ptr[3]; 162 | if (crc == ptr[4]) 163 | { 164 | addr = ptr[3] | (ptr[2] << 8) | (ptr[1] << 16) | (ptr[0] << 24); 165 | } 166 | } 167 | // send ack 168 | bl_send_ack(RES_ACK); 169 | // get data len and crc 170 | if(uart_get_data(ptr, 2) == 0) 171 | { 172 | if((ptr[0] ^ 0xFF) == ptr[1]) 173 | { 174 | len = ptr[0] + 1; 175 | } 176 | } 177 | // send ack 178 | bl_send_ack(RES_ACK); 179 | // send data 180 | for(i =0; i < len; i++) 181 | { 182 | ptr[i]= *(unsigned char *)(addr++); 183 | } 184 | uart_send_data(ptr,len); 185 | } 186 | 187 | void bl_erase_flash() 188 | { 189 | int i; 190 | unsigned int addr, len; 191 | unsigned char crc; 192 | unsigned char *ptr = data_buf; 193 | 194 | // get len 195 | if (uart_get_data(ptr, 1) == 0) 196 | { 197 | len = (ptr[0] + 1) & 0xFF; // maximum sector number is 256 198 | } 199 | // get sector sequence and crc 200 | if (uart_get_data(ptr, len + 1) == 0) 201 | { 202 | crc = 0xFF; 203 | for (i = 0; i < len; i++) 204 | { 205 | crc = crc ^ ptr[i]; 206 | } 207 | } 208 | // erase flash sectors 209 | if (crc == ptr[len]) 210 | { 211 | for (i = 0; i < len; i++) 212 | { 213 | addr = ptr[i] * FLASH_SECTOR_SIZE; 214 | if ((addr >= USER_CODE_ADDRESS) && addr < TOP_CODE_ADDRESS) 215 | { 216 | flash_erase_page(addr); 217 | } 218 | } 219 | } 220 | // send ack 221 | bl_send_ack(RES_ACK); 222 | } 223 | //============================================================================== 224 | // myApplication. 225 | //============================================================================== 226 | int main() 227 | { 228 | UART0_initialize(); 229 | flash_initialize(); 230 | while (1) 231 | { 232 | SI32_PBSTD_A_toggle_pins(SI32_PBSTD_2, 0xC00); 233 | // received CMD from host 234 | if (bl_get_cmd() == 0) 235 | { 236 | switch (data_buf[0]) 237 | { 238 | case CMD_WRITE_FLASH: 239 | bl_write_flash(); 240 | break; 241 | case CMD_READ_FLASH: 242 | bl_read_flash(); 243 | break; 244 | case CMD_ERASE_FLASH: 245 | bl_erase_flash(); 246 | break; 247 | default: 248 | break; 249 | } 250 | } 251 | }// while(1) 252 | 253 | } 254 | //---eof------------------------------------------------------------------------ 255 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | sim3u1xx_Bootloader 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.buildLocation 34 | ${workspace_loc:/Blinky/Debug} 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | true 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | full,incremental, 73 | 74 | 75 | 76 | 77 | 78 | org.eclipse.cdt.core.cnature 79 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 80 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 81 | 82 | 83 | 84 | src/sim3u1xx 85 | 2 86 | SI32_PATH/si32Hal/sim3u1xx 87 | 88 | 89 | src/sim3u1xx/SI32_AES_A_Type.c 90 | 1 91 | SI32_PATH/si32hal/si32_modules/SI32_AES_A_Type.c 92 | 93 | 94 | src/sim3u1xx/SI32_CAPSENSE_A_Type.c 95 | 1 96 | SI32_PATH/si32hal/si32_modules/SI32_CAPSENSE_A_Type.c 97 | 98 | 99 | src/sim3u1xx/SI32_CMP_A_Type.c 100 | 1 101 | SI32_PATH/si32hal/si32_modules/SI32_CMP_A_Type.c 102 | 103 | 104 | src/sim3u1xx/SI32_CRC_A_Type.c 105 | 1 106 | SI32_PATH/si32hal/si32_modules/SI32_CRC_A_Type.c 107 | 108 | 109 | src/sim3u1xx/SI32_DMACTRL_A_Type.c 110 | 1 111 | SI32_PATH/si32hal/si32_modules/SI32_DMACTRL_A_Type.c 112 | 113 | 114 | src/sim3u1xx/SI32_DMADESC_A_Type.c 115 | 1 116 | SI32_PATH/si32hal/si32_modules/SI32_DMADESC_A_Type.c 117 | 118 | 119 | src/sim3u1xx/SI32_EMIFIF_A_Type.c 120 | 1 121 | SI32_PATH/si32hal/si32_modules/SI32_EMIFIF_A_Type.c 122 | 123 | 124 | src/sim3u1xx/SI32_EMIF_A_Type.c 125 | 1 126 | SI32_PATH/si32hal/si32_modules/SI32_EMIF_A_Type.c 127 | 128 | 129 | src/sim3u1xx/SI32_EPCACH_A_Type.c 130 | 1 131 | SI32_PATH/si32hal/si32_modules/SI32_EPCACH_A_Type.c 132 | 133 | 134 | src/sim3u1xx/SI32_EPCA_A_Type.c 135 | 1 136 | SI32_PATH/si32hal/si32_modules/SI32_EPCA_A_Type.c 137 | 138 | 139 | src/sim3u1xx/SI32_EXTOSC_A_Type.c 140 | 1 141 | SI32_PATH/si32hal/si32_modules/SI32_EXTOSC_A_Type.c 142 | 143 | 144 | src/sim3u1xx/SI32_EXTVREG_A_Type.c 145 | 1 146 | SI32_PATH/si32hal/si32_modules/SI32_EXTVREG_A_Type.c 147 | 148 | 149 | src/sim3u1xx/SI32_FLASHCTRL_A_Type.c 150 | 1 151 | SI32_PATH/si32hal/si32_modules/SI32_FLASHCTRL_A_Type.c 152 | 153 | 154 | src/sim3u1xx/SI32_I2C_A_Type.c 155 | 1 156 | SI32_PATH/si32hal/si32_modules/SI32_I2C_A_Type.c 157 | 158 | 159 | src/sim3u1xx/SI32_I2S_A_Type.c 160 | 1 161 | SI32_PATH/si32hal/si32_modules/SI32_I2S_A_Type.c 162 | 163 | 164 | src/sim3u1xx/SI32_IDAC_A_Type.c 165 | 1 166 | SI32_PATH/si32hal/si32_modules/SI32_IDAC_A_Type.c 167 | 168 | 169 | src/sim3u1xx/SI32_IVC_A_Type.c 170 | 1 171 | SI32_PATH/si32hal/si32_modules/SI32_IVC_A_Type.c 172 | 173 | 174 | src/sim3u1xx/SI32_LPTIMER_A_Type.c 175 | 1 176 | SI32_PATH/si32hal/si32_modules/SI32_LPTIMER_A_Type.c 177 | 178 | 179 | src/sim3u1xx/SI32_PCACH_A_Type.c 180 | 1 181 | SI32_PATH/si32hal/si32_modules/SI32_PCACH_A_Type.c 182 | 183 | 184 | src/sim3u1xx/SI32_PCA_A_Type.c 185 | 1 186 | SI32_PATH/si32hal/si32_modules/SI32_PCA_A_Type.c 187 | 188 | 189 | src/sim3u1xx/SI32_PLL_A_Type.c 190 | 1 191 | SI32_PATH/si32hal/si32_modules/SI32_PLL_A_Type.c 192 | 193 | 194 | src/sim3u1xx/SI32_RTC_A_Type.c 195 | 1 196 | SI32_PATH/si32hal/si32_modules/SI32_RTC_A_Type.c 197 | 198 | 199 | src/sim3u1xx/SI32_SARADC_A_Type.c 200 | 1 201 | SI32_PATH/si32hal/si32_modules/SI32_SARADC_A_Type.c 202 | 203 | 204 | src/sim3u1xx/SI32_SPI_A_Type.c 205 | 1 206 | SI32_PATH/si32hal/si32_modules/SI32_SPI_A_Type.c 207 | 208 | 209 | src/sim3u1xx/SI32_SSG_A_Type.c 210 | 1 211 | SI32_PATH/si32hal/si32_modules/SI32_SSG_A_Type.c 212 | 213 | 214 | src/sim3u1xx/SI32_TIMER_A_Type.c 215 | 1 216 | SI32_PATH/si32hal/si32_modules/SI32_TIMER_A_Type.c 217 | 218 | 219 | src/sim3u1xx/SI32_UART_A_Type.c 220 | 1 221 | SI32_PATH/si32hal/si32_modules/SI32_UART_A_Type.c 222 | 223 | 224 | src/sim3u1xx/SI32_USART_A_Type.c 225 | 1 226 | SI32_PATH/si32hal/si32_modules/SI32_USART_A_Type.c 227 | 228 | 229 | src/sim3u1xx/SI32_USBEP_A_Type.c 230 | 1 231 | SI32_PATH/si32hal/si32_modules/SI32_USBEP_A_Type.c 232 | 233 | 234 | src/sim3u1xx/SI32_USB_A_Type.c 235 | 1 236 | SI32_PATH/si32hal/si32_modules/SI32_USB_A_Type.c 237 | 238 | 239 | src/sim3u1xx/SI32_VMON_A_Type.c 240 | 1 241 | SI32_PATH/si32hal/si32_modules/SI32_VMON_A_Type.c 242 | 243 | 244 | src/sim3u1xx/SI32_VREF_A_Type.c 245 | 1 246 | SI32_PATH/si32hal/si32_modules/SI32_VREF_A_Type.c 247 | 248 | 249 | src/sim3u1xx/SI32_VREG_A_Type.c 250 | 1 251 | SI32_PATH/si32hal/si32_modules/SI32_VREG_A_Type.c 252 | 253 | 254 | src/sim3u1xx/SI32_WDTIMER_A_Type.c 255 | 1 256 | SI32_PATH/si32hal/si32_modules/SI32_WDTIMER_A_Type.c 257 | 258 | 259 | 260 | 261 | 1337838653412 262 | 263 | 10 264 | 265 | org.eclipse.ui.ide.multiFilter 266 | 1.0-name-matches-true-false-ARM 267 | 268 | 269 | 270 | 1337838653412 271 | 272 | 10 273 | 274 | org.eclipse.ui.ide.multiFilter 275 | 1.0-name-matches-true-false-IAR 276 | 277 | 278 | 279 | 1337838653428 280 | 281 | 22 282 | 283 | org.eclipse.ui.ide.multiFilter 284 | 1.0-name-matches-false-false-*_arm.* 285 | 286 | 287 | 288 | 1337838653444 289 | 290 | 22 291 | 292 | org.eclipse.ui.ide.multiFilter 293 | 1.0-name-matches-false-false-*_iar.* 294 | 295 | 296 | 297 | 0 298 | src/sim3u1xx 299 | 5 300 | 301 | org.eclipse.ui.ide.multiFilter 302 | 1.0-name-matches-false-false-*.c 303 | 304 | 305 | 306 | 0 307 | src/sim3u1xx 308 | 5 309 | 310 | org.eclipse.ui.ide.multiFilter 311 | 1.0-name-matches-false-false-*.h 312 | 313 | 314 | 315 | 316 | -------------------------------------------------------------------------------- /sim32loader.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # -*- coding: utf-8 -*- 4 | # vim: sw=4:ts=4:si:et:enc=utf-8 5 | 6 | # Author: Ivan A-R 7 | # Project page: http://tuxotronic.org/wiki/projects/stm32loader 8 | # 9 | # This file is part of stm32loader. 10 | # 11 | # stm32loader is free software; you can redistribute it and/or modify it under 12 | # the terms of the GNU General Public License as published by the Free 13 | # Software Foundation; either version 3, or (at your option) any later 14 | # version. 15 | # 16 | # stm32loader is distributed in the hope that it will be useful, but WITHOUT ANY 17 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19 | # for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with stm32loader; see the file COPYING3. If not see 23 | # . 24 | 25 | import sys, getopt 26 | import serial 27 | import time 28 | import os 29 | 30 | try: 31 | from progressbar import * 32 | usepbar = 1 33 | except: 34 | usepbar = 0 35 | 36 | # Verbose level 37 | QUIET = 20 38 | 39 | def mdebug(level, message): 40 | if(QUIET >= level): 41 | print >> sys.stderr , message 42 | 43 | 44 | class CmdException(Exception): 45 | pass 46 | 47 | class CommandInterface: 48 | def open(self, aport='COM4', abaudrate=115200) : 49 | self.sp = serial.Serial( 50 | port=aport, 51 | baudrate=abaudrate, # baudrate 52 | bytesize=8, # number of databits 53 | parity=serial.PARITY_EVEN, 54 | stopbits=1, 55 | xonxoff=0, # enable software flow control 56 | rtscts=0, # disable RTS/CTS flow control 57 | timeout=5 # set a timeout value, None for waiting forever 58 | ) 59 | 60 | 61 | def _wait_for_ask(self, info = ""): 62 | # wait for ask 63 | try: 64 | ask = ord(self.sp.read()) 65 | except: 66 | raise CmdException("Can't read port or timeout") 67 | else: 68 | if ask == 0x79: 69 | # ACK 70 | return 1 71 | else: 72 | if ask == 0x1F: 73 | # NACK 74 | raise CmdException("NACK "+info) 75 | else: 76 | # Unknow responce 77 | raise CmdException("Unknow response. "+info+": "+hex(ask)) 78 | 79 | 80 | def reset(self): 81 | self.sp.setDTR(0) 82 | time.sleep(0.1) 83 | self.sp.setDTR(1) 84 | time.sleep(0.5) 85 | 86 | def initChip(self): 87 | # Set boot 88 | self.sp.setRTS(0) 89 | self.reset() 90 | # self.sp.write("a") 91 | # data = self.sp.read(69) 92 | # print "Readback" +data 93 | # self.sp.write("\x7F") # Syncro 94 | # return self._wait_for_ask("Syncro") 95 | 96 | def releaseChip(self): 97 | self.sp.setRTS(1) 98 | self.reset() 99 | 100 | def cmdGeneric(self, cmd): 101 | self.sp.write(chr(cmd)) 102 | self.sp.write(chr(cmd ^ 0xFF)) # Control byte 103 | return self._wait_for_ask(hex(cmd)) 104 | 105 | def cmdGet(self): 106 | if self.cmdGeneric(0x00): 107 | mdebug(10, "*** Get command"); 108 | len = ord(self.sp.read()) 109 | version = ord(self.sp.read()) 110 | mdebug(10, " Bootloader version: "+hex(version)) 111 | dat = map(lambda c: hex(ord(c)), self.sp.read(len)) 112 | mdebug(10, " Available commands: "+str(dat)) 113 | self._wait_for_ask("0x00 end") 114 | return version 115 | else: 116 | raise CmdException("Get (0x00) failed") 117 | 118 | def cmdGetVersion(self): 119 | if self.cmdGeneric(0x01): 120 | mdebug(10, "*** GetVersion command") 121 | version = ord(self.sp.read()) 122 | self.sp.read(2) 123 | self._wait_for_ask("0x01 end") 124 | mdebug(10, " Bootloader version: "+hex(version)) 125 | return version 126 | else: 127 | raise CmdException("GetVersion (0x01) failed") 128 | 129 | def cmdGetID(self): 130 | if self.cmdGeneric(0x02): 131 | mdebug(10, "*** GetID command") 132 | len = ord(self.sp.read()) 133 | id = self.sp.read(len+1) 134 | self._wait_for_ask("0x02 end") 135 | return id 136 | else: 137 | raise CmdException("GetID (0x02) failed") 138 | 139 | 140 | def _encode_addr(self, addr): 141 | byte3 = (addr >> 0) & 0xFF 142 | byte2 = (addr >> 8) & 0xFF 143 | byte1 = (addr >> 16) & 0xFF 144 | byte0 = (addr >> 24) & 0xFF 145 | crc = byte0 ^ byte1 ^ byte2 ^ byte3 146 | return (chr(byte0) + chr(byte1) + chr(byte2) + chr(byte3) + chr(crc)) 147 | 148 | 149 | def cmdReadMemory(self, addr, lng): 150 | assert(lng <= 256) 151 | if self.cmdGeneric(0x11): 152 | mdebug(10, "*** ReadMemory command") 153 | self.sp.write(self._encode_addr(addr)) 154 | self._wait_for_ask("0x11 address failed") 155 | N = (lng - 1) & 0xFF 156 | crc = N ^ 0xFF 157 | self.sp.write(chr(N) + chr(crc)) 158 | self._wait_for_ask("0x11 length failed") 159 | return map(lambda c: ord(c), self.sp.read(lng)) 160 | else: 161 | raise CmdException("ReadMemory (0x11) failed") 162 | 163 | 164 | def cmdGo(self, addr): 165 | if self.cmdGeneric(0x21): 166 | mdebug(10, "*** Go command") 167 | self.sp.write(self._encode_addr(addr)) 168 | self._wait_for_ask("0x21 go failed") 169 | else: 170 | raise CmdException("Go (0x21) failed") 171 | 172 | 173 | def cmdWriteMemory(self, addr, data): 174 | assert(len(data) <= 256) 175 | if self.cmdGeneric(0x31): 176 | mdebug(10, "*** Write memory command") 177 | self.sp.write(self._encode_addr(addr)) 178 | self._wait_for_ask("0x31 address failed") 179 | #map(lambda c: hex(ord(c)), data) 180 | lng = (len(data)-1) & 0xFF 181 | mdebug(10, " %s bytes to write" % [lng+1]); 182 | self.sp.write(chr(lng)) # len really 183 | crc = 0xFF 184 | for c in data: 185 | crc = crc ^ c 186 | self.sp.write(chr(c)) 187 | self.sp.write(chr(crc)) 188 | self._wait_for_ask("0x31 programming failed") 189 | mdebug(10, " Write memory done") 190 | else: 191 | raise CmdException("Write memory (0x31) failed") 192 | 193 | 194 | def cmdEraseMemory(self, sectors = None): 195 | if self.cmdGeneric(0x43): 196 | mdebug(10, "*** Erase memory command") 197 | if sectors is None: 198 | # Global erase 199 | self.sp.write(chr(0xFF)) 200 | self.sp.write(chr(0x00)) 201 | else: 202 | # Sectors erase 203 | self.sp.write(chr((len(sectors)-1) & 0xFF)) 204 | crc = 0xFF 205 | for c in sectors: 206 | crc = crc ^ c 207 | self.sp.write(chr(c)) 208 | self.sp.write(chr(crc)) 209 | self._wait_for_ask("0x43 erasing failed") 210 | mdebug(10, " Erase memory done") 211 | else: 212 | raise CmdException("Erase memory (0x43) failed") 213 | 214 | def cmdWriteProtect(self, sectors): 215 | if self.cmdGeneric(0x63): 216 | mdebug(10, "*** Write protect command") 217 | self.sp.write(chr((len(sectors)-1) & 0xFF)) 218 | crc = 0xFF 219 | for c in sectors: 220 | crc = crc ^ c 221 | self.sp.write(chr(c)) 222 | self.sp.write(chr(crc)) 223 | self._wait_for_ask("0x63 write protect failed") 224 | mdebug(10, " Write protect done") 225 | else: 226 | raise CmdException("Write Protect memory (0x63) failed") 227 | 228 | def cmdWriteUnprotect(self): 229 | if self.cmdGeneric(0x73): 230 | mdebug(10, "*** Write Unprotect command") 231 | self._wait_for_ask("0x73 write unprotect failed") 232 | self._wait_for_ask("0x73 write unprotect 2 failed") 233 | mdebug(10, " Write Unprotect done") 234 | else: 235 | raise CmdException("Write Unprotect (0x73) failed") 236 | 237 | def cmdReadoutProtect(self): 238 | if self.cmdGeneric(0x82): 239 | mdebug(10, "*** Readout protect command") 240 | self._wait_for_ask("0x82 readout protect failed") 241 | self._wait_for_ask("0x82 readout protect 2 failed") 242 | mdebug(10, " Read protect done") 243 | else: 244 | raise CmdException("Readout protect (0x82) failed") 245 | 246 | def cmdReadoutUnprotect(self): 247 | if self.cmdGeneric(0x92): 248 | mdebug(10, "*** Readout Unprotect command") 249 | self._wait_for_ask("0x92 readout unprotect failed") 250 | self._wait_for_ask("0x92 readout unprotect 2 failed") 251 | mdebug(10, " Read Unprotect done") 252 | else: 253 | raise CmdException("Readout unprotect (0x92) failed") 254 | 255 | 256 | # Complex commands section 257 | 258 | def readMemory(self, addr, lng): 259 | data = [] 260 | if usepbar: 261 | widgets = ['Reading: ', Percentage(),', ', ETA(), ' ', Bar()] 262 | pbar = ProgressBar(widgets=widgets,maxval=lng, term_width=79).start() 263 | 264 | while lng > 256: 265 | if usepbar: 266 | pbar.update(pbar.maxval-lng) 267 | else: 268 | mdebug(5, "Read %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256}) 269 | data = data + self.cmdReadMemory(addr, 256) 270 | addr = addr + 256 271 | lng = lng - 256 272 | if usepbar: 273 | pbar.update(pbar.maxval-lng) 274 | pbar.finish() 275 | else: 276 | mdebug(5, "Read %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256}) 277 | data = data + self.cmdReadMemory(addr, lng) 278 | return data 279 | 280 | def writeMemory(self, addr, data): 281 | lng = len(data) 282 | mdebug(5,"File length %(len)d bytes" %{'len':lng}) 283 | if usepbar: 284 | widgets = ['Writing: ', Percentage(),' ', ETA(), ' ', Bar()] 285 | pbar = ProgressBar(widgets=widgets, maxval=lng, term_width=79).start() 286 | 287 | offs = 0 288 | while lng > 256: 289 | if usepbar: 290 | pbar.update(pbar.maxval-lng) 291 | else: 292 | mdebug(5, "Write %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256}) 293 | self.cmdWriteMemory(addr, data[offs:offs+256]) 294 | offs = offs + 256 295 | addr = addr + 256 296 | lng = lng - 256 297 | if usepbar: 298 | pbar.update(pbar.maxval-lng) 299 | pbar.finish() 300 | else: 301 | mdebug(5, "Write %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256}) 302 | self.cmdWriteMemory(addr, data[offs:offs+lng] + ([0xFF] * (256-lng)) ) 303 | 304 | 305 | 306 | 307 | def __init__(self) : 308 | pass 309 | 310 | 311 | def usage(): 312 | print """Usage: %s [-hqVewvr] [-l length] [-p port] [-b baud] [-a addr] [file.bin] 313 | -h This help 314 | -q Quiet 315 | -V Verbose 316 | -e Erase 317 | -w Write 318 | -v Verify 319 | -r Read 320 | -l length Length of read 321 | -p port Serial port (default: /dev/tty.usbserial-ftCYPMYJ) 322 | -b baud Baud speed (default: 115200) 323 | -a addr Target address 324 | 325 | ./stm32loader.py -e -w -v example/main.bin 326 | 327 | """ % sys.argv[0] 328 | 329 | 330 | if __name__ == "__main__": 331 | 332 | # Import Psyco if available 333 | try: 334 | import psyco 335 | psyco.full() 336 | print "Using Psyco..." 337 | except ImportError: 338 | pass 339 | 340 | conf = { 341 | 'port': 'COM4', 342 | 'baud': 115200, 343 | 'address': 0x00001000, 344 | 'erase': 0, 345 | 'write': 0, 346 | 'verify': 0, 347 | 'read': 0, 348 | 'len': 1000, 349 | 'fname':'', 350 | } 351 | 352 | # http://www.python.org/doc/2.5.2/lib/module-getopt.html 353 | 354 | try: 355 | opts, args = getopt.getopt(sys.argv[1:], "hqVewvrp:b:a:l:") 356 | except getopt.GetoptError, err: 357 | # print help information and exit: 358 | print str(err) # will print something like "option -a not recognized" 359 | usage() 360 | sys.exit(2) 361 | 362 | QUIET = 5 363 | 364 | for o, a in opts: 365 | if o == '-V': 366 | QUIET = 10 367 | elif o == '-q': 368 | QUIET = 0 369 | elif o == '-h': 370 | usage() 371 | sys.exit(0) 372 | elif o == '-e': 373 | conf['erase'] = 1 374 | elif o == '-w': 375 | conf['write'] = 1 376 | elif o == '-v': 377 | conf['verify'] = 1 378 | elif o == '-r': 379 | conf['read'] = 1 380 | elif o == '-p': 381 | conf['port'] = a 382 | elif o == '-b': 383 | conf['baud'] = eval(a) 384 | elif o == '-a': 385 | conf['address'] = eval(a) 386 | elif o == '-l': 387 | conf['len'] = eval(a) 388 | # elif o == '-f': 389 | # conf['fname'] = a 390 | else: 391 | assert False, "unhandled option" 392 | 393 | cmd = CommandInterface() 394 | cmd.open(conf['port'], conf['baud']) 395 | mdebug(10, "Open port %(port)s, baud %(baud)d" % {'port':conf['port'], 'baud':conf['baud']}) 396 | try: 397 | try: 398 | cmd.initChip() 399 | except: 400 | print "Can't init. Ensure that BOOT0 is enabled and reset device" 401 | 402 | # bootversion = cmd.cmdGet() 403 | # mdebug(0, "Bootloader version %X" % bootversion) 404 | # mdebug(0, "Chip id `%s'" % str(map(lambda c: hex(ord(c)), cmd.cmdGetID()))) 405 | # cmd.cmdGetVersion() 406 | # cmd.cmdGetID() 407 | # cmd.cmdReadoutUnprotect() 408 | # cmd.cmdWriteUnprotect() 409 | # cmd.cmdWriteProtect([0, 1]) 410 | print args[0] 411 | if (conf['write'] or conf['verify']): 412 | data = map(lambda c: ord(c), file(args[0],'rb').read()) 413 | 414 | if conf['erase']: 415 | cmd.cmdEraseMemory() 416 | 417 | if conf['write']: 418 | sec_num = len(data) / 1024 + 1 419 | offset = conf['address'] / 1024 420 | sectors = range(offset,sec_num+offset) 421 | print sectors 422 | cmd.cmdEraseMemory(sectors) 423 | cmd.writeMemory(conf['address'], data) 424 | 425 | if conf['verify']: 426 | verify = cmd.readMemory(conf['address'], len(data)) 427 | if(data == verify): 428 | print "Verification OK" 429 | else: 430 | print "Verification FAILED" 431 | print str(len(data)) + ' vs ' + str(len(verify)) 432 | for i in xrange(0, len(data)): 433 | if data[i] != verify[i]: 434 | print hex(i) + ': ' + hex(data[i]) + ' vs ' + hex(verify[i]) 435 | 436 | if not conf['write'] and conf['read']: 437 | print "We are reading " 438 | rdata = cmd.readMemory(conf['address'], conf['len']) 439 | # file(conf['fname'], 'wb').write(rdata) 440 | file(args[0], 'wb').write(''.join(map(chr,rdata))) 441 | 442 | # cmd.cmdGo(addr + 0x04) 443 | finally: 444 | cmd.releaseChip() 445 | 446 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Make own bootloader for ARM Cortex M3 2 | ===================================== 3 | 4 | ## 1 Bootloader overview 5 | A Bootloader is a small application that is used to load new user applications to devices. After it is loaded, the new user application is able to run in the MCU. It works with two modes, user application and Bootloader mode. 6 | 7 | We are discussing common way to implement Bootloader on your own Arm Cortez M3. And we choose Silicon labs SIM3U167 MCU as example for making Bootloader. 8 | 9 | ## 2 Bootloader design method 10 | ### 2.1 Bootloader need to run in SRAM 11 | ### 2.1.1 Bootloader behavior 12 | Bootloader is an application which runs from internal flash, in case of update Bootloader itself requirement, the Bootloader code needed to be copied into internal SRAM and run. 13 | * The Bootloader code address need to set in SRAM in link file 14 | * The vector table entry needs to update from flash to SRAM after copying Bootloader into SRAM. 15 | * The Reset vector address we want to keep its original address, since it is hardware behavior. 16 | 17 | ### 2.1.2 Arm Cortex M3 internal memory map 18 | * Internal flash address (0x00000000-0x1FFFFFFF). 19 | * Internal SRAM address (0x20000000-0x3FFFFFFF). 20 | * Peripherals address (0x40000000-0x5FFFFFFF). 21 | * System levels address (0xE0000000-0xFFFFFFFF). 22 | 23 | So base on above memory, we need to copy code from internal flash address to internal SRAM address. And access UART peripheral register in Peripherals address, and change vector table address need to access register in System levels address. 24 | 25 | ### 2.1.3 Link file 26 | To make sure Bootloader code is located in SRAM, we need to specific the address setting in link file. Now we have a Bootloader_link.ld as our link file. We would talk detail about how to write link file, we assume that you 27 | already know the basic knowledge about link file. 28 | ```ld 29 | .text 0x20000000 : AT (0x00000000) 30 | { 31 | . = ALIGN(4); 32 | _text = .; 33 | KEEP(*(.isr_vector)) 34 | *(.text*) 35 | *(.rodata*) 36 | _etext = .; 37 | } 38 | ``` 39 | 40 | The first line `.text 0x20000000 : AT (0x00000000)` means .text section load address start from 0x20000000, store address from 0x00000000. 41 | 42 | Inside the description, we put `.isr_vector`, `*(.text*)` and `*(.rodata*)` in .text section. The `.isr_vector` is vector entry; we put it in front of Bootloader code. 43 | 44 | And then we have other two sections .data and .bss 45 | ```ld 46 | .data 0x20000000 + SIZEOF(.text) : AT (LOADADDR(.text) + SIZEOF(.text)) 47 | { 48 | _data = .; 49 | *(.data*) 50 | _edata = .; 51 | } 52 | 53 | .bss 0x20000000 + SIZEOF(.text) + SIZEOF(.data) : 54 | AT (LOADADDR(.data) + SIZEOF(.data)) 55 | { 56 | _bss = .; 57 | *(.bss*) 58 | *(COMMON) 59 | _ebss = .; 60 | } 61 | ``` 62 | And now the link file is ready. 63 | 64 | ### 2.1.4 Vector table introduction. 65 | By default Arm Cortex M3 vector table starts at memory address 0. The vector table can be relocated to other memory locations in the code or Random Access Memroy(RAM) region where the RAM is so that we can change the handlers during run time. This is down by settting a register in the NVIC called the vector table offset register (address `0xE000ED08`). You need to have the following (at a minimum). 66 | * Initial main stack pointer value 67 | * Reset vector 68 | * NMI vector 69 | * Hard fault vector 70 | 71 | ### 2.1.5 Vector table in startup file 72 | We prepare startup_sim3u1xx.S for our startup file. In this file, we will have the vector table, code copy from flash to SRAM, jump to user application code. Let us have a look on vector table first. We can see .isr_vector in link file is the vector table section name. 73 | 74 | ```asm 75 | .section .isr_vector 76 | Vectors: 77 | .word 0x20008000 // The initial stack pointer 78 | .word ResetISR - 0x20000000 // The reset handler 79 | .word NMI_Handler // The NMI handler 80 | .word HardFault_Handler // The hard fault handler 81 | .word Default_Handler // The MPU fault handler 82 | .word Default_Handler // The bus fault handler 83 | .word Default_Handler // The usage fault handler 84 | .word 0 // Reserved 85 | .word 0 // Reserved 86 | .word 0 // Reserved 87 | .word 0 // Reserved 88 | .word Default_Handler // SVCall handler 89 | .word Default_Handler // Debug monitor handler 90 | .word 0 // Reserved 91 | .word Default_Handler // The PendSV handler 92 | .extern SysTick_Handler 93 | .word SysTick_Handler // The SysTick handler 94 | ``` 95 | 96 | Note: 97 | * Stack pointer we set is 0x20008000, that is because SIM3U167 internal SRAM size is 32KB (0x20000000-0x20007FFF). 98 | * Reset handler address we minus 0x20000000, that is because, Arm will check the value in second word and jump to address in it. Since all Bootloader code was locate at SRAM (0x20000000), but at the time power up, all the codes are in internal flash, and didn’t copy to SRAM yet. So we have to set ResetISR address point to flash in order Arm can execute code correctly. 99 | * Other exception handlers. We need to keep some import exception handlers; we will see HardFault_Handler happens many times during the Bootloader development in case the address not matches. 100 | 101 | ### 2.1.6 ResetISR implements. 102 | We need to handle code that Arm will first execute, ResetISR. What does this function do? 103 | * Copy code to SRAM and initialize variables. 104 | * Initialize system hardware 105 | * Check external pin status to run under Bootloader or user application mode. 106 | 107 | Here is the cod structure of ResetISR 108 | 109 | ```asm 110 | .globl ResetISR 111 | .thumb_func 112 | ResetISR: 113 | // Copy code from flash to SRAM 114 | bl CopyCode2SRAM 115 | .extern SystemInit 116 | bl SystemInit 117 | // Check if update is needed 118 | .extern check_update_requirement 119 | bl check_update_requirement 120 | cbz r0, RunUserCode 121 | 122 | .extern main 123 | bl main 124 | ``` 125 | 126 | ### 2.1.6.1 Copy code to SRAM and initialize variables. 127 | Let us take a look on CopyCode2SRAM function. 128 | ```asm 129 | .text 130 | .thumb_func 131 | CopyCode2SRAM: 132 | // Copy the text and data sections from flash to SRAM. 133 | movs r0, #0x00000000 134 | ldr r1, =0x20000000 135 | .extern _bss 136 | ldr r2, =_bss 137 | copy_loop: 138 | ldr r3, [r0], #4 139 | str r3, [r1], #4 140 | cmp r1, r2 141 | blt copy_loop 142 | 143 | // Zero fill the bss segment 144 | movs r0, #0x00000000 145 | .extern _ebss 146 | ldr r2, =_ebss 147 | zero_loop: 148 | str r0, [r1], #4 149 | cmp r1, r2 150 | blt zero_loop 151 | 152 | // Set the vector table pointer to SRAM. 153 | ldr r0, =0xe000ed08 154 | ldr r1, =0x20000000 155 | str r1, [r0] 156 | // set return address to SRAM and return 157 | orr lr, lr, #0x20000000 158 | bx lr 159 | ``` 160 | 161 | The code is very simple. 162 | 163 | * Copy `.text` and `.data` from flash to SRAM 164 | * Zero `.bss` segment in SRAM 165 | * Relocate vector table address and return to SRAM to execute. 166 | 167 | Note: 168 | * `_bss` is defined in link file, which is address after .text and .data. So the copy_loop is copy code from flash to SRAM until it reaches _bss address. 169 | * `_ess` is defined in linke file, which is address after .bss segment. So zero_lopp, just write “0” into SRAM follow the .text and .data segment, until it reaches _ebss address. 170 | * And finally, we write new vector table address (0x20000000) into register `0xe00ed08`, and set return address to SRAM and return. 171 | 172 | ### 2.1.6.2 Initialize system hardware 173 | The idea is very simple too, set necessary hardware environment we need in startup file. For instance, we need to check GPIO status to choose running mode. We have to enable clock to GPIO and set the GPIO as input mode and something like that. I paste the example of SystemInit. 174 | 175 | ```c 176 | void mySystemInit(void) 177 | { 178 | SI32_WDTIMER_A_stop_counter (SI32_WDTIMER_0); 179 | // Enable the APB clock to the PB registers 180 | SI32_CLKCTRL_A_enable_apb_to_modules_0(SI32_CLKCTRL_0, SI32_CLKCTRL_A_APBCLKG0_PB0); 181 | SI32_PBSTD_A_set_pins_push_pull_output(SI32_PBSTD_1, 0x00000008); 182 | 183 | SI32_PBCFG_A_enable_crossbar_1(SI32_PBCFG_0); 184 | SI32_PBSTD_A_set_pins_digital_input(SI32_PBSTD_2,0x00000300); 185 | // Enable the LED drivers (P2.10, P2.11) 186 | SI32_PBSTD_A_set_pins_push_pull_output(SI32_PBSTD_2, 0x00000C00); 187 | SysTick_Config(SystemCoreClock / 1000); 188 | // set Priority for Cortex-M0 System Interrupts. 189 | NVIC_SetPriority(SysTick_IRQn, (1 << __NVIC_PRIO_BITS) - 1); 190 | } 191 | ``` 192 | 193 | ### 2.1.6.3 Check external pin status to run Bootloader or user application 194 | The code call check_update_requirement to check GPIO status, if the GPIO is high, we enter into user application mode; if the GPIO is low, we enter into Bootloader mode. Let’s check user application mode entry code. 195 | 196 | ```asm 197 | .thumb_func 198 | RunUserCode: 199 | // Set the vector table address to user code address. 200 | ldr r0, =USER_CODE_ADDRESS 201 | ldr r1, =0xe000ed08 202 | str r0, [r1] 203 | 204 | // Update stack pointer from user code vector table 205 | ldr r1, [r0] 206 | mov sp, r1 207 | 208 | // Load user code reset handler and jump to the user code 209 | ldr r0, [r0, #4] 210 | bx r0 211 | ``` 212 | 213 | Yeah, we have to relocate vector table if we want run user application. Note we have a macro `USER_CODE_ADDRESS` which is user application start address. At the end we load user code reset handler and jump to the user code. 214 | 215 | OK, we will talk about Bootloader mode in next couple sections. 216 | 217 | ### 2.2 Bootloader communicate with PC host tool via UART. 218 | We choose UART interface as communication port with PC host since it is easier to implement. Just have a look on SIM3U167 reference manual, initialize UART peripherals, and set it as 115200 baud rate. Prepare UART send and received functions. 219 | * UART hardware peripherals initialization. Those codes can be generated by Silabs AppBuilder. 220 | 221 | ```c 222 | Void UART0_initialize(void) 223 | { 224 | SI32_PBCFG_A_enable_crossbar_0(SI32_PBCFG_0); 225 | // UART PINS TO PROPER CONFIG (TX = PB1.12, RX = PB1.13) 226 | SI32_PBSTD_A_set_pins_push_pull_output(SI32_PBSTD_1, 0x0001000); 227 | SI32_PBSTD_A_set_pins_digital_input(SI32_PBSTD_1, 0x00002000); 228 | SI32_PBSTD_A_write_pbskipen(SI32_PBSTD_0, 0x0000FFFF); 229 | SI32_PBSTD_A_write_pbskipen(SI32_PBSTD_1, 0x00000FFF); 230 | // BRING OUT UART 231 | SI32_PBCFG_A_enable_xbar0h_peripherals(SI32_PBCFG_0, SI32_PBCFG_A_XBAR0H_UART0EN); 232 | 233 | // ENABLE UART0 CLOCK 234 | SI32_CLKCTRL_A_enable_apb_to_modules_0(SI32_CLKCTRL_0, 235 | SI32_CLKCTRL_A_APBCLKG0_UART0); 236 | 237 | // SETUP UART. BAUD RATE (9600 baud, APB = System Clock) 238 | SI32_UART_A_enter_full_duplex_mode(SI32_UART_0); 239 | SI32_UART_A_set_tx_baudrate(SI32_UART_0, (SystemCoreClock / (2 * UART_BAUD_RATE)) – 1); 240 | SI32_UART_A_set_rx_baudrate(SI32_UART_0, (SystemCoreClock / (2 * UART_BAUD_RATE)) – 1); 241 | // SETUP TX (8-bit, 1stop, no-parity) 242 | SI32_UART_A_select_tx_data_length(SI32_UART_0, 8); 243 | SI32_UART_A_enable_tx_start_bit(SI32_UART_0); 244 | SI32_UART_A_enable_tx_stop_bit(SI32_UART_0); 245 | SI32_UART_A_disable_tx_parity_bit(SI32_UART_0); 246 | SI32_UART_A_select_tx_stop_bits(SI32_UART_0, SI32_UART_A_STOP_BITS_1_BIT); 247 | SI32_UART_A_disable_tx_signal_inversion(SI32_UART_0); 248 | SI32_UART_A_enable_tx(SI32_UART_0); 249 | // SETUP RX 250 | SI32_UART_A_select_rx_data_length(SI32_UART_0, 8); 251 | SI32_UART_A_enable_rx_start_bit(SI32_UART_0); 252 | SI32_UART_A_enable_rx_stop_bit(SI32_UART_0); 253 | SI32_UART_A_select_rx_stop_bits(SI32_UART_0, SI32_UART_A_STOP_BITS_1_BIT); 254 | SI32_UART_A_disable_rx_signal_inversion(SI32_UART_0); 255 | SI32_UART_A_select_rx_fifo_threshold_1(SI32_UART_0); 256 | SI32_UART_A_enable_rx(SI32_UART_0); 257 | } 258 | ``` 259 | 260 | * UART send and receive functions. 261 | 262 | ```c 263 | Void uart_send_data(unsigned char *data, unsigned int count) 264 | { 265 | while(count--) 266 | { 267 | // Block if the output buffer is full 268 | while (SI32_UART_A_read_tx_fifo_count(SI32_UART_0) >= 4); 269 | // Write character to the output buffer 270 | SI32_UART_A_write_data_u8(SI32_UART_0, *data++); 271 | } 272 | } 273 | 274 | int uart_get_data(unsigned char *data, unsigned int count) 275 | { 276 | unsigned int time_out; 277 | while(count--) 278 | { 279 | time_out = msTicks + UART_TIME_OUT; 280 | while(SI32_UART_A_read_rx_fifo_count(SI32_UART_0) == 0) 281 | { 282 | if(time_out < msTicks) 283 | { 284 | return -1; 285 | } 286 | } 287 | *data++ = SI32_UART_A_read_data_u8(SI32_UART_0); 288 | } 289 | return 0; 290 | } 291 | ``` 292 | 293 | ### 2.3 Bootloader receive firmware from PC and burn it into flash. 294 | The UART driver was ready. We need to write user application into flash and flash device driver is needed now. 295 | * Flash hardware peripherals initialization. 296 | 297 | ```c 298 | Void flash_initialize(void) 299 | { 300 | // ENABLE FLASH CLOCK 301 | SI32_CLKCTRL_A_enable_apb_to_modules_0(SI32_CLKCTRL_0, 302 | SI32_CLKCTRL_A_APBCLKG0_FLCTRLCEN_ENABLED_U32); 303 | // 1. Enable VDD Supply Monitor and set as a reset source 304 | SI32_VMON_A_enable_vdd_supply_monitor(SI32_VMON_0); 305 | SI32_RSTSRC_A_enable_vdd_monitor_reset_source(SI32_RSTSRC_0); 306 | } 307 | ``` 308 | 309 | * Flash operation functions 310 | 311 | ```c 312 | void flash_erase_page(unsigned int addr) 313 | { 314 | SI32_FLASHCTRL_A_exit_multi_byte_write_mode(SI32_FLASHCTRL_0); 315 | SI32_FLASHCTRL_A_write_wraddr(SI32_FLASHCTRL_0, addr); 316 | SI32_FLASHCTRL_A_enter_flash_erase_mode(SI32_FLASHCTRL_0); 317 | SI32_FLASHCTRL_A_write_flash_key(SI32_FLASHCTRL_0, 0xA5); 318 | SI32_FLASHCTRL_A_write_flash_key(SI32_FLASHCTRL_0, 0xF1); 319 | SI32_FLASHCTRL_A_write_wrdata(SI32_FLASHCTRL_0, 0x0000); 320 | while(SI32_FLASHCTRL_A_is_buffer_full(SI32_FLASHCTRL_0)); 321 | } 322 | 323 | int flash_write_data(unsigned char * c,unsigned int addr, unsigned int num) 324 | { 325 | int i; 326 | unsigned short *buf = (unsigned short*)c; 327 | SI32_FLASHCTRL_A_exit_flash_erase_mode(SI32_FLASHCTRL_0); 328 | SI32_FLASHCTRL_A_write_wraddr(SI32_FLASHCTRL_0, addr); 329 | SI32_FLASHCTRL_A_enter_multi_byte_write_mode(SI32_FLASHCTRL_0); 330 | SI32_FLASHCTRL_A_write_flash_key(SI32_FLASHCTRL_0, 0xA5); 331 | SI32_FLASHCTRL_A_write_flash_key(SI32_FLASHCTRL_0, 0xF2); 332 | // Write all the half-words in the array 333 | for(i = 0; i < num / 2; i++) 334 | { 335 | SI32_FLASHCTRL_A_write_wrdata(SI32_FLASHCTRL_0, buf[i]); 336 | while(SI32_FLASHCTRL_A_is_flash_busy(SI32_FLASHCTRL_0)); 337 | } 338 | while(SI32_FLASHCTRL_A_is_buffer_full(SI32_FLASHCTRL_0)); 339 | SI32_FLASHCTRL_A_write_flash_key(SI32_FLASHCTRL_0, 0x5A); 340 | return 0; 341 | } 342 | ``` 343 | 344 | ## 3 Bootloader UART communication protocol 345 | ### 3.1 Protocol definition 346 | We can define our own protocol as we like. Also choose exist one is suitable. We list a protocol below just for reference. From view of host side. 347 | * Command package 348 | ``` 349 | | CMD | 350 | | CMD ^ 0xFF | 351 | | Wait for ACK | 352 | ``` 353 | 354 | * Address package 355 | ``` 356 | | ADDR3 | 357 | | ADDR2 | 358 | | ADDR1 | 359 | | ADDR0 | 360 | | CRC(=ADDR3^ADDR2^ADDR1^ADDR0) | 361 | ``` 362 | 363 | * Write flash command 364 | ``` 365 | | CMD(0x31) | 366 | | ADDR(address) | 367 | | Wait for ACK | 368 | | (LEN-1) & 0XFF | 369 | | DATA0 | 370 | | … | 371 | | DATA(LEN-1) | 372 | | CRC(=DATA0^DATA1…^DATA(LEN-1)) | 373 | | Wait for ACK | 374 | ``` 375 | 376 | * Read flash command 377 | ``` 378 | | CMD(0x11) | 379 | | ADDR(address) | 380 | | Wait for ACK | 381 | | (LEN-1) & 0XFF | 382 | | CRC (((LEN-1) & 0XFF) ^ 0xFF) | 383 | | Wait for ACK | 384 | | DATA0 | 385 | | … | 386 | | DATA(LEN-1) | 387 | ``` 388 | 389 | * Erase flash command 390 | ``` 391 | | CMD(0x43) | 392 | | LEN-1 | 393 | | SEC0 | 394 | | … | 395 | | SEC(LEN-1) | 396 | | CRC(SEC0^SEC1…^SEC(LEN-1)) | 397 | | Wait for ACK | 398 | ``` 399 | 400 | The device side control logic was list below. 401 | 402 | ```c 403 | While (1) 404 | { 405 | SI32_PBSTD_A_toggle_pins(SI32_PBSTD_2, 0xC00); 406 | // received CMD from host 407 | if (bl_get_cmd() == 0) 408 | { 409 | switch (data_buf[0]) 410 | { 411 | case CMD_WRITE_FLASH: 412 | bl_write_flash(); 413 | break; 414 | case CMD_READ_FLASH: 415 | bl_read_flash(); 416 | break; 417 | case CMD_ERASE_FLASH: 418 | bl_erase_flash(); 419 | break; 420 | default: 421 | break; 422 | } 423 | } 424 | } 425 | ``` 426 | 427 | ### 3.2 The protocol functions list below: 428 | 429 | ```c 430 | #define FLASH_SECTOR_SIZE 0x400 431 | 432 | #define CMD_WRITE_FLASH 0x31 433 | #define CMD_READ_FLASH 0x11 434 | #define CMD_ERASE_FLASH 0x43 435 | #define CMD_UNKNOW 0xFF 436 | 437 | #define RES_ACK 0x79 438 | #define RES_NACK 0x1F 439 | #define RES_UNKNOW 0xEE 440 | void bl_send_ack(unsigned char ack) 441 | { 442 | unsigned char res = ack; 443 | uart_send_data(&res, 1); 444 | } 445 | ``` 446 | 447 | * Get command from host 448 | ```c 449 | int bl_get_cmd(void) 450 | { 451 | unsigned char *ptr = data_buf; 452 | if (uart_get_data(ptr, 2) == 0) 453 | { 454 | if (ptr[0] != (ptr[1] ^ 0xFF)) 455 | { 456 | bl_send_ack(RES_NACK); 457 | return -2; 458 | } 459 | else 460 | { 461 | bl_send_ack(RES_ACK); 462 | return 0; 463 | } 464 | } 465 | return -1; 466 | } 467 | ``` 468 | 469 | * Handle write flash command 470 | ```c 471 | void bl_write_flash() 472 | { 473 | int i; 474 | unsigned int addr, len; 475 | unsigned char crc; 476 | unsigned char *ptr = data_buf; 477 | // get address 478 | if (uart_get_data(ptr, 5) == 0) 479 | { 480 | crc = ptr[0] ^ ptr[1] ^ ptr[2] ^ ptr[3]; 481 | if (crc == ptr[4]) 482 | { 483 | addr = ptr[3] | (ptr[2] << 8) | (ptr[1] << 16) | (ptr[0] << 24); 484 | } 485 | } 486 | // send ack 487 | bl_send_ack(RES_ACK); 488 | // get data len 489 | uart_get_data(ptr, 1); 490 | len = ptr[0] + 1; 491 | // get data and crc 492 | if (uart_get_data(ptr, len + 1) == 0) 493 | { 494 | crc = 0xFF; 495 | for (i = 0; i < len; i++) 496 | { 497 | crc = crc ^ ptr[i]; 498 | } 499 | } 500 | //write flash 501 | if (crc == ptr[len]) 502 | { 503 | if ((addr >= USER_CODE_ADDRESS) && addr < TOP_CODE_ADDRESS) 504 | { 505 | flash_write_data(ptr, addr, len); 506 | } 507 | } 508 | // send ack 509 | bl_send_ack(RES_ACK); 510 | } 511 | ``` 512 | 513 | * Handle read flash command 514 | ```c 515 | void bl_read_flash() 516 | { 517 | int i; 518 | unsigned int addr, len = 0; 519 | unsigned char crc; 520 | unsigned char *ptr = data_buf; 521 | // get address 522 | if (uart_get_data(ptr, 5) == 0) 523 | { 524 | crc = ptr[0] ^ ptr[1] ^ ptr[2] ^ ptr[3]; 525 | if (crc == ptr[4]) 526 | { 527 | addr = ptr[3] | (ptr[2] << 8) | (ptr[1] << 16) | (ptr[0] << 24); 528 | } 529 | } 530 | // send ack 531 | bl_send_ack(RES_ACK); 532 | // get data len and crc 533 | if(uart_get_data(ptr, 2) == 0) 534 | { 535 | if((ptr[0] ^ 0xFF) == ptr[1]) 536 | { 537 | len = ptr[0] + 1; 538 | } 539 | } 540 | // send ack 541 | bl_send_ack(RES_ACK); 542 | // send data 543 | for(i =0; i < len; i++) 544 | { 545 | ptr[i]= *(unsigned char *)(addr++); 546 | } 547 | uart_send_data(ptr,len); 548 | } 549 | ``` 550 | 551 | * Handle erase flash command 552 | ```c 553 | void bl_erase_flash() 554 | { 555 | int i; 556 | unsigned int addr, len; 557 | unsigned char crc; 558 | unsigned char *ptr = data_buf; 559 | 560 | // get len 561 | if (uart_get_data(ptr, 1) == 0) 562 | { 563 | len = (ptr[0] + 1) & 0xFF; // maximum sector number is 256 564 | } 565 | // get sector sequence and crc 566 | if (uart_get_data(ptr, len + 1) == 0) 567 | { 568 | crc = 0xFF; 569 | for (i = 0; i < len; i++) 570 | { 571 | crc = crc ^ ptr[i]; 572 | } 573 | } 574 | // erase flash sectors 575 | if (crc == ptr[len]) 576 | { 577 | for (i = 0; i < len; i++) 578 | { 579 | addr = ptr[i] * FLASH_SECTOR_SIZE; 580 | if ((addr >= USER_CODE_ADDRESS) && addr < TOP_CODE_ADDRESS) 581 | { 582 | flash_erase_page(addr); 583 | } 584 | } 585 | } 586 | // send ack 587 | bl_send_ack(RES_ACK); 588 | } 589 | ``` 590 | 591 | ## 4 Choose Python as host UART tool 592 | It is time to pick PC host UART tool. For easier usage purpose, we choose Python. I had tried to use Ruby serial port gem before Python. However, it is not stable. So Python become the first choice. And very lucky, I found a Python Bootloader UART source code. 593 | * Install Python 2.6/2.7 594 | 595 | Go to web site http://www.python.org to download python and install it under windows. 596 | * Download Python Serial Port Extension 597 | 598 | Get it from web site http://pypi.python.org/pypi/pyserial 599 | * Install Python Serial Port Extension 600 | 601 | Extract the package under Python install directory; execute command below to install the Serial Port Extension. 602 | ```python 603 | python setup.py install 604 | ``` 605 | * Get stm32loader.py and make you own modification. 606 | Get it from web site https://github.com/jsnyder/stm32loader. 607 | 608 | ## 5 Build Bootloader code 609 | We choose Silabs Precision32 UDP MCU Card as our hardware environment. 610 | * Build Bootloader with Precision32 IDE 611 | * Download Bootloader into SIM3U167 internal flash via Serial Wire. 612 | * Power up MCU card and pressing SW2, it enters Bootloader mode, DS3 and DS2 are blinking 613 | 614 | 615 | ## 6 Develop User application with Bootloader 616 | User applications runs on Flash, but start address is not 0x00000000, we have a default value 0x1000. We need to make this modification in user application’s link file. Just change .text segment load address to 0x1000. And we also want to generate binary file in post build stage of the user application. 617 | 618 | ## 7 Bootloader functional test 619 | We were doing the test on Silabs Precision32 UDP MCU Card. 620 | * Connect USB cable with J10 and PC USB port, PC will found COM4 after power on. 621 | * Copy stm32loader.py to C:\Python26 (your Python install directory). 622 | * Copy user code binary file to C:\Python26 directory, for blinky example code, we have a sim3u1xx_Blinky.bin. 623 | * Run Python tool. 624 | ```python 625 | C:\Python26>python sim32loader.py -wv sim3u1xx_Blinky.bin 626 | sim3u1xx_Blinky.bin 627 | [4, 5, 6, 7] 628 | File length 3076 bytes 629 | Write 256 bytes at 0x1000 630 | Write 256 bytes at 0x1100 631 | Write 256 bytes at 0x1200 632 | Write 256 bytes at 0x1300 633 | Write 256 bytes at 0x1400 634 | Write 256 bytes at 0x1500 635 | Write 256 bytes at 0x1600 636 | Write 256 bytes at 0x1700 637 | Write 256 bytes at 0x1800 638 | Write 256 bytes at 0x1900 639 | Write 256 bytes at 0x1A00 640 | Write 256 bytes at 0x1B00 641 | Write 256 bytes at 0x1C00 642 | Read 256 bytes at 0x1000 643 | Read 256 bytes at 0x1100 644 | Read 256 bytes at 0x1200 645 | Read 256 bytes at 0x1300 646 | Read 256 bytes at 0x1400 647 | Read 256 bytes at 0x1500 648 | Read 256 bytes at 0x1600 649 | Read 256 bytes at 0x1700 650 | Read 256 bytes at 0x1800 651 | Read 256 bytes at 0x1900 652 | Read 256 bytes at 0x1A00 653 | Read 256 bytes at 0x1B00 654 | Read 256 bytes at 0x1C00 655 | Verification OK 656 | ``` 657 | * Run user application 658 | 659 | Press Reset key, we can see DS3 and DS2 are alternate blinking, that means user code Blinky is running. 660 | 661 | ## 8 Source code 662 | The source code can be found in https://github.com/MarkDing/sim3u1xx_Bootloader 663 | -------------------------------------------------------------------------------- /.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 36 | 44 | 49 | 50 | 60 | 61 | 62 | 63 | 64 | 73 | 82 | 83 | 84 | 85 | 86 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | 1147 | 1156 | 1160 | 1161 | 1171 | 1172 | 1173 | 1174 | 1175 | 1184 | 1193 | 1194 | 1195 | 1196 | 1197 | 1198 | 1199 | 1200 | 1201 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 1210 | 1211 | 1212 | 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | 1226 | 1227 | 1228 | 1229 | 1230 | 1231 | 1232 | 1233 | 1234 | 1235 | 1236 | 1237 | 1238 | 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | 1246 | 1247 | 1248 | 1249 | 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | 1256 | 1257 | 1258 | 1259 | 1260 | 1261 | 1262 | 1263 | 1264 | 1265 | 1266 | 1267 | 1268 | 1269 | 1270 | 1271 | 1272 | 1273 | 1274 | 1275 | 1276 | 1277 | 1278 | 1279 | 1280 | 1281 | 1282 | 1283 | 1284 | 1285 | 1286 | 1287 | 1288 | 1289 | 1290 | 1291 | 1292 | 1293 | 1294 | 1295 | 1296 | 1297 | 1298 | 1299 | 1300 | 1301 | 1302 | 1303 | 1304 | 1305 | 1306 | 1307 | 1308 | 1309 | 1310 | 1311 | 1312 | 1313 | 1314 | 1315 | 1316 | 1317 | 1318 | 1319 | 1320 | 1321 | 1322 | 1323 | 1324 | 1325 | 1326 | 1327 | 1328 | 1329 | 1330 | 1331 | 1332 | 1333 | 1334 | 1335 | 1336 | 1337 | 1338 | 1339 | 1340 | 1341 | 1342 | 1343 | 1344 | 1345 | 1346 | 1347 | 1348 | 1349 | 1350 | 1351 | 1352 | 1353 | 1354 | 1355 | 1356 | 1357 | 1358 | 1359 | 1360 | 1361 | 1362 | 1363 | 1364 | 1365 | 1366 | 1367 | 1368 | 1369 | 1370 | 1371 | 1372 | 1373 | 1374 | 1375 | 1376 | 1377 | 1378 | 1379 | 1380 | 1381 | 1382 | 1383 | 1384 | 1385 | 1386 | 1387 | 1388 | 1389 | 1390 | 1391 | 1392 | 1393 | 1394 | 1395 | 1396 | 1397 | 1398 | 1399 | 1400 | 1401 | 1402 | 1403 | 1404 | 1405 | 1406 | 1407 | 1408 | 1409 | 1410 | 1411 | 1412 | 1413 | 1414 | 1415 | 1416 | 1417 | 1418 | 1419 | 1420 | 1421 | 1422 | 1423 | 1424 | 1425 | 1426 | 1427 | 1428 | 1429 | 1430 | 1431 | 1432 | 1433 | 1434 | 1435 | 1436 | 1437 | 1438 | 1439 | 1440 | 1441 | 1442 | 1443 | 1444 | 1445 | 1446 | 1447 | 1448 | 1449 | 1450 | 1451 | 1452 | 1453 | 1454 | 1455 | 1456 | 1457 | 1458 | 1459 | 1460 | 1461 | 1462 | 1463 | 1464 | 1465 | 1466 | 1467 | 1468 | 1469 | 1470 | 1471 | 1472 | 1473 | 1474 | 1475 | 1476 | 1477 | 1478 | 1479 | 1480 | 1481 | 1482 | 1483 | 1484 | 1485 | 1486 | 1487 | 1488 | 1489 | 1490 | 1491 | 1492 | 1493 | 1494 | 1495 | 1496 | 1497 | 1498 | 1499 | 1500 | 1501 | 1502 | 1503 | 1504 | 1505 | 1506 | 1507 | 1508 | 1509 | 1510 | 1511 | 1512 | 1513 | 1514 | 1515 | 1516 | 1517 | 1518 | 1519 | 1520 | 1521 | 1522 | 1523 | 1524 | 1525 | 1526 | 1527 | 1528 | 1529 | 1530 | 1531 | 1532 | 1533 | 1534 | 1535 | 1536 | 1537 | 1538 | 1539 | 1540 | 1541 | 1542 | 1543 | 1544 | 1545 | 1546 | 1547 | 1548 | 1549 | 1550 | 1551 | 1552 | 1553 | 1554 | 1555 | 1556 | 1557 | 1558 | 1559 | 1560 | 1561 | 1562 | 1563 | 1564 | 1565 | 1566 | 1567 | 1568 | 1569 | 1570 | 1571 | 1572 | 1573 | 1574 | 1575 | 1576 | 1577 | 1578 | 1579 | 1580 | 1581 | 1582 | 1583 | 1584 | 1585 | 1586 | 1587 | 1588 | 1589 | 1590 | 1591 | 1592 | 1593 | 1594 | 1595 | 1596 | 1597 | 1598 | 1599 | 1600 | 1601 | 1602 | 1603 | 1604 | 1605 | 1606 | 1607 | 1608 | 1609 | 1610 | 1611 | 1612 | 1613 | 1614 | 1615 | 1616 | 1617 | 1618 | 1619 | 1620 | 1621 | 1622 | 1623 | 1624 | 1625 | 1626 | 1627 | 1628 | 1629 | 1630 | 1631 | 1632 | 1633 | 1634 | 1635 | 1636 | 1637 | 1638 | 1639 | 1640 | 1641 | 1642 | 1643 | 1644 | 1645 | 1646 | 1647 | 1648 | 1649 | 1650 | 1651 | 1652 | 1653 | 1654 | 1655 | 1656 | 1657 | 1658 | 1659 | 1660 | 1661 | 1662 | 1663 | 1664 | 1665 | 1666 | 1667 | 1668 | 1669 | 1670 | 1671 | 1672 | 1673 | 1674 | 1675 | 1676 | 1677 | 1678 | 1679 | 1680 | 1681 | 1682 | 1683 | 1684 | 1685 | 1686 | 1687 | 1688 | 1689 | 1690 | 1691 | 1692 | 1693 | 1694 | 1695 | 1696 | 1697 | 1698 | 1699 | 1700 | 1701 | 1702 | 1703 | 1704 | 1705 | 1706 | 1707 | 1708 | 1709 | 1710 | 1711 | 1712 | 1713 | 1714 | 1715 | 1716 | 1717 | 1718 | 1719 | 1720 | 1721 | 1722 | 1723 | 1724 | 1725 | 1726 | 1727 | 1728 | 1729 | 1730 | 1731 | 1732 | 1733 | 1734 | 1735 | 1736 | 1737 | 1738 | 1739 | 1740 | 1741 | 1742 | 1743 | 1744 | 1745 | 1746 | 1747 | 1748 | 1749 | 1750 | 1751 | 1752 | 1753 | 1754 | 1755 | 1756 | 1757 | 1758 | 1759 | 1760 | 1761 | 1762 | 1763 | 1764 | 1765 | 1766 | 1767 | 1768 | 1769 | 1770 | 1771 | 1772 | 1773 | 1774 | 1775 | 1776 | 1777 | 1778 | 1779 | 1780 | 1781 | 1782 | 1783 | 1784 | 1785 | 1786 | 1787 | 1788 | 1789 | 1790 | 1791 | 1792 | 1793 | 1794 | 1795 | 1796 | 1797 | 1798 | 1799 | 1800 | 1801 | 1802 | 1803 | 1804 | 1805 | 1806 | 1807 | 1808 | 1809 | 1810 | 1811 | 1812 | 1813 | 1814 | 1815 | 1816 | 1817 | 1818 | 1819 | 1820 | 1821 | 1822 | 1823 | 1824 | 1825 | 1826 | 1827 | 1828 | 1829 | 1830 | 1831 | 1832 | 1833 | 1834 | 1835 | 1836 | 1837 | 1838 | 1839 | 1840 | 1841 | 1842 | 1843 | 1844 | 1845 | 1846 | 1847 | 1848 | 1849 | 1850 | 1851 | 1852 | 1853 | 1854 | 1855 | 1856 | 1857 | 1858 | 1859 | 1860 | 1861 | 1862 | 1863 | 1864 | 1865 | 1866 | 1867 | 1868 | 1869 | 1870 | 1871 | 1872 | 1873 | 1874 | 1875 | 1876 | 1877 | 1878 | 1879 | 1880 | 1881 | 1882 | 1883 | 1884 | 1885 | 1886 | 1887 | 1888 | 1889 | 1890 | 1891 | 1892 | 1893 | 1894 | 1895 | 1896 | 1897 | 1898 | 1899 | 1900 | 1901 | 1902 | 1903 | 1904 | 1905 | 1906 | 1907 | 1908 | 1909 | 1910 | 1911 | 1912 | 1913 | 1914 | 1915 | 1916 | 1917 | 1918 | 1919 | 1920 | 1921 | 1922 | 1923 | 1924 | 1925 | 1926 | 1927 | 1928 | 1929 | 1930 | 1931 | 1932 | 1933 | 1934 | 1935 | 1936 | 1937 | 1938 | 1939 | 1940 | 1941 | 1942 | 1943 | 1944 | 1945 | 1946 | 1947 | 1948 | 1949 | 1950 | 1951 | 1952 | 1953 | 1954 | 1955 | 1956 | 1957 | 1958 | 1959 | 1960 | 1961 | 1962 | 1963 | 1964 | 1965 | 1966 | 1967 | 1968 | 1969 | 1970 | 1971 | 1972 | 1973 | 1974 | 1975 | 1976 | 1977 | 1978 | 1979 | 1980 | 1981 | 1982 | 1983 | 1984 | 1985 | 1986 | 1987 | 1988 | 1989 | 1990 | 1991 | 1992 | 1993 | 1994 | 1995 | 1996 | 1997 | 1998 | 1999 | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | 2032 | 2033 | 2034 | 2035 | 2036 | 2037 | 2038 | 2039 | 2040 | 2041 | 2042 | 2043 | 2044 | 2045 | 2046 | 2047 | 2048 | 2049 | 2050 | 2051 | 2052 | 2053 | 2054 | 2055 | 2056 | 2057 | 2058 | 2059 | 2060 | 2061 | 2062 | 2063 | 2064 | 2065 | 2066 | 2067 | 2068 | 2069 | 2070 | 2071 | 2072 | 2073 | 2074 | 2075 | 2076 | 2077 | 2078 | 2079 | 2080 | 2081 | 2082 | 2083 | 2084 | 2085 | 2086 | 2087 | 2088 | 2089 | 2090 | 2091 | 2092 | 2093 | 2094 | 2095 | 2096 | 2097 | 2098 | 2099 | 2100 | 2101 | 2102 | 2103 | 2104 | 2105 | 2106 | 2107 | 2108 | 2109 | 2110 | 2111 | 2112 | 2113 | 2114 | 2115 | 2116 | 2117 | 2118 | 2119 | 2120 | 2121 | 2122 | 2123 | 2124 | 2125 | 2126 | 2127 | 2128 | 2129 | 2130 | 2131 | 2132 | 2133 | 2134 | 2135 | 2136 | 2137 | 2138 | 2139 | 2140 | 2141 | 2142 | 2143 | 2144 | 2145 | 2146 | 2147 | 2148 | 2149 | 2150 | 2151 | 2152 | 2153 | 2154 | 2155 | 2156 | 2157 | 2158 | 2159 | 2160 | 2161 | 2162 | 2163 | 2164 | 2165 | 2166 | 2167 | 2168 | 2169 | 2170 | 2171 | 2172 | 2173 | 2174 | 2175 | 2176 | 2177 | 2178 | 2179 | 2180 | 2181 | 2182 | 2183 | 2184 | 2185 | 2186 | 2187 | 2188 | 2189 | 2190 | 2191 | 2192 | 2193 | 2194 | 2195 | 2196 | 2197 | 2198 | 2199 | 2200 | 2201 | 2202 | 2203 | 2204 | 2205 | 2206 | 2207 | 2208 | 2209 | 2210 | 2211 | 2212 | 2213 | 2214 | 2215 | 2216 | 2217 | 2218 | 2219 | 2220 | 2221 | 2222 | 2223 | 2224 | 2225 | 2226 | 2227 | <?xml version="1.0" encoding="UTF-8"?> 2228 | <TargetConfig> 2229 | <Properties property_0="" property_2="SiM3U16x.cfx" property_3="Silabs" property_4="SiM3U167" property_count="5" version="1"/> 2230 | <infoList vendor="Silabs"><info chip="SiM3U167" flash_driver="SiM3U16x.cfx" match_id="0x0" name="SiM3U167" stub="crt_emu_cm3_gen"><chip><name>SiM3U167</name> 2231 | <family>SiM3U1xx</family> 2232 | <vendor>SiLabs (Silicon Labs)</vendor> 2233 | <reset board="None" core="Real" sys="Real"/> 2234 | <clock changeable="TRUE" freq="48MHz" is_accurate="TRUE"/> 2235 | <memory can_program="true" id="Flash" is_ro="true" type="Flash"/> 2236 | <memory id="RAM" type="RAM"/> 2237 | <memory id="Periph" is_volatile="true" type="Peripheral"/> 2238 | <memoryInstance derived_from="Flash" id="MFlash256" location="0x0" size="0x3fffc"/> 2239 | <memoryInstance derived_from="RAM" id="StandardRam28" location="0x20001000" size="0x7000"/> 2240 | <memoryInstance derived_from="RAM" id="RetentionRam4" location="0x20000000" size="0x1000"/> 2241 | <prog_flash blocksz="0x4000" location="0x0" size="0x40000"/> 2242 | <peripheralInstance derived_from="V7M_NVIC" id="NVIC" location="0xe000e000"/> 2243 | <peripheralInstance derived_from="V7M_DCR" id="DCR" location="0xe000edf0"/> 2244 | <peripheralInstance derived_from="V7M_ITM" id="ITM" location="0xe0000000"/> 2245 | <peripheralInstance derived_from="SARADC-0" id="SARADC-0" location="0x4001a000"/> 2246 | <peripheralInstance derived_from="SARADC-1" id="SARADC-1" location="0x4001b000"/> 2247 | <peripheralInstance derived_from="AES-0" id="AES-0" location="0x40027000"/> 2248 | <peripheralInstance derived_from="CRC-0" id="CRC-0" location="0x40028000"/> 2249 | <peripheralInstance derived_from="CAPSENSE-0" id="CAPSENSE-0" location="0x40023000"/> 2250 | <peripheralInstance derived_from="CLKCTRL-0" id="CLKCTRL-0" location="0x4002d000"/> 2251 | <peripheralInstance derived_from="CMP-0" id="CMP-0" location="0x4001f000"/> 2252 | <peripheralInstance derived_from="CMP-1" id="CMP-1" location="0x40020000"/> 2253 | <peripheralInstance derived_from="DMACTRL-0" id="DMACTRL-0" location="0x40036000"/> 2254 | <peripheralInstance derived_from="DMAXBAR-0" id="DMAXBAR-0" location="0x40037000"/> 2255 | <peripheralInstance derived_from="DEVICEID-0" id="DEVICEID-0" location="0x400490c0"/> 2256 | <peripheralInstance derived_from="EMIF-0" id="EMIF-0" location="0x40026000"/> 2257 | <peripheralInstance derived_from="EPCA-0" id="EPCA-0" location="0x4000e000"/> 2258 | <peripheralInstance derived_from="FLASHCTRL-0" id="FLASHCTRL-0" location="0x4002e000"/> 2259 | <peripheralInstance derived_from="I2C-0" id="I2C-0" location="0x40009000"/> 2260 | <peripheralInstance derived_from="I2C-1" id="I2C-1" location="0x4000a000"/> 2261 | <peripheralInstance derived_from="I2S-0" id="I2S-0" location="0x4003a000"/> 2262 | <peripheralInstance derived_from="IDAC-0" id="IDAC-0" location="0x40031000"/> 2263 | <peripheralInstance derived_from="IDAC-1" id="IDAC-1" location="0x40032000"/> 2264 | <peripheralInstance derived_from="IVC-0" id="IVC-0" location="0x40044000"/> 2265 | <peripheralInstance derived_from="LOCK-0" id="LOCK-0" location="0x40049000"/> 2266 | <peripheralInstance derived_from="LPTIMER-0" id="LPTIMER-0" location="0x40038000"/> 2267 | <peripheralInstance derived_from="PLL-0" id="PLL-0" location="0x4003b000"/> 2268 | <peripheralInstance derived_from="EXTOSC-0" id="EXTOSC-0" location="0x4003c000"/> 2269 | <peripheralInstance derived_from="LPOSC-0" id="LPOSC-0" location="0x40041000"/> 2270 | <peripheralInstance derived_from="PCA-0" id="PCA-0" location="0x4000f000"/> 2271 | <peripheralInstance derived_from="PCA-1" id="PCA-1" location="0x40010000"/> 2272 | <peripheralInstance derived_from="PMU-0" id="PMU-0" location="0x40048000"/> 2273 | <peripheralInstance derived_from="PBCFG-0" id="PBCFG-0" location="0x4002a000"/> 2274 | <peripheralInstance derived_from="PBHD-4" id="PBHD-4" location="0x4002a3c0"/> 2275 | <peripheralInstance derived_from="PBSTD-0" id="PBSTD-0" location="0x4002a0a0"/> 2276 | <peripheralInstance derived_from="PBSTD-1" id="PBSTD-1" location="0x4002a140"/> 2277 | <peripheralInstance derived_from="PBSTD-2" id="PBSTD-2" location="0x4002a1e0"/> 2278 | <peripheralInstance derived_from="PBSTD-3" id="PBSTD-3" location="0x4002a320"/> 2279 | <peripheralInstance derived_from="RTC-0" id="RTC-0" location="0x40029000"/> 2280 | <peripheralInstance derived_from="RSTSRC-0" id="RSTSRC-0" location="0x4002d060"/> 2281 | <peripheralInstance derived_from="SPI-0" id="SPI-0" location="0x40004000"/> 2282 | <peripheralInstance derived_from="SPI-1" id="SPI-1" location="0x40005000"/> 2283 | <peripheralInstance derived_from="SPI-2" id="SPI-2" location="0x40006000"/> 2284 | <peripheralInstance derived_from="SSG-0" id="SSG-0" location="0x4001e000"/> 2285 | <peripheralInstance derived_from="TIMER-0" id="TIMER-0" location="0x40014000"/> 2286 | <peripheralInstance derived_from="TIMER-1" id="TIMER-1" location="0x40015000"/> 2287 | <peripheralInstance derived_from="UART-0" id="UART-0" location="0x40002000"/> 2288 | <peripheralInstance derived_from="UART-1" id="UART-1" location="0x40003000"/> 2289 | <peripheralInstance derived_from="USART-0" id="USART-0" location="0x40000000"/> 2290 | <peripheralInstance derived_from="USART-1" id="USART-1" location="0x40001000"/> 2291 | <peripheralInstance derived_from="USB-0" id="USB-0" location="0x40018000"/> 2292 | <peripheralInstance derived_from="VMON-0" id="VMON-0" location="0x4002f000"/> 2293 | <peripheralInstance derived_from="VREF-0" id="VREF-0" location="0x40039010"/> 2294 | <peripheralInstance derived_from="EXTVREG-0" id="EXTVREG-0" location="0x40042000"/> 2295 | <peripheralInstance derived_from="VREG-0" id="VREG-0" location="0x40040000"/> 2296 | <peripheralInstance derived_from="LDO-0" id="LDO-0" location="0x40039000"/> 2297 | <peripheralInstance derived_from="WDTIMER-0" id="WDTIMER-0" location="0x40030000"/> 2298 | </chip> 2299 | <processor><name gcc_name="cortex-m3">Cortex-M3</name> 2300 | <family>Cortex-M</family> 2301 | </processor> 2302 | <link href="SiM3U1x7_peripheral.xme" show="embed" type="simple"/> 2303 | </info> 2304 | </infoList> 2305 | </TargetConfig> 2306 | 2307 | 2308 | --------------------------------------------------------------------------------