• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

TashTalk: Single-Chip LocalTalk Interface

tashtari

PIC Whisperer
What about using a simple STM32 with DMA
There is almost certainly a better way of having done what I did (there always is) but I already knew PIC development and had all the necessary hardware and such, and sometimes the right tool for the job is the tool you've got. =) Besides, getting everything to work within the tight space and time confines of the PIC12F1840 was a fun challenge and I'm more than a little pleased with myself for having managed it...
 

ronan

Well-known member
There is almost certainly a better way of having done what I did (there always is) but I already knew PIC development and had all the necessary hardware and such, and sometimes the right tool for the job is the tool you've got. =) Besides, getting everything to work within the tight space and time confines of the PIC12F1840 was a fun challenge and I'm more than a little pleased with myself for having managed it...
Totally agree :)

Well done by the way !
 

olePigeon

Well-known member
FWIW your bog-standard FIFO 16550 UARTs from 90's PCs *could* in theory support 1Mbit/plus baud rates but they're limited because the standard clock they're driven by in PC compatibles is 1.8432MHz and the minimal divisor is 16x. (1,843,200 /16 = 115,200) Old-tyme PCs never got faster crystals (This speed dates back to the 8250 in the original async serial card for IBM PC) because everyone hammered on the bare registers to set baud rates and changing it to something else would have broken register compatibility with older software.

I'm sure you're aware of this, but Danya and TOPS used an external clock source for their 1Mbit AppleTalk adapters.
 

tashtari

PIC Whisperer
Code on GitHub updated, changing the baud rate to 1 MHz, and reversing the polarity of CTS (turns out that okay-to-send is denoted by 0, not 1).

Separately - I was reading Inside AppleTalk and it occurred to me that my firmware does not precede RTS and ENQ frames with synchronization pulses (page 1-10). This so far doesn't seem to have caused any trouble, but I'm wondering what the necessity is. Certainly a missing clock would tip nodes off that the line is in use, but wouldn't the pulses of a transmission not initiated by them do the same thing? Anyone more familiar with the SCC than I am have any thoughts on this?
 

tashtari

PIC Whisperer
I've started work on tashtalkd, an attempt at a usermode daemon/"driver" for the chip. Objective, at least at first, is to translate between real LocalTalk and LToUDP. It's still got some rough edges to clean up before I show off the code, but I'm happy to report that I successfully accessed a file share on an emulated mac using a real one! That's definitely a big confidence booster in terms of the chip working reliably.

I'd still like to develop this into a full substitute for an AsantéTalk or so, with bridging to EtherTalk, but at the moment, reading the relevant sections of Inside AppleTalk is making me go crosseyed...
 

LaPorta

Well-known member
As the usual non-electronics person in the group...I just need to ask, whats this thing for?
 

tashtari

PIC Whisperer
As the usual non-electronics person in the group...I just need to ask, whats this thing for?
I envisioned it as a means to creating a modern-hardware replacement for the various LocalTalk-to-Ethernet bridges/routers, but really, it's for any hardware project that wants to involve LocalTalk.
 

cheesestraws

Well-known member
As the usual non-electronics person in the group...I just need to ask, whats this thing for?

@tashtari has produced what promises to be a solution to the "difficult" hardware problem in plugging things that aren't old Macs into LocalTalk networks. So, this could be the core of, say, a raspberry pi hat to allow R-Pis to talk LocalTalk as well as Ethernet and share files, or have an ESP8266 on the back to do wireless LocalTalk over UDP (no promises there, heh), or build a new LocalTalk to Ethernet gateway. Software would need to be written for any of these use cases but frankly in this case that's the comparatively easy bit.

Certainly a missing clock would tip nodes off that the line is in use, but wouldn't the pulses of a transmission not initiated by them do the same thing? Anyone more familiar with the SCC than I am have any thoughts on this?

I believe: The SCC provides two signals: "missing clock" and "SDLC Frame in Progress". The latter requires byte sync and the SCC can detect that it has lost a clock faster than it can detect that it has gained one. It does not seem to provide a "something's going on on my pins but I don't know what yet" signal.

Per Inside Appletalk (p. 1-10):

A drawback of the flag-byte synchronization approach is that synchronization can take 2 or more flag bytes to be achieved; during that time the node could determine the line to be idle when it is, in fact, being used by another node.

...

However, since the transition is followed by an idle period of sufficient length, all receivers conclude that they have lost the clock. They are said to have detected a missing clock. The hardware can detect this missing clock much more rapidly than it can achieve byte synchronization. With the synchronization pulse at the leading edge of an RTS frame, the detection of a missing clock provides a very quick way to detect use of the line by a sender.

