Академический Документы
Профессиональный Документы
Культура Документы
2.1. Transmitter
3 . System and Protocol Definition The MAX3232 3-V to 5.5-V RS232 line driver is
used for logic level voltage conversion between the
3.1. System Definition computer and the MSP-430 microcontroller. The
signal at the UART TX line of the microcontroller
The overall wireless UART system setup is shown in Figure 3. The start bit is a high pulse,
implemented in the firmware consists of two 26.04 micro-secs long (38.4 kbps). Then the first
computers exchanging data wirelessly. The data data bit is sent beginning with the LSB. After 8
transmission is half-duplex and bi-directional. The data bits, the stop bit arrives generating a low pulse
various phases of data transmission are illustrated on the RS-232 line.
in Figure 2.
i) Training sequence
ii) Start Bit
iii) Data packet that includes 32 bytes of data and
2 bytes of checksum
Figure 2: Various phases of data transmission
3.2.2.1. Training Sequence
3.2.1. RS-232 Protocol
Besides the ability to receive return to zero coded
The default protocol used for RS-232 serial signals, the TRF 6903 features the availability to
transmission and reception is 38.4 kbps data rate receive NRZ coded signals. This doubles the
with eight data bits, one stop bit and no parity. The maximum achievable data transmission rate.
firmware has been written to support this protocol.
E). The A and B words are almost identical and set process is depicted in Figure 7. Each step shown in
the device for two modes, designated as Mode0 and the flowchart is implemented as a function in the
Mode1, which are used to configure the transmit and firmware.
receive states. The C word sets the reference dividers,
the power amplifier bias, and contains various reset Table 2: TRF6903 Register Settings
bits. The D word is used to trim the external crystal REGISTER PARAMETER VALUE
frequency and tune the demodulator. The E word A PA Attenuation 0 dB
Mode 0 TX
contains the bit-rate select, data clock control bits and Charge Pump 0.5mA
the power amplifier bias control registers. Frequency Band 915Mhz
The registers used with the wireless UART B PA Attenuation 0dB
firmware are shown in Table 2. Mode 0 RX
Modulation FSK
Brownout Threshold 2.2V
5. The Graphic User Interface (GUI) Brownout Detector OFF
C Reference Divider 48
Reference Frequency 409.6 KHz
A GUI provided by Texas Instruments is being used
D Crystal Tune 20.23 pF
for transmission and reception of data for test Reset Signal for PFD Derived from
purposes. A snapshot of the GUI is shown in Figure prescaler
6. The GUI provides a means to set the baud rate, Crystal Switch Closed
E Receive Data Mode Self Train
select the COM port from where data is to be
(RXM)
sent/received and also displays the receive and sent Dividers D1, D2, D3 38.4 kbps
data. If the transmit data is acknowledged, the Transmit Capture select Set
received packet stream will be displayed in the
Received Data list box. Table 3: MSP430 Port Configuration
MSP430 Port PURPOSE DIRECTION
P1.0 to P1.3 Buttons Output
P1.4 to P1.7 LED’s Output
P2.0 RXDATA Input
P2.1 DCLK Input
P2.2 TXDATA Output
P2.3 RX-FLAG Input
P2.4 USART0 TX DATA Output
P2.5 USART0 RX DATA Input
P2.6 LOCKDET Input
P2.7 BROWN-OUT DET Input
P3.0 to P3.3 DIP SWITCH Input
P3.4 LN/HOLD Output
P3.5 STDBY Output
P3.6 CLK Output
Figure 6: Wireless UART GUI to transmit and receive P3.7 MODE Output
P4.0 DATA Output
6. Implementation of Wireless Transmission P4.1 STROBE Output
P6.0 to P6.3 LED’s Output
The firmware details used to implement wireless
transmission is explained in this section. The
firmware has been written using IAR embedded
workbench. The flowchart of the transmission
6.1. Configure Input Output Ports system cost and ultralow-power consumption. The
FLL+ features digital frequency-locked loop (FLL)
The MSP430 ports configured for input and output hardware. The FLL operates together with a digital
are shown in Table 3. modulator and stabilizes the internal digitally
All the ports are configured as general purpose controlled oscillator (DCO) frequency to a
input/output ports except USART0 TXDATA, programmable multiple of the LFXT1 watch
USART0 RXDATA, RXDATA and DCLK. These crystal frequency. The FLL+ clock module can be
pins are configured as peripheral module pins. This is configured under full software control. After a
accomplished using the Function Select Register PUC, MCLK and SMCLK are sourced from
Pxsel. This peripheral module selection configures DCOCLK at 32 times the ACLK frequency. When
RXDATA as Timer A Capture Input and DCLK as a 32,768-Hz crystal is used for ACLK, MCLK, and
Timer B Capture Input. SMCLK stabilizes to 1.048576 MHz. The
SCFQCTL, SCFI0, SCFI1, FLL_CTL0, and
FLL_CTL1 registers configure the FLL+ clock
module. The FLL+ can be configured or
reconfigured by software at any time during
program execution.
In the firmware, the DCO frequency is set to
75 times the watch crystal frequency = 75 x 32,768
= 2.4576 MHz. Thus the MCLK and SMCLK are
sourced by a 2.4576-MHz clock.
UART GUI, the clock recovery bit rate dividers interrupt and restarts. The RXDATA signal is
D1, D2, and D3 is chosen to program register E. applied to a capture-compare block.
The transceiver baud rate is set by DR_DLY_CNT, In recognizing the training sequence, the code
a global parameter used across all files in the distinguishes between three different states:
project. The formula used for calculation is: • No valid pulse is detected.
• Fewer than 16 valid consecutive pulses are
Transceiver Bit Rate = 2.4576 detected.
DR DLY CNT + 1 • More than 16 valid consecutive pulses are
detected—the training sequence is recognized.
If the bit rate is 38.4 kbps DR_DLY_CNT =
63; if the bit rate is 19.2 kbps DR_DLY_CNT = 7.2 Detection of Start Bit
127; If bit rate is 51.2 kbps DR_DLY_CNT = 47.
The principle of start-bit recognition is similar to
the detection of the training-sequence pulse except
7. Implementation of Wireless Reception
that the start bit consists of a single pulse. To
distinguish between the pulses of the training
Once the TRF6903 is initialized and configured, it
sequence and the pulse of the start bit, the length of
operates in the receive mode waiting for a training
the start bit was set to three times 26.04 s, i.e.,
sequence. The wireless receive protocol has three
three times as long as the pulses of the training
stages,
sequence. The falling edge of the start-bit pulse is
• Training sequence recognition
the trigger for the scanning and reading of the data
• Start bit recognition
package.
• Data bits recognition
8. Project Set Up
Figure 10: Block Diagram of Project Set-up
The actual project set-up is shown in Figure 9. A
block diagram of the set-up is depicted in Figure 9. Transmission without encoding/decoding
10. As shown in the figure, the EVM is interfaced
The first step was implementation of a wireless
with the PC via RS-232 cable. This RS-232 cable
link for sending and receiving data. The first step
is used to transmit and receive data to and from the
was to make sure that the RS-232 protocol and the
MSP430. While receiving MSP430 fills a buffer
wireless protocol are implemented appropriately
until all 32 bytes are full. As soon as the overflow
and the data is being transmitted over the link
occurs, the data in the buffer is sent to the PC via
correctly. In order to implement this, the data being
the RS-232 serial interface. The serial port of the
sent from the PC to the transmitter was directly put
PC can be configured used a hyper terminal to read
into the transmit buffer without any modification.
the data received by the MSP430. On the other
At this point the RS-232 protocol was implemented
hand, while transmitting, the buffer used to
to make sure that the data is being accumulated in The ratio k/n is called the code rate of the encoder.
the transmitting buffer. Once the data was It represents the amount of information per coded
successfully exchanged between the PC and the bit. The integer K is called the constraint length of
MCU, the next step was to program the TRF6903 the code. It represents the number of k-tuple stages
to transmit the data as it is, without any encoding in the encoding shift register. An important
decoding. On the receiving side, the data is directly characteristic of convolutional codes, unlike block
stored in the receiving buffer until all 32 bytes are codes, is that the encoder has memory. The n-tuple
received. On arrival of all the 32 bytes, the data is emitted by the convolutional encoding procedure is
then sent via the RS-232 line to the receiving PC. not only a function of an input k-tuple, but is also a
This data is displayed on the GUI or the hyper function of the previous K-1 input k-tuples. In
terminal. practice n and k are small integers and K is varied
For this case the data is transmitted as it is, to control the capability and complexity of the
without any encoding. Measurements of BER were code.
taken for this case and the results were evaluated. The convolutional encoder used in this project
The results are summarized in latter sections. is shown in Figure 11. The figure illustrates a
convolutional encoder with a constraint length of K
10. Transmission using Encoding/Decoding = 3. There are n = 2 modulo-2 adders; thus the
code rate k/n is ½. At each input bit time, a bit is
The encoding scheme used for the project is shifted into the leftmost stage and the bits in the
Convolutional Encoding. The decoding scheme register are shifted one position to the right. Next,
used is Viterbi Decoding. A detailed explanation of the output switch samples the output of each
these schemes and their implementation will be modulo-2 adder (i.e. first the upper adder and then
discussed in this section. the lower adder), thus forming the code symbol
by computer search for all constraint lengths less state b=10, c=01 and d=11. At each unit of time
than about 20. the trellis requires 2k-1 nodes to represent the 2k-1
Now consider that input bits, m = 101 is possible encoder states. The trellis in this example
convolutionally encoded with the encoder shown assumes a fixed periodic structure after a trellis
in Figure 11. The three message bits are inputted, depth 3 is reached (at time t4). In the general case,
one at a time, at times t1, t2 and t3. Subsequently, the fixed structure prevails after a depth K is
(K-1) = 2 zeros are inputted at times t4 and t5 to reached. At this point and thereafter, each of the
flush the register and thus ensure that the tail end states can transition to one of the two states. Of the
of the message is shifted the full length of the two outgoing branches, one corresponds to an
register. The output sequence in this case will be input bit zero and the other corresponds to an input
11 10 00 10 11, where the leftmost symbol bit one. In Figure 12, the output branch words
represents the earliest transmission. The entire corresponding to the state transitions appear as
output sequence, including the code symbols as a labels on the trellis branches.
result of flushing, is needed to decode the message. One time-interval section of a fully formed
To flush the message from the encoder requires encoding trellis structure completely defines the
one less zero than the number of stages in the code. The only reason for showing several sections
register or (K-1) flush bits. is for viewing a code-symbol sequence as a
function of time. The state of convolutional
10.1.1. Trellis Diagram encoder is represented by the contents of the right
most (K-1) stages in the encoder register.
The convolution encoding process can be
represented using a diagram called the Trellis 10.1.2 . Implementation of Convolutional Encoding
diagram. This diagram will form the basis for
decoding of the sequence on the receiving side. The packet size of the coded system was 288 bytes
The trellis diagram for a convolutional encoder since the input data bytes per packet was chosen as
with code rate ½ and K=3 is shown in Figure 12. 96 bytes. For the tests, 2000 packets are sent from
the PC to the TRF6903 valuation kit through the
serial port using the RS-232 protocol. The total
number of user data bits sent over the air is 1.536
million. The convolutional encoding algorithm is
designed to work with a data size of 2 bytes. Rate
½ convolutional encoding results in data size of 4
bytes. The encoding also results in 4 flush bits (2
for each byte). The MSP430 registers operate in
Figure 12: Encoder Trellis Diagram (rate= ½, K=3) terms of 2 bytes or a word. Thus 2 additional bytes
are needed to store the flush bits. Encoding
In drawing the trellis diagram, we use the
operation results in generating an output of 6 bytes
convention – a solid line denotes the output
for every 2 bytes input, 2 bytes input => 4 bytes
generated by an input bit zero, and a dashed line
encoded output + 2 bytes flush bits.
denotes the output generated by input bit one. The
The flowchart for implementation of
nodes of the trellis characterize the encoder states;
convolutional encoding is shown in Figure 13. The
the first row nodes correspond to the state a=00,
program first waits for the 96 bytes of the data to
the second and subsequent rows correspond to the
be available. Once the buffer is full, the first two
bytes are taken into consideration. These bytes are of Viterbi decoding is that the complexity of the
convolutionally coded using the XOR function (see Viterbi decoder is not a function of the number of
the Appendix code) and the byte counter is symbols in the codeword sequence. The algorithm
incremented by two in order to keep a track of the involves calculating a measure of similarity, or
number of bytes that have been processed. The distance, between the received signal, at a time ti ,
byte counter is then checked to see if all 96 bytes and all the trellis paths that could not possibly be
are processed. In case all 96 bytes are processed, the candidates for maximum likelihood choice.
the packet counter is incremented and checked When two paths enter the same state then the one
until 2000 packets are transmitted. On the receiver having the best metric is chosen; this path is called
side the same process is carried out for decoding as the surviving path. This selection of surviving
and the BER is evaluated. paths is performed for all states. The decoder
continues in this way to advance deeper into the
trellis, making decisions by eliminating the least
likely paths. The early rejection of the unlikely
paths reduces the decoding complexity.
10.2.2. Implementation of Viterbi Decoding contain the identical decoded bit (symbol) ‘x’
branches back in time. That is, with high
Encoding is done in chunks of 2 bytes in order to probability, all surviving sequences at time t stem
perform optimum Viterbi Decoding. The delay in from the same node at t-x. The flowchart for
decoding a longer information sequence is usually Viterbi decoding is shown in Figure 16.
too long for most practical applications. Moreover, The first 6 bytes are processed at a time from
the memory required to store the entire length of the received packet and Viterbi decoding is
surviving sequences is large and expensive. The performed until all 288 bytes are processed. The
solution is to modify the Viterbi algorithm to decoded sequence is stored in a buffer in order to
produce a fixed decoding delay without compare it with the known transmitted sequence
significantly affecting the optimal performance of for determining the BER.
the algorithm. The modification is to retain at any
given time t only the most recent ‘x’ decoded 11. Transmission using Block Interleaving
information bits (symbols) in each surviving
sequence. As each new information bit is received, In case of bit errors, encoding and decoding
a final decision is made on the bit (symbol) schemes implement necessary error correction
received ‘x’ branches back on the trellis, by technique. However, in case there is burst of errors
comparing the metrics in the surviving sequences (like in a fading channel), then the encoding and
decoding schemes do not solve the problem.
Interleaving is implemented in order to distribute a
burst of errors over the bits and appear the error to
look like bit errors rather than a burst of errors. In
other words interleaving transforms these error
bursts into statistically independent errors. On the
receiving side de-interleaving takes place before
decoding the received data.
A simple block interleaver is utilized in this
project. The encoded symbols are written column
by column into a matrix of I rows and J columns.
The number of rows is termed the interleaving
depth and the number of columns is termed the
interleaving span. The channel symbols to be
transmitted are then read row by row, and the
received coded symbols are reordered in the
reverse manner. Thus, two adjacent coded symbols
are separated by (J-1) symbols during transmission.
Since the receiver must wait until it has full matrix
Figure 16: Flowchart for Viterbi decoding before reordering the symbols, interleaving
introduces a transmission delay.
and deciding in favor of the bit in the sequence
having the largest metric. It ‘x’ is chosen 11.1 Implementation of Block Interleaving
sufficiently large, all surviving sequences will
A simple 16X144 (2304 bits) block interleaver is
used to spread the burst errors. The entire coded 12.1. Implementation of BER measurement
packet of 288 bytes (2304 bits) is stores in RAM
and then block interleaved. This operation is The BER measurement was performed by running
illustrated in Figure 17. the program in a loop and comparing the received
data with a known transmitted data. Hyper
Terminal was used to transmit data in a loop for
number of iterations and the size of data was kept 3
times larger than the original data (3X 32 bytes=
96 bytes) in order to have a larger sample size. The
reason to have a large sample size is to determine
the BER of sufficient magnitude.
Figure 17: The 16X144 block interleaver
On the receiving side, each bit is compared
with the known data bits, bit by bit and a counter
The incoming data bits are stored in the matrix
keeps track of the number of error bits. So if there
form with 16 rows and 144 columns. The data bits
are 100 error bits for 2000 iterations of 96 bytes of
are written column by column. Then RF
data (288 bytes of coded data), then the BER
transmission takes place row by row. Thus the
would be 100/ (2000X288X8) = 21.7X10-6. Based
order of transmission of bits for the above
on this a code was written for measuring the BER
arrangement shown in the figure is 1, 17,
for various distances between the transmitter and
33…..2289, 2…etc. It can be seen that the adjacent
the receiver. The results are summarized in the
bits are separated by 144 bits when transmitted.
following section.
Exactly the reverse operation takes place at the de-
interleaver. The received bits are then written row
by row and read column-wise. 13. Results
This process was iterated for 2000 times, while the the coded signal and the BER of the coded +
counter maintaining the error bits count was interleaved signal is almost the same for distances
incremented outside this loop. At the end, the between 20m~5m. However, at greater distance we
number of error bits was extracted from the can see that the BER of the coded + interleaved
program. The measurements were made for an un- data is better than the BER of the coded data alone.
coded system, coded system and for coded + The reason for this is that at greater distance the
interleaved system. fading effects of the channel are more, hence
The BER values attained during the test affecting the S/N ratio of the system by a greater
measurement are shown in Table 4. factor, and hence increasing error bursts.
Therefore, with these results it can be clearly stated
Table 4: BER values at various distances for that communication scheme such as
different schemes encoding/decoding improve the BER by forward
Distance Un-coded Coded Coded +
error correction, when compared to the un-coded
(m) Interleaved
25 142.8X10-3 125X10-3 72.5X10-3 system where the BER is high. However,
-3 -3
20 50X10 21.7X10 11.1X10-3 interleaving technique adds more robustness to bit
-3 -3
15 12.5X10 4.5X10 1.72X10-3 errors by distributing the burst of errors as
-3 -3
10 5X10 1.08X10 1.15X10-3 statistically independent errors.
-3 -3
5 10 0.2X10 0.11X10-3
The BER vs. Distance plot is shown in Figure 18. 14. Conclusion
The nature of the various curves is as expected and
can be explained. The plot was generated using A wireless communication system for indoor
MATLAB program. The BER values have been channel was successfully implemented along with
plotted on a logarithmic scale in order to see the various schemes such as convolutional encoding,
change in BER more clearly. viterbi decoding and block interleaving. Successful
measurements of BER were made for different
schemes and the performance of the system was
evaluated. A good understanding of protocols such
as RS-232 and wireless protocol was achieved. The
project served as means to explore and learn
programming techniques for a wireless system
using a transceiver and a microcontroller.
During the course of project a lot of
amendments were made to the original proposed
plan, in order to consider practical situations. One
example was using distance as a measure for S/N
ratio due to lack of means to measure the S/N of
the received signal and due to its complexity.
However, the results obtained were very consistent
Figure 18: BER (vs.) Distance Plot with the theoretical counterparts and helped in
understanding the behavior of a practical wireless
From the plot it is clear that the BER for the un- system.
coded data would be the maximum, hence making
the system prone to higher error rate. The BER for
15. References
APPENDIX
;*******************************************************************************************************
;;
; This code supports the transmition and reception of 32 data bytes and 2 checksum bytes.
; It supports an acknowledge.
; The data transmission rate is 38.4 kbit/s on the RF side
; The data transmission rate at the RS232 port is 19.2 kbit/s
;
; Written by: Ashutosh Jaiswal
; St. Mary's University, San Antonio
; Master Degree Project
; ;*******************************************************************************************************
#include "MSP430X14X.H"
NAME TRF6903_EVK
main
MOV #0300h,SP ; initialize system stack pointer
;;;;;;;;;;;;;;;;;;;;;;;
MOV #5468h,&0x0220
MOV #6973h,&0x021E
MOV #2069h,&0x021C
MOV #7320h,&0x021A
MOV #7465h,&0x0218
MOV #7374h,&0x0216
MOV #696Eh,&0x0214
MOV #6720h,&0x0212
MOV #6174h,&0x0210
MOV #2066h,&0x020E
MOV #756Ch,&0x020C
MOV #6C20h,&0x020A
MOV #7377h,&0x0208
MOV #696Eh,&0x0206
MOV #6720h,&0x0204
MOV #2020h,&0x0202
loop_main
reset_wdt
JMP loop_main ; end of the main routine
end_main
initialization
initialize_port1
MOV.B #txd,&P1OUT ; set TXD_MSP(P1.1), TXD_MSP by default high
; reset TXDATA(P1.4), DATA(P1.7), CLK(P1.6),
; STROBE(P1.5)
MOV.B #stdb_rs232+data+clk+tx+txd,&P1DIR ; switch DATA(P1.7), CLK(P1.6),
; TXDATA(P1.4), TXD(P1.1) and stdb_rs232(P1.0)
; to output dir.
MOV.B #rx+rxd,&P1SEL ; select the module function for P1.3 (TA2),
; RXD P1.2 (TA1)
initialize_port2
MOV.B #LED3,&P2OUT ; reset P2.0,CTS (-> CTS set!),
; STANDBY_TRF6903(P2.5), MODE(P2.1) ->
; receive, set LED3(P2.3), System Mode
MOV.B #stdb_trf6903+mode+cts+LED3,&P2DIR ; switch STANDBY_TRF6903(P2.5), MODE(P2.1),
; CTS(P2.0) to output, LOCKDET(P2.4) input
initialize_receive_status
CLR &data_rx_state ; reset receive status
oscillator_flag
BIC.B #02h,&IFG1 ; reset the oscillator fault flag
MOV #0Fh,wait_r ; wait 3 + Fx13 cycles
CALL #wait_x_cycles ; call the wait routine
initialize_Clock
BIS #SCG1,SR
MOV.B #0C8h,&BCSCTL2 ; SELS = 1 LFXT1CLK source for SMCLK
;-------------------------------------------------------------------------------------------------------
; programming the 4 words to TRF6903
CALL #program_DDS0_receive_learn
CALL #program_DDS1_send
CALL #program_send_FSK
CALL #program_receive_FSK_learn
initialize_CCR1_interrupt
program_DDS0_receive_learn
MOV #023h,word_h
MOV #05029h,word_l ; frequency for Mode 0, receive FSK in learn
; mode, DDS_0 settings for 904.3MHz,
; 25.6MHz system crystal, 10.7MHz IF
CALL #program_TRF6903
end_program_DDS0_receive_learn
RET
program_DDS1_send
MOV #063h,word_h
MOV #0BB21h,word_l ; frequency for Mode 1, send
; DDS_1 settings for 915MHz,
; 25.6MHz system crystal, 10.7MHz IF
CALL #program_TRF6903
end_program_DDS1_send
RET
program_send_FSK
MOV #0BCh,word_h
MOV #09E00h,word_l ; Module Mode 1, send
; 1_LNAM [bit 0..1] 00b disabled Low noise amplifier operation mode
; 1_MIX [bit 2] 0b disabled Enable Mixer
; 1_IF [bit 3] 0b disabled Enable 1st IF Amplifier
; 1_DEM [bit 4] 0b disabled Enable Limiter/Demodulator
CALL #program_TRF6903
end_program_send_FSK
RET
program_receive_FSK_learn
; MOV #0C6h,word_h
; MOV #0D99Fh,word_l ; Modulation, Module Mode 0, receive
MOV #0C7h,word_h
MOV #0199Fh,word_l ; Modulation, Module Mode 0, receive
; 0_LNAM [bit 0..1] 11b normal Low noise amplifier operation mode
; operation
; 0_MIX [bit 2] 1b enabled Enable Mixer
; 0_IF [bit 3] 1b enabled Enable 1st IF Amplifier
; 0_DEM [bit 4] 1b enabled Enable Limiter/Demodulator
; 0_RSSI [bit 5] 0b disabled Enable Limiter/RSSI
; 0_DSW [bit 6] 0b con. to Dem. LPF Amplifier input routed to Demodulator
; (FSK) or to RSSI (OOK)
; 0_LPF [bit 7] 1b enabled Enable LPF Amplifier
; 0_SLC [bit 8] 1b enabled Enable Data Slicer
; 0_PA [bit 9..10] 00b disabled Power Amplifier gain value in TX mode (see
; also MS bit)
; 0_VCO [bit 11] 1b enabled Enable VCO
; 0_PLL [bit 12] 1b enabled Enable PLL (DDS System, RF divider, Phase
; comparator and Chargepump)
; MR [bit 13..20] 0010 0110b FSK frequency deviation register (corresponds with
; 60kHz modulation)
CALL #program_TRF6903
end_program_receive_FSK_learn
RET
program_receive_FSK_hold
MOV #0BCh,word_h
MOV #01E00h,word_l ; Modulation, Module Mode 1, receive
; 1_LNAM [bit 0..1] 00b disabled Low noise amplifier operation mode
; 1_MIX [bit 2] 0b disabled Enable Mixer
; 1_IF [bit 3] 0b disabled Enable 1st IF Amplifier
; 1_DEM [bit 4] 0b disabled Enable Limiter/Demodulator
CALL #program_TRF6903
end_program_receive_FSK_hold
RET
program_TRF6903
init_high_byte
DINT
BIC.B #strobe,&P1OUT ; reset Strobe port
BIS.B #strobe,&P1DIR ; switch Strobe to output direction
MOV #02h,counter ; initialize the counter for high and low byte
MOV #08h,bits_r ; initialize bitcounter
MOV word_h,word_trf ; push the high byte to the programming buffer
SWPB word_trf ; push the low byte to the high byte, only the
; data in the low byte is relevant
JMP program_word
init_low_byte
MOV #010h,bits_r ; initialize bitcounter
MOV word_l,word_trf ; push the low byte to the programming buffer
program_word
RLC word_trf ; push the msb of the programming buffer to carry
JNC program_low
program_high
BIS.B #data,&P1OUT ; set data(P1.7)
program_clock
BIS.B #clk,&P1OUT ; generate a pulse on the clock line
BIC.B #clk,&P1OUT
program_next_bit
DEC bits_r ; decrement bit counter
JNZ program_word ; have already all bits been sent?
DEC counter ; decrement counter for low byte recognition
JNZ init_low_byte ; low byte is to be programmed
generate_strobe
BIC.B #data,&P1OUT ; reset data (P1.7)
BIT #08h,&data_rx_state ; shall the strobe pulse be suppressed?
JNZ end_program_TRF6903 ; yes suppress it
BIS.B #strobe,&P1OUT ; set strobe(P1.5)
BIC.B #strobe,&P1OUT ; clear strobe(P1.5)
BIC.B #strobe,&P1DIR ; set strobe(P1.5) to input direction
end_program_TRF6903
EINT
RET ; back to calling routine
program_low
BIC.B #data,&P1OUT ; clear data(P1.7)
JMP program_clock
send_RF
send_RF_init
DINT
EINT
send_RF_toggle
send_RF_long_bit
BIS #CPUOFF+GIE,SR ; CPU off
;------------------ Start of the start bit -------------------------------------------------------------
BIS.B #tx,&P1OUT ; start of the long start-bit 78,12µsec
; (end by the transmission of the 1st data bit)
BIS #CPUOFF+GIE,SR ; CPU off
BIC #04h,&data_rx_state ; the RS232 buffer is ready for reception
BIS #CPUOFF+GIE,SR ; CPU off
BIS #CPUOFF+GIE,SR ; CPU off
;----------------- End of the start bit ----------------------------------------------------------------
BIC.B #tx,&P1OUT ; reset TXDATA(P1.4)
BIS #CPUOFF+GIE,SR ; CPU off
send_RF_data
MOV #010h,bits_r ; init bitcounter, transmit first 16 bits
send_RF_bit_test
RLC data_r ; push the next data bit to carry
JC send_RF_high
send_RF_low
BIS #CPUOFF+GIE,SR ; CPU off
;-------------------------------- Start of the Databit -------------------------------------------------
BIC.B #tx,&P1OUT ; reset TXDATA(P1.4)
send_RF_next_word?
DEC bits_r ; decrement bit counter
JNZ send_RF_bit_test
DECD counter ; decrement word counter
JZ send_RF_LED3_on ; all data has been transmitted
JN send_RF_reset_ackn ; acknowledge has been transmitted
MOV 02FEh(counter),data_r ; get the next data word
JMP send_RF_data ; send next word
send_RF_high
BIS #CPUOFF+GIE,SR ; CPU off
;-------------------------------- Start of the Databit -------------------------------------------------
BIS.B #tx,&P1OUT ; set TXDATA(P1.4)
JMP send_RF_next_word?
send_RF_reset_ackn
BIC #020h,&data_rx_state ; reset acknoledge state
send_RF_LED3_on
BIS #CPUOFF+GIE,SR ; CPU off
BIS.B #LED3,&P2OUT ; LED3 on
end_send_RF
MOV #WDTPW+WDTHOLD,&WDTCTL ; stop Watchdog Timer
BIC.B #stdb_rs232,&P1OUT ; RS232 driver go active
BIC.B #tx,&P1OUT
BIC.B #stdb_trf6903,&P2OUT ; clear STDBY(P2.5), TRF6903 standby mode
; BIC.B #rxd,&P1IFG ; reset the interrupt flag
; BIS.B #rxd,&P1IE ; enable P1.2 Interrupt
RET
receive_RF
BIT #02h,&data_rx_state ; is the reception buffer full?
JNZ end_receive_RF ; yes the data has to be send to desktop first
CALL #program_send_FSK ; program the C-word for reception in
; learn mode
MOV #CCIE+CAP+CMNEG,&CCTL1 ; interrupt enable, capture mode, neg. edge
CLR data_r ; reset data_r
CLR wake_up_counter ; reset wake_up_counter
CLR RSTAT ; reset receive status register, RSTAT = 0,
CLR res_old_r ; detecting the Trainingssequence
BIC.B #mode,&P2OUT ; receive FSK in learn mode
BIS.B #01h,&IE1 ; enable Watchdog Timer interrupt
BIS.B #stdb_trf6903,&P2OUT ; TRF6903 active, STANDBY(P2.5) is high
CALL #wait_lockdet
MOV.B #0C0h,&BCSCTL1
MOV #TAIE+CLEAR+CONTUP+TASSEL_1,&TACTL ; interrupt enable, clear Timer_A,
; continuous up mode, ACLK as clock source
MOV #CCIE+CAP+CMANY,&CCTL2
BIS #08h,&data_rx_state ; changed from BIS for suppressing strobe pulse at the end
; of the programming routine
BIS.B #LED3,&P2OUT ; switch on the system mode LED
loop_receive_training_seq
;--------------------- scanning the received signal for the training sequence --------------------------
CMP #08h,wake_up_counter ; 8 equal pulses in succession
JL loop_receive_training_seq ; no the result is less than 8 equal pulses
; in a row
BIC #022h,&TACTL ; stop Timer_A and disable interrupt
BIC #CCIE,&CCTL2 ; disable interrupt
INCD RSTAT ; RSTAT = 4
loop_start_bit
CMP #04h,RSTAT ; has the start bit been detected?
JEQ loop_start_bit ; wait for the start bit
JN receive_RF ; the received sequence is invalid
BIC.B #rxd,&P1IE ; disable P1.2 interrupt
;----------------------------- start bit detected ------------------------------------------------------
init_rx_bit_counter
CLR bits_r ; Reset bitcounter
word_reception_loop
BIS #CPUOFF+GIE,SR ; go to sleep!
; wake up from WDT (Timer Mode, every 26µs)
; NOP ; insert for timing
; NOP ;
; NOP ;
; NOP ;
; NOP ;
; NOP
; NOP
; NOP
; XOR.B #LED3,&P2OUT ; for test purpose
BIT.B #08h,&P1IN ; is RXDATA high or low?
read_data
RLC data_r ; push carry into the data register
INC bits_r
CMP #010h,bits_r ; receive 16 bits in row
JNE word_reception_loop ; haven't received 8bits yet
store_data
INV data_r ; the received data is inverted!
MOV data_r,02FEh(counter) ; store received data to RAM
DECD counter ; next storage register
JNZ init_rx_bit_counter ; receive the next word
BIC.B #LED3,&P2OUT ; system LED off for test purpose
BIS #02h,&data_rx_state ; 2 stands for data received,
; has to be send to desktop via RS232
BIS #020h,&data_rx_state ; initialize the acknowledge state
end_receive_RF
BIC #CCIE,&CCTL2 ; disable CCR2 interrupt
BIC #022h,&TACTL ; stop Timer_A and disable interrupt
MOV #WDTPW+WDTHOLD,&WDTCTL ; stop Watchdog Timer
;CALL #checksum_r ; built checksum of received data
CALL #decode
BIC.B #stdb_trf6903,&P2OUT ; clear STDBY(P2.5), TRF6903 in standby mode
RET
rs232_send
BIT #02h,&data_rx_state ; is there any data in the reception buffer,
; which hasn't been sent to the desktop?
JZ end_rs232_send ; no the reception buffer is empty
BIC.B #cts,&P2OUT ; reset CTS !!!!
BIC.B #stdb_rs232,&P1OUT ; activate RS232 driver
MOV #032Eh,wait_r ; initialize wait register for ca. 1ms
; waiting loop
CALL #wait_x_cycles ; wait for RS232 driver ready to transmit
MOV.B #0D0h,&BCSCTL1 ; set the divider for ACLK to 2,
; high frequency oscillator
rs232_send_init
MOV.B 0223h(counter),data_r ; move the first received word into the output
; buffer
MOV #0Ah,bits_r ; send only 8bit in a row
BIS #0100h,data_r ; prepare stop bit
CLRC ; set carry, prepare startbit
RLC data_r ; prepare the output buffer for data
; transmission
rs232_send_loop
RRC data_r ; push next bit to carry for transmission
JNC rs232_send_low
rs232_send_high
BIS #CPUOFF+GIE,SR ; CPU off
BIS.B #txd,&P1OUT ; set TXD
DEC bits_r ; decrement bitcounter
JNZ rs232_send_loop
rs232_send_next_byte
DEC counter ; decrement byte counter
JNZ rs232_send_init ; get the next byte for transmission
BIC #02h,&data_rx_state ; the buffer is ready to receive from TRF6903
; the next data
JMP end_rs232_send_lp ;
rs232_send_low
BIS #CPUOFF+GIE,SR ; CPU off
BIC.B #txd,&P1OUT ; reset TXD
DEC bits_r ; decrement bitcounter
JNZ rs232_send_loop
JMP rs232_send_next_byte
end_rs232_send
DINT ;
MOV #WDTPW+WDTHOLD,&WDTCTL ; stop Watchdog Timer
BIS.B #LED3,&P2OUT ; set System LED for test purpose
RET
checksum_s
MOV #020h,counter ; initialize counter
CLR chcksum_s ; reset checksum
checksum_s_loop
ADD 0200h(counter),chcksum_s ; build checksum over all data to send
DECD counter
JNZ checksum_s_loop
MOV chcksum_s,&0222h ; save checksum
end_checksum_s
RET
checksum_r
BIT #040h,&data_rx_state ; expecting acknowledge?
JNZ end_checksum_r ; no need to built the checksum
MOV #020h,counter ; initialize counter
CLR chcksum_r ; reset checksum
checksum_r_loop
ADD 0222h(counter),chcksum_r ; build checksum over all data to send
DECD counter
JNZ checksum_r_loop
MOV chcksum_r,&0200h ; save checksum
end_checksum_r
RET
check_chcksm_s ; renamed
BIT #040h,&data_rx_state ; check if waiting for an acknowledge
JZ end_check_chcksm_s ;
CMP &0222h,&0244h ; compare the both checksums
JNE end_check_chcksm_s ; no the received data isn't valid
check_chcksm_s_ok ; renamed
MOV #06F6Bh,&0242h ; move "ok" to the first word
MOV #06F6Bh,&0240h ; test
MOV #06F6Bh,&023Eh ; test
MOV #06F6Bh,&023Ch ; test
MOV #06F6Bh,&023Ah ; test
MOV #06F6Bh,&0238h
MOV #06F6Bh,&0236h
MOV #06F6Bh,&0234h
MOV #06F6Bh,&0232h
MOV #06F6Bh,&0230h
MOV #06F6Bh,&022Eh
MOV #06F6Bh,&022Ch
MOV #06F6Bh,&022Ah
MOV #06F6Bh,&0228h
MOV #06F6Bh,&0226h
MOV #06F6Bh,&0224h
end_check_chcksm_s ; renamed
RET
check_chcksm_r_inv
BIC #02h,&data_rx_state ; reset the data package received state
BIC #020h,&data_rx_state ; reset the acknowledge to send state
end_check_chcksm_r
RET
end_wait_x_cycles
wait_lockdet
BIT.B #lockdet,&P2IN ; is the LOCKDET(P2.4) set?
JZ wait_lockdet ; not yet
end_wait_lockdet
RET
TA_INT
ADD &TAIV,PC
RETI
CC1_INT
BIC #CCIE,&CCTL1 ; disable CCR1 interrupt
rs232_init_WDT
; MOV.B #clock_neu_3,&BCSCTL2 ; set the divider for ACLK to 2,
; high frequency oscillator
MOV.B #0D0h,&BCSCTL1
MOV #WDTPW+WDTTMSEL+WDTCNTCL+07h,&WDTCTL ; Reset, Timer Mode, Password, every 52.08µs
rs232_rec_data
BIS #CPUOFF+GIE,SR ; CPU off
BIC.B #LED3,&P2OUT ; LED3 off
BIT.B #rxd,&P1IN ; is the rx line high, or low?
rs232_push_buffer
RRC data_r ; push carry to reception buffer
DEC bits_r ; decrement bit counter
JNZ rs232_rec_data ; read the next bit
rs232_stop_bit
BIS #CPUOFF+GIE,SR ; CPU off
BIS #04h,&data_rx_state ; set the data reception state to received!
MOV #WDTPW+WDTHOLD,&WDTCTL ; stop watchdog timer
end_CC1_INT
MOV #WDTPW+WDTHOLD,&WDTCTL ; stop watchdog timer
BIS #040h,&data_rx_state ; set the status on waiting for acknowledge
keep_sending
CALL #send_RF ; send the received data out
;BIS #04h,&data_rx_state ; the RS232 buffer is ready for reception
MOV #108h,counter ; init counter
MOV #0FFFFh,wait_r
CALL #wait_x_cycles
MOV #0FFFFh,wait_r
CALL #wait_x_cycles
MOV #0FFFFh,wait_r
CALL #wait_x_cycles
; MOV #0FFFFh,wait_r
; CALL #wait_x_cycles
DEC R7
JNZ keep_sending
POP R7
CC2_INT
;MOV.B #0F0h,&BCSCTL1 ;ACLK/8
MOV.B #0C0h,&BCSCTL1 ;ACLK/1
MOV #WDTPW+07h+WDTCNTCL+WDTTMSEL,&WDTCTL ; ACLK, ca.106ms, Timer Mode, Reset
; MOV #WDTPW+WDT26MS+WDTCNTCL+WDTTMSEL,&WDTCTL ; ACLK, ca.106ms, Timer Mode, Reset
MOV RRFTAB(RSTAT),PC ; conditional jump depends on RSTAT
; RSTAT = 0, detecting the Trainingsequence
; RSTAT = 1, Trainingsquence detected, waiting
; for the Start Bit
; RSTAT = 2, Start Bit detected, Data Reception
RRFTAB DW RSTAT00
DW RSTAT01
DW RSTAT10
RSTAT00
MOV &CCR2,res_new_r ; save Reference Capture value
MOV res_new_r,res_r ; copy Timer_A value
SUB res_old_r,res_r ; subtract the current Timer_A value from the
; old one -> Bitwidth in cycles in res_r
MOV res_new_r,res_old_r ; current value now -> old value later
test_res_r00
SUB #038h,res_r ; subtract the average value from the
; measured value
CMP #010h,res_r ; is the detected signal 51-63 cycles long?
JHS no_valid_pulse
INCD RSTAT ; first valid pulse detected
INC wake_up_counter ; count this valid pulse
BIC #CPUOFF,0(SP) ; wake up!
RETI
no_valid_pulse
CLR RSTAT ; no the signal doesn't fit the wakeup sequence
CLR wake_up_counter ; reset the wake_up_counter, received an
; invalid pulse
;BIC #CPUOFF,0(SP) ; wake up!
RETI
RSTAT01
MOV &CCR2,res_new_r ; save Reference Capture value
MOV res_new_r,res_r ; copy Timer_A value
SUB res_old_r,res_r ; subtract the current Timer_A value from the
; old one -> Bitwidth in cycles in res_r
MOV res_new_r,res_old_r ; current value now -> old value later
test_res_r01
SUB #038h,res_r ; subtract the average value from the
; measured value
CMP #010h,res_r ; is the detected signal 51-63 cycles long?
JHS no_valid_pulse
INC wake_up_counter ; next valid pulse
RETI
RSTAT10
MOV &CCR2,res_new_r ; save Reference Capture value
MOV res_new_r,res_r ; copy Timer_A value
SUB res_old_r,res_r ; subtract the current Timer_A value from
; the old one -> Bitwidth in cycles in res_r
MOV res_new_r,res_old_r ; current value now -> old value later
test_res_r10
SUB #0ACh,res_r ; subtract the average value from the
; measured value
no_start_bit
INC wake_up_counter ; count the pulses of the trainings sequence,
; to terninate at least after 8ms
CMP #02Fh,wake_up_counter ; compare the value of the counter with the 2.5.2000
; maximum value of the pulses of the trainings
; sequence
JGE invalid_bit ;
; BIC #CPUOFF,0(SP) ; wake up! 27.4.2000
RETI
invalid_bit
CMP #08h,wake_up_counter ; to avoid errors during the first run
27.4.2000
JEQ invalid_bit_end ; skip clearing RSTAT
27.4.2000
CLR RSTAT ; restart the detection, this is not a valid
; sequence
CLR wake_up_counter ; initialize the wake_up_counter
invalid_bit_end
; BIC #CPUOFF,0(SP) ; wake up! 27.4.2000
RETI
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;CONVOLUTIONAL ENCODING IMPLEMENTATION
;This routine implements convolutinal encoding before transmitting the data over the air
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
encode
MOV SP, &9F6h ; preliminary housekeeping
MOV #9F6h, SP
PUSH SR
PUSH R4
PUSH R5
PUSH R6
PUSH R7
PUSH R8
PUSH R9
PUSH R10
PUSH R11
PUSH R12
PUSH R13
PUSH R14
PUSH R15
MOV #40h,R12
MOV #20h, R15
MOV #20h, R14
loop1
MOV 0200h(R15),R4
okay
MOV R4, R5
MOV 0200h(R14),R13
DECD R14
RLA R5
RLC R13
ADC R5
MOV R5, R6
RLA R6
RLC R13
ADC R6
XOR R4, R6
XOR R6, R5
okay_1
MOV #8h,R11
loop2
loop3
RRC R6 ; makes 2nd output word
RRC R8 ; in R8
RRC R5
RRC R8
DEC R11
JNZ loop3
;MOV R7,342h(R12)
DECD R12
MOV R8,300h(R12) ; puts 2nd OW in mem to send
;MOV R8,342h(R12)
DECD R12
DECD R15
JNZ loop1
; flush bits
MOV R4,R5 ; setting up to XOR for
MOV R4,R6 ; last 2 bits.
; RRA R4
; RRA R4
; RRA R5
CLRC
RRC R4
CLRC
RRC R4
CLRC
RRC R5
XOR R4,R6
XOR R6,R5
CLR R7 ; clearing R7 to recv flush bits
RLC R5 ; extracting 7 encoding
RLC R7
RLC R6 ; extracting 5 encoding
RLC R7 ; R5 holds 7 encode
RLC R5 ; R6 holds 5 encode
RLC R7 ; rotating left to put at front
RLC R6 ; of R7
RLC R7
MOV R7,&300h
;MOV R7,&342h
CALL #decode
RET
CLR &9F8h
CLR &9FAh
CLR &9FCh
CLR &9FEh
wloop
MOV 0300h(R15), R10 ; get encoded word to work on
inner1
here0
RRC R9 ; saving AE11(n+1)
RRC R7 ; *
RRC R9 ; *
RRC R7 ; *
RLA R11 ; capturing pred state for state 11
RLA R11 ; *
ADD #0003h, R11 ; *
here2
RRC R9 ; saving AE10(n+1)
RRC R7 ; *
RRC R9 ; *
RRC R7 ; *
RLA R11 ; capturing pred state for state 10
RLA R11 ; *
ADD #0001h, R11 ; *
ADC R12 ; *
RRC R8 ; *
ADC R12 ; *
MOV R12, R8 ; *
ADD R4, R8 ; adds AE10(n)
; AE01(n+1) path1 in R8
here4
RRC R9 ; saving AE01(n+1)
RRC R7 ; *
RRC R9 ; *
RRC R7 ; *
RLA R11 ; capturing pred state for state 01
RLA R11 ; *
ADD #0003h, R11 ; *
RRC R7 ; *
RRC R8 ; *
RRC R7 ; *
RLA R11 ; capturing pred state for state 00
RLA R11 ; *
ADD #0000h, R11 ; *
JMP here7
here6
RRC R9 ; saving AE00(n+1)
RRC R7 ; *
RRC R9 ; *
RRC R7 ; *
RLA R11 ; capturing pred state for state 00
RLA R11 ; *
ADD #0001h, R11 ; *
here7
CLR R4 ; saving AE00(n+1)
RLC R7 ; *
RLC R4 ; *
RLC R7 ; *
RLC R4 ; *
MOV R4, &9F8h ; *
inner_1
RRC R10 ; *
RLC R8 ; *
RLC R6 ; *
RLC R8 ; *
MOV R8, R6 ; R8 collects AE 4 path 1 to AE11(n+1)
MOV R8, R9 ; R9 collects AE 4 path 2 to AE11(n+1)
; C0(n) in R8 and R9
XOR #0001h, R8 ; counts digits diff w/ PW into R8
CLR R12 ; *
RRC R8 ; *
ADC R12 ; *
RRC R8 ; *
ADC R12 ; *
MOV R12, R8 ; *
ADD R4, R8 ; adds AE10(n)
; AE11(n+1) path1 in R8
here_0
RRC R9 ; saving AE11(n+1)
RRC R7 ; *
RRC R9 ; *
RRC R7 ; *
RLA R11 ; capturing pred state for state 11
RLA R11 ; *
ADD #0003h, R11 ; *
ADC R12 ; *
RRC R9 ; *
ADC R12 ; *
MOV R12, R9 ; *
ADD R5, R9 ; adds AE01(n)
; AE10(n+1) path2 in R9
here_2
RRC R9 ; saving AE10(n+1)
RRC R7 ; *
RRC R9 ; *
RRC R7 ; *
RLA R11 ; capturing pred state for state 10
RLA R11 ; *
ADD #0001h, R11 ; *
here_4
RRC R9 ; saving AE01(n+1)
RRC R7 ; *
RRC R9 ; *
RRC R7 ; *
RLA R11 ; capturing pred state for state 01
RLA R11 ; *
ADD #0003h, R11 ; *
here_6
RRC R9 ; saving AE00(n+1)
RRC R7 ; *
RRC R9 ; *
RRC R7 ; *
RLA R11 ; capturing pred state for state 00
RLA R11 ; *
ADD #0001h, R11 ; *
here_7
CLR R4 ; saving AE00(n+1)
RLC R7 ; *
RLC R4 ; *
RLC R7 ; *
RLC R4 ; *
MOV R4, &9F8h ; *
MOV #0000h, R4
POP R5
MOV R5,R6
SWPB R6
AND #00FFh, R5
AND #00FFh, R6
CMP #0000h, R4
JNE yippee
AND #0003h, R5
MOV R5, R7
JMP woohoo
yippee
CMP #0001h, R4
JNE yippee1
RRA R5
RRA R5
AND #0003h, R5
MOV R5, R7
JMP woohoo
yippee1
CMP #0002h, R4
JNE yippee2
RRA R5
RRA R5
RRA R5
RRA R5
AND #0003h, R5
MOV R5, R7
JMP woohoo
yippee2
RRA R5
RRA R5
RRA R5
RRA R5
RRA R5
RRA R5
MOV R5, R7
woohoo
MOV R7, R4
CMP #0000h, R4
JNE yippee3
AND #0003h, R6
MOV R6, R7
JMP woohoo1
yippee3
CMP #0001h, R4
JNE yippee4
RRA R6
RRA R6
AND #0003h, R6
MOV R6, R7
JMP woohoo1
yippee4
CMP #0002h, R4
JNE yippee5
RRA R6
RRA R6
RRA R6
RRA R6
AND #0003h, R6
MOV R6, R7
JMP woohoo1
yippee5
RRA R6
RRA R6
RRA R6
RRA R6
RRA R6
RRA R6
MOV R6, R7
woohoo1
MOV R7, R4
; ENCODED BIT
MOV #0020h, R15 ; Set to total number of bytes of original uncoded message
MOV #0002h, R13
loopiest
MOV #0008h, R14
CLR R8
loopy POP R5
MOV R5, R6
SWPB R6
AND #00FFh, R5
AND #00FFh, R6
CMP #0000h, R4
JNE yippee_
AND #0003h, R5
MOV R5, R7
JMP woohoo_
yippee_
CMP #0001h, R4
JNE yippee1_
RRA R5
RRA R5
AND #0003h, R5
MOV R5, R7
JMP woohoo_
yippee1_
CMP #0002h, R4
JNE yippee2_
RRA R5
RRA R5
RRA R5
RRA R5
AND #0003h, R5
MOV R5, R7
JMP woohoo_
yippee2_
RRA R5
RRA R5
RRA R5
RRA R5
RRA R5
RRA R5
MOV R5, R7
woohoo_
CMP R7, R4
JNE not_equal
CMP #0000h, R7
JNE equals_3
CLRC
JMP done_is_done
equals_3
SETC
JMP done_is_done
not_equal
JL _less
SETC
JMP done_is_done
_less
CLRC
done_is_done
RLC R8
MOV R7, R4
; Repeat R5 process on R6
CMP #0000h, R4
JNE yippee3_
AND #0003h, R6
MOV R6, R7
JMP woohoo1_
yippee3_
CMP #0001h, R4
JNE yippee4_
RRA R6
RRA R6
AND #0003h, R6
MOV R6, R7
JMP woohoo1_
yippee4_
CMP #0002h, R4
JNE yippee5_
RRA R6
RRA R6
RRA R6
RRA R6
AND #0003h, R6
MOV R6, R7
JMP woohoo1_
yippee5_
RRA R6
RRA R6
RRA R6
RRA R6
RRA R6
RRA R6
MOV R6, R7
woohoo1_
CMP R7, R4
JNE not_equal_
CMP #0000h, R7
JNE equals_3_
CLRC
JMP done_is_done_
equals_3_
SETC
JMP done_is_done_
not_equal_
JL _less_
SETC
JMP done_is_done_
_less_
CLRC
done_is_done_
RLC R8
MOV R7, R4
DEC R14
JNZ loopy
MOV R8, 0222h(R13)
INCD R13
DECD R15
JNZ loopiest
wrap_up
POP R15 ; wrapping up
POP R14
POP R13
POP R12
POP R11
POP R10
POP R9
POP R8
POP R7
POP R6
POP R5
POP R4
POP SR
POP SP
RET
WDT_INT
BIC #CPUOFF,0(SP) ; reactivate CPU
RETI
reset
RSEG INTVEC
DW START ; 0FFE0h not used
DW START ; 0FFE2h not used
DW START ; 0FFF4h P1_INT
DW START ; 0FFE6h I/O Port P2
DW START ; 0FFE8h not used
DW TA_INT ; 0FFEAh timer A1(CC1,CC2)
DW START ; 0FFECh not used
DW START ; 0FFEEh not used
DW START ; 0FFF0h not used
DW START ; 0FFF2h CC0_INT
DW WDT_INT ; 0FFF4h Watchdog Timer in timer mode
DW START ; 0FFF6h not used
DW START ; 0FFF8h not used
DW START ; 0FFFAh not used
DW START ; 0FFFCh NMI, Oscillator fault
DW START ; 0FFFEh Power On Reset, WDTIFG
END main