Compare commits

...

13 Commits
v2.0.0 ... main

Author SHA1 Message Date
Tashtari
656b008b34
add FUNDING.yml with ko-fi 2024-05-28 09:33:33 -06:00
Tashtari
5f4013fb9d
expand PCBs and Products section, include software 2024-04-04 04:50:30 -06:00
Tashtari
0a0c0c9350
add PCBs and Products section to README 2024-04-04 04:18:36 -06:00
lampmerchant
0e15b7d230 20240110 2024-01-10 07:05:38 -07:00
lampmerchant
16178a16ef 20231202 2023-12-02 09:03:42 -07:00
lampmerchant
c7f052f49a 20231112 2023-11-12 06:17:16 -07:00
lampmerchant
fd7b098638 20230920 2023-09-20 09:09:52 -06:00
lampmerchant
7b9799b6a4
add SN65HVD11 and 12 to transceivers.md 2023-07-19 08:03:52 -06:00
lampmerchant
f4ed089bfc
update README.md to talk more about version differences 2023-07-19 08:01:47 -06:00
lampmerchant
452d78e1ab 20230408 2023-04-08 18:11:30 -06:00
lampmerchant
77bf995389
add BOM for TashTalk 2 hat 2023-03-12 08:53:54 -06:00
lampmerchant
5ca670b450
specify prototype used v1.x firmware 2023-03-12 08:35:59 -06:00
lampmerchant
b1af0a236f
mention v1.x/v2.x differences, add TashTalk 2 hat 2023-03-12 08:34:46 -06:00
7 changed files with 430 additions and 187 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
ko_fi: tashtari

View File

