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.

Compiler/EK-TM4C1294XL: How to read two consecutive location of EEPROM into a structure

Part Number: EK-TM4C1294XL

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

  • First . Use past code (the </> icon when using rich formatting), the code is difficult to read in this format.

    Second, you are populating two pointers from the contents of the EE. That is highly unlikely to be a correct approach.

    Third, your read and write sizes are mismatched

    Fourth, you are passing a size in bytes to the EEPROM routines. IIRC correctly they take size in words.

    Robert

  • Fifth:
    I the question is about one simple copy from eeprom to flash, please try not to paste 3851 lines of code... :)
    My (annoying, I know) suggestion is that the initial question contains just a few lines that poster believes is directly related to the issue, and then later "helpers" can as for more details if needed.
  • // 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 */ 

    // To read and write config parameters into EEPROM

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

  • Pavitra, why this second post?

    Robert
  • Because I thought a concise to the point problem statement including code was wanted.

    Thank you