User_flash.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. /*********************************************************************
  2. *
  3. * 文件名: User_flash.c
  4. * 功能描述:flash功能
  5. * 作者: 陈俊超
  6. * 时间:2020-12-12
  7. *
  8. ********************************************************************/
  9. #include "User_flash.h"
  10. #include "User_task.h"
  11. #include "app_timer.h"
  12. /********************** 变量区 **************************************/
  13. static bool volatile m_fds_initialized =false;
  14. static step_flash m_step_config = {0,{0}};
  15. extern TranforStep_type m_tranforStep;
  16. static const step_flash m_dummy_cfg ={0,{0}};/* 出工厂参数 */
  17. static fds_record_t const m_dummy_record =
  18. {
  19. .file_id = sportdatakey_file_id,
  20. .key = sportdatakey_rec_key,
  21. .data.p_data = &m_dummy_cfg,
  22. .data.length_words = (sizeof(m_dummy_cfg) + 2) / sizeof(uint32_t),//记录长度需要四字节对齐
  23. };
  24. #if DEBUG_EN
  25. const char *fds_err_str(ret_code_t ret)
  26. {
  27. /* Array to map FDS return values to strings. */
  28. static char const * err_str[] =
  29. {
  30. "FDS_ERR_OPERATION_TIMEOUT",
  31. "FDS_ERR_NOT_INITIALIZED",
  32. "FDS_ERR_UNALIGNED_ADDR",
  33. "FDS_ERR_INVALID_ARG",
  34. "FDS_ERR_NULL_ARG",
  35. "FDS_ERR_NO_OPEN_RECORDS",
  36. "FDS_ERR_NO_SPACE_IN_FLASH",
  37. "FDS_ERR_NO_SPACE_IN_QUEUES",
  38. "FDS_ERR_RECORD_TOO_LARGE",
  39. "FDS_ERR_NOT_FOUND",
  40. "FDS_ERR_NO_PAGES",
  41. "FDS_ERR_USER_LIMIT_REACHED",
  42. "FDS_ERR_CRC_CHECK_FAILED",
  43. "FDS_ERR_BUSY",
  44. "FDS_ERR_INTERNAL",
  45. };
  46. return err_str[ret - NRF_ERROR_FDS_ERR_BASE];
  47. }
  48. /* Array to map FDS events to strings. */
  49. static char const * fds_evt_str[] =
  50. {
  51. "FDS_EVT_INIT",
  52. "FDS_EVT_WRITE",
  53. "FDS_EVT_UPDATE",
  54. "FDS_EVT_DEL_RECORD",
  55. "FDS_EVT_DEL_FILE",
  56. "FDS_EVT_GC",
  57. };
  58. #endif
  59. /********************** 函数区 **************************************/
  60. /**********************************************************
  61. * 函数名字:fds_evt_handler
  62. * 函数作用:fds文件管理库事件回调
  63. * 函数参数:p_evt:回调参数
  64. * 函数返回值:无
  65. ***********************************************************/
  66. bool flashbusyFlag=false;
  67. static void fds_evt_handler(fds_evt_t const * p_evt)
  68. {
  69. if (p_evt->result == NRF_SUCCESS){
  70. flashbusyFlag=false;
  71. #if DEBUG_EN
  72. SEGGER_RTT_printf(0,"Event: %s received (NRF_SUCCESS)\n",fds_evt_str[p_evt->id]);
  73. #endif
  74. }
  75. else{
  76. flashbusyFlag=false;
  77. #if DEBUG_EN
  78. SEGGER_RTT_printf(0,"Event: %s received (%s)\n",fds_evt_str[p_evt->id],fds_err_str(p_evt->result));
  79. #endif
  80. }
  81. switch (p_evt->id)
  82. {
  83. case FDS_EVT_INIT:
  84. if (p_evt->result == NRF_SUCCESS){
  85. m_fds_initialized = true;
  86. }
  87. break;
  88. case FDS_EVT_WRITE:{
  89. flashbusyFlag=false;
  90. if (p_evt->result == NRF_SUCCESS)
  91. {
  92. #if DEBUG_EN
  93. SEGGER_RTT_printf(0,"Record ID:\t0x%04x\n", p_evt->write.record_id);
  94. SEGGER_RTT_printf(0,"File ID:\t0x%04x\n", p_evt->write.file_id);
  95. SEGGER_RTT_printf(0,"Record key:\t0x%04x\n", p_evt->write.record_key);
  96. #endif
  97. }
  98. } break;
  99. case FDS_EVT_DEL_RECORD:{
  100. flashbusyFlag=false;
  101. if (p_evt->result == NRF_SUCCESS){
  102. #if DEBUG_EN
  103. SEGGER_RTT_printf(0,"Record ID:\t0x%04x\n", p_evt->del.record_id);
  104. SEGGER_RTT_printf(0,"File ID:\t0x%04x\n", p_evt->del.file_id);
  105. SEGGER_RTT_printf(0,"Record key:\t0x%04x\n", p_evt->del.record_key);
  106. #endif
  107. }
  108. } break;
  109. default:
  110. break;
  111. }
  112. }
  113. /**********************************************************
  114. * 函数名字:record_delete_next
  115. * 函数作用:删除所有的记录
  116. * 函数参数:无
  117. * 函数返回值:true:删除成功
  118. * false:删除失败
  119. ***********************************************************/
  120. bool record_delete_next(void)
  121. {
  122. ret_code_t rc;
  123. fds_find_token_t tok = {0};
  124. fds_record_desc_t desc = {0};
  125. rc = fds_record_find(sportdatakey_file_id, sportdatakey_rec_key, &desc, &tok);//查找配置文件记录
  126. if (rc == NRF_SUCCESS){
  127. rc = fds_record_delete(&desc);
  128. if (rc != NRF_SUCCESS)return false;
  129. }
  130. else{
  131. return false;
  132. }
  133. return true;
  134. }
  135. /**********************************************************
  136. * 函数名字:Add_StepToflash
  137. * 函数作用:步数+1
  138. * 函数参数:无
  139. * 函数返回值:无
  140. ***********************************************************/
  141. void Add_Step(void)
  142. {
  143. m_step_config.step_number[m_step_config.step_journey_cun*2]+=1;
  144. m_step_config.step_number[m_step_config.step_journey_cun*2+1]= (uint16_t)(m_step_config.step_number[m_step_config.step_journey_cun*2]*OneStepLong);
  145. #if DEBUG_EN
  146. SEGGER_RTT_printf(0,"AAAAA_step:%d\n",m_step_config.step_number[m_step_config.step_journey_cun*2]);
  147. #endif
  148. }
  149. /**********************************************************
  150. * 函数名字:Update_StepToflash
  151. * 函数作用:更新步数到flash
  152. * 函数参数:无
  153. * 函数返回值:true:更新成功
  154. * false:更新失败
  155. ***********************************************************/
  156. bool Update_StepToflash(void)
  157. {
  158. ret_code_t rc;
  159. fds_record_desc_t desc = {0};//用来操作记录的描述符结构清零
  160. fds_find_token_t tok = {0};//保存秘钥的令牌清零
  161. bool Result =false;
  162. static step_flash m_step_config_1 = {0,{0}};
  163. if(flashbusyFlag){
  164. nrf_delay_ms(2);
  165. if(flashbusyFlag)return false;
  166. }
  167. rc = fds_record_find(sportdatakey_file_id, sportdatakey_rec_key, &desc, &tok);
  168. if(NRF_SUCCESS == rc){//对应KEY记录查找数据
  169. memcpy(&m_step_config_1, &m_step_config, sizeof(step_flash));
  170. fds_record_t const record =
  171. {
  172. .file_id = sportdatakey_file_id,
  173. .key = sportdatakey_rec_key,
  174. .data.p_data = &m_step_config_1,
  175. .data.length_words = (sizeof(step_flash) + 2) / sizeof(uint32_t)
  176. };
  177. // flashbusyFlag=true;
  178. rc = fds_record_update(&desc, &record);//重新写记录
  179. if(NRF_SUCCESS == rc){
  180. Result =true;
  181. }
  182. else if(FDS_ERR_NO_SPACE_IN_FLASH == rc) {
  183. fds_gc();//垃圾回收
  184. }
  185. #if DEBUG_EN
  186. SEGGER_RTT_printf(0,"Update_StepToflash:%02x,%d\n",rc,record.data.length_words);
  187. #endif
  188. }
  189. return Result;
  190. }
  191. /**********************************************************
  192. * 函数名字:Update_flash_read
  193. * 函数作用:向flash读取数据参数
  194. * 函数参数:无
  195. * 函数返回值:无
  196. ***********************************************************/
  197. void Update_flash_read(void)
  198. {
  199. ret_code_t rc;
  200. fds_record_desc_t desc = {0};//用来操作记录的描述符结构清零
  201. fds_find_token_t tok = {0};//保存秘钥的令牌清零
  202. rc = fds_record_find(sportdatakey_file_id, sportdatakey_rec_key, &desc, &tok);//对应KEY记录查找数据
  203. APP_ERROR_CHECK(rc);
  204. if (rc == NRF_SUCCESS){//如果查找成功
  205. fds_flash_record_t config = {0};//
  206. rc = fds_record_open(&desc, &config);//打开记录读取数据
  207. APP_ERROR_CHECK(rc);
  208. memcpy(&m_step_config,config.p_data,sizeof(step_flash));
  209. rc = fds_record_close(&desc);//关闭记录
  210. APP_ERROR_CHECK(rc);
  211. #if DEBUG_EN
  212. SEGGER_RTT_printf(0,"m_step_config.step_number:%d,%d\n",m_step_config.step_number[0],m_step_config.step_number[1]);
  213. #endif
  214. }
  215. }
  216. /**********************************************************
  217. * 函数名字:User_flash_init
  218. * 函数作用:flash功能初始化,定时管理任务
  219. * 函数参数:无
  220. * 函数返回值:无
  221. ***********************************************************/
  222. void User_flash_init(void)
  223. {
  224. ret_code_t rc;
  225. (void) fds_register(fds_evt_handler);
  226. rc = fds_init();
  227. APP_ERROR_CHECK(rc);
  228. while (!m_fds_initialized){}//等待初始化完成
  229. fds_stat_t stat = {0};
  230. rc = fds_stat(&stat);
  231. APP_ERROR_CHECK(rc);
  232. fds_record_desc_t desc = {0};
  233. fds_find_token_t tok = {0};
  234. rc = fds_record_find(sportdatakey_file_id, sportdatakey_rec_key, &desc, &tok);
  235. if (rc == NRF_SUCCESS){//如果查找成功
  236. fds_flash_record_t config = {0};
  237. rc = fds_record_open(&desc, &config);//打开记录读取数据
  238. APP_ERROR_CHECK(rc);
  239. rc = fds_record_close(&desc);//关闭记录
  240. APP_ERROR_CHECK(rc);
  241. #if DEBUG_EN
  242. SEGGER_RTT_printf(0,"fds_record_find,length:%d\n",config.p_header->length_words);
  243. #endif
  244. if(config.p_header->length_words != (sizeof(step_flash)+2)/4){//判断一下读出来的参数结构体长度是否正确
  245. record_delete_next();//把所有记录清零
  246. rc = fds_record_write(&desc, &m_dummy_record);//重新写记录
  247. APP_ERROR_CHECK(rc);
  248. #if DEBUG_EN
  249. SEGGER_RTT_printf(0,"Update config file..done.\n");
  250. #endif
  251. memcpy(&m_step_config, &m_dummy_record,sizeof(step_flash));//以出厂设置作为当前运行参数
  252. }
  253. else{
  254. memcpy(&m_step_config, config.p_data,sizeof(step_flash));
  255. #if DEBUG_EN
  256. #if STEP_TEST
  257. SEGGER_RTT_printf(0,"flash data:%02x,%02x,%02x,%02x,%02x,%02x\n", m_step_config.step_number[0],m_step_config.step_number[1],
  258. m_step_config.step_number[500],m_step_config.step_number[501],m_step_config.step_number[1438],m_step_config.step_number[1439]);
  259. #endif
  260. #endif
  261. }
  262. }
  263. else{
  264. #if DEBUG_EN
  265. SEGGER_RTT_printf(0,"Writing config file...\n");
  266. #endif
  267. rc = fds_record_write(&desc, &m_dummy_record);//重新写记录
  268. APP_ERROR_CHECK(rc);
  269. }
  270. ////////////////测试
  271. #if STEP_TEST
  272. m_step_config.step_journey_cun =1440;
  273. for(uint16_t i=0;i< m_step_config.step_journey_cun*2;i++){
  274. m_step_config.step_number[i]=(0x0000+i);
  275. }
  276. #if DEBUG_EN
  277. SEGGER_RTT_printf(0,"STEP_TEST\n");
  278. #endif
  279. Update_StepToflash();
  280. #endif
  281. }
  282. void Clear_Stepflash(void){
  283. memset(&m_step_config,0,sizeof(step_flash));
  284. }
  285. /**********************************************************
  286. * 函数名字:Rsponse_ReqStepCmd
  287. * 函数作用:回复脚步查询指令
  288. * 函数参数:Packet_number:需要发送的包的数量
  289. * 函数返回值:无
  290. ***********************************************************/
  291. void Rsponse_ReqStepCmd(uint8_t Packet_number)
  292. {
  293. uint8_t buf[40];
  294. uint8_t Length=0;
  295. uint8_t temp=0;
  296. buf[Length++] = 0x02;
  297. buf[Length++] = 0x00;
  298. memcpy(buf+Length, &m_tranforStep.systemtime[0],8);
  299. Length+=8;
  300. buf[Length++] = Packet_number;
  301. for(temp=0;temp<3;temp++){
  302. send_protocol(DEX_NUM,0xA1,buf,Length);
  303. nrf_delay_ms(1);
  304. }
  305. #if DEBUG_EN
  306. SEGGER_RTT_printf(0,"Rsponse Packet length:\n",Packet_number);
  307. #endif
  308. }
  309. /**********************************************************
  310. * 函数名字:SendStep_Packet
  311. * 函数作用:回复脚步查询指令
  312. * 函数参数:发送单个步数帧到ESB当中
  313. * 函数返回值:无
  314. ***********************************************************/
  315. void SendStep_Packet_ToEsb(void)
  316. {
  317. uint8_t buf[230];
  318. uint8_t temp=0;
  319. uint8_t Length=0;
  320. uint8_t StepDateLength=0;
  321. buf[Length++] = 0x02;
  322. buf[Length++] = m_tranforStep.CurrentPacket;
  323. if(1 == m_tranforStep.Packetlength)//单包
  324. StepDateLength =4;
  325. else if(m_tranforStep.BeSentDataLength >= ESB_MAX_SEND_DATA)
  326. StepDateLength =ESB_MAX_SEND_DATA;
  327. else
  328. StepDateLength =m_tranforStep.BeSentDataLength;//判断是否有最后一个包
  329. for(temp=0;temp < StepDateLength;temp +=2){
  330. buf[Length++] = m_step_config.step_number[temp] >>8;
  331. buf[Length++] = m_step_config.step_number[temp] & 0x00ff;
  332. }
  333. for(temp=0;temp<1;temp++){
  334. send_protocol(DEX_NUM,0xA1,buf,Length);
  335. nrf_delay_ms(1);
  336. }
  337. #if DEBUG_EN
  338. SEGGER_RTT_printf(0,"Step no send ==%d,%02x,%02x,%02x\n",m_tranforStep.BeSentDataLength,buf[0],buf[1],buf[2]);
  339. #endif
  340. }
  341. /**********************************************************
  342. * 函数名字:Calculate_Send_Packet
  343. * 函数作用:计算需要发送的脚步
  344. * 函数参数:无
  345. * 函数返回值:无
  346. ***********************************************************/
  347. void Calculate_Send_Packet(void)
  348. {
  349. //计算需要发送的数据包数量
  350. if(m_step_config.step_journey_cun ==0 && (0 == m_step_config.step_number[0])){
  351. m_tranforStep.Packetlength =0;
  352. }
  353. else if((m_step_config.step_journey_cun*4) <=ESB_MAX_SEND_DATA){
  354. m_tranforStep.Packetlength =1;
  355. m_tranforStep.BeSentDataLength = 4;
  356. }
  357. else{
  358. m_tranforStep.BeSentDataLength = (m_step_config.step_journey_cun+1)*4;
  359. m_tranforStep.Packetlength =(m_tranforStep.BeSentDataLength/ESB_MAX_SEND_DATA);
  360. if(m_tranforStep.BeSentDataLength%ESB_MAX_SEND_DATA != 0)
  361. {
  362. m_tranforStep.Packetlength +=1;
  363. }
  364. }
  365. #if DEBUG_EN
  366. SEGGER_RTT_printf(0,"step_journey_cun:%d,%d,Packetlength ==%d\n",m_step_config.step_journey_cun,m_tranforStep.BeSentDataLength,m_tranforStep.Packetlength);
  367. #endif
  368. }
  369. /**********************************************************
  370. * 函数名字:OneHour_StepF
  371. * 函数作用:计算需要发送的脚步
  372. * 函数参数:无
  373. * 函数返回值:无
  374. ***********************************************************/
  375. void OneHour_Step(void)
  376. {
  377. m_step_config.step_journey_cun++;
  378. if(m_step_config.step_journey_cun >= step_number_length){
  379. record_delete_next();
  380. }
  381. }