1 /* $Id: xiic_master.c,v 1.1.1.1 2005/04/11 02:50:21 jack Exp $ */
2 /******************************************************************************
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
13 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
14 * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
15 * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
16 * XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
17 * FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR
18 * OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
19 * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
20 * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
21 * WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
22 * CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
23 * FITNESS FOR A PARTICULAR PURPOSE.
26 * Xilinx products are not intended for use in life support appliances,
27 * devices, or systems. Use in such applications is expressly prohibited.
30 * (c) Copyright 2002 Xilinx Inc.
31 * All rights reserved.
34 * You should have received a copy of the GNU General Public License along
35 * with this program; if not, write to the Free Software Foundation, Inc.,
36 * 675 Mass Ave, Cambridge, MA 02139, USA.
38 ******************************************************************************/
39 /*****************************************************************************/
44 * Contains master functions for the XIic component. This file is necessary to
45 * send or receive as a master on the IIC bus.
48 * MODIFICATION HISTORY:
50 * Ver Who Date Changes
51 * ----- --- ------- -----------------------------------------------
52 * 1.01b jhl 3/27/02 Reparitioned the driver
55 ****************************************************************************/
57 /***************************** Include Files *******************************/
63 /************************** Constant Definitions ***************************/
65 /**************************** Type Definitions *****************************/
67 /***************** Macros (Inline Functions) Definitions *******************/
69 /*****************************************************************************
71 * This macro includes master code such that master operations, sending
72 * and receiving data, may be used. This function hooks the master processing
73 * to the driver such that events are handled properly and allows master
74 * processing to be optional. It must be called before any functions which
75 * are contained in this file are called, such as after the driver is
82 ******************************************************************************/
83 #define XIIC_MASTER_INCLUDE \
85 XIic_RecvMasterFuncPtr = RecvMasterData; \
86 XIic_SendMasterFuncPtr = SendMasterData; \
89 /************************** Function Prototypes ****************************/
91 static void SendSlaveAddr(XIic * InstancePtr);
92 static void RecvMasterData(XIic * InstancePtr);
93 static void SendMasterData(XIic * InstancePtr);
94 static u32 IsBusBusy(XIic * InstancePtr);
96 /************************** Variable Definitions **************************/
98 /****************************************************************************/
100 * This function sends data as a master on the IIC bus. If the bus is busy, it
101 * will indicate so and then enable an interrupt such that the status handler
102 * will be called when the bus is no longer busy. The slave address which has
103 * been set with the XIic_SetAddress() function is the address to which the
104 * specific data is sent. Sending data on the bus performs a write operation.
106 * @param InstancePtr points to the Iic instance to be worked on.
107 * @param TxMsgPtr points to the data to be transmitted
108 * @param ByteCount is the number of message bytes to be sent
112 * - XST_SUCCESS indicates the message transmission has been initiated.
113 * - XST_IIC_BUS_BUSY indicates the bus was in use and that the BusNotBusy
114 * interrupt is enabled which will update the EventStatus when the bus is no
121 ******************************************************************************/
123 XIic_MasterSend(XIic * InstancePtr, u8 * TxMsgPtr, int ByteCount)
127 XIic_mEnterCriticalRegion(InstancePtr->BaseAddress);
129 /* Ensure that the master processing has been included such that events
130 * will be properly handled
135 * If the busy is busy, then exit the critical region and wait for the
136 * bus to not be busy, the function enables the bus not busy interrupt
138 if (IsBusBusy(InstancePtr)) {
139 XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
141 return XST_IIC_BUS_BUSY;
144 /* If it is already a master on the bus (repeated start), the direction was
145 * set to tx which is throttling bus. The control register needs to be set
146 * before putting data into the FIFO
148 CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
150 if (CntlReg & XIIC_CR_MSMS_MASK) {
151 CntlReg &= ~XIIC_CR_NO_ACK_MASK;
153 (XIIC_CR_DIR_IS_TX_MASK | XIIC_CR_REPEATED_START_MASK);
155 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
157 InstancePtr->Stats.RepeatedStarts++;
160 /* Save message state
162 InstancePtr->SendByteCount = ByteCount;
163 InstancePtr->SendBufferPtr = TxMsgPtr;
165 /* Put the address into the FIFO to be sent and indicate that the operation
166 * to be performed on the bus is a write operation, a general call address
167 * handled the same as a 7 bit address even if 10 bit address is selected
168 * Set the transmit address state to indicate the address has been sent
170 if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) &&
171 (InstancePtr->AddrOfSlave != 0)) {
172 XIic_mSend10BitAddrByte1(InstancePtr->AddrOfSlave,
173 XIIC_WRITE_OPERATION);
174 XIic_mSend10BitAddrByte2(InstancePtr->AddrOfSlave);
176 XIic_mSend7BitAddr(InstancePtr->AddrOfSlave,
177 XIIC_WRITE_OPERATION);
179 /* Set the transmit address state to indicate the address has been sent
180 * for communication with event driven processing
182 InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
184 /* Fill remaining available FIFO with message data
186 if (InstancePtr->SendByteCount > 1) {
187 XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
190 /* After filling fifo, if data yet to send > 1, enable Tx ½ empty interrupt
192 if (InstancePtr->SendByteCount > 1) {
193 XIic_mClearEnableIntr(InstancePtr->BaseAddress,
194 XIIC_INTR_TX_HALF_MASK);
197 /* Clear any pending Tx empty, Tx Error and then enable them.
199 XIic_mClearEnableIntr(InstancePtr->BaseAddress,
200 XIIC_INTR_TX_ERROR_MASK |
201 XIIC_INTR_TX_EMPTY_MASK);
203 /* When repeated start not used, MSMS must be set after putting data into
204 * transmit FIFO, start the transmitter
207 if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
208 CntlReg &= ~XIIC_CR_NO_ACK_MASK;
209 CntlReg |= XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK;
210 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
214 XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
219 /*****************************************************************************/
221 * This function receives data as a master from a slave device on the IIC bus.
222 * If the bus is busy, it will indicate so and then enable an interrupt such
223 * that the status handler will be called when the bus is no longer busy. The
224 * slave address which has been set with the XIic_SetAddress() function is the
225 * address from which data is received. Receiving data on the bus performs a
228 * @param InstancePtr is a pointer to the Iic instance to be worked on.
229 * @param RxMsgPtr is a pointer to the data to be transmitted
230 * @param ByteCount is the number of message bytes to be sent
234 * - XST_SUCCESS indicates the message reception processes has been initiated.
235 * - XST_IIC_BUS_BUSY indicates the bus was in use and that the BusNotBusy
236 * interrupt is enabled which will update the EventStatus when the bus is no
238 * - XST_IIC_GENERAL_CALL_ADDRESS indicates the slave address is set to the
239 * the general call address. This is not allowed for Master receive mode.
243 * The receive FIFO threshold is a zero based count such that 1 must be
244 * subtracted from the desired count to get the correct value. When receiving
245 * data it is also necessary to not receive the last byte with the prior bytes
246 * because the acknowledge must be setup before the last byte is received.
248 ******************************************************************************/
250 XIic_MasterRecv(XIic * InstancePtr, u8 * RxMsgPtr, int ByteCount)
255 /* If the slave address is zero (general call) the master can't perform
256 * receive operations, indicate an error
258 if (InstancePtr->AddrOfSlave == 0) {
259 return XST_IIC_GENERAL_CALL_ADDRESS;
262 XIic_mEnterCriticalRegion(InstancePtr->BaseAddress);
264 /* Ensure that the master processing has been included such that events
265 * will be properly handled
269 * If the busy is busy, then exit the critical region and wait for the
270 * bus to not be busy, the function enables the bus not busy interrupt
272 if (IsBusBusy(InstancePtr)) {
273 XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
275 return XST_IIC_BUS_BUSY;
278 /* Save message state for event driven processing
280 InstancePtr->RecvByteCount = ByteCount;
281 InstancePtr->RecvBufferPtr = RxMsgPtr;
283 /* Clear and enable Rx full interrupt if using 7 bit, If 10 bit, wait until
284 * last address byte sent incase arbitration gets lost while sending out
287 if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) == 0) {
288 XIic_mClearEnableIntr(InstancePtr->BaseAddress,
289 XIIC_INTR_RX_FULL_MASK);
292 /* If already a master on the bus, the direction was set by Rx Interrupt
293 * routine to tx which is throttling bus because during Rxing, Tx reg is
294 * empty = throttle. CR needs setting before putting data or the address
295 * written will go out as Tx instead of receive. Start Master Rx by setting
296 * CR Bits MSMS to Master and msg direction.
298 CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
300 if (CntlReg & XIIC_CR_MSMS_MASK) {
301 CntlReg |= XIIC_CR_REPEATED_START_MASK;
302 XIic_mSetControlRegister(InstancePtr, CntlReg, ByteCount);
304 InstancePtr->Stats.RepeatedStarts++; /* increment stats counts */
305 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
309 /* Set receive FIFO occupancy depth which must be done prior to writing the
310 * address in the FIFO because the transmitter will immediatedly start when
311 * in repeated start mode followed by the receiver such that the number of
312 * bytes to receive should be set 1st.
314 if (ByteCount == 1) {
317 if (ByteCount < IIC_RX_FIFO_DEPTH) {
318 Temp = ByteCount - 2;
320 Temp = IIC_RX_FIFO_DEPTH - 1;
323 XIo_Out8(InstancePtr->BaseAddress + XIIC_RFD_REG_OFFSET, Temp);
325 if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) {
326 /* Send the 1st and 2nd byte of the 10 bit address of a write
327 * operation, write because it's a 10 bit address
329 XIic_mSend10BitAddrByte1(InstancePtr->AddrOfSlave,
330 XIIC_WRITE_OPERATION);
331 XIic_mSend10BitAddrByte2(InstancePtr->AddrOfSlave);
333 /* Set flag to indicate the next byte of the address needs to be
334 * send, clear and enable tx empty interrupt
336 InstancePtr->TxAddrMode = XIIC_TX_ADDR_MSTR_RECV_MASK;
337 XIic_mClearEnableIntr(InstancePtr->BaseAddress,
338 XIIC_INTR_TX_EMPTY_MASK);
340 /* 7 bit slave address, send the address for a read operation
341 * and set the state to indicate the address has been sent
343 XIic_mSend7BitAddr(InstancePtr->AddrOfSlave,
344 XIIC_READ_OPERATION);
345 InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
348 /* Tx error is enabled incase the address (7 or 10) has no device to answer
349 * with Ack. When only one byte of data, must set NO ACK before address goes
350 * out therefore Tx error must not be enabled as it will go off immediately
351 * and the Rx full interrupt will be checked. If full, then the one byte
352 * was received and the Tx error will be disabled without sending an error
355 XIic_mClearEnableIntr(InstancePtr->BaseAddress,
356 XIIC_INTR_TX_ERROR_MASK);
358 /* When repeated start not used, MSMS gets set after putting data
359 * in Tx reg. Start Master Rx by setting CR Bits MSMS to Master and
362 if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
363 CntlReg |= XIIC_CR_MSMS_MASK;
364 XIic_mSetControlRegister(InstancePtr, CntlReg, ByteCount);
365 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
369 XIic_mExitCriticalRegion(InstancePtr->BaseAddress);
374 /*****************************************************************************
376 * This function checks to see if the IIC bus is busy. If so, it will enable
377 * the bus not busy interrupt such that the driver is notified when the bus
380 * @param InstancePtr points to the Iic instance to be worked on.
384 * - FALSE indicates the IIC bus is not busy.
385 * - TRUE indicates the bus was in use and that the BusNotBusy
386 * interrupt is enabled which will update the EventStatus when the bus is no
393 ******************************************************************************/
395 IsBusBusy(XIic * InstancePtr)
400 ControlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
401 StatusReg = XIo_In8(InstancePtr->BaseAddress + XIIC_SR_REG_OFFSET);
403 /* If this device is already master of the bus as when using the repeated
404 * start and the bus is busy setup to wait for it to not be busy
406 if (((ControlReg & XIIC_CR_MSMS_MASK) == 0) && /* not master */
407 (StatusReg & XIIC_SR_BUS_BUSY_MASK)) { /* is busy */
410 * This code has been temporarily removed because the interrupt is enabled
411 * but never disabled. Ultimately, this will be fixed by Xilinx, but removing
412 * this for now at least prevents continuous bus idle interrupts. SAA
414 /* The bus is busy, clear pending BNB interrupt incase previously set
415 * and then enable BusNotBusy interrupt
417 XIic_mClearEnableIntr(InstancePtr->BaseAddress,
419 InstancePtr->Stats.BusBusy++;
427 /******************************************************************************
429 * This function sends the proper byte of the address as well as generate the
430 * proper address bit fields depending on the address byte required and the
431 * direction of the data (write or read).
433 * A master receiving has the restriction that the direction must be switched
434 * from write to read when the third address byte is transmitted.
435 * For the last byte of the 10 bit address, repeated start must be set prior
436 * to writing the address. If repeated start options is enabled, the
437 * control register is written before the address is written to the tx reg.
439 * @param InstancePtr is a pointer to the XIic instance to be worked on.
447 * This function does read/modify/write to the device control register. Calling
448 * functions must ensure critical sections are used.
450 ******************************************************************************/
452 SendSlaveAddr(XIic * InstancePtr)
456 /* Set the control register for Master Receive, repeated start must be set
457 * before writing the address, MSMS should be already set, don't set here
458 * so if arbitration is lost or some other reason we don't want MSMS set
461 CRreg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
463 CRreg |= XIIC_CR_REPEATED_START_MASK;
464 CRreg &= ~XIIC_CR_DIR_IS_TX_MASK;
466 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET, CRreg);
468 /* Send the 1st byte of the 10 bit address as a read operation, enable the
469 * receive interrupt to know when data is received, assuming that the
470 * receive FIFO threshold has been previously set
472 XIic_mSend10BitAddrByte1(InstancePtr->AddrOfSlave, XIIC_READ_OPERATION);
474 XIic_mClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_RX_FULL_MASK);
477 /******************************************************************************
479 * When the IIC Tx FIFO/register goes empty, this routine is called by the
480 * interrupt service routine to fill the transmit FIFO with data to be sent.
482 * This function also is called by the Tx ½ empty interrupt as the data handling
483 * is identical when you don't assume the FIFO is empty but use the Tx_FIFO_OCY
484 * register to indicate the available free FIFO bytes.
486 * @param InstancePtr is a pointer to the XIic instance to be worked on.
496 ******************************************************************************/
498 SendMasterData(XIic * InstancePtr)
501 u32 MessageDone = FALSE;
503 CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
505 /* The device is a master on the bus. If there is still more address bytes
506 * to send when in master receive operation and the slave device is 10 bit
507 * addressed. This requires the lower 7 bits of address to be resent when
508 * the mode switches to Read instead of write (while sending addresses).
510 if (InstancePtr->TxAddrMode & XIIC_TX_ADDR_MSTR_RECV_MASK) {
511 /* Send the 1st byte of the slave address in the read operation
512 * and change the state to indicate this has been done
514 SendSlaveAddr(InstancePtr);
515 InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
518 /* In between 1st and last byte of message, fill the FIFO with more data
519 * to send, disable the 1/2 empty interrupt based upon data left to send
521 else if (InstancePtr->SendByteCount > 1) {
522 XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
524 if (InstancePtr->SendByteCount < 2) {
525 XIic_mDisableIntr(InstancePtr->BaseAddress,
526 XIIC_INTR_TX_HALF_MASK);
530 * If there is only one byte left to send, processing differs between
531 * repeated start and normal messages
533 else if (InstancePtr->SendByteCount == 1) {
534 /* When using repeated start, another interrupt is expected after the
535 * last byte has been sent, so the message is not done yet
537 if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
538 XIic_mWriteSendByte(InstancePtr);
541 /* When not using repeated start, the stop condition must be generated
542 * after the last byte is written. The bus is throttled waiting for the last
546 /* Set the stop condition before sending the last byte of data so that
547 * the stop condition will be generated immediately following the data
548 * another transmit interrupt is not expected so the message is done
550 CntlReg &= ~XIIC_CR_MSMS_MASK;
551 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
554 XIic_mWriteSendByte(InstancePtr);
558 /* The message being sent has completed. When using repeated start with
559 * no more bytes to send repeated start needs to be set in the control
560 * register so that the bus will still be held by this master
564 if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
565 CntlReg |= XIIC_CR_REPEATED_START_MASK;
566 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
571 /* If the message that was being sent has finished, disable all transmit
572 * interrupts and call the callbac that was setup to indicate the message
573 * was sent, with 0 bytes remaining
576 XIic_mDisableIntr(InstancePtr->BaseAddress, XIIC_TX_INTERRUPTS);
577 InstancePtr->SendHandler(InstancePtr->SendCallBackRef, 0);
582 /*****************************************************************************/
585 * This function is called when the receive register is full. The number
586 * of bytes received to cause the interrupt is adjustable using the Receive FIFO
587 * Depth register. The number of bytes in the register is read in the Receive
588 * FIFO occupancy register. Both these registers are zero based values (0-15)
589 * such that a value of zero indicates 1 byte.
591 * For a Master Receiver to properly signal the end of a message, the data must
592 * be read in up to the message length - 1, where control register bits will be
593 * set for bus controls to occur on reading of the last byte.
595 * @param InstancePtr is a pointer to the XIic instance to be worked on.
605 ******************************************************************************/
607 RecvMasterData(XIic * InstancePtr)
611 int BytesToRead; /* Changed from u8 to int to prevent overflow. SAA */
614 /* Device is a master receiving, get the contents of the control register
615 * and determine the number of bytes in fifo to be read out
617 CntlReg = XIo_In8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET);
618 BytesInFifo = XIo_In8(InstancePtr->BaseAddress + XIIC_RFO_REG_OFFSET)
621 /* If data in FIFO holds all data to be retrieved - 1, set NOACK and
622 * disable the tx error
624 if ((InstancePtr->RecvByteCount - BytesInFifo) == 1) {
625 /* Disable tx error interrupt to prevent interrupt
626 * as this device will cause it when it set NO ACK next
628 XIic_mDisableIntr(InstancePtr->BaseAddress,
629 XIIC_INTR_TX_ERROR_MASK);
630 XIic_mClearIntr(InstancePtr->BaseAddress,
631 XIIC_INTR_TX_ERROR_MASK);
633 /* Write control reg with NO ACK allowing last byte to
634 * have the No ack set to indicate to slave last byte read.
636 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
637 (CntlReg | XIIC_CR_NO_ACK_MASK));
639 /* Read one byte to clear a place for the last byte to be read
640 * which will set the NO ACK
642 XIic_mReadRecvByte(InstancePtr);
645 /* If data in FIFO is all the data to be received then get the data
646 * and also leave the device in a good state for the next transaction
648 else if ((InstancePtr->RecvByteCount - BytesInFifo) == 0) {
649 /* If repeated start option is off then the master should stop
650 * using the bus, otherwise hold the bus, setting repeated start
651 * stops the slave from transmitting data when the FIFO is read
653 if ((InstancePtr->Options & XII_REPEATED_START_OPTION) == 0) {
654 CntlReg &= ~XIIC_CR_MSMS_MASK;
656 CntlReg |= XIIC_CR_REPEATED_START_MASK;
658 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
661 /* Read data from the FIFO then set zero based FIFO read depth for a byte
663 for (LoopCnt = 0; LoopCnt < BytesInFifo; LoopCnt++) {
664 XIic_mReadRecvByte(InstancePtr);
666 XIo_Out8(InstancePtr->BaseAddress + XIIC_RFD_REG_OFFSET, 0);
668 /* Disable Rx full interrupt and write the control reg with ACK allowing
669 * next byte sent to be acknowledged automatically
671 XIic_mDisableIntr(InstancePtr->BaseAddress,
672 XIIC_INTR_RX_FULL_MASK);
674 XIo_Out8(InstancePtr->BaseAddress + XIIC_CR_REG_OFFSET,
675 (CntlReg & ~XIIC_CR_NO_ACK_MASK));
677 /* Send notification of msg Rx complete in RecvHandler callback
679 InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef, 0);
681 /* Fifo data not at n-1, read all but the last byte of data from the
682 * slave, if more than a FIFO full yet to receive read a FIFO full
684 BytesToRead = InstancePtr->RecvByteCount - BytesInFifo - 1;
685 if (BytesToRead > IIC_RX_FIFO_DEPTH) {
686 BytesToRead = IIC_RX_FIFO_DEPTH;
689 /* Read in data from the FIFO */
691 for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
692 XIic_mReadRecvByte(InstancePtr);