#20096 - jd - Sat May 01, 2004 11:51 pm
Hi all,
Sorry for the long post - I didn't want to leave out any vital information by mistake.
Anyway, I've written some code to read and write to EEPROM (see below). It reads from EEPROM first and displays the first byte as a number on screen (on VBA this is always zero when the EEPROM is uninitialised, but I would be surprised if I can rely on this in hardware). It then increments this number and writes it back. Then, it repeats the procedure. This allows the user to increment the counter an arbitrary number of times, with the last value stored in EEPROM. If the machine is switched off then the count should continue from its previous state.
Unfortunately, I only get this behaviour in VBA. On real hardware it hangs on the EEPROM write with a Flash Advance Xtreme 512M (presumeably because I'm not checking for timeouts yet), which I'm guessing means that cart doesn't support EEPROM saves. However, it's on a Flash2Advance 64M cart that things get really weird. Everything works exactly as it should, except for the counter goes up by 3 each time, rather than by 1.
Ok, here are my questions:
1) Does the Flash Advance Xtreme 512M support EEPROM?
2) Any ideas why the counter goes up by 1 with VBA but by 3 on hardware with a Flash2Advance 64M cart? (Any suggestions would be welcome - I'm completely stumped right now.)
3) Is there any way to detect if the EEPROM hasn't been written to before? At the moment, the only way I can think of to test this is to check for a magic value but that's a nasty kludge that I'd rather avoid if possible.
Thanks for any assistance you can offer!
(printf_special is a routine which outputs text to the screen and waits for user input - it's been tested thoroughly so the problem definitely isn't there.)
Sorry for the long post - I didn't want to leave out any vital information by mistake.
Anyway, I've written some code to read and write to EEPROM (see below). It reads from EEPROM first and displays the first byte as a number on screen (on VBA this is always zero when the EEPROM is uninitialised, but I would be surprised if I can rely on this in hardware). It then increments this number and writes it back. Then, it repeats the procedure. This allows the user to increment the counter an arbitrary number of times, with the last value stored in EEPROM. If the machine is switched off then the count should continue from its previous state.
Unfortunately, I only get this behaviour in VBA. On real hardware it hangs on the EEPROM write with a Flash Advance Xtreme 512M (presumeably because I'm not checking for timeouts yet), which I'm guessing means that cart doesn't support EEPROM saves. However, it's on a Flash2Advance 64M cart that things get really weird. Everything works exactly as it should, except for the counter goes up by 3 each time, rather than by 1.
Ok, here are my questions:
1) Does the Flash Advance Xtreme 512M support EEPROM?
2) Any ideas why the counter goes up by 1 with VBA but by 3 on hardware with a Flash2Advance 64M cart? (Any suggestions would be welcome - I'm completely stumped right now.)
3) Is there any way to detect if the EEPROM hasn't been written to before? At the moment, the only way I can think of to test this is to check for a magic value but that's a nasty kludge that I'd rather avoid if possible.
Thanks for any assistance you can offer!
Code: |
#define EEPROM_ADDRESS (volatile u16*)0xD000000 #define REG_EEPROM (*(volatile u16*)0xD000000) #define REG_DM3SAD (*(volatile u32*)0x40000D4) #define REG_DM3DAD (*(volatile u32*)0x40000D8) #define REG_DM3CNT (*(volatile u32*)0x40000DC) void EEPROM_SendPacket( u16* packet, int size ) { REG_DM3SAD = (u32)packet; REG_DM3DAD = (u32)EEPROM_ADDRESS; REG_DM3CNT = 0x80000000 + size; } void EEPROM_ReceivePacket( u16* packet, int size ) { REG_DM3SAD = (u32)EEPROM_ADDRESS; REG_DM3DAD = (u32)packet; REG_DM3CNT = 0x80000000 + size; } void EEPROM_Read( int offset, u8* dest ) // dest must point to 8 bytes { u16 packet[68]; u8* out_pos; u16* in_pos; u8 out_byte; int byte, bit; // Read request packet[0] = 1; packet[1] = 1; // 6 bits eeprom address (MSB first) packet[2] = offset>>5; packet[3] = offset>>4; packet[4] = offset>>3; packet[5] = offset>>2; packet[6] = offset>>1; packet[7] = offset; // End of request packet[8] = 0; // Do transfers EEPROM_SendPacket( packet, 9 ); EEPROM_ReceivePacket( packet, 68 ); // Extract data in_pos = &packet[4]; out_pos = dest; for( byte = 7; byte >= 0; --byte ) { out_byte = 0; for( bit = 7; bit >= 0; --bit ) { out_byte += (*in_pos++)<<bit; } *out_pos++ = out_byte; } } void EEPROM_Write( int offset, u8* source ) // source must point to 8 bytes { u16 packet[73]; u8* in_pos; u16* out_pos; u8 in_byte; int byte, bit; // Write request packet[0] = 1; packet[1] = 0; // 6 bits eeprom address (MSB first) packet[2] = offset>>5; packet[3] = offset>>4; packet[4] = offset>>3; packet[5] = offset>>2; packet[6] = offset>>1; packet[7] = offset; // Extract data in_pos = source; out_pos = &packet[8]; for( byte = 7; byte >= 0; --byte ) { in_byte = *in_pos++; for( bit = 7; bit >= 0; --bit ) { *out_pos++ = in_byte>>bit; } } // End of request packet[72] = 0; // Do transfers EEPROM_SendPacket( packet, 73 ); // Wait for EEPROM to finish (should timeout after 10 ms) while( (REG_EEPROM & 1) == 0 ); } |
Code: |
int AgbMain(void) { u8 buffer[8]; // Edited out some set up stuff here // Set up waitstates for EEPROM access etc. *(volatile unsigned short *)0x04000204 = 0x4317; do { EEPROM_Read( 0, buffer ); printf_special( "%d\n", buffer[0] ); ++buffer[0]; EEPROM_Write( 0, buffer ); } while( 1 ); return 1; } |
(printf_special is a routine which outputs text to the screen and waits for user input - it's been tested thoroughly so the problem definitely isn't there.)