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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [i2c/] [m68k/] [mcf52xx/] [current/] [src/] [i2c_mcf52xx.c] - Blame information for rev 847

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      devs/i2c/m68k/mcf52xx/current/src/i2c_mcf52xx.c
4
//
5
//      I2C driver for Motorola coldfire processors
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.                  
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):     Uwe Kindler, Bart Veer
43
// Contributors:  
44
// Date:          2005-10-23
45
// Description:   I2C driver for motorola coldfire processor
46
//####DESCRIPTIONEND####
47
//==========================================================================
48
 
49
#include <pkgconf/system.h>
50
#include <pkgconf/devs_i2c_mcf52xx.h>
51
 
52
#include <cyg/infra/cyg_type.h>
53
#include <cyg/infra/cyg_ass.h>
54
#include <cyg/infra/diag.h>
55
#include <cyg/io/i2c.h>
56
#include <cyg/io/i2c_mcf52xx.h>
57
#include <cyg/hal/hal_arch.h>
58
#include <cyg/hal/hal_io.h>
59
#include <cyg/hal/hal_intr.h>
60
#include <cyg/hal/drv_api.h>
61
 
62
// Optimize for the case of a single bus device, while still allowing
63
// multiple devices.
64
#ifndef CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES
65
# define    I2C_BASE(_extra_)       (cyg_uint8*)HAL_MCF52xx_I2C_SINGLETON_BASE
66
# define    I2C_ISRVEC(_extra_)     HAL_MCF52xx_I2C_SINGLETON_ISRVEC
67
# define    I2C_ISRPRI(_extra_)     HAL_MCF52xx_I2C_SINGLETON_ISRPRI
68
# define    I2C_FDR(_extra_)        HAL_MCF52xx_I2C_SINGLETON_FDR
69
#else
70
# define    I2C_BASE(_extra_)       ((_extra_)->i2c_base)
71
# define    I2C_ISRVEC(_extra_)     ((_extra_)->i2c_isrvec)
72
# define    I2C_ISRPRI(_extra_)     ((_extra_)->i2c_isrpri)
73
# define    I2C_FDR(_extra_)        ((_extra_)->i2c_fdr)
74
#endif
75
 
76
// If building for a singleton but the macros are no defined, assume
77
// the I2C support is conditional on a disabled platform HAL
78
// configuration option. This handles the common case of an I2C bus
79
// accessed only via an expansion connector.
80
#if defined(CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES) || defined(HAL_MCF52xx_I2C_SINGLETON_BASE)
81
 
82
// ----------------------------------------------------------------------------
83
// Interrupt handling and polling
84
//
85
// The MCF52xx I2C bus device does not have a fifo or any kind of DMA
86
// capability, so can generate interrupts at a very high rate: ~10K
87
// interrupts per second if the bus is running at the standard 100KHz,
88
// or 50K for a high-speed 400KHz bus. To keep the cpu load down to
89
// something vaguely reasonable as much work as possible has to be
90
// done in the ISR, with the DSR used only for completion.
91
static cyg_uint32
92
mcf52xx_i2c_isr(cyg_vector_t vec, cyg_addrword_t data)
93
{
94
    cyg_mcf52xx_i2c_extra*  extra   = (cyg_mcf52xx_i2c_extra*)data;
95
    cyg_uint8               sr, dr;
96
    cyg_uint8*              base    = I2C_BASE(extra);
97
    cyg_uint32              result  = CYG_ISR_HANDLED;
98
 
99
    // Read the current status, then clear the interrupt and
100
    // arbitration-lost flags. No later code will look at the
101
    // SR register again.
102
    HAL_READ_UINT8( base + HAL_MCF52xx_I2C_SR_OFF, sr);
103
    HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, 0x00);
104
 
105
    // What to do next depends on the current transfer mode.
