xspOptFlash.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. #include "xspOptFlash.h"
  2. #include "../Hardware/boardinit.h"
  3. #include "xspDataOpt.h"
  4. FlahOpt g_flashopt;
  5. /*-------------------------------------------------------------------------------
  6. * 初始化
  7. * ------------------------------------------------------------------------------*/
  8. void init_flash(void)
  9. {
  10. g_flashopt.head = 0;
  11. g_flashopt.tail = 0;
  12. g_flashopt.flag = FALSE;
  13. g_flashopt.totalPage = 64; //一共64页
  14. g_flashopt.pageRecord = 32; // 一页32条记录
  15. }
  16. /*-------------------------------------------------------------------------------------------
  17. * 更新当前记录的上报标识 bsend ,将0xFF 更新为0x00, 说明已经上报
  18. * ------------------------------------------------------------------------------------------*/
  19. static void update_bsend_to_0x00(uint32_t baseAddr)
  20. {
  21. uint16_t data = 0x0000;
  22. Flash_BufferWrite_uint16(baseAddr+4,&data,2);//正常的flash 写入
  23. return;
  24. }
  25. /*-------------------------------------------------------------------------------
  26. * 读取flash中的记录
  27. * 返回值 1:成功 0:失败
  28. * --------------------------------------------------------------------------------*/
  29. uint8_t read_flash(uint8_t *outda,uint8_t bupdateSend)
  30. {
  31. uint32_t addr;
  32. uint8_t curPage,curRecord;
  33. if((g_flashopt.tail== g_flashopt.head) &&(g_flashopt.flag == FALSE)){ // 队列为空
  34. // printf("没有新记录\r\n");
  35. return 0;
  36. }
  37. curPage = g_flashopt.head/32;
  38. curRecord = g_flashopt.head%32;
  39. addr = START_FLASH_ADDR + curPage*PAGE_SIZE + curRecord*RECORD_SIZE;
  40. Flash_BufferRead(addr,outda,64);//数据存入到outda中
  41. if((1 == bupdateSend) &&(0xFFFFFFFF != *((uint32_t*)outda)) ) update_bsend_to_0x00(addr);
  42. g_flashopt.head = (g_flashopt.head+1)%RECORD_FIFO;
  43. if(g_flashopt.head == g_flashopt.tail) g_flashopt.flag = FALSE;
  44. return 1;
  45. }
  46. /*-----------------------------------------------------------------------------------
  47. * 写入
  48. * ----------------------------------------------------------------------------------*/
  49. void write_flash(uint8_t *data)
  50. {
  51. uint32_t addr;
  52. uint8_t curPage,curRecord,ret;
  53. if((g_flashopt.tail == g_flashopt.head) &&(g_flashopt.flag==TRUE)){ // fifo满了
  54. printf("队列已满 tail=%d, head=%d\r\n",g_flashopt.tail,g_flashopt.head);
  55. g_flashopt.head = (g_flashopt.head+1)%RECORD_FIFO;
  56. }
  57. curPage = g_flashopt.tail/32;
  58. curRecord = g_flashopt.tail%32;
  59. addr = START_FLASH_ADDR + curPage*PAGE_SIZE + curRecord*RECORD_SIZE;
  60. if(curRecord==0){ // 第0条记录时 要擦除本页
  61. Flash_RangeErase(addr,PAGE_SIZE);
  62. }
  63. ret = Flash_BufferWrite(addr,(uint32_t*)data,64);//正常的flash 写入
  64. if(ret == 0) printf("++++++++++++++写入flash出错误\r\n");
  65. g_flashopt.tail = (g_flashopt.tail+1)%RECORD_FIFO;
  66. if(g_flashopt.tail == g_flashopt.head) g_flashopt.flag = TRUE;
  67. printf("fifo head = %d, tail=%d\r\n",g_flashopt.head,g_flashopt.tail);
  68. }
  69. /*-------------------------------------------------------------------------------
  70. * 读取
  71. * readsize:读取的字节数据
  72. * --------------------------------------------------------------------------------*/
  73. void find_last_record(uint8_t pageIndex, uint8_t recordIndex, uint8_t readsize,uint8_t *outda)
  74. {
  75. uint32_t addr;
  76. addr = START_FLASH_ADDR + pageIndex*PAGE_SIZE + recordIndex*RECORD_SIZE;
  77. Flash_BufferRead(addr,outda,readsize);//数据存入到outda中
  78. return ;
  79. }
  80. #if( 1 )
  81. void find_fifo_head(void)
  82. {
  83. uint8_t i=0,j=0;//,pageIndex = 0, recordIndex = 0,
  84. uint8_t bfirst = 0;
  85. uint32_t min = 0xFFFFFFFF;
  86. tempRecord head;//,tail;
  87. g_flashopt.head = 0;
  88. for(i=0;i<g_flashopt.totalPage;i++){
  89. for(j=0;j<g_flashopt.pageRecord;j++){
  90. find_last_record(i,j,6,head.data); // 一页的第一条记录
  91. if(head.da.recordId != 0xFFFFFFFF){
  92. if(head.da.bSend == 0xFFFF) {
  93. if(min>=head.da.recordId) {
  94. g_flashopt.head = i*g_flashopt.pageRecord + j;
  95. min = head.da.recordId;
  96. }
  97. }
  98. }
  99. else if((head.da.recordId == 0xFFFFFFFF)&&(min == 0xFFFFFFFF)){
  100. if(head.da.bSend == 0xFFFF && bfirst == 0){
  101. g_flashopt.head = i*g_flashopt.pageRecord + j;
  102. bfirst = 1;
  103. }
  104. }
  105. }
  106. }
  107. }
  108. void find_fifo_head00(void)
  109. {
  110. uint8_t i=0,j=0,bfinish = 0;//,pageIndex = 0, recordIndex = 0;
  111. uint32_t min = 0xFFFFFFFF;
  112. tempRecord head,tail;
  113. g_flashopt.head = 0;
  114. for(i=0;i<g_flashopt.totalPage;i++){
  115. find_last_record(i,0,6,head.data); // 一页的第一条记录
  116. find_last_record(i,31,6,tail.data); // 一页的最后一条记录
  117. if(head.da.recordId != 0xFFFFFFFF) {
  118. for(j=0;j<g_flashopt.pageRecord;j++){
  119. find_last_record(i,j,6,head.data);
  120. if((head.da.recordId != 0xFFFFFFFF)){
  121. if(head.da.bSend == 0xFFFF){
  122. if(min>head.da.recordId){
  123. min = head.da.recordId;
  124. g_flashopt.head = i*g_flashopt.pageRecord + j;
  125. }
  126. }
  127. }
  128. }
  129. }
  130. else if((head.da.recordId == 0xFFFFFFFF) &&(tail.da.recordId==0xFFFFFFFF)){
  131. if(min != 0xFFFFFFFF) continue;
  132. if((i+1) == g_flashopt.totalPage) break;
  133. find_last_record(i+1,0,6,head.data);
  134. if(head.da.recordId == 0xFFFFFFFF){
  135. g_flashopt.head = i*g_flashopt.pageRecord;
  136. break;
  137. }
  138. else {
  139. if(head.da.bSend == 0xFFFF) {
  140. g_flashopt.head = i*g_flashopt.pageRecord;
  141. break;
  142. }
  143. else {
  144. for(j=1;j<g_flashopt.pageRecord;j++){
  145. find_last_record(i,j,6,head.data);
  146. if((head.da.recordId != 0xFFFFFFFF)){
  147. if(head.da.bSend == 0xFFFF){
  148. g_flashopt.head = i*g_flashopt.pageRecord + j;
  149. bfinish = 1;
  150. break;
  151. }
  152. }
  153. }
  154. }
  155. }
  156. }
  157. if(bfinish == 1) break;
  158. }
  159. // g_flashopt.head = pageIndex*g_flashopt.pageRecord + recordIndex;
  160. }
  161. #else
  162. void find_fifo_head(void)
  163. {
  164. uint8_t i=0,j=0,pageIndex = 0,recordIndex=0;
  165. int8_t bfirst = -1,bfind = 0;
  166. tempRecord head,tail;
  167. uint32_t min = 0xFFFFFFFF;
  168. for(i=0;i<g_flashopt.totalPage;i++){
  169. find_last_record(i,0,6,head.data);
  170. find_last_record(i,31,6,tail.data);
  171. if(head.da.recordId == 0xFFFFFFFF && tail.da.recordId==0xFFFFFFFF) {
  172. if((bfirst+1) == i){
  173. if(i==0) pageIndex = 0;
  174. else {
  175. find_last_record(i-1,31,6,tail.data); // 上一页的最后一条是否为FFFF
  176. if(tail.da.recordId==0xFFFFFFFF) pageIndex = bfirst-1;
  177. else pageIndex = bfirst;
  178. }
  179. recordIndex = 0;
  180. break;
  181. }
  182. bfirst = i;
  183. continue;
  184. }
  185. else if(head.da.recordId != 0xFFFFFFFF){
  186. if(tail.da.bSend == 0x0000){
  187. continue; // 如果最后一条为00,则表达这一页的数据都已经上发
  188. }
  189. if(head.da.bSend == 0xFFFF) {
  190. min = head.da.recordId;
  191. }
  192. for(j=1;j<g_flashopt.pageRecord;j++){
  193. find_last_record(i,j,6,head.data);
  194. if(head.da.recordId == 0xFFFFFFFF) {
  195. if(head.da.bSend == 0xFFFF && min == 0xFFFFFFFF) {
  196. pageIndex = i;
  197. recordIndex = j;
  198. bfind = 1;
  199. break;
  200. }
  201. }
  202. else {
  203. if(head.da.bSend == 0xFFFF){
  204. if(min>head.da.recordId){
  205. pageIndex = i;
  206. recordIndex = j;
  207. min = head.da.recordId;
  208. bfind = 1;
  209. break;
  210. }
  211. }
  212. }
  213. }
  214. if(bfind == 1) break;
  215. }
  216. }
  217. g_flashopt.head = pageIndex*g_flashopt.pageRecord + recordIndex;
  218. }
  219. #endif
  220. /*-----------------------------------------------------------------------------------------
  221. * powerup 上电后,读取flash中的数据 且根据记录ID找出最新的一条记录的位置
  222. * 以及找到最后一条没有上报的记录的位置
  223. * ----------------------------------------------------------------------------------------*/
  224. void powerup_read_record_from_flash(uint8_t *recordDA)
  225. {
  226. uint8_t i=0,j=0,bfind=0;//,curpage=0,currecord=0
  227. uint8_t data[4] = {0};
  228. uint32_t curread;//,maxread = 0;
  229. /*for(i=0;i<g_flashopt.totalPage;i++){ // 找页
  230. find_last_record(i,0,4,data);
  231. curread = *((uint32_t*)data);
  232. if(curread == 0xFFFFFFFF) {
  233. curpage = (i==0 ? 0:i-1);
  234. break;
  235. }
  236. else {
  237. find_last_record(i,31,4,data); // 判断本页的最后一条,最后一条为空,则最大的记录就在本页
  238. if(*((uint32_t*)data) == 0xFFFFFFFF){
  239. curpage = i;
  240. break;
  241. }
  242. else {
  243. if(maxread<curread){
  244. maxread = curread;
  245. }
  246. else {
  247. curpage = i;
  248. break;
  249. }
  250. }
  251. }
  252. }
  253. maxread = 0;
  254. for(i=0;i<g_flashopt.pageRecord;i++){ // 找页中的最大记录
  255. find_last_record(curpage,i,4,data);
  256. curread = *((uint32_t*)data);
  257. if(curread == 0xFFFFFFFF){
  258. currecord = (i==0?0:i-1);
  259. break;
  260. }
  261. else if(maxread<=curread){
  262. maxread = curread;
  263. }
  264. else {
  265. currecord = i;
  266. break;
  267. }
  268. if((i == (g_flashopt.pageRecord-1))&&(currecord==0)){ // 说明为最后一条
  269. currecord = 31;
  270. }
  271. }
  272. g_flashopt.tail = curpage*g_flashopt.pageRecord+currecord;
  273. g_flashopt.head = g_flashopt.tail;
  274. g_flashopt.tail = (g_flashopt.tail==0?0:g_flashopt.tail+1);*/
  275. for(i=0;i<g_flashopt.totalPage;i++){
  276. for(j=0;j<g_flashopt.pageRecord;j++){
  277. find_last_record(i,j,4,data);
  278. curread = *((uint32_t*)data);
  279. if(curread == 0xFFFFFFFF){
  280. g_flashopt.tail = i*g_flashopt.pageRecord+j;
  281. bfind = 1;
  282. break;
  283. }
  284. }
  285. if(bfind == 1) break;
  286. }
  287. g_flashopt.head = g_flashopt.tail-1; // 为了读取最后一条记录
  288. read_flash(recordDA,0); // 读取的最后一条记录
  289. // for(i=0;i<4;i++){
  290. // update_bsend_to_0x00();
  291. // }
  292. find_fifo_head();// 找到fifo的头
  293. printf("fifo_head = %d,fifo_tail = %d\r\n",g_flashopt.head, g_flashopt.tail);
  294. if(g_flashopt.head != g_flashopt.tail) g_flashopt.flag = TRUE;
  295. else {
  296. g_flashopt.flag = FALSE;
  297. }
  298. if(g_xspReDa.reDa.recordId==0xFFFFFFFF)
  299. memset(&g_xspReDa,0,64);
  300. g_xspCollDa.lastTamout = g_xspReDa.reDa.tamount;
  301. g_xspCollDa.lastToil = g_xspReDa.reDa.toil;
  302. printf("读取flash中最后记录 record=%d,amout=%d,oil=%d,tamout=%lld,toil=%lld\r\n",\
  303. g_xspReDa.reDa.recordId,g_xspReDa.reDa.amount,g_xspReDa.reDa.oil,
  304. g_xspReDa.reDa.tamount,g_xspReDa.reDa.toil);
  305. return;
  306. }
  307. /*-----------------------------------------------------------------------------
  308. * 根据记录ID查找交易记录
  309. * ----------------------------------------------------------------------------*/
  310. uint8_t xsp_check_point_record(uint32_t recordId,uint8_t *recordDa)
  311. {
  312. uint8_t i=0,ret = 0,j=0;
  313. uint8_t data[4] = {0};
  314. uint32_t curread;
  315. for(i=0;i<g_flashopt.totalPage;i++){ // 找页
  316. find_last_record(i,0,4,data); // 读取本页第一条
  317. curread = *((uint32_t*)data);
  318. if(curread == 0xFFFFFFFF) continue;
  319. else if(curread == recordId){ // 说明找到了
  320. find_last_record(i,0,64,recordDa);
  321. ret = 1;
  322. break;
  323. }
  324. else if(curread <recordId){
  325. find_last_record(i,63,4,data); // 读取本页是后一条
  326. curread = *((uint32_t*)data);
  327. if(curread < recordId) continue;
  328. else if(curread == recordId) { // 说明找到了
  329. find_last_record(i,63,64,recordDa);
  330. ret = 1;
  331. break;
  332. }
  333. else {
  334. for(j=1;j<g_flashopt.pageRecord;j++){
  335. find_last_record(i,j,4,data); // 读取本页是后一条
  336. curread = *((uint32_t*)data);
  337. if(curread == recordId){
  338. find_last_record(i,j,64,recordDa);
  339. ret = 1;
  340. break;
  341. }
  342. }
  343. if(ret == 1) break;
  344. }
  345. }
  346. }
  347. return ret;
  348. }