OpenCores
URL https://opencores.org/ocsvn/xenie/xenie/trunk

Subversion Repositories xenie

[/] [xenie/] [trunk/] [examples/] [Eth_example/] [mb_fw/] [drivers/] [iic_v3_4/] [src/] [xiic_master.c.bak] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 DFC
/******************************************************************************
2
*
3
* Copyright (C) 2002 - 2015 Xilinx, Inc.  All rights reserved.
4
*
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:
11
*
12
* The above copyright notice and this permission notice shall be included in
13
* all copies or substantial portions of the Software.
14
*
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.
18
*
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
25
* SOFTWARE.
26
*
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.
30
*
31
******************************************************************************/
32
/*****************************************************************************/
33
/**
34
*
35
* @file xiic_master.c
36
* @addtogroup iic_v3_1
37
* @{
38
*
39
* Contains master functions for the XIic component. This file is necessary to
40
* send or receive as a master on the IIC bus.
41
*
42
* 
43
* MODIFICATION HISTORY:
44
*
45
* Ver   Who  Date     Changes
46
* ----- --- ------- -----------------------------------------------
47
* 1.01b jhl 03/27/02 Reparitioned the driver
48
* 1.01c ecm 12/05/02 new rev
49
* 1.13a wgr 03/22/07 Converted to new coding style.
50
* 2.00a ktn 10/22/09 Converted all register accesses to 32 bit access.
51
*                    Updated to use the HAL APIs/macros.
52
*                    Removed the macro XIic_mEnterCriticalRegion,
53
*                    XIic_IntrGlobalDisable should be used in its place.
54
*                    Removed the macro XIic_mExitCriticalRegion,
55
*                    XIic_IntrGlobalEnable should be used in its place.
56
*                    Some of the macros have been renamed to remove _m from
57
*                    the name and some of the macros have been renamed to be
58
*                    consistent, see the xiic_i.h and xiic_l.h files for
59
*                    further information
60
* 2.05a bss 02/05/12 Assigned RecvBufferPtr in XIic_MasterSend API and
61
*                    SendBufferPtr in XIic_MasterRecv NULL
62
* 
63
*
64
****************************************************************************/
65
 
66
/***************************** Include Files *******************************/
67
 
68
#include "xiic.h"
69
#include "xiic_i.h"
70
 
71
/************************** Constant Definitions ***************************/
72
 
73
 
74
/**************************** Type Definitions *****************************/
75
 
76
 
77
/***************** Macros (Inline Functions) Definitions *******************/
78
 
79
/*****************************************************************************
80
*
81
* This macro includes master code such that master operations, sending
82
* and receiving data, may be used.  This function hooks the master processing
83
* to the driver such that events are handled properly and allows master
84
* processing to be optional.  It must be called before any functions which
85
* are contained in this file are called, such as after the driver is
86
* initialized.
87
*
88
* @param        None.
89
*
90
* @return       None.
91
*
92
* @note         None.
93
*
94
******************************************************************************/
95
#define XIIC_MASTER_INCLUDE                                             \
96
{                                                                       \
97
        XIic_RecvMasterFuncPtr = RecvMasterData;                        \
98
        XIic_SendMasterFuncPtr = SendMasterData;                        \
99
}
100
 
101
/************************** Function Prototypes ****************************/
102
 
103
static void SendSlaveAddr(XIic *InstancePtr);
104
static void RecvMasterData(XIic *InstancePtr);
105
static void SendMasterData(XIic *InstancePtr);
106
static int IsBusBusy(XIic *InstancePtr);
107
 
108
/************************** Variable Definitions **************************/
109
 
