6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 21, 2024 9:45 pm

All times are UTC




Post new topic Reply to topic  [ 47 posts ]  Go to page 1, 2, 3, 4  Next
Author Message
PostPosted: Thu Jan 28, 2021 12:45 pm 
Offline

Joined: Thu Jan 28, 2021 10:24 am
Posts: 14
Location: Thailand
This is the first 6502 project I've ever built and also the first time I'm using the 16550 UART.

I'm trying to initialize a 16550 and send characters 0 to 255 in an endless loop via a max232 to my PC.
I was expecting some unprintable characters and somewhere in between the whole ASCII char set.
However all I get in putty is gibberish.
I've tried different baud rates 1200, 9600, 38400
I've tried another USB to serial adapter,
I've tried another Crysal osc with the same frequency (1.8432Mhz),
I've tried another 16550 chip (the other is a 16C552 actually),
But still all i get is gibberish so i figured that the problem is likely in my assembly code.

Anyways just in case I've done something wrong with the hardware I attach a rough schematic too.
Data and Address lines that are not shown in the drawing are straight connected to every chip that needs them. All IC's have 100n decoupling capacitors near them.

Does anyone have an idea how to get the UART running correctly? Thanks.

Memory map:
0000-7FFF RAM
8000-BFFF IO
C000-FFFF ROM

Here my code:
Code:
INIT:
   LDA   #$80   ; DLAB=1 open special control register
   STA   $8003

   LDA   #$0C    ; $60 = 1200kbps, $0C = 9600kbps, $03 = 38400kbps
   STA   $8000   ; DLL

   LDA   #$00
   STA   $8001   ; DLM

   LDA   #$03
   STA   $8003   ; Set 8N1 byte framing: 8-bit data, no parity, 1 stop bit, reset DLAB Flag.

   LDY   #$00

LOOP:
   LDA   $8005      ; Fetch the control register.
   AND   #$20      ; Bit5 will be set to 1 if UART is ready to send.
   CMP   #$20
   BNE   LOOP

   STY   $8000      ; Transmit character in register A to UART.
   INY
   JMP LOOP


Attachments:
File comment: Glue logic and a list of IC pins (with pin number and name) wired to ground, VCC or held high with pull-up resistors.
glue-logic-and-wiring.png
glue-logic-and-wiring.png [ 32.79 KiB | Viewed 3850 times ]
File comment: The kind of gibberish i get in putty.
putty.jpg
putty.jpg [ 112.62 KiB | Viewed 3850 times ]
Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 28, 2021 6:11 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
The pattern appears to be repetitive and stable, so the first thing I would check is the compatibility of the parity and stop bit formats between transmitter and receiver.

I would also try to avoid sending non-printable characters, due to the possibility of triggering an unexpected mode change in the receiver.
Code:
   ...
   LDY   #$20

LOOP:
   LDA   $8005      ; Fetch the control register.
   AND   #$20       ; Bit5 will be set to 1 if UART is ready to send.
   BEQ   LOOP

   STY   $8000      ; Transmit character in register Y to UART.
   INY
   BPL   LOOP
   BMI   LOOP-2

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 28, 2021 9:10 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 255
I agree with everything Mike B. said and would add the following:

Check the /BAUDOUT pin (pin 15) with a scope or frequency counter of you have one - it should be running at 16x the baud rate you want.

Don't send data continuously - at a minimum, have a pause longer than 1 character (eg. 1.04ms for 10-bits of 9600 8N1) every so often.

When you open your PuTTY connection, it will open the COM port which will then wait for the first 0 it sees as the start of the frame (1 is IDLE for this kind of serial). It might see a 0 in the middle of one of your bytes and try to start there. The PC will usually silently throw away any bytes that have frame errors (eg. the stop bit (which should be a 1) is not found at the end) and just try again, but it might try in the middle of a byte again. With no pause in the data, it might never get it right.

If your application really needs to send continuous data, then open PuTTY *FIRST* with an idle serial port and then have your 6502 board start sending data. That guarantees that the first 0 on the bus is an actual start bit.

