如題,本人在使用ABOV A94B114芯片進行開發(fā)時,在掉電記憶的處理部分遇到了難題,希望有大佬能幫忙看看.大家討論討論交流一下思路也好eeprom.c文件內(nèi)容如下
- uint8 xdata SaveData[MAX_TAB_ADDRES];
- uint8 xdata NAME_SAVE_FG;
- uint8 xdata TestrAM1;
- uint8 xdata TestrAM2;
- unsigned int User_ID;
- unsigned char *PageBufData;
- unsigned int PageBufDataSize;
- volatile unsigned char data code_buf[20] _at_ 0x30;
- volatile unsigned char data g_FEMR, g_FECR, g_WDTMR;
- volatile unsigned char g_IE, g_IE1, g_IE2;
- extern void Flash_Enter(void);
- void Init_Flash()
- {
-
- User_ID = 0;
- // Set Flash Sector Address as Dummy address
- FEARH = (FLASH_ADDR_DUMMY >> 16) & 0x0f; //Flash Sector Address High Register
- FEARM = (FLASH_ADDR_DUMMY >> 8) & 0xff; //Flash Sector Address Middle Register
- FEARL = (FLASH_ADDR_DUMMY >> 0) & 0xff; //Flash Sector Address Low Register
- }
- void Flash_Enter(void)
- {
- g_IE = IE;
- g_IE1 = IE1;
- g_IE2 = IE2;
- IE = 0;
- IE1 = 0;
- IE2 = 0;
-
- g_WDTMR = WDTMR; // Backup WDTMR
- WDTMR = 0; // Watch Dog Timer Stop.
- g_WDTMR |= 0x04; // Clear WDT Counter
-
- // To access Flash Control register, ENTRY_0~2 should be set 0xAA, 0x55, 0xA5.
- *(unsigned char xdata *)0x10D8 = 0xAA;
- *(unsigned char xdata *)0x10DA = 0x55;
- *(unsigned char xdata *)0x10DD = 0xA5;
-
- // Set Flash Sector Address as Dummy address
- FEARH = (FLASH_ADDR_DUMMY >> 16) & 0x0f; //Flash Sector Address High Register
- FEARM = (FLASH_ADDR_DUMMY >> 8) & 0xff; //Flash Sector Address Middle Register
- FEARL = (FLASH_ADDR_DUMMY >> 0) & 0xff; //Flash Sector Address Low Register
-
- }
- void Flash_Exit(void)
- {
- FECR = 0x33; //FLASH_MODE_EXIT
- // After to change Flash Control register, ENTRY_0~2 should be set 0x00.
- *(unsigned char xdata *)0x10D8 = 0x00;
- *(unsigned char xdata *)0x10DA = 0x00;
- *(unsigned char xdata *)0x10DD = 0x00;
- // Flash code buffer ram clear.
- #pragma asm
- mov r0, #code_buf
- mov r2, #20
- clr a
- loop0:
- mov @r0, a
- inc r0
- djnz r2, loop0
- #pragma endasm
- WDTMR = g_WDTMR; // Restore WDTMR
- /* restore IE setting */
- IE = g_IE;
- IE1 = g_IE1;
- IE2 = g_IE2;
- }
- volatile void write_page_buffer_src()
- {
- FEMR = 0x89;//
- //FLASH_SEL // FSEL (Select Flash memory)
- //| FLASH_PBUFF_SEL // PBUFF (Select page buffer)
- //| FLASH_CON_ENABLE; // FEEN (Enable program & erase)
- #pragma asm
- mov r0,#32
- mov dptr,#0x10E0 ; page buffer address
- write_page_buffer_src_loop:
- mov a, @r1 ;r1=addr of rxdata
- movx @dptr,a
- inc r1
- inc dptr
- djnz r0,write_page_buffer_src_loop
- #pragma endasm
- FEMR = 0;
- }
- void write_page_buffer(unsigned char *dt) // dt -> r3, r2, r1
- {
- uint8 *temp = dt;
-
- #pragma asm
- mov dptr,#write_page_buffer_src
- mov r0,#0x30
- mov r2,#0x12
- write_page_buffer_loop:
- clr a
- movc a,@a+dptr
- mov @r0,a
- inc dptr
- inc r0
- djnz r2,write_page_buffer_loop
- ljmp 0x8030 ; jump sram region
- #pragma endasm
- }
- volatile void do_flash_at_sram_src()
- {
- #pragma asm
- mov FEMR,g_FEMR // 3 byte
- mov FECR,g_FECR // 3 byte
- _flash_busy_wait:
- mov A,FESR // 2 byte
- JNB ACC.7,_flash_busy_wait // 3 byte
- clr A // 1 byte
- mov FEMR,A // 2 byte
- #pragma endasm
- } // RET // 1byte
- void do_flash_at_sram()
- {
- #pragma asm
- mov dptr,#do_flash_at_sram_src
- mov r0,#0x30
- mov r1,#0x0F
- do_flash_at_sram_loop:
- clr a
- movc a,@a+dptr
- mov @r0,a
- inc dptr
- inc r0
- djnz r1,do_flash_at_sram_loop
- ljmp 0x8030
- #pragma endasm
- }
- void Update_Flash_Buf(unsigned char *buf, unsigned int buf_size)
- {
- //Flash Buffer Update
- User_ID = FLASH_USER_ID;
- PageBufData = buf;
- PageBufDataSize = buf_size;
- }
- void Update_Flash(unsigned int key)
- {
- unsigned char i = 0;
- unsigned int s = 0;
- unsigned long addr;
- unsigned char ret = 0;
- if(key == FLASH_KEY)
- {
- if(User_ID == FLASH_USER_ID)
- {
- addr = FLASH_ADDR_USER;
- s = PageBufDataSize;
- while(PageBufDataSize > 0)
- {
- if(PageBufDataSize < PAGE_BUFFER_SIZE)
- {
- s = PageBufDataSize;
- PageBufDataSize = 0;
- }
- else
- {
- s = PAGE_BUFFER_SIZE;
- PageBufDataSize -= PAGE_BUFFER_SIZE;
- }
- ret = Erase_Flash(FLASH_KEY, FLASH_ADDR_USER + (PAGE_BUFFER_SIZE*i));
- if(ret == 1 || ret == 2)
- {
- //error;
- while(1);
- }
- ret = Write_Flash(FLASH_KEY, FLASH_ADDR_USER + (PAGE_BUFFER_SIZE*i),
- s, PageBufData + (PAGE_BUFFER_SIZE*i));
- if(ret == 1 || ret == 4)
- {
- //error;
- while(1);
- }
- i++;
- }
- }
- User_ID = 0;
- }
- }
- unsigned char Erase_Flash(unsigned int key, unsigned long sector_address)
- {
- unsigned char code *rom_addr = 0x0000;
- unsigned char i = 0;
- unsigned char tmp = 0;
- unsigned char tmp2 = 0;
- unsigned char ret = 0;
- //Disable EA
- tmp = IE;
- IE &= (~0x80);
-
- //LVR enable, safety code
- tmp2 = LVIR;
- LVIR &= ~(1<<7); //LVR enable
- if(key == FLASH_KEY)
- {
- key ^= FLASH_XOR;
- if(sector_address < (unsigned long)FLASH_SIZE)
- {
-
- // Flash Flash Control Register CLR change before initialization.
- FECR = 0;
- FETCR = 0;
- FEMR = 0;
- // Enable program mode
- Flash_Enter();
-
- FETCR = WAITTIME; // 0x9D = 157 : (157+1) * 2 (31.25ns * 256) = 2.528ms
- FECR = 0x02; // Reset page buffer.
- _nop_( ); //Dummy instruction, This instruction must be needed.
- _nop_( ); //Dummy instruction, This instruction must be needed.
- _nop_( ); //Dummy instruction, This instruction must be needed.
-
- g_FEMR = 0x91; // Set Erase mode.
- g_FECR = 0x0B; // Start Erase.
-
- // Set Flash Sector Address as used area
- FEARH = (sector_address >> 16) & 0xFF;
- FEARM = (sector_address >> 8) & 0xFF;
- FEARL = (sector_address) & 0xFF;
-
- //Check Power stable by LVR Enable
- //if LVR disable, return error 2
- if((LVIR & 0x80) == 0x00)
- {
- // Check User_ID
- if(User_ID == FLASH_USER_ID)
- {
- // Check valid of Flash Sector Address range
- if( (unsigned long)FLASH_ADDR_MIN <= sector_address && sector_address <= (unsigned long)FLASH_ADDR_MAX)
- {
- if((key ^ FLASH_XOR) == FLASH_KEY)
- {
- // Flase Erase at ram
- do_flash_at_sram();
- }
-
- Flash_Exit(); // Set flash to normal mode.
- //verify data
- for(i = 0; i < PAGE_BUFFER_SIZE; i++)
- {
- if(rom_addr[sector_address + i] != 0x00)
- {
- ret = 2;
- }
- }
- }
- }
-
- }
- else
- {
- ret = 1;//LVI error
-
- Flash_Exit();
- }
- // Set Flash Sector Address as Dummy address
- FEARH = (FLASH_ADDR_DUMMY >> 16) & 0x0f; //Flash Sector Address High Register
- FEARM = (FLASH_ADDR_DUMMY >> 8) & 0xff; //Flash Sector Address Middle Register
- FEARL = (FLASH_ADDR_DUMMY >> 0) & 0xff; //Flash Sector Address Low Register
- }
- }
- LVIR = tmp2;
- IE = tmp;
- return ret;
- }
- unsigned char Write_Flash(unsigned int key, unsigned long sector_address, unsigned int buf_size, unsigned char *buf)
- {
- unsigned char *pdt;
- unsigned char code *rom_addr=0x0000;
- unsigned char i = 0;
- unsigned char tmp = 0;
- unsigned char tmp2 = 0;
- unsigned char ret = 0;
- //Disable EA
- tmp = IE;
- IE &= (~0x80);
-
- //LVR enable, safety code
- tmp2 = LVIR;
- LVIR &= ~(1<<7); //LVR enable
-
- if(key == FLASH_KEY)
- {
- key ^= FLASH_XOR;
- if(sector_address < (unsigned long)FLASH_SIZE)
- {
- // Enable program mode
- Flash_Enter();
-
- FETCR = WAITTIME; // 0x9D = 157 : (157+1) * 2 (31.25ns * 256) = 2.528ms
- FEMR = 0x81; // Select flash and enable control.
- FECR = 0x02 ; // (Reset page buffer)
- _nop_( ); //Dummy instruction, This instruction must be needed.
- _nop_( ); //Dummy instruction, This instruction must be needed.
- _nop_( ); //Dummy instruction, This instruction must be needed.
-
-
-
-
- // Set Flash Sector Address as used area
- FEARH = (sector_address >> 16) & 0xFF;
- FEARM = (sector_address >> 8) & 0xFF;
- FEARL = (sector_address) & 0xFF;
- write_page_buffer(buf);
- buf_size = buf_size;//not used A94B114
- g_FEMR = 0xA1; // Set write mode.
- g_FECR = 0x0B; // Start program.
-
- //Check Power stable by LVR Enable
- //if LVR disable, return error 2
- if((LVIR & 0x80) == 0x00)
- {
- // Check User_ID1/2
- if(User_ID == FLASH_USER_ID)
- {
- // Check valid of Flash Sector Address range
- if( (unsigned long)FLASH_ADDR_MIN <= sector_address && sector_address <= (unsigned long)FLASH_ADDR_MAX)
- {
- if((key ^ FLASH_XOR) == FLASH_KEY)
- {
- // Flase Write at ram
- do_flash_at_sram();
- }
- Flash_Exit(); // Set flash to normal mode.
- //verify data
- pdt = buf;
- for(i = 0; i < PAGE_BUFFER_SIZE; i++)
- {
- sector_address_tmp = sector_address;
- if(rom_addr[sector_address + i] != *pdt)
- {
- ret = 4;
- }
-
- pdt++;
- }
- }
- }
- }
- else
- {
- ret = 1;//LVI error
-
- Flash_Exit();
- }
- // Set Flash Sector Address as Dummy address
- FEARH = (FLASH_ADDR_DUMMY >> 16) & 0x0f; //Flash Sector Address High Register
- FEARM = (FLASH_ADDR_DUMMY >> 8) & 0xff; //Flash Sector Address Middle Register
- FEARL = (FLASH_ADDR_DUMMY >> 0) & 0xff; //Flash Sector Address Low Register
- }
- }
- LVIR = tmp2;
- IE = tmp;
- return ret;
- }
- void Read_Flash(unsigned long sector_address, unsigned int buf_size, unsigned char *buf)
- {
- unsigned char code *rom_addr=0x0000;
- unsigned int i = 0;
- for(i = 0; i < buf_size; i++)
- {
- buf[i] = rom_addr[sector_address + i];
- }
- }
- void WriteEEprom(void)
- {
- if (NAME_SAVE_FG == WRIT_COMMAND_CODE)
- {
- Init_Flash();
- SaveData[1] = TestrAM1;
- SaveData[2] = TestrAM2;
- SaveData[3] = TempMOde;
- SaveData[TEST_C1_ADDRES] = TEST_NAME_C1;
- SaveData[TEST_C2_ADDRES] = TEST_NAME_C2;
-
- Update_Flash_Buf(SaveData, PAGE_BUFFER_SIZE);
- Update_Flash(FLASH_KEY);
- NAME_SAVE_FG = 0;
- }
- }
- void RestPara(void)
- {
- SaveData[1] = 0X90;
- SaveData[2] = 0XA7;
- SaveData[3] = TempMOde = 0;
- SaveData[TEST_C1_ADDRES] = TEST_NAME_C1;
- SaveData[TEST_C2_ADDRES] = TEST_NAME_C2;
- Init_Flash();
- Update_Flash_Buf(SaveData, PAGE_BUFFER_SIZE);
- Update_Flash(FLASH_KEY);
- }
- void ReadEE(void)
- {
- Read_Flash(FLASH_ADDR_USER, PAGE_BUFFER_SIZE, SaveData);
- if ((SaveData[TEST_C1_ADDRES] == TEST_NAME_C1) && (SaveData[TEST_C2_ADDRES] == TEST_NAME_C2))
- {
- TestrAM1 = SaveData[1];
- TestrAM2 = SaveData[2];
- TempMOde = SaveData[3];
- }
- else
- {
- RestPara();
- }
-
- }
復制代碼
在eeprom.c文件當中,除了最后的WriteEEprom,RestPara,ReadEE,其余的部分都是從A94B114官方提供的flash.c例程中copy過來的, 以下是eeprom.h文件內(nèi)容
- #ifndef _EEPROM_H
- #define _EEPROM_H
- extern uint8 xdata NAME_SAVE_FG;
- #define WRIT_COMMAND_CODE 0X12
- #define TEST_NAME_C2 0XA4
- #define TEST_NAME_C1 0xB4
- #define TEST_C1_ADDRES 0
- #define TEST_C2_ADDRES 12
- #define MAX_TAB_ADDRES 32
- //Device Dependent=======================================
- #define FLASH_SIZE (0x001FFF)
- #define PAGE_BUFFER_SIZE (0x20)
- //Modify to use==========================================
- //Flash Address for used
- #define FLASH_ADDR_USER 0x001f80
- //Flash Address Min/Max value for permitted area
- #define FLASH_ADDR_MIN 0x001f80
- #define FLASH_ADDR_MAX 0x001fff
- //more than 2.0V @ IRC 16MHz
- #define FLASH_LVI 0x01 //LVI 2.4V(2.05V~2.35V)
- //Flash Dummy Address value, not used area
- #define FLASH_ADDR_DUMMY 0x03FF00
- //=====================================================
- //safety code for operation of flash memory
- #define FLASH_KEY 0xAA55
- #define FLASH_XOR 0x9C75
- #define WAITTIME 0x9D // 2.5ms
- //Flash Mode Control value
- #define FLASH_PAGEBUFFER_RESET 0x01
- //Flash User ID value, used password
- #define FLASH_USER_ID 0xCC33
- extern void Init_Flash();
- extern void Update_Flash_Buf(unsigned char *buf, unsigned int size);
- extern void Update_Flash(unsigned int key);
- extern unsigned char Erase_Flash(unsigned int key, unsigned long sector_address);
- extern unsigned char Write_Flash(unsigned int key, unsigned long sector_address, unsigned int size, unsigned char *buf);
- extern void Read_Flash(unsigned long sector_address, unsigned int size, unsigned char *buf);
- extern void ReadEE(void);
- extern void WriteEEprom(void);
- #endif
復制代碼
在調(diào)試過程中發(fā)現(xiàn),每次都是在Write_Flash()函數(shù)中,似乎是數(shù)據(jù)驗證出錯,導致ret = 4,然后在Update_Flash()中while(1)死循環(huán)觸發(fā)復位, 希望大家能幫忙看看,謝謝! |