@ -13,7 +13,7 @@ BeagleBone or full PC, or it can be part of a larger embedded system. It slices,
## Project Status
Stable enough to release a v1.0.0.
Stable.
## Caveats
@ -32,10 +32,67 @@ Also, "single-chip" doesn't include the separate and necessary driver/receiver c
Building the firmware requires Microchip MPASM, which is included with their development environment, MPLAB. Note that you **must** use MPLAB X version 5.35 or earlier or MPLAB 8 as later versions of MPLAB X have removed MPASM.
## Projects Using It
## PCBs and Products
* [TashTalkHat](https://68kmla.org/bb/index.php?threads/tashtalk-single-chip-localtalk-interface.38955/page-4#post-422138)
by bdurbrow - hat for Raspberry Pi
* [AirTalk](https://68kmla.org/bb/index.php?threads/introducing-and-interest-check-airtalk-wireless-plug-and-play-localtalk-dongles.39661/)
by cheesestraws - wireless plug-and-play LocalTalk dongle
* Yours? =)
### End User Hardware
* [AirTalk](https://68kmla.org/bb/index.php?threads/introducing-and-interest-check-airtalk-wireless-plug-and-play-localtalk-dongles.39661/) by [cheesestraws](https://68kmla.org/bb/index.php?members/cheesestraws.19339/)
* Plug-and-play WiFi-LocalTalk dongle
* [Buy](https://airtalk.shop/product/airtalk-complete/) from [airtalk.shop](https://airtalk.shop/)
### Serial Adapters
* TashTalkHat by [bdurbrow](https://68kmla.org/bb/index.php?members/bdurbrow.6275/)
* Raspberry Pi hat using v1.x firmware
* Pending release
* [Forum post](https://68kmla.org/bb/index.php?threads/tashtalk-single-chip-localtalk-interface.38955/page-4#post-422138)
* TashTalk 2 Hat by [Tashtari](https://github.com/lampmerchant)
* Raspberry Pi hat using v2.x firmware
* [Files](https://github.com/lampmerchant/tashtalk/tree/main/tashtalk2-rpihat)
* See latest release in this repository for gerbers
* Buy [fully assembled](https://ko-fi.com/s/4d01fa5b8a) or as kit with [regular](https://ko-fi.com/s/60b561a0e3) or [stackable](https://ko-fi.com/s/64219426b8) header from [Tashtari](https://ko-fi.com/tashtari)
* USB2LT by [twelvetone12](https://68kmla.org/bb/index.php?members/twelvetone12.23810/)
* USB serial adapter using v2.x firmware
* Pending release
* [Forum thread](https://68kmla.org/bb/index.php?threads/usb2lt-tashtalk-usb-to-localtalk.45282/)
### Software
* tashtalkd by [Tashtari](https://github.com/lampmerchant)
* Simple LocalTalk (via TashTalk) to LToUDP bridge
* [Files](https://github.com/lampmerchant/tashtalk/tree/main/tashtalkd)
* MultiTalk by [sfiera](https://github.com/sfiera/)
* Bridge between EtherTalk and LocalTalk (via LToUDP and TashTalk)
* [Project page](https://github.com/sfiera/multitalk/)
* TashRouter by [Tashtari](https://github.com/lampmerchant)
* Full-fledged AppleTalk router supporting EtherTalk and LocalTalk (via LToUDP and TashTalk)
* [Project page](https://github.com/lampmerchant/tashrouter/)
### Yours?
File a PR or an issue to add to these lists!
## Version Comparison
**AirTalk users: do not upgrade your TashTalk PIC to v2.x, it will stop working because of the change in pinout.**
| Version | Pinout | CRC Calculation |
| ------- | --------------------------- | -------------------------------------------- |
| v1.0 | RA3 input, RA5 output | Self-generated frames only |
| v2.0 | RA3 !MCLR, RA5 input/output | Self-generated frames only |
| v2.1 | RA3 !MCLR, RA5 input/output | Self-generated frames, optionally all frames |
### UART Protocol
As of the time of this writing, the base UART protocol is unchanged between all available versions. v2.1 adds the "Set Features"
command, but this can be ignored and is not used by tashtalkd.
### Pinout Change in v2.0
This change was made in order to enable applications where it is desirable to disable LocalTalk and allow other circuitry to use
the RS-422 driver - pulling RA3/!MCLR low will hold the PIC in reset, tristating its outputs. Using RS-422 interface ICs such as
the SN65HVD series, RA5 can be connected to both the receiver output and the driver input while RA4/Driver Enable is connected to
both the (active low) receiver enable and the (active high) driver enable.

View File

@ -36,6 +36,25 @@ The first byte following the 0x02 command byte determines whether the firmware w
Note that 0x00 and 0xFF are not valid for use as node IDs on a LocalTalk network; the bits corresponding to these node IDs should never be set. The former may not cause any problems, but the latter will prevent any broadcast data frames from being transmitted.
#### 0x03 - Set Features
*This command requires version 2.1.0 of the firmware or later.*
This command byte determines which optional features are active. It is followed by a single-byte bit field, the bits of which have the following significance:
##### Bit 7: CRC Calculation
When this bit is set, TashTalk will calculate CRCs for all outbound frames, not just for the control frames that it sends automatically. When transmitting the frame to TashTalk over the UART, the two CRC bytes at the end of the frame must still be present, but they will be overwritten with the correct CRC for the frame.
##### Bit 6: CRC Checking
When this bit is set, TashTalk will check the CRCs for all inbound frames, not just for the control frames that it responds to automatically. The frame data will be relayed to the host regardless of the CRC status, but if the CRC is incorrect, a different escape sequence (see *Escape Sequences* below) will follow the end of the frame.
##### Bits 5-0: Reserved
These bits are reserved for future optional features and should be maintained clear to ensure compatibility.
TashTalk to Host
----------------
@ -54,6 +73,8 @@ This sequence signifies a literal 0x00 byte in the frame being received.
This sequence signifies the end of a frame where no exceptional conditions occurred. The host should regard the data preceding it as an incoming frame, process it if its CRC is correct, and await the start of a new frame.
If the *CRC Checking* feature is enabled, this sequence also signifies that the frame's CRC was correct.
#### 0x00 0xFE - Framing Error
This sequence signifies a framing error - a condition in which six consecutive '1' bits are received but cannot be interpreted as a flag byte. The host should discard the data preceding it and await the start of a new frame.
@ -61,3 +82,9 @@ This sequence signifies a framing error - a condition in which six consecutive '
#### 0x00 0xFA - Frame Aborted
This sequence signifies an aborted frame - a condition where a host had been transmitting a frame but unexpectedly stopped without a concluding flag byte. The host should discard the data preceding it and await the start of a new frame.
#### 0x00 0xFC - Frame CRC Check Failed
*This sequence was introduced in version 2.1.0 of the firmware.*
This sequence, which is only used when the *CRC Checking* feature is enabled (see *Set Features* command above), signifies the end of a frame which was structurally correct but had an incorrect CRC. The host should discard the data preceding it and await the start of a new frame.

View File

@ -1,5 +1,5 @@
TashTalk Prototype Details
==========================
TashTalk v1.x Prototype Details
===============================
Raspberry Pi
------------

View File

@ -9,6 +9,10 @@ Not all of them do! This is a non-exhaustive list of known-good ones.
Used by Tashtari in breadboard testing.
## [SN65HVD11](https://www.ti.com/product/SN65HVD11), [SN65HVD12](https://www.ti.com/product/SN65HVD12)
Used by Tashtari in TashTalk v2.x Hat.
## [ISL83076E](https://www.renesas.com/us/en/products/interface-connectivity/rs-485-rs-422-rs-232/rs-485rs-422/standard-rs-485rs-422/isl83076e-15kv-esd-protected-33v-full-fail-safe-low-power-high-speed-or-slew-rate-limited-rs-485rs-422)
Used by bdurbrow on TashTalkHat.

View File

@ -8,22 +8,6 @@
;
;;; License ;;;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Connections ;;;
;;; ;;;
@ -77,7 +61,13 @@ DNOP macro
;FLAGS:
LR_FRM equ 7 ;Set when received frame registers have changed
CTS_PLS equ 6 ;Set when a CTS frame should trigger a send from queue
LR_CROK equ 6 ;Set when CRC of last frame passed
CTS_PLS equ 5 ;Set when a CTS frame should trigger a send from queue
TMPFLAG equ 4 ;Used as temporary storage in transmitter
;FEATURES:
CALCCRC equ 7 ;Set if transmitter should calculate CRC itself
CHKCRC equ 6 ;Set if receiver should check CRC and signal bad CRCs
;;; Variable Storage ;;;
@ -86,18 +76,18 @@ CTS_PLS equ 6 ;Set when a CTS frame should trigger a send from queue
FLAGS ;You've got to have flags
LR_BUF ;Receiver buffer
LR_BUF2 ;Receiver buffer
LR_CCRC1 ;Receiver CRC register
LR_CCRC2 ; "
LR_STATE ;Receiver state pointer
UR_LEN ;Current length of UART receiver queue
GBACKOFF ;Global backoff mask
LBACKOFF ;Local backoff mask
COL_HIST ;Collision history for last 8 transmissions
DEF_HIST ;Deferral history for last 8 transmissions
UR_DEST ;First five bytes of frame loaded for transmission
UR_SRC ; "
UR_TYPE ; "
UR_4TH ; "
UR_5TH ; "
ATTEMPTS ;Number of attempts at this transmission
FEATURES ;Feature flags
D2
D1
D0
@ -144,16 +134,19 @@ CTS_PLS equ 6 ;Set when a CTS frame should trigger a send from queue
FSR1L_TM ;Temp registers when using FSR1 to modify the node ID
INDF1_TM ; bitmap
LT_CRC1 ;Running CRC value calculated by SendByte
LT_CRC1 ;Running CRC value calculated by SendByte/SendFromQueue
LT_CRC2 ; "
LT_CRCX ;Temp variable used by SendByte when calculating CRC
LT_CRCX ;Temp variable used when calculating CRC
LT_LENH ;Number of bytes to be read from queue by SendFromQueue
LT_LENL ; "
LT_BUF ;Buffer used to hold the byte being sent over LocalTalk
LT_BUF2 ;Temporary buffer
LT_ONES ;Count of consecutive ones sent by LT transmitter
LR_CCRC1 ;CRC register used to calculate the CRC of incoming
LR_CCRC2 ; control frames
UR_DEST ;First five bytes of frame loaded for transmission
UR_SRC ; "
UR_TYPE ; "
UR_4TH ; "
UR_5TH ; "
endc
@ -167,6 +160,13 @@ CTS_PLS equ 6 ;Set when a CTS frame should trigger a send from queue
endc
;Linear Memory:
;0x2000-0x207F - UART receiver queue
;0x2080-0x209F - Node ID bitmap
;0x20A0-0x20AE - Bank 2 registers
;0x20AF-0x20EA - Unused
;0x20EB-0x20EF - Upper end of bank 2 registers
;;; Vectors ;;;
@ -210,20 +210,24 @@ Init
movlw B'11110000'
movwf OSCCON
banksel OSCSTAT ;Spin until PLL is ready and instruction clock
btfss OSCSTAT,PLLR ; gears up to 8 MHz
bra $-1
banksel IOCAN ;RA5 sets IOCAN[IOCAF5] on pos/neg edge
movlw B'00100000'
movwf IOCAN
movwf IOCAP
banksel RCSTA ;UART async mode, 1 MHz
movlw B'01001000'
banksel RCSTA ;UART async mode, 1 MHz, but receiver not
movlw B'01001000' ; enabled just yet
movwf BAUDCON
clrf SPBRGH
movlw 7
movwf SPBRGL
movlw B'00100110'
movwf TXSTA
movlw B'10010000'
movlw B'10000000'
movwf RCSTA
banksel OPTION_REG ;Timer0 uses instruction clock
@ -249,12 +253,26 @@ Init
movlw B'00101010'
movwf TRISA
clrf UR_LEN ;Set up UART receiver queue (0x2000-0x207F),
movlw 0x20 ; for which FSRs are push (FSR0) and pop (FSR1)
movwf FSR0H ; pointers
movlw 0x20 ;Set FSRs to point permanently to linear memory
movwf FSR0H
movwf FSR1H
clrf FSR0L
clrf FSR1L
movlw 0x80 ;Zero out node ID bitmap (0x2080-0x209F) so we
movwf FSR1L ; don't respond to random IDs before the host
movlw 0 ; gets a chance to initialize us
ZeroNID movwi FSR1++
btfss FSR1L,5
bra ZeroNID
clrf UR_LEN ;Set up UART receiver queue (0x2000-0x207F),
clrf FSR0L ; for which FSRs are push (FSR0) and pop (FSR1)
clrf FSR1L ; pointers
clrf FEATURES ;All optional features off to start
clrf LR_CCRC1 ;Receiver CRC registers cleared to ones to
decf LR_CCRC1,F ; start, we don't have time to do this when we
clrf LR_CCRC2 ; jump into the code
decf LR_CCRC2,F
banksel PIE1 ;UART Rx and IOC interrupts on, interrupt
movlw B'00100000' ; subsystem on
@ -262,8 +280,27 @@ Init
movlw B'11001000'
movwf INTCON
banksel RCSTA ;Enable receiver now that interrupt is on
bsf RCSTA,CREN
bra PrepForNextFrame
;entered with BSR = 2
AwaitFeatures
call CheckLtReceiver ;Check for and deal with receiver activity
movf UR_LEN,W ;If there isn't yet a byte in the UART receiver
addlw -1 ; queue, loop around again
btfss STATUS,C ; "
bra AwaitFeatures ; "
movwf UR_LEN ;Decrement the UART receiver queue size by 1
movlw B'11111011' ;If the pop off the queue dropped the length
btfss UR_LEN,6 ; below 64, assert CTS so the host sends us
andwf LATA,F ; data again
moviw FSR1++ ;Pop the next byte off the UART receiver queue
bcf FSR1L,7 ; "
movwf FEATURES ;Store this byte into the features bitmap
bra AwaitCommand ;Return to await next command
;entered with BSR = 2
AwaitNodeId
call CheckLtReceiver ;Check for and deal with receiver activity
@ -393,6 +430,9 @@ AwaitCommand
addlw -1 ;If it's two, that's the command byte for
btfsc STATUS,Z ; setting the node ID bitmap, so go wait for
bra AwaitNodeId ; that data
addlw -1 ;If it's three, that's the command byte for
btfsc STATUS,Z ; setting the features bitmap, so go wait for
bra AwaitFeatures ; that data
bra AwaitCommand ;All other commands are considered no-ops
;entered with BSR = ?
@ -442,13 +482,13 @@ PrepForNextFrame
btfsc WREG,7 ; "
clrf DEF_HIST ; "
btfsc WREG,7 ; "
decf DEF_HIST ; "
decf DEF_HIST,F ; "
lslf COL_HIST,F ;Progress the collision and deferral history
lslf DEF_HIST,F ; logs to make space for what happens this time
movf GBACKOFF,W ;Copy the global backoff mask into the local
movwf LBACKOFF ; backoff mask
movlw 33 ;Set attempts counter to 32 (plus one since we
movwf ATTEMPTS ; immediately decrement it)
movlw 32 ;Set attempts counter to 32
movwf ATTEMPTS ; "
bra AwaitCommand ;We're set for the next frame, wait for it
;entered with BSR = 2
@ -545,9 +585,10 @@ WaitToSendCtrl
WTSC1 bcf INTCON,GIE ;Disable interrupts before checking Timer2
btfss PIR1,TMR2IF ;Unless Timer2 has interrupted, loop around
bra WaitToSendCtrl ; again
btfss UR_TYPE,7 ;If the loaded frame is a control frame, just
bra WTSC2 ; go ahead and send it and then prepare for the
call SendControlFrame; next frame
movlb 2 ;If the loaded frame is a control frame, just
btfss UR_TYPE,7 ; go ahead and send it and then prepare for the
bra WTSC2 ; next frame
call SendControlFrame; "
bra PrepForNextFrame; "
WTSC2 call SendRts ;If it's a data frame, send an RTS frame first
movlb 0 ;Set Timer2 to interrupt after 200us, the
@ -556,21 +597,23 @@ WTSC2 call SendRts ;If it's a data frame, send an RTS frame first
bsf T2CON,TMR2ON ;Activate Timer2
clrf TMR2 ;Reset Timer2
bcf PIR1,TMR2IF ;Clear the Timer2 interrupt flag
incf UR_DEST,W ;If frame's destination is broadcast (0xFF)
btfsc STATUS,Z ; then we want to wait for 200us of silence
bra WaitForSilence ; before sending; otherwise we want to wait for
bra WaitForCts ; a CTS frame and 200us is our timeout
movlb 2 ;If frame's destination is broadcast (0xFF)
incf UR_DEST,W ; then we want to wait for 200us of silence
movlb 0 ; before sending; otherwise we want to wait for
btfsc STATUS,Z ; a CTS frame and 200us is our timeout
bra WaitForSilence ; "
bra WaitForCts ; "
;entered with BSR = ?
GiveUp
movlb 2
btfsc UR_TYPE,7 ;If loaded frame is a control frame, we already
bra PrepForNextFrame; have it in full
movlb 2 ;If loaded frame is a data frame, we need to
movf UR_4TH,W ; extract the length from the 4th and 5th bytes
andlw B'00000011' ; and drain that many characters from the UART
movwf LT_LENH ; receiver queue (even if it doesn't already
movf UR_5TH,W ; contain all of them)
movwf LT_LENL ; "
movf UR_4TH,W ;If loaded frame is a data frame, we need to
andlw B'00000011' ; extract the length from the 4th and 5th bytes
movwf LT_LENH ; and drain that many characters from the UART
movf UR_5TH,W ; receiver queue (even if it doesn't already
movwf LT_LENL ; contain all of them)
GiveUp1 movlw -1 ;Decrement the length counter; if it was
addwf LT_LENL,F ; already zero, we're done
addwfc LT_LENH,F ; "
@ -663,6 +706,8 @@ DealWithFrame
btfss FLAGS,LR_FRM ;If the incoming frame regs haven't changed,
return ; we have nothing to do here
bcf FLAGS,LR_FRM ;This is so we know if regs changed under us
btfss FLAGS,LR_CROK ;If the frame's CRC check failed, the frame is
return ; invalid, ignore it
btfss LR_TYPE,7 ;If the frame is not a control frame, there's
return ; nothing to do; host handles data frames
movf FSR1L,W ;Using the node ID bitmap, check whether this
@ -687,55 +732,6 @@ DealWithFrame
movf INDF1_TM,F ; "
btfsc STATUS,Z ; "
return ; "
clrf LR_CCRC1 ;Clear the CRC check registers to all ones so
clrf LR_CCRC2 ; we can start checking the CRC of the frame
decf LR_CCRC1,F ; "
decf LR_CCRC2,F ; "
movf LR_DEST,W ;Update the CRC check registers with the frame
xorwf LR_CCRC1,W ; destination
movwf LR_CCRC1 ; "
movlp high CrcLut1 ; "
callw ; "
xorwf LR_CCRC2,W ; "
xorwf LR_CCRC1,F ; "
xorwf LR_CCRC1,W ; "
xorwf LR_CCRC1,F ; "
movlp high CrcLut2 ; "
callw ; "
movwf LR_CCRC2 ; "
movf LR_SRC,W ;Update the CRC check registers with the frame
xorwf LR_CCRC1,W ; source
movwf LR_CCRC1 ; "
movlp high CrcLut1 ; "
callw ; "
xorwf LR_CCRC2,W ; "
xorwf LR_CCRC1,F ; "
xorwf LR_CCRC1,W ; "
xorwf LR_CCRC1,F ; "
movlp high CrcLut2 ; "
callw ; "
movwf LR_CCRC2 ; "
movf LR_TYPE,W ;Update the CRC check registers with the frame
xorwf LR_CCRC1,W ; type
movwf LR_CCRC1 ; "
movlp high CrcLut1 ; "
callw ; "
xorwf LR_CCRC2,W ; "
xorwf LR_CCRC1,F ; "
xorwf LR_CCRC1,W ; "
xorwf LR_CCRC1,F ; "
movlp high CrcLut2 ; "
callw ; "
movwf LR_CCRC2 ; "
movlp 0 ; "
comf LR_CCRC1,W ;If the calculated CRC does not match the
xorwf LR_CRC1,W ; received one, the frame is invalid and we're
btfss STATUS,Z ; done
return ; "
comf LR_CCRC2,W ; "
xorwf LR_CRC2,W ; "
btfss STATUS,Z ; "
return ; "
bcf INTCON,GIE ;Disable interrupts so frame vars don't change
btfsc FLAGS,LR_FRM ;If this flag is set, regs changed under us so
bra DealWiR ; we can't act, reenable interrupts and return
@ -784,13 +780,16 @@ SendControlFrame
DNOP ;30-31
call SendByte ;32-25
movf UR_4TH,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
btfsc FEATURES,CALCCRC;27
comf LT_CRC1,W ;28
movwf LT_BUF ;29
comf LT_CRC2,W ;30
movwf LT_BUF2 ;31
call SendByte ;32-25
movf UR_5TH,W ;26
movwf LT_BUF ;27
DNOP ;28-29
btfsc FEATURES,CALCCRC;27
movf LT_BUF2,W ;28
movwf LT_BUF ;29
DNOP ;30-31
call SendByte ;32-25
DNOP ;26-27
@ -819,24 +818,31 @@ SendDataFrame
call SendByte ;32-25
movf UR_TYPE,W ;26
movwf LT_BUF ;27
DNOP ;28-29
DNOP ;30-31
nop ;28
bsf FLAGS,TMPFLAG ;29 If frame length is 2, we need to overwrite
btfss FEATURES,CALCCRC;30 the CRC bytes with our calculated CRC; if
bcf FLAGS,TMPFLAG ;31 the feature is off, never do this
call SendByte ;32-25
movf UR_4TH,W ;26
movwf LT_BUF ;27
andlw B'00000011' ;28
movwf LT_LENH ;29
DNOP ;30-31
btfss STATUS,Z ;30 If high byte of length is not zero, length
bcf FLAGS,TMPFLAG ;31 of frame is not 2
call SendByte ;32-25
movf UR_5TH,W ;26
movwf LT_BUF ;27
movwf LT_LENL ;28
nop ;29
DNOP ;30-31
xorlw 2 ;29 If low byte of length is not 2, length of
btfss STATUS,Z ;30 frame is not 2
bcf FLAGS,TMPFLAG ;31 "
call SendByte ;32-25
DNOP ;26-27
DNOP ;28-29
DNOP ;30-31
comf LT_CRC1,W ;26 If length of frame is 2, overstrike the
btfsc FLAGS,TMPFLAG ;27 first byte to send with the first byte of
movwf INDF1 ;28 the CRC and store the second for later
comf LT_CRC2,W ;29 use; this takes care of the fact that we
btfsc FLAGS,TMPFLAG ;30 won't have time to do it later
movwf LT_BUF2 ;31 "
call SendFromQueue ;32-25 (Branches into SendPostamble)
movlb 7 ;Clear the inevitable IOC interrupt that came
bcf IOCAF,IOCAF5 ; in while (and because) we were transmitting
@ -1184,8 +1190,13 @@ SendFrL movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
DELAY 3 ;24-32
nop ;33
movf INDF1,W ;24 Update LT_CRC1 with the byte being sent;
xorwf LT_CRC1,W ;25 note that we don't movlp back to 0 because
movwf LT_CRCX ;26 we don't have time; this only works
movlp high CrcLut1 ;27 because CrcLut1 is below the page boundary
callw ;28-31 "
xorwf LT_CRC2,W ;32 "
movwf LT_CRC1 ;33 "
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
@ -1198,8 +1209,12 @@ SendFrL movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
DELAY 3 ;24-32
nop ;33
movf LT_CRCX,W ;24 Update LT_CRC2 with the byte being sent
movlp high CrcLut2 ;25 "
callw ;26-29 "
movlp 0 ;30 "
movwf LT_CRC2 ;31 "
DNOP ;32-33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
@ -1212,8 +1227,16 @@ SendFrL movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
DELAY 3 ;24-32
nop ;33
bsf FLAGS,TMPFLAG ;24 If frame length is 2, we need to overwrite
btfss FEATURES,CALCCRC;25 the CRC bytes with our calculated CRC; if
bcf FLAGS,TMPFLAG ;26 the feature is off, never do this
movf LT_LENH,W ;27 If the upper byte of the remaining byte
btfss STATUS,Z ;28 counter is not zero, remaining byte
bcf FLAGS,TMPFLAG ;29 counter is not 2
movf LT_LENL,W ;30 If the lower byte of the remaining byte
xorlw 2 ;31 counter is not 2, remaining byte counter
btfss STATUS,Z ;32 is not 2; we will use this flag later
bcf FLAGS,TMPFLAG ;33 "
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
@ -1226,8 +1249,16 @@ SendFrL movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
DELAY 3 ;24-32
nop ;33
moviw FSR1++ ;24 Advance the receiver queue pop pointer
bcf FSR1L,7 ;25 "
comf LT_CRC1,W ;26 If the remaining byte counter is at 2, set
btfsc FLAGS,TMPFLAG ;27 the next byte to be sent to the first byte
movwf INDF1 ;28 of the CRC and store the second byte of
comf LT_CRC2,W ;29 the CRC to be sent later (when the
btfsc FLAGS,TMPFLAG ;30 remaining byte counter is at 1)
movwf LT_BUF2 ;31 "
decf FSR1L,F ;32 Regress the receiver queue pop pointer
bcf FSR1L,7 ;33 "
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
@ -1240,8 +1271,16 @@ SendFrL movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
DELAY 3 ;24-32
nop ;33
bsf FLAGS,TMPFLAG ;24 If frame length is 2, we need to overwrite
btfss FEATURES,CALCCRC;25 the CRC bytes with our calculated CRC; if
bcf FLAGS,TMPFLAG ;26 the feature is off, never do this
movf LT_LENH,W ;27 If the upper byte of the remaining byte
btfss STATUS,Z ;28 counter is not zero, remaining byte
bcf FLAGS,TMPFLAG ;29 counter is not 1
movf LT_LENL,W ;30 If the lower byte of the remaining byte
xorlw 1 ;31 counter is not 1, remaining byte counter
btfss STATUS,Z ;32 is not 1; we will use this flag later
bcf FLAGS,TMPFLAG ;33 "
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
call SendDoUartSvc ;01-02 (03-14) Service the UART receiver
@ -1254,7 +1293,14 @@ SendFrL movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
bsf LT_ONES,0 ;21 "
btfsc LT_ONES,5 ;22 If the consecutive ones counter has reached
call SendByteStuff ;23(-24) five, stuff a zero
DELAY 3 ;24-32
moviw FSR1++ ;24 Advance the receiver queue pop pointer
bcf FSR1L,7 ;25 "
movf LT_BUF2,W ;26 If the remaining byte counter is at 1, set
btfsc FLAGS,TMPFLAG ;27 the next byte to be sent to the second
movwf INDF1 ;28 byte of the CRC that we saved earlier
decf FSR1L,F ;29 Regress the receiver queue pop pointer
bcf FSR1L,7 ;30 "
DNOP ;31-32
nop ;33
movlw B'00100000' ;34 Load pattern for inverting LocalTalk pin
xorwf LATA,F ;00 Invert LocalTalk pin for clock
@ -1375,7 +1421,7 @@ SendDoUartCts
;;; CRC Lookup Tables ;;;
org 0x700
org 0x600
CrcLut1
dt 0x00,0x89,0x12,0x9B,0x24,0xAD,0x36,0xBF
@ -1412,7 +1458,7 @@ CrcLut1
dt 0xC7,0x4E,0xD5,0x5C,0xE3,0x6A,0xF1,0x78
org 0x800
org 0x700
CrcLut2
dt 0x00,0x11,0x23,0x32,0x46,0x57,0x65,0x74
@ -1459,7 +1505,7 @@ CrcLut2
; \________________/
; Time period when we should be checking for a clock-inversion
org 0x900
org 0x800
OutNothingSkip
movlw B'00001111' ;16 If the UART receiver queue length >= 64,
@ -1607,6 +1653,33 @@ InCheckInv
bra InReceive ;43 "
bra InLostClock ;By this point, we must assume we've lost clock
InSecond
movf LR_BUF2,W ;12 Update the CRC with the last byte received
xorwf LR_CCRC1,W ;13 "
movlp high CrcLut1 ;14 "
callw ;15-18 "
movwf D0 ;19 "
bra InCheckInv ;20-21
InFourth
movf LR_BUF2,W ;12 Update the CRC with the last byte received
movwi FSR1++ ;13 "
xorwf LR_CCRC1,W ;14 "
movwf D1 ;15 "
movf D0,W ;16 "
xorwf LR_CCRC2,W ;17 "
movwf LR_CCRC1 ;18 "
nop ;19
bra InCheckInv ;20-21
InSixth
movf D1,W ;12 Update the CRC with the last byte received
movlp high CrcLut2 ;13 "
callw ;14-17 "
movwf LR_CCRC2 ;18 "
nop ;19
bra InCheckInv ;20-21
OutReceive
bcf IOCAF,IOCAF5 ;00 Ready to detect inversion
movlp high OutFSA ;01 Point PCLATH to the out-of-frame FSA for 0
@ -1632,19 +1705,80 @@ InReceive
movwf PCL ;05-06 "
InFlag
movlb 3 ;12 Transmit a zero, which is an escape
clrf TXREG ;13 character
movlw 0xFD ;14 Transmit 0xFD, which signifies 'Frame Done'
movwf TXREG ;15 "
movlb 7 ;16 "
bsf FLAGS,LR_FRM ;17 Raise the flag that frame regs have changed
DNOP ;18-19
bra OutCheckInv ;20-21 Switch to out-of-frame inversion check
bsf FLAGS,LR_CROK ;12 If the whole frame and a correct CRC have
movf LR_CCRC1,W ;13 been fed through the CRC calculator, the
xorlw 0xB8 ;14 registers should be 0xB8 and 0xF0; set
btfss STATUS,Z ;15 flag if this is the case and clear it
bcf FLAGS,LR_CROK ;16 otherwise
movf LR_CCRC2,W ;17 "
xorlw 0xF0 ;18 "
btfss STATUS,Z ;19 "
bcf FLAGS,LR_CROK ;20 "
movlw 0xFC ;21 Compute the correct status to send - if the
btfss FLAGS,LR_CROK ;22 CRC is wrong and CRC checking is enabled,
btfss FEATURES,CHKCRC ;23 this should be 0xFC (frame check failed),
movlw 0xFD ;24 otherwise it should be 0xFD (frame done)
movlb 3 ;25 Transmit a zero, which is an escape
clrf TXREG ;26 character
movwf TXREG ;27 Send the byte computed above
movlb 7 ;28 "
bsf FLAGS,LR_FRM ;29 Raise the flag that frame regs have changed
InFlag2 bcf IOCAF,IOCAF5 ;Ready to detect inversion
movlb 0 ;00 Check if there is a byte waiting from the
bcf STATUS,C ;01 UART
btfsc PIR1,RCIF ;02 "
bsf STATUS,C ;03 "
movlb 3 ;04 If there is a byte waiting from the UART,
btfsc STATUS,C ;05 push it onto the queue
movf RCREG,W ;06 "
movlb 0 ;07 "
btfsc STATUS,C ;08 "
movwi FSR0++ ;09 "
bcf FSR0L,7 ;10 Wrap the queue around
btfsc STATUS,C ;11 If there was a byte waiting from the UART,
incf UR_LEN,F ;12 increment the queue length
movlw B'00001111' ;13 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;14 deassert CTS so the host stops sending us
movwf PORTA ;15 data
bcf STATUS,C ;16 Check if there is a byte waiting from the
btfsc PIR1,RCIF ;17 UART
bsf STATUS,C ;18 "
movlb 3 ;19 If there is a byte waiting from the UART,
btfsc STATUS,C ;20 push it onto the queue
movf RCREG,W ;21 "
movlb 0 ;22 "
btfsc STATUS,C ;23 "
movwi FSR0++ ;24 "
bcf FSR0L,7 ;25 Wrap the queue around
btfsc STATUS,C ;26 If there was a byte waiting from the UART,
incf UR_LEN,F ;27 increment the queue length
movlw B'00001111' ;28 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;29 deassert CTS so the host stops sending us
movwf PORTA ;30 data
bcf STATUS,C ;31 Check if there is a byte waiting from the
btfsc PIR1,RCIF ;32 UART
bsf STATUS,C ;33 "
movlb 3 ;34 If there is a byte waiting from the UART,
btfsc STATUS,C ;35 push it onto the queue
movf RCREG,W ;36 "
movlb 0 ;37 "
btfsc STATUS,C ;38 "
movwi FSR0++ ;39 "
bcf FSR0L,7 ;40 Wrap the queue around
btfsc STATUS,C ;41 If there was a byte waiting from the UART,
incf UR_LEN,F ;42 increment the queue length
movlw B'00001111' ;43 If the UART receiver queue length >= 64,
btfsc UR_LEN,6 ;44 deassert CTS so the host stops sending us
movwf PORTA ;45 data
movlb 7 ;If there's been an inversion in the elapsed
btfsc IOCAF,IOCAF5 ; ~1.25 bit times, the line is not yet idle and
bra InFlag2 ; we should try again
bra FinishUp ;Else, proceed to finish the receive
EmpByte
InByte
movf LR_BUF,W ;12 Save the received byte into the frame regs
movwi FSR1++ ;13 using FSR1
movf LR_BUF,W ;12 Save received byte into second buffer so it
movwf LR_BUF2 ;13 can be CRC'd and copied into the frame regs
btfss STATUS,Z ;14 If the received byte is not a zero, just
bra InByte2 ;15(-16) transmit it as-is
movlb 3 ;16 If the received byte is a zero, transmit
@ -1714,7 +1848,24 @@ InFErr
clrf TXREG ; "
movlw 0xFE ;Transmit 0xFE, which signifies 'Frame Error'
movwf TXREG ; "
bra FinishUp
;fall through
OutLostClock
EmpLostClock
FinishUp
movlb 0 ;If the frame regs changed, deactivate Timer2
btfss FLAGS,LR_FRM ; and clear its interrupt flag so anything that
bra Finish2 ; was waiting for it knows that a frame was
bcf T2CON,TMR2ON ; received while waiting
bcf PIR1,TMR2IF ; "
Finish2 clrf LR_CCRC1 ;Clear receiver CRC registers to ones since we
decf LR_CCRC1,F ; don't have time to do this when we jump into
clrf LR_CCRC2 ; the receiver
decf LR_CCRC2,F ; "
movf FSR0L,W ;Store the changed UART receiver push point
movlb 31 ; back in its shadow register so it stays the
movwf FSR0L_SHAD ; same when we return from interrupt
retfie
InLostClock
movlb 0 ;Wait until the UART transmitter is ready for
@ -1730,17 +1881,6 @@ InLostClock
movwf TXREG ; "
bra FinishUp
OutLostClock
EmpLostClock
FinishUp
movlb 0 ;Deactivate Timer2 and clear its interrupt flag
bcf T2CON,TMR2ON ; so anything that was waiting for it knows
bcf PIR1,TMR2IF ; that a receive event happened while waiting
movf FSR0L,W ;Store the changed UART receiver push point
movlb 31 ; back in its shadow register so it stays the
movwf FSR0L_SHAD ; same when we return from interrupt
retfie
;;; LocalTalk Receiver State Machines ;;;
@ -2569,7 +2709,7 @@ Is0c0r0 bcf LR_BUF,0 ;07
Is0c1r0 bcf LR_BUF,1 ;07
movlw low Is0c2r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSecond ;10-11
Is0c2r0 bcf LR_BUF,2 ;07
movlw low Is0c3r0 ;08
movwf LR_STATE ;09
@ -2577,7 +2717,7 @@ Is0c2r0 bcf LR_BUF,2 ;07
Is0c3r0 bcf LR_BUF,3 ;07
movlw low Is0c4r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InFourth ;10-11
Is0c4r0 bcf LR_BUF,4 ;07
movlw low Is0c5r0 ;08
movwf LR_STATE ;09
@ -2585,7 +2725,7 @@ Is0c4r0 bcf LR_BUF,4 ;07
Is0c5r0 bcf LR_BUF,5 ;07
movlw low Is0c6r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSixth ;10-11
Is0c6r0 bcf LR_BUF,6 ;07
movlw low Is0c7r0 ;08
movwf LR_STATE ;09
@ -2601,7 +2741,7 @@ Is1c0r0 bcf LR_BUF,0 ;07
Is1c1r0 bcf LR_BUF,1 ;07
movlw low Is0c2r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSecond ;10-11
Is1c2r0 bcf LR_BUF,2 ;07
movlw low Is0c3r0 ;08
movwf LR_STATE ;09
@ -2609,7 +2749,7 @@ Is1c2r0 bcf LR_BUF,2 ;07
Is1c3r0 bcf LR_BUF,3 ;07
movlw low Is0c4r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InFourth ;10-11
Is1c4r0 bcf LR_BUF,4 ;07
movlw low Is0c5r0 ;08
movwf LR_STATE ;09
@ -2617,7 +2757,7 @@ Is1c4r0 bcf LR_BUF,4 ;07
Is1c5r0 bcf LR_BUF,5 ;07
movlw low Is0c6r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSixth ;10-11
Is1c6r0 bcf LR_BUF,6 ;07
movlw low Is0c7r0 ;08
movwf LR_STATE ;09
@ -2633,7 +2773,7 @@ Is2c0r0 bcf LR_BUF,0 ;07
Is2c1r0 bcf LR_BUF,1 ;07
movlw low Is0c2r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSecond ;10-11
Is2c2r0 bcf LR_BUF,2 ;07
movlw low Is0c3r0 ;08
movwf LR_STATE ;09
@ -2641,7 +2781,7 @@ Is2c2r0 bcf LR_BUF,2 ;07
Is2c3r0 bcf LR_BUF,3 ;07
movlw low Is0c4r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InFourth ;10-11
Is2c4r0 bcf LR_BUF,4 ;07
movlw low Is0c5r0 ;08
movwf LR_STATE ;09
@ -2649,7 +2789,7 @@ Is2c4r0 bcf LR_BUF,4 ;07
Is2c5r0 bcf LR_BUF,5 ;07
movlw low Is0c6r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSixth ;10-11
Is2c6r0 bcf LR_BUF,6 ;07
movlw low Is0c7r0 ;08
movwf LR_STATE ;09
@ -2665,7 +2805,7 @@ Is3c0r0 bcf LR_BUF,0 ;07
Is3c1r0 bcf LR_BUF,1 ;07
movlw low Is0c2r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSecond ;10-11
Is3c2r0 bcf LR_BUF,2 ;07
movlw low Is0c3r0 ;08
movwf LR_STATE ;09
@ -2673,7 +2813,7 @@ Is3c2r0 bcf LR_BUF,2 ;07
Is3c3r0 bcf LR_BUF,3 ;07
movlw low Is0c4r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InFourth ;10-11
Is3c4r0 bcf LR_BUF,4 ;07
movlw low Is0c5r0 ;08
movwf LR_STATE ;09
@ -2681,7 +2821,7 @@ Is3c4r0 bcf LR_BUF,4 ;07
Is3c5r0 bcf LR_BUF,5 ;07
movlw low Is0c6r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSixth ;10-11
Is3c6r0 bcf LR_BUF,6 ;07
movlw low Is0c7r0 ;08
movwf LR_STATE ;09
@ -2697,7 +2837,7 @@ Is4c0r0 bcf LR_BUF,0 ;07
Is4c1r0 bcf LR_BUF,1 ;07
movlw low Is0c2r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSecond ;10-11
Is4c2r0 bcf LR_BUF,2 ;07
movlw low Is0c3r0 ;08
movwf LR_STATE ;09
@ -2705,7 +2845,7 @@ Is4c2r0 bcf LR_BUF,2 ;07
Is4c3r0 bcf LR_BUF,3 ;07
movlw low Is0c4r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InFourth ;10-11
Is4c4r0 bcf LR_BUF,4 ;07
movlw low Is0c5r0 ;08
movwf LR_STATE ;09
@ -2713,7 +2853,7 @@ Is4c4r0 bcf LR_BUF,4 ;07
Is4c5r0 bcf LR_BUF,5 ;07
movlw low Is0c6r0 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSixth ;10-11
Is4c6r0 bcf LR_BUF,6 ;07
movlw low Is0c7r0 ;08
movwf LR_STATE ;09
@ -2772,7 +2912,7 @@ Is0c0r1 bsf LR_BUF,0 ;07
Is0c1r1 bsf LR_BUF,1 ;07
movlw low Is1c2r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSecond ;10-11
Is0c2r1 bsf LR_BUF,2 ;07
movlw low Is1c3r1 ;08
movwf LR_STATE ;09
@ -2780,7 +2920,7 @@ Is0c2r1 bsf LR_BUF,2 ;07
Is0c3r1 bsf LR_BUF,3 ;07
movlw low Is1c4r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InFourth ;10-11
Is0c4r1 bsf LR_BUF,4 ;07
movlw low Is1c5r1 ;08
movwf LR_STATE ;09
@ -2788,7 +2928,7 @@ Is0c4r1 bsf LR_BUF,4 ;07
Is0c5r1 bsf LR_BUF,5 ;07
movlw low Is1c6r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSixth ;10-11
Is0c6r1 bsf LR_BUF,6 ;07
movlw low Is1c7r1 ;08
movwf LR_STATE ;09
@ -2804,7 +2944,7 @@ Is1c0r1 bsf LR_BUF,0 ;07
Is1c1r1 bsf LR_BUF,1 ;07
movlw low Is2c2r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSecond ;10-11
Is1c2r1 bsf LR_BUF,2 ;07
movlw low Is2c3r1 ;08
movwf LR_STATE ;09
@ -2812,7 +2952,7 @@ Is1c2r1 bsf LR_BUF,2 ;07
Is1c3r1 bsf LR_BUF,3 ;07
movlw low Is2c4r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InFourth ;10-11
Is1c4r1 bsf LR_BUF,4 ;07
movlw low Is2c5r1 ;08
movwf LR_STATE ;09
@ -2820,7 +2960,7 @@ Is1c4r1 bsf LR_BUF,4 ;07
Is1c5r1 bsf LR_BUF,5 ;07
movlw low Is2c6r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSixth ;10-11
Is1c6r1 bsf LR_BUF,6 ;07
movlw low Is2c7r1 ;08
movwf LR_STATE ;09
@ -2836,7 +2976,7 @@ Is2c0r1 bsf LR_BUF,0 ;07
Is2c1r1 bsf LR_BUF,1 ;07
movlw low Is3c2r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSecond ;10-11
Is2c2r1 bsf LR_BUF,2 ;07
movlw low Is3c3r1 ;08
movwf LR_STATE ;09
@ -2844,7 +2984,7 @@ Is2c2r1 bsf LR_BUF,2 ;07
Is2c3r1 bsf LR_BUF,3 ;07
movlw low Is3c4r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InFourth ;10-11
Is2c4r1 bsf LR_BUF,4 ;07
movlw low Is3c5r1 ;08
movwf LR_STATE ;09
@ -2852,7 +2992,7 @@ Is2c4r1 bsf LR_BUF,4 ;07
Is2c5r1 bsf LR_BUF,5 ;07
movlw low Is3c6r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSixth ;10-11
Is2c6r1 bsf LR_BUF,6 ;07
movlw low Is3c7r1 ;08
movwf LR_STATE ;09
@ -2868,7 +3008,7 @@ Is3c0r1 bsf LR_BUF,0 ;07
Is3c1r1 bsf LR_BUF,1 ;07
movlw low Is4c2r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSecond ;10-11
Is3c2r1 bsf LR_BUF,2 ;07
movlw low Is4c3r1 ;08
movwf LR_STATE ;09
@ -2876,7 +3016,7 @@ Is3c2r1 bsf LR_BUF,2 ;07
Is3c3r1 bsf LR_BUF,3 ;07
movlw low Is4c4r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InFourth ;10-11
Is3c4r1 bsf LR_BUF,4 ;07
movlw low Is4c5r1 ;08
movwf LR_STATE ;09
@ -2884,7 +3024,7 @@ Is3c4r1 bsf LR_BUF,4 ;07
Is3c5r1 bsf LR_BUF,5 ;07
movlw low Is4c6r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSixth ;10-11
Is3c6r1 bsf LR_BUF,6 ;07
movlw low Is4c7r1 ;08
movwf LR_STATE ;09
@ -2900,7 +3040,7 @@ Is4c0r1 bsf LR_BUF,0 ;07
Is4c1r1 bsf LR_BUF,1 ;07
movlw low Is5c2r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSecond ;10-11
Is4c2r1 bsf LR_BUF,2 ;07
movlw low Is5c3r1 ;08
movwf LR_STATE ;09
@ -2908,7 +3048,7 @@ Is4c2r1 bsf LR_BUF,2 ;07
Is4c3r1 bsf LR_BUF,3 ;07
movlw low Is5c4r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InFourth ;10-11
Is4c4r1 bsf LR_BUF,4 ;07
movlw low Is5c5r1 ;08
movwf LR_STATE ;09
@ -2916,7 +3056,7 @@ Is4c4r1 bsf LR_BUF,4 ;07
Is4c5r1 bsf LR_BUF,5 ;07
movlw low Is5c6r1 ;08
movwf LR_STATE ;09
goto InNothing ;10-11
goto InSixth ;10-11
Is4c6r1 bsf LR_BUF,6 ;07
movlw low Is5c7r1 ;08
movwf LR_STATE ;09

View File

@ -0,0 +1,14 @@
TashTalk 2 Hat
==============
## Bill of Materials
| Qty | Make | Model | Description | Buy Link |
| --- | -------------- | -------------------- | ------------------------ | -------- |
| 1 | TI | SN65HVD12P | RS-422/485 transceiver | [DigiKey](https://www.digikey.com/en/products/detail/texas-instruments/SN65HVD12P/513465) |
| 1 | Microchip | PIC12F1840 | Microcontroller | [DigiKey](https://www.digikey.com/en/products/detail/microchip-technology/PIC12F1840-I-P/2651357) |
| 1 | Sullins | SFH11-PBPC-D20-ST-BK | 40-pin female header | [DigiKey](https://www.digikey.com/en/products/detail/sullins-connector-solutions/SFH11-PBPC-D20-ST-BK/1990093) |
| 1 | Panasonic | ECE-A1VKS100 | 10 uF radial capacitor | [DigiKey](https://www.digikey.com/en/products/detail/panasonic-electronic-components/ECE-A1VKS100/160560) |
| 1 | Stackpole | CFM14JT10K0 | 10k ohm resistor | [DigiKey](https://www.digikey.com/en/products/detail/stackpole-electronics-inc/CFM14JT10K0/1742061) |
| 1 | MaxCom | MMDF-8FOB-1 | 8-pin mini DIN connector | [Jameco](https://www.jameco.com/webapp/wcs/stores/servlet/ProductDisplay?langId=-1&storeId=10001&catalogId=10001&productId=207722) |
| 2 | TE Connectivity | 390261-2 | 8-pin DIP socket | [Jameco](https://www.jameco.com/webapp/wcs/stores/servlet/ProductDisplay?langId=-1&storeId=10001&catalogId=10001&productId=526299) |