106
    if (CYG_MCF52xx_I2C_XFER_MODE_TX == extra->i2c_mode) {
107
        // We are in a transmit, or sending the address byte just
108
        // before a transmit.
109
        if (sr & HAL_MCF52xx_I2C_SR_IAL) {
110
            // Lost the bus, abort the transfer. count has already been
111
            // decremented. Assume the byte did not actually arrive.
112
            extra->i2c_count    += 1;
113
            result              = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
114
        } else if (sr & HAL_MCF52xx_I2C_SR_RXAK) {
115
            // This byte has been sent but the device cannot accept
116
            // any more. The nack must be remembered. Otherwise if
117
            // we got a nack for the last byte in a tx then the
118
            // calling code will think the entire tx succeeded,
119
            // and there will be problems if the next call is
120
            // another tx without a repeated start.
121
            extra->i2c_got_nack = 1;
122
            result              = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
123
        } else if (0 == extra->i2c_count) {
124
            // No more bytes to send.
125
            result          = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
126
        } else {
127
            HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, *(extra->i2c_data.i2c_tx_data));
128
            extra->i2c_data.i2c_tx_data += 1;
129
            extra->i2c_count            -= 1;
130
        }
131
    } else if (CYG_MCF52xx_I2C_XFER_MODE_RX == extra->i2c_mode) {
132
        if (sr & HAL_MCF52xx_I2C_SR_IAL) {
133
            // Lost the bus? Maybe a spurious stop
134
            result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
135
        } else {
136
            if (extra->i2c_send_nack && (2 == extra->i2c_count)) {
137
                // Received one, one more to go, and that one should be nacked.
138
                HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
139
                                HAL_MCF52xx_I2C_CR_IEN  |
140
                                HAL_MCF52xx_I2C_CR_IIEN |
141
                                HAL_MCF52xx_I2C_CR_MSTA |
142
                                HAL_MCF52xx_I2C_CR_TXAK);
143
            } else if (1 == extra->i2c_count) {
144
                // Received the last byte. The docs say to send a stop,
145
                // but there may be another transaction_rx() call. We
146
                // cannot just read DR again, that would trigger another
147
                // read. So instead switch to transmit mode for now,
148
                // which should cause the h/w to wait until a byte is
149
                // written to DR.
150
                HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
151
                                HAL_MCF52xx_I2C_CR_IEN  |
152
                                HAL_MCF52xx_I2C_CR_IIEN |
153
                                HAL_MCF52xx_I2C_CR_MSTA |
154
                                HAL_MCF52xx_I2C_CR_MTX);
155
                result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
156
            }
157
 
158
            HAL_READ_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, dr);
159
            *(extra->i2c_data.i2c_rx_data)  = dr;
160
            extra->i2c_data.i2c_rx_data     += 1;
161
            extra->i2c_count                -= 1;
162
        }
163
    } else if (CYG_MCF52xx_I2C_XFER_MODE_STARTRX == extra->i2c_mode) {
164
        // Start followed by RX. The address byte has been sent, we
165
        // need to switch to receiving.
166
        if (sr & (HAL_MCF52xx_I2C_SR_IAL | HAL_MCF52xx_I2C_SR_RXAK)) {
167
            // Looks like no device acknowledged the address.
168
            result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
169
        } else {
170
            extra->i2c_mode = CYG_MCF52xx_I2C_XFER_MODE_RX;
171
            if (extra->i2c_send_nack && (1 == extra->i2c_count)) {
172
                HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
173
                                HAL_MCF52xx_I2C_CR_IEN  |
174
                                HAL_MCF52xx_I2C_CR_IIEN |
175
                                HAL_MCF52xx_I2C_CR_MSTA |
176
                                HAL_MCF52xx_I2C_CR_TXAK);
177
            } else {
178
                HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
179
                                HAL_MCF52xx_I2C_CR_IEN  |
180
                                HAL_MCF52xx_I2C_CR_IIEN |
181
                                HAL_MCF52xx_I2C_CR_MSTA);
182
            }
183
            // This dummy read causes the next rx to start
184
            HAL_READ_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, dr);
185
        }
186
    } else {
187
        // Invalid state? Some kind of spurious interrupt? Just ignore
188
        // it.
189
        CYG_FAIL("I2C spurious interrupt");
190
    }
191
 
192
    // NOTE: this will acknowledge the interrupt even in polled mode.
193
    // Probably harmless. Using I2C_ISRVEC rather than the vec arg
194
    // means a constant number for the singleton case, which may
195
    // allow the HAL to optimize the acknowledge away completely.
