avr32_sdio.c File Reference

#include <gpio.h>
#include <intc.h>
#include <avr32/io.h>
#include <compiler.h>
#include "platform_sdio.h"
#include "printf-stdarg.h"

Go to the source code of this file.

Defines

#define ARRAY_SIZE(a)   sizeof(a) / sizeof(a[0])
#define mdelay(ms)

Functions

static void avr32_irq_handler (void)
void platform_sdio_cmd (U8 idx, U32 arg, U8 flags, U32 *rsp, const U8 *data, U16 len)
void platform_sdio_init (U8 *flags)
void platform_sdio_irq (U8 op)
void platform_sdio_reset (void)
void platform_sdio_rx (U8 *data, U16 len)
void platform_sdio_tx (const U8 *data, U16 len)


Define Documentation

#define ARRAY_SIZE (  )     sizeof(a) / sizeof(a[0])

#define mdelay ( ms   ) 

Value:

do {                         \
        volatile int a = 0;     \
        int i;              \
        for (i = 0; i < ms * 5000; i++) \
            a++;            \
    } while (0)

Definition at line 40 of file avr32_sdio.c.

Referenced by platform_sdio_reset().


Function Documentation

static void avr32_irq_handler ( void   )  [static]

Definition at line 313 of file avr32_sdio.c.

References sdio_irq_handler(), and SDIO_IRQ_RX.

Referenced by platform_init(), and platform_sdio_init().

00313 {
00314         volatile avr32_mci_t *mci = &AVR32_MCI;
00315 
00316     uint8_t status = 0; 
00317 
00318     if (mci->SR.sdioirqa || mci->SR.sdioirqb)
00319         status |= SDIO_IRQ_RX;
00320 
00321         sdio_irq_handler(status);
00322 }
00323 }

void platform_sdio_cmd ( U8  idx,
U32  arg,
U8  flags,
U32 *  rsp,
const U8 *  data,
U16  len 
)

Definition at line 141 of file avr32_sdio.c.

References CMD_FLAG_TO_HOST, and MAX_BLOCK_LEN.

00143 {
00144         volatile avr32_mci_t *mci = &AVR32_MCI;
00145         U32 sr;
00146         union {
00147                 avr32_mci_cmdr_t CMDR;
00148                 U32 cmdr;
00149         } reg = { { 0 } };
00150 
00151         Assert(idx < (1 << 6));
00152         Assert(mci->SR.cmdrdy);
00153     
00154         reg.CMDR.cmdnb = idx;
00155 
00156         switch (idx) {
00157         case 3:
00158                 reg.CMDR.rsptyp = 1; /* R6 */
00159                 break;
00160                 
00161         case 7:
00162                 reg.CMDR.rsptyp = 3; /* R1b */
00163                 break;
00164                 
00165         case 52:
00166                 reg.CMDR.rsptyp = 1; /* R5 */
00167                 break;
00168                 
00169         case 53:
00170                 /* Set length */
00171                 Assert(len <= MAX_BLOCK_LEN);
00172                 mci->BLKR.bcnt = len % MAX_BLOCK_LEN;
00173                 
00174                 reg.CMDR.rsptyp = 1; /* R5 */
00175 
00176                 /* Start data transfer */
00177                 reg.CMDR.trcmd = 1;
00178         
00179                 /* SDIO byte transfer */
00180                 reg.CMDR.trtyp = 4; 
00181                 
00182                 if (flags & CMD_FLAG_TO_HOST)
00183                         reg.CMDR.trdir = 1;
00184                 break;
00185 
00186         default:
00187                 Assert(0);
00188         }
00189     
00190         /* Command is transmitted when CMDR is written */
00191         mci->argr = arg;
00192         mci->cmdr = reg.cmdr;
00193 
00194         /* Wait until command is transmitted and a respone is recvd,
00195          * (only required if rsp is != NULL)
00196          */
00197         while (!mci->SR.cmdrdy);
00198         if (rsp)
00199                 *rsp = mci->rspr0;
00200         
00201         /* Reading sr might reset some status bits, so make a shadow copy */
00202         sr = mci->sr;
00203 #if 0
00204         Assert(!(sr & AVR32_MCI_SR_DTOE_MASK));
00205         Assert(!(sr & AVR32_MCI_SR_OVRE_MASK));
00206         Assert(!(sr & AVR32_MCI_SR_CSTOE_MASK));
00207         Assert(!(sr & AVR32_MCI_SR_RCRCE_MASK));
00208         Assert(!(sr & AVR32_MCI_SR_RDIRE_MASK));
00209         Assert(!(sr & AVR32_MCI_SR_RENDE_MASK));
00210         Assert(!(sr & AVR32_MCI_SR_RINDE_MASK)); 
00211         Assert(!(sr & AVR32_MCI_SR_RTOE_MASK));
00212 #endif
00213 }

