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();