xiic_l.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. /* $Id: xiic_l.c,v 1.2 2002/12/05 19:32:40 meinelte Exp $ */
  2. /******************************************************************************
  3. *
  4. * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
  5. * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
  6. * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
  7. * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
  8. * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
  9. * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
  10. * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
  11. * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
  12. * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
  13. * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
  14. * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
  15. * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16. * FOR A PARTICULAR PURPOSE.
  17. *
  18. * (c) Copyright 2002 Xilinx Inc.
  19. * All rights reserved.
  20. *
  21. ******************************************************************************/
  22. /*****************************************************************************/
  23. /**
  24. *
  25. * @file xiic_l.c
  26. *
  27. * This file contains low-level driver functions that can be used to access the
  28. * device. The user should refer to the hardware device specification for more
  29. * details of the device operation.
  30. *
  31. * <pre>
  32. * MODIFICATION HISTORY:
  33. *
  34. * Ver Who Date Changes
  35. * ----- --- ------- -----------------------------------------------
  36. * 1.01b jhl 5/13/02 First release
  37. * 1.01b jhl 10/14/02 Corrected bug in the receive function, the setup of the
  38. * interrupt status mask was not being done in the loop such
  39. * that a read would sometimes fail on the last byte because
  40. * the transmit error which should have been ignored was
  41. * being used. This would leave an extra byte in the FIFO
  42. * and the bus throttled such that the next operation would
  43. * also fail. Also updated the receive function to not
  44. * disable the device after the last byte until after the
  45. * bus transitions to not busy which is more consistent
  46. * with the expected behavior.
  47. * 1.01c ecm 12/05/02 new rev
  48. * </pre>
  49. *
  50. ****************************************************************************/
  51. /***************************** Include Files *******************************/
  52. #include "xbasic_types.h"
  53. #include "xio.h"
  54. #include "xipif_v1_23_b.h"
  55. #include "xiic_l.h"
  56. /************************** Constant Definitions ***************************/
  57. /**************************** Type Definitions *****************************/
  58. /***************** Macros (Inline Functions) Definitions *******************/
  59. /******************************************************************************
  60. *
  61. * This macro clears the specified interrupt in the IPIF interrupt status
  62. * register. It is non-destructive in that the register is read and only the
  63. * interrupt specified is cleared. Clearing an interrupt acknowledges it.
  64. *
  65. * @param BaseAddress contains the IPIF registers base address.
  66. *
  67. * @param InterruptMask contains the interrupts to be disabled
  68. *
  69. * @return
  70. *
  71. * None.
  72. *
  73. * @note
  74. *
  75. * Signature: void XIic_mClearIisr(u32 BaseAddress,
  76. * u32 InterruptMask);
  77. *
  78. ******************************************************************************/
  79. #define XIic_mClearIisr(BaseAddress, InterruptMask) \
  80. XIIF_V123B_WRITE_IISR((BaseAddress), \
  81. XIIF_V123B_READ_IISR(BaseAddress) & (InterruptMask))
  82. /******************************************************************************
  83. *
  84. * This macro sends the address for a 7 bit address during both read and write
  85. * operations. It takes care of the details to format the address correctly.
  86. * This macro is designed to be called internally to the drivers.
  87. *
  88. * @param SlaveAddress contains the address of the slave to send to.
  89. *
  90. * @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION
  91. *
  92. * @return
  93. *
  94. * None.
  95. *
  96. * @note
  97. *
  98. * Signature: void XIic_mSend7BitAddr(u16 SlaveAddress, u8 Operation);
  99. *
  100. ******************************************************************************/
  101. #define XIic_mSend7BitAddress(BaseAddress, SlaveAddress, Operation) \
  102. { \
  103. u8 LocalAddr = (u8)(SlaveAddress << 1); \
  104. LocalAddr = (LocalAddr & 0xFE) | (Operation); \
  105. XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET, LocalAddr); \
  106. }
  107. /************************** Function Prototypes ****************************/
  108. static unsigned RecvData (u32 BaseAddress, u8 * BufferPtr,
  109. unsigned ByteCount);
  110. static unsigned SendData (u32 BaseAddress, u8 * BufferPtr,
  111. unsigned ByteCount);
  112. /************************** Variable Definitions **************************/
  113. /****************************************************************************/
  114. /**
  115. * Receive data as a master on the IIC bus. This function receives the data
  116. * using polled I/O and blocks until the data has been received. It only
  117. * supports 7 bit addressing and non-repeated start modes of operation. The
  118. * user is responsible for ensuring the bus is not busy if multiple masters
  119. * are present on the bus.
  120. *
  121. * @param BaseAddress contains the base address of the IIC device.
  122. * @param Address contains the 7 bit IIC address of the device to send the
  123. * specified data to.
  124. * @param BufferPtr points to the data to be sent.
  125. * @param ByteCount is the number of bytes to be sent.
  126. *
  127. * @return
  128. *
  129. * The number of bytes received.
  130. *
  131. * @note
  132. *
  133. * None
  134. *
  135. ******************************************************************************/
  136. unsigned XIic_Recv (u32 BaseAddress, u8 Address,
  137. u8 * BufferPtr, unsigned ByteCount)
  138. {
  139. u8 CntlReg;
  140. unsigned RemainingByteCount;
  141. /* Tx error is enabled incase the address (7 or 10) has no device to answer
  142. * with Ack. When only one byte of data, must set NO ACK before address goes
  143. * out therefore Tx error must not be enabled as it will go off immediately
  144. * and the Rx full interrupt will be checked. If full, then the one byte
  145. * was received and the Tx error will be disabled without sending an error
  146. * callback msg.
  147. */
  148. XIic_mClearIisr (BaseAddress,
  149. XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK |
  150. XIIC_INTR_ARB_LOST_MASK);
  151. /* Set receive FIFO occupancy depth for 1 byte (zero based)
  152. */
  153. XIo_Out8 (BaseAddress + XIIC_RFD_REG_OFFSET, 0);
  154. /* 7 bit slave address, send the address for a read operation
  155. * and set the state to indicate the address has been sent
  156. */
  157. XIic_mSend7BitAddress (BaseAddress, Address, XIIC_READ_OPERATION);
  158. /* MSMS gets set after putting data in FIFO. Start the master receive
  159. * operation by setting CR Bits MSMS to Master, if the buffer is only one
  160. * byte, then it should not be acknowledged to indicate the end of data
  161. */
  162. CntlReg = XIIC_CR_MSMS_MASK | XIIC_CR_ENABLE_DEVICE_MASK;
  163. if (ByteCount == 1) {
  164. CntlReg |= XIIC_CR_NO_ACK_MASK;
  165. }
  166. /* Write out the control register to start receiving data and call the
  167. * function to receive each byte into the buffer
  168. */
  169. XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, CntlReg);
  170. /* Clear the latched interrupt status for the bus not busy bit which must
  171. * be done while the bus is busy
  172. */
  173. XIic_mClearIisr (BaseAddress, XIIC_INTR_BNB_MASK);
  174. /* Try to receive the data from the IIC bus */
  175. RemainingByteCount = RecvData (BaseAddress, BufferPtr, ByteCount);
  176. /*
  177. * The receive is complete, disable the IIC device and return the number of
  178. * bytes that was received
  179. */
  180. XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, 0);
  181. /* Return the number of bytes that was received */
  182. return ByteCount - RemainingByteCount;
  183. }
  184. /******************************************************************************
  185. *
  186. * Receive the specified data from the device that has been previously addressed
  187. * on the IIC bus. This function assumes that the 7 bit address has been sent
  188. * and it should wait for the transmit of the address to complete.
  189. *
  190. * @param BaseAddress contains the base address of the IIC device.
  191. * @param BufferPtr points to the buffer to hold the data that is received.
  192. * @param ByteCount is the number of bytes to be received.
  193. *
  194. * @return
  195. *
  196. * The number of bytes remaining to be received.
  197. *
  198. * @note
  199. *
  200. * This function does not take advantage of the receive FIFO because it is
  201. * designed for minimal code space and complexity. It contains loops that
  202. * that could cause the function not to return if the hardware is not working.
  203. *
  204. * This function assumes that the calling function will disable the IIC device
  205. * after this function returns.
  206. *
  207. ******************************************************************************/
  208. static unsigned RecvData (u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount)
  209. {
  210. u8 CntlReg;
  211. u32 IntrStatusMask;
  212. u32 IntrStatus;
  213. /* Attempt to receive the specified number of bytes on the IIC bus */
  214. while (ByteCount > 0) {
  215. /* Setup the mask to use for checking errors because when receiving one
  216. * byte OR the last byte of a multibyte message an error naturally
  217. * occurs when the no ack is done to tell the slave the last byte
  218. */
  219. if (ByteCount == 1) {
  220. IntrStatusMask =
  221. XIIC_INTR_ARB_LOST_MASK | XIIC_INTR_BNB_MASK;
  222. } else {
  223. IntrStatusMask =
  224. XIIC_INTR_ARB_LOST_MASK |
  225. XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_BNB_MASK;
  226. }
  227. /* Wait for the previous transmit and the 1st receive to complete
  228. * by checking the interrupt status register of the IPIF
  229. */
  230. while (1) {
  231. IntrStatus = XIIF_V123B_READ_IISR (BaseAddress);
  232. if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
  233. break;
  234. }
  235. /* Check the transmit error after the receive full because when
  236. * sending only one byte transmit error will occur because of the
  237. * no ack to indicate the end of the data
  238. */
  239. if (IntrStatus & IntrStatusMask) {
  240. return ByteCount;
  241. }
  242. }
  243. CntlReg = XIo_In8 (BaseAddress + XIIC_CR_REG_OFFSET);
  244. /* Special conditions exist for the last two bytes so check for them
  245. * Note that the control register must be setup for these conditions
  246. * before the data byte which was already received is read from the
  247. * receive FIFO (while the bus is throttled
  248. */
  249. if (ByteCount == 1) {
  250. /* For the last data byte, it has already been read and no ack
  251. * has been done, so clear MSMS while leaving the device enabled
  252. * so it can get off the IIC bus appropriately with a stop.
  253. */
  254. XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
  255. XIIC_CR_ENABLE_DEVICE_MASK);
  256. }
  257. /* Before the last byte is received, set NOACK to tell the slave IIC
  258. * device that it is the end, this must be done before reading the byte
  259. * from the FIFO
  260. */
  261. if (ByteCount == 2) {
  262. /* Write control reg with NO ACK allowing last byte to
  263. * have the No ack set to indicate to slave last byte read.
  264. */
  265. XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
  266. CntlReg | XIIC_CR_NO_ACK_MASK);
  267. }
  268. /* Read in data from the FIFO and unthrottle the bus such that the
  269. * next byte is read from the IIC bus
  270. */
  271. *BufferPtr++ = XIo_In8 (BaseAddress + XIIC_DRR_REG_OFFSET);
  272. /* Clear the latched interrupt status so that it will be updated with
  273. * the new state when it changes, this must be done after the receive
  274. * register is read
  275. */
  276. XIic_mClearIisr (BaseAddress, XIIC_INTR_RX_FULL_MASK |
  277. XIIC_INTR_TX_ERROR_MASK |
  278. XIIC_INTR_ARB_LOST_MASK);
  279. ByteCount--;
  280. }
  281. /* Wait for the bus to transition to not busy before returning, the IIC
  282. * device cannot be disabled until this occurs. It should transition as
  283. * the MSMS bit of the control register was cleared before the last byte
  284. * was read from the FIFO.
  285. */
  286. while (1) {
  287. if (XIIF_V123B_READ_IISR (BaseAddress) & XIIC_INTR_BNB_MASK) {
  288. break;
  289. }
  290. }
  291. return ByteCount;
  292. }
  293. /****************************************************************************/
  294. /**
  295. * Send data as a master on the IIC bus. This function sends the data
  296. * using polled I/O and blocks until the data has been sent. It only supports
  297. * 7 bit addressing and non-repeated start modes of operation. The user is
  298. * responsible for ensuring the bus is not busy if multiple masters are present
  299. * on the bus.
  300. *
  301. * @param BaseAddress contains the base address of the IIC device.
  302. * @param Address contains the 7 bit IIC address of the device to send the
  303. * specified data to.
  304. * @param BufferPtr points to the data to be sent.
  305. * @param ByteCount is the number of bytes to be sent.
  306. *
  307. * @return
  308. *
  309. * The number of bytes sent.
  310. *
  311. * @note
  312. *
  313. * None
  314. *
  315. ******************************************************************************/
  316. unsigned XIic_Send (u32 BaseAddress, u8 Address,
  317. u8 * BufferPtr, unsigned ByteCount)
  318. {
  319. unsigned RemainingByteCount;
  320. /* Put the address into the FIFO to be sent and indicate that the operation
  321. * to be performed on the bus is a write operation
  322. */
  323. XIic_mSend7BitAddress (BaseAddress, Address, XIIC_WRITE_OPERATION);
  324. /* Clear the latched interrupt status so that it will be updated with the
  325. * new state when it changes, this must be done after the address is put
  326. * in the FIFO
  327. */
  328. XIic_mClearIisr (BaseAddress, XIIC_INTR_TX_EMPTY_MASK |
  329. XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_ARB_LOST_MASK);
  330. /* MSMS must be set after putting data into transmit FIFO, indicate the
  331. * direction is transmit, this device is master and enable the IIC device
  332. */
  333. XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
  334. XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK |
  335. XIIC_CR_ENABLE_DEVICE_MASK);
  336. /* Clear the latched interrupt
  337. * status for the bus not busy bit which must be done while the bus is busy
  338. */
  339. XIic_mClearIisr (BaseAddress, XIIC_INTR_BNB_MASK);
  340. /* Send the specified data to the device on the IIC bus specified by the
  341. * the address
  342. */
  343. RemainingByteCount = SendData (BaseAddress, BufferPtr, ByteCount);
  344. /*
  345. * The send is complete, disable the IIC device and return the number of
  346. * bytes that was sent
  347. */
  348. XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET, 0);
  349. return ByteCount - RemainingByteCount;
  350. }
  351. /******************************************************************************
  352. *
  353. * Send the specified buffer to the device that has been previously addressed
  354. * on the IIC bus. This function assumes that the 7 bit address has been sent
  355. * and it should wait for the transmit of the address to complete.
  356. *
  357. * @param BaseAddress contains the base address of the IIC device.
  358. * @param BufferPtr points to the data to be sent.
  359. * @param ByteCount is the number of bytes to be sent.
  360. *
  361. * @return
  362. *
  363. * The number of bytes remaining to be sent.
  364. *
  365. * @note
  366. *
  367. * This function does not take advantage of the transmit FIFO because it is
  368. * designed for minimal code space and complexity. It contains loops that
  369. * that could cause the function not to return if the hardware is not working.
  370. *
  371. ******************************************************************************/
  372. static unsigned SendData (u32 BaseAddress, u8 * BufferPtr, unsigned ByteCount)
  373. {
  374. u32 IntrStatus;
  375. /* Send the specified number of bytes in the specified buffer by polling
  376. * the device registers and blocking until complete
  377. */
  378. while (ByteCount > 0) {
  379. /* Wait for the transmit to be empty before sending any more data
  380. * by polling the interrupt status register
  381. */
  382. while (1) {
  383. IntrStatus = XIIF_V123B_READ_IISR (BaseAddress);
  384. if (IntrStatus & (XIIC_INTR_TX_ERROR_MASK |
  385. XIIC_INTR_ARB_LOST_MASK |
  386. XIIC_INTR_BNB_MASK)) {
  387. return ByteCount;
  388. }
  389. if (IntrStatus & XIIC_INTR_TX_EMPTY_MASK) {
  390. break;
  391. }
  392. }
  393. /* If there is more than one byte to send then put the next byte to send
  394. * into the transmit FIFO
  395. */
  396. if (ByteCount > 1) {
  397. XIo_Out8 (BaseAddress + XIIC_DTR_REG_OFFSET,
  398. *BufferPtr++);
  399. } else {
  400. /* Set the stop condition before sending the last byte of data so that
  401. * the stop condition will be generated immediately following the data
  402. * This is done by clearing the MSMS bit in the control register.
  403. */
  404. XIo_Out8 (BaseAddress + XIIC_CR_REG_OFFSET,
  405. XIIC_CR_ENABLE_DEVICE_MASK |
  406. XIIC_CR_DIR_IS_TX_MASK);
  407. /* Put the last byte to send in the transmit FIFO */
  408. XIo_Out8 (BaseAddress + XIIC_DTR_REG_OFFSET,
  409. *BufferPtr++);
  410. }
  411. /* Clear the latched interrupt status register and this must be done after
  412. * the transmit FIFO has been written to or it won't clear
  413. */
  414. XIic_mClearIisr (BaseAddress, XIIC_INTR_TX_EMPTY_MASK);
  415. /* Update the byte count to reflect the byte sent and clear the latched
  416. * interrupt status so it will be updated for the new state
  417. */
  418. ByteCount--;
  419. }
  420. /* Wait for the bus to transition to not busy before returning, the IIC
  421. * device cannot be disabled until this occurs.
  422. * Note that this is different from a receive operation because the stop
  423. * condition causes the bus to go not busy.
  424. */
  425. while (1) {
  426. if (XIIF_V123B_READ_IISR (BaseAddress) & XIIC_INTR_BNB_MASK) {
  427. break;
  428. }
  429. }
  430. return ByteCount;
  431. }