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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [drivers/] [Atmel/] [at91lib/] [peripherals/] [mci/] [mci.c] - Blame information for rev 608

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 608 jeremybenn
/* ----------------------------------------------------------------------------
2
 *         ATMEL Microcontroller Software Support  -  ROUSSET  -
3
 * ----------------------------------------------------------------------------
4
 * Copyright (c) 2006, Atmel Corporation
5
 
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions are met:
10
 *
11
 * - Redistributions of source code must retain the above copyright notice,
12
 * this list of conditions and the disclaimer below.
13
 *
14
 * - Redistributions in binary form must reproduce the above copyright notice,
15
 * this list of conditions and the disclaimer below in the documentation and/or
16
 * other materials provided with the distribution.
17
 *
18
 * Atmel's name may not be used to endorse or promote products derived from
19
 * this software without specific prior written permission.
20
 *
21
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
22
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
24
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
25
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
27
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
 * ----------------------------------------------------------------------------
32
 */
33
 
34
//------------------------------------------------------------------------------
35
//         Headers
36
//------------------------------------------------------------------------------
37
 
38
#include "mci.h"
39
#include <utility/assert.h>
40
#include <utility/trace.h>
41
 
42
//------------------------------------------------------------------------------
43
//         Local constants
44
//------------------------------------------------------------------------------
45
 
46
/// Bit mask for status register errors.
47
#define STATUS_ERRORS (AT91C_MCI_UNRE  \
48
                       | AT91C_MCI_OVRE \
49
                       | AT91C_MCI_DTOE \
50
                       | AT91C_MCI_DCRCE \
51
                       | AT91C_MCI_RTOE \
52
                       | AT91C_MCI_RENDE \
53
                       | AT91C_MCI_RCRCE \
54
                       | AT91C_MCI_RDIRE \
55
                       | AT91C_MCI_RINDE)
56
 
57
/// MCI data timeout configuration with 1048576 MCK cycles between 2 data transfers.
58
#define DTOR_1MEGA_CYCLES           (AT91C_MCI_DTOCYC | AT91C_MCI_DTOMUL)
59
 
60
#define SDCARD_APP_OP_COND_CMD      (41 | AT91C_MCI_SPCMD_NONE  | AT91C_MCI_RSPTYP_48   | AT91C_MCI_TRCMD_NO )
61
#define MMC_SEND_OP_COND_CMD        (1  | AT91C_MCI_TRCMD_NO    | AT91C_MCI_SPCMD_NONE  | AT91C_MCI_RSPTYP_48 | AT91C_MCI_OPDCMD)
62
 
63
 
64
#define DISABLE    0    // Disable MCI interface
65
#define ENABLE     1    // Enable MCI interface
66
 
67
 
68
//------------------------------------------------------------------------------
69
//         Local macros
70
//------------------------------------------------------------------------------
71
 
72
/// Used to write in PMC registers.
73
#define WRITE_PMC(pPmc, regName, value)     pPmc->regName = (value)
74
 
75
/// Used to write in MCI registers.
76
#define WRITE_MCI(pMci, regName, value)     pMci->regName = (value)
77
 
78
/// Used to read from MCI registers.
79
#define READ_MCI(pMci, regName)             (pMci->regName)
80
 
81
//------------------------------------------------------------------------------
82
//         Global functions
83
//------------------------------------------------------------------------------
84
 
85
//------------------------------------------------------------------------------
86
/// Enable/disable a MCI driver instance.
87
/// \param pMci  Pointer to a MCI driver instance.
88
/// \param enb  0 for disable MCI and 1 for enable MCI.
89
//------------------------------------------------------------------------------
90
void MCI_Enable(Mci *pMci, unsigned char enb)
91
{
92
        AT91S_MCI *pMciHw = pMci->pMciHw;
93
 
94
        SANITY_CHECK(pMci);
95
    SANITY_CHECK(pMci->pMciHw);
96
 
97
    // Set the Control Register: Enable/Disable MCI interface clock
98
    if(enb == DISABLE) {
99
        WRITE_MCI(pMciHw, MCI_CR, AT91C_MCI_MCIDIS);
100
    }
101
    else {
102
        WRITE_MCI(pMciHw, MCI_CR, AT91C_MCI_MCIEN);
103
    }
104
}
105
 
