I am attemping to port the sd_card code from the DK-TM4C123G example to the EK-TM4C1294XL board to read/write from a microSD card. I have used this post as a reference. I have been semi-successful in communicating with the microSD card. I have been able to display a list of the files in the root directory as well as write a file to the card and read the file back. So I know that my hardware connections and pin assignments are correct or nearly so.
The issues is that the connection is very unreliable. I will be able to successfully run my program, go off to lunch, then come back and it no longer works. There is no rhyme or reason when it will work.
My main method is given below. The below example reads the files/folders in the top level directory of the SD card, writes a file, then reads that file back.
int main(void) { FRESULT iFResult; // Enable lazy stacking for interrupt handlers. This allows floating-point // instructions to be used within interrupt handlers, but at the expense of // extra stack usage. ROM_FPULazyStackingEnable(); // Run from the PLL at 120 MHz. systemClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); // Configure SysTick for a 100Hz interrupt. ROM_SysTickPeriodSet(systemClock / 100); ROM_SysTickEnable(); ROM_SysTickIntEnable(); // Enable interrupts ROM_IntMasterEnable(); // Enable the GPIO Peripheral used by the UART. ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // Enable UART0 ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // Configure GPIO Pins for UART mode. ROM_GPIOPinConfigure(GPIO_PA0_U0RX); ROM_GPIOPinConfigure(GPIO_PA1_U0TX); ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // Initialize the UART for console I/O. UARTStdioConfig(0, 115200, systemClock); UARTprintf("\n\nSD Card Example Program\n"); // Mount the file system, using logical disk 0. iFResult = f_mount(0, &fatFS); if(iFResult != FR_OK) { UARTprintf("f_mount error: %s\n", StringFromFResult(iFResult)); return(1); } else { UARTprintf("SD card mounted.\n"); } iFResult = f_opendir(&dir, path); // Check for error and return if there is a problem. if(iFResult != FR_OK) { // Ensure that the error is reported. UARTprintf("Error from SD Card: %s\n",StringFromFResult(iFResult)); return(iFResult); } else { UARTprintf("Root dir opened.\n"); } // Enter loop to enumerate through all directory entries. for(;;) { // Read an entry from the directory. iFResult = f_readdir(&dir, &fileInfo); // Check for error and return if there is a problem. if(iFResult != FR_OK) { UARTprintf("Error from SD Card: %s\n",StringFromFResult(iFResult)); return(iFResult); } // If the file name is blank, then this is the end of the listing. if(!fileInfo.fname[0]) { break; } // Print file names UARTprintf("(%c) %s\n", (fileInfo.fattrib & AM_DIR) ? 'D' : 'F',fileInfo.fname); } UARTprintf("Done"); FIL fil; uint32_t count = 8*512; iFResult = f_open(&dir, "testfile.txt", FA_CREATE_NEW|FA_WRITE); SysCtlDelay(SysCtlClockGet()/3); if(iFResult != FR_OK) { UARTprintf("fresult: %s\n", StringFromFResult(iFResult)); } else { UARTprintf("\n Opened SD card\n"); } iFResult = f_write(&fil, "Hello world", 11, &count); if(iFResult != FR_OK) { UARTprintf("Error writing to file: %s\n", StringFromFResult(iFResult)); } iFResult = f_close(&fil); f_mount(0, NULL); }
My pin assignments in mmc-ek-tm4c1294xl.c. I am using SSI2 which is pins D0-D3 on the TM4C1294NCPDT
/* Peripheral definitions for EK-TM4C129EXL board */ /* SSI port */ #define SDC_SSI_BASE SSI2_BASE #define SDC_SSI_SYSCTL_PERIPH SYSCTL_PERIPH_SSI2 /* GPIO for SSI pins */ /* CLK pin */ #define SDC_SSI_CLK_GPIO_PORT_BASE GPIO_PORTD_BASE #define SDC_SSI_CLK GPIO_PIN_3 /* TX pin */ #define SDC_SSI_TX_GPIO_PORT_BASE GPIO_PORTD_BASE #define SDC_SSI_TX GPIO_PIN_1 /* RX pin */ #define SDC_SSI_RX_GPIO_PORT_BASE GPIO_PORTD_BASE #define SDC_SSI_RX GPIO_PIN_0 /* CS pin */ #define SDC_SSI_FSS_GPIO_PORT_BASE GPIO_PORTD_BASE #define SDC_SSI_FSS GPIO_PIN_2
My power_on method in mmc-ek-tm4c1294xl.c
static void power_on (void) { /* * This doesn't really turn the power on, but initializes the * SSI port and pins needed to talk to the card. */ /* Enable the peripherals used to drive the SDC on SSI */ ROM_SysCtlPeripheralEnable(SDC_SSI_SYSCTL_PERIPH); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); // Configure GPIO Pins for SSI mode. ROM_GPIOPinConfigure(GPIO_PD0_SSI2XDAT1); ROM_GPIOPinConfigure(GPIO_PD1_SSI2XDAT0); ROM_GPIOPinConfigure(GPIO_PD2_SSI2FSS); ROM_GPIOPinConfigure(GPIO_PD3_SSI2CLK); /* * Configure the appropriate pins to be SSI instead of GPIO. The FSS (CS) * signal is directly driven to ensure that we can hold it low through a * complete transaction with the SD card. */ ROM_GPIOPinTypeSSI(SDC_SSI_TX_GPIO_PORT_BASE, SDC_SSI_TX); ROM_GPIOPinTypeSSI(SDC_SSI_RX_GPIO_PORT_BASE, SDC_SSI_RX); ROM_GPIOPinTypeSSI(SDC_SSI_CLK_GPIO_PORT_BASE, SDC_SSI_CLK); ROM_GPIOPinTypeGPIOOutput(SDC_SSI_FSS_GPIO_PORT_BASE, SDC_SSI_FSS); /* * Set the SSI output pins to 4MA drive strength and engage the * pull-up on the receive line. */ MAP_GPIOPadConfigSet(SDC_SSI_RX_GPIO_PORT_BASE, SDC_SSI_RX, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU); MAP_GPIOPadConfigSet(SDC_SSI_CLK_GPIO_PORT_BASE, SDC_SSI_CLK, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD); MAP_GPIOPadConfigSet(SDC_SSI_TX_GPIO_PORT_BASE, SDC_SSI_TX, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD); MAP_GPIOPadConfigSet(SDC_SSI_FSS_GPIO_PORT_BASE, SDC_SSI_FSS, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD); /* Configure the SSI2 port */ ROM_SSIConfigSetExpClk(SDC_SSI_BASE, systemClock, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 400000, 8); ROM_SSIEnable(SDC_SSI_BASE); /* Set DI and CS high and apply more than 74 pulses to SCLK for the card */ /* to be able to accept a native command. */ send_initial_clock_train(); PowerFlag = 1; }