libpynq  (release 5EID0-2023 version 0.3.0 of 2024-04-25 09:42 )
xiic_l.c
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  ******************************************************************************/
5 
6 /*****************************************************************************/
70 /***************************** Include Files *******************************/
71 #define _DEFAULT_SOURCE
72 #include <stdio.h>
73 #include <time.h>
74 #include <unistd.h>
75 
76 #define IIC_TIMEOUT 5
77 
78 #include "xiic_l.h"
79 #include "xil_types.h"
80 
81 /************************** Constant Definitions ***************************/
82 
83 /**************************** Type Definitions *****************************/
84 
85 /***************** Macros (Inline Functions) Definitions *******************/
86 
87 /************************** Function Prototypes ****************************/
88 
89 static unsigned RecvData(UINTPTR BaseAddress, u8 *BufferPtr, unsigned ByteCount,
90  u8 Option);
91 static unsigned SendData(UINTPTR BaseAddress, u8 *BufferPtr, unsigned ByteCount,
92  u8 Option);
93 
94 /************************** Variable Definitions **************************/
95 
96 /****************************************************************************/
117 unsigned XIic_Recv(UINTPTR BaseAddress, u8 Address, u8 *BufferPtr,
118  unsigned ByteCount, u8 Option) {
119  u32 CntlReg;
120  unsigned RemainingByteCount;
121  volatile u32 StatusReg;
122 
123  /* Tx error is enabled in case the address (7 or 10) has no device to
124  * answer with Ack. When only one byte of data, must set NO ACK before
125  * address goes out therefore Tx error must not be enabled as it will go
126  * off immediately and the Rx full interrupt will be checked. If full,
127  * then the one byte was received and the Tx error will be disabled
128  * without sending an error callback msg
129  */
132 
133  /* Set receive FIFO occupancy depth for 1 byte (zero based) */
134  XIic_WriteReg(BaseAddress, XIIC_RFD_REG_OFFSET, 0);
135 
136  /* Check to see if already Master on the Bus.
137  * If Repeated Start bit is not set send Start bit by setting MSMS bit
138  * else Send the address
139  */
140  CntlReg = XIic_ReadReg(BaseAddress, XIIC_CR_REG_OFFSET);
141  if ((CntlReg & XIIC_CR_REPEATED_START_MASK) == 0) {
142  /* 7 bit slave address, send the address for a read operation
143  * and set the state to indicate the address has been sent
144  */
145  XIic_Send7BitAddress(BaseAddress, Address, XIIC_READ_OPERATION);
146 
147  /* MSMS gets set after putting data in FIFO. Start the master
148  * receive operation by setting CR Bits MSMS to Master, if the
149  * buffer is only one byte, then it should not be acknowledged
150  * to indicate the end of data
151  */
153  if (ByteCount == 1) {
154  CntlReg |= XIIC_CR_NO_ACK_MASK;
155  }
156 
157  /* Write out the control register to start receiving data and
158  * call the function to receive each byte into the buffer
159  */
160  XIic_WriteReg(BaseAddress, XIIC_CR_REG_OFFSET, CntlReg);
161 
162  /* Clear the latched interrupt status for the bus not busy bit
163  * which must be done while the bus is busy
164  */
165  StatusReg = XIic_ReadReg(BaseAddress, XIIC_SR_REG_OFFSET);
166 
167  while ((StatusReg & XIIC_SR_BUS_BUSY_MASK) == 0) {
168  StatusReg = XIic_ReadReg(BaseAddress, XIIC_SR_REG_OFFSET);
169  }
170 
171  XIic_ClearIisr(BaseAddress, XIIC_INTR_BNB_MASK);
172  } else {
173  /* Before writing 7bit slave address the Direction of Tx bit
174  * must be disabled
175  */
176  CntlReg &= ~XIIC_CR_DIR_IS_TX_MASK;
177  if (ByteCount == 1) {
178  CntlReg |= XIIC_CR_NO_ACK_MASK;
179  }
180  XIic_WriteReg(BaseAddress, XIIC_CR_REG_OFFSET, CntlReg);
181  /* Already owns the Bus indicating that its a Repeated Start
182  * call. 7 bit slave address, send the address for a read
183  * operation and set the state to indicate the address has been
184  * sent
185  */
186  XIic_Send7BitAddress(BaseAddress, Address, XIIC_READ_OPERATION);
187  }
188  /* Try to receive the data from the IIC bus */
189 
190  RemainingByteCount = RecvData(BaseAddress, BufferPtr, ByteCount, Option);
191 
192  CntlReg = XIic_ReadReg(BaseAddress, XIIC_CR_REG_OFFSET);
193  if ((CntlReg & XIIC_CR_REPEATED_START_MASK) == 0) {
194  /* The receive is complete, disable the IIC device if the Option
195  * is to release the Bus after Reception of data and return the
196  * number of bytes that was received
197  */
198  XIic_WriteReg(BaseAddress, XIIC_CR_REG_OFFSET, 0);
199  }
200 
201  /* Wait until I2C bus is freed, exit if timed out. */
202  if (XIic_WaitBusFree(BaseAddress) != XST_SUCCESS) {
203  return 0;
204  }
205 
206  /* Return the number of bytes that was received */
207  return ByteCount - RemainingByteCount;
208 }
209 
210 /******************************************************************************
211  *
212  * Receive the specified data from the device that has been previously addressed
213  * on the IIC bus. This function assumes that the 7 bit address has been sent
214  * and it should wait for the transmit of the address to complete.
215  *
216  * @param BaseAddress contains the base address of the IIC device.
217  * @param BufferPtr points to the buffer to hold the data that is
218  * received.
219  * @param ByteCount is the number of bytes to be received.
220  * @param Option indicates whether to hold or free the bus after reception
221  * of data, XIIC_STOP = end with STOP condition,
222  * XIIC_REPEATED_START = don't end with STOP condition.
223  *
224  * @return The number of bytes remaining to be received.
225  *
226  * @note
227  *
228  * This function does not take advantage of the receive FIFO because it is
229  * designed for minimal code space and complexity. It contains loops that
230  * that could cause the function not to return if the hardware is not working.
231  *
232  * This function assumes that the calling function will disable the IIC device
233  * after this function returns.
234  *
235  ******************************************************************************/
236 static unsigned RecvData(UINTPTR BaseAddress, u8 *BufferPtr, unsigned ByteCount,
237  u8 Option) {
238  u32 CntlReg;
239  u32 IntrStatusMask;
240  u32 IntrStatus;
241 
242  /* Attempt to receive the specified number of bytes on the IIC bus */
243 
244  while (ByteCount > 0) {
245  /* Setup the mask to use for checking errors because when
246  * receiving one byte OR the last byte of a multibyte message an
247  * error naturally occurs when the no ack is done to tell the
248  * slave the last byte
249  */
250  if (ByteCount == 1) {
251  IntrStatusMask = XIIC_INTR_ARB_LOST_MASK | XIIC_INTR_BNB_MASK;
252  } else {
255  }
256 
257  /* Wait for the previous transmit and the 1st receive to
258  * complete by checking the interrupt status register of the
259  * IPIF
260  */
261  while (1) {
262  IntrStatus = XIic_ReadIisr(BaseAddress);
263  if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
264  break;
265  }
266  /* Check the transmit error after the receive full
267  * because when sending only one byte transmit error
268  * will occur because of the no ack to indicate the end
269  * of the data
270  */
271  if (IntrStatus & IntrStatusMask) {
272  return ByteCount;
273  }
274  }
275 
276  CntlReg = XIic_ReadReg(BaseAddress, XIIC_CR_REG_OFFSET);
277 
278  /* Special conditions exist for the last two bytes so check for
279  * them. Note that the control register must be setup for these
280  * conditions before the data byte which was already received is
281  * read from the receive FIFO (while the bus is throttled
282  */
283  if (ByteCount == 1) {
284  if (Option == XIIC_STOP) {
285 
286  /* If the Option is to release the bus after the
287  * last data byte, it has already been read and
288  * no ack has been done, so clear MSMS while
289  * leaving the device enabled so it can get off
290  * the IIC bus appropriately with a stop
291  */
292  XIic_WriteReg(BaseAddress, XIIC_CR_REG_OFFSET,
294  }
295  }
296 
297  /* Before the last byte is received, set NOACK to tell the slave
298  * IIC device that it is the end, this must be done before
299  * reading the byte from the FIFO
300  */
301  if (ByteCount == 2) {
302  /* Write control reg with NO ACK allowing last byte to
303  * have the No ack set to indicate to slave last byte
304  * read
305  */
306  XIic_WriteReg(BaseAddress, XIIC_CR_REG_OFFSET,
307  CntlReg | XIIC_CR_NO_ACK_MASK);
308  }
309 
310  /* Read in data from the FIFO and unthrottle the bus such that
311  * the next byte is read from the IIC bus
312  */
313  *BufferPtr++ = (u8)XIic_ReadReg(BaseAddress, XIIC_DRR_REG_OFFSET);
314 
315  if ((ByteCount == 1) && (Option == XIIC_REPEATED_START)) {
316 
317  /* RSTA bit should be set only when the FIFO is
318  * completely Empty.
319  */
320  XIic_WriteReg(BaseAddress, XIIC_CR_REG_OFFSET,
323  }
324 
325  /* Clear the latched interrupt status so that it will be updated
326  * with the new state when it changes, this must be done after
327  * the receive register is read
328  */
332  ByteCount--;
333  }
334 
335  if (Option == XIIC_STOP) {
336 
337  /* If the Option is to release the bus after Reception of data,
338  * wait for the bus to transition to not busy before returning,
339  * the IIC device cannot be disabled until this occurs. It
340  * should transition as the MSMS bit of the control register was
341  * cleared before the last byte was read from the FIFO
342  */
343  while (1) {
344  if (XIic_ReadIisr(BaseAddress) & XIIC_INTR_BNB_MASK) {
345  break;
346  }
347  }
348  }
349 
350  return ByteCount;
351 }
352 
353 /****************************************************************************/
373 unsigned XIic_Send(UINTPTR BaseAddress, u8 Address, u8 *BufferPtr,
374  unsigned ByteCount, u8 Option) {
375  unsigned RemainingByteCount;
376  u32 ControlReg;
377  volatile u32 StatusReg;
378 
379  /* Wait until I2C bus is freed, exit if timed out. */
380  if (XIic_WaitBusFree(BaseAddress) != XST_SUCCESS) {
381  return 0;
382  }
383 
384  /* Check to see if already Master on the Bus.
385  * If Repeated Start bit is not set send Start bit by setting
386  * MSMS bit else Send the address.
387  */
388  ControlReg = XIic_ReadReg(BaseAddress, XIIC_CR_REG_OFFSET);
389  if ((ControlReg & XIIC_CR_REPEATED_START_MASK) == 0) {
390  /*
391  * Put the address into the FIFO to be sent and indicate
392  * that the operation to be performed on the bus is a
393  * write operation
394  */
395  XIic_Send7BitAddress(BaseAddress, Address, XIIC_WRITE_OPERATION);
396  /* Clear the latched interrupt status so that it will
397  * be updated with the new state when it changes, this
398  * must be done after the address is put in the FIFO
399  */
403 
404  /*
405  * MSMS must be set after putting data into transmit FIFO,
406  * indicate the direction is transmit, this device is master
407  * and enable the IIC device
408  */
409  XIic_WriteReg(BaseAddress, XIIC_CR_REG_OFFSET,
412 
413  /*
414  * Clear the latched interrupt
415  * status for the bus not busy bit which must be done while
416  * the bus is busy
417  */
418  time_t s = time(NULL);
419  StatusReg = XIic_ReadReg(BaseAddress, XIIC_SR_REG_OFFSET);
420  while ((StatusReg & XIIC_SR_BUS_BUSY_MASK) == 0) {
421  StatusReg = XIic_ReadReg(BaseAddress, XIIC_SR_REG_OFFSET);
422  time_t n = time(NULL);
423  if ((n - s) > IIC_TIMEOUT) {
424  printf("IIC timeout bus not busy.\n");
425  return 0;
426  }
427  }
428 
429  XIic_ClearIisr(BaseAddress, XIIC_INTR_BNB_MASK);
430  } else {
431  /*
432  * Already owns the Bus indicating that its a Repeated Start
433  * call. 7 bit slave address, send the address for a write
434  * operation and set the state to indicate the address has
435  * been sent.
436  */
437  XIic_Send7BitAddress(BaseAddress, Address, XIIC_WRITE_OPERATION);
438  }
439 
440  /* Send the specified data to the device on the IIC bus specified by the
441  * the address
442  */
443  RemainingByteCount = SendData(BaseAddress, BufferPtr, ByteCount, Option);
444 
445  ControlReg = XIic_ReadReg(BaseAddress, XIIC_CR_REG_OFFSET);
446  if ((ControlReg & XIIC_CR_REPEATED_START_MASK) == 0) {
447  /*
448  * The Transmission is completed, disable the IIC device if
449  * the Option is to release the Bus after transmission of data
450  * and return the number of bytes that was received. Only wait
451  * if master, if addressed as slave just reset to release
452  * the bus.
453  */
454  if ((ControlReg & XIIC_CR_MSMS_MASK) != 0) {
455  XIic_WriteReg(BaseAddress, XIIC_CR_REG_OFFSET,
456  (ControlReg & ~XIIC_CR_MSMS_MASK));
457  }
458 
459  if ((XIic_ReadReg(BaseAddress, XIIC_SR_REG_OFFSET) &
461  XIic_WriteReg(BaseAddress, XIIC_CR_REG_OFFSET, 0);
462  } else {
463  StatusReg = XIic_ReadReg(BaseAddress, XIIC_SR_REG_OFFSET);
464  while ((StatusReg & XIIC_SR_BUS_BUSY_MASK) != 0) {
465  StatusReg = XIic_ReadReg(BaseAddress, XIIC_SR_REG_OFFSET);
466  }
467  }
468  }
469 
470  return ByteCount - RemainingByteCount;
471 }
472 
473 /******************************************************************************
474  *
475  * Send the specified buffer to the device that has been previously addressed
476  * on the IIC bus. This function assumes that the 7 bit address has been sent
477  * and it should wait for the transmit of the address to complete.
478  *
479  * @param BaseAddress contains the base address of the IIC device.
480  * @param BufferPtr points to the data to be sent.
481  * @param ByteCount is the number of bytes to be sent.
482  * @param Option indicates whether to hold or free the bus after
483  * transmitting the data.
484  *
485  * @return The number of bytes remaining to be sent.
486  *
487  * @note
488  *
489  * This function does not take advantage of the transmit FIFO because it is
490  * designed for minimal code space and complexity. It contains loops that
491  * that could cause the function not to return if the hardware is not working.
492  *
493  ******************************************************************************/
494 static unsigned SendData(UINTPTR BaseAddress, u8 *BufferPtr, unsigned ByteCount,
495  u8 Option) {
496  u32 IntrStatus;
497 
498  /*
499  * Send the specified number of bytes in the specified buffer by polling
500  * the device registers and blocking until complete
501  */
502  while (ByteCount > 0) {
503  /*
504  * Wait for the transmit to be empty before sending any more
505  * data by polling the interrupt status register
506  */
507  while (1) {
508  IntrStatus = XIic_ReadIisr(BaseAddress);
509 
512  return ByteCount;
513  }
514 
515  if (IntrStatus & XIIC_INTR_TX_EMPTY_MASK) {
516  break;
517  }
518  }
519  /* If there is more than one byte to send then put the
520  * next byte to send into the transmit FIFO
521  */
522  if (ByteCount > 1) {
523  XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, *BufferPtr++);
524  } else {
525  if (Option == XIIC_STOP) {
526  /*
527  * If the Option is to release the bus after
528  * the last data byte, Set the stop Option
529  * before sending the last byte of data so
530  * that the stop Option will be generated
531  * immediately following the data. This is
532  * done by clearing the MSMS bit in the
533  * control register.
534  */
535  XIic_WriteReg(BaseAddress, XIIC_CR_REG_OFFSET,
537  }
538 
539  /*
540  * Put the last byte to send in the transmit FIFO
541  */
542  XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, *BufferPtr++);
543 
544  if (Option == XIIC_REPEATED_START) {
546  /*
547  * Wait for the transmit to be empty before
548  * setting RSTA bit.
549  */
550  while (1) {
551  IntrStatus = XIic_ReadIisr(BaseAddress);
552  if (IntrStatus & XIIC_INTR_TX_EMPTY_MASK) {
553  /*
554  * RSTA bit should be set only
555  * when the FIFO is completely
556  * Empty.
557  */
558  XIic_WriteReg(BaseAddress, XIIC_CR_REG_OFFSET,
562  break;
563  }
564  }
565  }
566  }
567 
568  /*
569  * Clear the latched interrupt status register and this must be
570  * done after the transmit FIFO has been written to or it won't
571  * clear
572  */
574 
575  /*
576  * Update the byte count to reflect the byte sent and clear
577  * the latched interrupt status so it will be updated for the
578  * new state
579  */
580  ByteCount--;
581  }
582 
583  if (Option == XIIC_STOP) {
584  /*
585  * If the Option is to release the bus after transmission of
586  * data, Wait for the bus to transition to not busy before
587  * returning, the IIC device cannot be disabled until this
588  * occurs. Note that this is different from a receive operation
589  * because the stop Option causes the bus to go not busy.
590  */
591  while (1) {
592  if (XIic_ReadIisr(BaseAddress) & XIIC_INTR_BNB_MASK) {
593  break;
594  }
595  }
596  }
597 
598  return ByteCount;
599 }
600 
601 /*****************************************************************************
602  *
603  * This is a function which tells whether the I2C bus is busy or free.
604  *
605  * @param BaseAddr is the base address of the I2C core to work on.
606  *
607  * @return
608  * - TRUE if the bus is busy.
609  * - FALSE if the bus is NOT busy.
610  *
611  * @note None.
612  *
613  ******************************************************************************/
614 u32 XIic_CheckIsBusBusy(UINTPTR BaseAddress) {
615  u32 StatusReg;
616 
617  StatusReg = XIic_ReadReg(BaseAddress, XIIC_SR_REG_OFFSET);
618  if (StatusReg & XIIC_SR_BUS_BUSY_MASK) {
619  return TRUE;
620  } else {
621  return FALSE;
622  }
623 }
624 
625 /******************************************************************************/
638 u32 XIic_WaitBusFree(UINTPTR BaseAddress) {
639  u32 BusyCount = 0;
640 
641  while (XIic_CheckIsBusBusy(BaseAddress)) {
642  if (BusyCount++ > 10000) {
643  return XST_FAILURE;
644  }
645  usleep(100);
646  }
647 
648  return XST_SUCCESS;
649 }
xil_types.h
XIIC_DTR_REG_OFFSET
#define XIIC_DTR_REG_OFFSET
Definition: xiic_l.h:84
XIIC_RFD_REG_OFFSET
#define XIIC_RFD_REG_OFFSET
Definition: xiic_l.h:90
XIIC_CR_DIR_IS_TX_MASK
#define XIIC_CR_DIR_IS_TX_MASK
Definition: xiic_l.h:152
xiic_l.h
XIic_ClearIisr
#define XIic_ClearIisr(BaseAddress, InterruptMask)
Definition: xiic_l.h:432
XIIC_INTR_ARB_LOST_MASK
#define XIIC_INTR_ARB_LOST_MASK
Definition: xiic_l.h:116
XIIC_DRR_REG_OFFSET
#define XIIC_DRR_REG_OFFSET
Definition: xiic_l.h:85
IIC_TIMEOUT
#define IIC_TIMEOUT
Definition: xiic_l.c:76
XIIC_WRITE_OPERATION
#define XIIC_WRITE_OPERATION
Definition: xiic_l.h:202
XIIC_STOP
#define XIIC_STOP
Definition: xiic_l.h:216
XIic_Recv
unsigned XIic_Recv(UINTPTR BaseAddress, u8 Address, u8 *BufferPtr, unsigned ByteCount, u8 Option)
Definition: xiic_l.c:2
XIic_ReadReg
#define XIic_ReadReg(BaseAddress, RegOffset)
Definition: xiic_l.h:247
XIIC_SR_BUS_BUSY_MASK
#define XIIC_SR_BUS_BUSY_MASK
Definition: xiic_l.h:168
XIIC_SR_REG_OFFSET
#define XIIC_SR_REG_OFFSET
Definition: xiic_l.h:83
XIIC_INTR_TX_ERROR_MASK
#define XIIC_INTR_TX_ERROR_MASK
Definition: xiic_l.h:117
XIic_Send
unsigned XIic_Send(UINTPTR BaseAddress, u8 Address, u8 *BufferPtr, unsigned ByteCount, u8 Option)
Definition: xiic_l.c:4
XIIC_INTR_RX_FULL_MASK
#define XIIC_INTR_RX_FULL_MASK
Definition: xiic_l.h:119
XIIC_READ_OPERATION
#define XIIC_READ_OPERATION
Definition: xiic_l.h:201
XIIC_CR_REG_OFFSET
#define XIIC_CR_REG_OFFSET
Definition: xiic_l.h:82
XIic_Send7BitAddress
#define XIic_Send7BitAddress(BaseAddress, SlaveAddress, Operation)
Definition: xiic_l.h:453
XIIC_INTR_BNB_MASK
#define XIIC_INTR_BNB_MASK
Definition: xiic_l.h:120
XIic_ReadIisr
#define XIic_ReadIisr(BaseAddress)
Definition: xiic_l.h:371
XIIC_CR_NO_ACK_MASK
#define XIIC_CR_NO_ACK_MASK
Definition: xiic_l.h:153
XIIC_CR_REPEATED_START_MASK
#define XIIC_CR_REPEATED_START_MASK
Definition: xiic_l.h:154
XIIC_CR_ENABLE_DEVICE_MASK
#define XIIC_CR_ENABLE_DEVICE_MASK
Definition: xiic_l.h:149
XIIC_CR_MSMS_MASK
#define XIIC_CR_MSMS_MASK
Definition: xiic_l.h:151
XIic_WriteReg
#define XIic_WriteReg(BaseAddress, RegOffset, RegisterValue)
Definition: xiic_l.h:270
XIIC_REPEATED_START
#define XIIC_REPEATED_START
Definition: xiic_l.h:219
XIic_CheckIsBusBusy
u32 XIic_CheckIsBusBusy(UINTPTR BaseAddress)
Definition: xiic_l.c:11
XIic_WaitBusFree
u32 XIic_WaitBusFree(UINTPTR BaseAddress)
Definition: xiic_l.c:12
XIIC_SR_ADDR_AS_SLAVE_MASK
#define XIIC_SR_ADDR_AS_SLAVE_MASK
Definition: xiic_l.h:165
XIIC_INTR_TX_EMPTY_MASK
#define XIIC_INTR_TX_EMPTY_MASK
Definition: xiic_l.h:118