libpynq (release 5EWC0-2023 version 0.2.6 of 2023-10-24 17:28)
Loading...
Searching...
No Matches
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
89static unsigned RecvData(UINTPTR BaseAddress, u8 *BufferPtr, unsigned ByteCount,
90 u8 Option);
91static unsigned SendData(UINTPTR BaseAddress, u8 *BufferPtr, unsigned ByteCount,
92 u8 Option);
93
94/************************** Variable Definitions **************************/
95
96/****************************************************************************/
117unsigned 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
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 ******************************************************************************/
236static 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) {
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 */
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 */
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 */
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/****************************************************************************/
373unsigned 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 */
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
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) {
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 ******************************************************************************/
494static 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 */
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 */
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 ******************************************************************************/
614u32 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/******************************************************************************/
638u32 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}
u32 XIic_CheckIsBusBusy(UINTPTR BaseAddress)
Definition xiic_l.c:614
unsigned XIic_Recv(UINTPTR BaseAddress, u8 Address, u8 *BufferPtr, unsigned ByteCount, u8 Option)
Definition xiic_l.c:117
unsigned XIic_Send(UINTPTR BaseAddress, u8 Address, u8 *BufferPtr, unsigned ByteCount, u8 Option)
Definition xiic_l.c:373
u32 XIic_WaitBusFree(UINTPTR BaseAddress)
Definition xiic_l.c:638
#define IIC_TIMEOUT
Definition xiic_l.c:76
#define XIIC_CR_REG_OFFSET
Definition xiic_l.h:82
#define XIIC_SR_BUS_BUSY_MASK
Definition xiic_l.h:168
#define XIIC_INTR_BNB_MASK
Definition xiic_l.h:120
#define XIIC_CR_REPEATED_START_MASK
Definition xiic_l.h:154
#define XIIC_DTR_REG_OFFSET
Definition xiic_l.h:84
#define XIIC_CR_NO_ACK_MASK
Definition xiic_l.h:153
#define XIic_WriteReg(BaseAddress, RegOffset, RegisterValue)
Definition xiic_l.h:270
#define XIic_Send7BitAddress(BaseAddress, SlaveAddress, Operation)
Definition xiic_l.h:453
#define XIIC_DRR_REG_OFFSET
Definition xiic_l.h:85
#define XIIC_WRITE_OPERATION
Definition xiic_l.h:202
#define XIIC_SR_REG_OFFSET
Definition xiic_l.h:83
#define XIIC_INTR_TX_ERROR_MASK
Definition xiic_l.h:117
#define XIIC_CR_ENABLE_DEVICE_MASK
Definition xiic_l.h:149
#define XIIC_SR_ADDR_AS_SLAVE_MASK
Definition xiic_l.h:165
#define XIic_ReadReg(BaseAddress, RegOffset)
Definition xiic_l.h:247
#define XIIC_READ_OPERATION
Definition xiic_l.h:201
#define XIIC_INTR_ARB_LOST_MASK
Definition xiic_l.h:116
#define XIIC_INTR_RX_FULL_MASK
Definition xiic_l.h:119
#define XIIC_STOP
Definition xiic_l.h:216
#define XIIC_RFD_REG_OFFSET
Definition xiic_l.h:90
#define XIIC_INTR_TX_EMPTY_MASK
Definition xiic_l.h:118
#define XIIC_REPEATED_START
Definition xiic_l.h:219
#define XIIC_CR_DIR_IS_TX_MASK
Definition xiic_l.h:152
#define XIic_ReadIisr(BaseAddress)
Definition xiic_l.h:371
#define XIic_ClearIisr(BaseAddress, InterruptMask)
Definition xiic_l.h:432
#define XIIC_CR_MSMS_MASK
Definition xiic_l.h:151