void platform_sdio_init ( U8 *  flags  ) 

Definition at line 47 of file avr32_sdio.c.

References ARRAY_SIZE, avr32_irq_handler(), and SDIO_FLAG_POLL.

00048 {   
00049 #ifdef _ASSERT_ENABLE_ /* To silence warning if Assert() macro is empty */ 
00050     volatile avr32_pm_t *pm = &AVR32_PM;
00051 #endif
00052     const gpio_map_t GPIO_MAP = {
00053 #ifdef SDIO_SLOT_A
00054         { AVR32_MCI_CLK_0_PIN, AVR32_MCI_CLK_0_FUNCTION },
00055         { AVR32_MCI_CMD_0_PIN, AVR32_MCI_CMD_0_FUNCTION },
00056         { AVR32_MCI_DATA_0_PIN, AVR32_MCI_DATA_0_FUNCTION },
00057         { AVR32_MCI_DATA_1_PIN, AVR32_MCI_DATA_1_FUNCTION },
00058         { AVR32_MCI_DATA_2_PIN, AVR32_MCI_DATA_2_FUNCTION },
00059         { AVR32_MCI_DATA_3_PIN, AVR32_MCI_DATA_3_FUNCTION }
00060 #else
00061         { AVR32_MCI_CLK_0_PIN, AVR32_MCI_CLK_0_FUNCTION },
00062         { AVR32_MCI_CMD_1_0_PIN, AVR32_MCI_CMD_1_0_FUNCTION },
00063         { AVR32_MCI_DATA_8_0_PIN, AVR32_MCI_DATA_8_0_FUNCTION },
00064         { AVR32_MCI_DATA_9_0_PIN, AVR32_MCI_DATA_9_0_FUNCTION },
00065         { AVR32_MCI_DATA_10_0_PIN, AVR32_MCI_DATA_10_0_FUNCTION },
00066         { AVR32_MCI_DATA_11_0_PIN, AVR32_MCI_DATA_11_0_FUNCTION }
00067 #endif
00068     };
00069     U32 i;
00070 
00071     gpio_enable_module(GPIO_MAP, ARRAY_SIZE(GPIO_MAP));
00072     for (i = 0; i < ARRAY_SIZE(GPIO_MAP); i++)
00073         gpio_enable_pin_pull_up((GPIO_MAP)[i].pin);
00074     
00075     /* Note: MCI_CLK enabled at reset in pm->pbbmask (see 8.6) */
00076     Assert(pm->pbbmask & (1 << 8));
00077 
00078     *flags = 0;
00079 
00080 #ifdef USE_1BIT_MODE
00081     *flags |= SDIO_1BIT_MODE;
00082 #endif
00083  
00084 #ifdef USE_POLL
00085     *flags |= SDIO_FLAG_POLL;
00086     return;
00087 #else
00088     INTC_register_interrupt(&avr32_irq_handler, AVR32_MCI_IRQ,
00089                 AVR32_INTC_INT0);
00090 #endif
00091 }

void platform_sdio_irq ( U8  op  ) 

Definition at line 288 of file avr32_sdio.c.

References IRQ_OP_DISABLE, and IRQ_OP_ENABLE.

00288 {
00289         volatile avr32_mci_t *mci = &AVR32_MCI;
00290 
00291 #ifdef USE_POLL
00292         return;
00293 #endif
00294         
00295 #ifdef SDIO_SLOT_A
00296         if (op == IRQ_OP_ENABLE)
00297                 mci->IER.sdioirqa = 1;
00298         else if (op == IRQ_OP_DISABLE)
00299                 mci->IDR.sdioirqa = 1;
00300         else
00301                 Assert(0);
00302 #else
00303         if (op == IRQ_OP_ENABLE)
00304                 mci->IER.sdioirqb = 1;
00305         else if (op == IRQ_OP_DISABLE)
00306                 mci->IDR.sdioirqb = 1;
00307         else
00308                 Assert(0);
00309 #endif
00310 }
00311 

void platform_sdio_reset ( void   ) 

Definition at line 93 of file avr32_sdio.c.

References mdelay.