110
/****************************************************************************/
111
/**
112
* This function sends data as a master on the IIC bus. If the bus is busy, it
113
* will indicate so and then enable an interrupt such that the status handler
114
* will be called when the bus is no longer busy.  The slave address which has
115
* been set with the XIic_SetAddress() function is the address to which the
116
* specific data is sent.  Sending data on the bus performs a write operation.
117
*
118
* @param        InstancePtr points to the Iic instance to be worked on.
119
* @param        TxMsgPtr points to the data to be transmitted.
120
* @param        ByteCount is the number of message bytes to be sent.
121
*
122
* @return
123
*               - XST_SUCCESS indicates the message transmission has been
124
*               initiated.
125
*               - XST_IIC_BUS_BUSY indicates the bus was in use and that
126
*               the BusNotBusy interrupt is enabled which will update the
127
*               EventStatus when the bus is no longer busy.
128
*
129
* @note         None.
130
*
131
******************************************************************************/
132
int XIic_MasterSend(XIic *InstancePtr, u8 *TxMsgPtr, int ByteCount)
133
{
134
        u32 CntlReg;
135
 
136
        XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
137
 
138
        /*
139
         * Ensure that the master processing has been included such that events
140
         * will be properly handled.
141
         */
142
        XIIC_MASTER_INCLUDE;
143
        InstancePtr->IsDynamic = FALSE;
144
 
145
        /*
146
         * If the busy is busy, then exit the critical region and wait for the
147
         * bus to not be busy, the function enables the bus not busy interrupt.
148
         */
149
        if (IsBusBusy(InstancePtr)) {
150
                XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
151
 
152
                return XST_IIC_BUS_BUSY;
153
        }
154
 
155
        /*
156
         * If it is already a master on the bus (repeated start), the direction
157
         * was set to Tx which is throttling bus. The control register needs to
158
         * be set before putting data into the FIFO.
159
         */
160
        CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
161
        if (CntlReg & XIIC_CR_MSMS_MASK) {
162
                CntlReg &= ~XIIC_CR_NO_ACK_MASK;
163
                CntlReg |= (XIIC_CR_DIR_IS_TX_MASK |
164
                                XIIC_CR_REPEATED_START_MASK);
165
 
166
                XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
167
                                CntlReg);
168
                InstancePtr->Stats.RepeatedStarts++;
169
        }
170
 
171
        /*
172
         * Save message state.
173
         */
174
        InstancePtr->SendByteCount = ByteCount;
175
        InstancePtr->SendBufferPtr = TxMsgPtr;
176
        InstancePtr->RecvBufferPtr = NULL;
177
 
178
        /*
179
         * Put the address into the FIFO to be sent and indicate that the
180
         * operation to be performed on the bus is a write operation,
181
         * a general call address is handled the same as a 7 bit address even
182
         * if 10 bit address is selected.
183
         * Set the transmit address state to indicate the address has been sent.
184
         */
185
        if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) &&
186
                (InstancePtr->AddrOfSlave != 0)) {
187
                XIic_Send10BitAddrByte1(InstancePtr->AddrOfSlave,
188
                                         XIIC_WRITE_OPERATION);
189
                XIic_Send10BitAddrByte2(InstancePtr->AddrOfSlave);
190
        } else {
191
                XIic_Send7BitAddr(InstancePtr->AddrOfSlave,
192
                                   XIIC_WRITE_OPERATION);
193
        }
194
        /*
195
         * Set the transmit address state to indicate the address has been sent
196
         * for communication with event driven processing.
197
         */
198
        InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
199
 
200
        /*
201
         * Fill remaining available FIFO with message data.
202
         */
203
        if (InstancePtr->SendByteCount > 1) {
204
                XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
205
        }
206
 
207
        /*
208
         * After filling fifo, if data yet to send > 1, enable Tx � empty
209
         * interrupt.
210
         */
211
        if (InstancePtr->SendByteCount > 1) {
212
                XIic_ClearEnableIntr(InstancePtr->BaseAddress,
213
                                        XIIC_INTR_TX_HALF_MASK);
214
        }
215
 
216
        /*
217
         * Clear any pending Tx empty, Tx Error and then enable them.
218
         */
219
        XIic_ClearEnableIntr(InstancePtr->BaseAddress,
220
                                XIIC_INTR_TX_ERROR_MASK |
221
                                XIIC_INTR_TX_EMPTY_MASK);
222
 
223
        /*
224
         * When repeated start not used, MSMS must be set after putting data
225
         * into transmit FIFO, start the transmitter.
226
         */
227
        CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
228
        if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
229
                CntlReg &= ~XIIC_CR_NO_ACK_MASK;
