1 /******************************************************************************
3 * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /*****************************************************************************/
35 * @file xiicps_master.c
36 * @addtogroup iicps_v3_0
39 * Handles master mode transfers.
41 * <pre> MODIFICATION HISTORY:
43 * Ver Who Date Changes
44 * ----- --- -------- ---------------------------------------------
45 * 1.00a jz 01/30/10 First release
46 * 1.00a sdm 09/21/11 Updated the XIicPs_SetupMaster to not check for
47 * Bus Busy condition when the Hold Bit is set.
48 * 1.01a sg 03/30/12 Fixed an issue in XIicPs_MasterSendPolled where a
49 * check for transfer completion is added, which indicates
50 * the completion of current transfer.
51 * 2.0 hk 03/07/14 Added check for error status in the while loop that
52 * checks for completion. CR# 762244, 764875.
53 * 2.1 hk 04/24/14 Fix for CR# 789821 to handle >14 byte transfers.
54 * Fix for CR# 761060 - provision for repeated start.
55 * 2.2 hk 08/23/14 Slave monitor mode changes - clear FIFO, enable
56 * read mode and clear transfer size register.
57 * Disable NACK to avoid interrupts on each retry.
58 * 2.3 sk 10/06/14 Fill transmit fifo before address register when sending.
59 * Replaced XIICPS_DATA_INTR_DEPTH with XIICPS_FIFO_DEPTH.
60 * Repeated start feature removed.
61 * 3.0 sk 12/06/14 Implemented Repeated start feature.
62 * 01/31/15 Modified the code according to MISRAC 2012 Compliant.
63 * 02/18/15 Implemented larger data transfer using repeated start
64 * in Zynq UltraScale MP.
68 ******************************************************************************/
70 /***************************** Include Files *********************************/
74 /************************** Constant Definitions *****************************/
76 /**************************** Type Definitions *******************************/
78 /***************** Macros (Inline Functions) Definitions *********************/
80 /************************** Function Prototypes ******************************/
81 s32 TransmitFifoFill(XIicPs *InstancePtr);
83 static s32 XIicPs_SetupMaster(XIicPs *InstancePtr, s32 Role);
84 static void MasterSendData(XIicPs *InstancePtr);
86 /************************* Variable Definitions *****************************/
88 /*****************************************************************************/
90 * This function initiates an interrupt-driven send in master mode.
92 * It tries to send the first FIFO-full of data, then lets the interrupt
93 * handler to handle the rest of the data if there is any.
95 * @param InstancePtr is a pointer to the XIicPs instance.
96 * @param MsgPtr is the pointer to the send buffer.
97 * @param ByteCount is the number of bytes to be sent.
98 * @param SlaveAddr is the address of the slave we are sending to.
102 * @note This send routine is for interrupt-driven transfer only.
104 ****************************************************************************/
105 void XIicPs_MasterSend(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount,
111 * Assert validates the input arguments.
113 Xil_AssertVoid(InstancePtr != NULL);
114 Xil_AssertVoid(MsgPtr != NULL);
115 Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
116 Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
119 BaseAddr = InstancePtr->Config.BaseAddress;
120 InstancePtr->SendBufferPtr = MsgPtr;
121 InstancePtr->SendByteCount = ByteCount;
122 InstancePtr->RecvBufferPtr = NULL;
123 InstancePtr->IsSend = 1;
126 * Set repeated start if sending more than FIFO of data.
128 if (((InstancePtr->IsRepeatedStart) != 0)||
129 ((ByteCount > XIICPS_FIFO_DEPTH) != 0U)) {
130 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_CR_OFFSET,
131 XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
132 (u32)XIICPS_CR_HOLD_MASK);
136 * Setup as a master sending role.
138 (void)XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
140 (void)TransmitFifoFill(InstancePtr);
142 XIicPs_EnableInterrupts(BaseAddr,
143 (u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_COMP_MASK |
144 (u32)XIICPS_IXR_ARB_LOST_MASK);
146 * Do the address transfer to notify the slave.
148 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
152 /*****************************************************************************/
154 * This function initiates an interrupt-driven receive in master mode.
156 * It sets the transfer size register so the slave can send data to us.
157 * The rest of the work is managed by interrupt handler.
159 * @param InstancePtr is a pointer to the XIicPs instance.
160 * @param MsgPtr is the pointer to the receive buffer.
161 * @param ByteCount is the number of bytes to be received.
162 * @param SlaveAddr is the address of the slave we are receiving from.
166 * @note This receive routine is for interrupt-driven transfer only.
168 ****************************************************************************/
169 void XIicPs_MasterRecv(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount,
175 * Assert validates the input arguments.
177 Xil_AssertVoid(InstancePtr != NULL);
178 Xil_AssertVoid(MsgPtr != NULL);
179 Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
180 Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
182 BaseAddr = InstancePtr->Config.BaseAddress;
183 InstancePtr->RecvBufferPtr = MsgPtr;
184 InstancePtr->RecvByteCount = ByteCount;
185 InstancePtr->CurrByteCount = ByteCount;
186 InstancePtr->SendBufferPtr = NULL;
187 InstancePtr->IsSend = 0;
188 InstancePtr->UpdateTxSize = 0;
190 if ((ByteCount > XIICPS_FIFO_DEPTH) ||
191 ((InstancePtr->IsRepeatedStart) !=0))
193 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
194 XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
195 (u32)XIICPS_CR_HOLD_MASK);
199 * Initialize for a master receiving role.
201 (void)XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
203 * Setup the transfer size register so the slave knows how much
206 if (ByteCount > XIICPS_MAX_TRANSFER_SIZE) {
207 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
208 XIICPS_MAX_TRANSFER_SIZE);
209 InstancePtr->CurrByteCount = (s32)XIICPS_MAX_TRANSFER_SIZE;
210 InstancePtr->UpdateTxSize = 1;
212 XIicPs_WriteReg(BaseAddr, (u32)(XIICPS_TRANS_SIZE_OFFSET),
216 XIicPs_EnableInterrupts(BaseAddr,
217 (u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_DATA_MASK |
218 (u32)XIICPS_IXR_RX_OVR_MASK | (u32)XIICPS_IXR_COMP_MASK |
219 (u32)XIICPS_IXR_ARB_LOST_MASK);
221 * Do the address transfer to signal the slave.
223 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
227 /*****************************************************************************/
229 * This function initiates a polled mode send in master mode.
231 * It sends data to the FIFO and waits for the slave to pick them up.
232 * If slave fails to remove data from FIFO, the send fails with
235 * @param InstancePtr is a pointer to the XIicPs instance.
236 * @param MsgPtr is the pointer to the send buffer.
237 * @param ByteCount is the number of bytes to be sent.
238 * @param SlaveAddr is the address of the slave we are sending to.
241 * - XST_SUCCESS if everything went well.
242 * - XST_FAILURE if timed out.
244 * @note This send routine is for polled mode transfer only.
246 ****************************************************************************/
247 s32 XIicPs_MasterSendPolled(XIicPs *InstancePtr, u8 *MsgPtr,
248 s32 ByteCount, u16 SlaveAddr)
258 * Assert validates the input arguments.
260 Xil_AssertNonvoid(InstancePtr != NULL);
261 Xil_AssertNonvoid(MsgPtr != NULL);
262 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
263 Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
265 BaseAddr = InstancePtr->Config.BaseAddress;
266 InstancePtr->SendBufferPtr = MsgPtr;
267 InstancePtr->SendByteCount = ByteCount;
269 if (((InstancePtr->IsRepeatedStart) != 0) ||
270 ((ByteCount > XIICPS_FIFO_DEPTH) != 0U)) {
271 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
272 XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
273 (u32)XIICPS_CR_HOLD_MASK);
276 (void)XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
279 * Intrs keeps all the error-related interrupts.
281 Intrs = (u32)XIICPS_IXR_ARB_LOST_MASK | (u32)XIICPS_IXR_TX_OVR_MASK |
282 (u32)XIICPS_IXR_NACK_MASK;
285 * Clear the interrupt status register before use it to monitor.
287 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
288 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
291 * Transmit first FIFO full of data.
293 (void)TransmitFifoFill(InstancePtr);
295 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
297 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
300 * Continue sending as long as there is more data and
301 * there are no errors.
303 Value = ((InstancePtr->SendByteCount > (s32)0) &&
304 ((IntrStatusReg & Intrs) == (u32)0U));
305 while (Value != (u32)0x00U) {
306 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
309 * Wait until transmit FIFO is empty.
311 if ((StatusReg & XIICPS_SR_TXDV_MASK) != 0U) {
312 IntrStatusReg = XIicPs_ReadReg(BaseAddr,
314 Value = ((InstancePtr->SendByteCount > (s32)0) &&
315 ((IntrStatusReg & Intrs) == (u32)0U));
320 * Send more data out through transmit FIFO.
322 (void)TransmitFifoFill(InstancePtr);
323 Value = ((InstancePtr->SendByteCount > (s32)0) &&
324 ((IntrStatusReg & Intrs) == (u32)0U));
328 * Check for completion of transfer.
330 while ((IntrStatusReg & XIICPS_IXR_COMP_MASK) != XIICPS_IXR_COMP_MASK){
332 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
334 * If there is an error, tell the caller.
336 if ((IntrStatusReg & Intrs) != 0U) {
337 return (s32)XST_FAILURE;
341 if ((!(InstancePtr->IsRepeatedStart)) != 0) {
342 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
343 XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
344 (~XIICPS_CR_HOLD_MASK));
347 return (s32)XST_SUCCESS;
350 /*****************************************************************************/
352 * This function initiates a polled mode receive in master mode.
354 * It repeatedly sets the transfer size register so the slave can
355 * send data to us. It polls the data register for data to come in.
356 * If slave fails to send us data, it fails with time out.
358 * @param InstancePtr is a pointer to the XIicPs instance.
359 * @param MsgPtr is the pointer to the receive buffer.
360 * @param ByteCount is the number of bytes to be received.
361 * @param SlaveAddr is the address of the slave we are receiving from.
364 * - XST_SUCCESS if everything went well.
365 * - XST_FAILURE if timed out.
367 * @note This receive routine is for polled mode transfer only.
369 ****************************************************************************/
370 s32 XIicPs_MasterRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr,
371 s32 ByteCount, u16 SlaveAddr)
385 s32 UpdateTxSize = 0;
386 s32 ByteCountVar = ByteCount;
390 * Assert validates the input arguments.
392 Xil_AssertNonvoid(InstancePtr != NULL);
393 Xil_AssertNonvoid(MsgPtr != NULL);
394 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
395 Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
397 BaseAddr = InstancePtr->Config.BaseAddress;
398 InstancePtr->RecvBufferPtr = MsgPtr;
399 InstancePtr->RecvByteCount = ByteCountVar;
401 Platform = XGetPlatform_Info();
403 if((ByteCountVar > XIICPS_FIFO_DEPTH) ||
404 ((InstancePtr->IsRepeatedStart) !=0))
406 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
407 XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
408 (u32)XIICPS_CR_HOLD_MASK);
412 (void)XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
415 * Clear the interrupt status register before use it to monitor.
417 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
418 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
420 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
423 * Set up the transfer size register so the slave knows how much
426 if (ByteCountVar > XIICPS_MAX_TRANSFER_SIZE) {
427 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
428 XIICPS_MAX_TRANSFER_SIZE);
429 ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE;
432 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
437 * Intrs keeps all the error-related interrupts.
439 Intrs = (u32)XIICPS_IXR_ARB_LOST_MASK | (u32)XIICPS_IXR_RX_OVR_MASK |
440 (u32)XIICPS_IXR_RX_UNF_MASK | (u32)XIICPS_IXR_NACK_MASK;
442 * Poll the interrupt status register to find the errors.
444 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
445 while ((InstancePtr->RecvByteCount > 0) &&
446 ((IntrStatusReg & Intrs) == 0U)) {
447 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
449 while ((StatusReg & XIICPS_SR_RXDV_MASK) != 0U) {
450 if (((InstancePtr->RecvByteCount <
451 XIICPS_DATA_INTR_DEPTH) != 0U) && (IsHold != 0) &&
452 ((!InstancePtr->IsRepeatedStart) != 0) &&
453 (UpdateTxSize == 0)) {
455 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
456 XIicPs_ReadReg(BaseAddr,
458 (~XIICPS_CR_HOLD_MASK));
460 XIicPs_RecvByte(InstancePtr);
463 if (Platform == XPLAT_ZYNQ) {
464 if ((UpdateTxSize != 0) &&
465 ((ByteCountVar == (XIICPS_FIFO_DEPTH + 1)) != 0U)) {
470 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
472 if (Platform == XPLAT_ZYNQ) {
473 if ((UpdateTxSize != 0) &&
474 ((ByteCountVar == (XIICPS_FIFO_DEPTH + 1)) != 0U)) {
475 /* wait while fifo is full */
476 while (XIicPs_ReadReg(BaseAddr,
477 XIICPS_TRANS_SIZE_OFFSET) !=
478 (u32)(ByteCountVar - XIICPS_FIFO_DEPTH)) { ;
481 if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
482 XIICPS_MAX_TRANSFER_SIZE) {
484 XIicPs_WriteReg(BaseAddr,
485 XIICPS_TRANS_SIZE_OFFSET,
486 XIICPS_MAX_TRANSFER_SIZE);
487 ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE +
490 XIicPs_WriteReg(BaseAddr,
491 XIICPS_TRANS_SIZE_OFFSET,
492 InstancePtr->RecvByteCount -
495 ByteCountVar = InstancePtr->RecvByteCount;
499 if ((InstancePtr->RecvByteCount > 0) && (ByteCountVar == 0)) {
501 * Clear the interrupt status register before use it to
504 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
505 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
507 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
509 if ((InstancePtr->RecvByteCount) >
510 XIICPS_MAX_TRANSFER_SIZE) {
512 XIicPs_WriteReg(BaseAddr,
513 XIICPS_TRANS_SIZE_OFFSET,
514 XIICPS_MAX_TRANSFER_SIZE);
515 ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE;
517 XIicPs_WriteReg(BaseAddr,
518 XIICPS_TRANS_SIZE_OFFSET,
519 InstancePtr->RecvByteCount);
521 ByteCountVar = InstancePtr->RecvByteCount;
526 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
529 if ((!(InstancePtr->IsRepeatedStart)) != 0) {
530 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
531 XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
532 (~XIICPS_CR_HOLD_MASK));
534 if ((IntrStatusReg & Intrs) != 0x0U) {
535 Result = (s32)XST_FAILURE;
538 Result = (s32)XST_SUCCESS;
544 /*****************************************************************************/
546 * This function enables the slave monitor mode.
548 * It enables slave monitor in the control register and enables
549 * slave ready interrupt. It then does an address transfer to slave.
550 * Interrupt handler will signal the caller if slave responds to
551 * the address transfer.
553 * @param InstancePtr is a pointer to the XIicPs instance.
554 * @param SlaveAddr is the address of the slave we want to contact.
560 ****************************************************************************/
561 void XIicPs_EnableSlaveMonitor(XIicPs *InstancePtr, u16 SlaveAddr)
566 Xil_AssertVoid(InstancePtr != NULL);
568 BaseAddr = InstancePtr->Config.BaseAddress;
570 /* Clear transfer size register */
571 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_TRANS_SIZE_OFFSET, 0x0U);
574 * Enable slave monitor mode in control register.
576 ConfigReg = XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET);
577 ConfigReg |= (u32)XIICPS_CR_MS_MASK | (u32)XIICPS_CR_NEA_MASK |
578 (u32)XIICPS_CR_CLR_FIFO_MASK | (u32)XIICPS_CR_SLVMON_MASK;
579 ConfigReg &= (u32)(~XIICPS_CR_RD_WR_MASK);
581 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_CR_OFFSET, ConfigReg);
584 * Set up interrupt flag for slave monitor interrupt.
587 XIicPs_EnableInterrupts(BaseAddr, (u32)XIICPS_IXR_SLV_RDY_MASK);
590 * Initialize the slave monitor register.
592 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_SLV_PAUSE_OFFSET, 0xFU);
595 * Set the slave address to start the slave address transmission.
597 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
602 /*****************************************************************************/
604 * This function disables slave monitor mode.
606 * @param InstancePtr is a pointer to the XIicPs instance.
612 ****************************************************************************/
613 void XIicPs_DisableSlaveMonitor(XIicPs *InstancePtr)
617 Xil_AssertVoid(InstancePtr != NULL);
619 BaseAddr = InstancePtr->Config.BaseAddress;
622 * Clear slave monitor control bit.
624 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
625 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET)
626 & (~XIICPS_CR_SLVMON_MASK));
629 * Clear interrupt flag for slave monitor interrupt.
631 XIicPs_DisableInterrupts(BaseAddr, XIICPS_IXR_SLV_RDY_MASK);
636 /*****************************************************************************/
638 * The interrupt handler for the master mode. It does the protocol handling for
639 * the interrupt-driven transfers.
641 * Completion events and errors are signaled to upper layer for proper handling.
644 * The interrupts that are handled are:
646 * This case is handled only for master receive data.
647 * The master has to request for more data (if there is more data to
648 * receive) and read the data from the FIFO .
651 * If the Master is transmitting data and there is more data to be
652 * sent then the data is written to the FIFO. If there is no more data to
653 * be transmitted then a completion event is signalled to the upper layer
654 * by calling the callback handler.
656 * If the Master is receiving data then the data is read from the FIFO and
657 * the Master has to request for more data (if there is more data to
658 * receive). If all the data has been received then a completion event
659 * is signalled to the upper layer by calling the callback handler.
660 * It is an error if the amount of received data is more than expected.
662 * - NAK and SLAVE_RDY
663 * This is signalled to the upper layer by calling the callback handler.
665 * - All Other interrupts
666 * These interrupts are marked as error. This is signalled to the upper
667 * layer by calling the callback handler.
671 * @param InstancePtr is a pointer to the XIicPs instance.
677 ****************************************************************************/
678 void XIicPs_MasterInterruptHandler(XIicPs *InstancePtr)
681 u32 StatusEvent = 0U;
689 * Assert validates the input arguments.
691 Xil_AssertVoid(InstancePtr != NULL);
692 Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
694 BaseAddr = InstancePtr->Config.BaseAddress;
696 Platform = XGetPlatform_Info();
699 * Read the Interrupt status register.
701 IntrStatusReg = XIicPs_ReadReg(BaseAddr,
702 (u32)XIICPS_ISR_OFFSET);
705 * Write the status back to clear the interrupts so no events are
706 * missed while processing this interrupt.
708 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_ISR_OFFSET, IntrStatusReg);
711 * Use the Mask register AND with the Interrupt Status register so
712 * disabled interrupts are not processed.
714 IntrStatusReg &= ~(XIicPs_ReadReg(BaseAddr, (u32)XIICPS_IMR_OFFSET));
716 ByteCnt = InstancePtr->CurrByteCount;
719 if ((XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) & (u32)XIICPS_CR_HOLD_MASK) != 0U) {
726 if (((InstancePtr->IsSend) != 0) &&
727 ((u32)0U != (IntrStatusReg & (u32)XIICPS_IXR_COMP_MASK))) {
728 if (InstancePtr->SendByteCount > 0) {
729 MasterSendData(InstancePtr);
731 StatusEvent |= XIICPS_EVENT_COMPLETE_SEND;
739 if (((!(InstancePtr->IsSend))!= 0) &&
740 ((0 != (IntrStatusReg & (u32)XIICPS_IXR_DATA_MASK)) ||
741 (0 != (IntrStatusReg & (u32)XIICPS_IXR_COMP_MASK)))){
743 while ((XIicPs_ReadReg(BaseAddr, (u32)XIICPS_SR_OFFSET) &
744 XIICPS_SR_RXDV_MASK) != 0U) {
745 if (((InstancePtr->RecvByteCount <
746 XIICPS_DATA_INTR_DEPTH)!= 0U) && (IsHold != 0) &&
747 ((!InstancePtr->IsRepeatedStart)!= 0) &&
748 (InstancePtr->UpdateTxSize == 0)) {
750 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
751 XIicPs_ReadReg(BaseAddr,
753 (~XIICPS_CR_HOLD_MASK));
755 XIicPs_RecvByte(InstancePtr);
758 if (Platform == XPLAT_ZYNQ) {
759 if ((InstancePtr->UpdateTxSize != 0) &&
760 ((ByteCnt == (XIICPS_FIFO_DEPTH + 1)) != 0U)) {
766 if (Platform == XPLAT_ZYNQ) {
767 if ((InstancePtr->UpdateTxSize != 0) &&
768 ((ByteCnt == (XIICPS_FIFO_DEPTH + 1))!= 0U)) {
769 /* wait while fifo is full */
770 while (XIicPs_ReadReg(BaseAddr,
771 XIICPS_TRANS_SIZE_OFFSET) !=
772 (u32)(ByteCnt - XIICPS_FIFO_DEPTH)) {
775 if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
776 XIICPS_MAX_TRANSFER_SIZE) {
778 XIicPs_WriteReg(BaseAddr,
779 XIICPS_TRANS_SIZE_OFFSET,
780 XIICPS_MAX_TRANSFER_SIZE);
781 ByteCnt = (s32)XIICPS_MAX_TRANSFER_SIZE +
784 XIicPs_WriteReg(BaseAddr,
785 XIICPS_TRANS_SIZE_OFFSET,
786 InstancePtr->RecvByteCount -
788 InstancePtr->UpdateTxSize = 0;
789 ByteCnt = InstancePtr->RecvByteCount;
793 if ((InstancePtr->RecvByteCount > 0) && (ByteCnt == 0)) {
795 * Clear the interrupt status register before use it to
798 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
799 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
801 SlaveAddr = XIicPs_ReadReg(BaseAddr, (u32)XIICPS_ADDR_OFFSET);
802 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
804 if ((InstancePtr->RecvByteCount) >
805 XIICPS_MAX_TRANSFER_SIZE) {
807 XIicPs_WriteReg(BaseAddr,
808 XIICPS_TRANS_SIZE_OFFSET,
809 XIICPS_MAX_TRANSFER_SIZE);
810 ByteCnt = (s32)XIICPS_MAX_TRANSFER_SIZE;
812 XIicPs_WriteReg(BaseAddr,
813 XIICPS_TRANS_SIZE_OFFSET,
814 InstancePtr->RecvByteCount);
815 InstancePtr->UpdateTxSize = 0;
816 ByteCnt = InstancePtr->RecvByteCount;
818 XIicPs_EnableInterrupts(BaseAddr,
819 (u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_DATA_MASK |
820 (u32)XIICPS_IXR_RX_OVR_MASK | (u32)XIICPS_IXR_COMP_MASK |
821 (u32)XIICPS_IXR_ARB_LOST_MASK);
824 InstancePtr->CurrByteCount = ByteCnt;
827 if (((!(InstancePtr->IsSend)) != 0) &&
828 (0U != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) {
830 * If all done, tell the application.
832 if (InstancePtr->RecvByteCount == 0){
833 if ((!(InstancePtr->IsRepeatedStart)) != 0) {
834 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
835 XIicPs_ReadReg(BaseAddr,
837 (~XIICPS_CR_HOLD_MASK));
839 StatusEvent |= XIICPS_EVENT_COMPLETE_RECV;
845 * Slave ready interrupt, it is only meaningful for master mode.
847 if (0U != (IntrStatusReg & XIICPS_IXR_SLV_RDY_MASK)) {
848 StatusEvent |= XIICPS_EVENT_SLAVE_RDY;
851 if (0U != (IntrStatusReg & XIICPS_IXR_NACK_MASK)) {
852 if ((!(InstancePtr->IsRepeatedStart)) != 0 ) {
853 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
854 XIicPs_ReadReg(BaseAddr,
856 (~XIICPS_CR_HOLD_MASK));
858 StatusEvent |= XIICPS_EVENT_NACK;
862 * Arbitration lost interrupt
864 if (0U != (IntrStatusReg & XIICPS_IXR_ARB_LOST_MASK)) {
865 StatusEvent |= XIICPS_EVENT_ARB_LOST;
869 * All other interrupts are treated as error.
871 if (0U != (IntrStatusReg & (XIICPS_IXR_NACK_MASK |
872 XIICPS_IXR_RX_UNF_MASK | XIICPS_IXR_TX_OVR_MASK |
873 XIICPS_IXR_RX_OVR_MASK))) {
874 if ((!(InstancePtr->IsRepeatedStart)) != 0) {
875 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
876 XIicPs_ReadReg(BaseAddr,
878 (~XIICPS_CR_HOLD_MASK));
880 StatusEvent |= XIICPS_EVENT_ERROR;
884 * Signal application if there are any events.
886 if (StatusEvent != 0U) {
887 InstancePtr->StatusHandler(InstancePtr->CallBackRef,
893 /*****************************************************************************/
895 * This function prepares a device to transfers as a master.
897 * @param InstancePtr is a pointer to the XIicPs instance.
899 * @param Role specifies whether the device is sending or receiving.
902 * - XST_SUCCESS if everything went well.
903 * - XST_FAILURE if bus is busy.
905 * @note Interrupts are always disabled, device which needs to use
906 * interrupts needs to setup interrupts after this call.
908 ****************************************************************************/
909 static s32 XIicPs_SetupMaster(XIicPs *InstancePtr, s32 Role)
913 u32 EnabledIntr = 0x0U;
915 Xil_AssertNonvoid(InstancePtr != NULL);
917 BaseAddr = InstancePtr->Config.BaseAddress;
918 ControlReg = XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET);
922 * Only check if bus is busy when repeated start option is not set.
924 if ((ControlReg & XIICPS_CR_HOLD_MASK) == 0U) {
925 if (XIicPs_BusIsBusy(InstancePtr) == (s32)1) {
926 return (s32)XST_FAILURE;
931 * Set up master, AckEn, nea and also clear fifo.
933 ControlReg |= (u32)XIICPS_CR_ACKEN_MASK | (u32)XIICPS_CR_CLR_FIFO_MASK |
934 (u32)XIICPS_CR_NEA_MASK | (u32)XIICPS_CR_MS_MASK;
936 if (Role == RECVING_ROLE) {
937 ControlReg |= (u32)XIICPS_CR_RD_WR_MASK;
938 EnabledIntr = (u32)XIICPS_IXR_DATA_MASK |(u32)XIICPS_IXR_RX_OVR_MASK;
940 ControlReg &= (u32)(~XIICPS_CR_RD_WR_MASK);
942 EnabledIntr |= (u32)XIICPS_IXR_COMP_MASK | (u32)XIICPS_IXR_ARB_LOST_MASK;
944 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, ControlReg);
946 XIicPs_DisableAllInterrupts(BaseAddr);
948 return (s32)XST_SUCCESS;
951 /*****************************************************************************/
953 * This function handles continuation of sending data. It is invoked
954 * from interrupt handler.
956 * @param InstancePtr is a pointer to the XIicPs instance.
962 ****************************************************************************/
963 static void MasterSendData(XIicPs *InstancePtr)
965 (void)TransmitFifoFill(InstancePtr);
968 * Clear hold bit if done, so stop can be sent out.
970 if (InstancePtr->SendByteCount == 0) {
973 * If user has enabled repeated start as an option,
976 if ((!(InstancePtr->IsRepeatedStart)) != 0) {
978 XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
979 (u32)XIICPS_CR_OFFSET,
980 XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
981 (u32)XIICPS_CR_OFFSET) & (u32)(~ XIICPS_CR_HOLD_MASK));