Browse Source

Improve SD card init on Teensy 3.5 & 3.6

main
PaulStoffregen 8 years ago
parent
commit
af803a9dbe
1 changed files with 12 additions and 5 deletions
  1. +12
    -5
      utility/KinetisSDHC.c

+ 12
- 5
utility/KinetisSDHC.c View File

* Private functions * Private functions
******************************************************************************/ ******************************************************************************/


static uint8_t SDHC_Init(void);
static void SDHC_InitGPIO(void); static void SDHC_InitGPIO(void);
static void SDHC_ReleaseGPIO(void); static void SDHC_ReleaseGPIO(void);
static void SDHC_SetClock(uint32_t sysctl); static void SDHC_SetClock(uint32_t sysctl);


// initialize the SDHC Controller // initialize the SDHC Controller
// returns status of initialization(OK, nonInit, noCard, CardProtected) // returns status of initialization(OK, nonInit, noCard, CardProtected)
uint8_t SDHC_Init(void)
static uint8_t SDHC_Init(void)
{ {
int i;

// Enable clock to SDHC peripheral // Enable clock to SDHC peripheral
SIM_SCGC3 |= SIM_SCGC3_SDHC; SIM_SCGC3 |= SIM_SCGC3_SDHC;


SIM_SCGC6 |= SIM_SCGC6_DMAMUX; SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
SIM_SCGC7 |= SIM_SCGC7_DMA; SIM_SCGC7 |= SIM_SCGC7_DMA;


// Switch of MPU unit (maybe bug of silicon)
// Enable DMA access via MPU (not currently used)
MPU_CESR &= ~MPU_CESR_VLD_MASK; MPU_CESR &= ~MPU_CESR_VLD_MASK;


// De-init GPIO - to prevent unwanted clocks on bus // De-init GPIO - to prevent unwanted clocks on bus
SDHC_IRQSTATEN_BRRSEN | SDHC_IRQSTATEN_BWRSEN | SDHC_IRQSTATEN_DINTSEN | SDHC_IRQSTATEN_BRRSEN | SDHC_IRQSTATEN_BWRSEN | SDHC_IRQSTATEN_DINTSEN |
SDHC_IRQSTATEN_CRMSEN | SDHC_IRQSTATEN_TCSEN | SDHC_IRQSTATEN_CCSEN; SDHC_IRQSTATEN_CRMSEN | SDHC_IRQSTATEN_TCSEN | SDHC_IRQSTATEN_CCSEN;


/* 80 initial clocks */
SDHC_SYSCTL |= SDHC_SYSCTL_INITA;
while (SDHC_SYSCTL & SDHC_SYSCTL_INITA) { };
// initial clocks... SD spec says only 74 clocks are needed, but if Teensy rebooted
// while the card was in middle of an operation, thousands of clock cycles can be
// needed to get the card to complete a prior command and return to a usable state.
for (i=0; i < 50; i++) {
SDHC_SYSCTL |= SDHC_SYSCTL_INITA;
while (SDHC_SYSCTL & SDHC_SYSCTL_INITA) { };
}


// to do - check if this needed // to do - check if this needed
SDHC_IRQSTAT |= SDHC_IRQSTAT_CRM; SDHC_IRQSTAT |= SDHC_IRQSTAT_CRM;

Loading…
Cancel
Save