M62-bus Nano Serial Interface Board

PCB Circuit (click to enlarge) Nano Serial Interface Board Circuits and Info

Eagle CAD: 1. Arduino Nano Interface 4" x 4"



Eagle CAD: 1a. Arduino Nano Interface 4" x 6"




Eagle CAD: 2. M62-bus Male Edge Connector



Eagle CAD: 3. PCB Layout 4" x 4"

(Second Version)



Eagle CAD: 3. PCB Layout 4" x 6"

(Second Version)



First PCB Production Board



PCB with I2C Devices



LA View of Z80 'Write' to Nano




LA View of Z80 'Read' of Nano



Arduino Nano v3 Pinout




(Bill of Materials)

PLEASE NOTE: I do not sell production boards. If you would like to buy an M62 Z80 system board/parts kit, contact Peter Murray, Peter@39k.ca

I simply provide you with information to build your own breadboard computer.


Giving credit where it's due

The Serial Interface board was designed by Peter Murray to allow the Z80 to communicate on its 8-bit parallel data bus through a 5v Arduino Nano to your I2C and SPI devices like RTC, SD, weather sensor, etc.


NOTE: 2019-11-20   I'm still testing the first version of the PCB that has returned from fabrication; the 6th item in the adjacent panel is a picture of it. It seems to work well as long as you use the upper I2C pins, SDA and SCL. If you wish to use the lower ones, you'll need to build a solder bridge between the upper and lower SDA pins and another solder bridge for the upper and lower SCL pins.

NOTE: 2019-12-02   The first 3 adjacent CAD diagrams are for the second version of the PCB that goes out for fabrication today. Use either design at your own risk.



If you attempt to use the Z80 and either an 8255 PPI/PIO or a UART to communicate with SPI or I2C devices like a Real Time Clock (RTC) or Barometric/Temperature sensor, etc., you're probably going to have to bit-bang the processor to communicate with these modern modules.

One alternative to this kind of "pain" is to let a microcontroller like the Arduino Nano do all the "heavy lifting". Instead of the Z80 sending one bit at a time serially, it will send 8 bits in parallel on its Data bus to the Nano. The Nano in turn will send the data using either the I2C or SPI protocol to communicate with the device.


How does the Z80 write to or read from the Nano?

Z80 -> Nano: The Z80 issues an OUT instruction to the Nano. This sets the data bus with the data. The addressing circuitry will trigger a latch holding the Z80 in a Wait state while notifying the Nano and giving it time to a) read the data off the bus, b) determine the address it was trying to reach, and c) release the latch allowing the Z80 to resume.

Nano <- Z80: the Z80 issues an IN command to the Nano which triggers the latch and notifies the Nano. The microcontroller will read the address and load its data bus with the appropriate response. The latch is released by the Nano so the Z80 can read the data via a '244 buffer.


General Operation

During a Z80 write-to-IO-bus operation, '244 IC4 is enabled via the Nano A_RD signal to gate the Z80 D0 to D7 signals onto the Nano bus.

During a Z80 read-from-IO-bus operation, '244 IC5 is enabled via the A2Z (Nano to Z80) signal to gate the Nano A_D0 to A_D7 signals onto the Z80 bus. It was initiated via the Z80 RD signal to the Nano.

For orderly flow, the WAIT signal to the Z80 is used whenever a Z80 (I/O) OUT or IN instruction for the I/O address range is executed. The Nano was initially interrupted via the A_INT signal. Normal operation is resumed when the Nano sees the A_REL signal.


Operations nitty gritty

Use schematic 'M62-bus_Serial_IF_Bd_01.png', Arduino sketch Z80-Nano_SIF.ino, and the ROM Monitor to enter OUT or IN commands to the Z80.
Within the sketch in the 'setup()' code, A_REL (nRELEASE) and A_RD (nREAD) are both set high and a low-going interrupt is attached to A_INT (nINT).
To get the Nano to write or read I/O data, use the Z80's ROM Monitor to write a value to the I/O address you jumpered on the Serial Interface board.
In the lower adjacent screenshot "LA View of Z80 'Write' to Nano", you can see the user has started up the Monitor and has issued an 'o' or 'O' command to output a value to an I/O address: the Monitor function uses the Z80 instruction 'OUT (C),A'. The first byte in the Monitor command that follows is '20' to indicate an I/O address/port of 0x20, and the next byte is '00' to indicate a value of 0x00.
In the same screenshot in the lower right we can see the Nano Serial Monitor display "Debug: Z80 wrote 0 to 0", followed by "Debug: Z80 wrote 0 to 1" meaning the value 0x00 was written to aA0 and aA1 locations of 00 followed by 01 . The Nano is not aware that the Z80 has been jumpered to a base I/O address other than 0x00.
Using schematic 'M62-bus_Serial_IF_Bd_01.png' and assuming a base I/O address of 0x20, when Z80 addresses 0x20 to 0x23 are used:
 - Z80's A0 and A1 (schematic frame location A3) are read into the Nano as aA0 and aA1 (see lines 25 and 26  of the Arduino sketch, Nano inputs A6 and A7) which causes a low to go out JP2 (location A6)
 - a high goes out IC3D pin 11 which is input to IC3C pin 9 (location B6)
 - IC3A Reset is high and so is A_REL (location B5) by default in the Nano sketch. The high into IC3C at pin 10 combined with the high from IC3D pin 11 causes a low out IC3C pin 8 which triggers the WAIT line (location B4) to the Z80.
 - This low out IC3C pin 8 also fires a low on A_INT to the Arduino Nano; this is an interrupt to the Nano.
 - According to the Nano sketch, a routine labeled 'theISR' will now run.
 - In summary, the Z80 is holding in a Wait state and the Nano is going to run an interrupt service routine.
