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

write_program_memory doesn't work for PIC24H

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



Joined: 09 Aug 2008
Posts: 3

View user's profile Send private message

write_program_memory doesn't work for PIC24H
PostPosted: Sat Aug 09, 2008 5:31 pm     Reply with quote

Hi everyone,
I’ve been going through all the posts regarding this function but still I can’t make it work. Eventually I need to write a routine that writes to program memory a long table of values received via serial port (which I’ve done using the write_program_eeprom for other PIC series, for the PIC24 series this function is not available), but for now I just want to write one value and read it back. This code just waits for an RS232 interrupt, receives 4 bytes, writes one of them to program memory and then reads it back and sends it over the serial port. The write never seems to occur, I always read back 255.
I’m using PIC24HJ128GP306, MPLAB IDE 8.14, CCS compiler 4.077.
Any ideas? Thanks

Code:
#include <24HJ128GP306.h>   
#device adc=10

#use fast_io (B)
#use fast_io (D)
#fuses HS,NOWDT,PR_PLL
#use delay(clock=80M, oscillator=20M)                                                                     
#use rs232(baud=19200,parity=N,xmit=PIN_F3,rcv=PIN_F2,bits=8,ERRORS, STREAM=HOSTPC)

void opcode_processor(int opcode,int byte1,int byte2,int byte3);
void rs232_handler();                                 

#include <stdlib.h>
#include <math.h>

int8    opcode,byte1,byte2,byte3,ack,qdata;       

void main(){
   set_tris_b (0x00);                           
   set_tris_d (0x00);                         
   enable_interrupts(int_rda);           
   enable_interrupts(intr_global);             
}

#int_rda
void  rs232_handler(){
    opcode=getc(HOSTPC);               
    if(opcode != 0xFF && opcode !=0x00)
    {
   byte1=getc(HOSTPC);                 
   byte2=getc(HOSTPC);                 
   byte3=getc(HOSTPC);                 
   while (kbhit()) getc(HOSTPC);           
   disable_interrupts(int_rda2);
   opcode_processor(opcode,byte1,byte2,byte3);           
   }
}

void opcode_processor(int opcode,int byte1, int byte2, int byte3)
{

   switch (opcode)
   {
     case 1:                           
      disable_interrupts(intr_global);
     
      write_program_memory(0x000600,&byte1,1);                                           
      delay_ms(1);
      read_program_memory(0x000600,&qdata,1);   
      delay_ms(100);
      putc(opcode, HOSTPC);
      putc(0, HOSTPC);
      putc(qdata, HOSTPC);
      putc(3, HOSTPC);
      enable_interrupts(intr_global);
   break;
   
    default:
    break;

      }
   enable_interrupts(int_rda);
   
}
Ttelmah
Guest







PostPosted: Sun Aug 10, 2008 3:30 am     Reply with quote

The whole thinking is screwy....
The interrupt says _one_ character is waiting. Just that. You get this in the first line of the interrupt. Then if this is anything but 00, of FF, sit and wait for three characters to arrive. Then 'kbhit', will _never_ be true (you have read the character that is waiting, and waited for three more). You then disable the wrong interrupt, and call the 'opcode processor'. In this, _which is inside the interrupt_, at the end, you perform the absolutute 'no no', of globally enabling interrupts. Since there has been a huge delay in this, and the interrupt flag probably _will_ be set, this will result in interrupt recursion...
Code:

#include <24HJ128GP306.h>   
#device adc=10

#use fast_io (B)
#use fast_io (D)
#fuses HS,NOWDT,PR_PLL
#use delay(clock=80M, oscillator=20M)                                                                     
#use rs232(baud=19200,parity=N,xmit=PIN_F3,rcv=PIN_F2,bits=8,ERRORS, STREAM=HOSTPC)

void opcode_processor(void);
void rs232_handler(void);                                 

#include <stdlib.h>
#include <math.h>

int8    opcode,byte[3];
int1 packet=FALSE;