106
//------------------------------------------------------------------------------
107
/// Initializes a MCI driver instance and the underlying peripheral.
108
/// \param pMci  Pointer to a MCI driver instance.
109
/// \param pMciHw  Pointer to a MCI peripheral.
110
/// \param mciId  MCI peripheral identifier.
111
/// \param mode  Slot and type of connected card.
112
//------------------------------------------------------------------------------
113
void MCI_Init(
114
    Mci *pMci,
115
    AT91S_MCI *pMciHw,
116
    unsigned char mciId,
117
    unsigned int mode)
118
{
119
    unsigned short clkDiv;
120
 
121
    SANITY_CHECK(pMci);
122
    SANITY_CHECK(pMciHw);
123
    SANITY_CHECK((mode == MCI_MMC_SLOTA) || (mode == MCI_MMC_SLOTB)
124
                 || (mode == MCI_SD_SLOTA) || (mode == MCI_SD_SLOTB));
125
 
126
    // Initialize the MCI driver structure
127
    pMci->pMciHw = pMciHw;
128
    pMci->mciId  = mciId;
129
    pMci->semaphore = 1;
130
    pMci->pCommand = 0;
131
 
132
    // Enable the MCI clock
133
    WRITE_PMC(AT91C_BASE_PMC, PMC_PCER, (1 << mciId));
134
 
135
     // Reset the MCI
136
    WRITE_MCI(pMciHw, MCI_CR, AT91C_MCI_SWRST);
137
 
138
    // Disable the MCI
139
    WRITE_MCI(pMciHw, MCI_CR, AT91C_MCI_MCIDIS | AT91C_MCI_PWSDIS);
140
 
141
    // Disable all the interrupts
142
    WRITE_MCI(pMciHw, MCI_IDR, 0xFFFFFFFF);
143
 
144
    // Set the Data Timeout Register
145
    WRITE_MCI(pMciHw, MCI_DTOR, DTOR_1MEGA_CYCLES);
146
 
147
    // Set the Mode Register: 400KHz for MCK = 48MHz (CLKDIV = 58)
148
    clkDiv = (BOARD_MCK / (400000 * 2)) - 1;
149
    WRITE_MCI(pMciHw, MCI_MR, (clkDiv | (AT91C_MCI_PWSDIV & (0x7 << 8))));
150
 
151
    // Set the SDCard Register
152
    WRITE_MCI(pMciHw, MCI_SDCR, mode);
153
 
154
    // Enable the MCI and the Power Saving
155
    WRITE_MCI(pMciHw, MCI_CR, AT91C_MCI_MCIEN);
156
 
157
    // Disable the MCI peripheral clock.
158
    WRITE_PMC(AT91C_BASE_PMC, PMC_PCDR, (1 << mciId));
159
}
160
 
161
//------------------------------------------------------------------------------
162
/// Close a MCI driver instance and the underlying peripheral.
163
/// \param pMci  Pointer to a MCI driver instance.
164
/// \param pMciHw  Pointer to a MCI peripheral.
165
/// \param mciId  MCI peripheral identifier.
166
//------------------------------------------------------------------------------
167
void MCI_Close(Mci *pMci)
168
{
169
    AT91S_MCI *pMciHw = pMci->pMciHw;
170
 
171
    SANITY_CHECK(pMci);
172
    SANITY_CHECK(pMciHw);
173
 
174
    // Initialize the MCI driver structure
175
    pMci->semaphore = 1;
176
    pMci->pCommand = 0;
177
 
178
    // Disable the MCI peripheral clock.
179
    WRITE_PMC(AT91C_BASE_PMC, PMC_PCDR, (1 << pMci->mciId));
180
 
181
    // Disable the MCI
182
    WRITE_MCI(pMciHw, MCI_CR, AT91C_MCI_MCIDIS);
183
 
184
    // Disable all the interrupts
185
    WRITE_MCI(pMciHw, MCI_IDR, 0xFFFFFFFF);
186
}
187
 
