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