xpacket_fifo_v1_00_b.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /******************************************************************************
  2. *
  3. * Author: Xilinx, Inc.
  4. *
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2 of the License, or (at your
  9. * option) any later version.
  10. *
  11. *
  12. * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
  13. * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
  14. * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
  15. * XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
  16. * FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
  17. * ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
  18. * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
  19. * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
  20. * WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
  21. * CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
  22. * FITNESS FOR A PARTICULAR PURPOSE.
  23. *
  24. *
  25. * Xilinx hardware products are not intended for use in life support
  26. * appliances, devices, or systems. Use in such applications is
  27. * expressly prohibited.
  28. *
  29. *
  30. * (c) Copyright 2002-2004 Xilinx Inc.
  31. * All rights reserved.
  32. *
  33. *
  34. * You should have received a copy of the GNU General Public License along
  35. * with this program; if not, write to the Free Software Foundation, Inc.,
  36. * 675 Mass Ave, Cambridge, MA 02139, USA.
  37. *
  38. ******************************************************************************/
  39. /*****************************************************************************/
  40. /*
  41. *
  42. * @file xpacket_fifo_v1_00_b.c
  43. *
  44. * Contains functions for the XPacketFifoV100b component. See xpacket_fifo_v1_00_b.h
  45. * for more information about the component.
  46. *
  47. * <pre>
  48. * MODIFICATION HISTORY:
  49. *
  50. * Ver Who Date Changes
  51. * ----- ---- -------- -----------------------------------------------
  52. * 1.00b rpm 03/26/02 First release
  53. * </pre>
  54. *
  55. *****************************************************************************/
  56. /***************************** Include Files *********************************/
  57. #include "xbasic_types.h"
  58. #include "xio.h"
  59. #include "xstatus.h"
  60. #include "xpacket_fifo_v1_00_b.h"
  61. /************************** Constant Definitions *****************************/
  62. /* width of a FIFO word */
  63. #define XPF_FIFO_WIDTH_BYTE_COUNT 4UL
  64. /**************************** Type Definitions *******************************/
  65. /***************** Macros (Inline Functions) Definitions *********************/
  66. /************************* Variable Definitions ******************************/
  67. /************************** Function Prototypes ******************************/
  68. /*****************************************************************************/
  69. /*
  70. *
  71. * This function initializes a packet FIFO. Initialization resets the
  72. * FIFO such that it's empty and ready to use.
  73. *
  74. * @param InstancePtr contains a pointer to the FIFO to operate on.
  75. * @param RegBaseAddress contains the base address of the registers for
  76. * the packet FIFO.
  77. * @param DataBaseAddress contains the base address of the data for
  78. * the packet FIFO.
  79. *
  80. * @return
  81. *
  82. * Always returns XST_SUCCESS.
  83. *
  84. * @note
  85. *
  86. * None.
  87. *
  88. ******************************************************************************/
  89. XStatus
  90. XPacketFifoV100b_Initialize(XPacketFifoV100b * InstancePtr,
  91. u32 RegBaseAddress, u32 DataBaseAddress)
  92. {
  93. /* assert to verify input argument are valid */
  94. XASSERT_NONVOID(InstancePtr != NULL);
  95. /* initialize the component variables to the specified state */
  96. InstancePtr->RegBaseAddress = RegBaseAddress;
  97. InstancePtr->DataBaseAddress = DataBaseAddress;
  98. InstancePtr->IsReady = XCOMPONENT_IS_READY;
  99. /* reset the FIFO such that it's empty and ready to use and indicate the
  100. * initialization was successful, note that the is ready variable must be
  101. * set prior to calling the reset function to prevent an assert
  102. */
  103. XPF_V100B_RESET(InstancePtr);
  104. return XST_SUCCESS;
  105. }
  106. /*****************************************************************************/
  107. /*
  108. *
  109. * This function performs a self-test on the specified packet FIFO. The self
  110. * test resets the FIFO and reads a register to determine if it is the correct
  111. * reset value. This test is destructive in that any data in the FIFO will
  112. * be lost.
  113. *
  114. * @param InstancePtr is a pointer to the packet FIFO to be operated on.
  115. *
  116. * @param FifoType specifies the type of FIFO, read or write, for the self test.
  117. * The FIFO type is specified by the values XPF_READ_FIFO_TYPE or
  118. * XPF_WRITE_FIFO_TYPE.
  119. *
  120. * @return
  121. *
  122. * XST_SUCCESS is returned if the selftest is successful, or
  123. * XST_PFIFO_BAD_REG_VALUE indicating that the value readback from the
  124. * occupancy/vacancy count register after a reset does not match the
  125. * specified reset value.
  126. *
  127. * @note
  128. *
  129. * None.
  130. *
  131. ******************************************************************************/
  132. XStatus
  133. XPacketFifoV100b_SelfTest(XPacketFifoV100b * InstancePtr, u32 FifoType)
  134. {
  135. u32 Register;
  136. /* assert to verify valid input arguments */
  137. XASSERT_NONVOID(InstancePtr != NULL);
  138. XASSERT_NONVOID((FifoType == XPF_READ_FIFO_TYPE) ||
  139. (FifoType == XPF_WRITE_FIFO_TYPE));
  140. XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
  141. /* reset the fifo and then check to make sure the occupancy/vacancy
  142. * register contents are correct for a reset condition
  143. */
  144. XPF_V100B_RESET(InstancePtr);
  145. Register = XIo_In32(InstancePtr->RegBaseAddress +
  146. XPF_COUNT_STATUS_REG_OFFSET);
  147. /* check the value of the register to ensure that it's correct for the
  148. * specified FIFO type since both FIFO types reset to empty, but a bit
  149. * in the register changes definition based upon FIFO type
  150. */
  151. if (FifoType == XPF_READ_FIFO_TYPE) {
  152. /* check the regiser value for a read FIFO which should be empty */
  153. if (Register != XPF_EMPTY_FULL_MASK) {
  154. return XST_PFIFO_BAD_REG_VALUE;
  155. }
  156. } else {
  157. /* check the register value for a write FIFO which should not be full
  158. * on reset
  159. */
  160. if ((Register & XPF_EMPTY_FULL_MASK) != 0) {
  161. return XST_PFIFO_BAD_REG_VALUE;
  162. }
  163. }
  164. /* the test was successful */
  165. return XST_SUCCESS;
  166. }
  167. /*****************************************************************************/
  168. /*
  169. *
  170. * Read data from a FIFO and puts it into a specified buffer. The packet FIFO is
  171. * currently 32 bits wide such that an input buffer which is a series of bytes
  172. * is filled from the FIFO a word at a time. If the requested byte count is not
  173. * a multiple of 32 bit words, it is necessary for this function to format the
  174. * remaining 32 bit word from the FIFO into a series of bytes in the buffer.
  175. * There may be up to 3 extra bytes which must be extracted from the last word
  176. * of the FIFO and put into the buffer.
  177. *
  178. * @param InstancePtr contains a pointer to the FIFO to operate on.
  179. * @param BufferPtr points to the memory buffer to write the data into. This
  180. * buffer must be 32 bit aligned or an alignment exception could be
  181. * generated. Since this buffer is a byte buffer, the data is assumed to
  182. * be endian independent.
  183. * @param ByteCount contains the number of bytes to read from the FIFO. This
  184. * number of bytes must be present in the FIFO or an error will be
  185. * returned.
  186. *
  187. * @return
  188. *
  189. * XST_SUCCESS indicates the operation was successful. If the number of
  190. * bytes specified by the byte count is not present in the FIFO
  191. * XST_PFIFO_LACK_OF_DATA is returned.
  192. *
  193. * If the function was successful, the specified buffer is modified to contain
  194. * the bytes which were removed from the FIFO.
  195. *
  196. * @note
  197. *
  198. * Note that the exact number of bytes which are present in the FIFO is
  199. * not known by this function. It can only check for a number of 32 bit
  200. * words such that if the byte count specified is incorrect, but is still
  201. * possible based on the number of words in the FIFO, up to 3 garbage bytes
  202. * may be present at the end of the buffer.
  203. * <br><br>
  204. * This function assumes that if the device consuming data from the FIFO is
  205. * a byte device, the order of the bytes to be consumed is from the most
  206. * significant byte to the least significant byte of a 32 bit word removed
  207. * from the FIFO.
  208. *
  209. ******************************************************************************/
  210. XStatus
  211. XPacketFifoV100b_Read(XPacketFifoV100b * InstancePtr,
  212. u8 * BufferPtr, u32 ByteCount)
  213. {
  214. u32 FifoCount;
  215. u32 WordCount;
  216. u32 ExtraByteCount;
  217. u32 *WordBuffer = (u32 *) BufferPtr;
  218. /* assert to verify valid input arguments including 32 bit alignment of
  219. * the buffer pointer
  220. */
  221. XASSERT_NONVOID(InstancePtr != NULL);
  222. XASSERT_NONVOID(BufferPtr != NULL);
  223. XASSERT_NONVOID(((u32) BufferPtr &
  224. (XPF_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
  225. XASSERT_NONVOID(ByteCount != 0);
  226. XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
  227. /* get the count of how many 32 bit words are in the FIFO, if there aren't
  228. * enought words to satisfy the request, return an error
  229. */
  230. FifoCount = XIo_In32(InstancePtr->RegBaseAddress +
  231. XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
  232. if ((FifoCount * XPF_FIFO_WIDTH_BYTE_COUNT) < ByteCount) {
  233. return XST_PFIFO_LACK_OF_DATA;
  234. }
  235. /* calculate the number of words to read from the FIFO before the word
  236. * containing the extra bytes, and calculate the number of extra bytes
  237. * the extra bytes are defined as those at the end of the buffer when
  238. * the buffer does not end on a 32 bit boundary
  239. */
  240. WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT;
  241. ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT;
  242. /* Read the 32 bit words from the FIFO for all the buffer except the
  243. * last word which contains the extra bytes, the following code assumes
  244. * that the buffer is 32 bit aligned, otherwise an alignment exception could
  245. * be generated
  246. */
  247. for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
  248. WordBuffer[FifoCount] = XIo_In32(InstancePtr->DataBaseAddress);
  249. }
  250. /* if there are extra bytes to handle, read the last word from the FIFO
  251. * and insert the extra bytes into the buffer
  252. */
  253. if (ExtraByteCount > 0) {
  254. u32 LastWord;
  255. u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
  256. /* get the last word from the FIFO for the extra bytes */
  257. LastWord = XIo_In32(InstancePtr->DataBaseAddress);
  258. /* one extra byte in the last word, put the byte into the next location
  259. * of the buffer, bytes in a word of the FIFO are ordered from most
  260. * significant byte to least
  261. */
  262. if (ExtraByteCount == 1) {
  263. ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
  264. }
  265. /* two extra bytes in the last word, put each byte into the next two
  266. * locations of the buffer
  267. */
  268. else if (ExtraByteCount == 2) {
  269. ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
  270. ExtraBytesBuffer[1] = (u8) (LastWord >> 16);
  271. }
  272. /* three extra bytes in the last word, put each byte into the next three
  273. * locations of the buffer
  274. */
  275. else if (ExtraByteCount == 3) {
  276. ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
  277. ExtraBytesBuffer[1] = (u8) (LastWord >> 16);
  278. ExtraBytesBuffer[2] = (u8) (LastWord >> 8);
  279. }
  280. }
  281. return XST_SUCCESS;
  282. }
  283. /*****************************************************************************/
  284. /*
  285. *
  286. * Write data into a packet FIFO. The packet FIFO is currently 32 bits wide
  287. * such that an input buffer which is a series of bytes must be written into the
  288. * FIFO a word at a time. If the buffer is not a multiple of 32 bit words, it is
  289. * necessary for this function to format the remaining bytes into a single 32
  290. * bit word to be inserted into the FIFO. This is necessary to avoid any
  291. * accesses past the end of the buffer.
  292. *
  293. * @param InstancePtr contains a pointer to the FIFO to operate on.
  294. * @param BufferPtr points to the memory buffer that data is to be read from
  295. * and written into the FIFO. Since this buffer is a byte buffer, the data
  296. * is assumed to be endian independent. This buffer must be 32 bit aligned
  297. * or an alignment exception could be generated.
  298. * @param ByteCount contains the number of bytes to read from the buffer and to
  299. * write to the FIFO.
  300. *
  301. * @return
  302. *
  303. * XST_SUCCESS is returned if the operation succeeded. If there is not enough
  304. * room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
  305. * returned.
  306. *
  307. * @note
  308. *
  309. * This function assumes that if the device inserting data into the FIFO is
  310. * a byte device, the order of the bytes in each 32 bit word is from the most
  311. * significant byte to the least significant byte.
  312. *
  313. ******************************************************************************/
  314. XStatus
  315. XPacketFifoV100b_Write(XPacketFifoV100b * InstancePtr,
  316. u8 * BufferPtr, u32 ByteCount)
  317. {
  318. u32 FifoCount;
  319. u32 WordCount;
  320. u32 ExtraByteCount;
  321. u32 *WordBuffer = (u32 *) BufferPtr;
  322. /* assert to verify valid input arguments including 32 bit alignment of
  323. * the buffer pointer
  324. */
  325. XASSERT_NONVOID(InstancePtr != NULL);
  326. XASSERT_NONVOID(BufferPtr != NULL);
  327. XASSERT_NONVOID(((u32) BufferPtr &
  328. (XPF_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
  329. XASSERT_NONVOID(ByteCount != 0);
  330. XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
  331. /* get the count of how many words may be inserted into the FIFO */
  332. FifoCount = XIo_In32(InstancePtr->RegBaseAddress +
  333. XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
  334. /* Calculate the number of 32 bit words required to insert the specified
  335. * number of bytes in the FIFO and determine the number of extra bytes
  336. * if the buffer length is not a multiple of 32 bit words
  337. */
  338. WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT;
  339. ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT;
  340. /* take into account the extra bytes in the total word count */
  341. if (ExtraByteCount > 0) {
  342. WordCount++;
  343. }
  344. /* if there's not enough room in the FIFO to hold the specified
  345. * number of bytes, then indicate an error,
  346. */
  347. if (FifoCount < WordCount) {
  348. return XST_PFIFO_NO_ROOM;
  349. }
  350. /* readjust the word count to not take into account the extra bytes */
  351. if (ExtraByteCount > 0) {
  352. WordCount--;
  353. }
  354. /* Write all the bytes of the buffer which can be written as 32 bit
  355. * words into the FIFO, waiting to handle the extra bytes seperately
  356. */
  357. for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
  358. XIo_Out32(InstancePtr->DataBaseAddress, WordBuffer[FifoCount]);
  359. }
  360. /* if there are extra bytes to handle, extract them from the buffer
  361. * and create a 32 bit word and write it to the FIFO
  362. */
  363. if (ExtraByteCount > 0) {
  364. u32 LastWord = 0;
  365. u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
  366. /* one extra byte in the buffer, put the byte into the last word
  367. * to be inserted into the FIFO, perform this processing inline rather
  368. * than in a loop to help performance
  369. */
  370. if (ExtraByteCount == 1) {
  371. LastWord = ExtraBytesBuffer[0] << 24;
  372. }
  373. /* two extra bytes in the buffer, put each byte into the last word
  374. * to be inserted into the FIFO
  375. */
  376. else if (ExtraByteCount == 2) {
  377. LastWord = ExtraBytesBuffer[0] << 24 |
  378. ExtraBytesBuffer[1] << 16;
  379. }
  380. /* three extra bytes in the buffer, put each byte into the last word
  381. * to be inserted into the FIFO
  382. */
  383. else if (ExtraByteCount == 3) {
  384. LastWord = ExtraBytesBuffer[0] << 24 |
  385. ExtraBytesBuffer[1] << 16 |
  386. ExtraBytesBuffer[2] << 8;
  387. }
  388. /* write the last 32 bit word to the FIFO and return with no errors */
  389. XIo_Out32(InstancePtr->DataBaseAddress, LastWord);
  390. }
  391. return XST_SUCCESS;
  392. }