fifo.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. #include <string.h>
  2. #include <gfambrtucom.h>
  3. #include "driverlib/sw_crc.h"
  4. /////////////////////////////////////////////////////////////////////////////
  5. #define FIFO_COUNT 2
  6. #define FIFO_BUFFER_SIZE 256
  7. #define FIFO_BUFFER_MASK (FIFO_BUFFER_SIZE - 1)
  8. /////////////////////////////////////////////////////////////////////////////
  9. typedef struct _FIFOHDR
  10. {
  11. volatile size_t nReadPtr;
  12. volatile size_t nWritePtr;
  13. volatile size_t nCbData;
  14. size_t nCbSize;
  15. size_t nBufferMask;
  16. volatile uint32_t nFlags;
  17. GFA_FIFO_BACKEND backend;
  18. }FIFOHDR, *LPFIFOHDR;
  19. typedef const FIFOHDR *LPCFIFOHDR;
  20. /////////////////////////////////////////////////////////////////////////////
  21. typedef struct _FIFO
  22. {
  23. FIFOHDR hdr;
  24. uint8_t fifo[FIFO_BUFFER_SIZE];
  25. }FIFO, *LPFIFO;
  26. typedef const FIFO *LPCFIFO;
  27. /////////////////////////////////////////////////////////////////////////////
  28. static FIFO g_fifo[FIFO_COUNT];
  29. /////////////////////////////////////////////////////////////////////////////
  30. /////////////////////////////////////////////////////////////////////////////
  31. static int _IsPowerOf2(size_t x)
  32. {
  33. return x && !(x & (x - 1));
  34. }
  35. /////////////////////////////////////////////////////////////////////////////
  36. /////////////////////////////////////////////////////////////////////////////
  37. HFIFO GfaMbFifoCreate(int nFifoIndex, LPCGFA_FIFO_BACKEND pBackend)
  38. {
  39. LPFIFO p;
  40. if((nFifoIndex < 0) || (nFifoIndex >= FIFO_COUNT))
  41. return NULL;
  42. if(!_IsPowerOf2(FIFO_BUFFER_SIZE))
  43. return NULL;
  44. p = &g_fifo[nFifoIndex];
  45. memset(p, 0, sizeof(FIFO));
  46. p->hdr.nCbSize = FIFO_BUFFER_SIZE;
  47. p->hdr.nBufferMask = FIFO_BUFFER_MASK;
  48. memcpy(&p->hdr.backend, pBackend, sizeof(GFA_FIFO_BACKEND));
  49. return (HFIFO)p;
  50. }
  51. /////////////////////////////////////////////////////////////////////////////
  52. void GfaMbFifoRelease(HFIFO hFifo)
  53. {
  54. }
  55. /////////////////////////////////////////////////////////////////////////////
  56. void GfaMbFifoReset(HFIFO hFifo, bool bLock)
  57. {
  58. bool bPrevLocked;
  59. register LPFIFO pf = (LPFIFO)hFifo;
  60. if(bLock && pf->hdr.backend.pfnLockBackend)
  61. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  62. pf->hdr.nReadPtr = 0;
  63. pf->hdr.nWritePtr = 0;
  64. pf->hdr.nCbData = 0;
  65. if(bLock && pf->hdr.backend.pfnLockBackend)
  66. (*pf->hdr.backend.pfnLockBackend)(bPrevLocked);
  67. }
  68. /////////////////////////////////////////////////////////////////////////////
  69. size_t GfaMbFifoRead(HFIFO hFifo, void *pData, size_t nCbData, bool bLock)
  70. {
  71. size_t nToRead;
  72. uint8_t *pByte = (uint8_t*)pData;
  73. register LPFIFO pf = (LPFIFO)hFifo;
  74. if(bLock && pf->hdr.backend.pfnLockBackend)
  75. (*pf->hdr.backend.pfnLockBackend)(false);
  76. for(nToRead = nCbData; nCbData; --nCbData)
  77. {
  78. if((pf->hdr.nWritePtr == pf->hdr.nReadPtr) && !pf->hdr.nCbData)
  79. break;
  80. *pByte++ = pf->fifo[pf->hdr.nReadPtr++];
  81. pf->hdr.nReadPtr &= pf->hdr.nBufferMask;
  82. pf->hdr.nCbData--;
  83. }
  84. if(bLock && pf->hdr.backend.pfnLockBackend)
  85. (*pf->hdr.backend.pfnLockBackend)(true);
  86. return nToRead - nCbData;
  87. }
  88. /////////////////////////////////////////////////////////////////////////////
  89. size_t GfaMbFifoWrite(HFIFO hFifo, const void *pData, size_t nCbData, bool bLock)
  90. {
  91. size_t nToWrite;
  92. const uint8_t *pByte = (const uint8_t*)pData;
  93. register LPFIFO pf = (LPFIFO)hFifo;
  94. if(bLock && pf->hdr.backend.pfnLockBackend)
  95. (*pf->hdr.backend.pfnLockBackend)(false);
  96. for(nToWrite = nCbData; nCbData; --nCbData)
  97. {
  98. if((pf->hdr.nCbData == pf->hdr.nCbSize))
  99. break;
  100. pf->fifo[pf->hdr.nWritePtr++] = *pByte++;
  101. pf->hdr.nWritePtr &= pf->hdr.nBufferMask;
  102. pf->hdr.nCbData++;
  103. }
  104. if(bLock && pf->hdr.backend.pfnLockBackend)
  105. (*pf->hdr.backend.pfnLockBackend)(true);
  106. return nToWrite - nCbData;
  107. }
  108. /////////////////////////////////////////////////////////////////////////////
  109. bool GfaMbFifoPop(HFIFO hFifo, uint8_t *b, bool bLock)
  110. {
  111. bool bRet;
  112. register LPFIFO pf = (LPFIFO)hFifo;
  113. if(bLock && pf->hdr.backend.pfnLockBackend)
  114. {
  115. (*pf->hdr.backend.pfnLockBackend)(false);
  116. if((bRet = !!pf->hdr.nCbData))
  117. {
  118. *b = pf->fifo[pf->hdr.nReadPtr++];
  119. pf->hdr.nReadPtr &= pf->hdr.nBufferMask;
  120. pf->hdr.nCbData--;
  121. }
  122. (*pf->hdr.backend.pfnLockBackend)(true);
  123. }
  124. else
  125. {
  126. if((bRet = !!pf->hdr.nCbData))
  127. {
  128. *b = pf->fifo[pf->hdr.nReadPtr++];
  129. pf->hdr.nReadPtr &= pf->hdr.nBufferMask;
  130. pf->hdr.nCbData--;
  131. }
  132. }
  133. return bRet;
  134. }
  135. /////////////////////////////////////////////////////////////////////////////
  136. bool GfaMbFifoPush(HFIFO hFifo, uint8_t b, bool bLock)
  137. {
  138. bool bRet;
  139. register LPFIFO pf = (LPFIFO)hFifo;
  140. if(bLock && pf->hdr.backend.pfnLockBackend)
  141. {
  142. (*pf->hdr.backend.pfnLockBackend)(false);
  143. if((bRet = (pf->hdr.nCbData < pf->hdr.nCbSize)))
  144. {
  145. pf->fifo[pf->hdr.nWritePtr++] = b;
  146. pf->hdr.nWritePtr &= pf->hdr.nBufferMask;
  147. pf->hdr.nCbData++;
  148. }
  149. (*pf->hdr.backend.pfnLockBackend)(true);
  150. }
  151. else
  152. {
  153. if((bRet = (pf->hdr.nCbData < pf->hdr.nCbSize)))
  154. {
  155. pf->fifo[pf->hdr.nWritePtr++] = b;
  156. pf->hdr.nWritePtr &= pf->hdr.nBufferMask;
  157. pf->hdr.nCbData++;
  158. }
  159. }
  160. return bRet;
  161. }
  162. /////////////////////////////////////////////////////////////////////////////
  163. size_t GfaMbFifoPeek(HFIFO hFifo, bool bLock)
  164. {
  165. bool bPrevLocked;
  166. size_t nAvail;
  167. register LPFIFO pf = (LPFIFO)hFifo;
  168. if(bLock && pf->hdr.backend.pfnLockBackend)
  169. {
  170. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  171. nAvail = pf->hdr.nCbData;
  172. if(bPrevLocked)
  173. (*pf->hdr.backend.pfnLockBackend)(true);
  174. return nAvail;
  175. }
  176. else
  177. return pf->hdr.nCbData;
  178. }
  179. /////////////////////////////////////////////////////////////////////////////
  180. bool GfaMbFifoCanWrite(HFIFO hFifo, bool bLock)
  181. {
  182. bool bPrevLocked, bCanWrite;
  183. register LPFIFO pf = (LPFIFO)hFifo;
  184. if(bLock && pf->hdr.backend.pfnLockBackend)
  185. {
  186. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  187. bCanWrite = (pf->hdr.nWritePtr != pf->hdr.nReadPtr) || !pf->hdr.nCbData;
  188. if(bPrevLocked)
  189. (*pf->hdr.backend.pfnLockBackend)(true);
  190. return bCanWrite;
  191. }
  192. else
  193. return (pf->hdr.nWritePtr != pf->hdr.nReadPtr) || !pf->hdr.nCbData;
  194. }
  195. /////////////////////////////////////////////////////////////////////////////
  196. bool GfaMbFifoEmpty(HFIFO hFifo, bool bLock)
  197. {
  198. bool bPrevLocked, bEmpty;
  199. register LPFIFO pf = (LPFIFO)hFifo;
  200. if(bLock && pf->hdr.backend.pfnLockBackend)
  201. {
  202. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  203. bEmpty = !pf->hdr.nCbData;
  204. if(bPrevLocked)
  205. (*pf->hdr.backend.pfnLockBackend)(true);
  206. return bEmpty;
  207. }
  208. else
  209. return !pf->hdr.nCbData;
  210. }
  211. /////////////////////////////////////////////////////////////////////////////
  212. bool GfaMbFifoRxPrepare(HFIFO hFifo, bool bLock)
  213. {
  214. bool bPrevLocked, bRet = false;
  215. register LPFIFO pf = (LPFIFO)hFifo;
  216. if(pf->hdr.backend.pfnRxPrepare)
  217. {
  218. if(bLock && pf->hdr.backend.pfnLockBackend)
  219. {
  220. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  221. bRet = (*pf->hdr.backend.pfnRxPrepare)();
  222. if(bPrevLocked)
  223. (*pf->hdr.backend.pfnLockBackend)(true);
  224. }
  225. else
  226. bRet = (*pf->hdr.backend.pfnRxPrepare)();
  227. }
  228. return bRet;
  229. }
  230. /////////////////////////////////////////////////////////////////////////////
  231. void GfaMbFifoRxStart(HFIFO hFifo, bool bLock)
  232. {
  233. bool bPrevLocked;
  234. register LPFIFO pf = (LPFIFO)hFifo;
  235. if(pf->hdr.backend.pfnRxStart)
  236. {
  237. if(bLock && pf->hdr.backend.pfnLockBackend)
  238. {
  239. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  240. (*pf->hdr.backend.pfnRxStart)();
  241. if(bPrevLocked)
  242. (*pf->hdr.backend.pfnLockBackend)(true);
  243. }
  244. else
  245. (*pf->hdr.backend.pfnRxStart)();
  246. }
  247. }
  248. /////////////////////////////////////////////////////////////////////////////
  249. bool GfaMbFifoRxFinalize(HFIFO hFifo, bool bLock)
  250. {
  251. bool bPrevLocked, bRet = false;
  252. register LPFIFO pf = (LPFIFO)hFifo;
  253. if(pf->hdr.backend.pfnRxFinalize)
  254. {
  255. if(bLock && pf->hdr.backend.pfnLockBackend)
  256. {
  257. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  258. bRet = (*pf->hdr.backend.pfnRxFinalize)();
  259. if(bPrevLocked)
  260. (*pf->hdr.backend.pfnLockBackend)(true);
  261. }
  262. else
  263. bRet = (*pf->hdr.backend.pfnRxFinalize)();
  264. }
  265. return bRet;
  266. }
  267. /////////////////////////////////////////////////////////////////////////////
  268. bool GfaMbFifoTxPrepare(HFIFO hFifo, bool bLock)
  269. {
  270. bool bPrevLocked, bRet = false;
  271. register LPFIFO pf = (LPFIFO)hFifo;
  272. if(pf->hdr.backend.pfnTxPrepare)
  273. {
  274. if(bLock && pf->hdr.backend.pfnLockBackend)
  275. {
  276. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  277. bRet = (*pf->hdr.backend.pfnTxPrepare)();
  278. if(bPrevLocked)
  279. (*pf->hdr.backend.pfnLockBackend)(true);
  280. }
  281. else
  282. bRet = (*pf->hdr.backend.pfnTxPrepare)();
  283. }
  284. return bRet;
  285. }
  286. /////////////////////////////////////////////////////////////////////////////
  287. void GfaMbFifoTxStart(HFIFO hFifo, bool bLock)
  288. {
  289. bool bPrevLocked;
  290. register LPFIFO pf = (LPFIFO)hFifo;
  291. if(pf->hdr.backend.pfnTxStart)
  292. {
  293. if(bLock && pf->hdr.backend.pfnLockBackend)
  294. {
  295. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  296. (*pf->hdr.backend.pfnTxStart)();
  297. if(bPrevLocked)
  298. (*pf->hdr.backend.pfnLockBackend)(true);
  299. }
  300. else
  301. (*pf->hdr.backend.pfnTxStart)();
  302. }
  303. }
  304. /////////////////////////////////////////////////////////////////////////////
  305. bool GfaMbFifoTxFinalize(HFIFO hFifo, bool bLock)
  306. {
  307. bool bPrevLocked, bRet = false;
  308. register LPFIFO pf = (LPFIFO)hFifo;
  309. if(pf->hdr.backend.pfnTxFinalize)
  310. {
  311. if(bLock && pf->hdr.backend.pfnLockBackend)
  312. {
  313. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  314. bRet = (*pf->hdr.backend.pfnTxFinalize)();
  315. if(bPrevLocked)
  316. (*pf->hdr.backend.pfnLockBackend)(true);
  317. }
  318. else
  319. bRet = (*pf->hdr.backend.pfnTxFinalize)();
  320. }
  321. return bRet;
  322. }
  323. /////////////////////////////////////////////////////////////////////////////
  324. void GfaMbFifoSetFlags(HFIFO hFifo, uint32_t nFlags, bool bLock)
  325. {
  326. bool bPrevLocked;
  327. register LPFIFO pf = (LPFIFO)hFifo;
  328. if(bLock && pf->hdr.backend.pfnLockBackend)
  329. {
  330. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  331. pf->hdr.nFlags |= nFlags;
  332. if(bPrevLocked)
  333. (*pf->hdr.backend.pfnLockBackend)(true);
  334. }
  335. else
  336. pf->hdr.nFlags |= nFlags;
  337. }
  338. /////////////////////////////////////////////////////////////////////////////
  339. void GfaMbFifoClearFlags(HFIFO hFifo, uint32_t nFlags, bool bLock)
  340. {
  341. bool bPrevLocked;
  342. register LPFIFO pf = (LPFIFO)hFifo;
  343. if(bLock && pf->hdr.backend.pfnLockBackend)
  344. {
  345. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  346. pf->hdr.nFlags &= ~nFlags;
  347. if(bPrevLocked)
  348. (*pf->hdr.backend.pfnLockBackend)(true);
  349. }
  350. else
  351. pf->hdr.nFlags &= ~nFlags;
  352. }
  353. /////////////////////////////////////////////////////////////////////////////
  354. uint32_t GfaMbFifoGetFlags(HFIFO hFifo, bool bLock)
  355. {
  356. uint32_t nFlags;
  357. bool bPrevLocked;
  358. register LPFIFO pf = (LPFIFO)hFifo;
  359. if(bLock && pf->hdr.backend.pfnLockBackend)
  360. {
  361. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  362. nFlags = pf->hdr.nFlags;
  363. if(bPrevLocked)
  364. (*pf->hdr.backend.pfnLockBackend)(true);
  365. return nFlags;
  366. }
  367. else
  368. return pf->hdr.nFlags;
  369. }
  370. bool GfaMbFifoMatchFlags(HFIFO hFifo, uint32_t nFlags, bool bLock)
  371. {
  372. bool bMatch;
  373. bool bPrevLocked;
  374. register LPFIFO pf = (LPFIFO)hFifo;
  375. if(bLock && pf->hdr.backend.pfnLockBackend)
  376. {
  377. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  378. bMatch = (pf->hdr.nFlags & nFlags) == nFlags;
  379. if(bPrevLocked)
  380. (*pf->hdr.backend.pfnLockBackend)(true);
  381. return bMatch;
  382. }
  383. else
  384. return (pf->hdr.nFlags & nFlags) == nFlags;
  385. }
  386. uint16_t GfaMbFifoCalcCRC(HFIFO hFifo, bool bLock)
  387. {
  388. bool bPrevLocked = false;
  389. register LPFIFO pf = (LPFIFO)hFifo;
  390. if(bLock && pf->hdr.backend.pfnLockBackend)
  391. bPrevLocked = (*pf->hdr.backend.pfnLockBackend)(false);
  392. if(!pf->hdr.nCbData)
  393. {
  394. if(bLock && pf->hdr.backend.pfnLockBackend)
  395. (*pf->hdr.backend.pfnLockBackend)(bPrevLocked);
  396. return 0;
  397. }
  398. size_t nCbData = pf->hdr.nCbData;
  399. size_t nReadPtr = pf->hdr.nReadPtr;
  400. uint8_t b;
  401. uint16_t nCrcSw = 0xFFFF;
  402. while(nCbData--) // calculate the CRC
  403. {
  404. b = pf->fifo[nReadPtr++];
  405. nReadPtr &= pf->hdr.nBufferMask;
  406. nCrcSw = Crc16(nCrcSw, &b, 1);
  407. }
  408. if(bLock && pf->hdr.backend.pfnLockBackend)
  409. (*pf->hdr.backend.pfnLockBackend)(bPrevLocked);
  410. return nCrcSw;
  411. }