230
                CntlReg |= XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK;
231
                XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
232
                         CntlReg);
233
        }
234
 
235
        XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
236
 
237
        return XST_SUCCESS;
238
}
239
 
240
/*****************************************************************************/
241
/**
242
* This function receives data as a master from a slave device on the IIC bus.
243
* If the bus is busy, it will indicate so and then enable an interrupt such
244
* that the status handler will be called when the bus is no longer busy.  The
245
* slave address which has been set with the XIic_SetAddress() function is the
246
* address from which data is received. Receiving data on the bus performs a
247
* read operation.
248
*
249
* @param        InstancePtr is a pointer to the Iic instance to be worked on.
250
* @param        RxMsgPtr is a pointer to the data to be transmitted
251
* @param        ByteCount is the number of message bytes to be sent
252
*
253
* @return
254
*               - XST_SUCCESS indicates the message reception processes has
255
*               been initiated.
256
*               - XST_IIC_BUS_BUSY indicates the bus was in use and that the
257
*               BusNotBusy interrupt is enabled which will update the
258
*               EventStatus when the bus is no longer busy.
259
*               - XST_IIC_GENERAL_CALL_ADDRESS indicates the slave address
260
*               is set to the the general call address. This is not allowed
261
*               for Master receive mode.
262
*
263
* @internal
264
*
265
* The receive FIFO threshold is a zero based count such that 1 must be
266
* subtracted from the desired count to get the correct value. When receiving
267
* data it is also necessary to not receive the last byte with the prior bytes
268
* because the acknowledge must be setup before the last byte is received.
269
*
270
******************************************************************************/
271
int XIic_MasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount)
272
{
273
        u32 CntlReg;
274
        u8 Temp;
275
 
276
        /*
277
         * If the slave address is zero (general call) the master can't perform
278
         * receive operations, indicate an error.
279
         */
280
        if (InstancePtr->AddrOfSlave == 0) {
281
                return XST_IIC_GENERAL_CALL_ADDRESS;
282
        }
283
 
284
        XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
285
 
286
        /*
287
         * Ensure that the master processing has been included such that events
288
         * will be properly handled.
289
         */
290
        XIIC_MASTER_INCLUDE;
291
        InstancePtr->IsDynamic = FALSE;
292
 
293
        /*
294
         * If the busy is busy, then exit the critical region and wait for the
295
         * bus to not be busy, the function enables the bus not busy interrupt.
296
         */
297
        if (IsBusBusy(InstancePtr)) {
298
                XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
299
 
300
                return XST_IIC_BUS_BUSY;
301
        }
302
 
303
        /*
304
         * Save message state for event driven processing.
305
         */
306
        InstancePtr->RecvByteCount = ByteCount;
307
        InstancePtr->RecvBufferPtr = RxMsgPtr;
308
        InstancePtr->SendBufferPtr = NULL;
309
 
310
        /*
311
         * Clear and enable Rx full interrupt if using 7 bit, If 10 bit, wait
312
         * until last address byte sent incase arbitration gets lost while
313
         * sending out address.
314
         */
315
        if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) == 0) {
316
                XIic_ClearEnableIntr(InstancePtr->BaseAddress,
317
                                        XIIC_INTR_RX_FULL_MASK);
318
        }
319
 
320
        /*
321
         * If already a master on the bus, the direction was set by Rx Interrupt
322
         * routine to Tx which is throttling bus because during Rxing, Tx reg is
323
         * empty = throttle. CR needs setting before putting data or the address
324
         * written will go out as Tx instead of receive. Start Master Rx by
325
         * setting CR Bits MSMS to Master and msg direction.
326
         */
327
        CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
328
 
329
        if (CntlReg & XIIC_CR_MSMS_MASK) {
330
                CntlReg |= XIIC_CR_REPEATED_START_MASK;
331
                XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);
332
 
333
                InstancePtr->Stats.RepeatedStarts++;
334
                XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
335
                         CntlReg);
336
 
337
        }
338
 
339
        /*
340
         * Set receive FIFO occupancy depth which must be done prior to writing
341
         * the address in the FIFO because the transmitter will immediatedly
342
         * start when in repeated start mode followed by the receiver such that
343
         * the number of  bytes to receive should be set 1st.
344
         */
