Serial EEPROMs as Mass Storage
Intro
Forth without mass storage (blocks, screens) is a not complete. A SD-Card interface could be a reasonable solution but it is an overkill for a small Forth system. Small serial EEPROMs are for my opinion more suitable.
SPI EEPROMs

SPI EEPROMs

The Serial Peripheral Interface SPI or four-wire serial bus is easy to use. The CDP1802 (MC) is the SPI master, the EEPROM is the slave. There are many different EEPROM types and sizes available e.g. AT25M02 (2Mbit, 256 KiB, $3), 25LC1024 (128 KiB, $2), or 25LC512 (64 KiB, $1.50). All available in DIL8 packages. 64/128/256 KiB seems very small for today's standards where storage is quantified in GiB, but I think it's more than enough for a small Forth system, the size is similar to early floppy disks. If you want more memory there are 16 MiB serial Flash chips e.g. from WINBOND W25Q128J or IS25LP128F, please note they are 3.3 V devices and in SMT!

CLK   MC ->- host
MOSI  MC ->- host
MISO  MC -<- host
SS    MC ->- host or other peripherals (optional)

A high-to-low transition on the CS pin is required to start an operation and a low-to-high transition is required to end an operation.

Invalid Opcode: If an invalid opcode is received, no data will be shifted into AT25M02 and the Serial Data Output (SO) pin will remain in a high impedance state until the falling edge of CS is detected again. This will reinitialize the serial communication.

While in Hold mode, the SO pin will be in a high impedance state. In addition, both the SI pin and the SCK pin will be ignored.

From 1024 Kibit up there are 24 address bits, 8 Kibit to 512 Kibit have 16 address bits. 1, 2, and 4 Kibit have 8 bit address bits.

25LCxxxx Instruction Set

Name Format Description
READ 0000 0011 Read data from memory array beginning at selected address
WRITE 0000 0010 Write data to memory array beginning at selected address
WREN 0000 0110 Set the write enable latch (enable write operations)
WRDI 0000 0100 Reset the write enable latch (disable write operations)
RDSR 0000 0101 Read STATUS register
WRSR 0000 0001 Write STATUS register
PE 0100 0010 Page Erase – erase one page in memory array
SE 1101 1000 Sector Erase – erase one sector in memory array
CE 1100 0111 Chip Erase – erase all sectors in memory array
RDID 1010 1011 Release from Deep power-down and read electronic signature
DPD 1011 1001 Deep Power-Dow

AT25M02 Instruction Set

Name Format Description
READ 0000 0011 Read from Memory Array
WRITE 0000 0010 Write to Memory Array
WREN 0000 0110 Set Write Enable Latch (WEL)
WRDI 0000 0100 Reset Write Enable Latch (WEL)
RDSR 0000 0101 Read Status Register (SR)
WRSR 0000 0001 Write Status Register (SR)
LPWP 0000 1000 Low Power Write Poll

EEPROM Connected to MC's Centronics Connector (Switches and LEDs)

EEPROM Connected to MC's Centronics Connector (Switches and LEDs)

Sharing the LED and Switch port, you loose three LEDs and one switch or IN. Possible conflict with the bootstrap loader, if there is a read sequence (CS and read pattern 0000 0011). To prevent this, set the EEPROM into HOLD state e.g. with the WAIT signal.

SPI MC (Master) 25LCxxxx (Slave) Interface
MISO J2.1 IN EF4 2 SO diode e.g. 1N4148
MOSI J2.11 O7 LED7 5 SI direct
CLK J2.10 O6 LED6 6 SCK direct
CS J2.12 O5 LED5 1 CS direct
  P4.3 VDD 8 VCC +5V capacitor 100 nF to GND
  " 3 WP +5V
  J2.14 WAIT 7 HOLD direct
  21 GND 4 GND GND

mc-eeprom-conn.png
Schematic

Raspberry Pi can emulate SPI EEPROM. On RaspiElf the switches/LEDs are already connected to Raspi's GPIOs. No need for additional hardware. But I have to write an SPI server for the Raspberry Pi. Raspi's SPI interfaces can't be used because of conflicting port usage.

Read Byte