196
    HAL_INTERRUPT_ACKNOWLEDGE(I2C_ISRVEC(extra));
197
    return result;
198
}
199
 
200
static void
201
mcf52xx_i2c_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
202
{
203
    cyg_mcf52xx_i2c_extra*  extra   = (cyg_mcf52xx_i2c_extra*)data;
204
    extra->i2c_completed    = 1;
205
    cyg_drv_cond_signal(&(extra->i2c_wait));
206
}
207
 
208
// A transfer has been started. Wait for completion, allowing for both
209
// polled and interrupt-driven mode.
210
static inline void
211
mcf52xx_i2c_doit(cyg_mcf52xx_i2c_extra* extra)
212
{
213
    cyg_uint8*  base    = I2C_BASE(extra);
214
    int         ints_state;
215
    int         sr;
216
 
217
    HAL_QUERY_INTERRUPTS(ints_state);
218
    if (((ints_state >> 8) & 0x07) > CYGNUM_HAL_INTERRUPT_DEFAULT_IPL_LEVEL) {
219
        // Interrupts are currently disabled. We'll have to poll.
220
        for ( ; ; ) {
221
            HAL_READ_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, sr);
222
            if (sr & HAL_MCF52xx_I2C_SR_IIF) {
223
                if (CYG_ISR_CALL_DSR & mcf52xx_i2c_isr(I2C_ISRVEC(extra), (cyg_addrword_t)extra)) {
224
                    break;
225
                }
226
            }
227
        }
228
    } else {
229
        cyg_drv_mutex_lock(&(extra->i2c_lock));
230
        cyg_drv_dsr_lock();
231
        while (! extra->i2c_completed) {
232
            cyg_drv_cond_wait(&(extra->i2c_wait));
233
        }
234
        cyg_drv_dsr_unlock();
235
        cyg_drv_mutex_unlock(&(extra->i2c_lock));
236
    }
237
}
238
 
239
static cyg_bool
240
mcf52xx_i2c_send_start(cyg_mcf52xx_i2c_extra* extra, int address)
241
{
242
    cyg_uint8*  base    = I2C_BASE(extra);
243
    cyg_uint8   sr;
244
 
245
    // This may be a repeated start or the beginning of a transaction.
246
    // If the former then we still own the bus.
247
    if (!extra->i2c_owner) {
248
        // The bus is currently in slave mode. See if another master
249
        // currently owns the bus and if so fail immediately. It is up
250
        // to higher level code to decide when to retry. Alternatively
251
        // if the bus has somehow got stuck in busy mode it is again
252
        // up to higher level code to sort things out.
253
        HAL_READ_UINT8(I2C_BASE(extra) + HAL_MCF52xx_I2C_SR_OFF, sr);
254
        if (sr & HAL_MCF52xx_I2C_SR_IBB) {
255
            return 0;
256
        }
257
 
258
        // Now we can put the bus into master mode
259
        HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
260
                        HAL_MCF52xx_I2C_CR_IEN   |
261
                        HAL_MCF52xx_I2C_CR_IIEN  |
262
                        HAL_MCF52xx_I2C_CR_MSTA  |  // This implicitly generates the start
263
                        HAL_MCF52xx_I2C_CR_MTX);    // The address byte needs to be transmitted.
264
        extra->i2c_owner    = 1;
265
    } else {
266
        HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
267
                        HAL_MCF52xx_I2C_CR_IEN   |
268
                        HAL_MCF52xx_I2C_CR_IIEN  |
269
                        HAL_MCF52xx_I2C_CR_MSTA  |  // Already set so no start generated by this
270
                        HAL_MCF52xx_I2C_CR_MTX   |
271
                        HAL_MCF52xx_I2C_CR_RSTA);    // Repeated start
272
    }
273
 
274
    // Any previous nack is no longer relevant. If the device cannot accept
275
    // more data it will nack the address.
276
    extra->i2c_got_nack = 0;
277
    // Now send the address. The rest of the transfer is handled by the
278
    // interrupt/polling code.
279
    HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, address);
280
    return 1;
281
}
282
 
