00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00072 #include <cfg/arch.h>
00073 #include <cfg/arch/gpio.h>
00074
00075 #include <sys/event.h>
00076 #include <dev/irqreg.h>
00077 #include <dev/mmcard.h>
00078 #include <dev/sbimmc.h>
00079
00080 #if 0
00081
00082 #define NUTDEBUG
00083 #include <stdio.h>
00084 #endif
00085
00090
00091 #ifndef SPI0_CS_BIT
00092
00093 #define SPI0_CS_BIT 6
00094 #endif
00095
00096 #ifndef SPI0_CLK_BIT
00097
00098 #define SPI0_CLK_BIT 4
00099 #endif
00100
00101 #ifndef SPI0_MOSI_BIT
00102
00103 #define SPI0_MOSI_BIT 5
00104 #endif
00105
00106 #ifndef SPI0_MISO_BIT
00107
00108 #define SPI0_MISO_BIT 3
00109 #endif
00110
00111 #if defined(MCU_AT91R40008) || defined(MCU_AT91SAM7X)
00112
00113 #ifndef SPI0_PE_REG
00114
00116 #define SPI0_PE_REG PIO_PER
00117 #endif
00118
00119 #ifndef SPI0_PD_REG
00120
00122 #define SPI0_PD_REG PIO_PDR
00123 #endif
00124
00125
00126 #ifndef SPI0_OE_REG
00127
00128 #define SPI0_OE_REG PIO_OER
00129 #endif
00130
00131 #ifndef SPI0_OD_REG
00132
00133 #define SPI0_OD_REG PIO_ODR
00134 #endif
00135
00136 #ifndef SPI0_SOD_REG
00137
00138 #define SPI0_SOD_REG PIO_SODR
00139 #endif
00140
00141 #ifndef SPI0_COD_REG
00142
00143 #define SPI0_COD_REG PIO_CODR
00144 #endif
00145
00146 #ifndef SPI0_PDS_REG
00147
00148 #define SPI0_PDS_REG PIO_PDSR
00149 #endif
00150
00151 #ifndef SPI0_ODS_REG
00152
00153 #define SPI0_ODS_REG PIO_ODSR
00154 #endif
00155
00156 #ifdef MMC0_CD_BIT
00157 #if MMC0_CD_BIT == 9
00158 #define SIG_MMC0DETECT sig_INTERRUPT0
00159 #elif MMC0_CD_BIT == 10
00160 #define SIG_MMC0DETECT sig_INTERRUPT1
00161 #elif MMC0_CD_BIT == 11
00162 #define SIG_MMC0DETECT sig_INTERRUPT2
00163 #else
00164 #warning "No external interrupt for card detect"
00165 #undef MMC0_CD_BIT
00166 #endif
00167 #endif
00168
00169 #elif defined(MCU_ATMEGA2561) || defined(MCU_AT90CAN128) || defined(MCU_ATMEGA128) || defined(MCU_ATMEGA103)
00170
00171 #ifndef inr
00172 #define inr(a) inb(a)
00173 #endif
00174 #ifndef outr
00175 #define outr(a, v) outb(a, v)
00176 #endif
00177
00178 #ifndef SPI0_OE_REG
00179 #if SPI0_PORT == AVRPORTA
00180 #define SPI0_OE_REG DDRA
00181 #elif SPI0_PORT == AVRPORTC
00182 #define SPI0_OE_REG DDRC
00183 #elif SPI0_PORT == AVRPORTD
00184 #define SPI0_OE_REG DDRD
00185 #elif SPI0_PORT == AVRPORTE
00186 #define SPI0_OE_REG DDRE
00187 #elif SPI0_PORT == AVRPORTF
00188 #define SPI0_OE_REG DDRF
00189 #elif SPI0_PORT == AVRPORTG
00190 #define SPI0_OE_REG DDRG
00191 #else
00192
00193 #define SPI0_OE_REG DDRB
00194 #endif
00195 #endif
00196
00197 #ifndef SPI0_SOD_REG
00198 #if SPI0_PORT == AVRPORTA
00199 #define SPI0_SOD_REG PORTA
00200 #elif SPI0_PORT == AVRPORTC
00201 #define SPI0_SOD_REG PORTC
00202 #elif SPI0_PORT == AVRPORTD
00203 #define SPI0_SOD_REG PORTD
00204 #elif SPI0_PORT == AVRPORTE
00205 #define SPI0_SOD_REG PORTE
00206 #elif SPI0_PORT == AVRPORTF
00207 #define SPI0_SOD_REG PORTF
00208 #elif SPI0_PORT == AVRPORTG
00209 #define SPI0_SOD_REG PORTG
00210 #else
00211
00212 #define SPI0_SOD_REG PORTB
00213 #endif
00214 #endif
00215
00216 #ifndef SPI0_PDS_REG
00217 #if SPI0_PORT == AVRPORTA
00218 #define SPI0_PDS_REG PINA
00219 #elif SPI0_PORT == AVRPORTC
00220 #define SPI0_PDS_REG PINC
00221 #elif SPI0_PORT == AVRPORTD
00222 #define SPI0_PDS_REG PIND
00223 #elif SPI0_PORT == AVRPORTE
00224 #define SPI0_PDS_REG PINE
00225 #elif SPI0_PORT == AVRPORTF
00226 #define SPI0_PDS_REG PINF
00227 #elif SPI0_PORT == AVRPORTG
00228 #define SPI0_PDS_REG PING
00229 #else
00230
00231 #define SPI0_PDS_REG PINB
00232 #endif
00233 #endif
00234
00235 #elif !defined(SPI0_OE_REG) || !defined(SPI0_SOD_REG) || !defined(SPI0_PDS_REG)
00236 #warning "No SPI bit banging registers for unknown CPU."
00237 #endif
00238
00239 #ifdef SPI0_COD_REG
00240
00241 #define MMC0_CLR_BIT(n) outr(SPI0_COD_REG, _BV(n))
00242
00243 #define MMC0_SET_BIT(n) outr(SPI0_SOD_REG, _BV(n))
00244 #else
00245 #define MMC0_CLR_BIT(n) outr(SPI0_SOD_REG, inr(SPI0_SOD_REG) & ~_BV(n))
00246 #define MMC0_SET_BIT(n) outr(SPI0_SOD_REG, inr(SPI0_SOD_REG) | _BV(n))
00247 #endif
00248
00249 #ifdef SPI0_ODS_REG
00250
00251 #define MMC0_IS_BIT_SET(n) ((inr(SPI0_ODS_REG) & _BV(n)) == _BV(n))
00252 #else
00253 #define MMC0_IS_BIT_SET(n) ((inr(SPI0_SOD_REG) & _BV(n)) == _BV(n))
00254 #endif
00255
00257 #define MMC0_TST_BIT(n) ((inr(SPI0_PDS_REG) & _BV(n)) == _BV(n))
00258
00259
00263 typedef struct _MMCDCB {
00264 int dcb_avail;
00265 int dcb_changed;
00266 } MMCDCB;
00267
00268 static MMCDCB mmc0_dcb;
00269
00278 static int SbiMmCard0Init(void)
00279 {
00280 mmc0_dcb.dcb_changed = 0;
00281 if (mmc0_dcb.dcb_avail) {
00282 return 0;
00283 }
00284 return -1;
00285 }
00286
00295 static int SbiMmCard0Select(int on)
00296 {
00297 int rc = MMC0_IS_BIT_SET(SPI0_CS_BIT);
00298
00299
00300 if (on == 1) {
00301 MMC0_CLR_BIT(SPI0_CS_BIT);
00302 } else if (on == 0) {
00303 MMC0_SET_BIT(SPI0_CS_BIT);
00304 }
00305 return rc;
00306 }
00307
00315 static uint8_t SbiMmCard0Io(uint8_t val)
00316 {
00317 uint8_t msk = 0x80;
00318
00319 #ifdef NUTDEBUG
00320 putchar('[');
00321 if (val != 0xFF) {
00322 printf("s%02X", val);
00323 }
00324 #endif
00325
00326 #if defined(MCU_AT91R40008) && defined(__GNUC__) && 0
00327
00328 asm volatile (
00329 "\nspi_tran_l:\n\t"
00330 "str %7, [%3, %5]" "\n\t"
00331 "tst %0, %2" "\n\t"
00332 "strne %8, [%3, %4]" "\n\t"
00333 "streq %8, [%3, %5]" "\n\t"
00334 "bic %0, %1, %2" "\n\t"
00335 "str %7, [%3, %4]" "\n\t"
00336 "ldr r1, [%3, %6]" "\n\t"
00337 "tst r1, %9" "\n\t"
00338 "orrne %0, %1, %2" "\n\t"
00339 "movs %2, %2, lsr #1""\n\t"
00340 "bne spi_tran_l"
00341 : "=r" (val)
00342 : "0" (val)
00343 , "r" (msk)
00344 , "r" (PIO_BASE)
00345 , "J" (PIO_SODR - PIO_BASE)
00346 , "J" (PIO_CODR - PIO_BASE)
00347 , "J" (PIO_PDSR - PIO_BASE)
00348 , "r" _BV(SPI0_CLK_BIT)
00349 , "r" _BV(SPI0_MOSI_BIT)
00350 , "I" _BV(SPI0_MISO_BIT)
00351 : "r1"
00352 );
00353 #else
00354
00355 while (msk) {
00356 MMC0_CLR_BIT(SPI0_CLK_BIT);
00357 if (val & msk) {
00358 MMC0_SET_BIT(SPI0_MOSI_BIT);
00359 } else {
00360 MMC0_CLR_BIT(SPI0_MOSI_BIT);
00361 }
00362 MMC0_SET_BIT(SPI0_CLK_BIT);
00363 if (MMC0_TST_BIT(SPI0_MISO_BIT)) {
00364 val |= msk;
00365 }
00366 else {
00367 val &= ~msk;
00368 }
00369 msk >>= 1;
00370 }
00371 #endif
00372
00373 #ifdef NUTDEBUG
00374 if (val != 0xFF) {
00375 printf("r%02X", val);
00376 }
00377 putchar(']');
00378 #endif
00379 return val;
00380 }
00381
00392 int SbiMmCard0Avail(void)
00393 {
00394 if (mmc0_dcb.dcb_avail) {
00395 if (mmc0_dcb.dcb_changed) {
00396 return 2;
00397 }
00398 return 1;
00399 }
00400 return 0;
00401 }
00402
00410 int SbiMmCard0WrProt(void)
00411 {
00412 return 0;
00413 }
00414
00415 #ifdef MMC0_CD_BIT
00416
00423 static void SbiMmCard0DetectIrq(void *arg)
00424 {
00425 int mode = NutIrqSetMode(&SIG_MMC0DETECT, NUT_IRQMODE_LOWLEVEL);
00426
00427 if (mode == NUT_IRQMODE_HIGHLEVEL) {
00428 mmc0_dcb.dcb_avail = 0;
00429 }
00430 else {
00431 NutIrqSetMode(&SIG_MMC0DETECT, NUT_IRQMODE_HIGHLEVEL);
00432 mmc0_dcb.dcb_avail = 1;
00433 }
00434 mmc0_dcb.dcb_changed = 1;
00435 }
00436 #endif
00437
00446 static int SbiMmcIfcInit(NUTDEVICE * dev)
00447 {
00448 #ifdef SPI0_PE_REG
00449
00450 outr(SPI0_PE_REG, _BV(SPI0_CLK_BIT) | _BV(SPI0_MOSI_BIT) | _BV(SPI0_CS_BIT) | _BV(SPI0_MISO_BIT));
00451 #endif
00452
00453 #ifdef SPI0_OD_REG
00454
00455 outr(SPI0_OE_REG, _BV(SPI0_CLK_BIT) | _BV(SPI0_MOSI_BIT) | _BV(SPI0_CS_BIT));
00456
00457 outr(SPI0_OD_REG, _BV(SPI0_MISO_BIT));
00458 #else
00459
00460
00461
00462
00463
00464 outr(SPI0_OE_REG, (inr(SPI0_OE_REG) & ~_BV(SPI0_MISO_BIT))
00465 | _BV(SPI0_CLK_BIT) | _BV(SPI0_MOSI_BIT) | _BV(SPI0_CS_BIT));
00466 #endif
00467
00468
00469 outr(SPI0_SOD_REG, _BV(SPI0_CLK_BIT) | _BV(SPI0_MOSI_BIT) | _BV(SPI0_CS_BIT));
00470
00471 #ifdef MMC0_CD_BIT
00472 #ifdef SPI0_PD_REG
00473 outr(SPI0_PD_REG, _BV(MMC0_CD_BIT));
00474 #endif
00475
00476
00477 if (NutRegisterIrqHandler(&SIG_MMC0DETECT, SbiMmCard0DetectIrq, 0)) {
00478 mmc0_dcb.dcb_avail = 1;
00479 }
00480 else {
00481 mmc0_dcb.dcb_avail = 0;
00482 NutIrqSetMode(&SIG_MMC0DETECT, NUT_IRQMODE_LOWLEVEL);
00483 NutIrqEnable(&SIG_MMC0DETECT);
00484 }
00485 #else
00486 mmc0_dcb.dcb_avail = 1;
00487 #endif
00488 mmc0_dcb.dcb_changed = 0;
00489
00490 return MmCardDevInit(dev);
00491 }
00492
00493 static MMCIFC mmc0_ifc = {
00494 SbiMmCard0Init,
00495 SbiMmCard0Io,
00496 SbiMmCard0Select,
00497 SbiMmCard0Avail,
00498 SbiMmCard0WrProt
00499 };
00500
00513 NUTDEVICE devSbiMmc0 = {
00514 0,
00515 {'M', 'M', 'C', '0', 0, 0, 0, 0, 0}
00516 ,
00517 0,
00518 0,
00519 0,
00520 &mmc0_ifc,
00521 &mmc0_dcb,
00522 SbiMmcIfcInit,
00523 MmCardIOCtl,
00524 MmCardBlockRead,
00525 MmCardBlockWrite,
00526 #ifdef __HARVARD_ARCH__
00527 MmCardBlockWrite_P,
00528 #endif
00529 MmCardMount,
00530 MmCardUnmount,
00531 0
00532 };
00533