aboutsummaryrefslogtreecommitdiff
path: root/amforth-6.5/avr8/lib/hardware/25xxx.frt
diff options
context:
space:
mode:
Diffstat (limited to 'amforth-6.5/avr8/lib/hardware/25xxx.frt')
-rw-r--r--amforth-6.5/avr8/lib/hardware/25xxx.frt131
1 files changed, 131 insertions, 0 deletions
diff --git a/amforth-6.5/avr8/lib/hardware/25xxx.frt b/amforth-6.5/avr8/lib/hardware/25xxx.frt
new file mode 100644
index 0000000..2951810
--- /dev/null
+++ b/amforth-6.5/avr8/lib/hardware/25xxx.frt
@@ -0,0 +1,131 @@
+
+ 6 constant SEE_WREN
+ 4 constant SEE_WRDI
+ 5 constant SEE_RDSR
+ 1 constant SEE_WRSR
+ 3 constant SEE_READ
+ 2 constant SEE_WRITE
+$AB constant SEE_RDID \ Microchip 25LCxxx only; remove from deep power-down
+
+ : 25xxx_disable \ raise serial EEPROM chip-select line high
+ 25XXX_CS_A_MASK
+ 25XXX_CS_A_PORT c@
+ or
+ 25XXX_CS_A_PORT c!
+ ;
+
+ : 25xxx_enable ( -- ) \ pull serial EEPROM chip-select line low
+ 25XXX_CS_A_MASK invert
+ 25XXX_CS_A_PORT c@
+ and
+ 25XXX_CS_A_PORT c!
+ ;
+
+ : 25xxx_c! ( c addr -- ) \ writes char in NOS to serial EEPROM, address in TOS
+ 25xxx_enable
+ 25XXX_WREN spi_send \ send enable-write command, ignore response
+ 25xxx_disable
+
+ 25xxx_enable
+ 25XXX_WRITE spi_send \ send write command, ignore response
+ 25xxx_sendaddr \ send addr (16 or 24 bits)
+ spi_send \ write byte
+ 25xxx_disable
+ 25xxx_wait_rdy
+ ;
+
+ : 25xxx_! ( w seeaddrl seeaddrh -- ) \ write word in NOS to serial EEPROM at addr in TOS
+ 2>r dup >< 2r> \ fast way to prep data in stack ( wl wh seeaddrl seeaddrh )
+ over over 1 0 d+ \ precalc addr of second byte in data
+ 2>r \ save for later ( wl wh seeaddrl seeaddrh )
+ 25xxx_c! \ write MSB of word ( wl )
+ 2r> \ recover addr of next byte ( wl seeaddrl+1 seeaddrh )
+ 25xxx_c! \ write LSB
+ ;
+
+ : 25xxx_wait_rdy ( -- ) \ busy-wait until serial EEPROM finishes writing
+ begin
+ 25xxx_enable
+ 25XXX_RDSR spi_xchg drop \ send read-status command, ignore response
+ 0 spi_xchg \ send null byte, response is on TOS
+ 25xxx_disable
+ 1 and \ isolate the WIP (write-in-progress) bit
+ 1 xor \ reverse state of WIP bit
+ until \ loop until WIP = 0
+ ;
+
+ : see_c@ ( addrl addrh -- c ) \ returns byte at 32-bit address in TOS
+ 25xxx_enable
+ 25XXX_READ spi_send \ send READ command, ignore response
+ 25xxx_sendaddr \ send address (16 or 24 bits)
+ 0 spi_xchg \ send null byte, response is in TOS
+ 25xxx_disable
+ ;
+
+ : 25xxx_c@_blk ( addr n eeaddrl eeaddrh -- )
+ 25xxx_enable
+ 25XXX_READ spi_send \ send READ command, ignore response
+ 25xxx_sendaddr \ send address (16 or 24 bits)
+ 0 \ ( -- addr n 0 )
+ do \ for all requested bytes...
+ 0 spi_xchg \ get byte from serial EEPROM
+ over \ get addr to use
+ c! \ save the byte
+ 1+ \ bump pointer
+ loop
+ drop \ done with address
+ 25xxx_disable
+ ;
+
+
+ : 25xxx_c!blk ( addr n seeaddrl seeaddrh -- ) \ copies N bytes from addr to EEPROM address in TOS/NOS
+ 25xxx_enable
+ 25XXX_WREN spisend \ need to enable serial EEPROM for writing
+ 25xxx_disable
+
+ 25xxx_enable
+ 25XXX_WRITE spi_send \ send WRITE command, ignore response
+ over over \ copy of 32-bit serial EEPROM addr
+ 25xxx_sendaddr \ send addr to serial EEPROM ( -- addr n seeaddrl seeaddrh )
+ rot \ ( -- addr seeaddrl seeaddrh n )
+ 0 \ ( -- addr seeaddrl seeaddrh n 0 )
+ do \ for all requested bytes ( -- addr seeaddrl seeaddrh )
+ rot dup i + \ addr of byte to fetch ( -- seeaddrl seeaddrh addr addr+i )
+ c@ spi_send \ write to serial EEPROM ( -- seeaddrl seeaddrh addr )
+ rot dup i + \ calc addr within serial EEPROM ( -- seeaddrh addr seeaddrl seeaddrl+i )
+ 7f and 7f = \ last addr in page?; use 7f for 25LC256/512, 3f for AT25128/256
+ if
+ 25xxx_disable \ done with this page
+ 25xxx_wait_rdy
+ 25xxx_enable
+ 25XXX_WREN spi_send \ need to enable serial EEPROM for writing
+ 25xxx_disable
+ 25xxx_enable
+ 25XXX_WRITE spi_send \ send WRITE command ( -- seeaddrh addr seeaddrl )
+ rot \ set up EEPROM addr ( -- addr seeaddrl seeaddrh )
+ over over \ get a copy
+ i 1+ 0 d+ \ calc addr of next page ( -- addr seeaddrl seeaddrh seeaddrl seeaddrh )
+ 25xxx_sendaddr \ send addr to serial EEPROM ( -- addr seeaddrl seeaddrh)
+ else \ not start of new page ( -- seeaddrh addr seeaddrl )
+ rot \ rearrange ( -- addr seeaddrl seeaddrh )
+ then
+ loop
+ drop
+ drop drop
+ 25xxx_disable
+ 25xxx_wait_rdy
+ ;
+
+
+ : 25xxx_init ( -- ) \ initialize SPI and I/O ports for accessing serial EEPROM
+ spi_init
+ 25XXX_CS_A_DDR c@
+ 25XXX_CS_A_MASK or \ need to make CS an output
+ 25XXX_CS_A_DDR c!
+ 25xxx_enable
+ 25XXX_RDID spi_xchg drop \ Microchip 25LCxxx only; take chip out of deep power-down
+ 0 spi_xchg drop \ need to send dummy 16-bit addr, ignore response
+ 0 spi_xchg drop
+ 0 spi_xchg drop \ one last null byte, Microchip devices will send ID, ignore it
+ 25xxx_disable
+ ;