|
|
View previous topic :: View next topic |
Author |
Message |
allenhuffman
Joined: 17 Jun 2019 Posts: 617 Location: Des Moines, Iowa, USA
|
Fantastic PIC24 conmfiguration bytes and where to find them. |
Posted: Thu Jan 16, 2025 4:27 pm |
|
|
Some observations and a question or two about configuration bytes and how to find them...
A) The datasheet for the PIC24FJ256GA110 chip...
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/PIC24FJ256GA110-Family-Data-Sheet-DS30009905F.pdf
...has Table 2-51 listing the "Flash Configuration Word Locations."
It lists Word Addresses 1, 2 and 3. For the 256 part, they are:
Code: | 1) 2ABFE
2) 2ABFC
3) 2ABFA |
However, getenv("CONFIGURATION_ADDRESS") returns 350192 (0xff7f0). 0x2ABF8 is half of that. and this is the value we have in a #define in our code for the start of the bytes.
If I load one of the .hex files into ICD Interface, it shows Configuration as:
But the data sheet does not reference this address.
B) In the PIC24FJ64GA004 datasheet, it lists
ICD Interface shows ABFC-AABFF and that makes sense.
getenv() shows 88056 (0x157f8). ABFC is half of that, so that also matches.
C) For the PIC24EPXXXXGP datasheet, they list 10 configuration bytes. For the 256 part, they are:
Code: | 1) 02AFEC
...
10) 02AFFE |
This one has the lower numbers first, while the other two parts are backwards. This was something CCS support was explaining when I was asking them about getenv() recently.
ICD Interface confirms 2AFEC-2AFFF which makes sense.
getenv() reports 352216 (0x55FD8), and half of that is 2AFEC so that one works.
So...
For A, I see other PIC chips have "Reserved" bytes, so I wonder if there really are 4 bytes, and the last one is Reserved.
But how do you know if the address reported means the last byte of config bytes, or the first? It looks like making generic PIC24 code that uses getenv() needs more information.
For C, in the .lst file, the compiler seems to skip over the two Reserved words at the start (1 and 2) but includes the two at the end (9-10):
Code: | Configuration Fuses:
Word 3L: FF4D ICSP3 NOJTAG DEBUG
H: 0000
. . .
Word 10L: FFFF
H: 0000
|
This caused an issue with a loader program I am working on that was expecting to find the start of config bytes as reported by getenv(), which didn't exist in the .hex file:
Code: | Configuration Words
02AFF0: 00FFFF4D 00FFFFEF 00FFFF6D 00FFFF39
02AFF8: 00FFFFF8 00FFFFFF 00FFFFFF 00FFFFFF
|
Checking for an address greater than would work, but not on the ones where it gives me the last word (since nothing will be after that in the hex file).
I've spent too much time in datasheets today trying to genericize my code, but I may just hard code it and move on to the next task... _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19649
|
|
Posted: Fri Jan 17, 2025 1:46 am |
|
|
Data sheet says _Word Locations_. Hence half the byte address value.
You do understand that the configuration on these chips is at two locations.
The chip has the physical ROM configuration data held at 0xF80000 and up.
It is this that has to be used to program the configuration. The data held
here is copied on boot, from the ROM to the RAM, and is copied into the
top locations in the RAM.
It is the _ROM_ configuration data that a loader would have to deal with,
not the RAM data.
It is the ROM data that the program listing shows, not the RAM copy.
The configuration data (as far as reading it is concerned), is the data in
RAM. For programming you need to be dealing with the ROM locations. |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 617 Location: Des Moines, Iowa, USA
|
|
Posted: Fri Jan 17, 2025 8:34 am |
|
|
Datasheet says program those flash locations and they are loaded to the config area during boot, yes?
My question is how do you know where to put data if the CONFIGURATION_MEMORY is sometimes the first word and sometimes the last, and sometimes is a value that is one word past what the datasheet says?
Is there another thing that can be read to clarify that?
And thanks - perhaps the write configuration talks directly to that area rather than the flash area. If so, maybe code can just set them as desired in main and not worry about flash? _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19649
|
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 617 Location: Des Moines, Iowa, USA
|
|
Posted: Fri Jan 24, 2025 10:36 pm |
|
|
I have not seen this document, but have read some of this elsewhere. This is worrisome:
Quote: | On other devices, the Configuration bits are stored in the last page of program Flash user memory space in a section called “Flash Configuration Bytes”. With these devices, performing a page erase operation on the last page of program memory erases the Flash Configuration bytes, which enables code protection. Therefore, users should not perform page erase operations on the last page of program memory. Refer to the Program Memory Map in the “Memory Organization” chapter of the specific device data sheet to determine where Configuration bits are located. |
The existing firmware update routines I maintain look like the original author was aware of this. They set a #define LOWER_BOUNDARY and leave anything past that alone:
Code: | 0x2a000 +---------------------+ 0x54000 LOWER_BOUNDARY
| 84 |
| |
| |
0x2a7ff +---------------------+ 0x54fff |
On the three PIC24s I use, getenv("CONFIGURATION_ADDRESS") is not useful. Two of them look like they are giving the hex file address, and the other doesn't match anything I can see.
But getenv("PROGRAM_MEMORY") is "correct" for all three of them, with the caveat that our PIC24EP module has two words at the start that are unused, so the hex file starts after that. PROGRAM_MEMORY gets me to the real start of the 10 words, but then you have to know to skip the first two.
We have a hard-coded #define on each board that is the address where the hex file stores the data. Between that, and the PROGRAM_MEMORY, I may be able to get where I want:
Code: |
#define START_ADDRESS_CONFIG 0x02AFF0 // Verified from .hex file.
#define PROGRAM_MEMORY getenv("PROGRAM_MEMORY") // Config Bytes |
I wrote a program to parse the .hex file and create ROM data, so config bytes for this chip end up looking like this:
Code: | #define SEGMENT2DEST (0x2aff0) // 176112
#rom int8 SEGMENT2SOURCE = // 32 bytes (24 PIC bytes)
{
/* PIC HEX */
/* 0x2aff0 0x55fe0 */ 0x4d, 0xff, 0xff, 0x00, 0xef, 0xff, 0xff, 0x00,
/* 0x2aff4 0x55fe8 */ 0x6d, 0xff, 0xff, 0x00, 0x39, 0xff, 0xff, 0x00,
/* 0x2aff8 0x55ff0 */ 0xf8, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
/* 0x2affc 0x55ff8 */ 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00
}; |
The funny thing is that #rom will represent all that data intact, so when this is stored in program memory, a zero is added every fourth byte, so a #rom of...
...gets stored in flash as...
Code: | 1,2,3,(0),0,4,5,(0),6,0 |
So I read_program_memory(SEGMENT2SOURCE...) into a buffer, and then have a routine that will strip it back down to the original data. That gives me...
Or, in the case of the config byte data:
Code: | 0x4d, 0xff, 0xff, 0x00, // word 3
0xef, 0xff, 0xff, 0x00, // word 4
0x6d, 0xff, 0xff, 0x00, // word 5
0x39, 0xff, 0xff, 0x00, // word 6
0xf8, 0xff, 0xff, 0x00, // word 7
0xff, 0xff, 0xff, 0x00, // word 8
0xff, 0xff, 0xff, 0x00, // word 9
0xff, 0xff, 0xff, 0x00 // word 10 |
On this part, if I do a read_configuration_memory() for 20 bytes (10 words), it comes back with 2-byte words, like:
(ff, ff), (ff, ff), (4d, ff), (ef, ff), (e9, ff), (f8, ff), (ff, ff), (ff, ff), (ff, ff)
...with the first two words being ff's (unused).
Since write_configuration_memory() appears to want 16-bit words, the routine further makes the data "just" the 16-bit values it seems to want:
Code: | 0x4d, 0xff, // word 3
0xef, 0xff, // word 4
0x6d, 0xff, // word 5
0x39, 0xff, // word 6
0xf8, 0xff, // word 7
0xff, 0xff, // word 8
0xff, 0xff, // word 9
0xff, 0xff // word 10 |
But if you just use write_configuration_memory(), it starts at word 1, and the hex file starts at word 3.
I did not know how I would tell this, but now it looks like I might be able to do:
Code: | write_configuration_memory (destAddress-PROGRAM_MEMORY,
configBytes, configBytesSize); |
...where "destAddress" is the value that came from the hex file (divided by two to be the PIC address).
So if the hex file has data for 0x2aff0, but PROGRAM_MEMORY has 0x2afec, I can subtract the two and get 4 for the offset.
This appears to work, and writes the bytes, then reads them back to verify, and they match.
But things do not work, so something is still off. I used the same byte order that read_configuration_memory() has, but maybe there is more to it.
SO fun! _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9370 Location: Greensville,Ontario
|
|
Posted: Sat Jan 25, 2025 7:12 am |
|
|
fun ? My head hurts just READING this post.....!!!
curious, could you standardize the PCBs to use just one type of PIC ? |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 617 Location: Des Moines, Iowa, USA
|
|
Posted: Sat Jan 25, 2025 9:54 am |
|
|
temtronic wrote: | fun ? My head hurts just READING this post.....!!!
curious, could you standardize the PCBs to use just one type of PIC ? |
I am sure the hardware designer had reasons for choosing the chips they did but I expect our next hardware change will be away from PIC24 and to some ARM-based processor and a small RTOS. There are so many hoops we jump through using these parts. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9370 Location: Greensville,Ontario
|
|
Posted: Sat Jan 25, 2025 11:47 am |
|
|
I learned a long time ago,buy the biggest PIC in the family, you'll save $$$ as client's always want another LED or feature that requires 17 more bytes than available EEPROM.......
Also having too learn that PIC B doesn't have xxx that PIC A has, arrrrrrgh |
|
|
allenhuffman
Joined: 17 Jun 2019 Posts: 617 Location: Des Moines, Iowa, USA
|
|
Posted: Sun Jan 26, 2025 3:39 pm |
|
|
temtronic wrote: | I learned a long time ago,buy the biggest PIC in the family, you'll save $$$ as client's always want another LED or feature that requires 17 more bytes than available EEPROM.......
Also having too learn that PIC B doesn't have xxx that PIC A has, arrrrrrgh |
How true!
One of our four boards has no LED I can control. None of serial pins. When they did a revision I finally got a test pin added which I planned to use for serial out.
Then they immediately had to use it as a chip select for a SPI part they added.
I still got my pin but can’t use it and that part at the same time ;)
Thanks for … the thought I guess!
I did more work with these config bytes. On the EP part I can just write program memory to set them so if the other two also do that, then I’ll comment out all my write program memory code for now. It was a good learning experience. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202 and 24FJ64GA002. |
|
|
|
|
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
|