Hi, starting with svn 7610, sdcc/pic16 allows read/write access EEPROM via generic pointers in the range of 0x40_0000 to 0x7F_FFFF (though only the one or two least significant byte(s) are actually used to index into the EEPROM). Devices that do not have any EEPROM will silently ignore EEPROM accesses, reads will return random values. Also note that interrupts are disabled during EEPROM accesses and that writes wait for the end of the EEPROM write by polling EECON1.WR after each byte while interrupts are still disabled. This seems to be the safest and simplest approach; safe improvements are welcome.
!!! THE CODE IS COMPLETELY UNTESTED. IT COMPILES FOR ME, BUT THERE ARE NO GUARANTEES WHATSOEVER BEYOND THAT !!! In order to accomodate the different device types (no EEPROM, 8-bit EEPROM range, 16-bit EEPROM range (via EEADRH)), generic pointer access to EEPROM is a bit involved: device/lib/pic16/libsdcc/gptr/gptr{get,put}[1234].c branches off to device-specific EEPROM dispatcher routine defined in either (a) device/non-free/lib/pic16/libdev/gptr/dispatch.S (returns immediately) (b) device/non-free/lib/pic16/libdev/gptr/eeprom8_*_dispatch.S (jumps on to __eeprom8_* to access 8-bit EEPROMs using EEADR only) (c) device/non-free/lib/pic16/libdev/gptr/eeprom16_*_dispatch.S (jumps on to __eeprom16_* to access 16-bit EEPROMs using EEADRH:EEADR) The __eeprom{8,16}_gptr{get,put}[1234] routines are again defined in device/lib/pic16/libsdcc/gptr/eeprom{8,16}_gptr{get,put}[1234].c and included in libsdcc, but are linked into the final executable only when referenced, and each device library references only one set of these (either eeprom8 or eeprom16). Writing to EEPROM is rather longish, so I factored the relevant code out into device/lib/pic16/libsdcc/gptr/eeprom{8,16}_write.c and call it from eeprom{8,16}_gptrput[1234].c The indirection via dispatchers requires two GOTOs (4 cycles) where one BRA (1 cycle) could suffice iff I provided 3 complete sets of gptr{get,put}[1234] and linked the proper one into each device lib, but that would require compiling them for each device separately and would add more free code to the non-free tree, both of which I wanted to avoid. To use, you MUST use an updated sdcc + an updated library (libsdcc, libdev) and you SHOULD try something like uint8_t *eeprom = (void *)0x400000; uint8_t read_eeprom(uint16_t offset) { return eeprom[offset]; } void write_eeprom(uint16_t offset, uint8_t val) { eeprom[offset] = val; } Pitfalls: * TYPE __at(0x400000) ID = INIT; does not work yet and probably never will * TYPE __at(0x400000) ID; does not work (yet) * accessing bitfields in EEPROM does probably not work * accessing structs in EEPROM via (*((struct TAG *)0x400000)).FIELD should work (except for bitfields, see above), but is untested * *((TYPE*)&eeprom[offset]) should work for any primitive TYPE with sizeof(TYPE) <= 4, including generic pointers (3 byte) I would like to hear any code review and/or test results. Raphael ------------------------------------------------------------------------------ For Developers, A Lot Can Happen In A Second. Boundary is the first to Know...and Tell You. Monitor Your Applications in Ultra-Fine Resolution. Try it FREE! http://p.sf.net/sfu/Boundary-d2dvs2 _______________________________________________ Sdcc-user mailing list Sdcc-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sdcc-user