UART Serial Console Interface


Photo Mar 30, 9 03 03 PM
The plan is to implement the UART as it often is, interfaced to a serial port. Since my last post I have had to re-wire all of my work, and I have moved from EAGLE to KiCAD since it is open-source, and I find it a bit more user-friendly. I also have new USB->Serial cable thanks to Rat Shack going out-of-business! This time we will try out an echo program. Type characters into a terminal emulator on a PC, and they will go through the USB->Serial port to the Z80 circuit. The character will then be read into a register, and echoed back to the PC to finally show up in the terminal emulator program. Sounds easy right?

Well yeah with the know how of before it was fairly easy to get this up and running. Wired everything up. Basically assembled the program in the previous post with a minor modification. Powered the circuit up, ran the echo program. You can type things on the PC’s keyboard and see them on the terminal emulator program. Whats the catch? Well when I type the character ‘w’ or ‘_’ or ‘o’ other characters echo back sometimes. Why is this? Well after much debugging and probing and asking people on forums I am leaning toward a timing issue caused by driving the UART directly from the Z80 control signals without any decoding logic to introduce propagation delay. The data bus gets latched at the wrong timing and you get garbage characters back.

Since the reliability is very high (I only have problems with the characters ‘w’ ‘o’ and ‘_’) I don’t think I am going to debug much further. In this situation if I got this far it is highly unlikely that there is any major mistake that would prevent me from expanding on my design. Although even with this small test I only have one section on my breadboard left to add things in.

What I am mostly worried about with my implementation is the modem control signals on the UART. I don’t use any hardware control for my serial port. I tried to implement RTS/CTS, but in PuTTy, with the hardware flow option selected, the circuit just doesn’t respond. I also tried to implement DTR/DSR, but it doesn’t seem to solve my above problem, so I am leaving it out for now for simplicity. I am absolutely clueless as to what to do with the remaining control signals, so I left the outputs unconnected, and the inputs tied to either VCC or GND based off of if they were active-high or active-low to ‘disable’ them.

Before thinking about PCBs  I need to run some tests with RAM in the system to make sure I am squared away with a stack so I can finally use calls, rets, pushes, and pops.

Next time around I will be adding both memory and I/O decoding logic to handle chip selects and reading and writing.

All Files from this project can be downloaded from my GitHub Repository,

Z80 Project Repository

This slideshow requires JavaScript.

About Matt Cook

Computer Engineer
This entry was posted in Uncategorized and tagged , , . Bookmark the permalink.