188
//------------------------------------------------------------------------------
189
/// Configure the  MCI CLKDIV in the MCI_MR register. The max. for MCI clock is 
190
/// MCK/2 and corresponds to CLKDIV = 0
191
/// \param pMci  Pointer to the low level MCI driver.
192
/// \param mciSpeed  MCI clock speed in Hz.
193
//------------------------------------------------------------------------------
194
void MCI_SetSpeed(Mci *pMci, unsigned int mciSpeed)
195
{
196
    AT91S_MCI *pMciHw = pMci->pMciHw;
197
    unsigned int mciMr;
198
    unsigned short clkdiv;
199
 
200
    SANITY_CHECK(pMci);
201
    SANITY_CHECK(pMci->pMciHw);
202
 
203
    // Set the Mode Register: 400KHz for MCK = 48MHz (CLKDIV = 58)
204
    mciMr = READ_MCI(pMciHw, MCI_MR) & (~AT91C_MCI_CLKDIV);
205
 
206
    // Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK)
207
    // divided by (2*(CLKDIV+1))
208
    if (mciSpeed > 0) {
209
 
210
        clkdiv = (BOARD_MCK / (mciSpeed * 2));
211
        if (clkdiv > 0) {
212
 
213
            clkdiv -= 1;
214
        }
215
    }
216
    else {
217
 
218
        clkdiv = 0;
219
    }
220
 
221
    WRITE_MCI(pMciHw, MCI_MR, mciMr | clkdiv);
222
}
223
 
224
//------------------------------------------------------------------------------
225
/// Configure the  MCI SDCBUS in the MCI_SDCR register. Only two modes available
226
/// 
227
/// \param pMci  Pointer to the low level MCI driver.
228
/// \param busWidth  MCI bus width mode.
229
//------------------------------------------------------------------------------
230
void MCI_SetBusWidth(Mci *pMci, unsigned char busWidth)
231
{
232
    AT91S_MCI *pMciHw = pMci->pMciHw;
233
    unsigned int mciSdcr;
234
 
235
    SANITY_CHECK(pMci);
236
    SANITY_CHECK(pMci->pMciHw);
237
 
238
    mciSdcr = (READ_MCI(pMciHw, MCI_SDCR) & ~(AT91C_MCI_SCDBUS));
239
 
240
    WRITE_MCI(pMciHw, MCI_SDCR, mciSdcr | busWidth);
241
}
242
 
