Trying to get bootloader from SD card working. Sorry, to post code with direct register writes, but all the Tivaware functions don't seem to be available or work from bootloader.
I'm not able to get any data going out the SPI port to the SD card. My hardware is good and my main application will read directories, files, etc. I've read through the datasheet and followed the steps there, but still no data coming out the SPI port. Debugger doesn't work and equivalent Tivaware calls crash the bootloader.
Below is my initialization in the bootloader and the SPI. I ripped the ConfigureSSI() code from Tivaware lib source. Maybe I'm missing something obvious, any help or suggestions would be greatly appreciated.
Regards,
Bob Starr
void ConfigureDevice(void) { #ifdef CRYSTAL_FREQ // // Since the crystal frequency was specified, enable the main oscillator // and clock the processor from it. // #if defined(TARGET_IS_TM4C129_RA0) || \ defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) // // Since the crystal frequency was specified, enable the main oscillator // and clock the processor from it. Check for whether the Oscillator range // has to be set and wait states need to be updated // if(CRYSTAL_FREQ >= 10000000) { HWREG(SYSCTL_MOSCCTL) |= (SYSCTL_MOSCCTL_OSCRNG); HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN | SYSCTL_MOSCCTL_NOXTAL); } else { HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN | SYSCTL_MOSCCTL_NOXTAL); } // // Wait for the Oscillator to Stabilize // Delay(524288); if(CRYSTAL_FREQ > 16000000) { HWREG(SYSCTL_MEMTIM0) = (SYSCTL_MEMTIM0_FBCHT_1_5 | (1 << SYSCTL_MEMTIM0_FWS_S) | SYSCTL_MEMTIM0_EBCHT_1_5 | (1 << SYSCTL_MEMTIM0_EWS_S) | SYSCTL_MEMTIM0_MB1); HWREG(SYSCTL_RSCLKCFG) = (SYSCTL_RSCLKCFG_MEMTIMU | SYSCTL_RSCLKCFG_OSCSRC_MOSC); } else { HWREG(SYSCTL_RSCLKCFG) = (SYSCTL_RSCLKCFG_OSCSRC_MOSC); } #else HWREG(SYSCTL_RCC) &= ~(SYSCTL_RCC_MOSCDIS); Delay(524288); HWREG(SYSCTL_RCC) = ((HWREG(SYSCTL_RCC) & ~(SYSCTL_RCC_OSCSRC_M)) | SYSCTL_RCC_OSCSRC_MAIN); #endif #endif // // Enable SSI peripheral (SSI1 => SDCard) // HWREG(SYSCTL_RCGCSSI) |= SSI_CLOCK_ENABLE; // // Enable the clocks to the SSI and GPIO modules. // HWREG(SYSCTL_RCGCGPIO) |= (SSI_CLKPIN_CLOCK_ENABLE | SSI_FSSPIN_CLOCK_ENABLE | SSI_MISOPIN_CLOCK_ENABLE | SSI_MOSIPIN_CLOCK_ENABLE); // // Make the pin be peripheral controlled. // HWREG(SSI_CLKPIN_BASE + GPIO_O_AFSEL) |= SSI_CLK; // SPI SCK PIN (PB5) HWREG(SSI_CLKPIN_BASE + GPIO_O_PCTL) |= SSI_CLK_PCTL; HWREG(SSI_CLKPIN_BASE + GPIO_O_DEN) |= SSI_CLK; HWREG(SSI_CLKPIN_BASE + GPIO_O_DR4R) |= SSI_CLK; // GPIO 4-mA Drive Select HWREG(SSI_FSSPIN_BASE + GPIO_O_AFSEL) |= SSI_CS; // SPI FSS PIN (PK7) HWREG(SSI_FSSPIN_BASE + GPIO_O_PCTL) |= SSI_CS_PCTL; HWREG(SSI_FSSPIN_BASE + GPIO_O_DEN) |= SSI_CS; HWREG(SSI_FSSPIN_BASE + GPIO_O_DR4R) |= SSI_CS; // GPIO 4-mA Drive Select HWREG(SSI_MISOPIN_BASE + GPIO_O_AFSEL) |= SSI_TX; // SPI MISO PIN (PE5) HWREG(SSI_MISOPIN_BASE + GPIO_O_PCTL) |= SSI_TX_PCTL; HWREG(SSI_MISOPIN_BASE + GPIO_O_DEN) |= SSI_TX; HWREG(SSI_MISOPIN_BASE + GPIO_O_PUR) |= SSI_TX; // GPIO Pull up Select HWREG(SSI_MOSIPIN_BASE + GPIO_O_AFSEL) |= SSI_RX; // SPI MOSI PIN (PE4) HWREG(SSI_MOSIPIN_BASE + GPIO_O_PCTL) |= SSI_RX_PCTL; HWREG(SSI_MOSIPIN_BASE + GPIO_O_DEN) |= SSI_RX; HWREG(SSI_MOSIPIN_BASE + GPIO_O_DR4R) |= SSI_RX; // GPIO 4-mA Drive Select // // We're initializing out of reset, so disable the SSI before making any changes. // HWREG(SSIx_BASE + SSI_O_CR1) &= ~(SSI_CR1_SSE); // // Set SSI protocol to Motorola mode 0 with default clock high and data valid // on the rising edge. SD card needs Motorola Mode 0 (CPOL=0 and CPHA=0) // and default clock speed of 400kHz per SD card specifications. // //HWREG(SSIx_BASE + SSI_O_CR0) = (SSI_CR0_SPH | SSI_CR0_SPO | (DATA_BITS_SSI - 1)); ConfigureSSI(SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 400000, 8); // Enable the synchronous serial interface in master mode. HWREG(SSIx_BASE + SSI_O_CR1) |= SSI_CR1_SSE; } //***************************************************************************** // //! Configure the SSI port the SPI for the SD interface in SPI mode. // //***************************************************************************** void ConfigureSSI(uint32_t ui32Protocol, uint32_t ui32Mode, uint32_t ui32BitRate, uint32_t ui32DataWidth) { uint32_t ui32MaxBitRate; uint32_t ui32RegVal; uint32_t ui32PreDiv; uint32_t ui32SCR; uint32_t ui32SPH_SPO; uint32_t ui32SSIClk = 120000000; // Set the mode. ui32RegVal = (ui32Mode == SSI_MODE_MASTER) ? 0 : SSI_CR1_MS; HWREG(SSIx_BASE + SSI_O_CR1) = ui32RegVal; // Set the clock predivider. ui32MaxBitRate = ui32SSIClk / ui32BitRate; ui32PreDiv = 0; do { ui32PreDiv += 2; ui32SCR = (ui32MaxBitRate / ui32PreDiv) - 1; } while(ui32SCR > 255); // Set the prescaler value HWREG(SSIx_BASE + SSI_O_CPSR) = ui32PreDiv; // Set protocol and clock rate. ui32SPH_SPO = (ui32Protocol & 3) << 6; ui32Protocol &= SSI_CR0_FRF_M; ui32RegVal = (ui32SCR << 8) | ui32SPH_SPO | ui32Protocol | (ui32DataWidth - 1); HWREG(SSIx_BASE + SSI_O_CR0) = ui32RegVal; // Configure the QSSI clock from system clock source HWREG(SSIx_BASE + SSI_O_CC) = SSI_CC_CS_SYSPLL; }