|
|
View previous topic :: View next topic |
Author |
Message |
Schmobol
Joined: 01 Mar 2004 Posts: 22 Location: Nice, France
|
Bug with write_program_memory() still in CCS 3.206 ? |
Posted: Mon Jul 19, 2004 9:22 am |
|
|
Hi,
I've just read a message of a bug, present last year on CCS 3.177, http://www.ccsinfo.com/forum/viewtopic.php?t=17281&highlight=writeprogrammemory , that has similar symptoms as the one I'm experiencing whatever version up to the last one 3.206. Is it still there ?
In fact, when using the write_program_memory() function with a 18F452 target, some extra locations get erased to FF.
the reported bug by brianj was "it seems that the carry bit is not cleared before the supplied byte count is rotated right to give the word count."
The definition of my Flash write routine (based on the byte factory boorloader)
Code: |
void kind_write_program_eeprom (int32 address, int16 data)
{
int16 current_data;
int16 ee_block[32];
int32 ee_block_address;
int ee_block_index;
current_data = read_program_eeprom (address);
if (current_data != data) {
ee_block_address = address & 0xFFFFFFC0;
ee_block_index = (int)((address & 0x0000003F)>>1);
read_program_memory (ee_block_address, ee_block, 64);
ee_block[ee_block_index] = data;
write_program_memory (ee_block_address, ee_block, 64);
}
}
|
And the processor get completly stuck (because of flash alteration) when I call
Code:
Code: |
kind_write_program_eeprom(label_address(FLAG_CALIBRATION),0xFFFF);
|
For info
Code: |
const int16 FLAG_CALIBRATION=0x55;
|
Any idea would be welcomed, I can't find a way to get out of this situation |
|
|
Guest
|
|
Posted: Mon Jul 19, 2004 9:46 am |
|
|
Quote: | Any idea would be welcomed, I can't find a way to get out of this situation |
I use inline #ASM ... #ENDASM to code my_write_program_memory(), never got caught. |
|
|
schmobolo Guest
|
Bug with write_program_memory() still in CCS 3.206 ? |
Posted: Tue Jul 20, 2004 12:03 am |
|
|
That's probably the best thing to do. Would you be so kind as to post your assembly language routine ? I'm such in a hurry, my boss is waiting for an operationnal software for wednesday ! |
|
|
Guest
|
Re: Bug with write_program_memory() still in CCS 3.206 ? |
Posted: Tue Jul 20, 2004 7:35 am |
|
|
schmobolo wrote: | That's probably the best thing to do. Would you be so kind as to post your assembly language routine ? I'm such in a hurry, my boss is waiting for an operationnal software for wednesday ! |
Actually, all what I have is the following three very basic routines simplified a lot from datasheet section 5.4 and 5.5 for my bootloader with very limited protection. Further more, global interrupt will be disabled in program_flash (). Last of all, I use word address instead of byte address in WRITE_PROGRAM_MEMORY(address, ...) where the address is a byte address. Read datasheet section 5.4 and 5.5 before using these functions!
Best wishes
Code: | #include <18F8720.H> // or <18F452.H>
int16 prog_addr; // word address ! not byte address
int16 prog_data[4]; // 4 words, 8 bytes
#byte data_addr=prog_data
void write_prog_eep_4_word (void); // program 8 bytes, starting from (prog_addr<<1)&0x07
void erase_32_word_flash (void); // erase 64 bytes, starting from (prog_addr<<1)&0x3f
void program_flash (void); // Warning: Global Interrupt will be disabled !
void main(void)
{
prog_addr = 0x0200; // word address
data_addr[0] = 0x1234;
erase_32_word_flash (); // erase 64 bytes,
// starting from (prog_addr<<1)&0x3f
write_prog_eep_4_word (); // program 8 bytes,
// starting from (prog_addr<<1)&0x07
while(1);
}
// --- utility functions --------------------------------------------------------
//
#define TABLAT *(int8 *)(0xFF5) // Data_Byte
#define TBLPTRL *(int8 *)(0xFF6) // Addr_Low
#define TBLPTRH *(int8 *)(0xFF7) // Addr_High
#define TBLPTRU *(int8 *)(0xFF8) // Addr_Upper
void program_flash (void)
{
#asm
BSF 0xFA6, 7 // EECON1.EEPGD
BSF 0xFA6, 2 // EECON1.WREN Enable EEP write
BCF 0xFF2, 7 // INTCON.GIE Disable interrupt
MOVLW 0x55
MOVWF 0xFA7 // EECON2
MOVLW 0xAA
MOVWF 0xFA7 // EECON2
BSF 0xFA6, 1 // EECON1.WR Start programming
NOP
// BSF 0xFF2, 7 // INTCON.GIE
BCF 0xFA6, 2 // EECON1.WREN
#endasm
}
void erase_32_word_flash (void) // erase 64 bytes, starting from (prog_addr<<1)&0x3f
{
TBLPTRU = bit_test (prog_addr,15);// TBLPTRU
*(int16 *)(0xFF6) = (prog_addr<<1);// TBLPTRL & TBLPTRH
#asm
BSF 0xFA6, 4 // EECON1.FREE Enable erase !
#endasm
program_flash();
}
void write_prog_eep_4_word (void) // 4 words, 8 bytes
{
if(((int8)prog_addr & 0x03)==0) // prog_addr must be multiple of 4 (words)
{
TBLPTRU = bit_test (prog_addr,15);
*(int16 *)(0xFF6) = (prog_addr<<1);// TBLPTRL & TBLPTRH
#asm
MOVFF &data_addr, 0xFF5
TBLWT*+
MOVFF &data_addr+1,0xFF5
TBLWT*+
MOVFF &data_addr+2,0xFF5
TBLWT*+
MOVFF &data_addr+3,0xFF5
TBLWT*+
MOVFF &data_addr+4,0xFF5
TBLWT*+
MOVFF &data_addr+5,0xFF5
TBLWT*+
MOVFF &data_addr+6,0xFF5
TBLWT*+
MOVFF &data_addr+7,0xFF5
TBLWT*
#endasm
program_flash();
}
}
|
|
|
|
Schmobol
Joined: 01 Mar 2004 Posts: 22 Location: Nice, France
|
|
Posted: Tue Jul 20, 2004 8:31 am |
|
|
Thank you very much. In the meantime I figured out a solution by modifying the write routine in the 18FXX2 datasheet. And now everything works ! I'll clean up my code when I get out of the rush situation though ! Here is the rough but operational version.
Code: |
void kind_write_program_eeprom (int32 address, int16 data)
{
int16 current_data;
int16 ee_block[32];
int32 ee_block_address;
int ee_block_index;
int counter_hi, counter;
current_data = read_program_eeprom (address);
if (current_data != data) {
ee_block_address = address & 0xFFFFFFC0;
ee_block_index = (int)((address & 0x0000003F)>>1);
read_program_memory (ee_block_address, ee_block, 64);
ee_block[ee_block_index] = data;
disable_interrupts(INT_RDA);
//write_program_memory (eeblockaddress, eeblock, 64);
#ASM
ERASE_BLOCK:
MOVFF &ee_block_address+2,TBLPTRU
MOVFF &ee_block_address+1,TBLPTRH
MOVFF &ee_block_address,TBLPTRL
BSF EECON1,7 // point to FLASH memory
BCF EECON1,6 // access FLASH memory
BSF EECON1,2 // enable write to memory
BSF EECON1,4 // enable Row Erase operation
BCF INTCON, 7 // disable interrupts
MOVLW 0x55
MOVWF EECON2
MOVLW 0xaa
MOVWF EECON2
BSF EECON1,1
BSF INTCON,7
TBLRD*-
WRITE_BUFFER_BACK :
MOVLW 8
MOVWF counter_hi
CLRF FSR0H
MOVLW ee_block
MOVWF FSR0L
BCF INTCON, 7
PROGRAM_LOOP :
MOVLW 8
MOVWF counter
WRITE_WORD_TO_HREGS :
MOVF POSTINC0, W
MOVWF TABLAT
TBLWT+*
DECFSZ counter
BRA WRITE_WORD_TO_HREGS
PROGRAM_MEMORY :
BSF EECON1, 7
BCF EECON1, 6
BSF EECON1, 2
//BCF INTCON, 7
MOVLW 0x55
MOVWF EECON2
MOVLW 0xaa
MOVWF EECON2
BSF EECON1, 1
DECFSZ counter_hi
BRA PROGRAM_LOOP
BCF EECON1, 2
BSF INTCON, 7
#ENDASM
//enable_interrupts(GLOBAL);
vide_buffer_rs232();
enable_interrupts(INT_RDA);
}
}
|
However, when I have time I'll try to implement your version and test it on 18F442
Thank you very much |
|
|
Guest
|
|
Posted: Tue Jul 20, 2004 11:12 am |
|
|
Great to hear your good news!
Oooops, I made two mistakes in my comments and forgot a very important command, now added into main(), the correct version should be Code: | #asm
// BSF 0xFA6, 6 // EECON1, CFGS, select Configuration bits
BCF 0xFA6, 6 // EECON1, CFGS, select Prog_EE and Data_EE
#endasm
erase_32_word_flash (); // erase 64 bytes,
// starting from (prog_addr<<1)&0xffffffc0
write_prog_eep_4_word (); // program 8 bytes,
// starting from (prog_addr<<1)&0xfffffff8
|
BTW, you mentioned that Quote: | I figured out a solution by modifying the write routine in the 18FXX2 datasheet. |
where is the magic ?
Thanks a lot |
|
|
Schmobol
Joined: 01 Mar 2004 Posts: 22 Location: Nice, France
|
|
Posted: Wed Jul 21, 2004 12:27 am |
|
|
The magic is a small detail ! If you use the routine as it is in the datasheet on a 18F442 it doesn't work. You just have to change the way the GIE bit is handled. I clear the bit GIE just before the label PROGRAM_LOOP and restore it at the very end of the routine instead of disabling it only for the write sequence. Otherwise the microcontroller get stuck. |
|
|
Guest
|
|
Posted: Wed Jul 21, 2004 9:16 am |
|
|
Schmobol wrote: | The magic is a small detail ! If you use the routine as it is in the datasheet on a 18F442 it doesn't work. You just have to change the way the GIE bit is handled. I clear the bit GIE just before the label PROGRAM_LOOP and restore it at the very end of the routine instead of disabling it only for the write sequence. Otherwise the microcontroller get stuck. |
Interesting !
You should tell CCS
Thanks |
|
|
|
|
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
|