How to view value of calculated defines

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 Can someone please explain how I can view the value of calculated defines during debug?

   

I have a set of addresses to use as pointers for an array. The first one is defined with a value and the rest are relative to this one.

   

The subsequent item addresses are calculated by adding offset of number of bytes. This keeps it dynamic so if I want to say extend the number of charectors of a string in the array, I only need to change the define for size of that type of string and all the resulting addresses will be recalculated at run time.

   

Ram is fine, I can hover over a variable or set up a watch and can see the value. When I hover over the define in code, I only see the formula I used in the define and not the calculated value. This make is diffcult to debug storage location bugs.

   

Thanks

0 Likes
22 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

No chance to see that! Use windows's calculator set to "programmer"-mode or assign the #defined value to a variable for inspection when debugging.

   

 

   

Bob

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 I changed then all to absulte values but will need to manually adjust them each time I change the size of an item.

   

Next problem is I cannot figure out the EEPROM. I am attempting to write some data to it and read back but I seem to get back all "0". I understand the functions are blocking but added delays for good measure during test. Data sheet says you can write after 5us of starting the component. I stop it after to ensure no accidental write. Below is my attempt to use the compopent after looking at datasheet and example.

   

WRITE TEST

   

  uint16 i;

   

  unsigned char *dataptr;

   

  EEPROM_1_Start();

   

 CyDelay(5);

   

  EEPROM_1_EraseSector(0);

   

  CyDelay(5);

   

  for(i=0;i<EEPROM_ROWS;i++)

   

  {

   

    dataptr = (unsigned char *) Settings+ i * EEPROM_ROWSIZE;

   

    EEPROM_1_Write(dataptr,i);

   

  }

   

EEPROM_1_Stop();

   

}

   

 

   

READ TEST

   

unsigned short i;

   

 reg8 * ReadPtr;

   

 EEPROM_1_Start();

   

  CyDelay(5);  

   

  ReadPtr = (reg8 *) CYDEV_EE_BASE;

   

  for(i = 0u; i < NUM_SETTING_WORDS; i++)

   

  {

   

        Settings = ReadPtr;

   

  }

   

  EEPROM_1_Stop();

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Based on write definition "i" wants to be uint8 -

   

 

   

EEPROM_Write(const uint8 * rowData, uint8 rowNumber)

   

 

   

Same thing for the data. Note char from one compiler to another not

   

necessarily same as uint8.

   

 

   

Regards Dana.

0 Likes
Anonymous
Not applicable
     I think the function prototype should be   
   
        
   
     EEPROM_Write(uint8 * rowData, uint8 rowNumber)   
   
        
   
    where   
   
        
   
     rowData is pointer to the array of 16bytes to be programmed   
   
        
   
     ie you load the array with data first then pass the pointer of the 1st byte to the function   
0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

EEPROM_Write(const uint8 * rowData, uint8 rowNumber)

   

 

   

Above taken from datasheet. PSOC 5LP. Below is GCC handling of

   

the const qualifier. Taken from GCC manual.

   

 

   

A Note On const

   

Many users bring up the idea of using C's keyword const as a means of declaring data to be in Program Space. Doing this would be an abuse of the intended meaning of the const keyword.

   

const is used to tell the compiler that the data is to be "read-only". It is used to help make it easier for the compiler to make certain transformations, or to help the compiler check for incorrect usage of those variables.

   

For example, the const keyword is commonly used in many functions as a modifier on the parameter type. This tells the compiler that the function will only use the parameter as read-only and will not modify the contents of the parameter variable.

   

const was intended for uses such as this, not as a means to identify where the data should be stored. If it were used as a means to define data storage, then it loses its correct meaning (changes its semantics) in other situations such as in the function parameter example.

0 Likes
Anonymous
Not applicable

 I copy mine from creator EEPROM data sheet.

   

My previous post is  just to point out the issue with the write function that needs to get the values from an array, nothing to do with the "const".

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

I looked at datasheet, its "Document Number: 001 -85001 Rev. *B", shows a number

   

of revs to write functions. Creator 3.0 SP2.

   


   

Regards, Dana.

0 Likes
JeCo_264681
Level 5
Level 5
100 replies posted 50 replies posted 25 replies posted

 Instead of #defines, try using typedef enum to set the values of your index pointers. These values should show up in your debug.

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

I didn't realise you could do calculated feilds inside an enum.

0 Likes
JeCo_264681
Level 5
Level 5
100 replies posted 50 replies posted 25 replies posted

 If I understand your intent, let me offer this:

   

typedef enum

   

{

   

var1 = &addr1 // address of some variable put into var1

   

var2 = &addr2 // etc.......

   

var3 = &addr3

   

NUM_VARS

   

}var_select;

   

So NUM_VARS gives the total number of variables which is 3. Now you can reference the addresses of your various arrays via var1, etc. Perhaps the var1, var2 and var4 could be elements of an array.  I haven't tried the actual compile but give it a try and use your code.

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

Does this mean that just to see the calculated addresses I need to do this....

   

