CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Bug with write_program_memory() still in CCS 3.206 ?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Schmobol



Joined: 01 Mar 2004
Posts: 22
Location: Nice, France

View user's profile Send private message

Bug with write_program_memory() still in CCS 3.206 ?
PostPosted: Mon Jul 19, 2004 9:22 am     Reply with quote

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








PostPosted: Mon Jul 19, 2004 9:46 am     Reply with quote

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. Very Happy
schmobolo
Guest







Bug with write_program_memory() still in CCS 3.206 ?
PostPosted: Tue Jul 20, 2004 12:03 am     Reply with quote

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 ?
PostPosted: Tue Jul 20, 2004 7:35 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jul 20, 2004 8:31 am     Reply with quote

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








PostPosted: Tue Jul 20, 2004 11:12 am     Reply with quote

Great to hear your good news! Very Happy

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

View user's profile Send private message

PostPosted: Wed Jul 21, 2004 12:27 am     Reply with quote

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








PostPosted: Wed Jul 21, 2004 9:16 am     Reply with quote

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 ! Shocked

You should tell CCS Razz

Thanks
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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