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
36 * @addtogroup iicps_v2_1
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.
58 ******************************************************************************/
60 /***************************** Include Files *********************************/
64 /************************** Constant Definitions *****************************/
66 /**************************** Type Definitions *******************************/
68 /***************** Macros (Inline Functions) Definitions *********************/
70 /************************** Function Prototypes ******************************/
71 int TransmitFifoFill(XIicPs *InstancePtr);
73 static int XIicPs_SetupMaster(XIicPs *InstancePtr, int Role);
74 static void MasterSendData(XIicPs *InstancePtr);
76 /************************* Variable Definitions *****************************/
78 /*****************************************************************************/
80 * This function initiates an interrupt-driven send in master mode.
82 * It tries to send the first FIFO-full of data, then lets the interrupt
83 * handler to handle the rest of the data if there is any.
85 * @param InstancePtr is a pointer to the XIicPs instance.
86 * @param MsgPtr is the pointer to the send buffer.
87 * @param ByteCount is the number of bytes to be sent.
88 * @param SlaveAddr is the address of the slave we are sending to.
92 * @note This send routine is for interrupt-driven transfer only.
94 ****************************************************************************/
95 void XIicPs_MasterSend(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
101 * Assert validates the input arguments.
103 Xil_AssertVoid(InstancePtr != NULL);
104 Xil_AssertVoid(MsgPtr != NULL);
105 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
106 Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
109 BaseAddr = InstancePtr->Config.BaseAddress;
110 InstancePtr->SendBufferPtr = MsgPtr;
111 InstancePtr->SendByteCount = ByteCount;
112 InstancePtr->RecvBufferPtr = NULL;
113 InstancePtr->IsSend = 1;
116 * Set repeated start if sending more than FIFO of data.
118 if ((InstancePtr->IsRepeatedStart) ||
119 (ByteCount > XIICPS_FIFO_DEPTH)) {
120 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
121 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
122 XIICPS_CR_HOLD_MASK);
126 * Setup as a master sending role.
128 XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
131 * Do the address transfer to notify the slave.
133 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
135 TransmitFifoFill(InstancePtr);
137 XIicPs_EnableInterrupts(BaseAddr,
138 XIICPS_IXR_NACK_MASK | XIICPS_IXR_COMP_MASK |
139 XIICPS_IXR_ARB_LOST_MASK);
142 /*****************************************************************************/
144 * This function initiates an interrupt-driven receive in master mode.
146 * It sets the transfer size register so the slave can send data to us.
147 * The rest of the work is managed by interrupt handler.
149 * @param InstancePtr is a pointer to the XIicPs instance.
150 * @param MsgPtr is the pointer to the receive buffer.
151 * @param ByteCount is the number of bytes to be received.
152 * @param SlaveAddr is the address of the slave we are receiving from.
156 * @note This receive routine is for interrupt-driven transfer only.
158 ****************************************************************************/
159 void XIicPs_MasterRecv(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
165 * Assert validates the input arguments.
167 Xil_AssertVoid(InstancePtr != NULL);
168 Xil_AssertVoid(MsgPtr != NULL);
169 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
170 Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
172 BaseAddr = InstancePtr->Config.BaseAddress;
173 InstancePtr->RecvBufferPtr = MsgPtr;
174 InstancePtr->RecvByteCount = ByteCount;
175 InstancePtr->CurrByteCount = ByteCount;
176 InstancePtr->SendBufferPtr = NULL;
177 InstancePtr->IsSend = 0;
178 InstancePtr->UpdateTxSize = 0;
180 if ((ByteCount > XIICPS_DATA_INTR_DEPTH) ||
181 (InstancePtr->IsRepeatedStart))
183 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
184 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
185 XIICPS_CR_HOLD_MASK);
189 * Initialize for a master receiving role.
191 XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
194 * Do the address transfer to signal the slave.
196 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
199 * Setup the transfer size register so the slave knows how much
202 if (ByteCount > XIICPS_MAX_TRANSFER_SIZE) {
203 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
204 XIICPS_MAX_TRANSFER_SIZE);
205 InstancePtr->CurrByteCount = XIICPS_MAX_TRANSFER_SIZE;
206 InstancePtr->UpdateTxSize = 1;
208 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
212 XIicPs_EnableInterrupts(BaseAddr,
213 XIICPS_IXR_NACK_MASK | XIICPS_IXR_DATA_MASK |
214 XIICPS_IXR_RX_OVR_MASK | XIICPS_IXR_COMP_MASK |
215 XIICPS_IXR_ARB_LOST_MASK);
218 /*****************************************************************************/
220 * This function initiates a polled mode send in master mode.
222 * It sends data to the FIFO and waits for the slave to pick them up.
223 * If slave fails to remove data from FIFO, the send fails with
226 * @param InstancePtr is a pointer to the XIicPs instance.
227 * @param MsgPtr is the pointer to the send buffer.
228 * @param ByteCount is the number of bytes to be sent.
229 * @param SlaveAddr is the address of the slave we are sending to.
232 * - XST_SUCCESS if everything went well.
233 * - XST_FAILURE if timed out.
235 * @note This send routine is for polled mode transfer only.
237 ****************************************************************************/
238 int XIicPs_MasterSendPolled(XIicPs *InstancePtr, u8 *MsgPtr,
239 int ByteCount, u16 SlaveAddr)
247 * Assert validates the input arguments.
249 Xil_AssertNonvoid(InstancePtr != NULL);
250 Xil_AssertNonvoid(MsgPtr != NULL);
251 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
252 Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
254 BaseAddr = InstancePtr->Config.BaseAddress;
255 InstancePtr->SendBufferPtr = MsgPtr;
256 InstancePtr->SendByteCount = ByteCount;
258 if ((InstancePtr->IsRepeatedStart) ||
259 (ByteCount > XIICPS_FIFO_DEPTH)) {
260 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
261 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
262 XIICPS_CR_HOLD_MASK);
265 XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
267 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
270 * Intrs keeps all the error-related interrupts.
272 Intrs = XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_TX_OVR_MASK |
273 XIICPS_IXR_NACK_MASK;
276 * Clear the interrupt status register before use it to monitor.
278 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
279 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
282 * Transmit first FIFO full of data.
284 TransmitFifoFill(InstancePtr);
286 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
289 * Continue sending as long as there is more data and
290 * there are no errors.
292 while ((InstancePtr->SendByteCount > 0) &&
293 ((IntrStatusReg & Intrs) == 0)) {
294 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
297 * Wait until transmit FIFO is empty.
299 if ((StatusReg & XIICPS_SR_TXDV_MASK) != 0) {
300 IntrStatusReg = XIicPs_ReadReg(BaseAddr,
306 * Send more data out through transmit FIFO.
308 TransmitFifoFill(InstancePtr);
312 * Check for completion of transfer.
314 while ((IntrStatusReg & XIICPS_IXR_COMP_MASK) != XIICPS_IXR_COMP_MASK){
316 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
318 * If there is an error, tell the caller.
320 if ((IntrStatusReg & Intrs) != 0) {
325 if (!(InstancePtr->IsRepeatedStart)) {
326 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
327 XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
328 (~XIICPS_CR_HOLD_MASK));
334 /*****************************************************************************/
336 * This function initiates a polled mode receive in master mode.
338 * It repeatedly sets the transfer size register so the slave can
339 * send data to us. It polls the data register for data to come in.
340 * If slave fails to send us data, it fails with time out.
342 * @param InstancePtr is a pointer to the XIicPs instance.
343 * @param MsgPtr is the pointer to the receive buffer.
344 * @param ByteCount is the number of bytes to be received.
345 * @param SlaveAddr is the address of the slave we are receiving from.
348 * - XST_SUCCESS if everything went well.
349 * - XST_FAILURE if timed out.
351 * @note This receive routine is for polled mode transfer only.
353 ****************************************************************************/
354 int XIicPs_MasterRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr,
355 int ByteCount, u16 SlaveAddr)
362 int UpdateTxSize = 0;
365 * Assert validates the input arguments.
367 Xil_AssertNonvoid(InstancePtr != NULL);
368 Xil_AssertNonvoid(MsgPtr != NULL);
369 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
370 Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
372 BaseAddr = InstancePtr->Config.BaseAddress;
373 InstancePtr->RecvBufferPtr = MsgPtr;
374 InstancePtr->RecvByteCount = ByteCount;
376 if((ByteCount > XIICPS_DATA_INTR_DEPTH) ||
377 (InstancePtr->IsRepeatedStart))
379 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
380 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
381 XIICPS_CR_HOLD_MASK);
385 XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
388 * Clear the interrupt status register before use it to monitor.
390 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
391 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
393 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
396 * Set up the transfer size register so the slave knows how much
399 if (ByteCount > XIICPS_MAX_TRANSFER_SIZE) {
400 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
401 XIICPS_MAX_TRANSFER_SIZE);
402 ByteCount = XIICPS_MAX_TRANSFER_SIZE;
405 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
410 * Intrs keeps all the error-related interrupts.
412 Intrs = XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_RX_OVR_MASK |
413 XIICPS_IXR_RX_UNF_MASK | XIICPS_IXR_NACK_MASK;
416 * Poll the interrupt status register to find the errors.
418 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
419 while ((InstancePtr->RecvByteCount > 0) &&
420 ((IntrStatusReg & Intrs) == 0)) {
421 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
423 while (StatusReg & XIICPS_SR_RXDV_MASK) {
424 if ((InstancePtr->RecvByteCount <
425 XIICPS_DATA_INTR_DEPTH) && IsHold &&
426 (!(InstancePtr->IsRepeatedStart))) {
428 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
429 XIicPs_ReadReg(BaseAddr,
431 (~XIICPS_CR_HOLD_MASK));
433 XIicPs_RecvByte(InstancePtr);
437 (ByteCount == XIICPS_FIFO_DEPTH + 1))
440 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
443 if (UpdateTxSize && (ByteCount == XIICPS_FIFO_DEPTH + 1)) {
445 * wait while fifo is full
447 while(XIicPs_ReadReg(BaseAddr,
448 XIICPS_TRANS_SIZE_OFFSET) !=
449 (ByteCount - XIICPS_FIFO_DEPTH));
451 if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
452 XIICPS_MAX_TRANSFER_SIZE) {
454 XIicPs_WriteReg(BaseAddr,
455 XIICPS_TRANS_SIZE_OFFSET,
456 XIICPS_MAX_TRANSFER_SIZE);
457 ByteCount = XIICPS_MAX_TRANSFER_SIZE +
460 XIicPs_WriteReg(BaseAddr,
461 XIICPS_TRANS_SIZE_OFFSET,
462 InstancePtr->RecvByteCount -
465 ByteCount = InstancePtr->RecvByteCount;
469 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
472 if (!(InstancePtr->IsRepeatedStart)) {
473 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
474 XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
475 (~XIICPS_CR_HOLD_MASK));
478 if (IntrStatusReg & Intrs) {
485 /*****************************************************************************/
487 * This function enables the slave monitor mode.
489 * It enables slave monitor in the control register and enables
490 * slave ready interrupt. It then does an address transfer to slave.
491 * Interrupt handler will signal the caller if slave responds to
492 * the address transfer.
494 * @param InstancePtr is a pointer to the XIicPs instance.
495 * @param SlaveAddr is the address of the slave we want to contact.
501 ****************************************************************************/
502 void XIicPs_EnableSlaveMonitor(XIicPs *InstancePtr, u16 SlaveAddr)
506 Xil_AssertVoid(InstancePtr != NULL);
508 BaseAddr = InstancePtr->Config.BaseAddress;
511 * Enable slave monitor mode in control register.
513 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
514 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
517 XIICPS_CR_SLVMON_MASK );
520 * Set up interrupt flag for slave monitor interrupt.
522 XIicPs_EnableInterrupts(BaseAddr, XIICPS_IXR_NACK_MASK |
523 XIICPS_IXR_SLV_RDY_MASK);
526 * Initialize the slave monitor register.
528 XIicPs_WriteReg(BaseAddr, XIICPS_SLV_PAUSE_OFFSET, 0xF);
531 * Set the slave address to start the slave address transmission.
533 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
538 /*****************************************************************************/
540 * This function disables slave monitor mode.
542 * @param InstancePtr is a pointer to the XIicPs instance.
548 ****************************************************************************/
549 void XIicPs_DisableSlaveMonitor(XIicPs *InstancePtr)
553 Xil_AssertVoid(InstancePtr != NULL);
555 BaseAddr = InstancePtr->Config.BaseAddress;
558 * Clear slave monitor control bit.
560 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
561 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET)
562 & (~XIICPS_CR_SLVMON_MASK));
565 * Clear interrupt flag for slave monitor interrupt.
567 XIicPs_DisableInterrupts(BaseAddr, XIICPS_IXR_SLV_RDY_MASK);
572 /*****************************************************************************/
574 * The interrupt handler for the master mode. It does the protocol handling for
575 * the interrupt-driven transfers.
577 * Completion events and errors are signaled to upper layer for proper handling.
580 * The interrupts that are handled are:
582 * This case is handled only for master receive data.
583 * The master has to request for more data (if there is more data to
584 * receive) and read the data from the FIFO .
587 * If the Master is transmitting data and there is more data to be
588 * sent then the data is written to the FIFO. If there is no more data to
589 * be transmitted then a completion event is signalled to the upper layer
590 * by calling the callback handler.
592 * If the Master is receiving data then the data is read from the FIFO and
593 * the Master has to request for more data (if there is more data to
594 * receive). If all the data has been received then a completion event
595 * is signalled to the upper layer by calling the callback handler.
596 * It is an error if the amount of received data is more than expected.
598 * - NAK and SLAVE_RDY
599 * This is signalled to the upper layer by calling the callback handler.
601 * - All Other interrupts
602 * These interrupts are marked as error. This is signalled to the upper
603 * layer by calling the callback handler.
607 * @param InstancePtr is a pointer to the XIicPs instance.
613 ****************************************************************************/
614 void XIicPs_MasterInterruptHandler(XIicPs *InstancePtr)
623 * Assert validates the input arguments.
625 Xil_AssertVoid(InstancePtr != NULL);
626 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
628 BaseAddr = InstancePtr->Config.BaseAddress;
631 * Read the Interrupt status register.
633 IntrStatusReg = XIicPs_ReadReg(BaseAddr,
637 * Write the status back to clear the interrupts so no events are
638 * missed while processing this interrupt.
640 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
643 * Use the Mask register AND with the Interrupt Status register so
644 * disabled interrupts are not processed.
646 IntrStatusReg &= ~(XIicPs_ReadReg(BaseAddr, XIICPS_IMR_OFFSET));
648 ByteCnt = InstancePtr->CurrByteCount;
651 if (XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) & XIICPS_CR_HOLD_MASK) {
658 if ((InstancePtr->IsSend) &&
659 (0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) {
660 if (InstancePtr->SendByteCount > 0) {
661 MasterSendData(InstancePtr);
663 StatusEvent |= XIICPS_EVENT_COMPLETE_SEND;
671 if ((!(InstancePtr->IsSend)) &&
672 ((0 != (IntrStatusReg & XIICPS_IXR_DATA_MASK)) ||
673 (0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK)))){
675 while (XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET) &
676 XIICPS_SR_RXDV_MASK) {
677 if ((InstancePtr->RecvByteCount <
678 XIICPS_DATA_INTR_DEPTH) && IsHold &&
679 (!(InstancePtr->IsRepeatedStart))) {
681 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
682 XIicPs_ReadReg(BaseAddr,
684 (~XIICPS_CR_HOLD_MASK));
686 XIicPs_RecvByte(InstancePtr);
689 if (InstancePtr->UpdateTxSize &&
690 (ByteCnt == XIICPS_FIFO_DEPTH + 1))
694 if (InstancePtr->UpdateTxSize &&
695 (ByteCnt == XIICPS_FIFO_DEPTH + 1)) {
697 * wait while fifo is full
699 while(XIicPs_ReadReg(BaseAddr,
700 XIICPS_TRANS_SIZE_OFFSET) !=
701 (ByteCnt - XIICPS_FIFO_DEPTH));
703 if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
704 XIICPS_MAX_TRANSFER_SIZE) {
706 XIicPs_WriteReg(BaseAddr,
707 XIICPS_TRANS_SIZE_OFFSET,
708 XIICPS_MAX_TRANSFER_SIZE);
709 ByteCnt = XIICPS_MAX_TRANSFER_SIZE +
712 XIicPs_WriteReg(BaseAddr,
713 XIICPS_TRANS_SIZE_OFFSET,
714 InstancePtr->RecvByteCount -
716 InstancePtr->UpdateTxSize = 0;
717 ByteCnt = InstancePtr->RecvByteCount;
720 InstancePtr->CurrByteCount = ByteCnt;
723 if ((!(InstancePtr->IsSend)) &&
724 (0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) {
726 * If all done, tell the application.
728 if (InstancePtr->RecvByteCount == 0){
729 if (!(InstancePtr->IsRepeatedStart)) {
730 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
731 XIicPs_ReadReg(BaseAddr,
733 (~XIICPS_CR_HOLD_MASK));
735 StatusEvent |= XIICPS_EVENT_COMPLETE_RECV;
741 * Slave ready interrupt, it is only meaningful for master mode.
743 if (0 != (IntrStatusReg & XIICPS_IXR_SLV_RDY_MASK)) {
744 StatusEvent |= XIICPS_EVENT_SLAVE_RDY;
747 if (0 != (IntrStatusReg & XIICPS_IXR_NACK_MASK)) {
748 if (!(InstancePtr->IsRepeatedStart)) {
749 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
750 XIicPs_ReadReg(BaseAddr,
752 (~XIICPS_CR_HOLD_MASK));
754 StatusEvent |= XIICPS_EVENT_NACK;
758 * All other interrupts are treated as error.
760 if (0 != (IntrStatusReg & (XIICPS_IXR_NACK_MASK |
761 XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_RX_UNF_MASK |
762 XIICPS_IXR_TX_OVR_MASK | XIICPS_IXR_RX_OVR_MASK))) {
763 if (!(InstancePtr->IsRepeatedStart)) {
764 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
765 XIicPs_ReadReg(BaseAddr,
767 (~XIICPS_CR_HOLD_MASK));
769 StatusEvent |= XIICPS_EVENT_ERROR;
773 * Signal application if there are any events.
775 if (0 != StatusEvent) {
776 InstancePtr->StatusHandler(InstancePtr->CallBackRef,
782 /*****************************************************************************/
784 * This function prepares a device to transfers as a master.
786 * @param InstancePtr is a pointer to the XIicPs instance.
788 * @param Role specifies whether the device is sending or receiving.
791 * - XST_SUCCESS if everything went well.
792 * - XST_FAILURE if bus is busy.
794 * @note Interrupts are always disabled, device which needs to use
795 * interrupts needs to setup interrupts after this call.
797 ****************************************************************************/
798 static int XIicPs_SetupMaster(XIicPs *InstancePtr, int Role)
802 u32 EnabledIntr = 0x0;
804 Xil_AssertNonvoid(InstancePtr != NULL);
806 BaseAddr = InstancePtr->Config.BaseAddress;
807 ControlReg = XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET);
811 * Only check if bus is busy when repeated start option is not set.
813 if ((ControlReg & XIICPS_CR_HOLD_MASK) == 0) {
814 if (XIicPs_BusIsBusy(InstancePtr)) {
820 * Set up master, AckEn, nea and also clear fifo.
822 ControlReg |= XIICPS_CR_ACKEN_MASK | XIICPS_CR_CLR_FIFO_MASK |
823 XIICPS_CR_NEA_MASK | XIICPS_CR_MS_MASK;
825 if (Role == RECVING_ROLE) {
826 ControlReg |= XIICPS_CR_RD_WR_MASK;
827 EnabledIntr = XIICPS_IXR_DATA_MASK |XIICPS_IXR_RX_OVR_MASK;
829 ControlReg &= ~XIICPS_CR_RD_WR_MASK;
831 EnabledIntr |= XIICPS_IXR_COMP_MASK | XIICPS_IXR_ARB_LOST_MASK;
833 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, ControlReg);
835 XIicPs_DisableAllInterrupts(BaseAddr);
840 /*****************************************************************************/
842 * This function handles continuation of sending data. It is invoked
843 * from interrupt handler.
845 * @param InstancePtr is a pointer to the XIicPs instance.
851 ****************************************************************************/
852 static void MasterSendData(XIicPs *InstancePtr)
854 TransmitFifoFill(InstancePtr);
857 * Clear hold bit if done, so stop can be sent out.
859 if (InstancePtr->SendByteCount == 0) {
862 * If user has enabled repeated start as an option,
865 if (!(InstancePtr->IsRepeatedStart)) {
867 XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
869 XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
870 XIICPS_CR_OFFSET) & ~ XIICPS_CR_HOLD_MASK);