#define addr1 0

   

#define addr2 addr1 + 3

   

#define addr3 addr 2 + 17

   

typedef enum

   

{

   

var1 = &addr1 // address of some variable put into var1

   

var2 = &addr2 // etc.......

   

var3 = &addr3 

   

NUM_VARS

   

}var_select;

   

And then set watch window on the enum values to see what the calculated addresses are?

0 Likes
JeCo_264681
Level 5
Level 5
100 replies posted 50 replies posted 25 replies posted

 I don't see why you would need the defines with offsets hard coded. The & symbol just puts the address of the array or string into var1, var2, and var 3.  I'm not sure if you are using arrays or offsets into a particular string.  If you are using various string names, this just sets up addresses to the first element of each string.

   

I haven't tried it, but perhaps var1 var2 var3 could be replaced with var[0], var[1], var[2]. This would be an array containing the addresses of the arrays, variables, or strings you are trying to access. Don't take my word for it. Try it.

0 Likes
JeCo_264681
Level 5
Level 5
100 replies posted 50 replies posted 25 replies posted

I'm not sure if I understand what you are trying to do but if the offsets are really the length of strings, you can use this code to determine the length of the string. It just searches the dereferenced pointer until it detects a null.  The length of the string is reported in i.  There's your string length to calculate the offset to the next string.

   

uint8 i = 0;
while(*p++)  i++;

   

// i contains the length of the string.

   

I re-read your original post. It seems that the length of strings can change dynamically. You might have to declare a variable as volatile since the compiler will not have any knowledge of dynamic changes at run time.

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 Referring to my original post.

   

I wanted to view the calculated addresses of #define I had set up. These are starting addresses for reading various types of information from EEPROM.

   

I have an originating address and then all the other addresses are relative to it.

   

Later I may want to add new data structure or make for entries in existing structure and I don't want to have to calculated new positions all the time.

   

For instance, say one block was storing 5 phone numbers and I set the number of digits to 10, and the following block contained contact names

   

#define PHONE_NUMBERS           0

   

#define CONTACTS                           PHONE_NUMBERS + (NUM_PHONES * DIGITS)

   

This way I can change PHONE_NUMS or DIGITS and not need to recalculate any addresses. But, when I debug to determine whether right data is in correct location, the #define does not show me the actual value assigned of say "Contacts", but it WILL show me that PHONE_NUMBERS has value of "0". It does not seem to like to show a calculated value for define.

   

This si what my original post was talking about.

0 Likes
JeCo_264681
Level 5
Level 5
100 replies posted 50 replies posted 25 replies posted

 typedef struct Customers

   

{

   

char Lname[20];

   

char Fname[20];

   

char Address1[40];

   

char Address2[40];

   

int Phone[13];

   

} Customer;

   

/*Then you can reference these by Customer.Address1 or Customer.Phone While I haven't tried it, these should show you values in debug whereas #include does not show you values. I have to run but I do hope I'm not leading you wrong. It's just a humble suggestion.*/

   

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 I don 't understant how these give me fixed constants I can use for addressing areas in the EEPROM?

   

They look like RAM structs to me. Or, can you save structs directly to EEPROM ?

   

What I do at the moment is copy all my variables into 1 Ram Array called "Settings" and then increment throgh that linear array saving each byte to EEPROM, And same when reading back.

   

 

   

void SaveSettings(void)

   

{

   

    unsigned char i;

   

    Settings[adr_CONFIG] = CONFIGURED;

   

    Settings[adr_REPORTING] = Reporting;

   

    Settings[adr_REPORTTIME] = ReportTime >> 8;

   

    Settings[adr_REPORTTIME + 1] = ReportTime;

   

    sprintf(Settings+adr_PASSWORD,"%s",Password);

   

    sprintf(Settings+adr_SITETITLE,"%s",SiteTitle);

   

    for(i=0;i<NUM_INPUTS;i++)

   

    {

   

        sprintf(Settings + adr_INPUT_START + (i * ofs_NEXTIP) + ofs_IPTITLE,   Din.Title);

   

        sprintf(Settings + adr_INPUT_START + (i * ofs_NEXTIP) + ofs_TRIPTEXT,  Din.TripText);

   

        sprintf(Settings + adr_INPUT_START + (i * ofs_NEXTIP) + ofs_OKTEXT,    Din.OKText);

   

        Settings[adr_INPUT_START + (i * ofs_NEXTIP) + ofs_TRIPDELAY] =         Din.TripTime;

   

        Settings[adr_INPUT_START + (i * ofs_NEXTIP) + ofs_RELEASEDELAY] =      Din.ReleaseTime;

   

        Settings[adr_INPUT_START + (i * ofs_NEXTIP) + ofs_TRIPSTATE] =         Din.TripState;

   

    }

   

    for(i=0;i<NUM_OUTPUTS;i++)

   

    {

   

        sprintf(Settings + adr_OUTPUT_START + (i * ofs_NEXTOP) + ofs_OPTITLE,  Rout.Title);

   

        sprintf(Settings + adr_OUTPUT_START + (i * ofs_NEXTOP) + ofs_RONTEXT,  Rout.OnText);

   

        sprintf(Settings + adr_OUTPUT_START + (i * ofs_NEXTOP) + ofs_ROFFTEXT, Rout.OffText);

   

    }

   

    Settings[adr_NUMPHONES] = NumPhones;

   

    for(i=0;i<NumPhones;i++)

   

    {

   

        sprintf(Settings + adr_NUMPHONES  + (i * ofs_NEXTPHONE) + ofs_NUMBER,  Phone.Number);

   

        sprintf(Settings + adr_NUMPHONES  + (i * ofs_NEXTPHONE) + ofs_CONTACT, Phone.Contact);

   

       

   

    }

   

    UpdateSettings();

   

}

   

 

   