283
static inline void
284
mcf52xx_i2c_stopit(cyg_mcf52xx_i2c_extra* extra)
285
{
286
    // If we still own the bus this releases it (by clearing MSTA) and
287
    // generating a stop. If we have lost arbitration then this write
288
    // has no effect (other than disabling interrupts). Either way the
289
    // bus should end up in a consistent state.
290
    HAL_WRITE_UINT8(I2C_BASE(extra) + HAL_MCF52xx_I2C_CR_OFF, HAL_MCF52xx_I2C_CR_IEN);
291
    extra->i2c_lost_arb = 0;
292
    extra->i2c_owner    = 0;
293
    extra->i2c_mode     = CYG_MCF52xx_I2C_XFER_MODE_INVALID;
294
}
295
 
296
// ----------------------------------------------------------------------------
297
// The functions needed for all I2C devices.
298
 
299
void
300
cyg_mcf52xx_i2c_init(struct cyg_i2c_bus* bus)
301
{
302
    cyg_mcf52xx_i2c_extra*  extra   = (cyg_mcf52xx_i2c_extra*)bus->i2c_extra;
303
    cyg_uint8               reg;
304
    cyg_uint8*              base    = I2C_BASE(extra);
305
 
306
    cyg_drv_mutex_init(&extra->i2c_lock);
307
    cyg_drv_cond_init(&extra->i2c_wait, &extra->i2c_lock);
308
    cyg_drv_interrupt_create(I2C_ISRVEC(extra),
309
                             I2C_ISRPRI(extra),
310
                             (cyg_addrword_t) extra,
311
                             &mcf52xx_i2c_isr,
312
                             &mcf52xx_i2c_dsr,
313
                             &(extra->i2c_interrupt_handle),
314
                             &(extra->i2c_interrupt_data));
315
    cyg_drv_interrupt_attach(extra->i2c_interrupt_handle);
316
 
317
    // Before unmasking the interrupt sort out the hardware.
318
    //
319
    // The bus frequency is set by the platform HAL or user, since
320
    // it depends on what mixture of devices are present on the bus.
321
    HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_FDR_OFF, I2C_FDR(extra));
322
    // The device will operate in slave mode when idle. If there is
323
    // another bus master then the coldfire might accidentally accept
324
    // requests intended for another device. Address 0 is installed
325
    // as the slave address. This is the General Call address, used
326
    // for broadcasting. It might be better to use another address
327
    // like an Hs-mode one, but conflicts are still possible.
328
    HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_ADR_OFF, 0x0);
329
    // Enable the I2C device but do not start any transfers and
330
    // leave interrupts disabled.
331
    HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, HAL_MCF52xx_I2C_CR_IEN);
332
 
333
    // As per the documentation, if IBB is set then issue a stop. It
334
    // is not really clear this is the right thing to do in
335
    // multimaster setups, if another master happens to start a
336
    // transfer at this exact time. Presumably it solves more problems
337
    // than it might cause.
338
    HAL_READ_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, reg);
339
    if (reg & HAL_MCF52xx_I2C_SR_IBB) {
340
        HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, 0x0000);
341
        HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, 0x00A0);
342
        HAL_READ_UINT8( base + HAL_MCF52xx_I2C_DR_OFF, reg);
343
        HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, 0x0000);
344
        HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, 0x0000);
345
 
346
        // Don't forget to reenable the device.
347
        HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, HAL_MCF52xx_I2C_CR_IEN);
348
    }
349
 
350
    // Clear any pending conditions including interrupts.
351
    HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, 0);
352
 
353
    // Interrupts can now be safely unmasked
354
    HAL_INTERRUPT_UNMASK(I2C_ISRVEC(extra));
355
}
356
 
357
cyg_uint32
358
cyg_mcf52xx_i2c_tx(const cyg_i2c_device* dev, cyg_bool send_start, const cyg_uint8* tx_data, cyg_uint32 count, cyg_bool send_stop)
359
{
360
    cyg_mcf52xx_i2c_extra*  extra   = (cyg_mcf52xx_i2c_extra*)dev->i2c_bus->i2c_extra;
361
 
362
    extra->i2c_count        = count;
363
    if (! extra->i2c_lost_arb) {
364
        extra->i2c_completed    = 0;
365
        extra->i2c_mode         = CYG_MCF52xx_I2C_XFER_MODE_TX;
366
 
367
        if (send_start) {
368
            extra->i2c_data.i2c_tx_data = tx_data;
369
            if (! mcf52xx_i2c_send_start(extra, (dev->i2c_address << 1) | 0x00)) {
370
                return 0;
371
            }
372
            mcf52xx_i2c_doit(extra);
373
        } else if ( !extra->i2c_got_nack) {
374
            // We are in the middle of a transaction and not
375
            // generating a repeated start, so the device must already
376
            // be set up for writes.
377
            extra->i2c_data.i2c_tx_data = &(tx_data[1]);
378
            extra->i2c_count            = count - 1;
379
            HAL_WRITE_UINT8(I2C_BASE(extra) + HAL_MCF52xx_I2C_DR_OFF, *tx_data);
380
            mcf52xx_i2c_doit(extra);
381
        }
382
    }
383
    if (send_stop) {
384
        mcf52xx_i2c_stopit(extra);
385
    }
386
 
387
    // tx() should return the number of bytes actually transmitted.
388
    // ISR() increments extra->count after a failure, which leads to
389
    // an edge condition when send_start and there is no acknowledgment
390
    // of the address byte.
391
    if (extra->i2c_count > count) {
392
        return 0;
393
    }
394
    return count - extra->i2c_count;
395
}
396
 
397
cyg_uint32
398
cyg_mcf52xx_i2c_rx(const cyg_i2c_device* dev, cyg_bool send_start, cyg_uint8* rx_data, cyg_uint32 count, cyg_bool send_nack, cyg_bool send_stop)
399
{
400
    cyg_mcf52xx_i2c_extra*  extra   = (cyg_mcf52xx_i2c_extra*)dev->i2c_bus->i2c_extra;
401
    cyg_uint8*              base    = I2C_BASE(extra);
402
    cyg_uint8               discard;
403
 
404
    extra->i2c_count        = count;
405
    extra->i2c_send_nack    = send_nack;
406
 
407
    if (! extra->i2c_lost_arb) {
408
        extra->i2c_completed        = 0;
409
        extra->i2c_data.i2c_rx_data = rx_data;
410
        if (send_start) {
411
            extra->i2c_mode     = CYG_MCF52xx_I2C_XFER_MODE_STARTRX;
412
            if (! mcf52xx_i2c_send_start(extra, (dev->i2c_address << 1) | 0x01) ) {
413
                return 0;
414
            }
415
        } else {
416
            // In the middle of a transaction. The previous transfer
417
            // will have left the device in tx mode.
418
            extra->i2c_mode     = CYG_MCF52xx_I2C_XFER_MODE_RX;
419
            if (send_nack && (1 == count)) {
420
                HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
421
                                HAL_MCF52xx_I2C_CR_IEN  |
422
                                HAL_MCF52xx_I2C_CR_IIEN |
423
                                HAL_MCF52xx_I2C_CR_MSTA |
424
                                HAL_MCF52xx_I2C_CR_TXAK);
425
            } else {
426
                HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
427
                                HAL_MCF52xx_I2C_CR_IEN  |
428
                                HAL_MCF52xx_I2C_CR_IIEN |
429
                                HAL_MCF52xx_I2C_CR_MSTA);
430
            }
431
            // So reading the data register here should get the device
432
            // reading the next byte.
433
            HAL_READ_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, discard);
434
        }
435
        mcf52xx_i2c_doit(extra);
436
    }
437
    if (send_stop) {
438
        mcf52xx_i2c_stopit(extra);
439
    }
440
    return count - extra->i2c_count;
441
}
442
 
443
void
444
cyg_mcf52xx_i2c_stop(const cyg_i2c_device* dev)
445
{
446
    cyg_mcf52xx_i2c_extra*  extra   = (cyg_mcf52xx_i2c_extra*)dev->i2c_bus->i2c_extra;
447
    mcf52xx_i2c_stopit(extra);
448
}
449
 
450
#endif  //  defined(CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES) || defined(HAL_MCF52xx_I2C_SINGLETON_BASE)
451
//---------------------------------------------------------------------------
452
// EOF i2c_mcf52xx.c

powered by: WebSVN 2.1.0

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