Go to the documentation of this file.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
00033
00034
00035
00054
00055 #if defined(MMC_CLK_PIO_BIT) && defined(MMC_CLK_PIO_ID)
00056 #undef GPIO_ID
00057 #define GPIO_ID MMC_CLK_PIO_ID
00058 #include <cfg/arch/porttran.h>
00059 static INLINE void MMC_CLK_LO(void) { GPIO_SET_LO(MMC_CLK_PIO_BIT); }
00060 static INLINE void MMC_CLK_HI(void) { GPIO_SET_HI(MMC_CLK_PIO_BIT); }
00061 static INLINE void MMC_CLK_EN(void) { GPIO_ENABLE(MMC_CLK_PIO_BIT); }
00062 static INLINE void MMC_CLK_SO(void) { GPIO_OUTPUT(MMC_CLK_PIO_BIT); }
00063 #else
00064 #define MMC_CLK_LO()
00065 #define MMC_CLK_HI()
00066 #define MMC_CLK_EN()
00067 #define MMC_CLK_SO()
00068 #endif
00069
00070 #if defined(MMC_MOSI_PIO_BIT) && defined(MMC_MOSI_PIO_ID)
00071 #undef GPIO_ID
00072 #define GPIO_ID MMC_MOSI_PIO_ID
00073 #include <cfg/arch/porttran.h>
00074 static INLINE void MMC_MOSI_LO(void) { GPIO_SET_LO(MMC_MOSI_PIO_BIT); }
00075 static INLINE void MMC_MOSI_HI(void) { GPIO_SET_HI(MMC_MOSI_PIO_BIT); }
00076 static INLINE void MMC_MOSI_EN(void) { GPIO_ENABLE(MMC_MOSI_PIO_BIT); }
00077 static INLINE void MMC_MOSI_SO(void) { GPIO_OUTPUT(MMC_MOSI_PIO_BIT); }
00078 #else
00079 #define MMC_MOSI_LO()
00080 #define MMC_MOSI_HI()
00081 #define MMC_MOSI_EN()
00082 #define MMC_MOSI_SO()
00083 #endif
00084
00085 #if defined(MMC_MISO_PIO_BIT) && defined(MMC_MISO_PIO_ID)
00086 #undef GPIO_ID
00087 #define GPIO_ID MMC_MISO_PIO_ID
00088 #include <cfg/arch/porttran.h>
00089 static INLINE int MMC_MISO_TEST(void) { return GPIO_GET(MMC_MISO_PIO_BIT); }
00090 static INLINE void MMC_MISO_EN(void) { GPIO_ENABLE(MMC_MISO_PIO_BIT); }
00091 static INLINE void MMC_MISO_SI(void) { GPIO_INPUT(MMC_MISO_PIO_BIT); }
00092 #else
00093 #define MMC_MISO_TEST() (1)
00094 #define MMC_MISO_EN()
00095 #define MMC_MISO_SI()
00096 #endif
00097
00098 #if defined(MMC_CS_PIO_BIT) && defined(MMC_CS_PIO_ID)
00099 #undef GPIO_ID
00100 #define GPIO_ID MMC_CS_PIO_ID
00101 #include <cfg/arch/porttran.h>
00102 static INLINE void MMC_CS_LO(void) { GPIO_SET_LO(MMC_CS_PIO_BIT); }
00103 static INLINE void MMC_CS_HI(void) { GPIO_SET_HI(MMC_CS_PIO_BIT); }
00104 static INLINE int MMC_CS_IS(void) { return GPIO_IS_HI(MMC_CS_PIO_BIT); }
00105 static INLINE void MMC_CS_EN(void) { GPIO_ENABLE(MMC_CS_PIO_BIT); }
00106 static INLINE void MMC_CS_SO(void) { GPIO_OUTPUT(MMC_CS_PIO_BIT); }
00107 #else
00108 #define MMC_CS_LO()
00109 #define MMC_CS_HI()
00110 #define MMC_CS_IS() (1)
00111 #define MMC_CS_EN()
00112 #define MMC_CS_SO()
00113 #endif
00114
00115
00119 typedef struct _MMCDCB {
00120 int dcb_avail;
00121 int dcb_changed;
00122 } MMCDCB;
00123
00124 static MMCDCB mmc_dcb;
00125
00134 static int SbiMmCardInit(void)
00135 {
00136 mmc_dcb.dcb_changed = 0;
00137 if (mmc_dcb.dcb_avail) {
00138 return 0;
00139 }
00140 return -1;
00141 }
00142
00151 static int SbiMmCardSelect(int on)
00152 {
00153 int rc = MMC_CS_IS();
00154
00155
00156 if (on == 1) {
00157 MMC_CS_LO();
00158 } else if (on == 0) {
00159 MMC_CS_HI();
00160 }
00161 return rc;
00162 }
00163
00171 static uint8_t SbiMmCardIo(uint8_t val)
00172 {
00173 uint_fast8_t msk = 0x80;
00174
00175 #if defined(NUTDEBUG)
00176 putchar('[');
00177 if (val != 0xFF) {
00178 printf("s%02X", val);
00179 }
00180 #endif
00181
00182
00183 while (msk) {
00184 MMC_CLK_LO();
00185 if (val & msk) {
00186 MMC_MOSI_HI();
00187 } else {
00188 MMC_MOSI_LO();
00189 }
00190 _NOP(); _NOP(); _NOP(); _NOP();
00191 _NOP(); _NOP(); _NOP(); _NOP();
00192 _NOP(); _NOP(); _NOP(); _NOP();
00193 _NOP(); _NOP(); _NOP(); _NOP();
00194 MMC_CLK_HI();
00195 if (MMC_MISO_TEST()) {
00196 val |= msk;
00197 }
00198 else {
00199 val &= ~msk;
00200 }
00201 msk >>= 1;
00202 }
00203
00204 #if defined(NUTDEBUG)
00205 if (val != 0xFF) {
00206 printf("r%02X", val);
00207 }
00208 putchar(']');
00209 #endif
00210 return val;
00211 }
00212
00223 static int SbiMmCardAvail(void)
00224 {
00225 if (mmc_dcb.dcb_avail) {
00226 if (mmc_dcb.dcb_changed) {
00227 return 2;
00228 }
00229 return 1;
00230 }
00231 return 0;
00232 }
00233
00241 static int SbiMmCardWrProt(void)
00242 {
00243 return 0;
00244 }
00245
00254 static int SbiMmcIfcInit(NUTDEVICE * dev)
00255 {
00256
00257 #if defined(PMC_PCER)
00258 #if defined(MMC_CLK_PIO_ID)
00259 outr(PMC_PCER, _BV(MMC_CLK_PIO_ID));
00260 #endif
00261 #if defined(MMC_MOSI_PIO_ID)
00262 outr(PMC_PCER, _BV(MMC_MOSI_PIO_ID));
00263 #endif
00264 #if defined(MMC_MISO_PIO_ID)
00265 outr(PMC_PCER, _BV(MMC_MISO_PIO_ID));
00266 #endif
00267 #if defined(MMC_CS_PIO_ID)
00268 outr(PMC_PCER, _BV(MMC_CS_PIO_ID));
00269 #endif
00270 #if defined(MMC_CD_PIO_ID)
00271 outr(PMC_PCER, _BV(MMC_CD_PIO_ID));
00272 #endif
00273 #if defined(MMC_WP_PIO_ID)
00274 outr(PMC_PCER, _BV(MMC_WP_PIO_ID));
00275 #endif
00276 #endif
00277
00278
00279 MMC_CLK_HI();
00280 MMC_MOSI_HI();
00281 MMC_CS_HI();
00282
00283
00284 MMC_CLK_EN();
00285 MMC_MOSI_EN();
00286 MMC_MISO_EN();
00287 MMC_CS_EN();
00288
00289
00290 MMC_CLK_SO();
00291 MMC_MOSI_SO();
00292 MMC_MISO_SI();
00293 MMC_CS_SO();
00294
00295 mmc_dcb.dcb_avail = 1;
00296 mmc_dcb.dcb_changed = 0;
00297
00298 return MmCardDevInit(dev);
00299 }
00300
00301 static MMCIFC mmc_ifc = {
00302 SbiMmCardInit,
00303 SbiMmCardIo,
00304 SbiMmCardSelect,
00305 SbiMmCardAvail,
00306 SbiMmCardWrProt
00307 };
00308
00321 NUTDEVICE devSbiMmCard = {
00322 0,
00323 MMC_DEV_NAME,
00324 0,
00325 0,
00326 0,
00327 &mmc_ifc,
00328 &mmc_dcb,
00329 SbiMmcIfcInit,
00330 MmCardIOCtl,
00331 MmCardBlockRead,
00332 MmCardBlockWrite,
00333 #ifdef __HARVARD_ARCH__
00334 MmCardBlockWrite_P,
00335 #endif
00336 MmCardMount,
00337 MmCardUnmount,
00338 0
00339 };
00340