This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DK-TM4C123G SD-card code on a TM4C123G

Hi everyone,

I'm trying to port the code from TivaWare_C_Series-2.0.1.11577/examples/boards/dk-tm4c123g/sd-card/sd_card.c to work on my TM4C123GXL Launchpad. I'm using functions from /port/mmc-dk-tm4c123g.c. I've checked the pins and have all the pull up resistors in. However, the code gets stuck when i try to f_open and when i tried to use the code from this topic http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/335963/1178721.aspx#1178721, but i am unable to use functions such as power_on or wait_ready. this brings to me to my question if I did not do my linkers proper or something like that. below are my current code.

#include <stdint.h>
#include <stdbool.h>
#include <string.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"


//*****************************************************************************
//
// 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;
static DIR g_sDirObject;
static FILINFO g_sFileInfo;
static FIL g_sFileObject;

//*****************************************************************************
//
// 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;
	char *pcResultStr;
}
tFResultString;

//*****************************************************************************
//
// A macro to make it easy to add result codes to the table.
//
//*****************************************************************************
#define FRESULT_ENTRY(f)        { (f), (#f) }

//*****************************************************************************
//
// 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),
		FRESULT_ENTRY(FR_DISK_ERR),
		FRESULT_ENTRY(FR_INT_ERR),
		FRESULT_ENTRY(FR_NOT_READY),
		FRESULT_ENTRY(FR_NO_FILE),
		FRESULT_ENTRY(FR_NO_PATH),
		FRESULT_ENTRY(FR_INVALID_NAME),
		FRESULT_ENTRY(FR_DENIED),
		FRESULT_ENTRY(FR_EXIST),
		FRESULT_ENTRY(FR_INVALID_OBJECT),
		FRESULT_ENTRY(FR_WRITE_PROTECTED),
		FRESULT_ENTRY(FR_INVALID_DRIVE),
		FRESULT_ENTRY(FR_NOT_ENABLED),
		FRESULT_ENTRY(FR_NO_FILESYSTEM),
		FRESULT_ENTRY(FR_MKFS_ABORTED),
		FRESULT_ENTRY(FR_TIMEOUT),
		FRESULT_ENTRY(FR_LOCKED),
		FRESULT_ENTRY(FR_NOT_ENOUGH_CORE),
		FRESULT_ENTRY(FR_TOO_MANY_OPEN_FILES),
		FRESULT_ENTRY(FR_INVALID_PARAMETER),
};

//*****************************************************************************
//
// 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();
}

//*****************************************************************************
//
// 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)
{
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

	ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
	ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
	ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

	UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

	UARTStdioConfig(0, 38400, 16000000);
}

//*****************************************************************************
//
// 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;

	ROM_FPULazyStackingEnable();

	ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);


	ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / 100);
	ROM_SysTickEnable();
	ROM_SysTickIntEnable();

	ROM_IntMasterEnable();

	ConfigureUART();

	UARTprintf("\n\nSD Card Example Program\n");

	iFResult = f_mount(0, &g_sFatFs);
	if(iFResult != FR_OK)
	{
		UARTprintf("f_mount error: %s\n", StringFromFResult(iFResult)); //no error message here
		return(1);
	}

	/*power_on();

	BOOL a = wait_ready();

	DSTATUS errd;

	if(a) {
		send_initial_clock_train();
		errd = disk_initialize(0);
		UARTprintf("\nInitialising disk 0. Status = %i\n", errd);
	}*/

	FIL fil;
	uint32_t count = 8*512;
	iFResult = f_open(&fil, "testfile.txt", FA_CREATE_NEW|FA_WRITE); //code breaks here
	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);
}
  • Hello Hong

    The functions like power_on and wait_ready are required as part of the sad card initialization. When you comment it out as linker is not allowing them to build it means that the functions have not been linked to the main code either through an include or due to non availability of the prototype. As indicated in the other thread, if you send us the project zipped we can help check why.

    A thought: Also if the pins are the same between do and the launch pad for the sad card example then why would you need to change anything w.r.t the original code? 

    Regards

    Amit