|
|
View previous topic :: View next topic |
Author |
Message |
Guest Guest
|
Code Corruption in PIC16F876A |
Posted: Wed Mar 22, 2006 10:01 am |
|
|
Hello Guys,
I have been experiencing code corruption issues on my project.
Unit works fine, however sometimes after a power-up reset, program
starts behaving badly. When I read the firmware, the first four words (address 0x00 to 0x03) are changed to non-sensical codes, which are almost always different every time this happens.
Some observations are:
1. I used CCS compiler version 3.235 when I first encountered it.
2. I reverted to version 3.185 and the occurrence was lessened significantly.
3. I have done a similar project on PIC16F876A (using CCS version 3.185) but did not encounter this.
4. Both projects have bootloader codes implemented.
5. The significant difference however is that my current problematic project have Internal EEPROM read and write features.
6. My bootloader code will not allow writes to address 0x00 to 0x03 (even if accidentally sent through the command), since this is part of the bootloader program. This same bootloader code was used in another similar project and did not encounter this.
Some questions are:
1. Will failed writes to the internal eeprom (such as writing during unstable Vcc) affect the program memory?
2. I did not use the CCS function for accessing the internal EEPROM, since I was not able to make it work in my previous project. I made my own function:
Code: |
/*******************************************************************************
FUNCTION: EEP_WriteByte()
INPUT: address and data byte
OUTPUT: NONE
NOTES: Writes a byte in the internal EEPROM
*******************************************************************************/
void EEP_WriteByte(int8 i8Address, int8 i8Data)
{
restart_wdt();
while(FLAG_WRITE_CONTROL){}
REG_EEADR = i8Address;
REG_EEDATA = i8Data;
FLAG_PROGRAM_MEMORY_SELECT = FALSE;
FLAG_WRITE_ENABLE = TRUE;
REG_EECON2 = 0x55;
REG_EECON2 = 0xAA;
FLAG_WRITE_CONTROL = TRUE;
FLAG_WRITE_ENABLE = FALSE;
while(FLAG_WRITE_CONTROL){}
}
|
Is there anything wrong with it which might cause it to do programming on the program memory instead?
Thanks very much! |
|
|
Ttelmah Guest
|
|
Posted: Wed Mar 22, 2006 10:41 am |
|
|
Where do you set EECON1...
If this gets 'left' with '1' in the top bit, then the code will write to the program memory. Your bootloader _will_ be setting this to 1.
I'd suggest that at the end of your bootloader, you clear the bit 'WREN' in EECON1, which inhibiits memory writes, and this bit. Then at the start of the EEPROM code, clear EEPGD (the top bit of this register), - again - then enable WREN, perform the write, and disable WREN.
Only the block being written, should ever be corrupted by a power fail during the operation, but if there is a 'brownout', rather than a full failure, anything is possible.
Best Wishes |
|
|
Guest Guest
|
|
Posted: Wed Mar 22, 2006 11:09 am |
|
|
Sorry I forgot this:
Code: |
//INTERNAL EEPROM ACCESS
#byte REG_EEDATA = 0x010C
#byte REG_EEDATH = 0x010E
#byte REG_EEADR = 0x010D
#byte REG_EEADRH = 0x010F
#byte REG_EECON2 = 0x018D
#byte REG_EECON1 = 0x018C
#bit FLAG_READ_CONTROL = REG_EECON1.0
#bit FLAG_WRITE_CONTROL = REG_EECON1.1
#bit FLAG_WRITE_ENABLE = REG_EECON1.2
#bit FLAG_WRITE_ERROR = REG_EECON1.3
#bit FLAG_PROGRAM_MEMORY_SELECT = REG_EECON1.7
|
After bootloading, the mcu resets using wdt, and based on the datasheet, this almost resets all registers.
Also the EEPGD is renamed to FLAG_PROGRAM_MEMORY_SELECT, and WREN to FLAG_WRITE_ENABLE which then follows what you mentioned.
I was also wondering if the flash data reliability is actually being lessened everytime I bootload since I read somewhere that every write to a flash memory location will degrade the neighboring cells. Therefore, the bootloader code which is normally not updated in the product lifetime will eventually degrade. I was thinking of this since the corrupted code is always 0x00-0x03, which is part of the bootloader code.
Thanks. |
|
|
Ttelmah Guest
|
|
Posted: Wed Mar 22, 2006 11:39 am |
|
|
The only remaining question, is whether you have any interrupts enabled?. Otherwise, the code looks 'right'.
Best Wishes |
|
|
Guest Guest
|
|
Posted: Wed Mar 22, 2006 11:57 am |
|
|
Yes, i use the "disable_interrupts(GLOBAL)" function before calling the routine.
Do you think there is a chance that the program counter gets lost during power-up or power-down/brown-out, and results to performing the code-writing instructions?
In power-up the ram location used for the address is still zero and therefore it might explain the consistent code corruption at 0x00-0x03 and the intermittent behavior of the problem. Note also the corrupted size is equal to one PIC16F876A block (4 words)
Is this even remotely possible? |
|
|
Ttelmah Guest
|
|
Posted: Wed Mar 22, 2006 3:34 pm |
|
|
Assuming your bootloader, is in the start of memory, and cannot re-write itself, why not just turn on the write protection for the first block of memory?...
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|