theISR() runs:
 - the variable 'address' from procedure 'readAddress()' at line 99 returns the value of the aA0 and aA1 pins. (You could use the 'Registers' in the sketch for your own needs, e.g., read the 'seconds' counter from an RTC, etc.)
- the variable 'DataIn' from routine 'readData()' at line 107 sets Nano 'nREAD' output A_RD (location D5) to low to read from the Z80 bus. We see the signal A_RD gate both halves of IC4 so that the data queued on the Z80 data bus is gated to the Nano data bus composed of A_D0 to A_D7.  The setDataDir() procedure at line 109 is set to input, so the 8-bit wide Z80 databus is read bit by bit into the Nano as value 'temp' in lines 114 to 121. Setting nREAD (A_RD) high at line 122 at the bottom of readData() ceases the Z80 bus read to the Nano and the value 'temp' is returned to DataIn.
 - the data direction variable, DIR, is read next in theISR(), line 77. DIR is determined to be high or low by the state of the Z80 RD line, location B4. If DIR is high (1) in the 'if' statement, then the statement that follows is true so it's a write (RD = 1). The comm is from the Z80 to the Nano, hence we see the Serial Monitor report "Debug: Z80 wrote [DataIn] to [address]." In the circuit, we see gate IC2B (location C6) gate the Nano bus queued data to the Z80 databus through the '244s.
 - if the data direction variable DIR is read to be low (0), then the statement is false so 'else' in line 85 is executed. The comm is from the Nano to the Z80 and we'll see the Serial Monitor report "Debug: Z80 read from [address].
 - The Nano has been writing or reading data but the Z80 is still in a wait state. The last two statements in theISR() routine toggle the A_REL line low then high which sets A_INT high which in turn terminates the WAIT signal.
There is no loop in the Nano sketch. That is up to you with whatever device you attach to the I2C or SPI connectors on the SIF board.


The SPI and I2C male jumpers:

Your Z80 can now talk to SPI- or I2C-based devices.

I2C uses jumpers JP4, JP6, JP8 and JP10.

SPI uses jumper JP16. If you wish to add 2 more SPI devices, then disable I2C (SDA and SCL) with jumpers JP22 and JP23. That will make jumpers JP18 and JP20 available for SPI for a total of 3 SPI devices.


Termination Resistors:

Both SPI and I2C can be finicky, especially when it comes to signal terminations needed for master or slave modes.

As such, I have provided optional 4.7K pullups for I2C. The original Adafruit DS1307 RTC I tested with this SIF board had 2.2K pullup resistors. I removed them and used the SIF board 4.7K resistors and it worked fine.

Additionally, I have provided optional 10K pullups and 4.7K pulldowns for SPI. You can see them labelled in the upper part of the schematic.


What do I need to program the Arduino Nano 5v?

Arduino Code: Nano-Z80_SIF.ino


How do I test the Nano Serial Interface (SIF) board?

Upload the sketch to the Nano, then start up the Arduino IDE's Serial Monitor function under Tools.

Fire up your Z80's ROM monitor and issue an OUT instruction to address 0x20 with data 0x00. This is assuming you have jumpered the SIF for I/O address 0x20.  You can see that in the adjacent screenshot, Z80 Write Nano.

Then try an IN instruction of address 0x23. You can see that in the adjacent screenshot, Z80 Read Nano.


The Logic Analyzer (LA) view of writes and reads

With a Z80 write to the Nano, there is no reason to use the A2Z gate. That's why we see it high in the adjacent "Write" screenshot.

With a Z80 read from the Nano, the A2Z gate is enabled immediately. That's what we see in the adjacent "Read" screenshot.


I see the schematics. Where is the Bill of Materials parts list?

The BOM is at the bottom of the adjacent panel.


How big is the Serial Interface board and what will the printed circuit board look like?

The PCB measures 100mm x 100mm (4" x 4") or 100mm x 150mm (4" x 6"). Click the adjacent thumbnail to see a possible parts layout.


Now that I've got the SIF board working, where do I go from here?

Adapt your fave real-time clock (RTC) board like the DS1307 or the DS1340 using the to the Nano sketch above and the Arduino Library RTC drivers. Then write some Z80 code to read the Registers created in the Nano sketch. We will be doing this at a later date when we design, build and test a board containing various I2C and/or SPI devices.















Note: M62 Bus is copyrighted by Peter Murray of Murray Electronics, http://www.39k.ca

NEXT PAGE: M62-bus Nano SIF with RTC =>



Tags: Z80 SBC, Z80-to-Nano I2C Serial Interface