nv_storage.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #include <string.h>
  2. #include "nv_storage.h"
  3. #include "bsp/AT24CXX.h"
  4. #include "app/sox/soc.h"
  5. #include "libs/logger.h"
  6. #include "libs/shark_utils.h"
  7. #if 0
  8. static void backup_timer_hander(shark_timer_t *timer);
  9. static void nv_save_soc_by_backup(int index);
  10. #endif
  11. static void nv_save_soc_task(shark_timer_t *timer);
  12. #define SOC_ADDR 0
  13. static shark_timer_t _save_backup_timer = {.handler = nv_save_soc_task};
  14. #define SOC_SIZE (((sizeof(soc_t) + sizeof(uint16_t)) + 0xF)&(0xFFF0)) //需要16字节对齐
  15. #define SN_ADDR (SOC_ADDR + (SOC_SIZE * 2))
  16. #define SN_SIZE 32
  17. #define RES_ADDR (SN_ADDR + SN_SIZE)
  18. static uint8_t soc_write_pending = 0;
  19. static uint8_t soc_write_backup_index = 0;
  20. static uint8_t soc_write_index = 0;
  21. static uint8_t soc_data[(sizeof(soc_t) + sizeof(uint16_t))];
  22. int nv_read_write_test(void){
  23. uint8_t data[32];
  24. memset(data, 0x5a, sizeof(data));
  25. AT24CXX_Write(0, data, sizeof(data));
  26. memset(data, 0x0, sizeof(data));
  27. AT24CXX_Read(0, data, sizeof(data));
  28. for (int i = 0; i < sizeof(data); i++){
  29. if (data[i] != 0x5a) {
  30. return 1;
  31. }
  32. }
  33. return 0;
  34. }
  35. int nv_save_sn(uint8_t *sn, int len){
  36. sn_t sn_info;
  37. if (len > sizeof(sn_info.sn)){
  38. return -1;
  39. }
  40. memcpy(sn_info.sn, sn, len);
  41. sn_info.len = len;
  42. sn_info.crc = shark_crc16_update(0, (const u8 *)sn_info.sn, len);
  43. return AT24CXX_Write(SN_ADDR, (uint8_t *)&sn_info, sizeof(sn_info));
  44. }
  45. int nv_read_sn(uint8_t *sn, int len){
  46. sn_t sn_info;
  47. if (len < sizeof(sn_info.sn)){
  48. return -1;
  49. }
  50. if (AT24CXX_Read(SN_ADDR, (uint8_t *)&sn_info, sizeof(sn_info)) < 0) {
  51. return -1;
  52. }
  53. if (sn_info.len > sizeof(sn_info.sn)){
  54. return -1;
  55. }
  56. uint16_t crc = shark_crc16_update(0, (const u8 *)sn_info.sn, sn_info.len);
  57. if (crc != sn_info.crc){
  58. return -1;
  59. }
  60. memcpy(sn, sn_info.sn, sn_info.len);
  61. return sn_info.len;
  62. }
  63. int nv_save_factory_result(uint8_t result) {
  64. factory_t f;
  65. f.result = result;
  66. uint16_t crc16 = shark_crc16_update(0, (const u8 *)&f, sizeof(f) - 2);
  67. f.crc = crc16;
  68. return AT24CXX_Write(RES_ADDR, (uint8_t *)&f, sizeof(f));
  69. }
  70. uint8_t nv_read_factory_result(void) {
  71. factory_t f;
  72. if (AT24CXX_Read(RES_ADDR, (uint8_t *)&f, sizeof(f)) < 0) {
  73. return 0xFF;
  74. }
  75. uint16_t crc16 = shark_crc16_update(0, (const u8 *)&f, sizeof(f) - 2);
  76. if (f.crc != crc16) {
  77. return 0xFF;
  78. }
  79. return f.result;
  80. }
  81. static int _soc_write_error = 0;
  82. static int _soc_write_success = 0;
  83. /* soc 保存,拆分每次保存一个byte,确保e2rom写操作不会占用太长时间 */
  84. void nv_save_soc(void){
  85. #if 0
  86. nv_save_soc_by_backup(0);
  87. shark_timer_post(&_save_backup_timer, 10);
  88. #else
  89. if (soc_write_pending == 0){
  90. soc_write_pending = 1;
  91. memcpy(soc_data, (void *)get_soc(), sizeof(soc_t));
  92. soc_write_backup_index = 0;
  93. soc_write_index = 0;
  94. uint16_t crc16 = shark_crc16_update(0, (const u8 *)soc_data, sizeof(soc_t));
  95. shark_encode_u16(soc_data + sizeof(soc_t), crc16);
  96. shark_timer_post(&_save_backup_timer, 0);
  97. }
  98. #endif
  99. }
  100. void nv_storage_log(void) {
  101. state_debug("soc nv write: %d, %d\n", _soc_write_success, _soc_write_error);
  102. }
  103. static void nv_save_soc_task(shark_timer_t *timer){
  104. if (soc_write_pending == 0) {
  105. return;
  106. }
  107. if (soc_write_index < sizeof(soc_data)){
  108. if (AT24CXX_Write(SOC_ADDR + SOC_SIZE * soc_write_backup_index + soc_write_index, soc_data + soc_write_index, 1) == 1) {
  109. soc_write_index ++;
  110. _soc_write_success ++;
  111. }else {
  112. _soc_write_error ++;
  113. }
  114. }else {
  115. soc_write_index = 0;
  116. soc_write_backup_index ++;
  117. if (soc_write_backup_index == 2){
  118. soc_write_pending = 0;
  119. soc_write_backup_index = 0;
  120. sys_debug("write soc to nv OK\n");
  121. return;
  122. }
  123. }
  124. shark_timer_post(&_save_backup_timer, 0);
  125. }
  126. #if 0
  127. static void backup_timer_hander(shark_timer_t *timer){
  128. nv_save_soc_by_backup(1);
  129. }
  130. #endif
  131. static void nv_save_soc_by_backup(int index){
  132. uint16_t nv_addr = SOC_ADDR + SOC_SIZE * index;
  133. soc_t *soc = get_soc();
  134. uint16_t crc16 = shark_crc16_update(0, (const u8 *)soc, sizeof(soc_t));
  135. AT24CXX_Write(nv_addr ,(uint8_t *)soc, sizeof(soc_t));
  136. AT24CXX_Write(nv_addr + sizeof(soc_t),(uint8_t *)&crc16, sizeof(crc16));
  137. }
  138. static void stop_writer(void) {
  139. shark_timer_cancel(&_save_backup_timer);
  140. soc_write_index = 0;
  141. soc_write_backup_index = 0;
  142. }
  143. void nv_save_all_soc(void){
  144. stop_writer();
  145. nv_save_soc_by_backup(0);
  146. nv_save_soc_by_backup(1);
  147. }
  148. void nv_erase_all_soc(int keep_cycle){
  149. soc_clear_calibrate(keep_cycle);
  150. }
  151. int nv_restore_soc_by_backup(int index, soc_t *soc){
  152. uint16_t crc_nv;
  153. uint16_t nv_addr = SOC_ADDR + SOC_SIZE * index;
  154. AT24CXX_Read(nv_addr , (uint8_t *)soc, sizeof(soc_t));
  155. AT24CXX_Read(nv_addr + sizeof(soc_t), (uint8_t *)&crc_nv, sizeof(crc_nv));
  156. if (shark_crc16_update(0, (const u8 *)soc, sizeof(soc_t)) != crc_nv){
  157. return -1;
  158. }
  159. return 0;
  160. }
  161. int nv_restore_soc(void){
  162. soc_t soc0, soc1;
  163. int success0, success1;
  164. success0 = nv_restore_soc_by_backup(0, &soc0);
  165. success1 = nv_restore_soc_by_backup(1, &soc1);
  166. if (success0 == 0 || success1 == 0){
  167. if (success0 == 0){
  168. *get_soc() = soc0;
  169. }else if (success1 == 0){
  170. *get_soc() = soc1;
  171. }
  172. if (success1 != 0){
  173. nv_save_soc_by_backup(1);
  174. }
  175. if (success0 != 0){
  176. nv_save_soc_by_backup(0);
  177. }
  178. }
  179. sys_debug("soc bk0=%d, bk1=%d\n", success0, success1);
  180. return ((success0 == 0) || (success1 == 0))?0:-1;
  181. }