00094 {
00095         volatile avr32_mci_t *mci = &AVR32_MCI;
00096 
00097         /* Reset MCI controller. It is not specified in the data sheet how long
00098          * to wait for reset to complete, so we'll just wait a few ms here.
00099          */
00100         mci->CR.swrst = 1;
00101         mdelay(10);
00102 
00103         /* Disable MCI controller during configuration */
00104         mci->CR.mcidis = 1;
00105 
00106         /* Use read proof, otherwise we might not be able to read all data and
00107          * will get overrun errors.
00108          */
00109         mci->MR.rdproof = 1;
00110 
00111         /* Write proof is needed to make 4-bit mode stable since we might not
00112          * be able to fill the fifo fast enough with the CPU.
00113          */
00114         mci->MR.wrproof = 1;
00115 
00116         /* Use maximum values for data timeout */
00117         mci->DTOR.dtocyc = 0xf;
00118         mci->DTOR.dtomul = 0x7;
00119 
00120         /* MCI_CLK = FMCK / (2 * (clkdiv + 1)), FMCK is 60 MHz */
00121         mci->MR.clkdiv = 0;
00122 
00123         /* 4 bit or 1 bit */
00124 #ifdef USE_1BIT_MODE
00125         mci->SDCR.sdcbus = 0;
00126 #else
00127         mci->SDCR.sdcbus = 2;
00128 #endif
00129 
00130         /* Use MCI slot A/B */
00131 #ifdef SDIO_SLOT_A
00132         mci->SDCR.sdcsel = 0;
00133 #else
00134         mci->SDCR.sdcsel = 1;
00135 #endif
00136 
00137         /* Enable MCI controller */
00138         mci->CR.mcien = 1;
00139 }

void platform_sdio_rx ( U8 *  data,
U16  len 
)

Definition at line 253 of file avr32_sdio.c.

00254 {
00255         volatile avr32_mci_t *mci = &AVR32_MCI;
00256         UnionPtr ptr;
00257         
00258         Assert(data);
00259         Assert(len);
00260         
00261         ptr.u8ptr = data;
00262         while (len) {
00263                 U32 rdr;
00264                 while (!mci->SR.rxrdy);
00265                 
00266                 /* XXX when len is not size aligned to 4 bytes, we might
00267                  * write outside the buffer. For now we'll just hope that
00268                  * nothing else live there.
00269                  */
00270 
00271                 /* access data using byte pointers, see platform_sdio_tx()  */
00272                 rdr = mci->rdr;
00273                 ptr.u8ptr[0] = (rdr >> 24) & 0xff;
00274                 ptr.u8ptr[1] = (rdr >> 16) & 0xff;
00275                 ptr.u8ptr[2] = (rdr >> 8) & 0xff;
00276                 ptr.u8ptr[3] = rdr & 0xff;
00277                 
00278                 /* 4 bytes recv'd */
00279                 (void) *ptr.u32ptr++;
00280                 if (len >= 4)
00281                         len -= 4;
00282                 else
00283                         len = 0;
00284         }
00285 }
00286 

void platform_sdio_tx ( const U8 *  data,
U16  len 
)

Definition at line 216 of file avr32_sdio.c.

00217 {
00218         volatile avr32_mci_t *mci = &AVR32_MCI;
00219         UnionCPtr ptr;
00220         
00221         Assert(data);
00222         Assert(len);
00223 
00224         ptr.u8ptr = data;
00225         while (len) {
00226                 while (!mci->SR.txrdy);
00227 
00228                 /* XXX when len is not size aligned to 4 bytes, we might
00229                  * read outside the buffer. Should probably be ok since
00230                  * word size is 4 bytes.
00231                  */
00232 
00233                 /* access data using byte pointers since we might get unaligned
00234                  * data from lwip. The cpu will issue a data abort if we try
00235                  * to access data which is not aligned to 4 bytes using a
00236                  * word pointer.
00237                  */
00238                 mci->tdr = (ptr.u8ptr[0] << 24) | (ptr.u8ptr[1] << 16) |
00239             (ptr.u8ptr[2] << 8) | ptr.u8ptr[3];
00240 
00241                 /* ok, 4 bytes transmitted */
00242                 ptr.u32ptr++;
00243                 if (len >= 4)
00244                         len -= 4;
00245                 else
00246                         len = 0;
00247         }
00248 
00249         /* Wait for the bus to become idle */
00250         while (!mci->SR.xfrdone);
00251 }


Generated on Fri Feb 19 02:24:07 2010 for AVR32 - H&D by  doxygen 1.5.5