1 |
3 |
kingmu |
Manchester Wireless Core
|
2 |
|
|
|
3 |
|
|
================================= Overview ====================================
|
4 |
|
|
|
5 |
|
|
This core was created to serve as a decoder for incoming Manchester encoded
|
6 |
|
|
data. This project was developed using an ASK A315 transmitter/receiver pair
|
7 |
|
|
obtained from Sparkfun.com. The transmitter was driven by an Atmel AVR
|
8 |
|
|
microcontroller. The receiver's output was was plugged into a Xilinx Spartan-3
|
9 |
|
|
starter board obtained from Digilent.
|
10 |
|
|
|
11 |
|
|
The ASK equipment is convenient in that when the input of the transmitter is
|
12 |
|
|
driven high, the output will also go high, and when the input goes low, the
|
13 |
|
|
output goes low. There is a caveat, however. The receiver's input must make
|
14 |
|
|
high/low transitions at a certain minimum frequency to prevent the receiver
|
15 |
|
|
from outputting random garbage. Furthermore, there is a maximum frequency at
|
16 |
|
|
which these transmitter/receiver pair will operate.
|
17 |
|
|
|
18 |
|
|
In brief, the Manchester encoding is trivial: 0 is converted to 10 and 1 is
|
19 |
|
|
converted to 01, where 0 and 1 refer to sending the data line of the ASK
|
20 |
|
|
transmitter low (0) or high (1) for one bit length. When programming the
|
21 |
|
|
microcontroller it was easiest to shift the bits of the message off to the
|
22 |
|
|
right and encode/transmit one bit at a time. Take the binary string 1000, for
|
23 |
|
|
example. The first zero is shifted off, and 10 is sent. Likewise, the other two
|
24 |
|
|
zeros are shifted off and sent. Finally the 1 is sent as 01. This gives a
|
25 |
|
|
transmission of 10101001. Note the encoded bits are are in reverse order of the
|
26 |
|
|
original; when the Manchester Wireless Core decodes the bits, it will present
|
27 |
|
|
them in the correct order as 1000.
|
28 |
|
|
|
29 |
|
|
Because of the asynchronous nature of the input, the challenge is in the
|
30 |
|
|
receiving side. To send a message, then, this core defines a protocol that must
|
31 |
|
|
be adhered to. First, the transmitter sends four high bits. Then the
|
32 |
|
|
transmitter sends one low bit. Then the data stream begins. Finally a few "end
|
33 |
|
|
transmission" bits are sent. Continuing the example above, the total message
|
34 |
|
|
would be :
|
35 |
|
|
|
36 |
|
|
11110 10101001 0101
|
37 |
|
|
start signal begin data stream begin end transmission
|
38 |
|
|
|
39 |
|
|
Note that the spaces between the 0's and 1's are added for readability.
|
40 |
|
|
|
41 |
|
|
|
42 |
|
|
|
43 |
|
|
================================= User's Guide ====================================
|
44 |
|
|
|
45 |
|
|
The file globals.vhd has the constants which must be configured by the user.
|
46 |
|
|
|
47 |
|
|
Those constants are
|
48 |
|
|
|
49 |
|
|
WORD_LENGTH : The number of data bits before encoding. In the overview, above,
|
50 |
|
|
the WORD_LENGTH was four bits.
|
51 |
|
|
|
52 |
|
|
INTERVAL_MIN/MAX_SINGLE, INTERVAL_MIN/MAX_DOUBLE : The number of FGPA clock
|
53 |
|
|
cycles that must pass before the algorithm classifies a single/double/quadruple
|
54 |
|
|
one/zero. For example if the transmitter bit length is 1 ms and the FPGA clock
|
55 |
|
|
is 50 MHz, then the nominal number of FPGA cycles required to classify a bit as
|
56 |
|
|
being a single is 1 ms / (1/50E6 cycles/second) = .001/2E-8 cycles = 50000
|
57 |
|
|
cycles. The transmission, for whatever reasons, will not be exactly 1 ms, which
|
58 |
|
|
is the reason for having a MIN and MAX interval for the single/double and
|
59 |
|
|
quadruple constants. Some experimentation may be necessary to get the best
|
60 |
|
|
performance from this core. It is recommended that you synthesize the
|
61 |
|
|
singleDouble.vhd module, which classifies single/double zeros/ones and see
|
62 |
|
|
which windows will provide the best performance.
|
63 |
|
|
|
64 |
|
|
INTERVAL_QUADRUPLE : The series of ones at the beginning of the transmission
|
65 |
|
|
must be at least INTERVAL_QUADRUPLE cycles. To get this constant, multiply the
|
66 |
|
|
nominal single bit length by four and add some padding.
|
67 |
|
|
|
68 |
|
|
Out of the box, the manchesterWireless core will decode one message, then set
|
69 |
|
|
the ready_o flag, then stop. The core must be reset to start waiting for the
|
70 |
|
|
next message. See synthTest.vhd for an example of how to use this core.
|
71 |
|
|
synthTest.vhd is used to create a simple counter which waits for and displays
|
72 |
|
|
the digits 0 to 9 on the LEDs of the Spartan-3 board.
|
73 |
|
|
|
74 |
|
|
|
75 |
|
|
|
76 |
|
|
================================= Design ====================================
|
77 |
|
|
|
78 |
|
|
manchesterWireless is composed of three modules which flow from the top down:
|
79 |
|
|
|
80 |
|
|
1)waitForStart : Waits for the data_i to go high for INTERVAL_QUADRUPLE
|
81 |
|
|
cycles then sets ready_o to 1. One process is in wait for start. When data_i
|
82 |
|
|
goes high, a counter will measure how long it stays high. If data_i stays high
|
83 |
|
|
for longer than INTERVAL_QUADRUPLE clocks then the ready_o flag is set and
|
84 |
|
|
remains set until the core is reset; the 'lock' variable keeps the flag set
|
85 |
|
|
after the window is reached. If data_i drops to zero before the ready_o flag is
|
86 |
|
|
set, then the counter will be set to zero.
|
87 |
|
|
|
88 |
|
|
2)singleDouble : Once waitForStart is finished, singleDouble classifies
|
89 |
|
|
single/double zeros/ones which it outputs on q_o. q_o is a four bit vector
|
90 |
|
|
with the following mapping
|
91 |
|
|
|
92 |
|
|
q_o(0) <= single_one;
|
93 |
|
|
q_o(1) <= double_one;
|
94 |
|
|
q_o(2) <= single_zero;
|
95 |
|
|
q_o(3) <= double_zero;
|
96 |
|
|
|
97 |
|
|
|
98 |
|
|
The constants set in globals.vhd are such that there is never an overlap
|
99 |
|
|
between what is classified as a single or a double.
|
100 |
|
|
|
101 |
|
|
TODO: The transition process infers a clock from transition_i. This should
|
102 |
|
|
probably be eliminated by polling transition_i on a clock edge.
|
103 |
|
|
|
104 |
|
|
3)decode : Takes serial input from singleDouble and provides a decoded parallel
|
105 |
|
|
output. The controller process counts how many bits have been decoded and
|
106 |
|
|
stops when all of the message has been encoded. The next_state_decode and
|
107 |
|
|
output_decode processes keep track of the bits coming from singleDouble and
|
108 |
|
|
decodes them. The challenge is that we receive a single_one followed by a
|
109 |
|
|
double_zero, that is 100, we will decode a 0 from the 10 and place the last
|
110 |
|
|
zero in 100 in the left most place of the insert buffer "0_". At this point,
|
111 |
|
|
as can be seen by inspecting the next_state_decode process, only a single
|
112 |
|
|
or double one is possible.
|
113 |
|
|
|
114 |
|
|
TODO: The next_state_decode process will reset when an unexpected next_state
|
115 |
|
|
is provided. For example, from the state one_0, the only possible valid
|
116 |
|
|
next state is one_1. Any other next_state will send the FSM to reset. It
|
117 |
|
|
would be good to reset the entire circuit at this point.
|