345
        if (ByteCount == 1) {
346
                Temp = 0;
347
        } else {
348
                if (ByteCount <= IIC_RX_FIFO_DEPTH) {
349
                        Temp = ByteCount - 2;
350
                } else {
351
                        Temp = IIC_RX_FIFO_DEPTH - 1;
352
                }
353
        }
354
        XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET,
355
                        (u32) Temp);
356
 
357
        if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) {
358
                /*
359
                 * Send the 1st and 2nd byte of the 10 bit address of a write
360
                 * operation, write because it's a 10 bit address.
361
                 */
362
                XIic_Send10BitAddrByte1(InstancePtr->AddrOfSlave,
363
                                         XIIC_WRITE_OPERATION);
364
                XIic_Send10BitAddrByte2(InstancePtr->AddrOfSlave);
365
 
366
                /*
367
                 * Set flag to indicate the next byte of the address needs to be
368
                 * send, clear and enable Tx empty interrupt.
369
                 */
370
                InstancePtr->TxAddrMode = XIIC_TX_ADDR_MSTR_RECV_MASK;
371
                XIic_ClearEnableIntr(InstancePtr->BaseAddress,
372
                                        XIIC_INTR_TX_EMPTY_MASK);
373
        } else {
374
                /*
375
                 * 7 bit slave address, send the address for a read operation
376
                 * and set the state to indicate the address has been sent.
377
                 */
378
                XIic_Send7BitAddr(InstancePtr->AddrOfSlave,
379
                                   XIIC_READ_OPERATION);
380
                InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
381
        }
382
 
383
        /*
384
         * Tx error is enabled incase the address (7 or 10) has no device to
385
         * answer with Ack. When only one byte of data, must set NO ACK before
386
         * address goes out therefore Tx error must not be enabled as it will
387
         * go off immediately and the Rx full interrupt will be checked.
388
         * If full, then the one byte was received and the Tx error will be
389
         * disabled without sending an error callback msg.
390
         */
391
        XIic_ClearEnableIntr(InstancePtr->BaseAddress,
392
                                XIIC_INTR_TX_ERROR_MASK);
393
 
394
        /*
395
         * When repeated start not used, MSMS gets set after putting data
396
         * in Tx reg. Start Master Rx by setting CR Bits MSMS to Master and
397
         * msg direction.
398
         */
399
        CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
400
        if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
401
                CntlReg |= XIIC_CR_MSMS_MASK;
402
                XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);
403
                XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
404
                                CntlReg);
405
        }
406
 
407
        XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
408
 
409
        return XST_SUCCESS;
410
}
411
 
412
/*****************************************************************************
413
*
414
* This function checks to see if the IIC bus is busy.  If so, it will enable
415
* the bus not busy interrupt such that the driver is notified when the bus
416
* is no longer busy.
417
*
418
* @param        InstancePtr points to the Iic instance to be worked on.
419
*
420
* @return
421
*               - FALSE indicates the IIC bus is not busy.
422
*               - TRUE indicates the bus was in use and that the BusNotBusy
423
*               interrupt is enabled which will update the EventStatus when
424
*               the bus is no longer busy.
425
*
426
* @note         None.
427
*
428
******************************************************************************/
429
static int IsBusBusy(XIic *InstancePtr)
430
{
431
        u32 CntlReg;
432
        u32 StatusReg;
433
 
434
        CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
435
        StatusReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_SR_REG_OFFSET);
436
 
437
        /*
438
         * If this device is already master of the bus as when using the
439
         * repeated start and the bus is busy setup to wait for it to not be
440
         * busy.
441
         */
442
        if (((CntlReg & XIIC_CR_MSMS_MASK) == 0) &&     /* Not master */
443
                (StatusReg & XIIC_SR_BUS_BUSY_MASK)) {  /* Is busy */
444
                /*
445
                 * The bus is busy, clear pending BNB interrupt incase
446
                 * previously set and then enable BusNotBusy interrupt.
447
                 */
448
                InstancePtr->BNBOnly = TRUE;
449
                XIic_ClearEnableIntr(InstancePtr->BaseAddress,
450
                                        XIIC_INTR_BNB_MASK);
451
                InstancePtr->Stats.BusBusy++;
452
 
453
                return TRUE;
454
        }