CS0     EQU     0b1101111
CS1     EQU     0b0010000
CLK0    EQU     0b1011111
CLK1    EQU     0b0100000
DATA0   EQU     0b0111111
DATA1   EQU     0b1000000

        ; MSB first

READBYTE:
        LDI     0
        PLO     R5
        LDI     0xFF
        PHI     R6
        LDI     0xFF - 8
        PLO     R6
        SEX     R0
BITLOOP:
        OUT4,0b01000000      ; CLK for SPI 
        OUT4,0b00000000
        INC     R6
        GHI     R6           ; set CARRY
        SHRC
        GLO     R5
        B4      SETBIT       ; branch if bit set
        SHL                  ; bit not set
        BR      SAVEBIT      
SETBIT:
        SHLC
SAVEBIT:
        PLO     R5
        GLO     R6
        BNZ     BITLOOP

about 230 cycles for one byte -> 1 ms -> 1 KiB takes about 1 s @ 1.79 MHz

Write Byte

WRITEBYTE:
        LDI     0
        PHI     R6
        LDI     8
        PLO     R6
        SEX     R0
BITLOOP:
        GLO     R5           ; get the next bit
        SHLC                 , next bit is in the carry
        PLO     R5
        BDF     SETBIT
        OUT4,0b01000000      ; CLK for SPI with data bit cleared
        OUT4,0b00000000
        BR      NEXT
SETBIT:
        OUT4,0b11000000      ; CLK for SPI with data bit set 
        OUT4,0b10000000
NEXT:      
        DEC     R6
        GLO     R6
        BNZ     BITLOOP
EEPROM patched on MC PCB

EEPROM patched on MC PCB

SPI Mode 0, data is always latched in on the rising edge of SCK and always output on the falling edge of SCK. For CS one output port bis is needed e.g. O7 or N2 (INP4) to start/end operation (A high-to-low transition on the CS pin is required to start an operation and a low-to-high transition is required to end an operation).

SPI MC (Master) 25LCxxxx (Slave) Interface
MISO EF2 2 SO direct
MOSI D0 5 SI direct
CLK TPB & N1 (OUT2) 6 SCK wired AND; Pullup 10 k, 2 1N4148
CS N2 1 CS direct
    8 VCC +5V
    3 WP +5V
  J2.14 WAIT 7 HOLD direct
    4 GND GND

mc-eeprom-u1.png
Schematic

Read Byte

        ; MSB first

        LDI     0
        PLO     R5
        LDI     0xFF
        PHI     R6
        LDI     0xFF - 8
        PLO     R6
        SEX     R6
BITLOOP:
        OUT2                 ; CLK for SPI, INC Rx
        GHI     R6           ; set CARRY
        SHRC
        GLO     R5
        B2      SETBIT       ; branch if bit set
        SHL                  ; bit not set
        BR      SAVEBIT      
SETBIT:
        SHLC
SAVEBIT:
        PLO     R5
        GLO     R6
        BNZ     BITLOOP

about 200 cycles for one byte -> 1 ms -> 1 KiB takes about 1 s

Write Byte

WRITEBYTE:
        LDI     0
        PHI     R6
        LDI     8
        PLO     R6
        SEX     R0
BITLOOP:
        GLO     R5           ; get the next bit
        SHLC                 , next bit is in the carry
        PLO     R5
        LSNF
        OUT2,0b00000000      ; CLK for SPI with data bit cleared
        LSDF
        OUT2,0b00000001      ; CLK for SPI with data bit set 
        DEC     R6
        GLO     R6
        BNZ     BITLOOP

EEPROM Connected to Raspberry Pi

EEPROM Connected to Raspberry Pi

SPI Function BCM/GPIO RaspiElf
SPI0 MISO 9 IN4
SPI0 MOSI 10 IN3
SPI0 SCLK 11 IN6
SPI0 CS0 8 IN7
SPI0 CS1 7 O0
EEPROM CS 5 O1
SPI1 MISO 19 O5
SPI1 MOSI 20 -
SPI1 SCLK 21 shutdown
SPI1 CS0 18 CLR
SPI1 CS1 17 WAIT

raspi-eeprom.png
Schematic
raspi-zero-eeprom.jpg
Raspberry Pi Zero and EEPROM interface

eeprom2bin (download tool)

