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.

Problem with writing data to SD card in DK-TM4C129X

Other Parts Discussed in Thread: TMP100

Hello forum,

I'm having problems while a try to write something in an SD card of a DK-TM4C129X dev board. What my code is to read the value of 2 analog inputs (2 potentiometers) and the value of the TMP100 sensor (through I2C) and write them in a .txt file in an SD card. While testing, when I skip the part in which I write the data in the .txt file, everything works fine, e.g. I can successfully mount the drive (with f_mount()) and open a .txt file (with f_open()). But, when I include the portion of the code in which I write the data in the file, I get the following error: "No source available in 0x******" and the program only mounts the drive, but cannot open a file. While debugging, I figured out that the program flow stops when the ROM_SSIConfigSetExpClk(SDC_SSI_BASE, systemClock, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, i, 8); function is called into the set_max_speed() function in the diskio.c file of the FatFs library by ChaN. I've tried some things in order to solve this problem but I haven't done it yet. Do you have something to suggest? I attached my code in order to understand me better.

/*
 * Read 2 ADC inputs (potentiometers), the TMP100 sensor via I2C
 * Prints the values to serial monitor through UART
 *
 * ADC inputs: PE2, PB4
 * TMP100 input: I2C6 (PB6, PB7)
 *
 * Author: Vaggelis Aggelou
 * Date: 15-1-2015
 *
 */

#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/interrupt.c"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/sysctl.c"
#include "driverlib/systick.h"
#include "driverlib/i2c.h"
#include "driverlib/i2c.c"
#include "ff.h"
#include "pinout.h"
#include "driverlib/adc.h"
#include "driverlib/adc.c"
#include "driverlib/gpio.h"
#include "driverlib/gpio.c"
#include "utils/uartstdio.h"
#include "utils/ustdlib.h"
#include "utils/cmdline.h"
#include "driverlib/can.h"
#include "driverlib/can.c"
#include "inc/hw_can.h"

/*
 * Defines
 */
#define SLAVE_ADDR_TMP100	0x4A //TMP100 I2C address
#define RXOBJNUM			1
#define TXOBJNUM			2

typedef struct
{
	uint16_t seconds;
	uint16_t subSeconds;
	uint16_t itemMask;
	uint16_t items[1000];
}tLogRecord;
static tLogRecord demoRec;

/*
 * Global variables
 */
volatile uint32_t systemClock;
static uint32_t adcBuffer[2];
static bool lastTrig = false;
static int16_t tempValueTMP100;

static FATFS fatfsObj;
static FIL fileObj;

void InitADC(void)
{

	//Enables ADC0 peripheral
	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

	//Enables GPIO port E, where the desired ADC pin is
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

	//Now PE2 pin is an ADC pin
	GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2);
	GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4);

	//ADC sequencer 3 configuration
	ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);

	//ADC sequencer 3 step configuration
	//PE2 pin is AIN1 channel
	ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH10);
	ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH1|ADC_CTL_IE|ADC_CTL_END);

}

void AcquireADCData(void)
{
	ADCProcessorTrigger(ADC0_BASE, 1);
	while(!ROM_ADCIntStatus(ADC0_BASE, 1, false))
	{
	}
	ADCIntClear(ADC0_BASE, 1);
	ADCSequenceDataGet(ADC0_BASE, 1, adcBuffer);
}

void InitTempI2C(uint32_t systemClock)
{

	//GPIO and I2C peripherals enable
	SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C6);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
	SysCtlDelay(10);

	//I2C pins configuration
	GPIOPinConfigure(GPIO_PB6_I2C6SCL);
	GPIOPinConfigure(GPIO_PB7_I2C6SDA);
	GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_6);
	GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_7);

	//I2C master block enable
	I2CMasterInitExpClk(I2C6_BASE, systemClock, false);

	//Sets the address that the I2C master places on bus
	I2CMasterSlaveAddrSet(I2C6_BASE, SLAVE_ADDR_TMP100, false); //false indicates that the master writes something to slave.
														 	    //Initialy we do that in order to configure the registers
														 	 	//of the slave device.

	//Changing the value of the configuration register
	I2CMasterDataPut(I2C6_BASE, 0x01);
	I2CMasterControl(I2C6_BASE, I2C_MASTER_CMD_BURST_SEND_START);
	while(I2CMasterBusy(I2C6_BASE));
	while(I2CMasterBusy(I2C6_BASE));
	I2CMasterDataPut(I2C6_BASE, 0x60);
	I2CMasterControl(I2C6_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
	while(I2CMasterBusy(I2C6_BASE));
	while(I2CMasterBusy(I2C6_BASE));

}