455
 
456
        return FALSE;
457
}
458
 
459
/******************************************************************************
460
*
461
* This function sends the proper byte of the address as well as generate the
462
* proper address bit fields depending on the address byte required and the
463
* direction of the data (write or read).
464
*
465
* A master receiving has the restriction that the direction must be switched
466
* from write to read when the third address byte is transmitted.
467
* For the last byte of the 10 bit address, repeated start must be set prior
468
* to writing the address. If repeated start options is enabled, the
469
* control register is written before the address is written to the Tx reg.
470
*
471
* @param        InstancePtr is a pointer to the XIic instance to be worked on.
472
*
473
* @return       None.
474
*
475
* @note
476
*
477
* This function does read/modify/write to the device control register. Calling
478
* functions must ensure critical sections are used.
479
*
480
******************************************************************************/
481
static void SendSlaveAddr(XIic *InstancePtr)
482
{
483
        u32 CRreg;
484
 
485
        /*
486
         * Set the control register for Master Receive, repeated start must be
487
         * set before writing the address, MSMS should be already set, don't
488
         * set here so if arbitration is lost or some other reason we don't
489
         * want MSMS set incase of error.
490
         */
491
        CRreg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
492
 
493
        CRreg |= XIIC_CR_REPEATED_START_MASK;
494
        CRreg &= ~XIIC_CR_DIR_IS_TX_MASK;
495
 
496
        XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET, CRreg);
497
 
498
        /*
499
         * Send the 1st byte of the 10 bit address as a read operation, enable
500
         * the receive interrupt to know when data is received, assuming that
501
         * the receive FIFO threshold has been previously set.
502
         */
503
        XIic_Send10BitAddrByte1(InstancePtr->AddrOfSlave, XIIC_READ_OPERATION);
504
 
505
        XIic_ClearEnableIntr(InstancePtr->BaseAddress, XIIC_INTR_RX_FULL_MASK);
506
}
507
 