My question for you is what kind of seral to USB port adapter are you using? Does it have a 9-pin plug on it? You'll need a level shifter if you want to connect to that kind of port. RS-232C uses (-3 to -25V) to send a logic 1 and (+3 to +25) to send a logic zero. You *CAN* put 0-5V type logic into *SOME* of these adapters, but note that you need to put 0V in for a logic 1 and 5V (more than 3V, really) in for a logic level 0, so you may need to invert your data. That's not really approved usage and you really should have a level converter (like a max232 or max3232 or equivalent) if interfacing to a 9-pin port. If you have an FTDI-to-TTL type cable, then you should be OK hooking that directly up to your 16550.

The good news is that you are getting something, which implies you've done a lot correctly to get your hardware working, and your address decoding is *probably* working correctly.

One last note: PuTTY treats some special characters as commands that can result with gibberish on the screen - sticking with the printable characters is definitely recommended.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 2:37 am 
Offline

Joined: Thu Jan 28, 2021 10:24 am
Posts: 14
Location: Thailand
Sadly I don't have a Scope,
however #BAUDOUT reads 153600 Hz on the frequency counter which divided by 16 equals 9600 and therefore should be corerct.

I have a MAX232 connected to the 16550.
Im using a USB to TTL serial adapter (CP210x based) with another MAX232 hooked up to it. (So in this case it's basically two MAX232 facing each other. Works fine with other projects I've built)
I also have tried another USB to serial adapter (PL2303 based if I remember right), this one is a real RS232 adapter with a DB9 connector.
It's the same pattern I'm seeing with both of them. I've even hooked up the TTL one directly to the 16550 just to have it tried.

