This new release mostly consists of added support for EEPROM chips. The drivers for this were originally written by Larry Lynch-Freshner - many thanks Larry!
The source code is here and the Intel Hex suitable for feeding to an EPROM burner is here (checksum should be BEE4). If you don't have access to an EPROM burner and want a free upgrade return you current EEPROM (or any 27C256) to me, packed carefully, along with a stamped self-addressed envelope and I'll send you a free 2.2 upgrade.
To use these features you must populate your board with a 24LC164 or equivalent EEPROM - the V1.0 boards don't have a spot for these but space is available in the proto area just copy the wiring on the 3rd page of the 2.0 schematics. Don't confuse the ROM that came with your kit with an EEPROM these were not included - you have always had to purchase this yourself.
If you use 24LC164 EEPROMs (rather than the 24C64s) you can add multiple EEPROMS on a daughter card up to a maximum of 8 (16Kbytes).
Also new is the ability to save a program into EEPROM - and recover it later or to have it automaticly loaded when the system is reset or is powered on. To trigger this you short the rcvin pin (usually used when you have the RS232 converter attached as an RS232 input pin to ground) for testing you can put a small switch in your cable harness. The RCVIN pin is P3.0 (pin 10 on the chip).
At power on the ROM now looks to see if P3.0 is 0, if it is it reads the first 2 bytes of the EEPROM (address 0) - if the first is 0xa5 and the second is one of 'C', 'B' or 'F' then the saved assembly, Basic or Forth (resp) is loaded from the EEPROM and executed rather than going to the appropriate command prompt. Bytes 2/3 of the EEPROM are used as a count (byte 2 is the lsb) of the number of bytes to load and bytes 4-N in the EEPROM are loaded.
The monitor has been modified to add a number of new commands:
DEThe basic idea is that you create a program that starts at 0x8000 (the base of external sram memory) and load it in to memory as you usually would to run it then enter "SEdumps out the eeprom from address SE copies bytes to the eeprom from 0x8000 with a 'C' header SF as above with a 'F' der (for Forth see below) LE loads the saved EEPROM code to 0x8000 ED give a listing of all data sets in the eeprom
At reset if P3.0 is tied low then the ROM will do an equivalent of "LE;G 8000" to start your saved program. Your program is called as a subroutine just before the monitor would normally turn on it's interrupts and print a prompt - if you execute a return from your program it will enter the monitor just as normal. One warning - your program is called with interrupts disabled - unless you want to completely replace the monitor you should have "mov ie, #0xa0" as the first instruction in your program.
If the
Saving a Basic program is easy - when you have the program loaded up and working
simply enter the "PROG" command - this copies your program to EEPROM, and prints
out the number of bytes it takes (the format in the EEPROM has the header described
above - but the data is the internal format of the Basic interpreter).
If you type "XFER" the current program in RAM is deleted and the one you saved in
EEPROM is returned.
If you have done a Basic PROG then starting the system with P3.0 tied low will
cause Basic to be entered at reset time and the program loaded as if you had typed
"XFER; RUN".
This is a little wierd ... the internal format of Forth programs doesn't make
them easy to save directly, instead you must save the source. You need to get a copy
of toforth.c a short C program which if fed text in it's
standard in spits out Intel hex records starting at 0x8000. Feed your Forth source
through this program ie "toforth
Now at reset time if P3.0 is tied low the Forth interpreter will be loaded up
and all input will be directed to the commands in EEPROM rather than to the keyboard.
In general be carefull about loops - an eeprom can only be written
a million or so times - a runaway loop can ruin it.
Programs can access the EEPROM drivers through the utility vector, parameters to
EEPROM calls are:
To write an EEPROM location do "EE(address) = value" - the value will be converted
into a value between 0 and 255 and will be written to that EEPROM address. To read from
EEPROM simply do "v = EE(address)".
From Forth you van write a value to EEPROM using:
Once you have code loaded into EEPROM there comes the problem of "how
do we share EEPROM space with data?". Working with Larry I've come up with
a standard for sharing space in the EEPROM.
Basicly the EEPROM contains a number of data or code sets - they sit
in EEPROM one after each other starting at address 0. Each set consists
of a header and some data, the header consists of the hex value 0xa5 followed
by a type - an upper case letter, followed by a 2 byte length field (LSB first)
followed by the data portion,
the length is the length of the data - the total length of the whole data set
is the length field+4 rounded up to the next multiple of 16 bytes if it isn't
already a multiple of 16 bytes.
The "ED" monitor command will walk down a list of data/code sets printing
out their types and lengths.
Saving/Loading Basic Programs
Saving/Loading Forth Programs
Accessing EEPROM from programs
Assembly
R2 - 'W' write with fixed (100) retries
- 'w' write with retry count in R4
- 'R' read with fixed (100) retries
- 'r' read with retry count in R4
R0 - the address in on board sram that the data will be
copied to/from
R6 - MSB of EEPROM address
R7 - LSB of EEPROM address
R3 - count of bytes to be copied, for reads this may be
up to 256 bytes, for writes it may not be more than
16 bytes - and all the bytes written must be contained
within the same 16-byte-aligned EEPROM memory block
The following code fragment makes a good entry to the utility vector:
utility_vector = 0x8a ;; pointer to generic utility vector
call_uv:
mov r1, #utility_vector
mov a, @r1
mov dpl, a
inc r1
mov a, @r1
mov dph, a
clr a
jmp @a+dptr
So to write the 16 bytes in on-board SRAM at 0xf0 to 0x1234
use:
mov r6, #0x12
mov r7, #0x34
mov r0, #0xf0
mov r3, #16
mov r2, #'W'
acall call_uv
Accesses to EEPROM can fail - especially after a write you may have to retry
several times before you can do another read or write - normally a large
timeout is used to (the 'R' and 'W' commands above) to make sure that
accesses always suceed - but that if there's no EEPROM responding at that address
the access doesn't hang for ever. If the timeout passed without an EEPROM acking the
request the access will return with the C bit set. If you have a time critical
process going where you don't want to hang in the EEPROM code for an unknown
amount of time - use the 'r'/'w' calls with a timeout of 1 - and repeat when you
have time untill it returns with the C bit clear.Accessing EEPROM from Basic
Accessing EEPROM from Forth
val address EE!
While to read the following leaves the value on the top of the stack:
address ?EE
Multiple Data/Code sets in EEPROM