16 Responses to UART Serial Console Interface

  1. MiaM says:

    Hi!

    Interesting project! I recently found your blog and I’m reading it from the start so I haven’t read anything you posted after this so ignore this comment if this has already been resolved in a more recent post.

    If you have a look at the binary pattern for ‘w’ ‘o’ and ‘_’ you will see that all of them have quite a few ones in a row. Problems with such characters (or for that sake characters with a long row of zeros, for example “@” and “`”) is an indication of a possible baud rate mismatch or a dc level sustainability problem i.e. the power in a TTL to RS232 converter drops when a specific level has been transmittet long enough or possible a mismatch between the dc limits for a logic zero, undefined and a logic one betwwen 3,3V and 5V.

    It would probably be a good idea to make a short program Z80 that transmits all (printable) ascii characters in a sequence, i.e. 0x20-0x7E and 0xA0-0xFF and see if all look ok. If they do, you have ruled out the transmit part and can focus on the recieve part. Another thing you cound do is a Z80 program that recieves a char, echoes it and convert it to hex and print the hex letters with words. I.e. if you recieve A it would print “four-one “. That way the output would be intelligeble even if there are issues in both ways of the transmission. Perhaps that would be overkill though 🙂

    • Matt Cook says:

      I think it just came down to bad wiring on the breadboard. Everything works currently via UART and I have expanded the functions that are possible. It was a slow process to figure out what was wrong. Also, a lot of the hassle actually came from the USB->serial converter since they can have all sorts of errors, and not even tell you. Most of time I would have to restart my PC to fix the issues since the converter hung, and Windows did not want to recognize the device after re-plugging. That was a pain. Moral of the story always check your wiring, since something is bound the be wrong, and everything hinges on it being right.

  2. HI,

    Interesting fault. Did you ever get to the bottom of it?

    I’ve a similar problem with my PCB version. The data coming from the PC to the UART has lost lower case ‘g’ and ‘7’ and a few other characters as well. I know the TX from the UART to the PC works as I’ve sent all characters correctly.

    I’ve tried a USB to Serial converter cable and also a serial to Bluetooth converter. Both suffer from the same fault – so I think the problem lies in the software or timing of the board. I’ve written a program to exercise the UART Scratch Pad register – this works fine. I’ve tried adding more decoupling capacitors. I’m using a 1.8432Mhz Crystal to generate the clock. I’ve just bought a 1.8432Mhz crystal oscillator and will try that when it arrives. When I get a moment I’ll take a look at the timing, however the scratch pad test leads me to believe that it is OK.

    My software is similar to yours. I don’t think it is at fault (although it is possible). By trade I’m an embedded software/hardware engineer (retired) and in the past I’ve coded this UART successfully.

    One of your later articles mentions a Z80 basic. YOu might like to know that, on the web there is the source code for the NASCOM (an early Z80 machine) Basic which is an early version Microsoft Basic written in assembler for the Z80. I’ve got this running on my system with no problems (apart from the UART issues).

    I want to add to my system an interface to a CF card and will follow your progress with interest.

    • Matt Cook says:

      I actually did get to the bottom of it finally after much confusion, or well it works now so I think I did anyway. I am assuming that you are storing the character the UART reads from the PCs keyboard in RAM and then shuttling it back to the UARTs Tx to see it on the terminal emulator screen? (An echo program) If so it makes sense that Tx from the UART to the PC works correctly for every character because you do not need to store anything in RAM just send it off from the Z80 directly. There is where my problem started to show up with my RAM and its attachment to the bus. Check and double check the continuity of the RAMs pins to the address and data bus. More than likely you are doing everything correctly if you got this far and it may be that an address or data pin does not have a very good connection to the address or data bus. In this way you could be storing weird data at weird locations. It is most likely a data pin that is ‘floating’ if you are seeing this because you are seeing the right characters sometimes and the wrong characters other times. I would definitely take a look at the hardware continuity before you start trying interesting things in software to identify/solve the problem. It may be right in the schematic, but sometimes this doesn’t translate 100% to a PCB layout. I am especially leaning towards RAM if it is implemented on your board because you are reading and writing to/from the scratch pad on the UART which would indicate that the device is operational.

      Nascom Basic does sound like a good idea. I could throw it on the CF card and read it over to RAM or wire a few more lines on the ROM and burn it directly. I am waiting on some prototyping materials to come in the mail and then I am going to point-to-point solder the system up to where it is now and beyond until I get CP/M working then I might spring for an actual PCB. The (untested) hardest part about this is banking between memory configurations 1: 32KB ROM + 32KB RAM and 2: 64KB RAM, but I think I have a solution that may work involving a JK flipflop + two OR gates along with a I/O chip select line. The idea is to create a switching mechanism for the select lines on the current ROM and another RAM chip to page them in an out by enabling an I/O chip select through a read or write. The JK will take care of the toggle for each time its enabled to page, and the OR gate will take care of when those chips are getting addressed also. Its sounds confusing in writing so hopefully I get to post the schematic soon so it becomes clearer.

      The CF card is going to be immensely helpful later once I actually have a use for it. Interfacing the card is fairly straight forward as long as it supports true 8-bit XT-IDE mode, which you probably won’t be able to figure out until you actually try to enable this feature and read/write sectors to/from the card. From all the information I have gathered most do support this legacy feature, and Sandisk brand cards in particular have been the most successful, or maybe just the most available/cheapest option to explore? It is very hit-or-miss though brand to brand. I have a feeling that this feature will slowly be phased out of CF cards, and that we might just be getting lucky that revisions on the silicon wafer designs just happen to be built upon legacy data. Once the wafer die sizing limitations vs storage capability hit a total wafer die revision I am quite sure that this feature will be removed to make space for more desirable features such as more storage capabilities. Most likely this is why we see such a discrepancy from brand to brand as they meet this cost vs support decision.

      If you have the time you should definitely find a way to post your progress online somewhere. I am very interested to see how others have approached their design since most of my progress can be directly attributed to reading other people’s blogs. Thanks for the comments!

      • tafm27 says:

        Hi Matt,

        Thanks for your reply.

        I was echoing the RX character straight back to the UART TX. No memory involved. Read into A reg and transmit from A reg. Most characters work solidly but a few do not.

        Over the weekend I spent some more time playing with my circuit. I’ve beefed up the power lines from the regulator directly to the UART. This has improved the situation. I’ve also soldered a 100uF and 100nf capacitor directly to the power pins. The lower case ‘g’ and ‘7 characters are now working almost 100% of the time. However ‘y’ and ‘w’ are not working very well at all. When I press ‘y’ this is what I get.

        At the moment, I think the problems are due to poor power distribution and layout. I’ve used a matrix board to build the circuit so the power and ground signals have to be hand wired. The 16550D UART seems to be sensitive to layout. I’m probably getting ground and VCC bounce between the chips. I hope to investigate this further later this week. I’ve a couple of ideas to try.

        I know my RAM works correctly. I’ve run memory tests on it for hours on end without error. Of course my memory test is relatively simple and not exhaustive however the Nascom Basic runs without crashing. This must exercise the memory quiet heavily.

        My memory map is an 8K EEProm with128K of RAM, but obviously with only 56 K normally in use. However the full 64 K RAM is available by switching the ROM off. I’ve also paged the top 32K of RAM with the top 32 K of the 128K RAM although this still needs testing. For switching I’ve used a 74HCT273 as an I/O register. It has a hardware clear which is connected to the reset signal. This chip controls the memory paging. The top four bits drive a TIL311 display with built-in hex decoder (I’ve a lot of really old parts!). I used this display for debug before I got the UART working.

        I’ve got some old CF cards and a socket carrier and I intend to develop this once I’ve got the UART working correctly.

        I do have a website (http://dev.traytonmitchell.co.uk/) but I’ve not put any details of this project on it yet. It mainly contains notes on the Raspberry Pi.

        The problem is I get distracted between Android Software development, Raspberry Pi and the Z80 – there is not enough time for everything.

      • MiaM says:

        This book (made in East Germany!) has an interesting solution to the ram/rom switching problem
        http://hc-ddr.hucki.net/wiki/doku.php/homecomputer:huebler

        They use a flip-flop that is put in one state by the reset pulse. In that state ram (and memory mapped i/o, i.e. VDU) is disabled and the data bus is driven to the value of a NOP instruction. That way the CPU will start executing NOP’s and the program counter will increase. The ROM is mapped in top of memory. When the address decoder for the ROM enables the rom it will also put the flip flop in it’s other state. Then the program counter is at the first address of ROM and you have a memory map set up for running CP/M.

        (The east german clone of Z80 were called U880 and their (pirated?) copy of CP/M were called SCP).

  3. Trayton Mitchell says:

    Hi again,

    I’ve got the UART working correctly. It turns out that there was a problem with the power connection to the UART. There were two wires providing power to the UART Chip. One was a very thin wire which was the original connection it came from the power pin of one of the logic chips. The other was a much thinker wire that I added to beef up the power to the UART. This connected directly to the regulator. When I removed the thin wire the UART started working correctly. I suspect that the logic chips were causing some spiking or ringing on the power rail, which was too much for the decoupling capacitors on the UART.

    Anyway all is well. I’m on to testing the interrupts and RAM paging.

    Thanks for your help and suggestions.

    • Matt Cook says:

      Glad to hear that you figured it out. I was thinking of asking you what your power situation was and if you were reaching some sort of current limit on the supply. I personally just use a USB plug-pack from an old phone and I spliced together a USB->banana-jacks connector to hook right to the breadboard. I have never had a problem with these types of wall-wart switching regulators so I am surprised that a logic chip could introduce so much noise that would disrupt the UART. For a TI 16550 it even has a 10% tolerance on the voltage which seems a bit high for a singular 74XX logic chip to introduce, and at that level I would think that any logic chip would start behaving weird itself.

      Good luck on interrupts, especially if you are going with mode 2 interrupts. I tried to wrap my head around this, but I just feel like it is more of a hassle than a necessary feature. I understand the concept when the interrupt occurs the device puts a specific sequence on the databus and then you jump to I*256+databus. The assembly is just very messy to implement though. I know if I were to implement this I could use the INT pins from the UART and IDE and use some sort of jelly bean logic to use those INT pins to create an 8-bit value based off of when the interrupts are generated. I might look into it in the future if I get a better idea of how to do it, but I have a feeling that I can do most everything without interrupt routines.

      • Trayton Mitchell says:

        Hi Matt,

        Thanks for the reply. I’ve got the interrupts working from the UART. I’ve taken the easy option and have used mode 1. I’ve also hooked up the Serial USB cable into my Raspberry Pi and run ‘minicom’ on the PI to talk to the Z80. I can use a secure shell program (SSH) from my phone or tablet to talk to the Pi and then minicom to the Z80 remotely.

        Next step is to implement a counter timer chip. In my junk box I’ve got some Intel 8253 chips. I’m going to try one of them. It will have to go on a second PCB so it will take some time to build the connections from the Z80 board to the daughter board. Hopefully I won’t run into any more power problems.

  4. Walter says:

    hi there, using this code (port address modified to 0x20.

    when i run it it echo’s the key I pressed, but keeps printing it until i press another key, then it continues to print that key…until i select another one…. so if it type test, it displays ttttttttttttttttteeeeeeeeeeeeeeeessssssssssssssssttttttttttttttttttttttttttt as an example…

    how would i modify it so it does not keep repeating but just repeats each key once as I type them 🙂 (obviously very new to z80 assembly….) cheers. 🙂

    this is my serial card here:

    JAIR8250 Serial interface card

    it’s for an S100 bus z80 based computer on this z80 board:

    Ithaca Audio Z80 card and home made 64k ram board.

    Cheers. 🙂

    ;***************************************************************************
    ; PROGRAM: UART Echo Test Program
    ; PURPOSE: Key typed on PC will display
    ; ASSEMBLER: TASM 3.2
    ; LICENCE: The MIT Licence
    ; AUTHOR : MCook
    ; CREATE DATE : 15 Mar 15
    ;***************************************************************************

    UART0: .EQU 20H ; DATA IN/OUT
    UART1: .EQU 21H ; CHECK RX
    UART2: .EQU 22H ; INTERRUPTS
    UART3: .EQU 23H ; LINE CONTROL
    UART4: .EQU 24H ; MODEM CONTROL
    UART5: .EQU 25H ; LINE STATUS
    UART6: .EQU 26H ; MODEM STATUS
    UART7: .EQU 27H ; SCRATCH REG.

    .ORG 00H

    ;***************************************************************************
    ;INIT_UART
    ;Function: Initialize the UART to BAUD Rate 9600 (1.8432 MHz clock input)
    ;DLAB A2 A1 A0 Register
    ;0 0 0 0 Receiver Buffer (read),
    ; Transmitter Holding
    ; Register (write)
    ;0 0 0 1 Interrupt Enable
    ;X 0 1 0 Interrupt Identification (read)
    ;X 0 1 0 FIFO Control (write)
    ;X 0 1 1 Line Control
    ;X 1 0 0 MODEM Control
    ;X 1 0 1 Line Status
    ;X 1 1 0 MODEM Status
    ;X 1 1 1 Scratch
    ;1 0 0 0 Divisor Latch
    ; (least significant byte)
    ;1 0 0 1 Divisor Latch
    ; (most significant byte)
    ;***************************************************************************

    INIT_UART:
    LD A,80H ; Mask to Set DLAB Flag
    OUT (UART3),A
    LD A,12 ; Divisor = 12 @ 9600bps w/ 1.8432 Mhz
    OUT (UART0),A ; Set BAUD rate to 9600
    LD A,00
    OUT (UART1),A ; Set BAUD rate to 9600
    LD A,03H
    OUT (UART3),A ; Set 8-bit data, 1 stop bit, reset DLAB Flag

    MAIN:
    LD A,00H

    ;***************************************************************************
    ;GET_CHAR_UART
    ;Function: Get current character from UART place in Accumulator
    ;***************************************************************************

    GET_CHAR_UART:
    IN A,(UART5) ; Get the line status register’s contents
    BIT 0,A ; Test BIT 0, it will be set if the UART is ready to receive
    JP Z,GET_CHAR_UART

    IN A,(UART0) ; Get character from the UART
    LD B,A ; Store character into B Register

    ;***************************************************************************
    ;SEND_CHAR_UART
    ;Function: Send current character in Accumulator to UART
    ;***************************************************************************

    SEND_CHAR_UART:
    IN A,(UART5) ; Get the line status register’s contents
    BIT 5,A ; Test BIT 5, it will be set if the UART is ready to send
    JP Z,SEND_CHAR_UART

    LD A,B ; Get character from B Register obtained earlier
    OUT (UART0),A ; Send character through the UART

    JP MAIN

    .END

    • Matt Cook says:

      Depends on a lot of different things. First do you have a schematic for that serial board? Second what are you using for communication to/from? Third is there a program you are using to intercept the transmission like PuTTy? I had this issue a long time ago, but I can’t remember exactly what was causing it. I am leaning toward some sort of handshaking issue with the extra signals that serial uses. I.E. DTR/DSR, RTS/CTS and how/if my serial to usb adapter was fit to make use of them.

    • Trayton Mitchell says:

      Could the be a short between the transmit and receive pins?

  5. Walter says:

    The FTDI could be the issue, there are pads on the back for DTR or RTS, DTR was shorted, so I unsoldered it, and now DTR and RTS pads of the Adafruit FTDI friend, have no solder link. I will try that, then try it with the RTS pads soldered. 🙂

    https://www.adafruit.com/products/284 I think i will put it back at the default of RTS pads shorted.

    and try it again…. I have to use the front panel to put the program in… as this is a very basic system, hoping to have a monitor to load hex files into it. 🙂 but for now, just testing my serial port. I will post the schematic it’s pretty straight forward “lifted” from my Buddy Josh Bensadon’s JAIR8080 board which includes 8080, ram, dual serial ports, parallel port, and SD card interface for 4 drive CP/M system, all in one card. I lifted the serial port part…. 🙂

    i added pictures to my flickr feed of the system and the FTDI 🙂 schematic to come. 🙂 how do I post the schematic?

  6. Walter says:

    Yup it was the FTDI. works great, added a picture in my flkr feed. 🙂 Thanks for posting your code, it was great for testing my serial card. 🙂 Cheers.

  7. Walter says:

    link to Flickr feed, the above pictures do not link for some reason, try this link:

    JAIR8250 Serial interface card
  8. Walter says:

    OK, sorry not sure what is going on with the link to my flickr feed. you can do a search for JAIR8250 on flicker. to find more pictures. 🙂 Thanks again for the test code. 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s