243
//------------------------------------------------------------------------------
244
/// Starts a MCI  transfer. This is a non blocking function. It will return
245
/// as soon as the transfer is started.
246
/// Return 0 if successful; otherwise returns MCI_ERROR_LOCK if the driver is
247
/// already in use.
248
/// \param pMci  Pointer to an MCI driver instance.
249
/// \param pCommand  Pointer to the command to execute.
250
//------------------------------------------------------------------------------
251
unsigned char MCI_SendCommand(Mci *pMci, MciCmd *pCommand)
252
{
253
    AT91PS_MCI pMciHw = pMci->pMciHw;
254
    unsigned int mciIer, mciMr;
255
 
256
    SANITY_CHECK(pMci);
257
    SANITY_CHECK(pMciHw);
258
    SANITY_CHECK(pCommand);
259
 
260
    // Try to acquire the MCI semaphore
261
    if (pMci->semaphore == 0) {
262
 
263
        return MCI_ERROR_LOCK;
264
    }
265
    pMci->semaphore--;
266
    // trace_LOG(trace_DEBUG, "MCI_SendCommand %x %d\n\r", READ_MCI(pMciHw, MCI_SR), pCommand->cmd & 0x3f);
267
 
268
    // Command is now being executed
269
    pMci->pCommand = pCommand;
270
    pCommand->status = MCI_STATUS_PENDING;
271
 
272
    // Enable the MCI clock
273
    WRITE_PMC(AT91C_BASE_PMC, PMC_PCER, (1 << pMci->mciId));
274
 
275
    //Disable MCI clock, for multi-block data transfer
276
    MCI_Enable(pMci, DISABLE);
277
 
278
    // Set PDC data transfer direction
279
    if(pCommand->blockSize > 0) {
280
        if(pCommand->isRead) {
281
            WRITE_MCI(pMciHw, MCI_PTCR, AT91C_PDC_RXTEN);
282
        }
283
        else {
284
            WRITE_MCI(pMciHw, MCI_PTCR, AT91C_PDC_TXTEN);
285
        }
286
    }
287
    // Disable transmitter and receiver
288
    WRITE_MCI(pMciHw, MCI_PTCR, AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS);
289
 
290
    mciMr = READ_MCI(pMciHw, MCI_MR) & (~(AT91C_MCI_BLKLEN | AT91C_MCI_PDCMODE));
291
 
292
    // Command with DATA stage
293
    if (pCommand->blockSize > 0) {
294
        // Enable PDC mode and set block size
295
        if(pCommand->conTrans != MCI_CONTINUE_TRANSFER) {
296
 
297
            WRITE_MCI(pMciHw, MCI_MR, mciMr | AT91C_MCI_PDCMODE | (pCommand->blockSize << 16));
298
        }
299
 
300
        // DATA transfer from card to host
301
        if (pCommand->isRead) {
302
            WRITE_MCI(pMciHw, MCI_RPR, (int) pCommand->pData);
303
 
304
            // If Multiblock command set the BLKR register
305
            /* if (pCommand->nbBlock > 1) {
306
                WRITE_MCI(pMciHw, MCI_BLKR, pCommand->nbBlock | (pCommand->blockSize << 16));
307
            }
308
            else {
309
                WRITE_MCI(pMciHw, MCI_BLKR, (pCommand->blockSize << 16));
310
            }*/
311
 
312
            // Sanity check
313
            if (pCommand->nbBlock == 0)
314
                pCommand->nbBlock = 1;
315
            ////////
316
            if ((pCommand->blockSize & 0x3) != 0) {
317
                WRITE_MCI(pMciHw, MCI_RCR, (pCommand->nbBlock * pCommand->blockSize) / 4 + 1);
318
            }
319
            else {
320
                WRITE_MCI(pMciHw, MCI_RCR, (pCommand->nbBlock * pCommand->blockSize) / 4);
321
            }
322
 
323
            WRITE_MCI(pMciHw, MCI_PTCR, AT91C_PDC_RXTEN);
324
            mciIer = AT91C_MCI_ENDRX | STATUS_ERRORS;
325
            // mciIer = AT91C_MCI_RXBUFF | STATUS_ERRORS;
326
        }
327
 
328
        // DATA transfer from host to card
329
        else {
330
            // Sanity check
331
            if (pCommand->nbBlock == 0)
332
                pCommand->nbBlock = 1;
333
            WRITE_MCI(pMciHw, MCI_TPR, (int) pCommand->pData);
334
            // Update the PDC counter
335
            if ((pCommand->blockSize & 0x3) != 0) {
336
                WRITE_MCI(pMciHw, MCI_TCR, (pCommand->nbBlock * pCommand->blockSize) / 4 + 1);
337
            }
338
            else {
339
                WRITE_MCI(pMciHw, MCI_TCR, (pCommand->nbBlock * pCommand->blockSize) / 4);
340
            }
341
            // MCI_BLKE notifies the end of Multiblock command
342
            mciIer = AT91C_MCI_BLKE | STATUS_ERRORS;
343
        }
344
    }
345
    // No data transfer: stop at the end of the command
346
    else {
347
        WRITE_MCI(pMciHw, MCI_MR, mciMr);
348
        mciIer = AT91C_MCI_CMDRDY | STATUS_ERRORS;
349
    }
350
    // Enable MCI clock
351
    MCI_Enable(pMci, ENABLE);
352
 
353
    // Send the command
354
    if((pCommand->conTrans != MCI_CONTINUE_TRANSFER)
355
        || (pCommand->blockSize == 0)) {
356
 
357
        WRITE_MCI(pMciHw, MCI_ARGR, pCommand->arg);
358
        WRITE_MCI(pMciHw, MCI_CMDR, pCommand->cmd);
359
    }
360
 
361
    // In case of transmit, the PDC shall be enabled after sending the command
362
    if ((pCommand->blockSize > 0) && !(pCommand->isRead)) {
363
        WRITE_MCI(pMciHw, MCI_PTCR, AT91C_PDC_TXTEN);
364
    }
365
 
366
    // Ignore data error
367
//    if (pCommand->blockSize == 0) {
368
    {
369
        mciIer &= ~(AT91C_MCI_UNRE | AT91C_MCI_OVRE \
370
            | AT91C_MCI_DTOE | AT91C_MCI_DCRCE);
371
    }
372
 
373
    // Interrupt enable shall be done after PDC TXTEN and RXTEN
374
    WRITE_MCI(pMciHw, MCI_IER, mciIer);
375
 
376
    return 0;
377
}
378
 