void main(){
   set_tris_b (0x00);                           
   set_tris_d (0x00);                         
   enable_interrupts(int_rda);           
   enable_interrupts(intr_global);
   while(TRUE) {
      if (packet) {
         opcode_processor();
      }
   }           
}

#int_rda
void  rs232_handler(){
   static int8 state=0;
   static int1 legitimate=FALSE;
   int8 temp;
   switch (state) {
   case 0:
      opcode=getc(HOSTPC);
      if (opcode != 0xFF && opcode !=0x00) legitimate=TRUE;
      else legitimate=FALSE;
      state=1;
      break;
   case 1:
   case 2:
   case 3:
       temp=getc(HOSTPC);
       if (legitimate) {
          byte[state-1]=temp;
       }
       state++;
       if (state==4) {
          if (legitimate) packet=TRUE;
          state=0;
          legitimate=FALSE;
       }
       break;
    }
}

void opcode_processor(void) {
   //You allow opcodes to be 1 to 254. What do you do for the
   //other values?
   int8 qdata;
   if (opcode==1)  {
      disable_interrupts(intr_global);
      write_program_memory(0x000600,byte,1);                                           
      // Why delay?. The write delays till data is written.
      read_program_memory(0x000600,&qdata,1);   
      //get interrupts back on ASAP
      enable_interrupts(intr_global);
      putc(opcode, HOSTPC);
      putc(0, HOSTPC);
      putc(qdata, HOSTPC);
      putc(3, HOSTPC);
   }
}

No guarantees, but this is closer to workable.

Best Wishes
GT



Joined: 09 Aug 2008
Posts: 3

View user's profile Send private message

PostPosted: Sun Aug 10, 2008 1:08 pm     Reply with quote

Ttelmah, thanks for your response and for pointing out the the correct way of doing this. I'll have to wait until tomorrow to test it. In the meantime, I see that you're putting the incoming values into an array and you use that to write to memory. Let's see if I understood correctly how the memory write works. The instruction:
write_program_memory(0x000600,byte,1);
writes the first element of the array to memory. Let's say I want to write all 3 values to memory but then read back the third element only, is this correct?

Code:

write_program_memory(0x000600,byte,3);                                           
read_program_memory(0x000601,&qdata,1);   
Ttelmah
Guest







PostPosted: Mon Aug 11, 2008 2:58 am     Reply with quote

A lot of caveats here....
Write_program_memory, only erases a block, when you write to the first byte of the block. You need to check if your starting address is evenly divisible by flash_erase_size, if not, then the memory block will not be cleared, and the result will not be what is expected.
Now, normally the functions use byte addresses, not word addresses. This is why on the 18chips, the LSB of the address for write_program_eeprom, has to be '0'.
If you are going to write to the program memory, you really need to ensure that the area concerned is not used by the CCS code.
You should also be careful about the write 'life' of the memory.

Best Wishes
GT



Joined: 09 Aug 2008
Posts: 3

View user's profile Send private message

PostPosted: Mon Aug 11, 2008 12:18 pm     Reply with quote

Still no luck on being able to write to memory. I sat aside my code and tested just the few lines bellow. I've seen posts from other people saying that write_program_memory works in other PIC families. So far I can't get it to work in the PIC24H family.
The FLASH_ERASE seems to be 2048, that's why I used 0x1000 to save my data.
Any ideas?
Code:

#include <24HJ128GP306.h>   
#device ICD=TRUE
#fuses HS,NOWDT,PR_PLL                                                                                     
#use delay(clock=80M, oscillator=20M)                                                                       
#use rs232(baud=19200,parity=N,xmit=PIN_F3,rcv=PIN_F2,bits=8,ERRORS, STREAM=HOSTPC)

int16   iq,idata, qdata,flash;

void main(){
flash=getenv("FLASH_ERASE_SIZE");
printf("%lu\n", flash);
iq=100; 
write_program_memory(0x001000,&iq,2);                                     
read_program_memory(0x001000,&qdata,2); 
printf("%lu\n", qdata);   
}
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