GP2X Reading The Gp2x Serial Number


Dzz

stmia r0!, {r2-r9}
Joined
Jan 30, 2006
Messages
1,098
Website
Visit site
In another thread I was whining about being unable to read the GP2X serial number, which is something I want to do as the first step in identifying Mk1 gp2x units so I can treat their graphics differently in my little games. Anyway, I finally figured it out. Code attached.

The "pszSerial" parameter should be a buffer of 25 or more characters. The result will be a null-terminated character string at most 24 characters long. The "pusRegs" parameter is the standard result from calling mmap() to get an address for the mmsp2 registers at 0xC0000000 (see many other code examples for doing that). The function returns a failure code if the I2C stuff fails, but makes no effort to validate the contents of the returned data, which looks like this:

20070607GP2XV00400000056

CODE

#define I2CCON (0xD00>>1)
#define I2CSTAT (0xD02>>1)
#define I2CADDR (0xD04>>1)
#define I2CDATA (0xD06>>1)

#define DEVICE 0xA0

int WaitOnI2CInterrupt(volatile unsigned short *pusRegs)
{
int n = 10000000;
while(n > 0)
{
if(pusRegs[I2CCON] & 0x10) // wait for interrupt pending flag
return 1;
n--;
}
return 0;
}

// returns 1 on success, 0 on failure

int FetchSerial(volatile unsigned short *pusRegs, char *pszSerial)
{
unsigned short usCount = 0;

// initialize registers
pusRegs[I2CCON] = 0xEF; // set clocks, enable interrupt, clear pending flag
pusRegs[I2CADDR] = DEVICE; // set address
pusRegs[I2CSTAT] = 0x10; // enable I2C

*pszSerial = 0;

// tell the eeprom what address we're interested in
pusRegs[I2CDATA] = DEVICE;
pusRegs[I2CSTAT] = 0xF0; // Master mode, data write
if(WaitOnI2CInterrupt(pusRegs))
{
pusRegs[I2CDATA] = 0x00; // high byte of address
pusRegs[I2CCON] = 0xEF;
if(WaitOnI2CInterrupt(pusRegs))
{
pusRegs[I2CDATA] = 0x20; // address of serial number
pusRegs[I2CCON] = 0xEF;
if(WaitOnI2CInterrupt(pusRegs))
{
// issue the read command
pusRegs[I2CDATA] = DEVICE;
pusRegs[I2CSTAT] = 0xB0; // Master mode, data read
pusRegs[I2CCON] = 0xEF;
if(WaitOnI2CInterrupt(pusRegs))
{
// read the data bytes
for(usCount = 0; usCount < 24; usCount++)
{
pusRegs[I2CCON] = 0xEF;
if(!WaitOnI2CInterrupt(pusRegs))
break;
*pszSerial++ = (char) pusRegs[I2CDATA];
*pszSerial = 0;
}
}
}
}
}
// shut down
pusRegs[I2CSTAT] = 0x90;
pusRegs[I2CCON] = 0xEF;
usleep(10000);
// leave the I2C in a quiet state
pusRegs[I2CCON] = 0x40; // disable interrupt
pusRegs[I2CSTAT] = 0x00; // disable I2C

if(usCount == 24)
return 1;
return 0;
}
 
May be worth you building a small .gpe that reports the result then we can all run it and figure out when a Mk 1 became a Mk 2..
or do we know this already - your string has V004 in it..?
btw, good work getting it going :)
 
Squidge said:
How did you manage getting this working in the end? I know you had loads of problems.
Just persistence.

Now, if memory serves, there was a break in availability of gp2x units when the design changed. Combing through the board archives should give me a good guess for the cutoff date.
 
Last edited by a moderator:
kevcal said:
May be worth you building a small .gpe that reports the result then we can all run it and figure out when a Mk 1 became a Mk 2..
I could, but the "info" page on the gp2x menu reports the serial number so there's no need to download anything. I think I'll ask in another topic!
 
Last edited by a moderator:
Dzz said:
In another thread I was whining about being unable to read the GP2X serial number, which is something I want to do as the first step in identifying Mk1 gp2x units so I can treat their graphics differently in my little games.
Does it have anything to do with my colour correcting daemon? Anyways, thanks for doing the research for me, I needed a way to tell MKI's from MKII's really bad! :)
 
Last edited by a moderator:
A_SN said:
Dzz said:
In another thread I was whining about being unable to read the GP2X serial number, which is something I want to do as the first step in identifying Mk1 gp2x units so I can treat their graphics differently in my little games.
Does it have anything to do with my colour correcting daemon? Anyways, thanks for doing the research for me, I needed a way to tell MKI's from MKII's really bad! :)

