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);
}