Writing to Flash EEPROMs is much
slower than writing to RAM, and requires writing control codes to the address
space of the chip to perform these operations. Apparently the Flash EEPROM used
is the "SHARP LH28F160S3-L", which has many features (some may be
disabled) including writing (multiple) words/bytes, erasing 64kb blocks, and
locking of blocks.
For more information on this chip
see Johan Borg's file at http://d188.ryd.student.liu.se/ftp/calculator/ti89/tech/flashrom.txt,
he also has put up the datasheet at ftp://d188.ryd.student.liu.se/calculator/ti89/tech/f160s3.pdf
which is worth a look.
Fortunately only a subset of this
chips features are used; writing words and erasing blocks. Write operations
take 12.95 micro-seconds, read operations 100ns, so you can see why a special
mode of operation is required.
To program the EEPROM we need to
enter a special mode by writing certain control codes to the address range. Two
operations can be performed, erase (64kb) sector, and write a word. In this
write mode reading from the address range gives the status register of the EEPROM,
generally the only value that is used is that bit 7 of the read word will be
set when complete. After the operations are complete Read mode is then set by
writing another control code.
The drawback of this method is that
the ROM cannot be read whilst write operations are being performed. Therefore
the writing code must execute from the RAM. Trap 11 handles all of this on the
calculator, copying the relevant portions to a buffer then executing them.
The following subset of operations
is used:
Code |
Function |
0x5050 |
Clear Status
Register |
0x1010 |
Write Setup
(next word will be written) |
0x2020 |
Erase Setup |
0xD0D0 |
Erase Conform
(address) |
0xFFFF |
Read Memory |
Erasing and writing require to
writes, e.g. 0x2020, 0xD0D0 to perform erase to prevent accidental operations.
Note
The flash memory is, by default,
write protected by the system. And can only be written to under special
circumstances. See Intelligent
Memory.
Examples
;erase 64kb block
in which ERASE_ADDR resides
lea (ERASE_ADDR),a2
move.w #0x5050,(a2) ;Clear Status
Register
move.w #0x2020,(a2) ;Erase Setup
move.w #0xD0D0,(a2) ;Erase Confirm
write_state_busy:
move.w (a2),d0 ;Read Status Register
btst #7,d0 ;1=Ready
beq write_state_busy
move.w #0xFFFF,(a2) ;Read
;write VALUE to
WRITE_ADDR
lea (WRITE_ADDR),a2
move.w #0x5050,(a2) ;Clear Status
Register
move.w #0x1010,(a2) ;Write Setup
move.w #VALUE,(a2) ;Erase
Confirm
write_state_busy:
move.w (a2),d0 ;Read Status Register
btst #7,d0 ;1=Ready
beq write_state_busy
move.w #0xFFFF,(a2) ;Read