1 /******************************************************************************
3 * (c) Copyright 2010-2014 Xilinx, Inc. All rights reserved.
5 * This file contains confidential and proprietary information of Xilinx, Inc.
6 * and is protected under U.S. and international copyright and other
7 * intellectual property laws.
10 * This disclaimer is not a license and does not grant any rights to the
11 * materials distributed herewith. Except as otherwise provided in a valid
12 * license issued to you by Xilinx, and to the maximum extent permitted by
13 * applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
14 * FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
15 * IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
16 * MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
17 * and (2) Xilinx shall not be liable (whether in contract or tort, including
18 * negligence, or under any other theory of liability) for any loss or damage
19 * of any kind or nature related to, arising under or in connection with these
20 * materials, including for any direct, or any indirect, special, incidental,
21 * or consequential loss or damage (including loss of data, profits, goodwill,
22 * or any type of loss or damage suffered as a result of any action brought by
23 * a third party) even if such damage or loss was reasonably foreseeable or
24 * Xilinx had been advised of the possibility of the same.
26 * CRITICAL APPLICATIONS
27 * Xilinx products are not designed or intended to be fail-safe, or for use in
28 * any application requiring fail-safe performance, such as life-support or
29 * safety devices or systems, Class III medical devices, nuclear facilities,
30 * applications related to the deployment of airbags, or any other applications
31 * that could lead to death, personal injury, or severe property or
32 * environmental damage (individually and collectively, "Critical
33 * Applications"). Customer assumes the sole risk and liability of any use of
34 * Xilinx products in Critical Applications, subject only to applicable laws
35 * and regulations governing limitations on product liability.
37 * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
40 ******************************************************************************/
41 /*****************************************************************************/
44 * @file xiicps_master.c
46 * Handles master mode transfers.
48 * <pre> MODIFICATION HISTORY:
50 * Ver Who Date Changes
51 * ----- --- -------- ---------------------------------------------
52 * 1.00a jz 01/30/10 First release
53 * 1.00a sdm 09/21/11 Updated the XIicPs_SetupMaster to not check for
54 * Bus Busy condition when the Hold Bit is set.
55 * 1.01a sg 03/30/12 Fixed an issue in XIicPs_MasterSendPolled where a
56 * check for transfer completion is added, which indicates
57 * the completion of current transfer.
58 * 2.0 hk 03/07/14 Added check for error status in the while loop that
59 * checks for completion. CR# 762244, 764875.
60 * 2.1 hk 04/24/14 Fix for CR# 789821 to handle >14 byte transfers.
61 * Fix for CR# 761060 - provision for repeated start.
65 ******************************************************************************/
67 /***************************** Include Files *********************************/
71 /************************** Constant Definitions *****************************/
73 /**************************** Type Definitions *******************************/
75 /***************** Macros (Inline Functions) Definitions *********************/
77 /************************** Function Prototypes ******************************/
78 int TransmitFifoFill(XIicPs *InstancePtr);
80 static int XIicPs_SetupMaster(XIicPs *InstancePtr, int Role);
81 static void MasterSendData(XIicPs *InstancePtr);
83 /************************* Variable Definitions *****************************/
85 /*****************************************************************************/
87 * This function initiates an interrupt-driven send in master mode.
89 * It tries to send the first FIFO-full of data, then lets the interrupt
90 * handler to handle the rest of the data if there is any.
92 * @param InstancePtr is a pointer to the XIicPs instance.
93 * @param MsgPtr is the pointer to the send buffer.
94 * @param ByteCount is the number of bytes to be sent.
95 * @param SlaveAddr is the address of the slave we are sending to.
99 * @note This send routine is for interrupt-driven transfer only.
101 ****************************************************************************/
102 void XIicPs_MasterSend(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
108 * Assert validates the input arguments.
110 Xil_AssertVoid(InstancePtr != NULL);
111 Xil_AssertVoid(MsgPtr != NULL);
112 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
113 Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
116 BaseAddr = InstancePtr->Config.BaseAddress;
117 InstancePtr->SendBufferPtr = MsgPtr;
118 InstancePtr->SendByteCount = ByteCount;
119 InstancePtr->RecvBufferPtr = NULL;
120 InstancePtr->IsSend = 1;
123 * Set repeated start if sending more than FIFO of data.
125 if ((InstancePtr->IsRepeatedStart) ||
126 (ByteCount > XIICPS_FIFO_DEPTH)) {
127 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
128 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
129 XIICPS_CR_HOLD_MASK);
133 * Setup as a master sending role.
135 XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
138 * Do the address transfer to notify the slave.
140 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
142 TransmitFifoFill(InstancePtr);
144 XIicPs_EnableInterrupts(BaseAddr,
145 XIICPS_IXR_NACK_MASK | XIICPS_IXR_COMP_MASK |
146 XIICPS_IXR_ARB_LOST_MASK);
149 /*****************************************************************************/
151 * This function initiates an interrupt-driven receive in master mode.
153 * It sets the transfer size register so the slave can send data to us.
154 * The rest of the work is managed by interrupt handler.
156 * @param InstancePtr is a pointer to the XIicPs instance.
157 * @param MsgPtr is the pointer to the receive buffer.
158 * @param ByteCount is the number of bytes to be received.
159 * @param SlaveAddr is the address of the slave we are receiving from.
163 * @note This receive routine is for interrupt-driven transfer only.
165 ****************************************************************************/
166 void XIicPs_MasterRecv(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount,
172 * Assert validates the input arguments.
174 Xil_AssertVoid(InstancePtr != NULL);
175 Xil_AssertVoid(MsgPtr != NULL);
176 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
177 Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
179 BaseAddr = InstancePtr->Config.BaseAddress;
180 InstancePtr->RecvBufferPtr = MsgPtr;
181 InstancePtr->RecvByteCount = ByteCount;
182 InstancePtr->CurrByteCount = ByteCount;
183 InstancePtr->SendBufferPtr = NULL;
184 InstancePtr->IsSend = 0;
185 InstancePtr->UpdateTxSize = 0;
187 if ((ByteCount > XIICPS_DATA_INTR_DEPTH) ||
188 (InstancePtr->IsRepeatedStart))
190 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
191 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
192 XIICPS_CR_HOLD_MASK);
196 * Initialize for a master receiving role.
198 XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
201 * Do the address transfer to signal the slave.
203 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
206 * Setup the transfer size register so the slave knows how much
209 if (ByteCount > XIICPS_MAX_TRANSFER_SIZE) {
210 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
211 XIICPS_MAX_TRANSFER_SIZE);
212 InstancePtr->CurrByteCount = XIICPS_MAX_TRANSFER_SIZE;
213 InstancePtr->UpdateTxSize = 1;
215 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
219 XIicPs_EnableInterrupts(BaseAddr,
220 XIICPS_IXR_NACK_MASK | XIICPS_IXR_DATA_MASK |
221 XIICPS_IXR_RX_OVR_MASK | XIICPS_IXR_COMP_MASK |
222 XIICPS_IXR_ARB_LOST_MASK);
225 /*****************************************************************************/
227 * This function initiates a polled mode send in master mode.
229 * It sends data to the FIFO and waits for the slave to pick them up.
230 * If slave fails to remove data from FIFO, the send fails with
233 * @param InstancePtr is a pointer to the XIicPs instance.
234 * @param MsgPtr is the pointer to the send buffer.
235 * @param ByteCount is the number of bytes to be sent.
236 * @param SlaveAddr is the address of the slave we are sending to.
239 * - XST_SUCCESS if everything went well.
240 * - XST_FAILURE if timed out.
242 * @note This send routine is for polled mode transfer only.
244 ****************************************************************************/
245 int XIicPs_MasterSendPolled(XIicPs *InstancePtr, u8 *MsgPtr,
246 int ByteCount, u16 SlaveAddr)
254 * Assert validates the input arguments.
256 Xil_AssertNonvoid(InstancePtr != NULL);
257 Xil_AssertNonvoid(MsgPtr != NULL);
258 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
259 Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
261 BaseAddr = InstancePtr->Config.BaseAddress;
262 InstancePtr->SendBufferPtr = MsgPtr;
263 InstancePtr->SendByteCount = ByteCount;
265 if ((InstancePtr->IsRepeatedStart) ||
266 (ByteCount > XIICPS_FIFO_DEPTH)) {
267 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
268 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
269 XIICPS_CR_HOLD_MASK);
272 XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
274 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
277 * Intrs keeps all the error-related interrupts.
279 Intrs = XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_TX_OVR_MASK |
280 XIICPS_IXR_NACK_MASK;
283 * Clear the interrupt status register before use it to monitor.
285 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
286 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
289 * Transmit first FIFO full of data.
291 TransmitFifoFill(InstancePtr);
293 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
296 * Continue sending as long as there is more data and
297 * there are no errors.
299 while ((InstancePtr->SendByteCount > 0) &&
300 ((IntrStatusReg & Intrs) == 0)) {
301 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
304 * Wait until transmit FIFO is empty.
306 if ((StatusReg & XIICPS_SR_TXDV_MASK) != 0) {
307 IntrStatusReg = XIicPs_ReadReg(BaseAddr,
313 * Send more data out through transmit FIFO.
315 TransmitFifoFill(InstancePtr);
319 * Check for completion of transfer.
321 while ((IntrStatusReg & XIICPS_IXR_COMP_MASK) != XIICPS_IXR_COMP_MASK){
323 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
325 * If there is an error, tell the caller.
327 if ((IntrStatusReg & Intrs) != 0) {
332 if (!(InstancePtr->IsRepeatedStart)) {
333 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
334 XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
335 (~XIICPS_CR_HOLD_MASK));
341 /*****************************************************************************/
343 * This function initiates a polled mode receive in master mode.
345 * It repeatedly sets the transfer size register so the slave can
346 * send data to us. It polls the data register for data to come in.
347 * If slave fails to send us data, it fails with time out.
349 * @param InstancePtr is a pointer to the XIicPs instance.
350 * @param MsgPtr is the pointer to the receive buffer.
351 * @param ByteCount is the number of bytes to be received.
352 * @param SlaveAddr is the address of the slave we are receiving from.
355 * - XST_SUCCESS if everything went well.
356 * - XST_FAILURE if timed out.
358 * @note This receive routine is for polled mode transfer only.
360 ****************************************************************************/
361 int XIicPs_MasterRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr,
362 int ByteCount, u16 SlaveAddr)
369 int UpdateTxSize = 0;
372 * Assert validates the input arguments.
374 Xil_AssertNonvoid(InstancePtr != NULL);
375 Xil_AssertNonvoid(MsgPtr != NULL);
376 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
377 Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
379 BaseAddr = InstancePtr->Config.BaseAddress;
380 InstancePtr->RecvBufferPtr = MsgPtr;
381 InstancePtr->RecvByteCount = ByteCount;
383 if((ByteCount > XIICPS_DATA_INTR_DEPTH) ||
384 (InstancePtr->IsRepeatedStart))
386 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
387 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
388 XIICPS_CR_HOLD_MASK);
392 XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
395 * Clear the interrupt status register before use it to monitor.
397 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
398 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
400 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
403 * Set up the transfer size register so the slave knows how much
406 if (ByteCount > XIICPS_MAX_TRANSFER_SIZE) {
407 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
408 XIICPS_MAX_TRANSFER_SIZE);
409 ByteCount = XIICPS_MAX_TRANSFER_SIZE;
412 XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
417 * Intrs keeps all the error-related interrupts.
419 Intrs = XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_RX_OVR_MASK |
420 XIICPS_IXR_RX_UNF_MASK | XIICPS_IXR_NACK_MASK;
423 * Poll the interrupt status register to find the errors.
425 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
426 while ((InstancePtr->RecvByteCount > 0) &&
427 ((IntrStatusReg & Intrs) == 0)) {
428 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
430 while (StatusReg & XIICPS_SR_RXDV_MASK) {
431 if ((InstancePtr->RecvByteCount <
432 XIICPS_DATA_INTR_DEPTH) && IsHold &&
433 (!(InstancePtr->IsRepeatedStart))) {
435 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
436 XIicPs_ReadReg(BaseAddr,
438 (~XIICPS_CR_HOLD_MASK));
440 XIicPs_RecvByte(InstancePtr);
444 (ByteCount == XIICPS_FIFO_DEPTH + 1))
447 StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
450 if (UpdateTxSize && (ByteCount == XIICPS_FIFO_DEPTH + 1)) {
452 * wait while fifo is full
454 while(XIicPs_ReadReg(BaseAddr,
455 XIICPS_TRANS_SIZE_OFFSET) !=
456 (ByteCount - XIICPS_FIFO_DEPTH));
458 if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
459 XIICPS_MAX_TRANSFER_SIZE) {
461 XIicPs_WriteReg(BaseAddr,
462 XIICPS_TRANS_SIZE_OFFSET,
463 XIICPS_MAX_TRANSFER_SIZE);
464 ByteCount = XIICPS_MAX_TRANSFER_SIZE +
467 XIicPs_WriteReg(BaseAddr,
468 XIICPS_TRANS_SIZE_OFFSET,
469 InstancePtr->RecvByteCount -
472 ByteCount = InstancePtr->RecvByteCount;
476 IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
479 if (!(InstancePtr->IsRepeatedStart)) {
480 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
481 XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
482 (~XIICPS_CR_HOLD_MASK));
485 if (IntrStatusReg & Intrs) {
492 /*****************************************************************************/
494 * This function enables the slave monitor mode.
496 * It enables slave monitor in the control register and enables
497 * slave ready interrupt. It then does an address transfer to slave.
498 * Interrupt handler will signal the caller if slave responds to
499 * the address transfer.
501 * @param InstancePtr is a pointer to the XIicPs instance.
502 * @param SlaveAddr is the address of the slave we want to contact.
508 ****************************************************************************/
509 void XIicPs_EnableSlaveMonitor(XIicPs *InstancePtr, u16 SlaveAddr)
513 Xil_AssertVoid(InstancePtr != NULL);
515 BaseAddr = InstancePtr->Config.BaseAddress;
518 * Enable slave monitor mode in control register.
520 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
521 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) |
524 XIICPS_CR_SLVMON_MASK );
527 * Set up interrupt flag for slave monitor interrupt.
529 XIicPs_EnableInterrupts(BaseAddr, XIICPS_IXR_NACK_MASK |
530 XIICPS_IXR_SLV_RDY_MASK);
533 * Initialize the slave monitor register.
535 XIicPs_WriteReg(BaseAddr, XIICPS_SLV_PAUSE_OFFSET, 0xF);
538 * Set the slave address to start the slave address transmission.
540 XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
545 /*****************************************************************************/
547 * This function disables slave monitor mode.
549 * @param InstancePtr is a pointer to the XIicPs instance.
555 ****************************************************************************/
556 void XIicPs_DisableSlaveMonitor(XIicPs *InstancePtr)
560 Xil_AssertVoid(InstancePtr != NULL);
562 BaseAddr = InstancePtr->Config.BaseAddress;
565 * Clear slave monitor control bit.
567 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
568 XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET)
569 & (~XIICPS_CR_SLVMON_MASK));
572 * Clear interrupt flag for slave monitor interrupt.
574 XIicPs_DisableInterrupts(BaseAddr, XIICPS_IXR_SLV_RDY_MASK);
579 /*****************************************************************************/
581 * The interrupt handler for the master mode. It does the protocol handling for
582 * the interrupt-driven transfers.
584 * Completion events and errors are signaled to upper layer for proper handling.
587 * The interrupts that are handled are:
589 * This case is handled only for master receive data.
590 * The master has to request for more data (if there is more data to
591 * receive) and read the data from the FIFO .
594 * If the Master is transmitting data and there is more data to be
595 * sent then the data is written to the FIFO. If there is no more data to
596 * be transmitted then a completion event is signalled to the upper layer
597 * by calling the callback handler.
599 * If the Master is receiving data then the data is read from the FIFO and
600 * the Master has to request for more data (if there is more data to
601 * receive). If all the data has been received then a completion event
602 * is signalled to the upper layer by calling the callback handler.
603 * It is an error if the amount of received data is more than expected.
605 * - NAK and SLAVE_RDY
606 * This is signalled to the upper layer by calling the callback handler.
608 * - All Other interrupts
609 * These interrupts are marked as error. This is signalled to the upper
610 * layer by calling the callback handler.
614 * @param InstancePtr is a pointer to the XIicPs instance.
620 ****************************************************************************/
621 void XIicPs_MasterInterruptHandler(XIicPs *InstancePtr)
630 * Assert validates the input arguments.
632 Xil_AssertVoid(InstancePtr != NULL);
633 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
635 BaseAddr = InstancePtr->Config.BaseAddress;
638 * Read the Interrupt status register.
640 IntrStatusReg = XIicPs_ReadReg(BaseAddr,
644 * Write the status back to clear the interrupts so no events are
645 * missed while processing this interrupt.
647 XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
650 * Use the Mask register AND with the Interrupt Status register so
651 * disabled interrupts are not processed.
653 IntrStatusReg &= ~(XIicPs_ReadReg(BaseAddr, XIICPS_IMR_OFFSET));
655 ByteCnt = InstancePtr->CurrByteCount;
658 if (XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) & XIICPS_CR_HOLD_MASK) {
665 if ((InstancePtr->IsSend) &&
666 (0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) {
667 if (InstancePtr->SendByteCount > 0) {
668 MasterSendData(InstancePtr);
670 StatusEvent |= XIICPS_EVENT_COMPLETE_SEND;
678 if ((!(InstancePtr->IsSend)) &&
679 ((0 != (IntrStatusReg & XIICPS_IXR_DATA_MASK)) ||
680 (0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK)))){
682 while (XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET) &
683 XIICPS_SR_RXDV_MASK) {
684 if ((InstancePtr->RecvByteCount <
685 XIICPS_DATA_INTR_DEPTH) && IsHold &&
686 (!(InstancePtr->IsRepeatedStart))) {
688 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
689 XIicPs_ReadReg(BaseAddr,
691 (~XIICPS_CR_HOLD_MASK));
693 XIicPs_RecvByte(InstancePtr);
696 if (InstancePtr->UpdateTxSize &&
697 (ByteCnt == XIICPS_FIFO_DEPTH + 1))
701 if (InstancePtr->UpdateTxSize &&
702 (ByteCnt == XIICPS_FIFO_DEPTH + 1)) {
704 * wait while fifo is full
706 while(XIicPs_ReadReg(BaseAddr,
707 XIICPS_TRANS_SIZE_OFFSET) !=
708 (ByteCnt - XIICPS_FIFO_DEPTH));
710 if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
711 XIICPS_MAX_TRANSFER_SIZE) {
713 XIicPs_WriteReg(BaseAddr,
714 XIICPS_TRANS_SIZE_OFFSET,
715 XIICPS_MAX_TRANSFER_SIZE);
716 ByteCnt = XIICPS_MAX_TRANSFER_SIZE +
719 XIicPs_WriteReg(BaseAddr,
720 XIICPS_TRANS_SIZE_OFFSET,
721 InstancePtr->RecvByteCount -
723 InstancePtr->UpdateTxSize = 0;
724 ByteCnt = InstancePtr->RecvByteCount;
727 InstancePtr->CurrByteCount = ByteCnt;
730 if ((!(InstancePtr->IsSend)) &&
731 (0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) {
733 * If all done, tell the application.
735 if (InstancePtr->RecvByteCount == 0){
736 if (!(InstancePtr->IsRepeatedStart)) {
737 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
738 XIicPs_ReadReg(BaseAddr,
740 (~XIICPS_CR_HOLD_MASK));
742 StatusEvent |= XIICPS_EVENT_COMPLETE_RECV;
748 * Slave ready interrupt, it is only meaningful for master mode.
750 if (0 != (IntrStatusReg & XIICPS_IXR_SLV_RDY_MASK)) {
751 StatusEvent |= XIICPS_EVENT_SLAVE_RDY;
754 if (0 != (IntrStatusReg & XIICPS_IXR_NACK_MASK)) {
755 if (!(InstancePtr->IsRepeatedStart)) {
756 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
757 XIicPs_ReadReg(BaseAddr,
759 (~XIICPS_CR_HOLD_MASK));
761 StatusEvent |= XIICPS_EVENT_NACK;
765 * All other interrupts are treated as error.
767 if (0 != (IntrStatusReg & (XIICPS_IXR_NACK_MASK |
768 XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_RX_UNF_MASK |
769 XIICPS_IXR_TX_OVR_MASK | XIICPS_IXR_RX_OVR_MASK))) {
770 if (!(InstancePtr->IsRepeatedStart)) {
771 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
772 XIicPs_ReadReg(BaseAddr,
774 (~XIICPS_CR_HOLD_MASK));
776 StatusEvent |= XIICPS_EVENT_ERROR;
780 * Signal application if there are any events.
782 if (0 != StatusEvent) {
783 InstancePtr->StatusHandler(InstancePtr->CallBackRef,
789 /*****************************************************************************/
791 * This function prepares a device to transfers as a master.
793 * @param InstancePtr is a pointer to the XIicPs instance.
795 * @param Role specifies whether the device is sending or receiving.
798 * - XST_SUCCESS if everything went well.
799 * - XST_FAILURE if bus is busy.
801 * @note Interrupts are always disabled, device which needs to use
802 * interrupts needs to setup interrupts after this call.
804 ****************************************************************************/
805 static int XIicPs_SetupMaster(XIicPs *InstancePtr, int Role)
809 u32 EnabledIntr = 0x0;
811 Xil_AssertNonvoid(InstancePtr != NULL);
813 BaseAddr = InstancePtr->Config.BaseAddress;
814 ControlReg = XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET);
818 * Only check if bus is busy when repeated start option is not set.
820 if ((ControlReg & XIICPS_CR_HOLD_MASK) == 0) {
821 if (XIicPs_BusIsBusy(InstancePtr)) {
827 * Set up master, AckEn, nea and also clear fifo.
829 ControlReg |= XIICPS_CR_ACKEN_MASK | XIICPS_CR_CLR_FIFO_MASK |
830 XIICPS_CR_NEA_MASK | XIICPS_CR_MS_MASK;
832 if (Role == RECVING_ROLE) {
833 ControlReg |= XIICPS_CR_RD_WR_MASK;
834 EnabledIntr = XIICPS_IXR_DATA_MASK |XIICPS_IXR_RX_OVR_MASK;
836 ControlReg &= ~XIICPS_CR_RD_WR_MASK;
838 EnabledIntr |= XIICPS_IXR_COMP_MASK | XIICPS_IXR_ARB_LOST_MASK;
840 XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, ControlReg);
842 XIicPs_DisableAllInterrupts(BaseAddr);
847 /*****************************************************************************/
849 * This function handles continuation of sending data. It is invoked
850 * from interrupt handler.
852 * @param InstancePtr is a pointer to the XIicPs instance.
858 ****************************************************************************/
859 static void MasterSendData(XIicPs *InstancePtr)
861 TransmitFifoFill(InstancePtr);
864 * Clear hold bit if done, so stop can be sent out.
866 if (InstancePtr->SendByteCount == 0) {
869 * If user has enabled repeated start as an option,
872 if (!(InstancePtr->IsRepeatedStart)) {
874 XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
876 XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
877 XIICPS_CR_OFFSET) & ~ XIICPS_CR_HOLD_MASK);