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