View previous topic :: View next topic |
Author |
Message |
sjb
Joined: 13 Apr 2010 Posts: 34 Location: UK
|
Reading the Device ID (DEVID) |
Posted: Tue Aug 10, 2010 4:26 am |
|
|
Is there an easy way to read back the device ID?
I see there is a library function to read back the config fuses - read_configuration_memory( ) - but I can't find a similar function to read back the device ID and revision which are at 0xFF0000 and 0xFF00002 on the PIC24 that I'm using.
Would I need to do this in assembler to use the table read operation, or are there helper functions so I can do this in c? I've looked but can't find any.
I'm using PCD v4.109 |
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
Re: Reading the Device ID (DEVID) |
Posted: Tue Aug 10, 2010 5:17 am |
|
|
I could not find anything built in to do that.
Below is code I used on a PIC18. You will almost certainly have to do heavy modifications but it's a start. As you can see, on a PIC18 the device ID is stored in the most idiotic fashion possible.
Code: |
#byte TABLAT = 0x0FF5
#byte TBLPTRL = 0x0FF6
#byte TBLPTRH = 0x0FF7
#byte TBLPTRU = 0x0FF8
int8 table_read(int8 page, int16 addr) {
int8 ret;
TBLPTRU = page;
TBLPTRH = addr >> 8;
TBLPTRL = addr & 0xff;
#asm
TBLRD
#endasm
ret = TABLAT;
return(ret);
}
myID = ((int16)table_read(0x20,0) << 12) + ((int16)table_read(0x20,2) << 8) + ((int16)table_read(0x20,4) << 4) + (int16)table_read(0x20,6) ;
|
sjb wrote: | Is there an easy way to read back the device ID?
I see there is a library function to read back the config fuses - read_configuration_memory( ) - but I can't find a similar function to read back the device ID and revision which are at 0xFF0000 and 0xFF00002 on the PIC24 that I'm using.
Would I need to do this in assembler to use the table read operation, or are there helper functions so I can do this in c? I've looked but can't find any.
I'm using PCD v4.109 |
|
|
|
sjb
Joined: 13 Apr 2010 Posts: 34 Location: UK
|
|
Posted: Tue Aug 10, 2010 6:23 am |
|
|
Thanks collink.
I took the plunge with the asm and on PIC 24 the following seems to be working...
Code: |
/* Read DEVID and REV from a PIC24 */
#byte TBLPAG = getenv("SFR:TBLPAG")
uint32_t devid;
uint32_t rev;
#asm
mov #0x00FF, W0
mov W0, TBLPAG
mov #0000, W1
tblrdl [W1],W0
mov W0, devid
tblrdh [W1],W0
mov W0, devid+2
mov #0x0002, W1
tblrdl [W1],W0
mov W0, rev
tblrdh [W1],W0
mov W0, rev+2
#endasm
printf(" devid = 0x%LX, rev = 0x%LX)\r\n", devid, rev);
|
|
|
|
FFT
Joined: 07 Jul 2010 Posts: 92
|
|
Posted: Sun Aug 15, 2010 11:30 am |
|
|
getenv()
ID
Returns the device ID (set by #ID)
DEVICE
Returns the device name string (like "PIC16C74")
MyID = getenv("ID");
But there is no way to get revision number of chip using getenv. |
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Sun Aug 15, 2010 11:38 am |
|
|
FFT wrote: | getenv()
ID
Returns the device ID (set by #ID)
DEVICE
Returns the device name string (like "PIC16C74")
MyID = getenv("ID");
But there is no way to get revision number of chip using getenv. |
Yes, that works if your program actually has set the ID. That is, if the source code for your current program has the device ID within it. If, for instance, your bootloader or something else set the ID but your currently running program didn't then the only way to get the ID is through code like what I or the OP posted. This is a big downside to getenv. It can only get data which is available to the compiler at compile time.
The revision code does require table reads but that's not so hard.
Using table reads/writes its also possible to get around the stupid 16bit ID codes that the CCS compiler supports. PIC18 chips actually support 64bit IDs. |
|
|
sjb
Joined: 13 Apr 2010 Posts: 34 Location: UK
|
|
Posted: Sun Aug 15, 2010 11:49 am |
|
|
In my case I wanted to be able to identify the processor at run time. My code can run on the PIC24HJ265GP610 and the PIC24HJ265GP610A. One build with work for both, but at run time I might need to make allowances for certain errata if it's running on the 610 rather than the 610A.
The gentenv() method would not work (for me) as that's a compile time method. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 15, 2010 12:06 pm |
|
|
Quote: | getenv()
ID
Returns the device ID (set by #ID)
|
getenv() returns a user defined ID value, which is different from the PIC's
hard-coded Device ID. They are stored in different locations in the PIC.
The User ID can be put in by you, but the Device ID is put in by Microchip
during manufacture. That CCS getenv() function returns the User ID.
The link below shows how to use the read_program_memory() function
to read the Device ID (not user ID):
http://www.ccsinfo.com/forum/viewtopic.php?t=20257&start=1
This code was tested with an 18F PIC. You didn't give your exact PIC,
but let's say you have an 24HJ128GP504. The programming spec
gives the Device ID addresses in this table on page 66:
Quote: |
TABLE 7-2: dsPIC33F/PIC24H PROGRAMMING SPECIFICATION DEVICE ID REGISTERS
|
You could try the code given in the link with the PIC24's Device ID
addresses and see if it works. Here is the Programming specification:
http://ww1.microchip.com/downloads/en/DeviceDoc/70152G.pdf |
|
|
FFT
Joined: 07 Jul 2010 Posts: 92
|
|
Posted: Sun Aug 15, 2010 2:37 pm |
|
|
@collink, @PCM Programmer,
I never knew that. There is written Device ID on help of getenv() and I was thinking that the same thing as collink's code.
Thanks for the explanations.
Finally, equivalent code for reading ID and rev with table_read is: Code: | id1 = read_program_eeprom(0x3FFFFEL); // device id 1
id2 = read_program_eeprom(0x3FFFFFL); // device id 2
Revision = id1 & 0x1F; // revision
|
Right? (18F only) |
|
|
|