From my understanding I've set the 16550 to 8N1 with no parity and 1 stop bit. I have set up putty accordingly.
However I have played around with all kinds of data bit, stop bit and parity options in putty just to rule out the possibility. (didn't fix the problem)

Code:
   LDA   #$03
   STA   $8003   ; Set 8N1 byte framing: 8-bit data, no parity, 1 stop bit, reset DLAB Flag.


Also I've followed Mike B's advice to not send unprintable characters and start with char 0x20, which did change the pattern I'm seeing a little bit but still nothing close to resembling the ASCII char set.

Then i have tried to implement a delay between every character by having a loop of NOP's in between every char. If I've got the assembly right this should loop 255 times and then go on with whatever comes after BPL DELAY.

Code:
   LDX #$00
DELAY:
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   NOP
   INX
   BPL DELAY


However having this delay implemented I receive something completely different in putty. Something that confuses me even more than I have been before.


Attachments:
puttynew.jpg
puttynew.jpg [ 97.36 KiB | Viewed 3792 times ]
Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 4:25 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Recommend using capital U as your test character. When your format is 8N1, the U is a 50% duty cycle square wave. If you're feeding the UART the character with no delays, then the frequency counter should read 4800 Hz. Once you have this, then you can try the other printable characters.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 6:32 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1431
Capital U is hexadecimal $55, binary 01010101.

It's been 20 years that I had tinkered with the 16550, and it wasn't 6502 related,
but to me it looks like your schematic and your code are supposed to work.

Would be nice if you could post photos of your hardware, maybe we are missing something obvious.

BTW: you better avoid transmitting ESC, that's hexadecimal $1B, decimal 27.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 7:03 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8504
Location: Midwestern USA
barrym95838 wrote:
The pattern appears to be repetitive and stable, so the first thing I would check is the compatibility of the parity and stop bit formats between transmitter and receiver.

I would also try to avoid sending non-printable characters, due to the possibility of triggering an unexpected mode change in the receiver.
Code:
   ...
   LDY   #$20

LOOP:
   LDA   $8005      ; Fetch the control register.
   AND   #$20       ; Bit5 will be set to 1 if UART is ready to send.
   BEQ   LOOP

   STY   $8000      ; Transmit character in register Y to UART.
   INY
   BPL   LOOP
   BMI   LOOP-2

And for a more compact loop that doesn't send the rubout character to the terminal...

Code:
  ...
         LDA #%00100000        ;test mask
         LDY #$20              ;ASCII space
;
LOOP     BIT $8005             ;UART ready?
         BEQ LOOP              ;no
;
         STY $8000             ;Transmit character in register Y to UART.
         INY
         CPY #$7F              ;end of ASCII series?
         BCC LOOP              ;no, send next
;
         JMP LOOP_2            ;yes, exit loop (BRA LOOP_2 if 65C02)

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 9:12 am 
Offline

Joined: Thu Jan 28, 2021 10:24 am
Posts: 14
Location: Thailand
ttlworks wrote:
Capital U is hexadecimal $55, binary 01010101.

It's been 20 years that I had tinkered with the 16550, and it wasn't 6502 related,
but to me it looks like your schematic and your code are supposed to work.

Would be nice if you could post photos of your hardware, maybe we are missing something obvious.

BTW: you better avoid transmitting ESC, that's hexadecimal $1B, decimal 27.


I have not tried sending U's yet, but I will as soon as I get home. However I have some pictures of the hardware at hand.
The MAX232 is on a separate board since I don't have enough of them to stick one on every board that I build (the MAX232 boards work fine with other projects, however could the wire length to these boards be a problem? Maybe the Output of the 16550 is not as strong as the ATmega chips I usually use it with?!).


Attachments:
File comment: a view on the wiring that is mostly under the IC's however I have taken this picture while i was building it, so there are still some wires missing in this picture and I am not keen on pulling out all the IC's just to make another photo.
wiring.jpg
wiring.jpg [ 451.01 KiB | Viewed 3762 times ]
File comment: bottom side of the board
bottom.jpg
bottom.jpg [ 508.28 KiB | Viewed 3762 times ]
File comment: The whole thing including the two mentioned MAX232 boards.
the-whole-thing.jpg
the-whole-thing.jpg [ 320.28 KiB | Viewed 3762 times ]
Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 10:19 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1431
IMHO the problem can't be related to the MAX232, because then the pattern on the screen wouldn't be that repetive.

To me, it feels more like something goes wrong with the initialisation of the UART and/or with writing characters into the UART TX register on hardware level.

Would suggest to check the wiring of the bus interface of the UART.
From your photos, it looks like D7..D0 are connected correctly.
Please check, if AS is tied to GND indeed, and if A2..0 are connected correctly.
Also, please check the 74HCT00 and 74HCT04 wiring, to be sure that there is nothing wrong with /IOCE, /WE, /RD.


For your next build, I would suggest not to have wires below the IC sockets (for simplifying debugging/modifying the hardware),
also it would be better to use the more expensive IC sockets with precision pins (because > 10 times of plugging/unplugging a chip won't do good to the sockets you are using).

Another trick for simplifying debugging is to stick with the resistor color code for the wires of the bus lines,
like D0=black, D1=brown, D2=red, D3=yellow (if you can't buy orange), D4=black again etc.

Another trick is to have labels covering the top of the ICs, with printed info which signal is on which IC pin (so you won't have to look into the schematics too often).


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 11:05 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1431
If you want to roughly measure frequency, but you lack an oscilloscope and a frequency counter,
one option would be to build a binary counter from, let's say, 74HCT393 chips.

For instance, if you have a 12 Bit counter with the outputs Q11..Q0,
and a LED tied to Q11 (don't forget the resistor in between) would be blinking at ca. 1.17 times per second,
you know that the counter is clocked with 1.17Hz * 2^12 = ca. 4792Hz.

Hope, this helps.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 1:08 pm 
Offline

Joined: Thu Jan 28, 2021 10:24 am
Posts: 14
Location: Thailand
OK I tried to send only capital U's which gives me a reading of 1280Hz +- a few Hz jumping up and down on the TX pin using this loop:

Code:
LOOP:
   LDA   UART5   ; Fetch the control register.
   AND   #$20   ; Bit5 will be set to 1 if UART is ready to send.
   BEQ   LOOP

   LDY #$55
   STY UART0

   JMP LOOP


I thought waiting for the UART in this loop might cause this low reading so i tried to just write U's without waiting for the UART using the following loop. However all I've got is about 200Hz on the TX pin. Ergo the faster I write to the UART the less comes out of TX, which I think suggests that the problem really lies somewhere with the /IOCE, /WE, /RD lines.

Code:
LOOP:
   LDY #$55
   STY UART0

   JMP LOOP



ttlworks wrote:
IMHO the problem can't be related to the MAX232, because then the pattern on the screen wouldn't be that repetive.

To me, it feels more like something goes wrong with the initialisation of the UART and/or with writing characters into the UART TX register on hardware level.

Would suggest to check the wiring of the bus interface of the UART.
From your photos, it looks like D7..D0 are connected correctly.
Please check, if AS is tied to GND indeed, and if A2..0 are connected correctly.
Also, please check the 74HCT00 and 74HCT04 wiring, to be sure that there is nothing wrong with /IOCE, /WE, /RD.


For your next build, I would suggest not to have wires below the IC sockets (for simplifying debugging/modifying the hardware),
also it would be better to use the more expensive IC sockets with precision pins (because > 10 times of plugging/unplugging a chip won't do good to the sockets you are using).

Another trick for simplifying debugging is to stick with the resistor color code for the wires of the bus lines,
like D0=black, D1=brown, D2=red, D3=yellow (if you can't buy orange), D4=black again etc.

Another trick is to have labels covering the top of the ICs, with printed info which signal is on which IC pin (so you won't have to look into the schematics too often).


I've checked A0..A2 are connected correctly and AS is wired to ground as well.
So I guess the problem really must be somewhere with the 74HCT logic or the wiring around there. I'll go thru the whole board checking for shorts between bus lines and correct wiring and post an update once I've done that.

Thanks for the hint with the wire colors using resistor color code. I haven't thought of that yet. That'll make it a a lot easier to debug than just one color for each bus.

This actually is one of the very few builds where I've crammed so many wires under the sockets since I thought looping this amount of wires around the sockets might take up too much space and the local parts shop here has got only one size of perfboard. (wasn't fun to do that anyways since I soldered the sockets in first)

Regarding the IC sockets I'm well aware that they are not very durable but they usually do the job well enough as it wasn't planned to run into a mysterious problem that forces me to swap the memory a few dozen times. I do by the way prefer this kind of socket over precision sockets since precision sockets make bending or breaking off IC legs too easy and its also difficult to stick salvaged parts with a little solder residue on the pins in those.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 2:37 pm 
Offline

Joined: Thu Jan 28, 2021 10:24 am
Posts: 14
Location: Thailand
I've got it working!!!

After checking the wiring and not finding anything wrong I went thru my IC boxes looking for some 74HCT replacements to just eliminate the possibility that one of them is faulty. I found some and replacing them didn't solve the problem either. However while going thru the boxes I did find a third 16550 and this one just works. So it seems both IC's I tried before are faulty (how small is the chance of having two faulty IC's from different manufacturers producing similar gibberish?!)

Thank you everyone for your help and suggestions. I did even learn a few assembly things in the process, especially how to make efficient loops.


Attachments:
File comment: it works and I am seriously so happy about it that I might actually enjoy watching the ASCII char set printing over and over for half an hour.
works.jpg
works.jpg [ 104.5 KiB | Viewed 3721 times ]
Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 3:25 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8504
Location: Midwestern USA
maewn21 wrote:
However while going thru the boxes I did find a third 16550 and this one just works.

What was your source for the UARTs? If eBay, there is no telling what you were sold. Also, it could be the UART was damaged by ESD, which is always lurking during the cold months.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 4:43 pm 
Offline

Joined: Thu Jan 28, 2021 10:24 am
Posts: 14
Location: Thailand
BigDumbDinosaur wrote:
maewn21 wrote:
However while going thru the boxes I did find a third 16550 and this one just works.

What was your source for the UARTs? If eBay, there is no telling what you were sold. Also, it could be the UART was damaged by ESD, which is always lurking during the cold months.


The 16550 are all salvaged from old Mainboards and ISA I/O cards, as is the SRAM.

The 6502 is from China tho, from the looks I'd say the original marking has been sanded off. I've got two of them, both DIP packages look exactly the same with the small circle in the top corner and the marking "SB59" and Taiwan on the bottom. From the current draw (~150mA for the whole board) I'd say they are probably real, just NMOS versions remarked. I don't really mind about them being NMOS or the current draw, I just wanted to play around with some 6502 for the first time ever. At least I got 6502's and not some useless random IC with a fresh marking. (I did buy them fully aware of that I might get remarked or even worse complete fake chips since I could not find another source for these.)


Last edited by maewn21 on Fri Jan 29, 2021 5:18 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 29, 2021 4:58 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
Great to see a result!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 47 posts ]  Go to page 1, 2, 3, 4  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: