Tool/software: TI C/C++ Compiler
Hi sir,
I am Facing lots of issue while interfacing SD card with TM4C123. I am new to SD card programming, If any issue is there please let me know.
1.I am trying to display the data in UART terminal. I was getting garbage values in my terminal window. Kept the program in debug mode and checked getting the correct data in the watch window. I am not understanding why in PC terminal garbage values are coming.The baud rate in both program and the terminal window is same.
2. Next issue I was facing inside the disk initialisation condition, the program is continuously running in the given below section and it is not executing further step.
static
BYTE wait_ready (void)
{
BYTE res;
Timer2 = 50; /* Wait for ready in timeout of 500ms */
rcvr_spi();
do
res = rcvr_spi();
while ((res != 0xFF) && Timer2);
return res;
}
where in res I am getting zero continouosly.
Given below is the complete code.
#include "stdint.h" #include "stdbool.h" #include "string.h" #include "stdio.h" #include "inc/hw_memmap.h" #include "driverlib/fpu.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" #include "driverlib/uart.h" #include "utils/uartstdio.h" #include "utils/ustdlib.h" #include "third_party/fatfs/src/ff.h" #include "third_party/fatfs/src/diskio.h" #include "inc/hw_nvic.h" #include "inc/hw_ints.h" #include "third_party/fatfs/port/mmc-dk-tm4c123g.c" //***************************************************************************** // // Defines the size of the buffers that hold the path, or temporary data from // the SD card. There are two buffers allocated of this size. The buffer size // must be large enough to hold the longest expected full path name, including // the file name, and a trailing null character. // // // The following are data structures used by FatFs. // //***************************************************************************** static FATFS g_sFatFs; /* Work area (File system object structure (FATFS)) for logical drive */ //static DIR g_sDirObject; /* Directory object structure (DIR) */ //static FILINFO g_sFileInfo; /* File status structure (FILINFO) */ //static FIL g_sFileObject; /* File object structure (FIL) */ extern void power_on (void); //***************************************************************************** // // A structure that holds a mapping between an FRESULT numerical code, and a // string representation. FRESULT codes are returned from the FatFs FAT file // system driver. // //***************************************************************************** typedef struct { FRESULT iFResult; /* File function return code (FRESULT) */ char *pcResultStr; } tFResultString; //***************************************************************************** // // A macro to make it easy to add result codes to the table. // //***************************************************************************** #define FRESULT_ENTRY(f) { (f), (#f) } //(stringnizing)convert a macro argument into a string constant(#f) in macro definition //***************************************************************************** // // A table that holds a mapping between the numerical FRESULT code and it's // name as a string. This is used for looking up error codes for printing to // the console. // //***************************************************************************** tFResultString g_psFResultStrings[] = { FRESULT_ENTRY(FR_OK), /* (0) Succeeded */ FRESULT_ENTRY(FR_DISK_ERR), /* (1) A hard error occurred in the low level disk I/O layer */ FRESULT_ENTRY(FR_INT_ERR), /* (2) Assertion failed */ FRESULT_ENTRY(FR_NOT_READY), /* (3) The physical drive cannot work */ FRESULT_ENTRY(FR_NO_FILE), /* (4) Could not find the file */ FRESULT_ENTRY(FR_NO_PATH), /* (5) Could not find the path */ FRESULT_ENTRY(FR_INVALID_NAME), /* (6) The path name format is invalid */ FRESULT_ENTRY(FR_DENIED), /* (7) Access denied due to prohibited access or directory full */ FRESULT_ENTRY(FR_EXIST), /* (8) Access denied due to prohibited access */ FRESULT_ENTRY(FR_INVALID_OBJECT), /* (9) The file/directory object is invalid */ FRESULT_ENTRY(FR_WRITE_PROTECTED), /* (10) The physical drive is write protected */ FRESULT_ENTRY(FR_INVALID_DRIVE), /* (11) The logical drive number is invalid */ FRESULT_ENTRY(FR_NOT_ENABLED), /* (12) The volume has no work area */ FRESULT_ENTRY(FR_NO_FILESYSTEM), /* (13) There is no valid FAT volume */ FRESULT_ENTRY(FR_MKFS_ABORTED), /* (14) The f_mkfs() aborted due to any parameter error */ FRESULT_ENTRY(FR_TIMEOUT), /* (15) Could not get a grant to access the volume within defined period */ FRESULT_ENTRY(FR_LOCKED), /* (16) The operation is rejected according to the file sharing policy */ FRESULT_ENTRY(FR_NOT_ENOUGH_CORE), /* (17) LFN working buffer could not be allocated */ FRESULT_ENTRY(FR_TOO_MANY_OPEN_FILES), /* (18) Number of open files > _FS_SHARE */ FRESULT_ENTRY(FR_INVALID_PARAMETER), /* (19) Given parameter is invalid */ }; //***************************************************************************** // // A macro that holds the number of result codes. // //***************************************************************************** #define NUM_FRESULT_CODES (sizeof(g_psFResultStrings) / \ sizeof(tFResultString)) //***************************************************************************** // // This function returns a string representation of an error code that was // returned from a function call to FatFs. It can be used for printing human // readable error messages. // //***************************************************************************** const char * StringFromFResult(FRESULT iFResult) { uint_fast8_t ui8Idx; // // Enter a loop to search the error code table for a matching error code. // for(ui8Idx = 0; ui8Idx < NUM_FRESULT_CODES; ui8Idx++) { // // If a match is found, then return the string name of the error code. // if(g_psFResultStrings[ui8Idx].iFResult == iFResult) { return(g_psFResultStrings[ui8Idx].pcResultStr); } } // // At this point no matching code was found, so return a string indicating // an unknown error. // return("UNKNOWN ERROR CODE"); } //***************************************************************************** // // This is the handler for this SysTick interrupt. FatFs requires a timer tick // every 10 ms for internal timing purposes. // //***************************************************************************** void SysTickHandler(void) { disk_timerproc(); //Function inside mmc-dk-tm4c123g.c } //***************************************************************************** // // The error routine that is called if the driver library encounters an error. // //***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif //***************************************************************************** // // Configure the UART and its pins. This must be called before UARTprintf(). // //***************************************************************************** void ConfigureUART(void) { // // Enable GPIO port A which is used for UART0 pins. // TODO: change this to whichever GPIO port you are using. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Enable UART0 so that we can configure the clock. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // // Configure the pin muxing for UART0 functions on port A0 and A1. // This step is not necessary if your part does not support pin muxing. // TODO: change this to select the port/pin you are using. // ROM_GPIOPinConfigure(GPIO_PA0_U0RX); ROM_GPIOPinConfigure(GPIO_PA1_U0TX); // // Use the internal 8MHz oscillator as the UART clock source. // // UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,(UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE)); // // Select the alternate (UART) function for these pins. // TODO: change this to select the port/pin you are using. // //ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); //ROM_UARTCharPut(UART0_BASE,'A'); //UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); // // Initialize the UART for console I/O. // UARTStdioConfig(0, 9600, 8000000); UARTprintf("\n\nSD Card Program\n"); //SysCtlDelay(100); } //***************************************************************************** // // The program main function. It performs initialization, then runs a command // processing loop to read commands from the console. // //***************************************************************************** int main(void) { //int nStatus; 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(); //ROM_SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL |SYSCTL_XTAL_8MHZ|SYSCTL_OSC_MAIN);//8MHz crystall oscilator ROM_SysCtlClockSet(SYSCTL_XTAL_8MHZ|SYSCTL_OSC_MAIN|SYSCTL_USE_OSC|SYSCTL_SYSDIV_5);//8MHz crystall oscilator // // Configure SysTick for a 100Hz interrupt. The FatFs driver wants a 10 ms // tick. // ROM_IntMasterEnable(); ROM_SysTickPeriodSet(SysCtlClockGet()/100); ROM_SysTickIntEnable(); ROM_SysTickEnable(); // //Systick interrupt enable // IntMasterEnable();// Enable interrupts to the processor. // SysTickPeriodSet(79997); // Set up the period for the SysTick timer of 1ms. // SysTickIntEnable(); // Enable the SysTick Interrupt. // SysTickEnable();// Enable SysTick. SysTickEnable();// Enable SysTick. // SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0); // while(!SysCtlPeripheralReady(SYSCTL_PERIPH_SSI0)); // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA)); // GPIOPinConfigure(GPIO_PA2_SSI0CLK); // GPIOPinConfigure(GPIO_PA3_SSI0FSS); // GPIOPinConfigure(GPIO_PA4_SSI0RX); // GPIOPinConfigure(GPIO_PA5_SSI0TX); // GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 |GPIO_PIN_3 | GPIO_PIN_2); // // Initialize the UART as a console for text I/O. // ConfigureUART(); SysCtlDelay(100); UARTprintf("\n\nSD Card Example Program\n"); iFResult = f_mount(0, &g_sFatFs);// /* Mount the file system, using logical disk 1. */ if(iFResult != FR_OK) { UARTprintf("f_mount error: %s\n", StringFromFResult(iFResult)); SysCtlDelay(1000); return(1); } power_on(); BOOL a = wait_ready(); //Wait for card ready DSTATUS errd; if(a) { send_initial_clock_train(); errd = disk_initialize(0); UARTprintf("\nInitialising disk 0. Status = %i\n", errd); } /********************************************************************************************************* create a file testfile.txt with the following content - ***********************************************************************************************************/ FIL fil; //fill: Pointer to the blank file object structure uint32_t count = 8*512; //multiple write block(4096bytes) iFResult = f_open(&fil, "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); }
Please help me to solve the issue.
Looking forward for a quick reply.
Regards,
Alphy