379
//------------------------------------------------------------------------------
380
/// Check NOTBUSY and DTIP bits of status register on the given MCI driver.
381
/// Return value, 0 for bus ready, 1 for bus busy
382
/// \param pMci  Pointer to a MCI driver instance.
383
//------------------------------------------------------------------------------
384
unsigned char MCI_CheckBusy(Mci *pMci)
385
{
386
    AT91S_MCI *pMciHw = pMci->pMciHw;
387
    unsigned int status;
388
 
389
    // Enable MCI clock
390
    MCI_Enable(pMci, ENABLE);
391
 
392
    status = READ_MCI(pMciHw, MCI_SR);
393
    // trace_LOG(trace_DEBUG, "status %x\n\r",status);
394
 
395
 
396
    if(((status & AT91C_MCI_NOTBUSY)!=0)
397
        && ((status & AT91C_MCI_DTIP)==0)) {
398
 
399
        // Disable MCI clock
400
        MCI_Enable(pMci, DISABLE);
401
 
402
        return 0;
403
    }
404
    else {
405
        return 1;
406
    }
407
}
408
 
409
//------------------------------------------------------------------------------
410
/// Check BLKE bit of status register on the given MCI driver.
411
/// \param pMci  Pointer to a MCI driver instance.
412
//------------------------------------------------------------------------------
413
unsigned char MCI_CheckBlke(Mci *pMci)
414
{
415
    AT91S_MCI *pMciHw = pMci->pMciHw;
416
    unsigned int status;
417
 
418
    status = READ_MCI(pMciHw, MCI_SR);
419
    // trace_LOG(trace_DEBUG, "status %x\n\r",status);
420
 
421
    if((status & AT91C_MCI_BLKE)!=0) {
422
        return 0;
423
    }
424
    else {
425
        return 1;
426
    }
427
}
428
 