I thought there was wording in there that implementing missing clock detection was optional for non-SCC implementations of LocalTalk, but I can't actually find that now, so I might have dreamed it...
 
Last edited:

bdurbrow

Well-known member
I'm a lot more familiar with the Atmel side of the house (AVR, SAMD) so pardon the rudimentary level of the question...

What would it take to move to a PIC with a little more IO pins? I'd like to be able to tell the chip that the line isn't in LocalTalk mode; and it should shut down it's driver for RA5 and ignore anything on RA3. Otherwise I'd have to add a couple of 7400 series data MUX chips to switch the connections to the RS422 driver chip from the PIC to another chip on the board.

🤔
 

dougg3

Well-known member
Anyone more familiar with the SCC than I am have any thoughts on this?

I'll try to jump in with my thoughts here, but I think cheesestraws pretty much covered it.

I believe: The SCC provides two signals: "missing clock" and "SDLC Frame in Progress". The latter requires byte sync and the SCC can detect that it has lost a clock faster than it can detect that it has gained one. It does not seem to provide a "something's going on on my pins but I don't know what yet" signal.

Page A-3 in Inside AppleTalk talks a little bit more about these two indications:

Note: A frame cannot be detected until a complete flag has been transmitted on the line and
recognized by the hardware. On the other hand, the synchronization pulse sent before
frames and the resulting missing clock detected by receivers provide a more immediate
indication of an ongoing transmission (see Chapter 1, “LocalTalk Link Access Protocol”).
Missing clock indicates the detection and then the absence of a clocking signal on the line.

The synchronization pulse is clearly designed around the "missing clock" detection feature of the SCC. In Appendix B there's a bunch of sample code for doing LocalTalk with the SCC, which is what I used for my SCC LocalTalk bridge implementation. In the notes, it talks about missing clock being the "one clock missing" bit in RR10 of the SCC. In the sample code, there's only one place that bit is checked, and it's in the transmit routine immediately after the random wait period. After the wait period, it checks both the byte sync bit (RR0 bit 4) and the "one clock missing" bit. As long as there's no byte synchronization *and* it hasn't seen a missing clock, it will proceed with a transmit by sending its own sync pulse followed by an RTS or ENQ. Otherwise, it knows someone else has already started transmitting, and it backs off. (BTW, thanks for bringing this up -- my SCC code was only doing the sync pulse with RTS, I should add the sync pulse on ENQ as well).

So as far as I can tell, it's just about minimizing collisions. It's pretty SCC-specific, but it allows every other device on the bus that uses an SCC to more quickly detect that you've started transmitting. I believe if you don't send the sync pulse, it's going to be slightly more likely that another SCC-based LocalTalk device clobbers your transmit because there's that (small) window during your first flag byte being transmitted where it hasn't achieved byte synchronization yet, but it thinks the bus is still free because you didn't send a sync pulse so it has no other way of knowing that you're in the middle of transmitting already. So you'll effectively end up with less efficient use of the bus because of more collisions.

I thought there was wording in there that implementing missing clock detection was optional for non-SCC implementations of LocalTalk, but I can't actually find that now, so I might have dreamed it...

Based on what I'm seeing, they wouldn't have said that -- any other LocalTalk device on the same bus that has an SCC would be dependent on this sync pulse being there to know sooner that someone else beat it to transmitting the next frame. With that said, I'm guessing that it matters more on loaded LocalTalk buses and it's going to be much less of an issue if it's just a tiny 2-device LocalTalk network (the PIC and a single Mac).
 

tashtari

PIC Whisperer
What would it take to move to a PIC with a little more IO pins?
I don't think it would be overly difficult, hardware-wise; the 8-pin PIC12F1840 has a larger cousin in the 14-pin PIC16F1825, which I was considering using for a while; the core is the same and the peripherals are similar in spite of one being a "PIC12" and the other a "PIC16". The UART pins would by default move to added pins on PORTC, so the proposed enable/disable pin could be on PORTA and trigger its interrupt-on-change interrupt. Currently that's what touches off the receiver, so some logic would have to be added to tell the two event types apart; this might take enough time that we have to get rid of one iteration of servicing the UART, but I don't think that'd be disastrous. The thing that worries me is the latency of the enable pin's response - if the chip were in the middle of a receive or a transmit when the enable pin was deasserted, it wouldn't respond until the receive or transmit was done. There just isn't enough space in the time-critical receive and transmit code to add checking that pin, at least not without getting rid of an uncomfortable number of UART servicings.

I can think of some solutions that wouldn't involve adding any more chips, but they depend on the larger picture. What is it you're trying to do that involves part-time shutting down of LocalTalk?
 

