|
|
View previous topic :: View next topic |
Author |
Message |
Nevillestone
Joined: 05 Aug 2014 Posts: 24
|
Flash write problem |
Posted: Thu Dec 13, 2018 1:42 pm |
|
|
HI Guys
Maybe someone can point me in the right direction here.
I'm upgrading a Pic 12F675 to 12F1571.
But having problems with the flash write.
I'm using the write_program_memory(i, value, 2); and its not working.
I can see in the list file that it is not compiling for the unlock sequence.
i.e. write 55 the write AA etc..
Does the CCS compiler handle this or do I need to write the code myself?
Am I using the wrong command?
using compiler V5.074 _________________ Neville |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Thu Dec 13, 2018 1:58 pm |
|
|
you should post your program ( use code 'buttons...) so we can see what you're trying to do. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Fri Dec 14, 2018 1:16 am |
|
|
Remember that unless you get rid of the #nolist at the start of the processor
include file, the CCS 'internal' code for core functions will not be shown in
the listing.
Also you must always say 'what compiler version' for a question like this.
I just put together a minimum test on the current compiler (5.081):
Code: |
#include "12F1571.h" //using local copy with nolist removed
#device ADC=10
#fuses NOMCLR
#fuses NOLVP
#use delay(internal=4000000)
void main()
{
char test[16] = "Test message";
write_program_memory(0x200,test,16);
//Horrid will write every time chip boots.
while(TRUE)
{
}
}
|
and in the listing, at the start of the write code (once it has loaded the
data latches), it calls address 3:
Code: |
0003: MOVF INTCON,W
0004: MOVWF @78 //save interrupt status
0005: BCF INTCON.GIE //disable interrupts
0006: MOVLB 03 //bank 3
0007: MOVLW 55 //first unlock byte
0008: MOVWF PMCON2
0009: MOVLW AA //second unlock byte
000A: MOVWF PMCON2
000B: BSF PMCON1.WR //now trigger write
000C: NOP
000D: NOP
000E: BTFSC PMCON1.WR //loop till write completes
000F: GOTO 00E
0010: BCF PMCON1.WREN //turn off write enable
0011: MOVF @78,W
0012: IORWF INTCON,F //re-enable interrupts
0013: MOVLB 00
0014: RETURN
|
So the compiler is generating the unlock correctly.
Remember you cannot just write to a byte, like EPROM. The flash memory
is in pages (32 bytes). If you want to write a byte that is not at the start
of a page, you have to read the whole page, modify the single byte, and
write the whole page back. A write to a byte in the middle of a page, will
happen, but can only change bits from '1' to '0'. So if byte 5 in a page was
(say) 0xAA, and you wrote 0x11, the result would be 0x00!...
The page will be erased if you write to the first byte in a page, so if you
are (for example) storing some configuration data, then lay this out as
a single entity, and always write it to the start of the page. Remember
that the 'odd' bytes only have 6 bits available to use though...
As a further comment, unless 'value' is an array, your calling syntax is
wrong. You need to pass the address of the memory you want to transfer
so if 'value' is an int16, you need:
write_program_memory(i, &value, 2);
to pass the address of 'value'. This may well be why you think it is not
working.... |
|
|
Nevillestone
Joined: 05 Aug 2014 Posts: 24
|
Flash write problem |
Posted: Sat Dec 15, 2018 1:36 am |
|
|
HI temtronic
Thank for your suggestion.
Tried them still no luck.
I'm trying to write 1 byte into flash for configuration purposes will do the erase once I have the code working.
My compiler version is 5.074
Here is my test code similar to yours but changed the string to a int16:
Code: |
void main()
{
Value=0x66;
write_program_memory(0x0380, &Value, 2);
//Horrid will write every time chip boots.
while (TRUE) {
//Example program using Tick Timer
CurrentTick = get_ticks();
}
}
|
The list
Code: |
.................... {
.................... Value=0x66;
00DC: MOVLB 00
00DD: CLRF 2B
00DE: MOVLW 66
00DF: MOVWF 2A
....................
.................... write_program_memory(0x0380, &Value, 2);
00E0: MOVLW 03
00E1: MOVLB 03
00E2: MOVWF 12
00E3: MOVLW 80
00E4: MOVWF 11
00E5: MOVLW 20
00E6: MOVWF 05
00E7: MOVLW 0A
00E8: MOVWF 04
00E9: MOVLW 02
00EA: MOVLB 00
00EB: MOVWF 2F
00EC: GOTO 015
.................... //Horrid will write every time chip boots.
|
AS you can see still no unlock code
# nolist disabled _________________ Neville |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Sat Dec 15, 2018 4:39 am |
|
|
Yes there is...
The 'goto 015', jumps to the physical 'write' code.
What you are posting, is the code that loads the value to save, the address
and the count, ready to call the write function.
The write itself is down at address 015.
If you compile in 'symbolic' mode, this is made much clearer:
(Using 5.074)
Code: |
.................... write_program_memory(0x380,&Value,2);
007C: MOVLW 03
007D: MOVLB 03
007E: MOVWF PMADRH
007F: MOVLW 80
0080: MOVWF PMADRL
0081: MOVLW value+-1
0082: MOVWF FSR0H
0083: MOVLW value+-32
0084: MOVWF FSR0L
0085: MOVLW 02
0086: MOVLB 00
0087: MOVWF @WRITE_PROGRAM_MEMORY.P2
0088: GOTO @WRITE_PROGRAM_MEMORY
|
It's loading the address where the write is to go, then the FSR registers
with where it is to come 'from', loading the W register with the count, and
then jumps to the actual write routine.
The write routine itself is about 4* the size of this code, and has the unlock
sequence. |
|
|
Nevillestone
Joined: 05 Aug 2014 Posts: 24
|
Flash write problem |
Posted: Mon Dec 17, 2018 1:59 am |
|
|
Thanks for the detailed reply.
However your code does not fill address 0x380-038F with the message if you simulate the code. (or address 0x200 tried both in the MPLABX simulator and on a chip).
I'm compiling from within MPLABX V4.05'
CCS Compiler V5.074.
I'm looking in the program watch window.
The code I'm compiling:
Code: |
#include<C:\Users\Neville\Documents\Stoneage\mplabpj\Flash\flash1571.>
void main()
{
char test[16] = "Test message";
write_program_memory(0x200,test,16);
//Horrid will write every time chip boots.
while(TRUE)
{
}
}
|
Is there any sample code that works ? I can't find any. _________________ Neville |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Mon Dec 17, 2018 6:40 am |
|
|
OK. Though the unlock is working, the actual write is not.
This gives a basic erase/block write of a 16byte area, and should get you going:
Code: |
#include "12F1571.h"
#device ADC=10
#fuses NOMCLR
#fuses NOLVP
#fuses NOWDT
#use delay(internal=4000000)
#byte PMADRL=getenv("SFR:PMADRL")
#byte PMADRH=getenv("SFR:PMADRH")
#byte PMCON1=getenv("SFR:PMCON1")
#byte PMCON2=getenv("SFR:PMCON2")
#byte PMDATL=getenv("SFR:PMDATL")
#byte PMDATH=getenv("SFR:PMDATH")
#bit CFGS=PMCON1.6
#bit FREE=PMCON1.4
#bit LWLO=PMCON1.5
#bit WREN=PMCON1.2
#bit WR=PMCON1.1
void unlock_wr(void)
{
//unlock and trigger write
PMCON2=0x55;
PMCON2=0xAA;
WR=1;
delay_cycles(1);
delay_cycles(1); //NOP
WR=0;
}
//This writes a block of 16bytes to the flash memory
void write_program_mem(int16 address, int8 * data)
{
int8 ctr=16;
//Basic memory erase/write 16 byte block
disable_interrupts(GLOBAL);
//first erase row
PMADRL=make8(address,0) & 0xF0; //page boundary address
PMADRH=make8(address,1);
CFGS=0;
FREE=1;
WREN=1;
unlock_wr(); //This will force an erase
WREN=0;
//now write 16 bytes (must be even number))
CFGS=0;
PMADRL=make8(address,0);
PMADRH=make8(address,1);
FREE=0;
WREN=1;
do
{
ctr-=2; //2 bytes at a time
LWLO=(ctr != 0); //loads LWLO with 1 except on last loop
PMDATL=*data; //load data
data++;
PMDATH=*data; //second byte
data++;
unlock_wr(); //This write just sets the latches, except on last loop
PMADRL++; //next address
} while (ctr); //and loop
WREN=0; //turn off write
enable_interrupts(GLOBAL);
}
void main()
{
char test[16] = "Test message";
//remember alternate bytes of this will lose their top 2 bits
//Horrid will write every time chip boots.
write_program_mem(0x200,test);
while(TRUE)
{
}
}
|
|
|
|
Nevillestone
Joined: 05 Aug 2014 Posts: 24
|
Flash write problem |
Posted: Mon Dec 17, 2018 12:49 pm |
|
|
Thanks
it workes...
However it seems we are going backwards when we have to start coding in assembler after we have paid for a C compiler. _________________ Neville |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Mon Dec 17, 2018 1:02 pm |
|
|
Not a single line of assembler there. Just C.
In fact the issue is a one line slip in the CCS code. I've reported it to them
and hopefully a fix will appear shortly. Basically they are setting the 'FREE'
bit during the code that is meant to perform the write. This results in the
cells being erased instead of written... |
|
|
|
|
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
|