508
/******************************************************************************
509
*
510
* When the IIC Tx FIFO/register goes empty, this routine is called by the
511
* interrupt service routine to fill the transmit FIFO with data to be sent.
512
*
513
* This function also is called by the Tx � empty interrupt as the data handling
514
* is identical when you don't assume the FIFO is empty but use the Tx_FIFO_OCY
515
* register to indicate the available free FIFO bytes.
516
*
517
* @param        InstancePtr is a pointer to the XIic instance to be worked on.
518
*
519
* @return       None.
520
*
521
* @note         None.
522
*
523
******************************************************************************/
524
static void SendMasterData(XIic *InstancePtr)
525
{
526
        u32 CntlReg;
527
 
528
        /*
529
         * The device is a master on the bus.  If there is still more address
530
         * bytes to send when in master receive operation and the slave device
531
         * is 10 bit addressed.
532
         * This requires the lower 7 bits of address to be resent when the mode
533
         * switches to Read instead of write (while sending addresses).
534
         */
535
        if (InstancePtr->TxAddrMode & XIIC_TX_ADDR_MSTR_RECV_MASK) {
536
                /*
537
                 * Send the 1st byte of the slave address in the read operation
538
                 * and change the state to indicate this has been done
539
                 */
540
                SendSlaveAddr(InstancePtr);
541
                InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
542
        }
543
 
544
        /*
545
         * In between 1st and last byte of message, fill the FIFO with more data
546
         * to send, disable the 1/2 empty interrupt based upon data left to
547
         * send.
548
         */
549
        else if (InstancePtr->SendByteCount > 1) {
550
                XIic_TransmitFifoFill(InstancePtr, XIIC_MASTER_ROLE);
551
 
552
                if (InstancePtr->SendByteCount < 2) {
553
                        XIic_DisableIntr(InstancePtr->BaseAddress,
554
                                          XIIC_INTR_TX_HALF_MASK);
555
                }
556
        }
557
        /*
558
         * If there is only one byte left to send, processing differs between
559
         * repeated start and normal messages.
560
         */
561
        else if (InstancePtr->SendByteCount == 1) {
562
                /*
563
                 * When using repeated start, another interrupt is expected
564
                 * after the last byte has been sent, so the message is not
565
                 * done yet.
566
                 */
567
                if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
568
                        XIic_WriteSendByte(InstancePtr);
569
                }
570
 
571
                /*
572
                 * When not using repeated start, the stop condition must be
573
                 * generated after the last byte is written. The bus is
574
                 * throttled waiting for the last byte.
575
                 */
576
                else {
577
                        /*
578
                         * Set the stop condition before sending the last byte
579
                         * of data so that the stop condition will be generated
580
                         * immediately following the data another transmit
581
                         * interrupt is not expected so the message is done.
582
                         */
583
                        CntlReg = XIic_ReadReg(InstancePtr->BaseAddress,
584
                                        XIIC_CR_REG_OFFSET);
585
                        CntlReg &= ~XIIC_CR_MSMS_MASK;
586
                        XIic_WriteReg(InstancePtr->BaseAddress,
587
                                        XIIC_CR_REG_OFFSET,
588
                                        CntlReg);
589
 
590
                        XIic_WriteSendByte(InstancePtr);
591
 
592
                        /*
593
                         * Wait for bus to not be busy before declaring message
594
                         * has been sent for the no repeated start operation.
595
                         * The callback will be called from the BusNotBusy part
596
                         * of the Interrupt handler to ensure that the message
597
                         * is completely sent.
598
                         * Disable the Tx interrupts and enable the BNB
599
                         * interrupt.
600
                         */
601
 
602
                        InstancePtr->BNBOnly = FALSE;
603
                        XIic_DisableIntr(InstancePtr->BaseAddress,
604
                                                XIIC_TX_INTERRUPTS);
605
                        XIic_EnableIntr(InstancePtr->BaseAddress,
606
                                         XIIC_INTR_BNB_MASK);
607
 
608
                }
609
        } else {
610
                if (InstancePtr->Options & XII_REPEATED_START_OPTION) {
611
 
612
                        /*
613
                         * The message being sent has completed. When using
614
                         * repeated start with no more bytes to send repeated
615
                         * start needs to be set in the control register so
616
                         * that the bus will still be held by this master.
617
                         */
618
                        CntlReg = XIic_ReadReg(InstancePtr->BaseAddress,
619
                                        XIIC_CR_REG_OFFSET);
620
                        CntlReg |= XIIC_CR_REPEATED_START_MASK;
621
                        XIic_WriteReg(InstancePtr->BaseAddress,
622
                                        XIIC_CR_REG_OFFSET, CntlReg);
623
 
624
                        /*
625
                         * If the message that was being sent has finished,
626
                         * disable all transmit interrupts and call the callback
627
                         * that was setup to indicate the message was sent,
628
                         * with 0 bytes remaining.
629
                         */
630
 
631
                        XIic_DisableIntr(InstancePtr->BaseAddress,
632
                                          XIIC_TX_INTERRUPTS);
633
                        InstancePtr->SendHandler(InstancePtr->SendCallBackRef,
634
                                                 0);
635
                }
636
        }
637
 
638
        return;
639
}
640
 
