|
|
View previous topic :: View next topic |
Author |
Message |
GT
Joined: 09 Aug 2008 Posts: 3
|
write_program_memory doesn't work for PIC24H |
Posted: Sat Aug 09, 2008 5:31 pm |
|
|
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
|
|
Posted: Sun Aug 10, 2008 3:30 am |
|
|
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
|
|
Posted: Sun Aug 10, 2008 1:08 pm |
|
|
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
|
|
Posted: Mon Aug 11, 2008 2:58 am |
|
|
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
|
|
Posted: Mon Aug 11, 2008 12:18 pm |
|
|
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);
}
|
|
|
|
|
|
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
|