From 0721c588f0e1d8aaae133afb20423c16434fd267 Mon Sep 17 00:00:00 2001 From: tpu Date: Fri, 9 May 2025 17:17:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=87=AA=E5=8A=A8=E5=86=99?= =?UTF-8?q?=E5=85=A5=E5=9B=BA=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Keil_5/ble_app_peripheral.uvoptx | 2 +- src/epd/epd.h | 5 +- src/epd/spi_flash.c | 200 +++++++++++++++++++++++++++++-- src/user_peripheral.c | 67 +++++++---- 4 files changed, 239 insertions(+), 35 deletions(-) diff --git a/Keil_5/ble_app_peripheral.uvoptx b/Keil_5/ble_app_peripheral.uvoptx index c162e6a..2032681 100644 --- a/Keil_5/ble_app_peripheral.uvoptx +++ b/Keil_5/ble_app_peripheral.uvoptx @@ -120,7 +120,7 @@ 0 DLGUARM - + d 0 diff --git a/src/epd/epd.h b/src/epd/epd.h index 092af19..1882338 100644 --- a/src/epd/epd.h +++ b/src/epd/epd.h @@ -17,12 +17,15 @@ int gpio_get(int index); // spi flash +#define ERASE_4K 0x20 +#define ERASE_32K 0x52 int fspi_config(u32 gpio_word); int fspi_init(void); int sf_readid(void); -int sf_sector_erase(int addr); +int sf_sector_erase(int cmd, int addr, int wait); int sf_page_write(int addr, u8 *buf, int size); int sf_read(int addr, int len, u8 *buf); +int selflash(int otp_boot); // epd_hw void epd_hw_init(u32 config0, u32 config1); diff --git a/src/epd/spi_flash.c b/src/epd/spi_flash.c index f14edfe..c036d56 100644 --- a/src/epd/spi_flash.c +++ b/src/epd/spi_flash.c @@ -111,7 +111,7 @@ int sf_readid(void) int id = fspi_trans(0); FSPI_CS(1); - return id; + return __REV(id); } int sf_status(void) @@ -170,20 +170,39 @@ int sf_wait() } -int sf_sector_erase(int addr) +int sf_sector_erase(int cmd, int addr, int wait) { sf_wen(1); fspi_set_bitmode(BIT_32); FSPI_CS(0); - fspi_trans(0x20000000|addr); + fspi_trans((cmd<<24)|addr); FSPI_CS(1); - sf_wait(); + if(wait) + sf_wait(); return 0; } +int sf_erase(int addr, int size, int wait) +{ + while(size){ + if((addr%0x8000)==0 && size<=0x8000){ + sf_sector_erase(ERASE_32K, addr, wait); + addr += 0x8000; + size -= 0x8000; + }else{ + sf_sector_erase(ERASE_4K, addr, wait); + addr += 0x1000; + size -= 0x1000; + } + } + + return 0; +} + + int sf_page_write(int addr, u8 *buf, int size) { int i; @@ -195,12 +214,11 @@ int sf_page_write(int addr, u8 *buf, int size) fspi_trans(0x02000000|addr); for(i=0; i> 8); + + return crc ^ ~0U; +} + + +/******************************************************************************/ + +extern int Region$$Table$$Base; + + +int selflash(int otp_boot) +{ + u8 pbuf[256]; + u32 *p32 = (u32*)pbuf; + int image_addr[2]; + int image_flag[2]; + + fspi_init(); + int id = sf_readid(); + printk("Flash ID: %08x\n", id); + + int region_table = (int)&Region$$Table$$Base; + int firm_size = *(u32*)(region_table+0x10) - 0x07fc0000; + printk("Firm size: %08x\n", firm_size); + u32 firm_crc = crc32(0, (u8*)0x07fc0000, firm_size); + printk("Firm crc: %08x\n", firm_crc); + + + memset(pbuf, 0, 256); + if(otp_boot==0x1234a5a5){ + // 从OTP启动。读product header。 + sf_read(0x38000, 16, pbuf); + if(pbuf[0]!=0x70 || pbuf[1]!=0x52){ + printk("Build Product header ...\n"); + p32[0] = 0x00005270; + p32[1] = 0x00004000; + p32[2] = 0x0001f000; + sf_sector_erase(ERASE_4K, 0x38000, 1); + sf_page_write(0x38000, pbuf, 12); + sf_wait(); + } + image_addr[0] = p32[1]; + image_addr[1] = p32[2]; + + // 读image header + sf_read(image_addr[0], 16, pbuf+0 ); + sf_read(image_addr[0], 16, pbuf+16); + printk("Product iamge0: %08x: %08x %08x %08x\n", image_addr[0], __REV(p32[0]), p32[1], p32[2]); + printk(" iamge1: %08x: %08x %08x %08x\n", image_addr[1], __REV(p32[4]), p32[5], p32[6]); + + // 获取当前使用的image的id + image_flag[0] = -1; + image_flag[1] = -1; + if(pbuf[ 0]==0x70 && pbuf[ 1]==0x51 && pbuf[ 2]==0xaa){ + image_flag[0] = (signed char)pbuf[ 3]; + } + if(pbuf[16]==0x70 && pbuf[17]==0x51 && pbuf[18]==0xaa){ + image_flag[1] = (signed char)pbuf[19]; + } + int active = (image_flag[0]>=image_flag[1]) ? 0 : 1; + printk("Active image: %d flag: %02x\n", active, image_flag[active]); + + if(firm_crc != p32[active*4+2]){ + // 当前运行的固件与flash中的固件不同 + // 将当前固件写入非活动的image中 + int new_flag = image_flag[active]+1; + int new_id = active^1; + + // 擦除flash + printk("Erase %08x ...\n", image_addr[new_id]); + sf_erase(image_addr[new_id], firm_size+64, 1); + // 初始化image header + memset(pbuf, 0xff, 64); + p32[0] = (new_flag<<24)|0x00aa5170; + p32[1] = firm_size; + p32[2] = firm_crc; + pbuf[0x20] = 0; + + // 写入flash + u8 *firm_data = (u8*)0x07fc0000; + int addr = image_addr[new_id]; + for(int i=0; i>24); + ba0 &= 0x00ffffff; + ba0 ^= ba1; + + u8 *ba = (u8*)&ba0; + sprintf(adv_name+2, "DLG-CLOCK-%02x%02x%02x", ba[2], ba[1], ba[0]); + int name_len = strlen(adv_name+2); + + if(device_info.dev_name.length==0){ + device_info.dev_name.length = name_len; + memcpy(device_info.dev_name.name, adv_name+2, name_len); + } + + adv_name[0] = name_len+1; + adv_name[1] = GAP_AD_TYPE_COMPLETE_NAME; +} + +extern int Region$$Table$$Base; void user_app_init(void) { - printk("\n\nuser_app_init!\n"); + read_otp_value(); + + printk("\n\nuser_app_init! %s\n", __TIME__); app_param_update_request_timer_used = EASY_TIMER_INVALID_TIMER; app_clock_timer_used = EASY_TIMER_INVALID_TIMER; @@ -146,9 +185,7 @@ void user_app_init(void) fspi_config(0x00030605); epd_hw_init(0x23200700, 0x05210006); // for 2.13 board BW - fspi_init(); - int id = sf_readid(); - printk("Flash ID: %08x\n", id); + selflash(otp_boot); default_app_on_init(); } @@ -205,28 +242,8 @@ void user_app_on_db_init_complete( void ) void user_app_adv_start(void) { - u32 ba0 = *(volatile u32*)(0x40000024); - u32 ba1 = *(volatile u32*)(0x40000028); - char adv_name[20]; - - ba1 = (ba1<<8)|(ba0>>24); - ba0 &= 0x00ffffff; - ba0 ^= ba1; - - u8 *ba = (u8*)&ba0; - sprintf(adv_name+2, "DLG-CLOCK-%02x%02x%02x", ba[2], ba[1], ba[0]); - int name_len = strlen(adv_name+2); - - if(device_info.dev_name.length==0){ - device_info.dev_name.length = name_len; - memcpy(device_info.dev_name.name, adv_name+2, name_len); - } - - adv_name[0] = name_len+1; - adv_name[1] = GAP_AD_TYPE_COMPLETE_NAME; - struct gapm_start_advertise_cmd* cmd = app_easy_gap_undirected_advertise_get_active(); - app_add_ad_struct(cmd, adv_name, name_len+2, 1); + app_add_ad_struct(cmd, adv_name, adv_name[0]+1, 1); //default_advertise_operation(); //app_easy_gap_undirected_advertise_start();