- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Everybody
I'm trying to implement a Em_EEPROM 2.0-Module with PSoC Creator 4.2. to store a calibration value novolatile on a PSoC 4 CY8C4247AXI-M485.
After searching for examples and fiddeling around with the found stuff I'm still lost at the beginning.
I'm not an expert in c-code, so I don't know for example where to put the lines...
const uint8 emEeprom[Em_EEPROM_1_PHYSICAL_SIZE]
__ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};
...that are mentioned in the component datasheet. Put in main.c I get the error "expected ';' after top level declarator"
With the example CE195313 I can't select my device, and other examples I found are for older components.
Any help appreciated
Thomas
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ah; Try making a new project in PSoC creator 4.2, select the device to be CY8C4247AXI-M485, then select the "EEPROM" example. The project should create the example project for EM_EEPROM already ready to be built. Build it, and watch all of the errors disappear. Fwiw:
This is what the example project shows:
/* EEPROM storage in work flash, this is defined in Em_EEPROM.c*/
#if defined (__ICCARM__)
#pragma data_alignment = CY_FLASH_SIZEOF_ROW
const uint8_t Em_EEPROM_em_EepromStorage[Em_EEPROM_PHYSICAL_SIZE] = {0u};
#else
const uint8_t Em_EEPROM_em_EepromStorage[Em_EEPROM_PHYSICAL_SIZE]
__ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};
#endif /* defined (__ICCARM__) */
The example project should be the "crane" for your proverbial "staircase"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Something like this: http://www.cypress.com/file/144961/download ?
Here is a recently updated version of it: Emulated EEPROM
The error you encountered is this: Basically, after every line of code that doesn't end with an opening bracket of parenthesis you should have a semicolon to tell the compiler that the line of code is "complete".
I would expect that the error is referring to you missing a semicolon after the line: const uint8 emEeprom[Em_EEPROM_1_PHYSICAL_SIZE];
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
...Something like this: http://www.cypress.com/file/144961/download ?...
That deals with the module "E2PROM" for PSoC 1 and PSoC Designer. It doesn't exist in PSoC Creator.
...Here is a recently updated version of it: Emulated EEPROM...
That's the Datasheet I was refering to.
...you should have a semicolon...
I thought of that, but when I put a semicolon at the end
const uint8 emEeprom[Em_EEPROM_1_PHYSICAL_SIZE];
__ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};
I get an error in the next line: implicit declaration of function '__ALIGNED' is invalid in C99
That tells me that, with my level of experience, I can't just copy an paste code from the datasheet.
And so I'm looking for a staircase to the next level 😉
Thomas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ah; Try making a new project in PSoC creator 4.2, select the device to be CY8C4247AXI-M485, then select the "EEPROM" example. The project should create the example project for EM_EEPROM already ready to be built. Build it, and watch all of the errors disappear. Fwiw:
This is what the example project shows:
/* EEPROM storage in work flash, this is defined in Em_EEPROM.c*/
#if defined (__ICCARM__)
#pragma data_alignment = CY_FLASH_SIZEOF_ROW
const uint8_t Em_EEPROM_em_EepromStorage[Em_EEPROM_PHYSICAL_SIZE] = {0u};
#else
const uint8_t Em_EEPROM_em_EepromStorage[Em_EEPROM_PHYSICAL_SIZE]
__ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};
#endif /* defined (__ICCARM__) */
The example project should be the "crane" for your proverbial "staircase"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for this stepping stone. First choosing a device and afterwards creating the example worked. I wasn't aware of the fact, that choosing the device afterwards is a problem.
Anyway, I played arround with the project and adapted it to my custom made board for a PsOC 4 (CY8C4247AZI-M485) with a 2x16Char-LCD-Display.
In short I ...
- replaced the UART of the original example with a 2x16Char LCD component
- added two digital input ports for switches to save values to EEPROM
What it does now:
A counter is incremented and its value is displayed on the LCD. If the Save-switch is pressed, the value of the counter is
saved to the EEPROM. If the Restore-switch is pressed the value 0000 is saved to the EEPROM.
Like in the original example every time a value is written to the EEPROM, the number of writing cycles (two digits) is also written to EEPROM.
The LCD displays on the first line the counter-value that is increasing, and on the second line the bytes that were
written and read back from EEPROM. The 2x16 Character Display might look like this:
----------------
Counter: 1565
EEP 1214 Cy# 06
----------------
Cy# 06 means, there have been 6 write cycles so far. (This number is set to 0 after a reprogramming of the PSoC)
After powering up of the device, the bytes are read back from EEPROM and the counter starts counting from that number.
I attached a workspace-bundle. Anyone who points out dangerous code or suggests an improvement is welcome.
Cheers
Thomas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@user_1815019
You're welcome!
Glad you got it working for your project!
Some comments on your project:
You could potentially read the entire EEPROM array when checking for the ASCII_E as the first char, and then only write values if necessary afterwards. This would reduce the overhead and redundancy of reading the first EEPROM value twice, but not really much of an improvement so much as a trade-off depending on what you want the project to do in the future
Your switch doesn't have debouncing from what I can see. This could cause multiple presses each time you physically move the switch. One method around this is to count the time a switch is on/off to force a "minimum on" or "minimum off" time before the switch is acknowledged by software. Especially when you are using flash directly with the switch activation, the flash might wear out really fast if you are reading/writing dozens of times on each switch activation rather than just the one time.
But these are minor things to consider, otherwise your project looks very solid and well done
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
e.pratt_1639216 Thanks for following my journey
I guess in my application I will save calibration values about every other week. So I don't worry much about efficiency.
Concerning the bouncing of the switches: I thought I covered that with my if-statement. But you're right, that can be improved!
Thomas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are using a set/reset switch for the switches, which does work due to the LCD update function delaying 1 second before doing the next iteration. This does mean that you need to hold down the switch for at least a whole second to make sure the EEPROM updates.
I guess I should have finished reading the code first
Nvm then, the debouncing won't be an issue if you only check the switch every second. This does mean you need to hold down the switch for a whole second to trigger the switch however, which is a long time for pressing a switch (Not to mention an erroneous save/restore due to RF triggering the switch at the time it is measure by the CPU).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I wanted to use an interrupt to trigger a "save" or a "restore" event, but I have no luck. The isr doesn't seem to get started.
the two switches a still on port 4[4] and 4[5] but because it's not possible to connect an isr to these ports directly I joined them in a pin-component. See picture below.
In main I write:
....
....
/*Interrupt*/
CY_ISR_PROTO(isr_switches_Function);
uint8 isrFlag = 0u;// status of the Interrupt
uint8 Switches = 0u; // status of the "Switches"-pins
CY_ISR(isr_switches_Function)
{
isrFlag = 1u;
isr_switches_ClearPending();
}
int main(void)
{
__enable_irq();
isr_switches_StartEx(isr_switches_Function);
CyGlobalIntEnable; /* Enable global interrupts */
LCD_Char_1_Start();
....
....
Any Idea why the interrupt isn't working? Is it because port 4 can't make interrupts?
Thanks
Thomas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you open the "isr_switches" component in the schematic, there is a setting for "LEVEL", "DERIVED", "PULSE" for which one will trigger the interrupt. Potentially, you will need to verify that is set to the correct setting. Also, you will want to make sure the debounce component is working based on the directions in its datasheet
I would guess there are APIs for the debouncer component. Possibly you will need to call some of these APIs for it to function correctly.
Also, you could make a small ms timer that checks the status every so often, and if it gets a number of highs or lows in a row then the state of the pin has changed for the switch. See here for debouncing techniques for generic microchips: Switch Bounce and How to Deal with It
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My guess would be it is not the port 4 being uninterruptible; The component for the debouncer has a clock and I would suspect it is polling the pins instead.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
And the phe problem was: I had to clear the interrupt after I handled it
Now it works and doesn't seem to bounce a bit.
Thanks!
Thomas
.......
.......
/*Interrupt*/
CY_ISR_PROTO(isr_switches_Function);
uint8 isrFlag = 0u; // status of the Interrupt
uint8 Switches = 0u; // status of the "Switches"-pins
CY_ISR(isr_switches_Function)
{
Switches = Switches_Read();
if (0x03 != Switches) // otherwise we get also an interrupt after releasing the button
{
isrFlag = 1u;
}
isr_switches_ClearPending();
Switches_ClearInterrupt(); // The interrupt isn't cleared just by reading the switches
}
int main(void)
{
__enable_irq();
isr_switches_StartEx(isr_switches_Function);
CyGlobalIntEnable; /* Enable global interrupts */
LCD_Char_1_Start();
......
......
for(;;)
{
//read the switches
if (isrFlag == 1u)// an Interrupt has occured
{
switch (Switches)
{
case 0x01: // Save
.....
break;
case 0x02: // Restore
.....
break;
}
....
}
....
isrFlag = 0u;// reset interrupt-Flag
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Nice! Sounds perfect now
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
After updating the libraries, projects including EEPROM module stop working. This should not be, if CYPRESS extends the functionality, then they should guarantee backward compatibility.
I cannot confirm email and add messages due to a bug on your site, the email section is not active