- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I've developed a few prototype products using the PSOC CY8C4246AZI-M445 device. I distributed these products among members of our company for testing. The product is an instrument that gets powered up, used for a few minutes or more and then gets powered down. After some time had passed (maybe a few weeks), a few of the products failed to start up (failed to completely initialize); there was no response using the switches and the LCD only showed the Battery icon light up.
I tried to use the "Debug without programming" feature in PSOC creator 4.2 but I received "Debugger exited unexpectedly during run. Encountered error." If I reprogrammed the meters they began working as expected.
I can see that the battery icon is initialized and that is all. Knowing this, I located the portion of code that initializes this segment and then I followed the subsequent code. I can see that the EEPROM is then read and this is where I suspect the issue lies.
void load()
{
uint16_t eeprom_data;
eeprom_data = mem_read(CALIBRATION_COMPLETE);
if (eeprom_data != COMPLETE)
{
calibrate();
}
Here is the main.c where I configure the EEPROM:
#include "project.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "functions.h"
#include "configure.h"
#include "main.h"
#include "state_machine.h"
#define USED_EEPROM_SECTOR (1u)
//---------------- Global variables --------------------
volatile uint16_t bat_level=100;
//volatile char bat_update_count = BAT_UPDATE_PERIOD;
volatile unsigned char on_hold_time=0;
volatile unsigned char on_down_2s=0;
volatile unsigned char on_down_1s=0;
volatile unsigned char mode_hold_time=0;
volatile unsigned char update_battery = FALSE; //returned to False for debugging
volatile unsigned char minute_timer_expired = FALSE;
//these variables are used to store the buttons state
// in between interruption
volatile unsigned char mode = 0;
volatile unsigned char on = 0;
volatile unsigned long tick = 0;
void init_WDT(void);
cy_en_em_eeprom_status_t returnValue;
//---------------- End Global variables --------------------
//---------------- Interrupts --------------------
CY_ISR(PIN_MODE_HANDLER) // ISR for the Mode Button
{
mode = 1;
Pin_Mode_ClearInterrupt();
}
CY_ISR(PIN_PWR_HANDLER) // ISR for the Power/Hold Button
{
on = 1;
Control_Timer_2s_reset_Write(1); //reset the timer
Pin_Pwr_ClearInterrupt();
}
CY_ISR(TIMER_4SEC_HANDLER) // ISR for updating the battery status
{
update_battery = TRUE;
Timer_ClearInterrupt(1); //See datasheet. Recommended to write '1' to clear
}
CY_ISR(TIMER_2SEC_HANDLER)
{
if (Pin_Pwr_Read() == 1) // Changed to 1 to work with new PCBA April 1,2020
{
on_down_1s = TRUE;
}
Timer_2s_ClearInterrupt(1);
}
CY_ISR(TIMER_1MIN_HANDLER)
{
minute_timer_expired = TRUE;
Timer_1min_ClearInterrupt(1); // see datasheet. Recommended to write '1' to clear
}
//---------------- End Interrupts --------------------
const uint8 emEeprom[EEPROM_1_PHYSICAL_SIZE]
__ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};
int main(void)
{
init();
load();
run();
for(;;)
{
/* Should not reach here */
}
}
void init()
{
// CyGlobalIntEnable; /* Enable global interrupts. */
/* Place your initialization/startup code here (e.g. MyInst_Start()) */
/* Component Setup */
ADC_Start();
Opamp_Start();
ADC_Init();
ADC_Enable();
Timer_Start();
Timer_1min_Start();
Timer_2s_Start();
LCD_Seg_Start();
ADC_SetChanMask(CHANNEL_MASK); //read these channels only
/*INTERRUPT SETUP*/
isr_mode_StartEx( PIN_MODE_HANDLER ); // MODE BUTTON INTERRUPT
isr_pwr_StartEx(PIN_PWR_HANDLER); // ON BUTTON INTERRUPT
isr_timer_4sec_StartEx(TIMER_4SEC_HANDLER); // BATTERY TIMER INTERRUPT
isr_timer_1min_StartEx(TIMER_1MIN_HANDLER); // TIMER 1MIN INTERRUPT
isr_timer_2sec_StartEx(TIMER_2SEC_HANDLER);
returnValue = EEPROM_1_Init((uint32)&emEeprom[0]);
Control_Write(0);
Control_MUX_Write(0);
ShutdownPin_Write(1); // Keep circuit ON
LCD_Seg_ClearDisplay();
/******************************************************************************
* The battery segments unfortunately interfere slightly with the ADC readings.
* Theref
*******************************************************************************/
LCD_Seg_WritePixel(LCD_Seg_BFRAME,LCD_Seg_PIXEL_STATE_ON); // bat frame
LCD_Seg_WritePixel(LCD_Seg_BAT1,LCD_Seg_PIXEL_STATE_ON);
LCD_Seg_WritePixel(LCD_Seg_BAT2,LCD_Seg_PIXEL_STATE_ON);
LCD_Seg_WritePixel(LCD_Seg_BAT3,LCD_Seg_PIXEL_STATE_ON);
LCD_Seg_WritePixel(LCD_Seg_BAT4,LCD_Seg_PIXEL_STATE_ON);
CyGlobalIntEnable; /* Enable global interrupts. */
on = 0; /* Needed to clear these as they were being set */
mode = 0; /* I don't know what triggered the ISRs */
}
/* [] END OF FILE */
I suspect I'm not configuring the EEPROM correctly and this leads to latent failures. Any advice is appreciated.
-Shawn
- Tags:
- eeprom
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello.
I noticed the software has instances of using EEPROM_1... instead of Em_EEPROM_1...
Since this processor uses FLASH to emulate EEPROM, the Em_EEPROM is required (in most cases). Those functions behave quite differently when the wrong one is used.
I suggest reviewing the Em_EEPROM component datasheet for details of the function call naming convention. It's easy to get it mixed up.
There's also an Em_EEPROM code example you can look at: CE195313. It's fairly old, but informative.
Good luck with your project.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I renamed my component. This is why you see the difference in naming.
I updated the component from v2.0 to v2.2. I also enabled redundancy.
If you or anyone else sees any issues with my code, please comment.
thanks