I2C driver for AT24C256 32 kByte EEProm
Fred Zelders has contributed a 32K EPROM driver for the Scamp, providing a reliable way to expand non-volatile storage. This code enables seamless read and write operations, making it a valuable addition for developers working with the Scamp.
Source code and implementation details:
Source code and implementation details:
\ **************************************************************
\
\ Filename: at24c256_rw.frt
\ Version: 1.4
\ Date: 2024-12-12
\ FF Version: 5.0
\ MCU: PIC24 | Scamp3/Scamp3e
\ Copyright: Fred Zelders
\ Author: Fred Zelders
\ Description: I2C driver for AT24C256 32 kByte EEProm
\
\
\ FlashForth is licensed according to the GNU GPL3
\
\
\ Remarks:
\ One eeprom page - #64 consecutive bytes
\ Device: AT24C256
\ Interface: I2C (address $50)
\ Connections:
\ VCC Power 3.3V or 5V
\ GND Ground
\ SDA Data
\ SCL Clock
\
\ Tokens:
\ eByte@ ( eeprom-address -- byte ) : Retrieves byte
\ from eeprom address
\ eByte! ( byte, eeprom-address -- ): Stores byte in eeprom address
\ ePage@ ( page -- ): Reads an eeprom page in
\ address 'dataPointer @'
\ ePage! ( page -- ) : Copies content 'dataPointer @'
\ to eeprom page
-at24c256
marker -at24c256
$2de constant I2CBUSCLK \ Address of the i2c bus clock
#157 I2CBUSCLK ! \ Set i2c bus clock to 100 kHz
\ Erasable eprom: at24c256 32 kB
$50 constant AT24C256EPROM \ eeprom i2c adress
\ eeprom-adres: $0000-$7fff
#64 constant PAGESIZE \ 1 page = #64 bytes
#512 constant #PAGES \ Number of pages in the eeprom
#32 constant #SCREENS \ Number of screens in the eeprom
\ The variable dataPointer points to an area of 64 bytes in RAM
variable dataPointer
$ffff dataPointer ! \ Initial value: -1
\ Check if eeprom is present and use 'buffer'
: disk-init ( -- )
#157 I2CBUSCLK ! \ 100 kHz i2c bus clock
AT24C256EPROM ping abort" abort! > 0-no eeprom."
dataPointer @ 0 < abort" abort! > 1-dataPointer not set."
;
\ Eeprom access at byte level
\ write byte to eeprom address
: eByte! ( byte, eeprom-address -- )
start \ Start i2c communication
AT24C256EPROM write drop \ To AT24C256EPROM
( address ) \ Send MSB and LSB eeprom address
dup
8 rshift $ff and send drop \ MSB
$ff and send drop \ LSB
( byte ) send drop \ Send byte
stop \ Stop i2c communication
5 ms
;
\ Get byte from eeprom address
: eByte@ ( eeprom-address -- byte )
start
AT24C256EPROM write drop
( address ) \ Send MSB and LSB eeprom address
dup
8 rshift $ff and send drop \ MSB
$ff and send drop \ LSB
repstart \ Switch immediately to read mode
AT24C256EPROM read drop
receive nack \ Receive byte
stop
;
\ Copy dataPointer content using burst-write to an eeprom page
: ePage! ( address, page -- ) \ From memory to EEPROM
swap dataPointer ! \ begin data
#PAGES mod \ Stay within the limits
PAGESIZE *
start \ Start i2c communication
AT24C256EPROM write drop \ To AT24C256EPROM
( address ) \ Send MSB and LSB eeprom address
dup
8 rshift send drop \ MSB
$ff and send drop \ LSB
\ Send by burst-write 64 bytes to eeprom page
PAGESIZE for
PAGESIZE 1- r@ -
dataPointer @ +
c@ \ Remove byte from buffer
send drop \ Save in eeprom
next
stop \ Stop i2c communication
5 ms
;
\ Copy content eeprom page using sequential read > memory
: ePage@ ( page, address -- ) \ Read 64 bytes seqRead
dataPointer !
#PAGES mod \ Stay within the limits
PAGESIZE * \ Eeprom page start address
\ Start i2c communication
start
AT24C256EPROM write drop
dup \ eeprom adress
8 rshift send drop \ eeprom address MSB
$ff and send drop \ eeprom address LSB
\ Switch to receive
repstart
AT24C256EPROM read drop
PAGESIZE 1- for
receive \ Remove byte from eeprom page
PAGESIZE 2- r@ -
dataPointer @ +
c! \ Store in buffer
ack
next
receive \ Get last byte from eeprom page
dataPointer @ PAGESIZE 1- +
c! \ Save in dataPointer @
nack \ Stop sequential with nack
\ Stop i2c communication
stop
;