641
/*****************************************************************************/
642
/**
643
*
644
* This function is called when the receive register is full. The number
645
* of bytes received to cause the interrupt is adjustable using the Receive FIFO
646
* Depth register. The number of bytes in the register is read in the Receive
647
* FIFO occupancy register. Both these registers are zero based values (0-15)
648
* such that a value of zero indicates 1 byte.
649
*
650
* For a Master Receiver to properly signal the end of a message, the data must
651
* be read in up to the message length - 1, where control register bits will be
652
* set for bus controls to occur on reading of the last byte.
653
*
654
* @param        InstancePtr is a pointer to the XIic instance to be worked on.
655
*
656
* @return       None.
657
*
658
* @note         None.
659
*
660
******************************************************************************/
661
static void RecvMasterData(XIic *InstancePtr)
662
{
663
        u8 LoopCnt;
664
        int BytesInFifo;
665
        int BytesToRead;
666
        u32 CntlReg;
667
 
668
        /*
669
         * Device is a master receiving, get the contents of the control
670
         * register and determine the number of bytes in fifo to be read out.
671
         */
672
        CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
673
        BytesInFifo = XIic_ReadReg(InstancePtr->BaseAddress,
674
                                XIIC_RFO_REG_OFFSET) + 1;
675
 
676
        /*
677
         * If data in FIFO holds all data to be retrieved - 1, set NOACK and
678
         * disable the Tx error.
679
         */
680
        if ((InstancePtr->RecvByteCount - BytesInFifo) == 1) {
681
                /*
682
                 * Disable Tx error interrupt to prevent interrupt
683
                 * as this device will cause it when it set NO ACK next.
684
                 */
685
                XIic_DisableIntr(InstancePtr->BaseAddress,
686
                                  XIIC_INTR_TX_ERROR_MASK);
687
                XIic_ClearIntr(InstancePtr->BaseAddress,
688
                                XIIC_INTR_TX_ERROR_MASK);
689
 
690
                /*
691
                 * Write control reg with NO ACK allowing last byte to
692
                 * have the No ack set to indicate to slave last byte read.
693
                 */
694
                XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
695
                         (CntlReg | XIIC_CR_NO_ACK_MASK));
696
 
697
                /*
698
                 * Read one byte to clear a place for the last byte to be read
699
                 * which will set the NO ACK.
700
                 */
701
                XIic_ReadRecvByte(InstancePtr);
702
        }
703
 
704
        /*
705
         * If data in FIFO is all the data to be received then get the data
706
         * and also leave the device in a good state for the next transaction.
707
         */
708
        else if ((InstancePtr->RecvByteCount - BytesInFifo) == 0) {
709
                /*
710
                 * If repeated start option is off then the master should stop
711
                 * using the bus, otherwise hold the bus, setting repeated start
712
                 * stops the slave from transmitting data when the FIFO is read.
713
                 */
714
                if ((InstancePtr->Options & XII_REPEATED_START_OPTION) == 0) {
715
                        CntlReg &= ~XIIC_CR_MSMS_MASK;
716
                } else {
717
                        CntlReg |= XIIC_CR_REPEATED_START_MASK;
718
                }
719
                XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
720
                         CntlReg);
721
 
722
                /*
723
                 * Read data from the FIFO then set zero based FIFO read depth
724
                 * for a byte.
725
                 */
726
                for (LoopCnt = 0; LoopCnt < BytesInFifo; LoopCnt++) {
727
                        XIic_ReadRecvByte(InstancePtr);
728
                }
729
                XIic_WriteReg(InstancePtr->BaseAddress,
730
                                XIIC_RFD_REG_OFFSET, 0);
731
 
732
                /*
733
                 * Disable Rx full interrupt and write the control reg with ACK
734
                 * allowing next byte sent to be acknowledged automatically.
735
                 */
736
                XIic_DisableIntr(InstancePtr->BaseAddress,
737
                                  XIIC_INTR_RX_FULL_MASK);
738
 
739
                XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
740
                         (CntlReg & ~XIIC_CR_NO_ACK_MASK));
741
 
742
                /*
743
                 * Send notification of msg Rx complete in RecvHandler callback.
744
                 */
745
                InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef, 0);
746
        } else {
747
                /*
748
                 * Fifo data not at n-1, read all but the last byte of data
749
                 * from the slave, if more than a FIFO full yet to receive
750
                 * read a FIFO full.
751
                 */
752
                BytesToRead = InstancePtr->RecvByteCount - BytesInFifo - 1;
753
                if (BytesToRead > IIC_RX_FIFO_DEPTH) {
754
                        BytesToRead = IIC_RX_FIFO_DEPTH;
755
                }
756
 
757
                /*
758
                 * Read in data from the FIFO.
759
                 */
760
                for (LoopCnt = 0; LoopCnt < BytesToRead; LoopCnt++) {
761
                        XIic_ReadRecvByte(InstancePtr);
762
                }
763
        }
764
}
765
/** @} */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.