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
37 * Handles master mode transfers.
39 * <pre> MODIFICATION HISTORY:
41 * Ver Who Date Changes
42 * ----- --- -------- ---------------------------------------------
43 * 1.00a jz 01/30/10 First release
44 * 1.00a sdm 09/21/11 Updated the XIicPs_SetupMaster to not check for
45 * Bus Busy condition when the Hold Bit is set.
46 * 1.01a sg 03/30/12 Fixed an issue in XIicPs_MasterSendPolled where a
47 * check for transfer completion is added, which indicates
48 * the completion of current transfer.
49 * 2.0 hk 03/07/14 Added check for error status in the while loop that
50 * checks for completion. CR# 762244, 764875.
51 * 2.1 hk 04/24/14 Fix for CR# 789821 to handle >14 byte transfers.
52 * Fix for CR# 761060 - provision for repeated start.
53 * 2.2 hk 08/23/14 Slave monitor mode changes - clear FIFO, enable
54 * read mode and clear transfer size register.
55 * Disable NACK to avoid interrupts on each retry.
56 * 2.3 sk 10/06/14 Fill transmit fifo before address register when sending.
57 * Replaced XIICPS_DATA_INTR_DEPTH with XIICPS_FIFO_DEPTH.
58 * Repeated start feature removed.
59 * 3.0 sk 12/06/14 Implemented Repeated start feature.
60 * 01/31/15 Modified the code according to MISRAC 2012 Compliant.
61 * 02/18/15 Implemented larger data transfer using repeated start
62 * in Zynq UltraScale MP.
66 ******************************************************************************/
68 /***************************** Include Files *********************************/
72 /************************** Constant Definitions *****************************/
74 /**************************** Type Definitions *******************************/
76 /***************** Macros (Inline Functions) Definitions *********************/
78 /************************** Function Prototypes ******************************/
79 s32 TransmitFifoFill(XIicPs *InstancePtr);
81 static s32 XIicPs_SetupMaster(XIicPs *InstancePtr, s32 Role);
82 static void MasterSendData(XIicPs *InstancePtr);
84 /************************* Variable Definitions *****************************/
86 /*****************************************************************************/
88 * This function initiates an interrupt-driven send in master mode.
90 * It tries to send the first FIFO-full of data, then lets the interrupt
91 * handler to handle the rest of the data if there is any.
93 * @param InstancePtr is a pointer to the XIicPs instance.
94 * @param MsgPtr is the pointer to the send buffer.
95 * @param ByteCount is the number of bytes to be sent.
96 * @param SlaveAddr is the address of the slave we are sending to.
100 * @note This send routine is for interrupt-driven transfer only.
102 ****************************************************************************/
103 void XIicPs_MasterSend(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount,
109 * Assert validates the input arguments.
111 Xil_AssertVoid(InstancePtr != NULL);
112 Xil_AssertVoid(MsgPtr != NULL);
113 Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
114 Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
117 BaseAddr = InstancePtr->Config.BaseAddress;
118 InstancePtr->SendBufferPtr = MsgPtr;
119 InstancePtr->SendByteCount = ByteCount;
120 InstancePtr->RecvBufferPtr = NULL;
121 InstancePtr->IsSend = 1;
124 * Set repeated start if sending more than FIFO of data.
126 if (((InstancePtr->IsRepeatedStart) != 0)||
127 ((ByteCount > XIICPS_FIFO_DEPTH) != 0U)) {
128 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_CR_OFFSET,
129 XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
130 (u32)XIICPS_CR_HOLD_MASK);
134 * Setup as a master sending role.
136 (void)XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
138 (void)TransmitFifoFill(InstancePtr);
141 * Do the address transfer to notify the slave.
143 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
145 XIicPs_EnableInterrupts(BaseAddr,
146 (u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_COMP_MASK |
147 (u32)XIICPS_IXR_ARB_LOST_MASK);
150 /*****************************************************************************/
152 * This function initiates an interrupt-driven receive in master mode.
154 * It sets the transfer size register so the slave can send data to us.
155 * The rest of the work is managed by interrupt handler.
157 * @param InstancePtr is a pointer to the XIicPs instance.
158 * @param MsgPtr is the pointer to the receive buffer.
159 * @param ByteCount is the number of bytes to be received.
160 * @param SlaveAddr is the address of the slave we are receiving from.
164 * @note This receive routine is for interrupt-driven transfer only.
166 ****************************************************************************/
167 void XIicPs_MasterRecv(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount,
173 * Assert validates the input arguments.
175 Xil_AssertVoid(InstancePtr != NULL);
176 Xil_AssertVoid(MsgPtr != NULL);
177 Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
178 Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
180 BaseAddr = InstancePtr->Config.BaseAddress;
181 InstancePtr->RecvBufferPtr = MsgPtr;
182 InstancePtr->RecvByteCount = ByteCount;
183 InstancePtr->CurrByteCount = ByteCount;
184 InstancePtr->SendBufferPtr = NULL;
185 InstancePtr->IsSend = 0;
186 InstancePtr->UpdateTxSize = 0;
188 if ((ByteCount > XIICPS_FIFO_DEPTH) ||
189 ((InstancePtr->IsRepeatedStart) !=0))
191 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
192 XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
193 (u32)XIICPS_CR_HOLD_MASK);
197 * Initialize for a master receiving role.
199 (void)XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
202 * Do the address transfer to signal the slave.
204 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
207 * Setup the transfer size register so the slave knows how much
210 if (ByteCount > XIICPS_MAX_TRANSFER_SIZE) {
211 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
212 XIICPS_MAX_TRANSFER_SIZE);
213 InstancePtr->CurrByteCount = (s32)XIICPS_MAX_TRANSFER_SIZE;
214 InstancePtr->UpdateTxSize = 1;
216 XIicPs_WriteReg(BaseAddr, (u32)(XIICPS_TRANS_SIZE_OFFSET),
220 XIicPs_EnableInterrupts(BaseAddr,
221 (u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_DATA_MASK |
222 (u32)XIICPS_IXR_RX_OVR_MASK | (u32)XIICPS_IXR_COMP_MASK |
223 (u32)XIICPS_IXR_ARB_LOST_MASK);
226 /*****************************************************************************/
228 * This function initiates a polled mode send in master mode.
230 * It sends data to the FIFO and waits for the slave to pick them up.
231 * If slave fails to remove data from FIFO, the send fails with
234 * @param InstancePtr is a pointer to the XIicPs instance.
235 * @param MsgPtr is the pointer to the send buffer.
236 * @param ByteCount is the number of bytes to be sent.
237 * @param SlaveAddr is the address of the slave we are sending to.
240 * - XST_SUCCESS if everything went well.
241 * - XST_FAILURE if timed out.
243 * @note This send routine is for polled mode transfer only.
245 ****************************************************************************/
246 s32 XIicPs_MasterSendPolled(XIicPs *InstancePtr, u8 *MsgPtr,
247 s32 ByteCount, u16 SlaveAddr)
257 * Assert validates the input arguments.
259 Xil_AssertNonvoid(InstancePtr != NULL);
260 Xil_AssertNonvoid(MsgPtr != NULL);
261 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
262 Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
264 BaseAddr = InstancePtr->Config.BaseAddress;
265 InstancePtr->SendBufferPtr = MsgPtr;
266 InstancePtr->SendByteCount = ByteCount;
268 if (((InstancePtr->IsRepeatedStart) != 0) ||
269 ((ByteCount > XIICPS_FIFO_DEPTH) != 0U)) {
270 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
271 XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
272 (u32)XIICPS_CR_HOLD_MASK);
275 (void)XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
278 * Intrs keeps all the error-related interrupts.
280 Intrs = (u32)XIICPS_IXR_ARB_LOST_MASK | (u32)XIICPS_IXR_TX_OVR_MASK |
281 (u32)XIICPS_IXR_NACK_MASK;
284 * Clear the interrupt status register before use it to monitor.
286 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
287 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
290 * Transmit first FIFO full of data.
292 (void)TransmitFifoFill(InstancePtr);
294 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
296 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
299 * Continue sending as long as there is more data and
300 * there are no errors.
302 Value = ((InstancePtr->SendByteCount > (s32)0) &&
303 ((IntrStatusReg & Intrs) == (u32)0U));
304 while (Value != (u32)0x00U) {
305 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
308 * Wait until transmit FIFO is empty.
310 if ((StatusReg & XIICPS_SR_TXDV_MASK) != 0U) {
311 IntrStatusReg = XIicPs_ReadReg(BaseAddr,
313 Value = ((InstancePtr->SendByteCount > (s32)0) &&
314 ((IntrStatusReg & Intrs) == (u32)0U));
319 * Send more data out through transmit FIFO.
321 (void)TransmitFifoFill(InstancePtr);
322 Value = ((InstancePtr->SendByteCount > (s32)0) &&
323 ((IntrStatusReg & Intrs) == (u32)0U));
327 * Check for completion of transfer.
329 while ((IntrStatusReg & XIICPS_IXR_COMP_MASK) != XIICPS_IXR_COMP_MASK){
331 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
333 * If there is an error, tell the caller.
335 if ((IntrStatusReg & Intrs) != 0U) {
336 return (s32)XST_FAILURE;
340 if ((!(InstancePtr->IsRepeatedStart)) != 0) {
341 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
342 XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
343 (~XIICPS_CR_HOLD_MASK));
346 return (s32)XST_SUCCESS;
349 /*****************************************************************************/
351 * This function initiates a polled mode receive in master mode.
353 * It repeatedly sets the transfer size register so the slave can
354 * send data to us. It polls the data register for data to come in.
355 * If slave fails to send us data, it fails with time out.
357 * @param InstancePtr is a pointer to the XIicPs instance.
358 * @param MsgPtr is the pointer to the receive buffer.
359 * @param ByteCount is the number of bytes to be received.
360 * @param SlaveAddr is the address of the slave we are receiving from.
363 * - XST_SUCCESS if everything went well.
364 * - XST_FAILURE if timed out.
366 * @note This receive routine is for polled mode transfer only.
368 ****************************************************************************/
369 s32 XIicPs_MasterRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr,
370 s32 ByteCount, u16 SlaveAddr)
384 s32 UpdateTxSize = 0;
385 s32 ByteCountVar = ByteCount;
389 * Assert validates the input arguments.
391 Xil_AssertNonvoid(InstancePtr != NULL);
392 Xil_AssertNonvoid(MsgPtr != NULL);
393 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
394 Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
396 BaseAddr = InstancePtr->Config.BaseAddress;
397 InstancePtr->RecvBufferPtr = MsgPtr;
398 InstancePtr->RecvByteCount = ByteCountVar;
400 Platform = XGetPlatform_Info();
402 if((ByteCountVar > XIICPS_FIFO_DEPTH) ||
403 ((InstancePtr->IsRepeatedStart) !=0))
405 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
406 XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
407 (u32)XIICPS_CR_HOLD_MASK);
411 (void)XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
414 * Clear the interrupt status register before use it to monitor.
416 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
417 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
419 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
422 * Set up the transfer size register so the slave knows how much
425 if (ByteCountVar > XIICPS_MAX_TRANSFER_SIZE) {
426 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
427 XIICPS_MAX_TRANSFER_SIZE);
428 ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE;
431 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
436 * Intrs keeps all the error-related interrupts.
438 Intrs = (u32)XIICPS_IXR_ARB_LOST_MASK | (u32)XIICPS_IXR_RX_OVR_MASK |
439 (u32)XIICPS_IXR_RX_UNF_MASK | (u32)XIICPS_IXR_NACK_MASK;
441 * Poll the interrupt status register to find the errors.
443 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
444 while ((InstancePtr->RecvByteCount > 0) &&
445 ((IntrStatusReg & Intrs) == 0U)) {
446 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
448 while ((StatusReg & XIICPS_SR_RXDV_MASK) != 0U) {
449 if (((InstancePtr->RecvByteCount <
450 XIICPS_DATA_INTR_DEPTH) != 0U) && (IsHold != 0) &&
451 ((!InstancePtr->IsRepeatedStart) != 0) &&
452 (UpdateTxSize == 0)) {
454 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
455 XIicPs_ReadReg(BaseAddr,
457 (~XIICPS_CR_HOLD_MASK));
459 XIicPs_RecvByte(InstancePtr);
462 if (Platform == XPLAT_ZYNQ) {
463 if ((UpdateTxSize != 0) &&
464 ((ByteCountVar == (XIICPS_FIFO_DEPTH + 1)) != 0U)) {
469 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
471 if (Platform == XPLAT_ZYNQ) {
472 if ((UpdateTxSize != 0) &&
473 ((ByteCountVar == (XIICPS_FIFO_DEPTH + 1)) != 0U)) {
474 /* wait while fifo is full */
475 while (XIicPs_ReadReg(BaseAddr,
476 XIICPS_TRANS_SIZE_OFFSET) !=
477 (u32)(ByteCountVar - XIICPS_FIFO_DEPTH)) { ;
480 if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
481 XIICPS_MAX_TRANSFER_SIZE) {
483 XIicPs_WriteReg(BaseAddr,
484 XIICPS_TRANS_SIZE_OFFSET,
485 XIICPS_MAX_TRANSFER_SIZE);
486 ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE +
489 XIicPs_WriteReg(BaseAddr,
490 XIICPS_TRANS_SIZE_OFFSET,
491 InstancePtr->RecvByteCount -
494 ByteCountVar = InstancePtr->RecvByteCount;
498 if ((InstancePtr->RecvByteCount > 0) && (ByteCountVar == 0)) {
500 * Clear the interrupt status register before use it to
503 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
504 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
506 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
508 if ((InstancePtr->RecvByteCount) >
509 XIICPS_MAX_TRANSFER_SIZE) {
511 XIicPs_WriteReg(BaseAddr,
512 XIICPS_TRANS_SIZE_OFFSET,
513 XIICPS_MAX_TRANSFER_SIZE);
514 ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE;
516 XIicPs_WriteReg(BaseAddr,
517 XIICPS_TRANS_SIZE_OFFSET,
518 InstancePtr->RecvByteCount);
520 ByteCountVar = InstancePtr->RecvByteCount;
525 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
528 if ((!(InstancePtr->IsRepeatedStart)) != 0) {
529 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
530 XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
531 (~XIICPS_CR_HOLD_MASK));
533 if ((IntrStatusReg & Intrs) != 0x0U) {
534 Result = (s32)XST_FAILURE;
537 Result = (s32)XST_SUCCESS;
543 /*****************************************************************************/
545 * This function enables the slave monitor mode.
547 * It enables slave monitor in the control register and enables
548 * slave ready interrupt. It then does an address transfer to slave.
549 * Interrupt handler will signal the caller if slave responds to
550 * the address transfer.
552 * @param InstancePtr is a pointer to the XIicPs instance.
553 * @param SlaveAddr is the address of the slave we want to contact.
559 ****************************************************************************/
560 void XIicPs_EnableSlaveMonitor(XIicPs *InstancePtr, u16 SlaveAddr)
565 Xil_AssertVoid(InstancePtr != NULL);
567 BaseAddr = InstancePtr->Config.BaseAddress;
569 /* Clear transfer size register */
570 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_TRANS_SIZE_OFFSET, 0x0U);
573 * Enable slave monitor mode in control register.
575 ConfigReg = XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET);
576 ConfigReg |= (u32)XIICPS_CR_MS_MASK | (u32)XIICPS_CR_NEA_MASK |
577 (u32)XIICPS_CR_CLR_FIFO_MASK | (u32)XIICPS_CR_SLVMON_MASK;
578 ConfigReg &= (u32)(~XIICPS_CR_RD_WR_MASK);
580 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_CR_OFFSET, ConfigReg);
583 * Set up interrupt flag for slave monitor interrupt.
586 XIicPs_EnableInterrupts(BaseAddr, (u32)XIICPS_IXR_SLV_RDY_MASK);
589 * Initialize the slave monitor register.
591 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_SLV_PAUSE_OFFSET, 0xFU);
594 * Set the slave address to start the slave address transmission.
596 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
601 /*****************************************************************************/
603 * This function disables slave monitor mode.
605 * @param InstancePtr is a pointer to the XIicPs instance.
611 ****************************************************************************/
612 void XIicPs_DisableSlaveMonitor(XIicPs *InstancePtr)
616 Xil_AssertVoid(InstancePtr != NULL);
618 BaseAddr = InstancePtr->Config.BaseAddress;
621 * Clear slave monitor control bit.
623 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
624 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET)
625 & (~XIICPS_CR_SLVMON_MASK));
628 * Clear interrupt flag for slave monitor interrupt.
630 XIicPs_DisableInterrupts(BaseAddr, XIICPS_IXR_SLV_RDY_MASK);
635 /*****************************************************************************/
637 * The interrupt handler for the master mode. It does the protocol handling for
638 * the interrupt-driven transfers.
640 * Completion events and errors are signaled to upper layer for proper handling.
643 * The interrupts that are handled are:
645 * This case is handled only for master receive data.
646 * The master has to request for more data (if there is more data to
647 * receive) and read the data from the FIFO .
650 * If the Master is transmitting data and there is more data to be
651 * sent then the data is written to the FIFO. If there is no more data to
652 * be transmitted then a completion event is signalled to the upper layer
653 * by calling the callback handler.
655 * If the Master is receiving data then the data is read from the FIFO and
656 * the Master has to request for more data (if there is more data to
657 * receive). If all the data has been received then a completion event
658 * is signalled to the upper layer by calling the callback handler.
659 * It is an error if the amount of received data is more than expected.
661 * - NAK and SLAVE_RDY
662 * This is signalled to the upper layer by calling the callback handler.
664 * - All Other interrupts
665 * These interrupts are marked as error. This is signalled to the upper
666 * layer by calling the callback handler.
670 * @param InstancePtr is a pointer to the XIicPs instance.
676 ****************************************************************************/
677 void XIicPs_MasterInterruptHandler(XIicPs *InstancePtr)
680 u32 StatusEvent = 0U;
688 * Assert validates the input arguments.
690 Xil_AssertVoid(InstancePtr != NULL);
691 Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
693 BaseAddr = InstancePtr->Config.BaseAddress;
695 Platform = XGetPlatform_Info();
698 * Read the Interrupt status register.
700 IntrStatusReg = XIicPs_ReadReg(BaseAddr,
701 (u32)XIICPS_ISR_OFFSET);
704 * Write the status back to clear the interrupts so no events are
705 * missed while processing this interrupt.
707 XIicPs_WriteReg(BaseAddr, (u32)XIICPS_ISR_OFFSET, IntrStatusReg);
710 * Use the Mask register AND with the Interrupt Status register so
711 * disabled interrupts are not processed.
713 IntrStatusReg &= ~(XIicPs_ReadReg(BaseAddr, (u32)XIICPS_IMR_OFFSET));
715 ByteCnt = InstancePtr->CurrByteCount;
718 if ((XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) & (u32)XIICPS_CR_HOLD_MASK) != 0U) {
725 if (((InstancePtr->IsSend) != 0) &&
726 ((u32)0U != (IntrStatusReg & (u32)XIICPS_IXR_COMP_MASK))) {
727 if (InstancePtr->SendByteCount > 0) {
728 MasterSendData(InstancePtr);
730 StatusEvent |= XIICPS_EVENT_COMPLETE_SEND;
738 if (((!(InstancePtr->IsSend))!= 0) &&
739 ((0 != (IntrStatusReg & (u32)XIICPS_IXR_DATA_MASK)) ||
740 (0 != (IntrStatusReg & (u32)XIICPS_IXR_COMP_MASK)))){
742 while ((XIicPs_ReadReg(BaseAddr, (u32)XIICPS_SR_OFFSET) &
743 XIICPS_SR_RXDV_MASK) != 0U) {
744 if (((InstancePtr->RecvByteCount <
745 XIICPS_DATA_INTR_DEPTH)!= 0U) && (IsHold != 0) &&
746 ((!InstancePtr->IsRepeatedStart)!= 0) &&
747 (InstancePtr->UpdateTxSize == 0)) {
749 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
750 XIicPs_ReadReg(BaseAddr,
752 (~XIICPS_CR_HOLD_MASK));
754 XIicPs_RecvByte(InstancePtr);
757 if (Platform == XPLAT_ZYNQ) {
758 if ((InstancePtr->UpdateTxSize != 0) &&
759 ((ByteCnt == (XIICPS_FIFO_DEPTH + 1)) != 0U)) {
765 if (Platform == XPLAT_ZYNQ) {
766 if ((InstancePtr->UpdateTxSize != 0) &&
767 ((ByteCnt == (XIICPS_FIFO_DEPTH + 1))!= 0U)) {
768 /* wait while fifo is full */
769 while (XIicPs_ReadReg(BaseAddr,
770 XIICPS_TRANS_SIZE_OFFSET) !=
771 (u32)(ByteCnt - XIICPS_FIFO_DEPTH)) {
774 if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
775 XIICPS_MAX_TRANSFER_SIZE) {
777 XIicPs_WriteReg(BaseAddr,
778 XIICPS_TRANS_SIZE_OFFSET,
779 XIICPS_MAX_TRANSFER_SIZE);
780 ByteCnt = (s32)XIICPS_MAX_TRANSFER_SIZE +
783 XIicPs_WriteReg(BaseAddr,
784 XIICPS_TRANS_SIZE_OFFSET,
785 InstancePtr->RecvByteCount -
787 InstancePtr->UpdateTxSize = 0;
788 ByteCnt = InstancePtr->RecvByteCount;
792 if ((InstancePtr->RecvByteCount > 0) && (ByteCnt == 0)) {
794 * Clear the interrupt status register before use it to
797 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
798 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
800 SlaveAddr = XIicPs_ReadReg(BaseAddr, (u32)XIICPS_ADDR_OFFSET);
801 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
803 if ((InstancePtr->RecvByteCount) >
804 XIICPS_MAX_TRANSFER_SIZE) {
806 XIicPs_WriteReg(BaseAddr,
807 XIICPS_TRANS_SIZE_OFFSET,
808 XIICPS_MAX_TRANSFER_SIZE);
809 ByteCnt = (s32)XIICPS_MAX_TRANSFER_SIZE;
811 XIicPs_WriteReg(BaseAddr,
812 XIICPS_TRANS_SIZE_OFFSET,
813 InstancePtr->RecvByteCount);
814 InstancePtr->UpdateTxSize = 0;
815 ByteCnt = InstancePtr->RecvByteCount;
817 XIicPs_EnableInterrupts(BaseAddr,
818 (u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_DATA_MASK |
819 (u32)XIICPS_IXR_RX_OVR_MASK | (u32)XIICPS_IXR_COMP_MASK |
820 (u32)XIICPS_IXR_ARB_LOST_MASK);
823 InstancePtr->CurrByteCount = ByteCnt;
826 if (((!(InstancePtr->IsSend)) != 0) &&
827 (0U != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) {
829 * If all done, tell the application.
831 if (InstancePtr->RecvByteCount == 0){
832 if ((!(InstancePtr->IsRepeatedStart)) != 0) {
833 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
834 XIicPs_ReadReg(BaseAddr,
836 (~XIICPS_CR_HOLD_MASK));
838 StatusEvent |= XIICPS_EVENT_COMPLETE_RECV;
844 * Slave ready interrupt, it is only meaningful for master mode.
846 if (0U != (IntrStatusReg & XIICPS_IXR_SLV_RDY_MASK)) {
847 StatusEvent |= XIICPS_EVENT_SLAVE_RDY;
850 if (0U != (IntrStatusReg & XIICPS_IXR_NACK_MASK)) {
851 if ((!(InstancePtr->IsRepeatedStart)) != 0 ) {
852 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
853 XIicPs_ReadReg(BaseAddr,
855 (~XIICPS_CR_HOLD_MASK));
857 StatusEvent |= XIICPS_EVENT_NACK;
861 * Arbitration lost interrupt
863 if (0U != (IntrStatusReg & XIICPS_IXR_ARB_LOST_MASK)) {
864 StatusEvent |= XIICPS_EVENT_ARB_LOST;
868 * All other interrupts are treated as error.
870 if (0U != (IntrStatusReg & (XIICPS_IXR_NACK_MASK |
871 XIICPS_IXR_RX_UNF_MASK | XIICPS_IXR_TX_OVR_MASK |
872 XIICPS_IXR_RX_OVR_MASK))) {
873 if ((!(InstancePtr->IsRepeatedStart)) != 0) {
874 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
875 XIicPs_ReadReg(BaseAddr,
877 (~XIICPS_CR_HOLD_MASK));
879 StatusEvent |= XIICPS_EVENT_ERROR;
883 * Signal application if there are any events.
885 if (StatusEvent != 0U) {
886 InstancePtr->StatusHandler(InstancePtr->CallBackRef,
892 /*****************************************************************************/
894 * This function prepares a device to transfers as a master.
896 * @param InstancePtr is a pointer to the XIicPs instance.
898 * @param Role specifies whether the device is sending or receiving.
901 * - XST_SUCCESS if everything went well.
902 * - XST_FAILURE if bus is busy.
904 * @note Interrupts are always disabled, device which needs to use
905 * interrupts needs to setup interrupts after this call.
907 ****************************************************************************/
908 static s32 XIicPs_SetupMaster(XIicPs *InstancePtr, s32 Role)
912 u32 EnabledIntr = 0x0U;
914 Xil_AssertNonvoid(InstancePtr != NULL);
916 BaseAddr = InstancePtr->Config.BaseAddress;
917 ControlReg = XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET);
921 * Only check if bus is busy when repeated start option is not set.
923 if ((ControlReg & XIICPS_CR_HOLD_MASK) == 0U) {
924 if (XIicPs_BusIsBusy(InstancePtr) == (s32)1) {
925 return (s32)XST_FAILURE;
930 * Set up master, AckEn, nea and also clear fifo.
932 ControlReg |= (u32)XIICPS_CR_ACKEN_MASK | (u32)XIICPS_CR_CLR_FIFO_MASK |
933 (u32)XIICPS_CR_NEA_MASK | (u32)XIICPS_CR_MS_MASK;
935 if (Role == RECVING_ROLE) {
936 ControlReg |= (u32)XIICPS_CR_RD_WR_MASK;
937 EnabledIntr = (u32)XIICPS_IXR_DATA_MASK |(u32)XIICPS_IXR_RX_OVR_MASK;
939 ControlReg &= (u32)(~XIICPS_CR_RD_WR_MASK);
941 EnabledIntr |= (u32)XIICPS_IXR_COMP_MASK | (u32)XIICPS_IXR_ARB_LOST_MASK;
943 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, ControlReg);
945 XIicPs_DisableAllInterrupts(BaseAddr);
947 return (s32)XST_SUCCESS;
950 /*****************************************************************************/
952 * This function handles continuation of sending data. It is invoked
953 * from interrupt handler.
955 * @param InstancePtr is a pointer to the XIicPs instance.
961 ****************************************************************************/
962 static void MasterSendData(XIicPs *InstancePtr)
964 (void)TransmitFifoFill(InstancePtr);
967 * Clear hold bit if done, so stop can be sent out.
969 if (InstancePtr->SendByteCount == 0) {
972 * If user has enabled repeated start as an option,
975 if ((!(InstancePtr->IsRepeatedStart)) != 0) {
977 XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
978 (u32)XIICPS_CR_OFFSET,
979 XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
980 (u32)XIICPS_CR_OFFSET) & (u32)(~ XIICPS_CR_HOLD_MASK));