Your excellent work on the color correcting demon revived my hopes that I could do something about the highly annoying differences in the way my graphics look on the Mk1 vs the Mk2.

We need to figure out how individual game writers like me can interact smoothly with users of your demon, as we will be fighting over the gamma table. I wonder if your demon could only change the gamma if the gamma is not enabled and set to custom values?
 
Last edited by a moderator:
Dzz said:
Your excellent work on the color correcting demon revived my hopes that I could do something about the highly annoying differences in the way my graphics look on the Mk1 vs the Mk2.

We need to figure out how individual game writers like me can interact smoothly with users of your demon, as we will be fighting over the gamma table. I wonder if your demon could only change the gamma if the gamma is not enabled and set to custom values?
I think the best way is yet to look for a process named colourd. Anyways, some guy who works on that wind and water game thing PMed me asking me if he could use my code for his game to which I replied I was about to work on improving my code so that it works with configuration files, that means I'm gonna release very soon code that anyone can put in his game.

Your work of identifying MKI's and MKII's will avoid the awkward "Is your GP2X a MKII or a MKI?" to the user :).
 
Last edited by a moderator:
A_SN said:
I think the best way is yet to look for a process named colourd. Anyways, some guy who works on that wind and water game thing PMed me asking me if he could use my code for his game to which I replied I was about to work on improving my code so that it works with configuration files, that means I'm gonna release very soon code that anyone can put in his game.

Your work of identifying MKI's and MKII's will avoid the awkward "Is your GP2X a MKII or a MKI?" to the user :).
Ok, but looking for colourd doesn't give much benefit, since if I don't colourd will still wreck my carefully chosen gamma values in a few seconds anyway :)
 
Last edited by a moderator:
Dzz said:
A_SN said:
I think the best way is yet to look for a process named colourd. Anyways, some guy who works on that wind and water game thing PMed me asking me if he could use my code for his game to which I replied I was about to work on improving my code so that it works with configuration files, that means I'm gonna release very soon code that anyone can put in his game.

Your work of identifying MKI's and MKII's will avoid the awkward "Is your GP2X a MKII or a MKI?" to the user :).
Ok, but looking for colourd doesn't give much benefit, since if I don't colourd will still wreck my carefully chosen gamma values in a few seconds anyway :)


Oh yeah, I didn't get your original question right. Well honnestly, that's quite a problematic question. One simple solution would be to send a SIGQUIT to my daemon from a script right before running your game and then starting my daemon again once your program quits..
 
Last edited by a moderator:
A_SN said:
Dzz said:
A_SN said:
I think the best way is yet to look for a process named colourd. Anyways, some guy who works on that wind and water game thing PMed me asking me if he could use my code for his game to which I replied I was about to work on improving my code so that it works with configuration files, that means I'm gonna release very soon code that anyone can put in his game.

Your work of identifying MKI's and MKII's will avoid the awkward "Is your GP2X a MKII or a MKI?" to the user :).
Ok, but looking for colourd doesn't give much benefit, since if I don't colourd will still wreck my carefully chosen gamma values in a few seconds anyway :)


Oh yeah, I didn't get your original question right. Well honnestly, that's quite a problematic question. One simple solution would be to send a SIGQUIT to my daemon from a script right before running your game and then starting my daemon again once your program quits..

I think what I'll do is just ignore the issue -- if somebody wants the gamma values they get from colourd, they did that on purpose, so why should I complain? If they don't like it they can do whatever they need to do to shut off colourd.
 
Last edited by a moderator:
Dzz said:
A_SN said:
Dzz said:
A_SN said:
I think the best way is yet to look for a process named colourd. Anyways, some guy who works on that wind and water game thing PMed me asking me if he could use my code for his game to which I replied I was about to work on improving my code so that it works with configuration files, that means I'm gonna release very soon code that anyone can put in his game.

Your work of identifying MKI's and MKII's will avoid the awkward "Is your GP2X a MKII or a MKI?" to the user :).
Ok, but looking for colourd doesn't give much benefit, since if I don't colourd will still wreck my carefully chosen gamma values in a few seconds anyway :)


Oh yeah, I didn't get your original question right. Well honnestly, that's quite a problematic question. One simple solution would be to send a SIGQUIT to my daemon from a script right before running your game and then starting my daemon again once your program quits..

I think what I'll do is just ignore the issue -- if somebody wants the gamma values they get from colourd, they did that on purpose, so why should I complain? If they don't like it they can do whatever they need to do to shut off colourd.


Yeah, not really your problem. I guess whether you decide to force your values or let the user's colourd do its job doesn't matter, as most of the time the result would be the same thing anyways :). Just make it simple and set your colour correction when your program starts and don't bother knowing with what would happen then.. :)
 
Last edited by a moderator:
Back
Top