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

Subversion Repositories xenie

[/] [xenie/] [trunk/] [examples/] [Eth_example/] [mb_fw/] [xenie_eth_test_womtd/] [src/] [iic_wrap.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 DFC
 
2
/******************************************************************************
3
**
4
** (C) Copyright 2013 DFC Design, s.r.o., Brno, Czech Republic
5
** Author: Marek Kvas (m.kvas@dspfpga.com)
6
**
7
****************************************************************************
8
**
9
** This file is part of Xenia Ethernet Example project.
10
**
11
** Xenia Ethernet Example project is free software: you can
12
** redistribute it and/or modify it under the terms of
13
** the GNU Lesser General Public License as published by the Free
14
** Software Foundation, either version 3 of the License, or
15
** (at your option) any later version.
16
**
17
** Xenia Ethernet Example project is distributed in the hope that
18
** it will be useful, but WITHOUT ANY WARRANTY; without even
19
** the implied warranty of MERCHANTABILITY or FITNESS FOR A
20
** PARTICULAR PURPOSE.  See the GNU Lesser General Public License
21
** for more details.
22
**
23
** You should have received a copy of the GNU Lesser General Public
24
** License along with Xenia Ethernet Example project.  If not,
25
** see <http://www.gnu.org/licenses/>.
26
*******************************************************************************
27
**
28
** This is a wrapper for Xilinx IIC driver in interrupt mode.
29
**
30
*******************************************************************************
31
*/
32
 
33
 
34
#include "iic_wrap.h"
35
#include "timers.h"
36
 
37
static void RecvHandler(void *CallbackRef, int ByteCount)
38
{
39
        struct iic_wrap_dev *dev = (struct iic_wrap_dev *)CallbackRef;
40
 
41
        dev->hi.unprocessed_bytes = ByteCount;
42
        dev->hi.finished = 1;
43
        dev->hi.rcv_stat++;
44
}
45
 
46
static void SendHandler(void *CallbackRef, int ByteCount)
47
{
48
        struct iic_wrap_dev *dev = (struct iic_wrap_dev *)CallbackRef;
49
 
50
        dev->hi.unprocessed_bytes = ByteCount;
51
        dev->hi.finished = 1;
52
        dev->hi.snd_star++;
53
}
54
 
55
static void StatusHandler(void *CallbackRef, int Status)
56
{
57
        struct iic_wrap_dev *dev = (struct iic_wrap_dev *)CallbackRef;
58
 
59
        /* As we are single master, when this is called, it is always wrong */
60
        dev->hi.error = Status;
61
        dev->hi.finished = 1;
62
        dev->hi.stat_stat++;
63
}
64
 
65
/*
66
 * Initialize underlying iic controller and wrapper structures.
67
 */
68
int iic_wrap_init(struct iic_wrap_dev *dev, u16 IicDeviceId)
69
{
70
        int Status;
71
        XIic_Config *ConfigPtr; /* Pointer to configuration data */
72
 
73
        /* Clear the device structure */
74
        memset(dev, 0, sizeof(*dev));
75
 
76
        /*
77
         * Initialize the IIC driver so that it is ready to use.
78
         */
79
        ConfigPtr = XIic_LookupConfig(IicDeviceId);
80
        if (ConfigPtr == NULL) {
81
                return -1;
82
        }
83
 
84
        Status = XIic_CfgInitialize(&dev->iic, ConfigPtr,
85
                                        ConfigPtr->BaseAddress);
86
        if (Status != XST_SUCCESS) {
87
                return -1;
88
        }
89
 
90
        /*
91
         * Setup handler to process the asynchronous events which occur,
92
         * the driver is only interrupt driven such that this must be
93
         * done prior to starting the device.
94
         */
95
        XIic_SetRecvHandler(&dev->iic, (void *)dev, RecvHandler);
96
        XIic_SetSendHandler(&dev->iic, (void *)dev, SendHandler);
97
        XIic_SetStatusHandler(&dev->iic, (void *)dev, StatusHandler);
98
 
99
        return 0;
100
}
101
 
102
/*
103
 * Send message on I2C bus with timeout.
104
 * Returns 0 on success, negative number otherwise.
105
 */
106
int iic_wrap_send_timeout(struct iic_wrap_dev *dev, u8 addr, u8 *tx_msg, int length, int timeout_ms)
107
{
108
        int ret;
109
        /* If device is not started, do it */
110
        if (!dev->started) {
111
                dev->started = 1;
112
                XIic_Start(&dev->iic);
113
        }
114
 
115
        dev->hi.error = 0;
116
        dev->hi.finished = 0;
117
        dev->hi.op_started = 1;
118
        dev->hi.end_tstmp = timers_ms_now() + timeout_ms;
119
 
120
        XIic_SetAddress(&dev->iic, XII_ADDR_TO_SEND_TYPE, addr);
121
        /* If busy, retry until timeout */
122
        /* TODO: There is a bug xilinx driver in busy signaling. Make fix part of project */
123
        do {
124
                ret = XIic_DynMasterSend(&dev->iic, tx_msg, length);
125
        } while ((ret != XST_SUCCESS) && (timers_ms_now() < dev->hi.end_tstmp));
126
 
127
        while (!dev->hi.finished) {
128
                if (timers_ms_now() > dev->hi.end_tstmp) {
129
                        dev->hi.op_started = 0;
130
                        return -1;
131
                }
132
        }
133
 
134
        /* check for errors */
135
        if(dev->hi.error || dev->hi.unprocessed_bytes) {
136
                dev->hi.op_started = 0;
137
                return -1;
138
        }
139
 
140
        /* Success */
141
        dev->hi.op_started = 0;
142
        return 0;
143
}
144
 
145
/*
146
 * Receive message on I2C bus with timeout.
147
 * Returns 0 on success, negative number otherwise.
148
 */
149
int iic_wrap_recv_timeout(struct iic_wrap_dev *dev, u8 addr, u8 *rx_msg, int length, int timeout_ms)
150
{
151
        int ret;
152
 
153
        /* If device is not started, do it */
154
        if (!dev->started) {
155
                dev->started = 1;
156
                XIic_Start(&dev->iic);
157
        }
158
 
159
        dev->hi.error = 0;
160
        dev->hi.finished = 0;
161
        dev->hi.op_started = 1;
162
        dev->hi.end_tstmp = timers_ms_now() + timeout_ms;
163
 
164
        XIic_SetAddress(&dev->iic, XII_ADDR_TO_SEND_TYPE, addr);
165
        do {
166
                ret = XIic_DynMasterRecv(&dev->iic, rx_msg, length);
167
        } while ((ret != XST_SUCCESS) && (timers_ms_now() < dev->hi.end_tstmp));
168
 
169
        while (!dev->hi.finished) {
170
                if (timers_ms_now() > dev->hi.end_tstmp) {
171
                        dev->hi.op_started = 0;
172
                        return -1;
173
                }
174
        }
175
 
176
        /* check for errors */
177
        if(dev->hi.error || dev->hi.unprocessed_bytes) {
178
                dev->hi.op_started = 0;
179
                return -1;
180
        }
181
 
182
        /* Success */
183
        dev->hi.op_started = 0;
184
        return 0;
185
}
186
 
187
 
188
 
189
 
190
 
191
 
192
 
193
 
194
 
195
 
196
 
197
 
198
 
199
 
200
 

powered by: WebSVN 2.1.0

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