int16_t AcquireTMP100Data(void)
{

	int16_t tempDataHigh;
	int16_t tempDataLow;
	int16_t tempData;

	I2CMasterSlaveAddrSet(I2C6_BASE, SLAVE_ADDR_TMP100, false);
	I2CMasterDataPut(I2C6_BASE, 0x00);
	I2CMasterControl(I2C6_BASE, I2C_MASTER_CMD_BURST_SEND_START);
	while(I2CMasterBusy(I2C6_BASE));
	while(I2CMasterBusy(I2C6_BASE));

	//Reading the high byte of temperature value
	I2CMasterSlaveAddrSet(I2C6_BASE, SLAVE_ADDR_TMP100, true);
	I2CMasterControl(I2C6_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
	while(I2CMasterBusy(I2C6_BASE));
	while(I2CMasterBusy(I2C6_BASE));
	SysCtlDelay(1000);
	tempDataHigh = I2CMasterDataGet(I2C6_BASE);

	//Read low byte of temperature value
	I2CMasterControl(I2C6_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
	while(I2CMasterBusy(I2C6_BASE));
	while(I2CMasterBusy(I2C6_BASE));
	SysCtlDelay(1000);
	tempDataLow = I2CMasterDataGet(I2C6_BASE);

	tempDataHigh = tempDataHigh << 4;
	tempDataLow = tempDataLow >> 4;
	tempData = (tempDataHigh | tempDataLow);

	return tempData;

}

int main(void)
{
	tLogRecord *testRec = &demoRec;
	uint32_t countHeader = 0;
	uint32_t countRow = 0;
	FRESULT iFResult;
	uint32_t chanIdx = 0;

	//Enable lazy stacking for interrupt handlers
	ROM_FPULazyStackingEnable();

	systemClock = SysCtlClockFreqSet((SYSCTL_OSC_INT | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_320), 25000000);

	// Enable interrupts
	ROM_IntMasterEnable();

	//Pin configuration
	PinoutSet();

	//Initialize the UART for console I/O.
	UARTStdioConfig(0, 115200, systemClock);

	//ADC0 initialization
	InitADC();
	ADCSequenceEnable(ADC0_BASE, 1);

	//Temperature sensor I2C6 initialization
	InitTempI2C(systemClock);

	//Initialize CAN0
	InitCAN(systemClock);

	int i = 1;
	int j = 0;

	testRec->itemMask = 0x07;
	uint8_t numItems = 0;
	uint16_t tempMask;
	tempMask = testRec->itemMask;
	while(tempMask)
	{
		if(tempMask & 1)
		{
			numItems++;
		}
		tempMask >>= 1;
	}

	while(1)
	{
		AcquireADCData();
		tempValueTMP100 = AcquireTMP100Data();
		if(adcBuffer[0] > 50)
		{
			lastTrig = true;
			for(j = 0; j < 3; j++)
			{
				if(j < 2)
				{
					testRec->items[chanIdx++] = adcBuffer[j];
				}
				else
				{
					testRec->items[chanIdx++] = tempValueTMP100;
				}
			}
			UARTprintf("%i: %i ; %i ; %i\n", i, testRec->items[chanIdx - numItems],
					testRec->items[chanIdx - (numItems - 1)], testRec->items[chanIdx - (numItems - 2)]);
			i++;
		}
		else if((adcBuffer[0] < 50) && (lastTrig == true))
		{
			UARTprintf("STOP LOGGING\n");
			break;
		}
		else
		{
			UARTprintf("NOT LOGGING\n");
		}

		ROM_SysCtlDelay(5000000);
	}

	int k = 0;
	UARTprintf("POT_1,POT_2,TMP100\n");
	while(k < chanIdx)
	{
		k += 3;
		UARTprintf("%i,%i,%i\n", testRec->items[k - numItems],
					testRec->items[k - (numItems - 1)], testRec->items[k - (numItems - 2)]);
	}

	iFResult = f_mount(0, &fatfsObj);
	if(iFResult != FR_OK)
	{
		UARTprintf("CANNOT MOUNT DRIVE\n");
		return(1);
	}
	else
	{
		UARTprintf("DRIVE MOUNTED SUCCESSFULLY\n");
	}
	SysCtlDelay(1000000);

	iFResult = f_open(&fileObj, "0:log1901.txt", FA_WRITE|FA_OPEN_ALWAYS);
	if(iFResult != FR_OK)
	{
		UARTprintf("CANNOT OPEN FILE\n");
		if(iFResult == FR_NOT_READY)
		{
			UARTprintf("ERROR: FR_NOT_READY\n");
		}
		return(1);
	}
	else
	{
		UARTprintf("FILE OPENED SUCCESSFULLY\n");
	}

	iFResult = f_lseek(&fileObj, f_size(&fileObj));
	if(iFResult != FR_OK)
	{
		UARTprintf("CANNOT FIND FREE SPACE\n");
		return(1);
	}
	else
	{
		UARTprintf("FREE SPACE FOUND\n");
	}

	char fileHeaders[] = "POT_1,POT_2,TMP100";
	iFResult = f_write(&fileObj, fileHeaders, sizeof(fileHeaders), (UINT *)&countHeader);
	SysCtlDelay(500000);
	if(iFResult != FR_OK)
	{
		UARTprintf("CANNOT WRITE TO FILE HEADERS\n");
		return(1);
	}
	else
	{
		UARTprintf("FILE HEADERS WRITTEN SUCCESSFULLY\n");
	}

	int k = 0;
	char valueStr[50];
	while(k < chanIdx)
	{
		k += 3;
		sprintf(valueStr, "%i,%i,%i\n", testRec->items[k - numItems],
				testRec->items[k - (numItems - 1)], testRec->items[k - (numItems - 2)]);
		SysCtlDelay(500000);
		iFResult = f_write(&fileObj, valueStr, sizeof(valueStr), (UINT *)&countRow);
		SysCtlDelay(500000);
		if(iFResult != FR_OK)
		{
			UARTprintf("CANNOT WRITE ROW %i\n", k);
			return(1);
		}
		else
		{
			UARTprintf("ROW %i WRITTEN SUCCESSFULLY\n", k);
		}
	}

	f_close(&fileObj);
	f_mount(0, NULL);

	return(1);
}