429
//------------------------------------------------------------------------------
430
/// Processes pending events on the given MCI driver.
431
/// \param pMci  Pointer to a MCI driver instance.
432
//------------------------------------------------------------------------------
433
void MCI_Handler(Mci *pMci)
434
{
435
    AT91S_MCI *pMciHw = pMci->pMciHw;
436
    MciCmd *pCommand = pMci->pCommand;
437
    unsigned int status;
438
    unsigned char i;
439
    #if defined(at91rm9200)
440
    unsigned int mciCr, mciSdcr, mciMr, mciDtor;
441
    #endif
442
 
443
    SANITY_CHECK(pMci);
444
    SANITY_CHECK(pMciHw);
445
    SANITY_CHECK(pCommand);
446
 
447
    // Read the status register
448
    status = READ_MCI(pMciHw, MCI_SR) & READ_MCI(pMciHw, MCI_IMR);
449
    // trace_LOG(trace_DEBUG, "status %x\n\r", status);
450
 
451
    // Check if an error has occured
452
    if ((status & STATUS_ERRORS) != 0) {
453
 
454
        // Check error code
455
        if ((status & STATUS_ERRORS) == AT91C_MCI_RTOE) {
456
 
457
            pCommand->status = MCI_STATUS_NORESPONSE;
458
        }
459
        // if the command is SEND_OP_COND the CRC error flag is always present
460
        // (cf : R3 response)
461
        else if (((status & STATUS_ERRORS) != AT91C_MCI_RCRCE)
462
                  || ((pCommand->cmd != SDCARD_APP_OP_COND_CMD)
463
                      && (pCommand->cmd != MMC_SEND_OP_COND_CMD))) {
464
 
465
            pCommand->status = MCI_STATUS_ERROR;
466
        }
467
    }
468
 
469
    // Check if a transfer has been completed
470
    if (((status & AT91C_MCI_CMDRDY) != 0)
471
        || ((status & AT91C_MCI_ENDRX) != 0)
472
        || ((status & AT91C_MCI_RXBUFF) != 0)
473
        || ((status & AT91C_MCI_ENDTX) != 0)
474
        || ((status & AT91C_MCI_BLKE) != 0)
475
        || ((status & AT91C_MCI_RTOE) != 0)) {
476
 
477
        if (((status & AT91C_MCI_ENDRX) != 0)
478
            || ((status & AT91C_MCI_RXBUFF) != 0)
479
            || ((status & AT91C_MCI_ENDTX) != 0)) {
480
 
481
            MCI_Enable(pMci, DISABLE);
482
        }
483
 
484
        /// On AT91RM9200-EK, if stop transmission, software reset MCI.
485
        #if defined(at91rm9200)
486
        if ((pCommand->cmd & AT91C_MCI_TRCMD_STOP) != 0) {
487
            mciMr = READ_MCI(pMciHw, MCI_MR);
488
            mciSdcr = READ_MCI(pMciHw, MCI_SDCR);
489
            mciDtor = READ_MCI(pMciHw, MCI_DTOR);
490
            WRITE_MCI(pMciHw, MCI_CR, AT91C_MCI_SWRST);
491
            // trace_LOG(trace_DEBUG, "reset MCI\n\r");
492
 
493
            WRITE_MCI(pMciHw, MCI_CR, AT91C_MCI_MCIDIS | AT91C_MCI_PWSDIS);
494
            WRITE_MCI(pMciHw, MCI_MR, mciMr);
495
            WRITE_MCI(pMciHw, MCI_SDCR, mciSdcr);
496
            WRITE_MCI(pMciHw, MCI_DTOR, mciDtor);
497
        }
498
        #endif
499
 
500
        // If no error occured, the transfer is successful
501
        if (pCommand->status == MCI_STATUS_PENDING) {
502
            pCommand->status = 0;
503
        }
504
#if 0
505
        if ((status & AT91C_MCI_CMDRDY) != 0)
506
            trace_LOG(trace_DEBUG, ".");
507
        if ((status & AT91C_MCI_ENDRX) != 0)
508
            trace_LOG(trace_DEBUG, "<");
509
        if ((status & AT91C_MCI_ENDTX) != 0)
510
            trace_LOG(trace_DEBUG, "-");
511
        if ((status & AT91C_MCI_BLKE) != 0)
512
            trace_LOG(trace_DEBUG, ">");
513
        trace_LOG(trace_DEBUG, "\n\r");
514
#endif        
515
        // Store the card response in the provided buffer
516
        if (pCommand->pResp) {
517
 
518
            for (i=0; i < pCommand->resSize; i++) {
519
 
520
                pCommand->pResp[i] = READ_MCI(pMciHw, MCI_RSPR[0]);
521
            }
522
        }
523
 
524
        // Disable interrupts
525
        WRITE_MCI(pMciHw, MCI_IDR, READ_MCI(pMciHw, MCI_IMR));
526
 
527
        // Release the semaphore
528
        pMci->semaphore++;
529
 
530
        // Invoke the callback associated with the current command (if any)
531
        if (pCommand->callback) {
532
            (pCommand->callback)(pCommand->status, pCommand);
533
        }
534
    }
535
}
536
 
537
//------------------------------------------------------------------------------
538
/// Returns 1 if the given MCI transfer is complete; otherwise returns 0.
539
/// \param pCommand  Pointer to a MciCmd instance.
540
//------------------------------------------------------------------------------
541
unsigned char MCI_IsTxComplete(MciCmd *pCommand)
542
{
543
    if (pCommand->status != MCI_STATUS_PENDING) {
544
        if (pCommand->status != 0)
545
            printf("MCI_IsTxComplete %d\n\r", pCommand->status);
546
        return 1;
547
    }
548
    else {
549
        return 0;
550
    }
551
}

powered by: WebSVN 2.1.0

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