Tool/software: TI C/C++ Compiler
Hi,
I have a structure (KVSpair) which I want to program into Location 0x0 of EEPROM and read back into a similar structure. What I see is only the first element in the structure is populated after Read and the next one leads to segmentation fault ISR looping.
This is a test program to find index of key and its obtain its value where both key and value are strings.
Please help.
I am attaching the test code for you convenience (Whole Program) and I am annotating part of the program which is relevant.
#define NUMKEYS 3
/**************************************************************************************
*
* Variables
*
* ************************************************************************************
*/
// Start address is 0x0 to 0x17FC and where the sizeof(...) words would be written.
#define E2PROM_TEST_ADDRESS 0x0
*************************************************************************************************************
* main.c
* Driver program to calculate size of EEPROM and number of Blocks
* To write into every location from start to 6KB ie 0x0 to 0x17FC
* To read back that data
* Print to UART
**************************************************************************************************/
int main(void) {
uint32_t e2size,e2block;
uint32_t ui32SysClock;
uint32_t ui32EEPROMInit, ui32EEPROMStatus;
// Structure for holding Config parameter Strings
typedef struct {
char *key;
char *value;
}KVSpair, *dict_t ;
// initialize name value pairs
KVSpair KVarray[NUMKEYS] = {
{"UniquePartID\0","GEOM-MFAM-SENSOR\0"},
{"SerialNumber\0","ABCD-1294X-TM4c-xxxx\0"},
{"MachineSerialNumber\0","xxxx-xx-xxxx\0"}
};
KVSpair e2prom_kv_read_value= {"\0","\0"}; /* Read key value struct */
//******************************SET CPU CLOCK AT 120 MHZ***********************************************************************************************//
// Run from the PLL at 120 MHz.
//
ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480), 120000000);
/* EEPROM SETTINGS */
SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0); // EEPROM activate
//
// Wait for the EEPROM module to be ready.
//
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EEPROM0))
{
}
// Wait for the EEPROM Initialization to complete
ui32EEPROMInit = EEPROMInit();
//
// Check if the EEPROM Initialization returned an error
// and inform the application
//
if(ui32EEPROMInit != EEPROM_INIT_OK)
{
while(1)
{
}
}
/* UART SETTINGS */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioConfig(0, 115200, ui32SysClock);
/***************Main Action ****************/
UARTprintf("EEPROM Test Program \r\n");
e2size = EEPROMSizeGet(); // Get EEPROM Size
UARTprintf("EEPROM Size %d bytes\n", e2size);
e2block = EEPROMBlockCountGet(); // Get EEPROM Block Count
UARTprintf("EEPROM Block Count: %d\n", e2block);
***************************************************************************************************
* Config Parameters into EEPROM ********************************************************************
****************************************************************************************************** */
int i = 0;
const char *Key = "UniquePartID\0";
dict_t dict;
dict = KVarray; // pointer to point to our assigned data structure top
// print all keys
// find key
char *tmpStr;
for (i=0;i<NUMKEYS;i++){
// tmpStr = strdup(dict->key); // copy the key at index i to tmp str -- This does not work in Tiva
tmpStr = dict->key;
if (!strcmp(tmpStr, Key)){
// Write Confif Parameter String into EEPROM and read back
UARTprintf("Write Try > Address %u: Struct : {%s,%s}\n", E2PROM_TEST_ADDRESS, dict->key,dict->value);
// Wait for Write operation to complete
ui32EEPROMStatus = EEPROMProgram((uint32_t *)dict, E2PROM_TEST_ADDRESS, sizeof(dict)); //Write struct to start from 0x0000
while (ui32EEPROMStatus == EEPROM_RC_WORKING){
} // wait for current program to complete
//Do not attempt to read if a write is in progress
ui32EEPROMStatus = EEPROMStatusGet(); // This returns status of EEDONE register
if (!ui32EEPROMStatus) // the EEDONE register is all zeroes if EEPROM is idle
EEPROMRead((uint32_t *)&e2prom_kv_read_value, E2PROM_TEST_ADDRESS, sizeof(e2prom_kv_read_value)); //Read from struct at EEPROM start from 0x0000
// EEPROMRead((uint32_t *)&e2prom_kv_read_value.value, E2PROM_TEST_ADDRESS+1, sizeof(e2prom_kv_read_value.value)); //Read from struct at EEPROM start from 0x0000
UARTprintf("Read Try > Address %u: Struct : {%s,%s}\n", E2PROM_TEST_ADDRESS, e2prom_kv_read_value.key,e2prom_kv_read_value.value);
if (i<NUMKEYS-1) dict++;
return i;
}
}//end for
/******************************************************************************************************
* *********Basic Program for reading and writing to EEPROM*************************************
*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_ints.h"
#include "driverlib/gpio.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/eeprom.h"
#include "utils/uartstdio.h"
#include "drivers/pinout.h"
//#define TEST_WHOLE_MEMORY /* Macro to enable whole memory read write block by block */
/* Enable this if you want to ecute the for loop that reads and writes from whole EEPROM memory*/
// number of key value pairs defined statically
#define NUMKEYS 3
/**************************************************************************************
*
* Variables
*
* ************************************************************************************
*/
// Start address is 0x0 to 0x17FC and where the sizeof(...) words would be written.
#define E2PROM_TEST_ADDRESS 0x0
/*************************************************************************************************************
* main.c
* Driver program to calculate size of EEPROM and number of Blocks
* To write into every location from start to 6KB ie 0x0 to 0x17FC
* To read back that data
* Print to UART
**************************************************************************************************/
int main(void) {
uint32_t e2size,e2block;
uint32_t ui32SysClock;
uint32_t ui32EEPROMInit, ui32EEPROMStatus;
#ifdef TEST_WHOLE_MEMORY
// Data Variables and address
uint32_t pui32Data[2];
uint32_t pui32Read[2];
#endif
// Structure for holding Character Strings
struct E2PROM
{
uint8_t value1;
uint8_t value2;
uint16_t value3;
uint8_t value4[12];
};
// Character Strings test
struct E2PROM e2prom_write_value = {5,7,9826, "Hello World"}; /* Write struct */
struct E2PROM e2prom_read_value = {0,0,0,""}; /* Read struct */
// Structure for holding Config parameter Strings
typedef struct {
char *key;
char *value;
}KVSpair, *dict_t ;
// initialize name value pairs
KVSpair KVarray[NUMKEYS] = {
{"UniquePartID\0","GEOM-MFAM-SENSOR\0"},
{"SerialNumber\0","ABCD-1294X-TM4c-xxxx\0"},
{"MachineSerialNumber\0","xxxx-xx-xxxx\0"}
};
KVSpair e2prom_kv_read_value= {"\0","\0"}; /* Read key value struct */
//******************************SET CPU CLOCK AT 120 MHZ***********************************************************************************************//
// Run from the PLL at 120 MHz.
//
ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480), 120000000);
//******************************ENABLE SYSTEM CLOCK FOR ON BOARD LED***********************************************************************************************//
// Enable the GPIO port that is used for the on-board LED.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
// Check if the peripheral access is enabled.
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPION))
{
}
//
// Turn off the LED.
//
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x0);
// Enable the GPIO pin for the LED (PN0). Set the direction as output, and
// enable the GPIO pin for digital function.
GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
SysCtlDelay(20000);
// Turn on board LED
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
//******************************INITIALIZE UART***********************************************************************************************//
/* EEPROM SETTINGS */
SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0); // EEPROM activate
//
// Wait for the EEPROM module to be ready.
//
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EEPROM0))
{
}
// Wait for the EEPROM Initialization to complete
ui32EEPROMInit = EEPROMInit();
//
// Check if the EEPROM Initialization returned an error
// and inform the application
//
if(ui32EEPROMInit != EEPROM_INIT_OK)
{
while(1)
{
}
}
/* UART SETTINGS */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioConfig(0, 115200, ui32SysClock);
/***************Main Action ****************/
UARTprintf("EEPROM Test Program \r\n");
e2size = EEPROMSizeGet(); // Get EEPROM Size
UARTprintf("EEPROM Size %d bytes\n", e2size);
e2block = EEPROMBlockCountGet(); // Get EEPROM Block Count
UARTprintf("EEPROM Block Count: %d\n", e2block);
//*** Test Section***********************************************/
// Write character string into EEPROM and read back
UARTprintf("Write Try > Address %u: Struct : {%u,%u,%u,%s}\n", E2PROM_TEST_ADDRESS, e2prom_write_value.value1, e2prom_write_value.value2, e2prom_write_value.value3, e2prom_write_value.value4);
// Wait for Write operation to complete
ui32EEPROMStatus = EEPROMProgram((uint32_t *)&e2prom_write_value, E2PROM_TEST_ADDRESS, sizeof(e2prom_write_value)); //Write struct to start from 0x0000
while (ui32EEPROMStatus == EEPROM_RC_WORKING){
} // wait for current program to complete
//Do not attempt to read if a write is in progress
ui32EEPROMStatus = EEPROMStatusGet(); // This returns status of EEDONE register
if (!ui32EEPROMStatus) // the EEDONE register is all zeroes if EEPROM is idle
EEPROMRead((uint32_t *)&e2prom_read_value, E2PROM_TEST_ADDRESS, sizeof(e2prom_read_value)); //Read from struct at EEPROM start from 0x0000
UARTprintf("Read Try > Address %u: Struct : {%u,%u,%u,%s}\n", E2PROM_TEST_ADDRESS, e2prom_read_value.value1, e2prom_read_value.value2, e2prom_read_value.value3, e2prom_read_value.value4);
/***************************************************************************************************
* Config Parameters into EEPROM ********************************************************************
****************************************************************************************************** */
int i = 0;
const char *Key = "UniquePartID\0";
dict_t dict;
dict = KVarray; // pointer to point to our assigned data structure top
// print all keys
// find key
char *tmpStr;
for (i=0;i<NUMKEYS;i++){
// tmpStr = strdup(dict->key); // copy the key at index i to tmp str -- This does not work in Tiva
tmpStr = dict->key;
if (!strcmp(tmpStr, Key)){
// Write Confif Parameter String into EEPROM and read back
UARTprintf("Write Try > Address %u: Struct : {%s,%s}\n", E2PROM_TEST_ADDRESS, dict->key,dict->value);
// Wait for Write operation to complete
ui32EEPROMStatus = EEPROMProgram((uint32_t *)dict, E2PROM_TEST_ADDRESS, sizeof(dict)); //Write struct to start from 0x0000
while (ui32EEPROMStatus == EEPROM_RC_WORKING){
} // wait for current program to complete
//Do not attempt to read if a write is in progress
ui32EEPROMStatus = EEPROMStatusGet(); // This returns status of EEDONE register
if (!ui32EEPROMStatus) // the EEDONE register is all zeroes if EEPROM is idle
EEPROMRead((uint32_t *)&e2prom_kv_read_value, E2PROM_TEST_ADDRESS, sizeof(e2prom_kv_read_value)); //Read from struct at EEPROM start from 0x0000
// EEPROMRead((uint32_t *)&e2prom_kv_read_value.value, E2PROM_TEST_ADDRESS+1, sizeof(e2prom_kv_read_value.value)); //Read from struct at EEPROM start from 0x0000
UARTprintf("Read Try > Address %u: Struct : {%s,%s}\n", E2PROM_TEST_ADDRESS, e2prom_kv_read_value.key,e2prom_kv_read_value.value);
if (i<NUMKEYS-1) dict++;
return i;
}
}//end for
/****************************************************************************************************
* Test 6K of EEPROM memory with read word and write words block by block***********************************
********************************************************************************************************/
#ifdef TEST
// Program some data into the EEPROM at address 0x0000.
// Calculate size of EEPROM and number of Blocks in that size
pui32Data[0] = 0xFFFFFFFF;
pui32Data[1] = 0x00000000;
// wait for programming to be over
ui32EEPROMStatus = EEPROMProgram(pui32Data, 0x400, sizeof(pui32Data));
while (ui32EEPROMStatus == EEPROM_RC_WORKING){
}
UARTprintf("Data Written to EEPROM: %d\n", pui32Data);
//
// Read it back.
//Do not attempt to read if a write is in progress
if (ui32EEPROMStatus != EEPROM_RC_WRBUSY)
EEPROMRead(pui32Read, 0x400, sizeof(pui32Read));
UARTprintf("Data read from EEPROM: %d\n", pui32Read);
#endif
#ifdef TEST_WHOLE_MEMORY
int i =0,j=0;
/********************************************************************************************************
// For whole EEPROM: Number of iterations = EEPROMSIZE/NUMBER OF EEPROMBLOCKS :j<(e2size/e2block)
// Calculation is as follows:
// inner loop always traverses each block
// Outer loop is responsible for correct offset into each block from start address
// First block: j=0l; so inner loop goes from 0 to 95 location
// Second iteration of inner loop :j is 1(outer loop) and so we traverse locations 96 onwards to 192..
**********************************************************************************************************/
for (j=0;j<(e2size/e2block);j++) {
for (i=0;i<e2block;i++) {
// One Block
// wait for write to complete
ui32EEPROMStatus = EEPROMProgram(pui32Data,(E2PROM_TEST_ADDRESS+i+j*e2block)
, sizeof(pui32Data));
while (ui32EEPROMStatus == EEPROM_RC_WORKING){
} // wait for current program to complete
//Do not attempt to read if a write is in progress
ui32EEPROMStatus = EEPROMStatusGet(); // This returns status of EEDONE register
if (!ui32EEPROMStatus) // the EEDONE register is all zeroes if EEPROM is idle
EEPROMRead(pui32Read, (E2PROM_TEST_ADDRESS+i+j*e2block), sizeof(pui32Read));
UARTprintf(" Block %d : Location:,%d", j,i);
UARTprintf("Data read from EEPROM: %d\n", pui32Read);
// UARTFlushTx(1); // wait for data to be flushed
} // end inner loop for
UARTprintf("Done Block EEPROM: %d\n", j);
} // end out loop for
UARTprintf("Done Whole EEPROM:\n");
#endif
while (1)
{
}
return 0;
}