1 /******************************************************************************
3 * Copyright (C) 2010 - 2014 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.
56 ******************************************************************************/
58 /***************************** Include Files *********************************/
62 /************************** Constant Definitions *****************************/
64 /**************************** Type Definitions *******************************/
66 /***************** Macros (Inline Functions) Definitions *********************/
68 /************************** Function Prototypes ******************************/
69 int TransmitFifoFill(XIicPs *InstancePtr);
71 static int XIicPs_SetupMaster(XIicPs *InstancePtr, int Role);
72 static void MasterSendData(XIicPs *InstancePtr);
74 /************************* Variable Definitions *****************************/
76 /*****************************************************************************/
78 * This function initiates an interrupt-driven send in master mode.
80 * It tries to send the first FIFO-full of data, then lets the interrupt
81 * handler to handle the rest of the data if there is any.
83 * @param InstancePtr is a pointer to the XIicPs instance.
84 * @param MsgPtr is the pointer to the send buffer.
85 * @param ByteCount is the number of bytes to be sent.
86 * @param SlaveAddr is the address of the slave we are sending to.
90 * @note This send routine is for interrupt-driven transfer only.
92 ****************************************************************************/
93 void XIicPs_MasterSend(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
99 * Assert validates the input arguments.
101 Xil_AssertVoid(InstancePtr != NULL);
102 Xil_AssertVoid(MsgPtr != NULL);
103 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
104 Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
107 BaseAddr = InstancePtr->Config.BaseAddress;
108 InstancePtr->SendBufferPtr = MsgPtr;
109 InstancePtr->SendByteCount = ByteCount;
110 InstancePtr->RecvBufferPtr = NULL;
111 InstancePtr->IsSend = 1;
114 * Set repeated start if sending more than FIFO of data.
116 if ((InstancePtr->IsRepeatedStart) ||
117 (ByteCount > XIICPS_FIFO_DEPTH)) {
118 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
119 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
120 XIICPS_CR_HOLD_MASK);
124 * Setup as a master sending role.
126 XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
129 * Do the address transfer to notify the slave.
131 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
133 TransmitFifoFill(InstancePtr);
135 XIicPs_EnableInterrupts(BaseAddr,
136 XIICPS_IXR_NACK_MASK | XIICPS_IXR_COMP_MASK |
137 XIICPS_IXR_ARB_LOST_MASK);
140 /*****************************************************************************/
142 * This function initiates an interrupt-driven receive in master mode.
144 * It sets the transfer size register so the slave can send data to us.
145 * The rest of the work is managed by interrupt handler.
147 * @param InstancePtr is a pointer to the XIicPs instance.
148 * @param MsgPtr is the pointer to the receive buffer.
149 * @param ByteCount is the number of bytes to be received.
150 * @param SlaveAddr is the address of the slave we are receiving from.
154 * @note This receive routine is for interrupt-driven transfer only.
156 ****************************************************************************/
157 void XIicPs_MasterRecv(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
163 * Assert validates the input arguments.
165 Xil_AssertVoid(InstancePtr != NULL);
166 Xil_AssertVoid(MsgPtr != NULL);
167 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
168 Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
170 BaseAddr = InstancePtr->Config.BaseAddress;
171 InstancePtr->RecvBufferPtr = MsgPtr;
172 InstancePtr->RecvByteCount = ByteCount;
173 InstancePtr->CurrByteCount = ByteCount;
174 InstancePtr->SendBufferPtr = NULL;
175 InstancePtr->IsSend = 0;
176 InstancePtr->UpdateTxSize = 0;
178 if ((ByteCount > XIICPS_DATA_INTR_DEPTH) ||
179 (InstancePtr->IsRepeatedStart))
181 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
182 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
183 XIICPS_CR_HOLD_MASK);
187 * Initialize for a master receiving role.
189 XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
192 * Do the address transfer to signal the slave.
194 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
197 * Setup the transfer size register so the slave knows how much
200 if (ByteCount > XIICPS_MAX_TRANSFER_SIZE) {
201 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
202 XIICPS_MAX_TRANSFER_SIZE);
203 InstancePtr->CurrByteCount = XIICPS_MAX_TRANSFER_SIZE;
204 InstancePtr->UpdateTxSize = 1;
206 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
210 XIicPs_EnableInterrupts(BaseAddr,
211 XIICPS_IXR_NACK_MASK | XIICPS_IXR_DATA_MASK |
212 XIICPS_IXR_RX_OVR_MASK | XIICPS_IXR_COMP_MASK |
213 XIICPS_IXR_ARB_LOST_MASK);
216 /*****************************************************************************/
218 * This function initiates a polled mode send in master mode.
220 * It sends data to the FIFO and waits for the slave to pick them up.
221 * If slave fails to remove data from FIFO, the send fails with
224 * @param InstancePtr is a pointer to the XIicPs instance.
225 * @param MsgPtr is the pointer to the send buffer.
226 * @param ByteCount is the number of bytes to be sent.
227 * @param SlaveAddr is the address of the slave we are sending to.
230 * - XST_SUCCESS if everything went well.
231 * - XST_FAILURE if timed out.
233 * @note This send routine is for polled mode transfer only.
235 ****************************************************************************/
236 int XIicPs_MasterSendPolled(XIicPs *InstancePtr, u8 *MsgPtr,
237 int ByteCount, u16 SlaveAddr)
245 * Assert validates the input arguments.
247 Xil_AssertNonvoid(InstancePtr != NULL);
248 Xil_AssertNonvoid(MsgPtr != NULL);
249 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
250 Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
252 BaseAddr = InstancePtr->Config.BaseAddress;
253 InstancePtr->SendBufferPtr = MsgPtr;
254 InstancePtr->SendByteCount = ByteCount;
256 if ((InstancePtr->IsRepeatedStart) ||
257 (ByteCount > XIICPS_FIFO_DEPTH)) {
258 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
259 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
260 XIICPS_CR_HOLD_MASK);
263 XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
265 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
268 * Intrs keeps all the error-related interrupts.
270 Intrs = XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_TX_OVR_MASK |
271 XIICPS_IXR_NACK_MASK;
274 * Clear the interrupt status register before use it to monitor.
276 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
277 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
280 * Transmit first FIFO full of data.
282 TransmitFifoFill(InstancePtr);
284 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
287 * Continue sending as long as there is more data and
288 * there are no errors.
290 while ((InstancePtr->SendByteCount > 0) &&
291 ((IntrStatusReg & Intrs) == 0)) {
292 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
295 * Wait until transmit FIFO is empty.
297 if ((StatusReg & XIICPS_SR_TXDV_MASK) != 0) {
298 IntrStatusReg = XIicPs_ReadReg(BaseAddr,
304 * Send more data out through transmit FIFO.
306 TransmitFifoFill(InstancePtr);
310 * Check for completion of transfer.
312 while ((IntrStatusReg & XIICPS_IXR_COMP_MASK) != XIICPS_IXR_COMP_MASK){
314 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
316 * If there is an error, tell the caller.
318 if ((IntrStatusReg & Intrs) != 0) {
323 if (!(InstancePtr->IsRepeatedStart)) {
324 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
325 XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
326 (~XIICPS_CR_HOLD_MASK));
332 /*****************************************************************************/
334 * This function initiates a polled mode receive in master mode.
336 * It repeatedly sets the transfer size register so the slave can
337 * send data to us. It polls the data register for data to come in.
338 * If slave fails to send us data, it fails with time out.
340 * @param InstancePtr is a pointer to the XIicPs instance.
341 * @param MsgPtr is the pointer to the receive buffer.
342 * @param ByteCount is the number of bytes to be received.
343 * @param SlaveAddr is the address of the slave we are receiving from.
346 * - XST_SUCCESS if everything went well.
347 * - XST_FAILURE if timed out.
349 * @note This receive routine is for polled mode transfer only.
351 ****************************************************************************/
352 int XIicPs_MasterRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr,
353 int ByteCount, u16 SlaveAddr)
360 int UpdateTxSize = 0;
363 * Assert validates the input arguments.
365 Xil_AssertNonvoid(InstancePtr != NULL);
366 Xil_AssertNonvoid(MsgPtr != NULL);
367 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
368 Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
370 BaseAddr = InstancePtr->Config.BaseAddress;
371 InstancePtr->RecvBufferPtr = MsgPtr;
372 InstancePtr->RecvByteCount = ByteCount;
374 if((ByteCount > XIICPS_DATA_INTR_DEPTH) ||
375 (InstancePtr->IsRepeatedStart))
377 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
378 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
379 XIICPS_CR_HOLD_MASK);
383 XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
386 * Clear the interrupt status register before use it to monitor.
388 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
389 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
391 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
394 * Set up the transfer size register so the slave knows how much
397 if (ByteCount > XIICPS_MAX_TRANSFER_SIZE) {
398 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
399 XIICPS_MAX_TRANSFER_SIZE);
400 ByteCount = XIICPS_MAX_TRANSFER_SIZE;
403 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
408 * Intrs keeps all the error-related interrupts.
410 Intrs = XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_RX_OVR_MASK |
411 XIICPS_IXR_RX_UNF_MASK | XIICPS_IXR_NACK_MASK;
414 * Poll the interrupt status register to find the errors.
416 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
417 while ((InstancePtr->RecvByteCount > 0) &&
418 ((IntrStatusReg & Intrs) == 0)) {
419 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
421 while (StatusReg & XIICPS_SR_RXDV_MASK) {
422 if ((InstancePtr->RecvByteCount <
423 XIICPS_DATA_INTR_DEPTH) && IsHold &&
424 (!(InstancePtr->IsRepeatedStart))) {
426 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
427 XIicPs_ReadReg(BaseAddr,
429 (~XIICPS_CR_HOLD_MASK));
431 XIicPs_RecvByte(InstancePtr);
435 (ByteCount == XIICPS_FIFO_DEPTH + 1))
438 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
441 if (UpdateTxSize && (ByteCount == XIICPS_FIFO_DEPTH + 1)) {
443 * wait while fifo is full
445 while(XIicPs_ReadReg(BaseAddr,
446 XIICPS_TRANS_SIZE_OFFSET) !=
447 (ByteCount - XIICPS_FIFO_DEPTH));
449 if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
450 XIICPS_MAX_TRANSFER_SIZE) {
452 XIicPs_WriteReg(BaseAddr,
453 XIICPS_TRANS_SIZE_OFFSET,
454 XIICPS_MAX_TRANSFER_SIZE);
455 ByteCount = XIICPS_MAX_TRANSFER_SIZE +
458 XIicPs_WriteReg(BaseAddr,
459 XIICPS_TRANS_SIZE_OFFSET,
460 InstancePtr->RecvByteCount -
463 ByteCount = InstancePtr->RecvByteCount;
467 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
470 if (!(InstancePtr->IsRepeatedStart)) {
471 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
472 XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
473 (~XIICPS_CR_HOLD_MASK));
476 if (IntrStatusReg & Intrs) {
483 /*****************************************************************************/
485 * This function enables the slave monitor mode.
487 * It enables slave monitor in the control register and enables
488 * slave ready interrupt. It then does an address transfer to slave.
489 * Interrupt handler will signal the caller if slave responds to
490 * the address transfer.
492 * @param InstancePtr is a pointer to the XIicPs instance.
493 * @param SlaveAddr is the address of the slave we want to contact.
499 ****************************************************************************/
500 void XIicPs_EnableSlaveMonitor(XIicPs *InstancePtr, u16 SlaveAddr)
504 Xil_AssertVoid(InstancePtr != NULL);
506 BaseAddr = InstancePtr->Config.BaseAddress;
509 * Enable slave monitor mode in control register.
511 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
512 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
515 XIICPS_CR_SLVMON_MASK );
518 * Set up interrupt flag for slave monitor interrupt.
520 XIicPs_EnableInterrupts(BaseAddr, XIICPS_IXR_NACK_MASK |
521 XIICPS_IXR_SLV_RDY_MASK);
524 * Initialize the slave monitor register.
526 XIicPs_WriteReg(BaseAddr, XIICPS_SLV_PAUSE_OFFSET, 0xF);
529 * Set the slave address to start the slave address transmission.
531 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
536 /*****************************************************************************/
538 * This function disables slave monitor mode.
540 * @param InstancePtr is a pointer to the XIicPs instance.
546 ****************************************************************************/
547 void XIicPs_DisableSlaveMonitor(XIicPs *InstancePtr)
551 Xil_AssertVoid(InstancePtr != NULL);
553 BaseAddr = InstancePtr->Config.BaseAddress;
556 * Clear slave monitor control bit.
558 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
559 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET)
560 & (~XIICPS_CR_SLVMON_MASK));
563 * Clear interrupt flag for slave monitor interrupt.
565 XIicPs_DisableInterrupts(BaseAddr, XIICPS_IXR_SLV_RDY_MASK);
570 /*****************************************************************************/
572 * The interrupt handler for the master mode. It does the protocol handling for
573 * the interrupt-driven transfers.
575 * Completion events and errors are signaled to upper layer for proper handling.
578 * The interrupts that are handled are:
580 * This case is handled only for master receive data.
581 * The master has to request for more data (if there is more data to
582 * receive) and read the data from the FIFO .
585 * If the Master is transmitting data and there is more data to be
586 * sent then the data is written to the FIFO. If there is no more data to
587 * be transmitted then a completion event is signalled to the upper layer
588 * by calling the callback handler.
590 * If the Master is receiving data then the data is read from the FIFO and
591 * the Master has to request for more data (if there is more data to
592 * receive). If all the data has been received then a completion event
593 * is signalled to the upper layer by calling the callback handler.
594 * It is an error if the amount of received data is more than expected.
596 * - NAK and SLAVE_RDY
597 * This is signalled to the upper layer by calling the callback handler.
599 * - All Other interrupts
600 * These interrupts are marked as error. This is signalled to the upper
601 * layer by calling the callback handler.
605 * @param InstancePtr is a pointer to the XIicPs instance.
611 ****************************************************************************/
612 void XIicPs_MasterInterruptHandler(XIicPs *InstancePtr)
621 * Assert validates the input arguments.
623 Xil_AssertVoid(InstancePtr != NULL);
624 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
626 BaseAddr = InstancePtr->Config.BaseAddress;
629 * Read the Interrupt status register.
631 IntrStatusReg = XIicPs_ReadReg(BaseAddr,
635 * Write the status back to clear the interrupts so no events are
636 * missed while processing this interrupt.
638 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
641 * Use the Mask register AND with the Interrupt Status register so
642 * disabled interrupts are not processed.
644 IntrStatusReg &= ~(XIicPs_ReadReg(BaseAddr, XIICPS_IMR_OFFSET));
646 ByteCnt = InstancePtr->CurrByteCount;
649 if (XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) & XIICPS_CR_HOLD_MASK) {
656 if ((InstancePtr->IsSend) &&
657 (0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) {
658 if (InstancePtr->SendByteCount > 0) {
659 MasterSendData(InstancePtr);
661 StatusEvent |= XIICPS_EVENT_COMPLETE_SEND;
669 if ((!(InstancePtr->IsSend)) &&
670 ((0 != (IntrStatusReg & XIICPS_IXR_DATA_MASK)) ||
671 (0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK)))){
673 while (XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET) &
674 XIICPS_SR_RXDV_MASK) {
675 if ((InstancePtr->RecvByteCount <
676 XIICPS_DATA_INTR_DEPTH) && IsHold &&
677 (!(InstancePtr->IsRepeatedStart))) {
679 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
680 XIicPs_ReadReg(BaseAddr,
682 (~XIICPS_CR_HOLD_MASK));
684 XIicPs_RecvByte(InstancePtr);
687 if (InstancePtr->UpdateTxSize &&
688 (ByteCnt == XIICPS_FIFO_DEPTH + 1))
692 if (InstancePtr->UpdateTxSize &&
693 (ByteCnt == XIICPS_FIFO_DEPTH + 1)) {
695 * wait while fifo is full
697 while(XIicPs_ReadReg(BaseAddr,
698 XIICPS_TRANS_SIZE_OFFSET) !=
699 (ByteCnt - XIICPS_FIFO_DEPTH));
701 if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
702 XIICPS_MAX_TRANSFER_SIZE) {
704 XIicPs_WriteReg(BaseAddr,
705 XIICPS_TRANS_SIZE_OFFSET,
706 XIICPS_MAX_TRANSFER_SIZE);
707 ByteCnt = XIICPS_MAX_TRANSFER_SIZE +
710 XIicPs_WriteReg(BaseAddr,
711 XIICPS_TRANS_SIZE_OFFSET,
712 InstancePtr->RecvByteCount -
714 InstancePtr->UpdateTxSize = 0;
715 ByteCnt = InstancePtr->RecvByteCount;
718 InstancePtr->CurrByteCount = ByteCnt;
721 if ((!(InstancePtr->IsSend)) &&
722 (0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) {
724 * If all done, tell the application.
726 if (InstancePtr->RecvByteCount == 0){
727 if (!(InstancePtr->IsRepeatedStart)) {
728 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
729 XIicPs_ReadReg(BaseAddr,
731 (~XIICPS_CR_HOLD_MASK));
733 StatusEvent |= XIICPS_EVENT_COMPLETE_RECV;
739 * Slave ready interrupt, it is only meaningful for master mode.
741 if (0 != (IntrStatusReg & XIICPS_IXR_SLV_RDY_MASK)) {
742 StatusEvent |= XIICPS_EVENT_SLAVE_RDY;
745 if (0 != (IntrStatusReg & XIICPS_IXR_NACK_MASK)) {
746 if (!(InstancePtr->IsRepeatedStart)) {
747 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
748 XIicPs_ReadReg(BaseAddr,
750 (~XIICPS_CR_HOLD_MASK));
752 StatusEvent |= XIICPS_EVENT_NACK;
756 * All other interrupts are treated as error.
758 if (0 != (IntrStatusReg & (XIICPS_IXR_NACK_MASK |
759 XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_RX_UNF_MASK |
760 XIICPS_IXR_TX_OVR_MASK | XIICPS_IXR_RX_OVR_MASK))) {
761 if (!(InstancePtr->IsRepeatedStart)) {
762 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
763 XIicPs_ReadReg(BaseAddr,
765 (~XIICPS_CR_HOLD_MASK));
767 StatusEvent |= XIICPS_EVENT_ERROR;
771 * Signal application if there are any events.
773 if (0 != StatusEvent) {
774 InstancePtr->StatusHandler(InstancePtr->CallBackRef,
780 /*****************************************************************************/
782 * This function prepares a device to transfers as a master.
784 * @param InstancePtr is a pointer to the XIicPs instance.
786 * @param Role specifies whether the device is sending or receiving.
789 * - XST_SUCCESS if everything went well.
790 * - XST_FAILURE if bus is busy.
792 * @note Interrupts are always disabled, device which needs to use
793 * interrupts needs to setup interrupts after this call.
795 ****************************************************************************/
796 static int XIicPs_SetupMaster(XIicPs *InstancePtr, int Role)
800 u32 EnabledIntr = 0x0;
802 Xil_AssertNonvoid(InstancePtr != NULL);
804 BaseAddr = InstancePtr->Config.BaseAddress;
805 ControlReg = XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET);
809 * Only check if bus is busy when repeated start option is not set.
811 if ((ControlReg & XIICPS_CR_HOLD_MASK) == 0) {
812 if (XIicPs_BusIsBusy(InstancePtr)) {
818 * Set up master, AckEn, nea and also clear fifo.
820 ControlReg |= XIICPS_CR_ACKEN_MASK | XIICPS_CR_CLR_FIFO_MASK |
821 XIICPS_CR_NEA_MASK | XIICPS_CR_MS_MASK;
823 if (Role == RECVING_ROLE) {
824 ControlReg |= XIICPS_CR_RD_WR_MASK;
825 EnabledIntr = XIICPS_IXR_DATA_MASK |XIICPS_IXR_RX_OVR_MASK;
827 ControlReg &= ~XIICPS_CR_RD_WR_MASK;
829 EnabledIntr |= XIICPS_IXR_COMP_MASK | XIICPS_IXR_ARB_LOST_MASK;
831 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, ControlReg);
833 XIicPs_DisableAllInterrupts(BaseAddr);
838 /*****************************************************************************/
840 * This function handles continuation of sending data. It is invoked
841 * from interrupt handler.
843 * @param InstancePtr is a pointer to the XIicPs instance.
849 ****************************************************************************/
850 static void MasterSendData(XIicPs *InstancePtr)
852 TransmitFifoFill(InstancePtr);
855 * Clear hold bit if done, so stop can be sent out.
857 if (InstancePtr->SendByteCount == 0) {
860 * If user has enabled repeated start as an option,
863 if (!(InstancePtr->IsRepeatedStart)) {
865 XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
867 XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
868 XIICPS_CR_OFFSET) & ~ XIICPS_CR_HOLD_MASK);