tashtari

PIC Whisperer
Thanks, @cheesestraws and @dougg3 - your interpretations make sense. I suppose it's not highest priority, but I should think about implementing that sync pulse, just for sake of completeness in making this chip a full-fledged replacement for the SCC.
 

cheesestraws

Well-known member
Based on what I'm seeing, they wouldn't have said that -- any other LocalTalk device on the same bus that has an SCC would be dependent on this sync pulse being there to know sooner that someone else beat it to transmitting the next frame. With that said, I'm guessing that it matters more on loaded LocalTalk buses and it's going to be much less of an issue if it's just a tiny 2-device LocalTalk network (the PIC and a single Mac).

Yeah, I think you're right. I'm slightly bewildered about why I thought that, having re-read that chapter. I suppose this is why one revisits reference material rather than trying to work from memory!
 

mactjaap

Well-known member
As said before…I’m very happy with this development.
By coincidence In the recent weeks I have been working on my Pentium III with LocalTalk PC card model 630-5306. The famous lt0 in Linux.

in 2011 also worked with this system. Now 10 years later I thought it was an nice idea to give it a try again. Read all about it in:

https://68kmla.org/bb/index.php?threads/a-localtalk-pc-card-a-macintosh-plus-and-a-linux-box.23032/

or as PDF in original 68kmla design:

https://blog.macip.net/wp-content/uploads/linuxbox.pdf

In 2011 I got it working. I could see the Debian box in the chooser if I connected machines on the LocalTalk port of the LocalTalkPC card. Same now. I booted in Debian 3.0r6 Woody (released 2 June 2005). The atalk.conf I use is:

dummy0 -seed -phase 2 -net 65280-65534 -addr 65281.41
lt0 -seed -phase 1 -net 1033 -addr 1033.27 -zone "1033"

WhatsApp Image 2021-09-11 at 18.07.13.jpeg

The zone is strange, because phase 1 doesn’t support zones…but I got this from the readme of the ltpc. However I adjusted the dummy0 a little bit.

https://www.kernel.org/doc/html/latest/networking/device_drivers/appletalk/ltpc.html

I also installed other old Debian varieties:

Squeeze from February 2011
Lenny from February 2009
Potato from August 2000

Lenny and Squeezy didn’t work better. I could do better debugging with tcpdump, but got a lot of errors on lt0. Now testing on a very old one…Potato from 2000. I will keep you posted, but will use another thread for this.
 

bdurbrow

Well-known member
What is it you're trying to do that involves part-time shutting down of LocalTalk?
Switching back to raw SLIP or PPP mode. This will be mediated by an app or control panel that communicates to the board over ADB.
 

tashtari

PIC Whisperer
Hmm, not microsecond-critical, then... what about, instead of a dedicated pin, a command byte sent over the UART causes the chip to tristate the driver/data-out pins and effectively suspend operations until another byte from the UART tells it to resume?
 

tashtari

PIC Whisperer
Project Update: The code for tashtalkd is now up at https://github.com/lampmerchant/tashtalk/tree/main/tashtalkd. (I think I'm just going to keep the project's various elements in the same repository.) It requires Python 3, a POSIX OS and PySerial. It supports LToUDP, allowing builds of Mini vMac 37 that have LToUDP support to communicate with real-world macs over LocalTalk.

What's next? Not sure. Options include:
  • Expand tashtalkd to bridge to EtherTalk
  • Build a RPi "hat" PCB
  • Add sync pulses when sending RTS or ENQ frames
  • Add suspend command
  • Totally pause on LocalTalk stuff and do something with ADB for fun...
I think I'm most interested in the first. I'm wondering, though, if it's really as complicated as I think it is. Anyone know of example code that already does this that I can use for inspiration?
 

dougg3

Well-known member
I think I'm most interested in the first. I'm wondering, though, if it's really as complicated as I think it is. Anyone know of example code that already does this that I can use for inspiration?

I implemented a userspace barebones LocalTalk to EtherTalk bridge for my project, prior to getting the kernel module working. I believe I emulated the approach used by the Farallon EtherWave Printer Adapter. It was pretty hacky and incomplete, but it did work as a proof of concept. I've attached a zip of the userspace portion of the code (GPLv2). Hope this is useful!
 

Attachments

  • llap_to_elap.zip
    25.9 KB · Views: 10

mactjaap

Well-known member
I hope you will do option 2 also….

At this moment there is really nothing like what you are developing. This could be the FloppyEmu of LocalTalk networking. So …. Please give it a try. Even if it is just a prototype what can be finished by others.
 
Top