{\rtf1\ansi\ansicpg1252\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\fmodern Courier New;}{\f3\fmodern Courier;}{\f4\fmodern Courier New;}} {\colortbl\red0\green0\blue0;} \deflang1033\horzdoc{\*\fchars }{\*\lchars }\pard\tx360\tx1080\tx1800\tx2520\tx3240\tx3960\tx4680\tx5400\tx6120\tx6840\tx7560\tx8280\tx9000\plain\f3\fs20 ;------------------------------------------------------------------------ \par ; RFZ8.ASM (Version 1.0) 12/17/99 \par ; Asynchronous 232 and RF Interface for Z86x08 \par ; Baud Rate is 9600 for both channels \par ; Half-Duplex Operation Mode. \par ; \par ; Signal Pin Z86E08 Pin Signal \par ; ----------- ----- --------- ----- ----------- \par ; D3 P24 -- | 1 18 |-- P23 ID3 \par ; D4 P25 -- | 2 17 |-- P22 ID2 \par ; D5 P26 -- | 3 16 |-- P21 ID1 \par ; PTT_ \tab \tab \tab P27 \tab -- | 4 15 |-- P20 ID0 \par ; Power VCC -\tab - | \tab 5 \tab \tab 14\tab \tab |-- GND Ground \par ; Crystal Out XTAL2 -- \tab \tab | 6 13 |-- P02 SHDN_ \par ; Crystal In XTAL1 -- \tab \tab | 7 12 |-- P01 232_TX \par ; 232_RX P31 -- \tab \tab \tab | 8 11 |-- P00 RTX \par ; RRX\tab \tab \tab P32 -- \tab | 9 10 |-- \par ; --------- \par ; \par ;\tab SCLK = 6 MHz (FOSC = 12 MHz in OSC/2 Standard Mode) \par ; \par ;\tab Assembler: ZDS V3.0 \par \plain\f4\fs20 ;\tab \plain\f3\fs20 Best if viewed in Courier New 9 pt with 7 space tabs \par ;------------------------------------------------------------------------ \par \par \tab GLOBALS ON \par \tab DEFINE\tab \tab REGDATA, SPACE=RFILE \par \par ;************************************************************************ \par ;* Global Definitions \par ;************************************************************************ \par \tab SEGMENT\tab \tab REGDATA \par \par \tab \tab DS\tab 4\tab \tab ; Ports \par P0COPY\tab \tab DS\tab 1\tab \tab ; %04 \par P2COPY\tab \tab DS\tab 1\tab \tab ; %05 \par P3COPY\tab \tab DS\tab 1\tab \tab ; %06 \par RCV_STATUS\tab \tab DS\tab 1\tab \tab ; %07 \par FRAME_ERR\tab \tab DS\tab 1\tab \tab ; %08 \par MY_ADDR\tab \tab DS\tab 1\tab \tab ; %09 \par FROMFROM\tab \tab DS\tab 1\tab \tab ; %0A \par SERDATA\tab \tab DS\tab 1\tab \tab ; %0B \par RFDATA\tab \tab DS\tab 1\tab \tab ; %0C \par RETRY\tab \tab DS\tab 1\tab \tab ; %0D \par DATA_PTR\tab \tab DS\tab 1\tab \tab ; %0E \par SPCL_DATA\tab \tab DS\tab 1\tab \tab ; %0F \par \tab \tab DS\tab 14\tab \tab ; %10-1D \par COPYSIZE\tab \tab DS\tab 1\tab \tab ; %1E \par BYTECNT\tab \tab DS\tab 1\tab \tab ; %1F \par STARTBYTE\tab \tab DS\tab 1\tab \tab ; %20 \par TOFROM\tab \tab DS\tab 1\tab \tab ; %21 \par PACKET\tab \tab DS\tab 1\tab \tab ; %22 \par SIZE\tab \tab DS\tab 1\tab \tab ; %23 \par DATABUF\tab \tab DS\tab 1\tab \tab ; %24 \par \tab \tab DS\tab 33\tab \tab ; %25 \par FCSHI\tab \tab DS\tab 1\tab \tab ; %46 \par FCSLO\tab \tab DS\tab 1\tab \tab ; %47 \par ESTARTBYTE\tab \tab DS\tab 1\tab \tab ; %48 \par ETOFROM\tab \tab DS\tab 1\tab \tab ; %49 \par EPACKET\tab \tab DS\tab 1\tab \tab ; %4A \par EFCSHI\tab \tab DS\tab 1\tab \tab ; %4B \par EFCSLO\tab \tab DS\tab 1\tab \tab ; %4C \par \tab \tab DS\tab 19\tab \tab ; %4D\tab \par TABLE\tab \tab DS\tab 16\tab \tab ; %60-6F \par \par \par ;************************************************************************ \par ;\tab Register Definitions \par ;************************************************************************ \par ; \par ; RCV_STATUS: \par ; BIT0 - PC_RCV\tab \tab \tab \tab Receiving Serial Data from PC \par ; BIT1 - RF_DATA_WAIT\tab \tab \tab \tab Waiting for RF Data (Preamble rcvd) \par ; BIT2 - PC_TIMEOUT\tab \tab \tab \tab Timeout of PC Channel occurred \par ; BIT3 - RF_TIMEOUT\tab \tab \tab \tab Timeout of RF Channel occurred \par ; BIT4 - RF_ECHO_FAIL\tab \tab \tab \tab Timeout of RF Channel awaiting echo \par ; BIT5 - RF_ECHO_WAIT\tab \tab \tab \tab Waiting for echo on RF channel \par ; BIT6 - EMPTY \par ; BIT7 - BROADCAST\tab \tab \tab \tab TOFROM=00 (from PC) for RF Broadcast \par ; \par ;************************************************************* \par ; RAM bank 0 (RP=00H for working register usage. Physical * \par ; addresses 00H to 0FH). * \par ;************************************************************* \par \par PORT_GRP\tab \tab .EQU\tab 00h\tab ; Register Work Group 0 \par _P0\tab \tab .EQU\tab r0\tab ; Port 0, 4-bit address \par _P2\tab \tab .EQU\tab r2\tab ; Port 2, 4-bit address \par _P3\tab \tab .EQU\tab r3\tab ; Port 3, 4-bit address \par _P2COPY\tab \tab .EQU\tab r5\tab ; Port 2 shadow register \par \par ;************************************************************* \par ; RAM bank 6 (RP=60H for working register usage. Physical * \par ; addresses 60H to 6FH). * \par ; This bank holds the table for DC balancing the RF output * \par ; This table is stored in RAM to increase the lookup speed * \par ;************************************************************* \par \par _TABLE\tab \tab .EQU\tab 60h; \par NIBBLE0\tab \tab .EQU 15H\tab \tab ; NIBBLE = 0\tab \tab \tab 010101 \par NIBBLE1\tab \tab .EQU 31H ; NIBBLE = 1\tab \tab \tab \tab \tab 110001 \par NIBBLE2\tab \tab .EQU 32H \tab ; NIBBLE = 2\tab \tab \tab \tab 110010 \par NIBBLE3\tab \tab .EQU 23H \tab ; NIBBLE = 3\tab \tab \tab \tab 100011 \par NIBBLE4\tab \tab .EQU 34H \tab ; NIBBLE = 4\tab \tab \tab \tab 110100 \par NIBBLE5\tab \tab .EQU 25H \tab ; NIBBLE = 5\tab \tab \tab 100101 \par NIBBLE6\tab \tab .EQU 26H \tab \tab ; NIBBLE = 6\tab \tab \tab 100110 \par NIBBLE7\tab \tab .EQU 07H \tab \tab ; NIBBLE = 7\tab \tab \tab 000111 \par NIBBLE8\tab \tab .EQU 38H \tab \tab ; NIBBLE = 8\tab \tab \tab 111000 \par NIBBLE9\tab \tab .EQU 29H\tab \tab ; NIBBLE = 9\tab \tab \tab 101001 \par NIBBLE10\tab \tab .EQU 2AH ; NIBBLE = 10 101010 \par NIBBLE11\tab \tab .EQU 0BH ; NIBBLE = 11 001011 \par NIBBLE12\tab \tab .EQU 2CH ; NIBBLE = 12 101100 \par NIBBLE13\tab \tab .EQU 0DH ; NIBBLE = 13 001101 \par NIBBLE14\tab \tab .EQU 0EH \tab \tab ; NIBBLE = 14 001110 \par NIBBLE15\tab \tab .EQU\tab 1CH \tab ; NIBBLE = 15 011100 \par \par ;************************************************************* \par ; RAM bank F (RP=F0H for working register usage. Physical \par ; addresses F0H to FFH). \par ;************************************************************* \par \par CTRL_GRP\tab \tab .EQU\tab 0F0h\tab ; Register Work Group F \par _TMR\tab \tab .EQU r1\tab \tab ;Timer Mode Register \par _T1 \tab \tab .EQU r2\tab \tab ;Timer T1 \par _PRE1\tab \tab .EQU r3\tab \tab ;T1 Prescaler \par _P2M\tab \tab .EQU r6\tab \tab ;Port 2 Mode Register \par _P3M\tab \tab .EQU r7\tab \tab ;Port 3 Mode Register \par _P01M\tab \tab .EQU r8\tab \tab ;Port 0/1 Mode Register \par _IPR\tab \tab .EQU r9\tab \tab ;Interrupt Priority Register \par _IMR\tab \tab .EQU r11\tab \tab ;Interrupt Mask Register \par _SPL\tab \tab .EQU r15\tab \tab ;Stack Pointer Low \par \par ;************************************************************** \par ;* Constants Definitions \par ;************************************************************** \par SCRATCHPAD\tab \tab .EQU\tab 50h\tab ; \par PC_PRE\tab \tab .EQU\tab 07h\tab ; \par PC_BAUD\tab \tab .EQU\tab 156\tab ; 104us ~(9.6kbps) \par RF_BAUD\tab \tab .EQU\tab 156\tab ; 104us ~(9.6kbps) \par BIT0\tab \tab .EQU 01h\tab \tab ; Bit 0 mask \par BIT1\tab \tab .EQU 02h\tab \tab ; Bit 1 mask \par BIT2\tab \tab .EQU 04h\tab \tab ; Bit 2 mask \par BIT3\tab \tab .EQU 08h\tab \tab ; Bit 3 mask \par BIT4\tab \tab .EQU 10h\tab \tab ; Bit 4 mask \par BIT5\tab \tab .EQU 20h \tab \tab ; Bit 5 mask \par BIT6\tab \tab .EQU 40h\tab \tab ; Bit 6 mask \par BIT7\tab \tab .EQU 80h\tab \tab ; Bit 7 mask \par MASK0\tab \tab .EQU\tab 0Eh\tab ; Bit 0 Mask \par MASK1\tab \tab .EQU\tab 0Dh\tab ; Bit 1 Mask \par MASK_ID\tab \tab .EQU\tab 0Fh\tab ; ID Mask \par ON_232\tab \tab .EQU\tab 04h\tab ; Turn RS232 Drive On \par OFF_232\tab \tab .EQU\tab 0FBh\tab ; Turn RS232 Drive Off \par PTT_ON\tab \tab .EQU\tab 7Fh\tab ; Turn PTT (RF Xmt) On \par PTT_OFF\tab \tab .EQU\tab 80h\tab ; Turn PTT (RF Xmt) Off \par D3_ON\tab \tab .EQU\tab 0E0h\tab ; Turn on D3 \par D3_OFF\tab \tab .EQU\tab 10h\tab ; Turn off D3 \par D4_ON\tab \tab .EQU\tab 0D0h\tab ; Turn on D4 \par D4_OFF\tab \tab .EQU\tab 20h\tab ; Turn off D4 \par D5_ON\tab \tab .EQU\tab 0B0h\tab ; Turn off D5 \par D5_OFF\tab \tab .EQU\tab 40h\tab ; Turn off D5 \par RAM_TOP\tab \tab .EQU\tab 7Fh\tab ; Top of RAM \par RAM_BOT\tab \tab .EQU\tab 07h\tab ; Bottom of RAM \par RF_IMR\tab \tab .EQU 01h\tab \tab ; IMR for IRQ0 (RF_RCV) \par PC_IMR\tab \tab .EQU\tab 04h\tab ; IMR for IRQ2 (PC_RCV) \par PCRF_IMR\tab \tab .EQU\tab 05h\tab ; IMR for IRQ2/IRQ0 \par TMR1_IMR\tab \tab .EQU\tab 20h\tab ; IMR for IRQ5 (Timer1) \par TMR0_IMR\tab \tab .EQU\tab 10h\tab ; IMR for IRQ4 (Timer0) \par TMR10_IMR\tab \tab .EQU\tab 30h\tab ; IMR for IRQ5/IRQ4 \par PCTMR0_IMR\tab \tab .EQU\tab 14h\tab ; IMR for IRQ2/IRQ4 \par RFTMR0_IMR\tab \tab .EQU\tab 11h\tab ; IMR for IRQ2/IRQ4 \par RFTMR1_IMR\tab \tab .EQU\tab 21h\tab ; IMR for IRQ2/IRQ5 \par \par ;************************************************************************ \par ; Interrupt Vector Table \par ;************************************************************************ \par \par \tab SEGMENT code \par \tab \par \tab VECTOR\tab \tab IRQ0=\tab RF_RCV\tab \tab \tab \par \tab VECTOR\tab \tab IRQ1=\tab START \par \tab VECTOR\tab \tab IRQ2=\tab PC_RCV\tab \tab \par \tab VECTOR\tab \tab IRQ3=\tab START \par \tab VECTOR\tab \tab IRQ4=\tab TIMER0 \par \tab VECTOR\tab \tab IRQ5=\tab TIMER1\tab \tab \tab \par \tab VECTOR\tab \tab RESET=\tab \tab START \par \tab \par ;************************************************************************ \par ;\tab Initialization Section \par ;\tab Functions: \par ;\tab 1) Initialize I/O ports \par ;\tab 2) Clear memory (RAM) \par ;\tab 3) Initialize DC Balance Table into RAM \par ;\tab 4) Retrieve and process Protocol CCA address \par ;\tab 5) Initialize Stack \par ;\tab 6) Initialize interrupts and set interrupt priority \par ;************************************************************************ \par \par START: \par \tab \tab srp\tab #0h\tab \tab \tab ; \par \tab \tab ld\tab P2COPY,#0F0h\tab \tab \tab ; LEDs off, PTT off \par \tab \tab ld\tab P0COPY,#02h\tab \tab \tab ; serial ports High, SHDN_ High \par \tab \tab ld\tab P2, P2COPY\tab \tab \tab ; \par \tab \tab ld\tab P0, P0COPY\tab \tab \tab ; \par \tab \tab ld\tab P3M,#01h \tab \tab \tab ; Port3 -> Digital Inputs \par \tab \tab ld\tab P2M,#00fh \tab \tab \tab ; Port2 -> P24,P25,P26 Outputs \par \tab \tab ld\tab P01M,#04h\tab \tab \tab ; Port1 -> P01-P03 Inputs \par \tab \tab srp\tab #CTRL_GRP\tab \tab \tab ; \par \par \tab \tab ld\tab r15,#RAM_BOT \tab \tab \tab ; Clear RAM from 07h to 7Fh \par initram: \par \tab \tab clr\tab @r15\tab \tab \tab ; RAM_BOT = 07h \par \tab \tab inc\tab r15 \tab \tab \tab ; RAM_TOP = 7Fh \par \tab \tab cp\tab r15,#RAM_TOP+1\tab \tab \tab ; \par \tab \tab jr\tab nz,initram\tab \tab \tab ; \par \par \tab \tab srp\tab #_TABLE\tab \tab \tab ; This section initializes the \par \tab \tab ld\tab r0,#NIBBLE0\tab \tab \tab ; BALANCE TABLE into RAM memory \par \tab \tab ld\tab r1,#NIBBLE1\tab \tab \tab ; \par \tab \tab ld\tab r2,#NIBBLE2\tab \tab \tab ; \par \tab \tab ld\tab r3,#NIBBLE3\tab \tab \tab ; \par \tab \tab ld\tab r4,#NIBBLE4\tab \tab \tab ; \par \tab \tab ld\tab r5,#NIBBLE5\tab \tab \tab ; \par \tab \tab ld\tab r6,#NIBBLE6\tab \tab \tab ; \par \tab \tab ld\tab r7,#NIBBLE7\tab \tab \tab ; \par \tab \tab ld\tab r8,#NIBBLE8\tab \tab \tab ; \par \tab \tab ld\tab r9,#NIBBLE9\tab \tab \tab ; \par \tab \tab ld\tab r10,#NIBBLE10\tab \tab \tab ; \par \tab \tab ld\tab r11,#NIBBLE11\tab \tab \tab ; \par \tab \tab ld\tab r12,#NIBBLE12\tab \tab \tab ; \par \tab \tab ld\tab r13,#NIBBLE13\tab \tab \tab ; \par \tab \tab ld\tab r14,#NIBBLE14\tab \tab \tab ; \par \tab \tab ld\tab r15,#NIBBLE15\tab \tab \tab ; \par \par \tab \tab or\tab P2COPY,P2\tab \tab \tab ; Retrieve and process board addr \par \tab \tab ld\tab MY_ADDR,P2COPY\tab \tab \tab ; \par \tab \tab com\tab MY_ADDR\tab \tab \tab ; \par \tab \tab inc\tab MY_ADDR\tab \tab \tab ; \par \tab \tab and\tab MY_ADDR,#MASK_ID\tab \tab \tab ; \par \tab \tab ld\tab FROMFROM,MY_ADDR\tab \tab \tab ; \par \tab \tab swap\tab FROMFROM\tab \tab \tab ; \par \tab \tab or\tab FROMFROM,MY_ADDR\tab \tab \tab ; \par \tab \tab \par \tab \tab ld\tab SPL,#80h\tab \tab \tab ; Initialize stack \par \tab \tab ld\tab IPR,#%20 \tab \tab \tab ; interrupt priority: 3>5>2>0>4>1 \par \tab \tab ld\tab IMR,#PCRF_IMR\tab \tab \tab ; enable IRQ0 and IRQ2 \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \par ;************************************************************************ \par ;\tab Main Program \par ;************************************************************************ \par \par MAIN: \par \tab \tab or\tab P2COPY,#70h\tab \tab \tab ; Disable all diodes \par \tab \tab ld\tab P2,P2COPY\tab \tab \tab ; \par \tab \tab ei \tab \tab \tab \tab ; enable interrupts \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait for next interrupt \par \tab jr\tab \tab MAIN\tab \tab \tab ; \par \par ;************************************************************************ \par ;\tab Timeout Interrupt Service \par ;\tab INPUT: RCV_STATUS \par ;\tab DESCRIPTION: Uses RCV_STATUS register to determine cause of \par ;\tab a data communications timeout of the PC or RF ports and resets \par ;\tab the communications accordingly.\tab \tab \tab \tab \tab \tab \par ;************************************************************************ \par TIMER0: \par \tab \tab clr\tab tmr\tab \tab \tab ; \par \tab \tab tm\tab RCV_STATUS,#BIT7\tab \tab \tab ; test for Broadcast Echo \par \tab \tab jr\tab nz,BROADCAST\tab \tab \tab \tab ; \par \tab \tab cp\tab RCV_STATUS,#BIT0\tab \tab \tab ; test for PC Data fail \par \tab \tab jr\tab z,PC_DATA_FAIL\tab \tab \tab ;\tab \tab \par \tab \tab tm\tab RCV_STATUS,#BIT5\tab \tab \tab ; test for Echo fail \par \tab \tab jr\tab nz,RF_ECHO_FAIL\tab \tab \tab ; \par \tab \tab tm\tab RCV_STATUS,#BIT1\tab \tab \tab ; test for RF Data Fail \par \tab \tab jr\tab nz,RF_DATA_FAIL\tab \tab \tab ; \par \tab \tab call\tab DELAY5MS\tab \tab \tab ; delay 5ms before returning \par \tab \tab ld\tab IMR,#PCRF_IMR\tab \tab \tab ; enable IRQ0 and IRQ2 \par \tab \tab clr\tab RCV_STATUS\tab \tab \tab ; \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts\tab \tab \tab \tab \par \tab \tab iret\tab \tab \tab \tab ; \par RF_DATA_FAIL: \par \tab \tab call\tab DELAY5MS\tab \tab \tab ; 5 ms delay \par \tab \tab jp\tab RF_EXIT\tab \tab \tab ; exit RF_RCV module \par RF_ECHO_FAIL: \par \tab \tab or\tab RCV_STATUS,#BIT4\tab \tab \tab ; RF_Echo Timeout \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab jp\tab RF_RETRY\tab \tab \tab ; retry \par PC_DATA_FAIL: \par \tab \tab jp\tab PC_EXIT\tab \tab \tab ; exit PC_RCV module \par BROADCAST: \par \tab \tab call\tab PC_ECHO\tab \tab \tab ; \par \tab \tab jp\tab PC_WAIT10\tab \tab \tab ; wait 10ms for next byte\tab \tab \tab \tab \tab \tab \par TIMEOUT10: \par \tab \tab ld\tab PRE0,#0F3h\tab \tab \tab ; 10ms Timeout \par \tab \tab ld\tab T0,#0FAh\tab \tab \tab ; \par \tab \tab ld\tab TMR,#03h\tab \tab \tab ; \par \tab \tab ret ; \par TIMEOUT1: \par \tab \tab ld\tab PRE0,#3Ch\tab \tab \tab ; 1ms Timeout \par \tab \tab ld\tab T0,#14h\tab \tab \tab ; \par \tab \tab ld\tab TMR,#03h\tab \tab \tab ; \par \tab \tab ret \tab \tab \tab \tab ; \par \par ;*********************************************************************** \par ;\tab PC_RCV (Interrupt Service) \par ;\tab INPUT: Serial Data on P31 \par ;\tab OUTPUT: SERDATA \tab \tab \tab \tab \tab \tab \tab \par ;\tab DESCRIPTION: Enter on falling edge of P31 (IRQ2) \par ;\tab After a half bittime P31 is sampled again to validate \par ;\tab the Start bit. Then IRQ5 is enabled and T1 is setup \par ;\tab for bittime delay in continous mode. \par ;*********************************************************************** \par \par bitcnt\tab \tab .EQU r0\tab \tab \tab ; # of bits/word \par rbuf\tab \tab .EQU\tab r1\tab \tab ; buffer \par hbcnt\tab \tab .EQU\tab r2\tab \tab ; halfbit count \par loopcnt\tab \tab .EQU\tab r12\tab \tab ; \par rtxcnt\tab \tab .EQU\tab r13\tab \tab ; RF Retry count \par \par PC_RCV: \par \tab \tab srp\tab #SCRATCHPAD\tab \tab \tab ; \par \tab \tab push\tab IMR\tab \tab \tab ; save present interrupt mask \par \tab \tab ld\tab PRE1,#07h\tab \tab \tab ; Modulo-N, PSC=1, TCLK=SCLK/4=1us \par \tab \tab ld\tab T1,#PC_BAUD\tab \tab \tab ; Baudrate = 9600 \par \tab \tab and\tab P2COPY,#D3_ON\tab \tab \tab ; turn on PCRCV diode \par \tab \tab ld\tab P2,P2COPY\tab \tab \tab ; \par \tab \tab ld\tab hbcnt,#04\tab \tab \tab ; delay to half bit point \par HALF_BIT: \par \tab \tab djnz\tab hbcnt,HALF_BIT \tab \tab \tab ; total delay ~ 25uS \par \tab \tab tm\tab P3,#02h\tab \tab \tab ; take Sample on P31: RX=0? \par \tab \tab jp\tab nz,PC_FAIL\tab \tab \tab ; if zero, Start bit is valid \par START_OK: \par \tab \tab or\tab TMR,#0ch\tab \tab \tab ; load and enable T1 \par \tab \tab ld\tab IMR,#TMR1_IMR\tab \tab \tab ; enable IRQ5 \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ei\tab \tab \tab \tab ; enable interrupts \par \tab \tab ld\tab bitcnt,#08h\tab \tab \tab ; number of data bits/word \par RECEIVE_LP: \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait for next bit \par \tab \tab tm\tab P3,#BIT1\tab \tab \tab ; RX=0? \par \tab \tab jr\tab z,ZERO_IN\tab \tab \tab ; if zero, then reset carry bit \par \tab \tab scf\tab \tab \tab \tab ; if one, then set carry bit \par \tab \tab jr\tab COM_IN\tab \tab \tab ; "1" into buffer \par ZERO_IN: \par \tab \tab rcf\tab \tab \tab \tab ; reset carry; "0" into buffer \par COM_IN: \par \tab \tab rrc\tab rbuf\tab \tab \tab ; carry into MSB, LSB into Carry \par \tab \tab djnz\tab bitcnt,RECEIVE_LP \tab \tab \tab ; max loop delay = 108 SCLK (27us) \par GET_STOP: \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait for Stop Bit \par \tab \tab clr\tab TMR\tab \tab \tab ; \par \tab \tab pop\tab IMR\tab \tab \tab ; \par \tab \tab tm\tab P3,#BIT1\tab \tab \tab ; test Stop Bit \par \par \tab \tab jp\tab z,PC_FAIL\tab \tab \tab ; use BYTECNT to determine \par \tab \tab cp\tab BYTECNT,#0h\tab \tab \tab ; which word was received \par \tab \tab jr\tab z,PCTOFROM\tab \tab \tab ; \par \tab \tab cp\tab BYTECNT,#1h\tab \tab \tab ; \par \tab \tab jr\tab z,PCPACKET\tab \tab \tab ; \par \tab \tab cp\tab BYTECNT,#2h\tab \tab \tab ; \par \tab \tab jr\tab z,PCSIZE\tab \tab \tab ; \par \tab \tab jr\tab PCDATA\tab \tab \tab ; \par \par PCTOFROM: \par \tab \tab ld\tab DATA_PTR,#24h\tab \tab \tab ; if TO/FROM indicates 'special msg' \par \tab \tab ld\tab TOFROM,rbuf\tab \tab \tab ; no echo is returned and code \par \tab \tab cp\tab rbuf,#0h\tab \tab \tab ; waits for next byte. \par \tab \tab jr\tab z,SPCLMSG\tab \tab \tab ; else go to LOCAL \par \tab \tab cp\tab rbuf,FROMFROM\tab \tab \tab ; \par \tab \tab jr\tab z,SPCLMSG\tab \tab \tab ; \par \tab \tab inc\tab BYTECNT\tab \tab \tab ; \par \tab \tab call\tab PC_ECHO\tab \tab \tab ; send echo to PC \par \tab \tab jp\tab PC_WAIT\tab \tab \tab ; wait for next byte \par SPCLMSG: \par \tab \tab inc\tab BYTECNT \tab \tab \tab ; Special Message \par \tab \tab ld\tab RCV_STATUS,#BIT7\tab \tab \tab ; RCV_STATUS = Broadcast \par \tab \tab jp\tab PC_WAIT1\tab \tab \tab ; wait 1ms for next byte \par PCPACKET: \par \tab \tab ld\tab PACKET,rbuf\tab \tab \tab ; Save PCPACKET \par \tab \tab inc\tab BYTECNT\tab \tab \tab ; \par \tab \tab jp\tab PC_WAIT10\tab \tab \tab ; wait 10ms for next byte \par PCSIZE: \par \tab \tab ld\tab DATA_PTR,#24h\tab \tab \tab ; Save PCSIZE \par \tab \tab ld\tab SIZE,rbuf\tab \tab \tab ; \par \tab \tab ld\tab COPYSIZE,rbuf\tab \tab \tab ; \par \tab \tab inc\tab BYTECNT\tab \tab \tab ; \par \tab \tab jp\tab PC_WAIT10\tab \tab \tab ; wait 10ms for next byte \par PCDATA: \par \tab \tab ld\tab @DATA_PTR,rbuf\tab \tab \tab ; store message DATA \par \tab \tab inc\tab DATA_PTR\tab \tab \tab ; increment RAM address \par \tab \tab dec\tab COPYSIZE\tab \tab \tab ; \par \tab \tab jr\tab z,PCPROC\tab \tab \tab ; \par \tab \tab jp\tab PC_WAIT10\tab \tab \tab ; wait 10ms for next byte \par PCPROC: \par \tab \tab clr\tab TMR\tab \tab \tab ; Process Message Data \par \tab \tab cp\tab DATA_PTR,#44h\tab \tab \tab ; check if size > 32 bytes \par \tab \tab jr\tab gt,MSG_LONG\tab \tab \tab ; message is too long \par \tab \tab cp\tab PACKET,#0h\tab \tab \tab ; check if PACKET = 0 \par \tab \tab jr\tab z,XMT_SPECIAL\tab \tab \tab ; message is 'special' \par \tab \tab call\tab FCS\tab \tab \tab ; calculate FCS \par \tab \tab clr\tab BYTECNT\tab \tab \tab ; \par \tab \tab clr\tab TMR \tab \tab \tab ; \par \tab \tab call\tab DELAY5MS\tab \tab \tab ; \par \tab \tab ld\tab rtxcnt,#8h\tab \tab \tab ; ld transmit counter = 8 \par \tab \tab cp\tab TOFROM,#0h\tab \tab \tab ; Check TOFROM = 0 for 'broadcast' \par \tab \tab jr\tab z,RF_XMT_BCST\tab \tab \tab ; message \par RF_XMT_CALL: \par \tab \tab call\tab RF_XMT\tab \tab \tab ; transmit RF Data \par \tab \tab call\tab DELAY3MS\tab \tab \tab ; delay 6ms before 10ms timeout \par \tab \tab call\tab DELAY3MS\tab \tab \tab ;\tab \par RFECHO_WAIT: \par \tab \tab call\tab TIMEOUT10\tab \tab \tab ; 10ms timeout for RF_ECHO \par \tab \tab ld\tab IMR,#RFTMR0_IMR\tab \tab \tab ; Enable IRQ0 and IRQ2 \par \tab \tab clr\tab IRQ\tab \tab \tab ; \par \tab \tab iret\tab \tab \tab \tab ; \par RF_XMT_BCST: \par \tab \tab call\tab RF_XMT\tab \tab \tab ; RF Broadcast 8X \par \tab \tab call\tab DELAY100\tab \tab \tab ; 100ms delay between broadcasts \par \tab \tab djnz\tab rtxcnt,RF_XMT_BCST ; \par \tab \tab call\tab PC_NAK\tab \tab \tab ; 'NAK' sent to PC after xmt \par \tab \tab jp\tab PC_EXIT\tab \tab \tab ; is completed. \par TIMER1: \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab iret\tab \tab \tab \tab ; \par XMT_SPECIAL:\tab \tab \tab \tab \tab \tab ; Transmit response for 'Special' \par \tab \tab or\tab P0COPY,#ON_232\tab \tab \tab ; Enable 232 Drive \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab ld\tab SERDATA,TOFROM\tab \tab \tab ; Echo \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send echo to PC \par \tab \tab cp\tab DATABUF,#30h\tab \tab \tab ; Software Reset \par \tab \tab jr\tab z,RESET\tab \tab \tab ; \par \tab \tab cp\tab DATABUF,#31h\tab \tab \tab ; Unit Address \par \tab \tab jr\tab z,SEND_ADDR\tab \tab \tab ; send unit node address \par \tab \tab cp\tab DATABUF,#32h\tab \tab \tab ; Battery Status \par \tab \tab jr\tab z,SEND_BATT\tab \tab \tab ; send battery status \par \tab \tab cp\tab DATABUF,#33h\tab \tab \tab ; Self Test \par \tab \tab jr\tab z,SELF_TEST\tab \tab \tab ; self Self Test pass/fail \par \tab \tab cp\tab DATABUF,#34h\tab \tab \tab ; Set Address \par \tab \tab jr\tab z,SET_ADDR\tab \tab \tab ; s/w setting of node address \par MSG_LONG: \par \tab \tab ld\tab SPCL_DATA,#30h\tab \tab \tab ; Message >32 Bytes \par \tab \tab jr\tab XMT_SPCL\tab \tab \tab ; \par RESET: \par \tab \tab jp\tab START\tab \tab \tab ; Software Reset \par SEND_ADDR: \par \tab \tab ld\tab SPCL_DATA,#35h\tab \tab \tab ; Send Address \par \tab \tab jr\tab XMT_SPCL\tab \tab \tab ; \par SELF_TEST: \par \tab \tab call\tab RAMTEST\tab \tab \tab ; Self Test \par \tab \tab jp\tab START\tab \tab \tab ; \par SEND_BATT: \par \tab \tab ld\tab SPCL_DATA,#32h\tab \tab \tab ; Assume battery ok \par \tab \tab jr\tab XMT_SPCL\tab \tab \tab ; \par SET_ADDR: \par \tab \tab dec\tab DATA_PTR\tab \tab \tab ; S/W setting of Address \par \tab \tab ld\tab MY_ADDR,@DATA_PTR\tab \tab \tab ; \par \tab \tab ld\tab FROMFROM,MY_ADDR\tab \tab \tab ; \par \tab \tab swap\tab FROMFROM\tab \tab \tab ; \par \tab \tab or\tab FROMFROM,MY_ADDR\tab \tab \tab ; \par \tab \tab ld\tab SPCL_DATA,#35h\tab \tab \tab ; \par \tab \tab jr\tab PC_EXIT\tab \tab \tab ; \par XMT_SPCL: \par \tab \tab ld\tab SERDATA,FROMFROM\tab \tab \tab ; send FROMFROM \par \tab \tab call\tab PC_XMT\tab \tab \tab ; \par XMT_SPCL1: \par \tab \tab ld\tab SERDATA,#0h\tab \tab \tab ; send '00h' to PC \par \tab \tab call\tab PC_XMT\tab \tab \tab ; \par \tab \tab cp\tab DATABUF,#34\tab \tab \tab ; \par \tab \tab jr\tab nz,XMT_SPCL2\tab \tab \tab ; \par \tab \tab ld\tab SERDATA,#0h\tab \tab \tab ; send '00h' to PC \par \tab \tab call\tab PC_XMT\tab \tab \tab ; \par XMT_SPCL2: \par \tab \tab ld\tab SERDATA,#01h\tab \tab \tab ; send '01h' to PC \par \tab \tab call\tab PC_XMT\tab \tab \tab ; \par \tab \tab ld\tab SERDATA,SPCL_DATA\tab \tab \tab ; send status byte to PC \par \tab \tab call\tab PC_XMT\tab \tab \tab ; \par \tab \tab jr\tab PC_EXIT\tab \tab \tab ; exit PC_RCV module \par PC_WAIT: \par \tab \tab ld\tab RCV_STATUS,#BIT0\tab \tab \tab ; RCV_STATUS = PC_RCV \par \tab \tab ld\tab IMR,#PCTMR0_IMR \tab \tab \tab ; Enable IRQ2 and IRQ4 \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab iret\tab \tab \tab \tab ; return to MAIN loop \par PC_WAIT10: \par \tab \tab ld\tab RCV_STATUS,#BIT0\tab \tab \tab ; RCV_STATUS = PC_RCV \par \tab \tab call\tab TIMEOUT10\tab \tab \tab ; 10ms timeout \par \tab \tab ld\tab IMR,#PCTMR0_IMR\tab \tab \tab ; Enable IRQ2 and IRQ4 \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab iret\tab \tab \tab \tab ; return to MAIN loop \par PC_WAIT1: \par \tab \tab call\tab TIMEOUT1\tab \tab \tab ; 1ms timeout \par \tab \tab ld\tab IMR,#PCTMR0_IMR\tab \tab \tab ; enable IRQ2 and IRQ4 \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab iret\tab \tab \tab \tab ; return to MAIN loop \par PC_FAIL; \par \tab \tab clr\tab TMR\tab \tab \tab ; exit PC_RCV \par \tab \tab pop\tab IMR\tab \tab \tab ; reload initial IMR and TMR \par PC_EXIT: \par \tab \tab and\tab P0COPY,#OFF_232\tab \tab \tab ; Turn off 232 drive \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab clr\tab RCV_STATUS\tab \tab \tab ; \par \tab \tab clr\tab BYTECNT\tab \tab \tab ; \par \tab \tab ld\tab IMR,#PCRF_IMR\tab \tab \tab ; enable IRQ0 and IRQ2 \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab iret \tab \tab \tab \tab ; return to MAIN loop \par PC_ECHO: \par \tab \tab ld\tab SERDATA,TOFROM\tab \tab \tab ; Echo TOFROM back to PC \par \tab \tab or\tab P0COPY,#ON_232\tab \tab \tab ; Enable 232 drive \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab call\tab PC_XMT\tab \tab \tab ; Send Echo \par \tab \tab and\tab P0COPY,#OFF_232\tab \tab \tab ; Disable 232 drive \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab ret\tab \tab \tab \tab ; \par \par ;************************************************************************ \par ;\tab Transmit RS232 Data\tab \tab \tab \tab (CALL) \par ;\tab Input: SERDATA \par ;\tab Output: Serial Data on P01 \par ;\tab Format: | start | data | stop | \par ;\tab \tab start = active Low \par ;\tab \tab data = 8 bits \par ;\tab \tab stop = active High \par ;*********************************************************************** \par xbitcnt\tab \tab .EQU r3\tab \tab \tab ; \par data1\tab \tab .EQU\tab r4\tab \tab ; \par data2\tab \tab .EQU\tab r5\tab \tab ; \par dummy\tab \tab .EQU\tab r6\tab \tab ; \par \par PC_XMT: \par \tab \tab push\tab IMR\tab \tab \tab ; \par \tab \tab push\tab RP\tab \tab \tab ; \par \tab \tab srp\tab #SCRATCHPAD\tab \tab \tab ; \par TX_LP: \par \tab \tab or\tab P0COPY,#BIT1 \tab \tab \tab ; insure output is High \par \tab \tab ld\tab P0,P0COPY \tab \tab \tab ; \par \tab \tab ld\tab data1,SERDATA\tab \tab \tab ; load SERDATA into temp register \par \tab \tab ld\tab data2,#1\tab \tab \tab ; shift in stop bit \par \par \tab \tab rcf\tab \tab \tab \tab ; reset Carry \par \tab \tab rlc\tab data1\tab \tab \tab ; start bit into LSB \par \tab \tab rlc\tab data2\tab \tab \tab ; now all bits are in \par \par \tab \tab ld\tab xbitcnt,#10\tab \tab \tab ; number of bits (start,data,stop) \par \tab \tab ld\tab PRE1,#PC_PRE\tab \tab \tab ; \par \tab \tab ld\tab T1,#PC_BAUD \tab \tab \tab ; PC Baudrate = 9600 ~ 104us \par \tab \tab ld\tab TMR,#0ch \tab \tab \tab ; load and enable timer \par \tab \tab ld\tab IMR,#TMR1_IMR \tab \tab \tab ; enable IRQ5 bittime delay on T1 \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ei\tab \tab \tab \tab ; enable interrupts \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 104us to send next bit \par SEND_LP: \par \tab \tab rrc data2\tab \tab \tab \tab ; LSB into Carry \par \tab \tab rrc data1\tab \tab \tab \tab ; Carry into MSB, LSB into Carry \par \tab \tab jr nc,ZERO_OUT\tab \tab \tab \tab ; data bit zero? \par \tab \tab or P0COPY,#BIT1\tab \tab \tab \tab ; TX=1, '1' on output port \par \tab \tab jr COM_OUT\tab \tab \tab \tab ; \par ZERO_OUT: \par \tab \tab and P0COPY,#MASK1\tab \tab \tab \tab ; TX=0, '0' on output port \par \tab \tab ld dummy,#0\tab \tab \tab \tab ; balance loop, 10 SCLK \par COM_OUT: \par \tab \tab ld P0,P0COPY\tab \tab \tab \tab ; Output at port, 50 SCLK delay (TX=1) \par \tab \tab nop \par \tab \tab halt\tab \tab \tab \tab ; wait 104us to send next bit \par \tab \tab djnz\tab xbitcnt,SEND_LP\tab \tab \tab ; \par \tab \tab clr\tab TMR\tab \tab \tab ; \par \tab \tab pop\tab RP\tab \tab \tab ; \par \tab \tab pop\tab IMR\tab \tab \tab ; \par \tab \tab ret\tab \tab \tab \tab ; \par \par ;************************************************************************ \par ; \tab RF_XMT: \par ; \tab Performs transmission of RF Data Stream \par ;\tab Input: STARTBYTE,TOFROM,PACKET,SIZE,DATABUF,FCSHI,FCSLO \par ;\tab \tab (RAM Address 20h...) \par ;\tab Output: Serial Data on P01 \par ;\tab Protocol: |0x55|TOFROM|PACKET|SIZE|0x02|DATA...|0x03|FCSHI|FCSLO| \par ; \par ;*********************************************************************** \par rf_ptr\tab \tab \tab .EQU\tab r0\tab \tab ; \par rfsize\tab \tab \tab .EQU\tab r1\tab \tab ; \par rfbits\tab \tab \tab .EQU\tab r2\tab \tab ; \par rfpass\tab \tab \tab .EQU\tab r3\tab \tab ; \par rfretry\tab \tab \tab .EQU\tab r4\tab \tab ; \par table_ls\tab \tab \tab .EQU\tab r6\tab \tab ; \par table_ms\tab \tab \tab .EQU\tab r7\tab \tab ; \par dcb_ls\tab \tab \tab .EQU\tab r8\tab \tab ; \par dcb_ms\tab \tab \tab .EQU\tab r9\tab \tab ; \par loop_cnt\tab \tab \tab .EQU\tab r10\tab \tab ; \par temp1\tab \tab \tab .EQU\tab r11\tab \tab ; \par \par RF_XMT: \par \tab \tab srp\tab #SCRATCHPAD\tab \tab \tab ; \par \tab \tab and\tab P2COPY,#PTT_ON\tab \tab \tab ; Clear PTT to enable RF Xmit \par \tab \tab ld\tab P2,P2COPY\tab \tab \tab ; \par \tab \tab call\tab RF_TRAIN\tab \tab \tab ; send preamble (DC Bal Training)\tab \tab \tab \tab \tab \tab \tab \par \tab \tab ld\tab rf_ptr,#20h\tab \tab \tab ; pointer to start of data buffer \par \tab \tab ld\tab rfsize,SIZE\tab \tab \tab ; # of bytes to send \par \tab \tab add\tab rfsize,#4\tab \tab \tab ; Add Headers, FCS, \par \tab \tab ld\tab STARTBYTE,#55h\tab \tab \tab ; STARTBYTE = '55h' \par XMT_LOOP: \par \tab \tab ld\tab SERDATA,@rf_ptr\tab \tab \tab ; XMT RF Data Loop \par \tab \tab call\tab RF_SEND\tab \tab \tab ; send byte \par \tab \tab inc\tab rf_ptr\tab \tab \tab ; increment data pointer \par \tab \tab djnz\tab rfsize,XMT_LOOP\tab \tab \tab ; \par \tab \tab ld\tab SERDATA,FCSLO\tab \tab \tab ; send FCSLO \par \tab \tab call\tab RF_SEND\tab \tab \tab ; \par \tab \tab ld\tab SERDATA,FCSHI\tab \tab \tab ; send FCSHI \par \tab \tab call\tab RF_SEND\tab \tab \tab ; \par \tab \tab or\tab P2COPY,#PTT_OFF \tab \tab \tab ; Disable RF Transmit \par \tab \tab ld\tab P2,P2COPY\tab \tab \tab ; \par \tab \tab ld\tab loop_cnt,#0FFh\tab \tab \tab ; \par \tab \tab or\tab RCV_STATUS,#BIT5\tab \tab \tab ; RCV_STATUS = RF_ECHO_WAIT \par \tab \tab call\tab DELAY3MS\tab \tab \tab ; delay 3ms \par \tab \tab ret\tab \tab \tab \tab ; \par RF_SEND: \par \tab \tab ld\tab rfbits,#6\tab \tab \tab ; # of bits/pass \par \tab \tab ld\tab rfpass,#2\tab \tab \tab ; # of passes (2 6-bit xmits) \par \tab \tab push\tab IMR\tab \tab \tab ; \par \tab \tab ld\tab IMR,#TMR1_IMR\tab \tab \tab ; enable IRQ5 bittime dela\plain\f4\fs20 y on T1 \par \plain\f3\fs20 \tab \tab ld\tab PRE1,#07h\tab \tab \tab ; continous mode T1, TCLK=SLCK/4=1us \par \tab \tab ld\tab T1,#RF_BAUD \tab \tab \tab ; set T1 for baud rate 9600 \par \tab \tab or\tab TMR,#0ch\tab \tab \tab ; load and enable timer \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ei\tab \tab \tab \tab ; enable interrupts \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 104us to send next bit \par \tab \tab or\tab P0COPY,#1\tab \tab \tab ; send start bit \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par DC_BAL: \par \tab \tab ld\tab table_ls,SERDATA\tab \tab \tab ; Retrieve DC Balanced Value \par \tab \tab ld\tab table_ms,table_ls\tab \tab \tab ; for LS and MS Nibble of \par \tab \tab and\tab table_ls,#MASK_ID\tab \tab \tab ; Data \par \tab \tab ld\tab dcb_ls,TABLE(table_ls); r8 = LS (6 bits) \par \tab \tab swap\tab table_ms\tab \tab \tab ; \par \tab \tab and\tab table_ms,#MASK_ID\tab \tab \tab ; \par \tab \tab ld\tab dcb_ms,TABLE(table_ms); r9 = MS (6 bits) \par RFTX_LOOP: \par \tab \tab rrc\tab dcb_ls\tab \tab \tab ; Inverted logic. \par \tab \tab jr\tab nc,ONE_OUT\tab \tab \tab ; \par \tab \tab and\tab P0COPY,#MASK0\tab \tab \tab ; data=1 sends a 0 on RTX. \par \tab \tab jr\tab RF_OUT\tab \tab \tab ; \par ONE_OUT: \par \tab \tab or\tab P0COPY,#BIT0\tab \tab \tab ; \par RF_OUT: \par \tab \tab clr\tab IRQ\tab \tab \tab ; Transmit loop (12 bits) \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 104us to send next bit \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab djnz\tab rfbits,RFTX_LOOP\tab \tab \tab ; 6 bits/pass \par \tab \tab ld\tab dcb_ls,dcb_ms\tab \tab \tab ; \par \tab \tab ld\tab rfbits,#6\tab \tab \tab ; 2 passes \par \tab \tab djnz\tab rfpass,RFTX_LOOP\tab \tab \tab ; \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 104us to send next bit \par \par \tab \tab and\tab P0COPY,#0FEh\tab \tab \tab ; send stop bit \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab pop\tab IMR\tab \tab \tab ; \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ret\tab \tab \tab \tab ; \par RF_TRAIN: \par \tab \tab push\tab IMR\tab \tab \tab ; Output 24 bit alternating \par \tab \tab ld\tab rfpass,#12\tab \tab \tab ; 1,0,1,0 pulses to 'train' \par \tab \tab ld\tab IMR,#TMR1_IMR\tab \tab \tab ; the DC Balance of the RF \par \tab \tab ld\tab PRE1,#07h\tab \tab \tab ; Transmitter (preamble) \par \tab \tab ld\tab T1,#RF_BAUD\tab \tab \tab ; RF_BAUD = 9600 \par \tab \tab or\tab TMR,#0ch\tab \tab \tab ; load and enable timer \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ei\tab \tab \tab \tab ; enable interrupts \par TRAIN_LOOP: \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 104us to send next bit \par \tab \tab or\tab P0COPY,#1\tab \tab \tab ; send '1' \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ei\tab \tab \tab \tab ; enable interrupts \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 104us to send next bit \par \tab \tab and\tab P0COPY,#0FEh\tab \tab \tab ; send a '0' \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab djnz\tab rfpass,TRAIN_LOOP\tab \tab \tab ; loop 12 times \par \tab \tab pop\tab IMR\tab \tab \tab ; \par \tab \tab ret\tab \tab \tab \tab ; \par \par ;***************************************************************************** \par ; \tab RF_RCV: \par ; \tab Entry: Enter module from IRQ0, falling edge of P32 \par ;\tab INPUT: Serial Data on P32\tab \tab \tab \tab \tab \tab \tab \tab \tab \par ; \tab Definition: Module reacts to incoming data on P31 RF serial input. Input \par ;\tab should be 1 start bit, 12 data bits, 1 stop bit. Each bit is sampled \par ;\tab 11X for verification. After 6 data bits have been received, the data \par ;\tab is run through the 6to4 module to convert from 12 bit data format to \par ;\tab 8 bit data format. After 12 bits are received, the data is combined \par ;\tab into a 8-bit word and stored in RAM (0x20 to 0x45) \par ;\tab Memory map for RAM is as follows:\tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \par ;\tab \tab Start\tab Finish Reg\tab \tab Description\tab \tab \tab \tab \tab \tab \par ;\tab \tab 0x20\tab 0x20\tab r0\tab RF Start Byte (0x55) \par ;\tab \tab 0x21\tab 0x21\tab r1\tab RF TO/FROM \par ;\tab \tab 0x22\tab 0x22\tab r2\tab RFPACKET#\tab \tab \tab \tab \tab \tab \par ;\tab \tab 0x23\tab 0x23\tab r3\tab RF Size \par ;\tab \tab 0x24\tab 0x24\tab r4\tab Start byte (0x02) \par ;\tab \tab 0x24\tab 0x43\tab \tab RF Data \par ;\tab \tab 0x44\tab 0x44\tab r4\tab Stop byte (0x03) \par ;\tab \tab 0x45\tab 0x45\tab r5\tab RFFCSHI\tab \tab \par ;\tab \tab 0x46\tab 0x46\tab r6\tab RFFCSLO\tab \tab \par ; After each byte is received, the module will exit to the MAIN loop \par ;\tab to await the next interrupt. If the wait loop times out (1ms), the \par ;\tab module will be exited and an error flag risen. After the FCS data is \par ;\tab stored, the FCS module is called to calculate and verify the FCS \par ;\tab for the data stream. If the FCS is verified, then the RFECHO\plain\f4\fs20 module \par \plain\f3\fs20 ;\tab is called and an ECHO/ACKNOWLEDGE is transmitted back on the RF link \par ;\tab to acknowledge receipt of the data. \par ;\tab BROADCAST: \par ;\tab In the special case of BROADCAST: When a TOFROM=00h is detected, the \par ;\tab ECHO is skipped and the software enters a 100ms delay loop to wait out \par ;\tab the 8x broadcast of the message. \par ;\tab RF NOISE FILTERING: \par ;\tab 1) 11X oversampling - Each bit is sampled 11X to determine the value \par ;\tab 2) RF Data Validation - Each time the potential start of a message \par ;\tab is received (Training Pulses), the 1st, 2nd, and 3rd bits of the \par ;\tab training pulses are verified. The purpose of this is to filter \par ;\tab RF noise and ensure that a valid message is being received \par ;\tab before delaying past the remaining pulses and entering the main \par ;\tab loop. \tab \tab \par ;***************************************************************************** * \par \par rx_ptr\tab \tab \tab .EQU\tab r0\tab \tab ; \par rfdata\tab \tab \tab .EQU\tab r1\tab \tab ; \par rffcshi\tab \tab \tab .EQU\tab r2\tab \tab ; \par rffcslo\tab \tab \tab .EQU\tab r3\tab \tab ; \par cmp_val\tab \tab \tab .EQU\tab r4\tab \tab ; \par bits\tab \tab \tab .EQU\tab r5\tab \tab ; \par nibcnt\tab \tab \tab .EQU\tab r6\tab \tab ; \par p32mask\tab \tab \tab .EQU\tab r7\tab \tab ; \par lonib\tab \tab \tab .EQU\tab r8\tab \tab ; \par hinib\tab \tab \tab .EQU\tab r9\tab \tab ; \par rf_size\tab \tab \tab .EQU\tab r10\tab \tab ; \par rftofrom\tab \tab \tab .EQU\tab r11\tab \tab ; \par pdata\tab \tab \tab .EQU\tab r12\tab \tab ; \par result\tab \tab \tab .EQU\tab r13\tab \tab ; \par \par RF_RCV: \par \tab \tab srp\tab #SCRATCHPAD\tab \tab \tab ; \par \tab \tab push\tab IMR\tab \tab \tab ; \par \tab \tab and\tab P2COPY,#D5_ON\tab \tab \tab ; Enable RXI Diode \par \tab \tab ld\tab P2,P2COPY\tab \tab \tab ; \par RF_TRAIN_TEST: \par \tab \tab ld\tab PRE1,#07h\tab \tab \tab ; Verify first 3 pulses of \par \tab \tab ld\tab T1,#RF_BAUD \tab \tab \tab ; pulse train (preamble). Return \par \tab \tab ld\tab IMR,#TMR1_IMR\tab \tab \tab ; to main if any one is invalid \par \tab \tab or\tab TMR,#0ch\tab \tab \tab ; enable timer \par \tab \tab tm\tab RCV_STATUS,#BIT1\tab \tab \tab ; if RCV_STATUS = RF_DATA_WAIT \par \tab \tab jr\tab nz,RF_RCV_DATA\tab \tab \tab ; skip preamble check \par RF_RCV_TRAIN: \par \tab \tab ld\tab nibcnt,#11\tab \tab \tab ; \par NLOOP: \par \tab \tab nop\tab \tab \tab \tab ; delay to ~ middle of pulse \par \tab \tab djnz\tab nibcnt,NLOOP\tab \tab \tab ; \par \tab \tab ld\tab p32mask,#04h\tab \tab \tab ; P32 Test Mask \par \tab \tab call\tab RF_SAMPLE\tab \tab \tab ; test Sample#1=0 \par \tab \tab cp\tab result,#16h\tab \tab \tab ; sample time ~ 40us (50-90us) \par \tab \tab jr\tab ugt,RF_INVALID \tab \tab \tab ; invalid bit if result > 16h \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ei\tab \tab \tab \tab ; enable interrupts \par \tab \tab nop \tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 104us for next bit \par \tab \tab call\tab RF_SAMPLE\tab \tab \tab ; test for valid Sample#2 \par \tab \tab cp\tab result,#16h\tab \tab \tab ; sample time ~ 40us (50-90us) \par \tab \tab jr\tab ult,RF_INVALID\tab \tab \tab ; invalid bit if result < 16h \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ei\tab \tab \tab \tab ; enable interrupts \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 104us for next bit \par \tab \tab call\tab RF_SAMPLE\tab \tab \tab ; Test for valid Sample#3 \par \tab \tab cp\tab result,#16h\tab \tab \tab ; sample time ~40us (50-90us) \par \tab \tab jr\tab ult,RF_VALID\tab \tab \tab ; invalid bit if result > 16h \par RF_INVALID: \par \tab \tab pop\tab IMR\tab \tab \tab ; if preamble test fails, \par \tab \tab clr\tab IRQ\tab \tab \tab ; restore IMR and return to \par \tab \tab iret\tab \tab \tab \tab ; MAIN loop \par RF_VALID: \par \tab \tab ld\tab PRE1,#57h\tab \tab \tab ; if preamble test passes \par \tab \tab ld\tab T1,#RF_BAUD \tab \tab \tab ; delay 21 x 104us (21 pulses) \par \tab \tab ld\tab IMR,#TMR1_IMR\tab \tab \tab ; to start of message \par \tab \tab ld\tab TMR,#0ch\tab \tab \tab ; \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ei\tab \tab \tab \tab ; enable interrupts \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 104us for next bit \par \tab \tab or\tab RCV_STATUS,#BIT1\tab \tab \tab ; Set Status = RF_DATA_WAIT \par \tab \tab pop\tab IMR\tab \tab \tab ; restore IMR \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab iret\tab \tab \tab \tab ; return to MAIN loop \par RF_RCV_DATA: \par \tab \tab pop\tab IMR\tab \tab \tab ; \par \tab \tab ld\tab PRE1,#07h\tab \tab \tab ; set timer0 = 104us \par \tab \tab ld\tab T1,#RF_BAUD\tab \tab \tab ; \par \tab \tab ld\tab IMR,#TMR1_IMR\tab \tab \tab ; \par \tab \tab ld\tab TMR,#0ch\tab \tab \tab ; load and enable T1 \par \tab \tab ld\tab nibcnt,#2\tab \tab \tab ; 2 6-bit nibbles/word \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ei\tab \tab \tab \tab ; enable interrupts \par SB_SAMPLE: \par \tab \tab call\tab RF_SAMPLE \tab \tab \tab ; 11x sampling of input \par \tab \tab cp\tab result,#16h\tab \tab \tab ; Compare to 22 (14h) \par \tab \tab jp\tab gt,RF_FAIL\tab \tab \tab ; Error if not zero \par RFNIB_LP: \par \tab \tab ld\tab bits,#6\tab \tab \tab ; number of data bits \par \tab \tab clr\tab r12\tab \tab \tab ; \par RFRCV_OLP: \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 104us for next bit \par RFRCV_SAMPLE: \par \tab \tab call\tab RF_SAMPLE\tab \tab \tab ; 11x sampling of input \par \tab \tab cp\tab result,#16h\tab \tab \tab ; compare to 22 (16h) \par \tab \tab jr\tab gt,LOGIC1\tab \tab \tab ; if > 16, data = 1 \par LOGIC0:\tab \tab \tab \par \tab \tab rcf\tab \tab \tab \tab ; set carry flag \par \tab \tab rrc\tab rfdata\tab \tab \tab ; rotate '1' into byte \par \tab \tab djnz\tab bits,RFRCV_OLP\tab \tab \tab ; \par \tab \tab jr\tab STORE\tab \tab \tab ; \par LOGIC1:\tab \tab \tab \par \tab \tab scf\tab \tab \tab \tab ; clear carry flag \par \tab \tab rrc\tab rfdata\tab \tab \tab ; rotate '0' into byte \par \tab \tab djnz\tab bits,RFRCV_OLP \tab \tab \tab ; \par STORE: \par \tab \tab rr\tab rfdata\tab \tab \tab ; format data and convert \par \tab \tab rr\tab rfdata\tab \tab \tab ; dc balanced (12 bit) data \par \tab \tab and\tab rfdata,#3Fh\tab \tab \tab ; \par CONV6TO4: \par \tab \tab cp\tab rfdata,#7h\tab \tab \tab ; verify 7 <= R13 <= 38 \par \tab \tab jp\tab lt,RF_FAIL\tab \tab \tab ; DC Balanced data is invalid \par \tab \tab cp\tab rfdata,#38h\tab \tab \tab ; if not withing this range \par \tab \tab jp\tab gt,RF_FAIL\tab \tab \tab ; \par SIX_OK: \par \tab \tab cp\tab rfdata,#15h\tab \tab \tab ; if 15, then return 0 \par \tab \tab jr\tab ne,CHECK1\tab \tab \tab ; '15' corresponds to value '0' \par \tab \tab clr\tab rfdata\tab \tab \tab ; in the DC Balance Table \par \tab \tab jr\tab SIXOUT\tab \tab \tab ; \par CHECK1: \par \tab \tab cp\tab rfdata,#1Ch \tab \tab \tab ; elseif 1C, then return 15 \par \tab \tab jr\tab ne,CHECK2 \tab \tab \tab ; '1C' corresponds to value '15' \par \tab \tab ld\tab rfdata,#0fh\tab \tab \tab ; in the DC Balance TAble \par \tab \tab jr\tab SIXOUT\tab \tab \tab ; \par CHECK2: \par \tab \tab and\tab rfdata,#0fh\tab \tab \tab ; elseif return Low nibble \par SIXOUT: \par \tab \tab djnz\tab nibcnt,LONIBBLE\tab \tab \tab ; \par HINIBBLE:\tab \tab \par \tab \tab ld\tab hinib,rfdata\tab \tab \tab ; store results for hinibble \par \tab \tab jr\tab COMBINE\tab \tab \tab ; \par LONIBBLE: \par \tab \tab ld\tab lonib,rfdata\tab \tab \tab ; store results for lonibble \par \tab \tab jr\tab RFNIB_LP\tab \tab \tab ;\tab \par COMBINE: \par \tab \tab swap\tab hinib \tab \tab \tab ; swamp nibbles to format data \par \tab \tab or\tab hinib,lonib\tab \tab \tab ; \par \tab \tab ld\tab RFDATA,hinib\tab \tab \tab ; RFDATA <= RESULT \par RFSTOP: \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 104us \par \tab \tab clr\tab TMR\tab \tab \tab ; \par \tab \tab tm\tab RCV_STATUS,#BIT5\tab \tab \tab ; if RCV_STATUS = RF_ECHO_WAIT \par \tab \tab jr\tab z,RF_PROCESS\tab \tab \tab ; then received data is RF ECHO data \par \par ;***************************************************************************** \par ; \tab RFECHO_PROCESS: \par ; \tab Entry: Enter module from RF_RCV\tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \par ; \tab Definition: Module takes data from RF_RCV and determines where \par ;\tab in SRAM each byte should be stored.\tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \par ;***************************************************************************** \par RFECHO_PROCESS: \par \tab \tab cp\tab BYTECNT,#0\tab \tab \tab ; use BYTECNT to determine which \par \tab \tab jr\tab z,RFETOFROM\tab \tab \tab ; databyte was received \par \tab \tab cp\tab BYTECNT,#1\tab \tab \tab ; \par \tab \tab jr\tab z,RFEPACKET\tab \tab \tab ; \par \tab \tab cp\tab BYTECNT,#2\tab \tab \tab ; \par \tab \tab jr\tab z,RFESIZE\tab \tab \tab ; \par \tab \tab jr\tab RF_RETRY\tab \tab \tab ; \par RFETOFROM: \par \tab \tab cp\tab RFDATA,TOFROM\tab \tab \tab ; verify TOFROM is valid \par \tab \tab jr\tab nz,RF_RETRY\tab \tab \tab ; if not, RETRY \par \tab \tab inc\tab BYTECNT\tab \tab \tab ; \par \tab \tab jp\tab RFECHO_WAIT\tab \tab \tab ; wait for next byte \par RFEPACKET: \par \tab \tab cp\tab RFDATA,PACKET\tab \tab \tab ; verify PACKET # \par \tab \tab jr\tab nz,RF_RETRY\tab \tab \tab ; if not, RETRY \par \tab \tab inc\tab BYTECNT\tab \tab \tab ; \par \tab \tab jp\tab RFECHO_WAIT\tab \tab \tab ; wait for next byte \par RFESIZE: \par \tab \tab cp\tab RFDATA,SIZE\tab \tab \tab ; verify SIZE is valid \par \tab \tab jr\tab nz,RF_RETRY\tab \tab \tab ; if not, RETRY \par \tab \tab inc\tab RETRY\tab \tab \tab ; \par \tab \tab call\tab PC_ACK\tab \tab \tab ; if valid, send ACK to PC \par \tab \tab jp\tab RF_XMT_EXIT\tab \tab \tab ; \par RF_RETRY: \par \tab \tab call\tab DELAY100\tab \tab \tab ; 100ms delay between retries \par \tab \tab inc\tab RETRY\tab \tab \tab ; \par \tab \tab ld\tab RCV_STATUS,#BIT5\tab \tab \tab ; RCV_STATUS = RF_ECHO_WAIT \par \tab \tab cp\tab RETRY,#8h\tab \tab \tab ; \par \tab \tab jp\tab nz,RF_XMT_CALL\tab \tab \tab ; send RF Message \par RF_XMT_FAIL: \par \tab \tab call\tab PC_NAK\tab \tab \tab ; \par RF_XMT_EXIT: \par \tab \tab clr\tab RETRY\tab \tab \tab ; exit the module \par \tab \tab clr\tab BYTECNT\tab \tab \tab ; clear globals \par \tab \tab clr\tab RCV_STATUS\tab \tab \tab ; \par \tab \tab ld\tab IMR,#PCRF_IMR\tab \tab \tab ; enable IRQ0 and IRQ2 \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab iret\tab \tab \tab \tab ; return to MAIN loop \par ;***************************************************************************** \par ; \tab RF_PROCESS:\tab \tab (JUMP) \par ; \tab Entry: Enter module from RF_RCV\tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \par ; \tab Definition: Module takes data from RF_RCV and determines where \par ;\tab in SRAM each byte should be stored.\tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \par ;*****************************************************************************\tab \tab \par RF_PROCESS: \par \tab \tab cp\tab BYTECNT,#0h\tab \tab \tab ; use BYTECNT to determine which \par \tab \tab jr\tab z,RFSTARTBYTE\tab \tab \tab ; databyte was received \par \tab \tab cp\tab BYTECNT,#1h\tab \tab \tab ; \par \tab \tab jr\tab z,RFTOFROM\tab \tab \tab ; \par \tab \tab cp\tab BYTECNT,#2h\tab \tab \tab ; \par \tab \tab jr\tab z,RFPACKET\tab \tab \tab ; \par \tab \tab cp\tab BYTECNT,#3\tab \tab \tab ; \par \tab \tab jr\tab z,RFSIZE\tab \tab \tab ; \par \tab \tab jr\tab RFDATABUF\tab \tab \tab ; \par RFSTARTBYTE: \par \tab \tab cp\tab RFDATA,#55h\tab \tab \tab ; verify the STARTBYTE = 55h \par \tab \tab jr\tab nz,RF_FAIL\tab \tab \tab ; \par \tab \tab ld\tab STARTBYTE,RFDATA\tab \tab \tab ; \par \tab \tab inc\tab BYTECNT\tab \tab \tab ; \par \tab \tab jr\tab RF_WAIT\tab \tab \tab ; wait for next byte \par RFTOFROM:\tab \tab \par \tab \tab ld\tab rx_ptr,#24h\tab \tab \tab ; store TOFROM \par \tab \tab ld\tab TOFROM,RFDATA\tab \tab \tab ; \par \tab \tab inc\tab BYTECNT\tab \tab \tab ; \par \tab \tab jr\tab RF_WAIT\tab \tab \tab ; wait for next byte \par RFPACKET:\tab \tab \par \tab \tab ld\tab PACKET,RFDATA\tab \tab \tab ; store PACKET # \par \tab \tab inc\tab BYTECNT\tab \tab \tab ; \par \tab \tab jr\tab RF_WAIT\tab \tab \tab ; wait for next byte \par RFSIZE:\tab \tab \par \tab \tab ld\tab SIZE,RFDATA\tab \tab \tab ; store SIZE (# of data bytes) \par \tab \tab ld\tab rf_size,SIZE\tab \tab \tab ; \par \tab \tab add\tab rf_size,#2\tab \tab \tab ; add 2 to account for FCS bytes \par \tab \tab inc\tab BYTECNT\tab \tab \tab ; in determining message size \par \tab \tab jr\tab RF_WAIT\tab \tab \tab ; wait for next byte \par RFDATABUF: \par \tab \tab ld\tab @rx_ptr,RFDATA\tab \tab \tab ; store message data bytes \par \tab \tab inc\tab rx_ptr\tab \tab \tab ; rf_size = # of bytes \par \tab \tab djnz\tab rf_size,RF_WAIT\tab \tab \tab ; \par \tab \tab \par \tab \tab dec\tab rx_ptr\tab \tab \tab ; Load FCS into global variables \par \tab \tab ld\tab EFCSHI,@rx_ptr\tab \tab \tab ; for compare with calculated \par \tab \tab dec\tab rx_ptr\tab \tab \tab ; values \par \tab \tab ld\tab EFCSLO,@rx_ptr\tab \tab \tab ; \par \tab \tab jr\tab RF_VERIFY\tab \tab \tab ; verification of RF Message \par RF_WAIT: \par \tab \tab ld\tab RCV_STATUS,#BIT1\tab \tab \tab ; RCV_STATUS = RF_DATA_WAIT \par \tab \tab call\tab TIMEOUT1\tab \tab \tab ; (causes s/w to skip preamble test) \par \tab \tab ld\tab IMR,#RFTMR0_IMR\tab \tab \tab ; enable IRQ0 and IRQ4 \par \tab \tab clr\tab IRQ \tab \tab \tab ; clear interrupts \par \tab \tab iret\tab \tab \tab \tab ; return to MAIN loop \par RF_VERIFY: \par \tab \tab cp\tab TOFROM,#0h\tab \tab \tab ; if TOFROM = 0, message is a \par \tab \tab jr\tab z,PACK_VERIFY\tab \tab \tab ; 'BROADCAST' message \par \tab \tab ld\tab rftofrom,TOFROM\tab \tab \tab ; else verify TO Address \par \tab \tab swap\tab rftofrom\tab \tab \tab ; \par \tab \tab and\tab rftofrom,#0fh\tab \tab \tab ; \par \tab \tab cp\tab rftofrom,MY_ADDR\tab \tab \tab ; exit if address not equal to \par \tab \tab jr\tab nz,RF_EXIT\tab \tab \tab ; MY_ADDR \par PACK_VERIFY:\tab \tab \tab \tab \par \tab \tab cp\tab PACKET,#8h\tab \tab \tab ; verify Valid Packet # \par \tab \tab jr\tab gt,RF_EXIT\tab \tab \tab ; if 1 <= PACKET <=8 \par \tab \tab cp\tab PACKET,#1h\tab \tab \tab ; else PACKET # is invalid \par \tab \tab jr\tab lt,RF_EXIT\tab \tab \tab ; and module is exited \par \tab \tab call\tab FCS\tab \tab \tab ; verify FCS (checksum) \par \tab \tab cp\tab FCSHI,EFCSHI\tab \tab \tab ; compare calclated (FCSHI/LO) \par \tab \tab jr\tab nz,RF_EXIT\tab \tab \tab ; to the received (EFCSHI/LO) \par \tab \tab cp\tab FCSLO,EFCSLO\tab \tab \tab ; exit if FCS fails \par \tab \tab jr\tab nz,RF_EXIT\tab \tab \tab ; \par \tab \tab call\tab RF_ACK\tab \tab \tab ; Send 'ACK' to PC if FCS is okay \par \tab \tab call\tab PC_XMT_DATA\tab \tab \tab ; transmit Message to PC \par \tab \tab cp\tab TOFROM,#0h\tab \tab \tab ; Check if message is a 'BROADCAST' \par \tab \tab jr\tab z,DELAY1200\tab \tab \tab ; if 'BROADCAST', Delay 1.2ms \par \tab \tab jr\tab RF_EXIT\tab \tab \tab ; then exit module \par RF_FAIL: \par \tab \tab tm\tab RCV_STATUS,#BIT5\tab \tab \tab ; if RCV_STATUS = RF_ECHO_WAIT \par \tab \tab jr\tab z,RF_EXIT\tab \tab \tab ; exit module \par \tab \tab clr\tab BYTECNT\tab \tab \tab ; \par \tab \tab jp\tab RF_RETRY\tab \tab \tab ; else RETRY \par RF_EXIT: \par \tab \tab clr\tab BYTECNT\tab \tab \tab ; clear global variables \par \tab \tab clr\tab RCV_STATUS\tab \tab \tab ; \par \tab \tab ld\tab IMR,#PCRF_IMR\tab \tab \tab ; enable IRQ0 and IRQ2 \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab iret\tab \tab \tab \tab ; return to MAIN loop \par DELAY1200: \par \tab \tab ld\tab r12,#240\tab \tab \tab ; 1200ms delay loop \par D1200_LOOP: \par \tab \tab call\tab DELAY5MS\tab \tab \tab ; perform 240 5ms delay loops \par \tab \tab djnz\tab r12,D1200_LOOP\tab \tab \tab ; \par \tab \tab jr\tab RF_EXIT\tab \tab \tab ; \par \par ;***************************************************************************** \par ; \tab RF_SAMPLE:\tab \tab (CALL) \par ; \tab Entry: Enter module from RF_RCV \par ;\tab INPUT: Serial Data on P32 \par ;\tab OUTPUT: 'result' (local variable)\tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \par ; \tab Definition: Module sample P32 input 11 times. P32 is masked and \par ;\tab a running sum is calculated in the 'result' register. This 'result' \par ;\tab is used to determine whether the average sample was a '1' or '0' by \par ;\tab comparing the value to 16h (22). \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \par ;*****************************************************************************\tab \tab \par RF_SAMPLE: \par \tab \tab clr\tab result\tab \tab \tab ; 11X Sampling of P32 \par \tab \tab ld\tab result,P3\tab \tab \tab ; Sample #1 \par \tab \tab and\tab result,p32mask\tab \tab \tab ; \par \tab \tab ld\tab pdata,P3\tab \tab \tab ; Sample #2 \par \tab \tab and\tab pdata,p32mask\tab \tab \tab ; \par \tab \tab add\tab result,pdata\tab \tab \tab ; \par \tab \tab ld\tab pdata,P3\tab \tab \tab ; Sample #3 \par \tab \tab and\tab pdata,p32mask\tab \tab \tab ; \par \tab \tab add\tab result,pdata\tab \tab \tab ; \par \tab \tab ld\tab pdata,P3\tab \tab \tab ; Sample #4 \par \tab \tab and\tab pdata,p32mask\tab \tab \tab ; \par \tab \tab add\tab result,pdata\tab \tab \tab ; \par \tab \tab ld\tab pdata,P3\tab \tab \tab ; Sample #5 \par \tab \tab and\tab pdata,p32mask\tab \tab \tab ; \par \tab \tab add\tab result,pdata\tab \tab \tab ; \par \tab \tab ld\tab pdata,P3\tab \tab \tab ; Sample #6 \par \tab \tab and\tab pdata,p32mask\tab \tab \tab ; \par \tab \tab add\tab result,pdata\tab \tab \tab ; \par \tab \tab ld\tab pdata,P3\tab \tab \tab ; Sample #7 \par \tab \tab and\tab pdata,p32mask\tab \tab \tab ; \par \tab \tab add\tab result,pdata\tab \tab \tab ; \par \tab \tab ld\tab pdata,P3\tab \tab \tab ; Sample #8 \par \tab \tab and\tab pdata,p32mask\tab \tab \tab ; \par \tab \tab add\tab result,pdata\tab \tab \tab ; \par \tab \tab ld\tab pdata,P3\tab \tab \tab ; Sample #9 \par \tab \tab and\tab pdata,p32mask\tab \tab \tab ; \par \tab \tab add\tab result,pdata\tab \tab \tab ; \par \tab \tab ld\tab pdata,P3\tab \tab \tab ; Sample #10 \par \tab \tab and\tab pdata,p32mask\tab \tab \tab ; \par \tab \tab add\tab result,pdata\tab \tab \tab ; \par \tab \tab ld\tab pdata,P3\tab \tab \tab ; Sample #11 \par \tab \tab and\tab pdata,p32mask\tab \tab \tab ; \par \tab \tab add\tab result,pdata\tab \tab \tab ; sum results \par \tab \tab ret\tab \tab \tab \tab ; \par \tab \par ;************************************************************* \par ; \tab PC_XMT_DATA:\tab \tab \tab (CALL) \par ;\tab INPUT: RF DATA SRAM ADDR 0x21 to End of data \par ;\tab OUTPUT: Serial Data on P01 \par ; \tab Description: Transmits Rf data received by RRX to the host \par ;\tab software (PC). \par ;************************************************************* \par pc_ptr\tab \tab \tab .EQU\tab r0\tab \tab ; \par pc_size\tab \tab \tab .EQU\tab r1\tab \tab ; \par \par PC_XMT_DATA: \par \tab \tab call\tab DELAY5MS\tab \tab \tab ; \par \tab \tab and\tab P2COPY,#D4_ON\tab \tab \tab ; turn on RFRCV Diode \par \tab \tab ld\tab P2,P2COPY\tab \tab \tab ; \par \tab \tab or\tab P0COPY,#ON_232\tab \tab \tab ; enable 232 \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab ld\tab pc_ptr,#24h\tab \tab \tab ; set pointer to DATA Buffer \par \tab \tab ld\tab pc_size,SIZE\tab \tab \tab ; \par \tab \tab ld\tab SERDATA,TOFROM\tab \tab \tab ; transmit protocol info \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send TOFROM byte \par \tab \tab ld\tab SERDATA,PACKET\tab \tab \tab ; \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send PACKET byte \par \tab \tab ld\tab SERDATA,SIZE\tab \tab \tab ; \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send SIZE byte \par PCXMT_LOOP:\tab \tab \tab \par \tab \tab ld\tab SERDATA,@pc_ptr\tab \tab \tab ; send message data \par \tab \tab call\tab PC_XMT\tab \tab \tab ; \par \tab \tab inc\tab pc_ptr\tab \tab \tab ; \par \tab \tab djnz\tab pc_size,PCXMT_LOOP; \par \par \tab \tab and\tab P0COPY,#OFF_232\tab \tab \tab ; Disable 232 \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab or\tab P2COPY,#D4_OFF\tab \tab \tab ; Turn off RFRCV Diode \par \tab \tab ld\tab P2,P2COPY\tab \tab \tab ; \par \tab \tab ret\tab \tab \tab \tab ; \par RF_ACK:\tab \tab \tab \tab \tab \tab ; sends RF_ACK to RF msg originator \par \tab \tab call\tab DELAY5MS\tab \tab \tab ; Delay 10ms to allow xmtr \par \tab \tab call\tab DELAY5MS\tab \tab \tab ; power to stabilize \par \tab \tab and\tab P2COPY,#PTT_ON\tab \tab \tab ; Enable RF Transmit \par \tab \tab ld\tab P2,P2COPY\tab \tab \tab ; \par \tab \tab call\tab RF_TRAIN\tab \tab \tab ; send preamble (DC Balance Train) \par \tab \tab ld\tab SERDATA,TOFROM\tab \tab \tab ; Transmits Acknowledge to RF Link \par \tab \tab call\tab RF_SEND\tab \tab \tab ; send TOFROM byte \par \tab \tab ld\tab SERDATA,PACKET\tab \tab \tab ; \par \tab \tab call\tab RF_SEND\tab \tab \tab ; send PACKET byte \par \tab \tab ld\tab SERDATA,SIZE\tab \tab \tab ; \par \tab \tab call\tab RF_SEND\tab \tab \tab ; send SIZE byte \par \tab \tab or\tab P2COPY,#PTT_OFF\tab \tab \tab ; Disable RF Transmit \par \tab \tab ld\tab P2,P2COPY\tab \tab \tab ; \par \tab \tab ret\tab \tab \tab \tab ; \par PC_NAK: \par \tab \tab call\tab DELAY5MS\tab \tab \tab ; sends NAK to PC (retry failed 8X) \par \tab \tab or\tab P0COPY,#ON_232\tab \tab \tab ; Enable 232 \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ;\tab \tab \par \tab \tab ld\tab SERDATA,TOFROM\tab \tab \tab ; format = |TOFROM|PACKET|DDh| \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send TOFROM byte \par \tab \tab ld\tab SERDATA,PACKET\tab \tab \tab ; \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send PACKET byte \par \tab \tab ld\tab SERDATA,#0DDh\tab \tab \tab ; \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send 'DDh' byte \par \tab \tab and\tab P0COPY,#OFF_232\tab \tab \tab ; Disable 232 \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab ret\tab \tab \tab \tab ; \par PC_ACK: \par \tab \tab call\tab DELAY5MS\tab \tab \tab ; sends ACK to PC \par \tab \tab or\tab P0COPY,#ON_232\tab \tab \tab ; Enable 232 \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; format = |TOFROM|PACKET|En|\tab \tab \tab \tab \tab \tab \par \tab \tab ld\tab SERDATA,TOFROM\tab \tab \tab ; n = RETRY \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send TOFROM byte \par \tab \tab ld\tab SERDATA,PACKET\tab \tab \tab ; \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send PACKET byte \par \tab \tab ld\tab SERDATA,#0E0h\tab \tab \tab ; \par \tab \tab or\tab SERDATA,RETRY\tab \tab \tab ; send 'En' byte \par \tab \tab call\tab PC_XMT\tab \tab \tab ; \par \tab \tab and\tab P0COPY,#OFF_232\tab \tab \tab ; Disable 232 \par \tab \tab ld\tab P0,P0COPY\tab \tab \tab ; \par \tab \tab ret \par DELAY5MS: \par \tab \tab di\tab \tab \tab \tab ; 5ms Delay routine \par \tab \tab push\tab IMR\tab \tab \tab ; \par \tab \tab ld\tab PRE1,#7Bh\tab \tab \tab ; \par \tab \tab ld\tab T1,#0FAh\tab \tab \tab ; \par \tab \tab ld\tab IMR,#TMR1_IMR\tab \tab \tab ; enable interrupts \par \tab \tab ld\tab TMR,#0Ch\tab \tab \tab ; \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ei\tab \tab \tab \tab ; enable interrupts \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 5ms \par \tab \tab pop\tab IMR\tab \tab \tab ; restore IMR \par \tab \tab ret\tab \tab \tab \tab ; \par DELAY3MS: \par \tab \tab di\tab \tab \tab \tab ; 3ms delay routine \par \tab \tab push\tab IMR\tab \tab \tab ; \par \tab \tab ld\tab PRE1,#0F3h\tab \tab \tab ; \par \tab \tab ld\tab T1,#04Bh\tab \tab \tab ; \par \tab \tab ld\tab IMR,#TMR1_IMR\tab \tab \tab ; enable IRQ5 \par \tab \tab ld\tab TMR,#0Ch\tab \tab \tab ; \par \tab \tab clr\tab IRQ\tab \tab \tab ; clear interrupts \par \tab \tab ei\tab \tab \tab \tab ; enable interrupts \par \tab \tab nop\tab \tab \tab \tab ; clear pipeline \par \tab \tab halt\tab \tab \tab \tab ; wait 3ms \par \tab \tab pop\tab IMR\tab \tab \tab ; restore IMR \par \tab \tab ret\tab \tab \tab \tab ; \par RAMTEST: \par \tab \tab push\tab RP\tab \tab \tab ; RAM Self Test \par \tab \tab srp\tab #0h\tab \tab \tab ; \par \tab \tab ld\tab R13,TOFROM\tab \tab \tab ; \par \tab \tab ld\tab DATA_PTR,#10h\tab \tab \tab ; \par RAMWR: \par \tab \tab ld\tab @DATA_PTR,#0AAh\tab \tab \tab ; ld 'AA' into memory from \par \tab \tab inc\tab DATA_PTR\tab \tab \tab ; address '10h' to '76' \par \tab \tab cp\tab DATA_PTR,#76h\tab \tab \tab ; avoids overwriting data and \par \tab \tab jr\tab nz,RAMWR\tab \tab \tab ; stack \par \tab \tab ld\tab DATA_PTR,#10h\tab \tab \tab ; \par RAMRD: \par \tab \tab cp\tab @DATA_PTR,#0AAh\tab \tab \tab ; read memory and verify 'AA' \par \tab \tab jr\tab nz,RAMFAIL\tab \tab \tab ; \par \tab \tab inc\tab DATA_PTR\tab \tab \tab ; \par \tab \tab cp\tab DATA_PTR,#76h\tab \tab \tab ; \par \tab \tab jr\tab nz,RAMRD\tab \tab \tab ; \par \tab \tab jr\tab RAMPASS\tab \tab \tab ; \par RAMFAIL: \par \tab \tab ld\tab r15,#33h\tab \tab \tab ; send '33h' if RAM fails \par \tab \tab jr\tab RAMCLR\tab \tab \tab ; clear RAM \par RAMPASS: \par \tab \tab ld\tab r15,#34h\tab \tab \tab ; send '34h' if RAM passes \par RAMCLR: \par \tab \tab ld\tab DATA_PTR,#10h\tab \tab \tab ; clear RAM from '10h' to '76h' \par RAMCLR1: \par \tab \tab clr\tab @DATA_PTR\tab \tab \tab ; \par \tab \tab inc\tab DATA_PTR\tab \tab \tab ; \par \tab \tab cp\tab DATA_PTR,#76h\tab \tab \tab ; \par \tab \tab jr\tab nz,RAMCLR1\tab \tab \tab ;\tab \tab \par RAM_XMT: \par \tab \tab ld\tab SERDATA,#0\tab \tab \tab ; transmit test status to PC \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send '00' to PC \par \tab \tab ld\tab SERDATA,#0\tab \tab \tab ; \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send '00' to PC \par \tab \tab ld\tab SERDATA,#1\tab \tab \tab ; \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send '01' to PC \par \tab \tab ld\tab SERDATA,r15\tab \tab \tab ; \par \tab \tab call\tab PC_XMT\tab \tab \tab ; send '33h' to '34h' to PC \par \tab \tab pop\tab RP\tab \tab \tab ; restore RP \par \tab \tab ret\tab \tab \tab \tab ; \par DELAY100: \par \tab \tab push\tab RP\tab \tab \tab ; 100ms delay routine \par \tab \tab srp\tab #SCRATCHPAD\tab \tab \tab ; \par \tab \tab ld\tab r12,#20\tab \tab \tab ; \par D100_LOOP: \par \tab \tab call\tab DELAY5MS\tab \tab \tab ; perform 20 5ms delays \par \tab \tab djnz\tab r12,D100_LOOP\tab \tab \tab ; \par \tab \tab pop\tab RP\tab \tab \tab ; \par \tab \tab ret\tab \tab \tab \tab ; \par \par ;************************************************************************ \par ; \tab FCS: Performs FCS Checksum calculation\tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \par ;\tab \tab \tab \tab \tab \tab \tab \tab \tab \par ;\tab \tab Input: DATABUF (all data contained in SRAM) \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \par ;\tab \tab Output: FCSHI,FCSLO \par ; \par ; \tab \tab Output placed at end of the data buffer\tab \tab \tab \tab \tab \tab \tab \tab \tab \tab \par ; \tab \tab This section uses register group 50h as a scratchpad \par ;************************************************************************ \par \par fcs_ptr\tab \tab .EQU\tab r0\tab ; \par fsize\tab \tab .EQU\tab r2\tab ; \par fbitcnt\tab \tab .EQU\tab r3\tab ; \par fdata1\tab \tab .EQU\tab r4\tab ; \par fdata2\tab \tab .EQU\tab r5\tab ; \par fcsls\tab \tab .EQU\tab r6\tab ; \par fcsms\tab \tab .EQU\tab r7\tab ; \par ftemp1\tab \tab .EQU\tab r8\tab ; \par ftemp2\tab \tab .EQU\tab r9\tab ; \par \par FCS: \par \tab \tab srp\tab #SCRATCHPAD\tab \tab \tab ; set register pointer to scratchpad \par \tab \tab ld\tab fsize,SIZE\tab \tab \tab ; calculate # bytes to process \par \tab \tab add\tab fsize,#03h\tab \tab \tab ; by adding (size +3) \par \tab \tab ld\tab fcs_ptr,#21h\tab \tab \tab ; FCS starts with TO/FROM byte \par \tab \par \tab \tab ld\tab fcsls,#0ffh\tab \tab \tab ; preset FCS \par \tab \tab ld\tab fcsms,#0ffh\tab \tab \tab ; \par FCS21: \par \tab \tab ld\tab fbitcnt,#08h\tab \tab \tab ; Process 8 bits/byte \par \tab \tab ld\tab fdata1,@fcs_ptr\tab \tab \tab ; \par \tab \tab inc\tab fcs_ptr\tab \tab \tab ; increment for next pass \par FCS22: \par \tab \tab ld\tab ftemp1,fdata1\tab \tab \tab ; \par \tab \tab and\tab ftemp1,#1\tab \tab \tab ; get LSB\tab \tab \par \tab \tab rr\tab fdata1\tab \tab \tab ; rotate for next pass \par \tab \par \tab \tab ld\tab fdata2,fcsls\tab \tab \tab ; \par \tab \tab and\tab fdata2,#1\tab \tab \tab ; LS byte of FCS \par \tab \par ;************************************************************************ \par ;\tab 16 bit shift of FCS ;************************************************************************ \par \tab \tab rcf\tab \tab \tab \tab ; \par \tab \tab rrc\tab fcsms\tab \tab \tab ; from buffer \par \tab \tab rrc\tab fcsls\tab \tab \tab ; from FCS \par ;************************************************************************ \par ;\tab Compare Bits saved from buffer and from LS bit of LS byte of FCS \par ;************************************************************************ \par \tab \tab ld\tab ftemp2,ftemp1\tab \tab \tab ; Use r8 as temp \par \tab \tab xor\tab ftemp2,fdata2\tab \tab \tab ; \par \tab \tab jp\tab z,FCS23\tab \tab \tab ; jump if r8=0 \par \tab \tab xor\tab fcsms,#84h\tab \tab \tab ; xor with poly \par \tab \tab xor\tab fcsls,#08h\tab \tab \tab ; \par FCS23: \par \tab \tab djnz\tab fbitcnt,FCS22\tab \tab \tab ; go for another bit \par \tab \tab djnz\tab fsize,FCS21\tab \tab \tab ; go for another byte \par \tab \tab ld\tab FCSHI,fcsls\tab \tab \tab ; store FCS data in data buffer \par \tab \tab inc\tab DATA_PTR\tab \tab \tab ; \par \tab \tab ld\tab FCSLO,fcsms\tab \tab \tab ; \par \tab \tab ret\tab \tab \tab \tab ; return for FCS in r7,r6 \par ;************************************************************************ \par ;\tab Add FCS Buffer to XMIT\tab \tab \tab \tab \tab \tab \tab \tab \tab \par ;************************************************************************ \par ADD_FCS: \par \tab \tab ld\tab fsize,#8h\tab \tab \tab ; \par RLOOP1: \par \tab \tab rrc\tab fcsms\tab \tab \tab ; \par \tab \tab rlc\tab ftemp1\tab \tab \tab ; \par \tab \tab djnz\tab fsize,RLOOP1\tab \tab \tab ; \par \tab \tab com\tab ftemp1\tab \tab \tab ; \par \tab \tab ld\tab @fcs_ptr,ftemp1\tab \tab \tab ; \par \tab \tab ld\tab FCSHI,ftemp1\tab \tab \tab ; \par \tab \tab \tab \tab \tab \tab \tab \par \tab \tab inc\tab fcs_ptr\tab \tab \tab ;\tab \par \tab \tab ld\tab fsize,#8h\tab \tab \tab ; \par RLOOP2: \par \tab \tab rrc\tab fcsls\tab \tab \tab ; \par \tab \tab rlc\tab ftemp1\tab \tab \tab ; \par \tab \tab djnz\tab fsize,RLOOP2\tab \tab \tab ; \par \tab \tab com\tab ftemp1\tab \tab \tab ; \par \tab \tab ld\tab @fcs_ptr,ftemp1\tab \tab \tab ; \par \tab \tab ld\tab FCSLO,ftemp1\tab \tab \tab ; \par \tab \tab ret\tab \tab \tab \tab ; \par \par \tab \tab END \par \pard\plain\f2\fs20 \par }