FRAM.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. // ----------------------------------------------------------------------------
  2. // FRAM.c -
  3. // ----------------------------------------------------------------------------
  4. // Beschreibung: FRAM mit SPI-IF
  5. //
  6. // Revision: 02. Juli 2012, neu Maurer, IPE
  7. // 19. Juli 2012, +Polling-Betrieb der FSM
  8. // ----------------------------------------------------------------------------
  9. #include "BMS_Master.h"
  10. FramStatus_t Fram_S;
  11. static const FramStatus_t Fram_S_INIT = {Fram_Idle,NoTask,0,0,(uint8_t*)0,0,0,0};
  12. static int8_t FRAM_FSM_update(uint8_t tick);
  13. static int8_t FRAM_get_SuccessState();
  14. DSPI_config_t FRAM_SPI_conf = {
  15. &DSPI_0,
  16. DSPI_Master,
  17. 8, //FrameSize
  18. DSPI_ClassicFormat,
  19. DSPI_Baud2MHz,
  20. 2, //uint8_t CStoSCK_Delay_Cycles; //nur MasterMode;
  21. 2, //uint8_t AfterSCK_Delay_Cycles; //nur MasterMode;
  22. 0, //uint8_t DelayAfterTransfer_Cycles; //nur MasterMode;
  23. 1,
  24. CS_Cont_ON, //enum{CS_Cont_ON, CS_Cont_OFF};
  25. DSPI0_PortA12
  26. } ;
  27. //==================================================================================================
  28. //API
  29. int8_t FRAM_init(void)
  30. {
  31. int8_t ret;
  32. ret = DSPI_init(&FRAM_SPI_conf);
  33. // SIU.PCR[153].R = 0x0302; // FRAM_WP;act Low PJ[9] Output enable, input enable, Weak PU/PD enable, Weak PD selected
  34. // SIU.PCR[154].R = 0x0303; // FRAM_HOLD;act. Low PJ[10] Output enable, input enable, Weak PU/PD enable, Weak PU selected
  35. SIU.PCR[153].B.OBE = 1; // FRAM_WP;act Low PJ[9] Output enable,
  36. SIU.PCR[154].B.OBE = 1; // FRAM_HOLD;act. Low PJ[10] Output enable
  37. SET_OUTPIN(153); // set PJ[9], /WP = 1 (switch off HW Write Protection of FRAM)
  38. SET_OUTPIN(154); // set PJ[10], /hold = 1 (do not hold the FRAM)
  39. Fram_S = Fram_S_INIT;
  40. return ret;
  41. }
  42. int8_t FRAM_update(uint8_t tick)
  43. {
  44. return FRAM_FSM_update(tick);
  45. }
  46. int8_t FRAM_trigger_write(const vuint16_t Addr, vuint8_t *const data, const vuint8_t num_data)
  47. {
  48. if (num_data < 1) return -1;
  49. if (Fram_S.FsmState != Fram_Idle) return -2;
  50. // if (Fram_S.FramTest_state != 0) return -3;
  51. Fram_S.TaskTrigger = RamWrite;
  52. Fram_S.Addr = Addr;
  53. Fram_S.datastart = data;
  54. Fram_S.num_data = num_data;
  55. return 0;
  56. }
  57. int8_t FRAM_trigger_read(const vuint16_t Addr, vuint8_t *const data, vuint8_t num_data)
  58. {
  59. if (num_data < 1) return -1;
  60. if (Fram_S.FsmState != Fram_Idle) return -2;
  61. // if (Fram_S.FramTest_state != 0) return -3;
  62. Fram_S.TaskTrigger = RamRead;
  63. Fram_S.Addr = Addr;
  64. Fram_S.datastart = data;
  65. Fram_S.num_data = num_data;
  66. return 0;
  67. }
  68. int8_t FRAM_trigger_Test()
  69. {
  70. if (Fram_S.FsmState != Fram_Idle) return -1;
  71. Fram_S.TaskTrigger = RamTest;
  72. return 0;
  73. }
  74. int8_t FRAM_Test_update()
  75. {
  76. #define NUM_DATA 10
  77. #define DATA_1 0xCC
  78. #define DATA_2 0x33
  79. static vuint8_t data[NUM_DATA];
  80. uint8_t i = 0;
  81. switch (Fram_S.FramTest_state) {
  82. case 0:
  83. if (Fram_S.TaskTrigger == RamTest) {
  84. Fram_S.TaskTrigger = NoTask;
  85. for (i=0;i<NUM_DATA;i++) data[i] = DATA_1;
  86. if (FRAM_trigger_write(0, &data[0], NUM_DATA) < 0) return -1;
  87. Fram_S.FramTest_state = 1;
  88. }
  89. break;
  90. case 1:
  91. if (FRAM_get_SuccessState() < 0) {
  92. Fram_S.FramTest_state = 0;
  93. return -2;
  94. }
  95. if (FRAM_get_SuccessState() > 0) {
  96. Fram_S.FramTest_state = 0;
  97. for (i=0;i<NUM_DATA;i++) data[i] = 0;
  98. if (FRAM_trigger_read(0, data, NUM_DATA) < 0) return -3;
  99. Fram_S.FramTest_state = 2;
  100. }
  101. break;
  102. case 2:
  103. if (FRAM_get_SuccessState() < 0) {
  104. Fram_S.FramTest_state = 0;
  105. return -4;
  106. }
  107. if (FRAM_get_SuccessState() > 0) {
  108. Fram_S.FramTest_state = 0;
  109. for (i=0;i<NUM_DATA;i++) if ( data[i] != DATA_1 ) return -5;
  110. for (i=0;i<NUM_DATA;i++) data[i] = DATA_2;
  111. if (FRAM_trigger_write(0, &data[0], NUM_DATA) < 0) return -6;
  112. Fram_S.FramTest_state = 3;
  113. }
  114. break;
  115. case 3:
  116. if (FRAM_get_SuccessState() < 0) {
  117. Fram_S.FramTest_state = 0;
  118. return -7;
  119. }
  120. if (FRAM_get_SuccessState() > 0) {
  121. for (i=0;i<NUM_DATA;i++) data[i] = 0;
  122. FRAM_trigger_read(0, &data[0], NUM_DATA);
  123. Fram_S.FramTest_state += 1;
  124. }
  125. break;
  126. case 4:
  127. if (FRAM_get_SuccessState() < 0) {
  128. Fram_S.FramTest_state = 0;
  129. return -8;
  130. }
  131. if (FRAM_get_SuccessState() > 0) {
  132. Fram_S.FramTest_state = 0;
  133. for (i=0;i<NUM_DATA;i++) if (data[i] != DATA_2) return -9;
  134. return 1; //Test erfolgreich
  135. }
  136. break;
  137. }
  138. return 0;
  139. #undef NUM_DATA
  140. #undef DATA_1
  141. #undef DATA_2
  142. }
  143. //==================================================================================
  144. static int8_t FRAM_push(uint16_t data, uint8_t isEOQ)
  145. {
  146. return DSPI_push(&FRAM_SPI_conf, data, isEOQ);
  147. }
  148. static int8_t FRAM_pop(vuint16_t *dataptr)
  149. {
  150. return DSPI_pop(&FRAM_SPI_conf, dataptr);
  151. }
  152. //-----------------------------------------------------------------------
  153. typedef enum {noEOQ=0, withEOQ} EOQbool_t;
  154. typedef struct {
  155. vuint8_t *datastart;
  156. uint16_t i_data;
  157. uint16_t i_read;
  158. uint16_t i_dummy;
  159. uint16_t num_data;
  160. EOQbool_t EOQbool;
  161. uint8_t busy;
  162. } Seqnce_Status_t;
  163. static volatile Seqnce_Status_t Seqnce_S;
  164. static int8_t FRAM_Seqnce_init(){
  165. Seqnce_S.datastart = 0;
  166. Seqnce_S.num_data = 0;
  167. Seqnce_S.i_data = 0;
  168. Seqnce_S.i_read = 0;
  169. Seqnce_S.i_dummy = 0;
  170. Seqnce_S.EOQbool = noEOQ;
  171. Seqnce_S.busy = 0;
  172. return 0;
  173. }
  174. static int8_t FRAM_Seqnce_try_load(vuint8_t *data, uint16_t num_data, EOQbool_t EOQbool)
  175. {
  176. if (Seqnce_S.busy) return -1;
  177. Seqnce_S.datastart = data;
  178. Seqnce_S.num_data = num_data;
  179. Seqnce_S.i_data = 0;
  180. Seqnce_S.i_read = 0;
  181. Seqnce_S.EOQbool = EOQbool;
  182. Seqnce_S.busy = 1;
  183. return 0;
  184. }
  185. static int8_t FRAM_get_SuccessState()
  186. {
  187. if (Fram_S.TaskTrigger == NoTask) {
  188. if (Fram_S.Flags.B.FSM_TO) return -1;
  189. if (Fram_S.Flags.B.JobFinished) return 1;
  190. }
  191. return 0;
  192. }
  193. static int8_t FRAM_Seqnce_try_push()
  194. {
  195. uint16_t cnt_sent = 0;
  196. uint8_t isEOQ = 0;
  197. while (Seqnce_S.i_data < Seqnce_S.num_data) // transmit still running
  198. {
  199. if ( Seqnce_S.i_data == (Seqnce_S.num_data-1) && Seqnce_S.EOQbool==withEOQ ) // last Byte transmit
  200. {
  201. isEOQ = 1;
  202. }
  203. if ( FRAM_push((uint16_t)(Seqnce_S.datastart[Seqnce_S.i_data]) & 0xFF, isEOQ) < 0 )
  204. {
  205. if ( cnt_sent==0 )
  206. return -1; //nothing sent
  207. else
  208. return 0; //sent but not finished
  209. }
  210. else
  211. {
  212. cnt_sent++;
  213. Seqnce_S.i_data++;
  214. }
  215. }
  216. //end of data
  217. Seqnce_S.busy = 0;
  218. return 1; //1 = finished
  219. }
  220. static int8_t FRAM_Seqnce_load_forDummies(vuint8_t *datastart,uint16_t num_data)
  221. {
  222. // if (Seqnce_S.busy) return -1;
  223. Seqnce_S.datastart = datastart;
  224. Seqnce_S.num_data = num_data;
  225. Seqnce_S.i_data = 0;
  226. Seqnce_S.i_read = 0;
  227. Seqnce_S.i_dummy = 0;
  228. Seqnce_S.busy = 1;
  229. return 0;
  230. }
  231. static int8_t FRAM_Seqnce_try_pushDummies()
  232. {
  233. uint16_t cnt_sent = 0;
  234. uint8_t isEOQ = 0;
  235. while (Seqnce_S.i_data < Seqnce_S.num_data) // while transmit still running
  236. {
  237. if ( Seqnce_S.i_data == (Seqnce_S.num_data-1) ) // last Byte transmit?
  238. {
  239. isEOQ = 1;
  240. }
  241. if ( FRAM_push(Seqnce_S.i_data, isEOQ) < 0 )
  242. {
  243. return 0; //sent but not finished
  244. }
  245. else
  246. {
  247. Seqnce_S.i_data++;
  248. cnt_sent++;
  249. if (cnt_sent>=4)
  250. return 0; //nothing sent
  251. }
  252. }
  253. Seqnce_S.busy = 0;
  254. return 1; //1 = finished
  255. }
  256. static int8_t FRAM_Seqnce_try_pop()
  257. {
  258. vuint16_t data_tmp = 0;
  259. while (Seqnce_S.i_dummy < Fram_S.n_RxDummies)
  260. {
  261. if ( FRAM_pop(&data_tmp) < 0 )
  262. return 0; // Error: Fifo empty
  263. else
  264. Seqnce_S.i_dummy++;
  265. }
  266. data_tmp = 4;
  267. while (Seqnce_S.i_read < Seqnce_S.num_data)
  268. {
  269. if ( FRAM_pop(&data_tmp) < 0 )
  270. return 0; // Error: Fifo empty
  271. else
  272. {
  273. Seqnce_S.datastart[Seqnce_S.i_read] = (vuint8_t)(data_tmp&0xFF);
  274. Seqnce_S.i_read++;
  275. }
  276. }
  277. //end of data
  278. return 1; //1 = finished
  279. }
  280. //-----------------------------------------------------------------------
  281. static int8_t FRAM_checkTimeOut(uint16_t Cnt, uint16_t TO_Value)
  282. {
  283. if (Cnt >= TO_Value) {
  284. FRAM_init();
  285. Fram_S.Flags.B.FSM_TO = 1;
  286. return -1;
  287. }
  288. return 0;
  289. }
  290. //FRAM FSM
  291. static int8_t FRAM_FSM_update(uint8_t tick)
  292. {
  293. #define FSM_TIMEOUT 6
  294. static uint8_t OPCSeq[3];
  295. static uint16_t StateTimeoutCnt = 0;
  296. if (tick == 1) StateTimeoutCnt += 1;
  297. switch (Fram_S.FsmState) {
  298. case Fram_Idle:
  299. if (Fram_S.TaskTrigger == RamWrite) {
  300. //PushOPCs
  301. //if (Fram_S.num_data == 0) return -1;
  302. FRAM_SPI_conf.CS_Cont = CS_Cont_OFF; //Select geht nach dem Byte aus
  303. //Write_Enable vor jedem Schreiben auf Speicher
  304. FRAM_push(WREN_OPC,0);
  305. //Write-Befehl
  306. FRAM_SPI_conf.CS_Cont = CS_Cont_ON; //CS bleibt zw. den Bytes aktiv
  307. OPCSeq[0] = WRITE_OPC;
  308. //2Byte Adresse (= Adr. des 1.Databytes) 0..7FFFh
  309. OPCSeq[1] = (uint8_t)(Fram_S.Addr>>8) & 0x7F;
  310. OPCSeq[2] = (uint8_t)Fram_S.Addr & 0xFF;
  311. if (FRAM_Seqnce_try_load(OPCSeq,3,noEOQ) >= 0 ) {
  312. Fram_S.Flags.R = 0;
  313. StateTimeoutCnt = 0;
  314. Fram_S.FsmState = Fram_Write_1;
  315. Fram_S.TaskTrigger = NoTask;
  316. }
  317. }
  318. else if (Fram_S.TaskTrigger == RamRead) {
  319. if (Fram_S.num_data == 0) break;
  320. FRAM_SPI_conf.CS_Cont = CS_Cont_ON;
  321. OPCSeq[0] = READ_OPC;
  322. //2Byte Adresse (= Adr. des 1.Databytes) 0..7FFFh
  323. OPCSeq[1] = (uint8_t)(Fram_S.Addr>>8) & 0x7F;
  324. OPCSeq[2] = (uint8_t)Fram_S.Addr & 0xFF;
  325. DSPI_Clear_RxFifo(&FRAM_SPI_conf);
  326. if (FRAM_Seqnce_try_load(OPCSeq,3,noEOQ) >= 0 ) {
  327. DSPI_Clear_RxFifo(&FRAM_SPI_conf);
  328. StateTimeoutCnt = 0;
  329. Fram_S.Flags.R = 0;
  330. Fram_S.n_RxDummies = 3;
  331. Fram_S.FsmState = Fram_Read_1;
  332. Fram_S.TaskTrigger = NoTask;
  333. }
  334. }
  335. break;
  336. //auf den Ram Schreiben
  337. case Fram_Write_1:
  338. if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -1;
  339. if (FRAM_Seqnce_try_push() == 1 ) { //finished
  340. FRAM_Seqnce_try_load(Fram_S.datastart,Fram_S.num_data,withEOQ);
  341. StateTimeoutCnt = 0;
  342. Fram_S.FsmState = Fram_Write_2;
  343. }
  344. break;
  345. case Fram_Write_2:
  346. if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -2;
  347. if (FRAM_Seqnce_try_push() == 1 ) { //finished
  348. StateTimeoutCnt = 0;
  349. Fram_S.FsmState = Fram_Write_3;
  350. }
  351. break;
  352. case Fram_Write_3:
  353. {
  354. volatile struct DSPI_tag *p_DSPI = FRAM_SPI_conf.p_Modul;
  355. if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -3;
  356. if (p_DSPI->SR.B.EOQF == 1) {
  357. p_DSPI->SR.B.EOQF = 1;
  358. Fram_S.Flags.B.JobFinished = 1;
  359. StateTimeoutCnt = 0;
  360. Fram_S.FsmState = Fram_Idle;
  361. }
  362. break;
  363. }
  364. //vom Ram lesen
  365. case Fram_Read_1:
  366. if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -4;
  367. if (FRAM_Seqnce_try_push() == 1 ) { //finished?
  368. FRAM_Seqnce_load_forDummies(Fram_S.datastart,Fram_S.num_data);
  369. StateTimeoutCnt = 0;
  370. Fram_S.FsmState = Fram_Read_2;
  371. }
  372. break;
  373. case Fram_Read_2:
  374. if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) return -6;
  375. FRAM_Seqnce_try_pop();
  376. if (FRAM_Seqnce_try_pushDummies() == 1 ) { //finished
  377. StateTimeoutCnt = 0;
  378. Fram_S.FsmState = Fram_Read_3;
  379. }
  380. break;
  381. case Fram_Read_3:
  382. {
  383. volatile struct DSPI_tag *p_DSPI = FRAM_SPI_conf.p_Modul;
  384. if (FRAM_checkTimeOut(StateTimeoutCnt,FSM_TIMEOUT) < 0) {
  385. // while (1) {}
  386. return -6;
  387. }
  388. if (FRAM_Seqnce_try_pop()==1 ) {// && p_DSPI->SR.B.EOQF == 1) {
  389. p_DSPI->SR.B.EOQF = 1;
  390. StateTimeoutCnt = 0;
  391. Fram_S.Flags.B.JobFinished = 1;
  392. Fram_S.FsmState = Fram_Idle;
  393. }
  394. break;
  395. }
  396. }
  397. return 0;
  398. #undef FSM_TIMEOUT
  399. }