#include #include "nv_storage.h" #include "bsp/AT24CXX.h" #include "app/sox/soc.h" #include "libs/logger.h" #include "libs/shark_utils.h" #if 0 static void backup_timer_hander(shark_timer_t *timer); static void nv_save_soc_by_backup(int index); #endif static void nv_save_soc_task(shark_timer_t *timer); #define SOC_ADDR 0 static shark_timer_t _save_backup_timer = {.handler = nv_save_soc_task}; #define SOC_SIZE (((sizeof(soc_t) + sizeof(uint16_t)) + 0xF)&(0xFFF0)) //需要16字节对齐 #define SN_ADDR (SOC_ADDR + (SOC_SIZE * 2)) #define SN_SIZE 32 #define RES_ADDR (SN_ADDR + SN_SIZE) static uint8_t soc_write_pending = 0; static uint8_t soc_write_backup_index = 0; static uint8_t soc_write_index = 0; static uint8_t soc_data[(sizeof(soc_t) + sizeof(uint16_t))]; int nv_read_write_test(void){ uint8_t data[32]; memset(data, 0x5a, sizeof(data)); AT24CXX_Write(0, data, sizeof(data)); memset(data, 0x0, sizeof(data)); AT24CXX_Read(0, data, sizeof(data)); for (int i = 0; i < sizeof(data); i++){ if (data[i] != 0x5a) { return 1; } } return 0; } int nv_save_sn(uint8_t *sn, int len){ sn_t sn_info; if (len > sizeof(sn_info.sn)){ return -1; } memcpy(sn_info.sn, sn, len); sn_info.len = len; sn_info.crc = shark_crc16_update(0, (const u8 *)sn_info.sn, len); return AT24CXX_Write(SN_ADDR, (uint8_t *)&sn_info, sizeof(sn_info)); } int nv_read_sn(uint8_t *sn, int len){ sn_t sn_info; if (len < sizeof(sn_info.sn)){ return -1; } if (AT24CXX_Read(SN_ADDR, (uint8_t *)&sn_info, sizeof(sn_info)) < 0) { return -1; } if (sn_info.len > sizeof(sn_info.sn)){ return -1; } uint16_t crc = shark_crc16_update(0, (const u8 *)sn_info.sn, sn_info.len); if (crc != sn_info.crc){ return -1; } memcpy(sn, sn_info.sn, sn_info.len); return sn_info.len; } int nv_save_factory_result(uint8_t result) { factory_t f; f.result = result; uint16_t crc16 = shark_crc16_update(0, (const u8 *)&f, sizeof(f) - 2); f.crc = crc16; return AT24CXX_Write(RES_ADDR, (uint8_t *)&f, sizeof(f)); } uint8_t nv_read_factory_result(void) { factory_t f; if (AT24CXX_Read(RES_ADDR, (uint8_t *)&f, sizeof(f)) < 0) { return 0xFF; } uint16_t crc16 = shark_crc16_update(0, (const u8 *)&f, sizeof(f) - 2); if (f.crc != crc16) { return 0xFF; } return f.result; } static int _soc_write_error = 0; static int _soc_write_success = 0; /* soc 保存,拆分每次保存一个byte,确保e2rom写操作不会占用太长时间 */ void nv_save_soc(void){ #if 0 nv_save_soc_by_backup(0); shark_timer_post(&_save_backup_timer, 10); #else if (soc_write_pending == 0){ soc_write_pending = 1; memcpy(soc_data, (void *)get_soc(), sizeof(soc_t)); soc_write_backup_index = 0; soc_write_index = 0; uint16_t crc16 = shark_crc16_update(0, (const u8 *)soc_data, sizeof(soc_t)); shark_encode_u16(soc_data + sizeof(soc_t), crc16); shark_timer_post(&_save_backup_timer, 0); } #endif } void nv_storage_log(void) { state_debug("soc nv write: %d, %d\n", _soc_write_success, _soc_write_error); } static void nv_save_soc_task(shark_timer_t *timer){ if (soc_write_pending == 0) { return; } if (soc_write_index < sizeof(soc_data)){ if (AT24CXX_Write(SOC_ADDR + SOC_SIZE * soc_write_backup_index + soc_write_index, soc_data + soc_write_index, 1) == 1) { soc_write_index ++; _soc_write_success ++; }else { _soc_write_error ++; } }else { soc_write_index = 0; soc_write_backup_index ++; if (soc_write_backup_index == 2){ soc_write_pending = 0; soc_write_backup_index = 0; sys_debug("write soc to nv OK\n"); return; } } shark_timer_post(&_save_backup_timer, 0); } #if 0 static void backup_timer_hander(shark_timer_t *timer){ nv_save_soc_by_backup(1); } #endif static void nv_save_soc_by_backup(int index){ uint16_t nv_addr = SOC_ADDR + SOC_SIZE * index; soc_t *soc = get_soc(); uint16_t crc16 = shark_crc16_update(0, (const u8 *)soc, sizeof(soc_t)); AT24CXX_Write(nv_addr ,(uint8_t *)soc, sizeof(soc_t)); AT24CXX_Write(nv_addr + sizeof(soc_t),(uint8_t *)&crc16, sizeof(crc16)); } static void stop_writer(void) { shark_timer_cancel(&_save_backup_timer); soc_write_index = 0; soc_write_backup_index = 0; } void nv_save_all_soc(void){ stop_writer(); nv_save_soc_by_backup(0); nv_save_soc_by_backup(1); } void nv_erase_all_soc(int keep_cycle){ soc_clear_calibrate(keep_cycle); } int nv_restore_soc_by_backup(int index, soc_t *soc){ uint16_t crc_nv; uint16_t nv_addr = SOC_ADDR + SOC_SIZE * index; AT24CXX_Read(nv_addr , (uint8_t *)soc, sizeof(soc_t)); AT24CXX_Read(nv_addr + sizeof(soc_t), (uint8_t *)&crc_nv, sizeof(crc_nv)); if (shark_crc16_update(0, (const u8 *)soc, sizeof(soc_t)) != crc_nv){ return -1; } return 0; } int nv_restore_soc(void){ soc_t soc0, soc1; int success0, success1; success0 = nv_restore_soc_by_backup(0, &soc0); success1 = nv_restore_soc_by_backup(1, &soc1); if (success0 == 0 || success1 == 0){ if (success0 == 0){ *get_soc() = soc0; }else if (success1 == 0){ *get_soc() = soc1; } if (success1 != 0){ nv_save_soc_by_backup(1); } if (success0 != 0){ nv_save_soc_by_backup(0); } } sys_debug("soc bk0=%d, bk1=%d\n", success0, success1); return ((success0 == 0) || (success1 == 0))?0:-1; } uint8_t nv_get_sn_byte7(void) { uint8_t sn[30] = {0}; int try_cnt = 20; while (nv_read_sn(sn, sizeof(sn)) < 7) { if (try_cnt-- < 0) { break; } } if (sn[0] == 0) { return 'N'; } return sn[6]; }