void Get_EEprom_Settings(void)

   

{

   

  unsigned short i;

   

  reg8 * ReadPtr;

   

  EEPROM_1_Start();

   

  CyDelay(1);

   

  ReadPtr = (reg8 *) CYDEV_EE_BASE;

   

  for(i = 0u; i < NUM_SETTING_WORDS; i++)

   

  {

   

        Settings = ReadPtr;

   

  }

   

  EEPROM_1_Stop();

   

}

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 The method I use begs the question, there must be a better way.

   

What would be good is a method of saving the actual variables directly to non-volatile memory without having to unpack them into a linear array and back.

   

Maybe I could set up const structs in Flash that I can write over? But the recommendations from literature found recommend using EEPROM due to the much higher write cycle lifetime etc?

   

Some of my project have no external memory. So I would need to use Flash or EEPROM. Some projects use the FRAM

   

Any ideas for improvments in the way to save these ram structs to memory would be much appreciated.

   

Thanks

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

I am not exactly the C expert here. hli, Marlowe much better.

   

 

   

Basically I create a struct in ram, then knowing its length copy that

   

out to EEPROM byte for byte, or row at a time. In fact sometimes I buffer

   

the end of the struc to pad it to even row size. Then retrieval is trivial,

   

we have the start address of the EE write, and length of data, and start

   

address of RAM struc, then just execute the read in a for loop back to the

   

RAM struc. Simple pointer incs for R/W do all the work.

   

 

   

Regards, Dana.

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

You asked for me?

   

I did something like that a while ago in a project (using an external EEPROM). Basically I did what Dana described: define a struct holding all the data, and then write it (after casting it to uint8_t[]) to the EEPROM. based on the data I needed to store the struct was designed to fit exactly 8 bytes, so 64 of them could be fit into one EEPROM page exactly.

   

In addition, I defined the first byte of the struct as marker.  The EEPROM was 'formatted' at the beginning, filling it with 0x00 (when using Flash memory, this would be 0xff). The marker was 0x42 IIRC. Using this I can, after startup, easily find the first free slot in memory and write starting from there (and actually I could even delete entries and reuse them later, since my struct also had a timestamp).

0 Likes
JeCo_264681
Level 5
Level 5
100 replies posted 50 replies posted 25 replies posted

 I found two links that might help you and me (for a problem I'm trying to solve).

   

http://www.cypress.com/?id=4&rID=39139  It's about EEPROM useage notes.

   

then for me who is trying to get an array into SRAM:

   

http://www.cypress.com/?app=forum&id=2233&rID=71060  See the comments by Bob Marlowe.

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 Thanks for the links. I took a look at them. I have a couple of questions:

   

1. The post was dated in 2011, does the latest Creator have a convenient utility for flash protection now instead of editing the "flashsecurity.txt" file?

   

2. Can I declare several structs and they will be placed in contiguous memory? Or would I need to put all my parameters into one super structure? The program starts with 0 phone numbers and users can add up to 10 numbers with contact names, I suppose I need to set asside the entire block size for all 10 numbers and initiate them all with value = ""

   

For instance:

   

#define NUMPHONES 10

   

#define PHONEDIGITS 20

   

#define CONTACTCHARS 12

   

#define NUMOUTPUTS 4

   

#define TITLECHARS 8

   

typedef struct output_type

   

{

   

  char Status;

   

  char Tripped;

   

  char Title[TITLECHARS];

   

}

   

typedef struct phonetype

   

{

   

    char Number[PHONEDIGITS] ;

   

    char Contact[CONTACTCHARS];

   

}

   

#pragma abd_address 0x7fc0

   

const phonestruct phonenumbers[NUMPHONES]

   

const outputstruct outputparams[NUMOUTPUTS]

   

const 

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

In both Keil (PSOC 3) and GCC (PSOC 4, 5LP) you can force fixed

   

placement of a variable/struc in memory.

   

 

   

FLASH security or EEPROM fixed burn data can be set in the xxprojectnamexx.cydwr

   

entry in workspace explorer. Just double click that project entry and you will see two

   

tabs on the right of the .cydwr window that take care of FLASH and EEPROM.

   

 

   

Regards, Dana.

0 Likes