NAME
eeprom2bin - Copies the EEPROM memory to a binary file on the Raspberry Pi.

SYNOPSIS
eeprom2bin [-s hexadr] [-e hexadr] [file]

DESCRIPTION
Copies the EEPROM memory to a binary file (or stdout) on the Raspberry Pi. The Raspberry Pi GPIO SPI0.1 is used as interface to the SPI EEPROM (24 bit address, at least a 1024 Kibit type, 256 byte page). The generated data is written to the standard output stream or to a file. Caution: Overwrite file if it exists. Use > for redirecting (save the file) or | for piping to another command (e.g. hexdump).

OPTIONS
Non argument options that are duplicated on the command line are not harmful. For options that require an argument, each duplication will override the previous argument value.
-s hexadr
start address in hex (0 is default)
-e hexadr
end adress in hex (0x1FFFF is default)

bin2eeprom (upload tool)

NAME
bin2eeprom - Copies the content of binary file on the Raspberry Pi to EEPROM.

SYNOPSIS
bin2eeprom [-s hexadr] [-e hexadr] [file]

DESCRIPTION
Copies the content of binary file on the Raspberry Pi to EEPROM memory. The Raspberry Pi GPIO SPI0.1 is used as interface to the SPI EEPROM (24 bit address, at least a 1024 Kibit type, 256 byte page). Use < for redirecting or | for piping from another command.

OPTIONS
Non argument options that are duplicated on the command line are not harmful. For options that require an argument, each duplication will override the previous argument value.
-s hexadr
start address in hex (0 is default)
-e hexadr
end adress in hex (0x1FFFF is default)

How to get and build the EEPROM tools

Get the source from the GIT repository (if you have not installed GIT yet, then install it with sudo apt-get install git), type only the bold text after the $ sign:

pi@cosmac:~/elf $ git clone https://github.com/spyren/RaspiElf
Cloning into 'RaspiElf'...
pi@cosmac:~/elf $

Build (compile) from the sources:

pi@cosmac:~/elf $ cd RaspiElf
pi@cosmac:~/elf/RaspiElf $ cd eeprom
pi@cosmac:~/elf/RaspiElf/eeprom $ make
cc -g -c eeprom2bin.c
cc -g -o eeprom2bin -lwiringPi eeprom2bin.o
cc -g -c bin2eeprom.c
cc -g -o bin2eeprom -lwiringPi bin2eeprom.o
pi@cosmac:~/elf/RaspiElf/eeprom $ 

Install the binaries into /usr/local/bin

pi@cosmac:~/elf/RaspiElf/eeprom $ sudo make install
install -m 557 eeprom2bin bin2eeprom /usr/local/bin

Install wiringPi (GPIO Interface library for the Raspberry Pi), details see http://wiringpi.com/download-and-install/

Enable the SPI interface

@cosmac:~/elf/RaspiElf/eeprom $ sudo raspi-config
  • 5 Interfacing Options Configure connections to peripherals
  • P4 SPI Enable/Disable automatic loading of SPI kernel module

Kermit/ZModem

Kermit/ZModem

What about using KERMIT or ZMODEM protocol for the file transfer and use the file system on the host? No need to add additional hardware (SD-card is anyway to modern wink You could use an old CP/M or even a PDP11 as host. The C-Kermit Local Server mode, e.g. MC can read/write the blocks as files block.0, block.2, block.255.

The serial communication is really slow, not only because of the 9600 baud, but you have to wait after each character to give CDP1802 some computation time.

https://github.com/utoh/pygmy-forth/blob/master/extras/kermit/pfkerm.doc

-- Peter Schmid - 2019-01-24

Comments

Topic attachments
I Attachment History Action Size Date Who Comment
PNGpng raspi-eeprom.png r3 r2 r1 manage 25.8 K 2019-01-27 - 21:22 PeterSchmid  
JPEGjpg raspi-zero-eeprom.jpg r1 manage 201.6 K 2019-01-27 - 21:40 PeterSchmid  
Edit | Attach | Watch | Print version | History: r23 | r12 < r11 < r10 < r9 | Backlinks | Raw View | Raw edit | More topic actions...
Topic revision: r10 - 2019-01-28 - PeterSchmid
 
  • Edit
  • Attach
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback