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 CCS Technical Support

Fantastic PIC24 conmfiguration bytes and where to find them.

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



Joined: 17 Jun 2019
Posts: 617
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

Fantastic PIC24 conmfiguration bytes and where to find them.
PostPosted: Thu Jan 16, 2025 4:27 pm     Reply with quote

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:

Code:
02ABF8-02ABFF


But the data sheet does not reference this address.


B) In the PIC24FJ64GA004 datasheet, it lists

Code:
1) ABFE
2) ABFC


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

View user's profile Send private message

PostPosted: Fri Jan 17, 2025 1:46 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Fri Jan 17, 2025 8:34 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jan 17, 2025 10:52 am     Reply with quote

Have a look here:
[url]
https://microchip.my.site.com/s/article/16-bit--32-bit-MCU---Write-Configuration-Bits-during-run-time-using-Run-Time-Self-Programming--RTSP
[/url]
This describes the different ways that the configuration stuff is handled.
Unfortunately the chips you are using are the most awkward.
allenhuffman



Joined: 17 Jun 2019
Posts: 617
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Fri Jan 24, 2025 10:36 pm     Reply with quote

Ttelmah wrote:
Have a look here:
[url]
https://microchip.my.site.com/s/article/16-bit--32-bit-MCU---Write-Configuration-Bits-during-run-time-using-Run-Time-Self-Programming--RTSP
[/url]
This describes the different ways that the configuration stuff is handled.
Unfortunately the chips you are using are the most awkward.


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...

Code:
1,2,3,0,4,5,6,0


...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...

Code:
1,2,3,4,5,6


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: 9372
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jan 25, 2025 7:12 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Sat Jan 25, 2025 9:54 am     Reply with quote

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: 9372
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jan 25, 2025 11:47 am     Reply with quote

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....... Sad
Also having too learn that PIC B doesn't have xxx that PIC A has, arrrrrrgh Sad
allenhuffman



Joined: 17 Jun 2019
Posts: 617
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Sun Jan 26, 2025 3:39 pm     Reply with quote

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....... Sad
Also having too learn that PIC B doesn't have xxx that PIC A has, arrrrrrgh Sad


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.
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