-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathrx.c
171 lines (149 loc) · 4.71 KB
/
rx.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#define RX_WRITE 0x2000
#define RX_WRITE_COUNT 0x2008
#define RX_READ 0x2100
#define RX_READ_COUNT 0x2108
//#define TX_WRITE 0x2000
//#define TX_WRITE_COUNT 0x2008
//#define TX_READ 0x2100
//#define TX_READ_COUNT 0x2108
#include <stdio.h>
#include "mmio.h"
/**
* Make sure these #defines are correct for your chosen parameters.
* You'll get really strange (and wrong) results if they do not match.
*/
#define BITS_WIDTH 8
#define BITS_MASK ((1L << BITS_WIDTH) - 1)
#define PKT_START_MASK (1L << BITS_WIDTH)
#define PKT_END_MASK (1L << (BITS_WIDTH + 1))
#define IS_HEAD_MASK (1L << (BITS_WIDTH + 2))
#define PUNCTURE_WIDTH 4
#define PUNCTURE_MASK (((1L << PUNCTURE_WIDTH) - 1) << (BITS_WIDTH + 3))
#define MODULATION_MASK (3L << (BITS_WIDTH + PUNCTURE_WIDTH + 3))
#define FP1 (1L << 13)
#define FPM1 (0xd000)
/**
* Pack modem fields into 64-bit unsigned integer.
* Make sure the #defines above are correct!
* You will need to pack into multiple uint64_t if 2 * XY_WIDTH + Z_WIDTH + 1 > 64
*/
uint64_t pack_modem_rx(int16_t inphase, int16_t quadrature) {
return quadrature | (inphase << 16);
}
/*
* Unpack output of modem and get an integer version of bits.
*/
uint64_t unpack_rx_bits(uint64_t packed) {
return packed & BITS_MASK;
}
/*
* Unpack output of modem and get the pktStart flag.
*/
uint8_t unpack_rx_pktStart(uint64_t packed) {
return (packed >> BITS_WIDTH) & 0x1;
}
/*
* Unpack output of modem and get the pktEnd flag.
*/
uint8_t unpack_rx_pktEnd(uint64_t packed) {
return (packed >> (BITS_WIDTH + 1)) & 0x1;
}
void run_modem(uint64_t data) {
// SIGNAL field
// rate 6Mbps, R, length 6, parity, 0s
// 1101 0 011000000000 1 000000
uint64_t packPlusPlus = pack_modem_rx(FP1, FP1);
uint64_t packPlusMinus = pack_modem_rx(FP1, FPM1);
uint64_t packMinusPlus = pack_modem_rx(FPM1, FP1);
uint64_t packMinusMinus = pack_modem_rx(FPM1, FPM1);
// Write data
int i, write_count;
// Write STF
for (i=0; i < 80; ++i) {
while((write_count = reg_read8(RX_WRITE_COUNT)) > 6) {
printf("Waiting for modem queue (%d) to empty...\n", write_count);
}
reg_write64(RX_WRITE, packPlusPlus);
reg_write64(RX_WRITE, packMinusMinus);
}
// Write LTF
for (i=0; i < 80; ++i) {
while((write_count = reg_read8(RX_WRITE_COUNT)) > 6) {
printf("Waiting for modem queue (%d) to empty...\n", write_count);
}
reg_write64(RX_WRITE, packPlusMinus);
reg_write64(RX_WRITE, packMinusPlus);
}
// Write SIGNAL
for (i=0; i < 80; ++i) {
while((write_count = reg_read8(RX_WRITE_COUNT)) > 6) {
printf("Waiting for modem queue (%d) to empty...\n", write_count);
}
reg_write64(RX_WRITE, packPlusPlus);
reg_write64(RX_WRITE, packMinusPlus);
}
// Write SERVICE
for (i=0; i < 80; ++i) {
while((write_count = reg_read8(RX_WRITE_COUNT)) > 6) {
printf("Waiting for modem queue (%d) to empty...\n", write_count);
}
reg_write64(RX_WRITE, packMinusMinus);
reg_write64(RX_WRITE, packMinusPlus);
}
// Write DATA
for (i=0; i < 80; ++i) {
while((write_count = reg_read8(RX_WRITE_COUNT)) > 6) {
printf("Waiting for modem queue (%d) to empty...\n", write_count);
}
reg_write64(RX_WRITE, packPlusMinus);
reg_write64(RX_WRITE, packPlusPlus);
}
// Write zeros to end packet
for (i=0; i < 80; ++i) {
while((write_count = reg_read8(RX_WRITE_COUNT)) > 0) {
printf("Waiting for modem queue (%d) to empty...\n", write_count);
}
reg_write64(RX_WRITE, 0LL);
reg_write64(RX_WRITE, 0LL);
reg_write64(RX_WRITE, 0LL);
reg_write64(RX_WRITE, 0LL);
reg_write64(RX_WRITE, 0LL);
reg_write64(RX_WRITE, 0LL);
}
// Read SIGNAL
while (reg_read8(RX_READ_COUNT) == 0) {
printf("Waiting for read queue...\n");
}
uint64_t result = reg_read64(RX_READ);
printf("packet start: %d\n", unpack_rx_pktStart(result));
printf("packet end: %d\n", unpack_rx_pktEnd(result));
printf("packet SIGNAL: %u\n", unpack_rx_bits(result));
// Read SERVICE
while (reg_read8(RX_READ_COUNT) == 0) {
printf("Waiting for read queue...\n");
}
result = reg_read64(RX_READ);
printf("packet start: %d\n", unpack_rx_pktStart(result));
printf("packet end: %d\n", unpack_rx_pktEnd(result));
printf("packet SERVICE: %u\n", unpack_rx_bits(result));
// Read DATA
while (reg_read8(RX_READ_COUNT) == 0) {
printf("Waiting for read queue...\n");
}
result = reg_read64(RX_READ);
printf("packet start: %d\n", unpack_rx_pktStart(result));
printf("packet end: %d\n", unpack_rx_pktEnd(result));
printf("packet DATA: %u\n", unpack_rx_bits(result));
}
int main(void)
{
int write_cnt;
printf("starting...\n");
// Send HI!
uint64_t data = 0x484921;
run_modem(data);
// Send Cat
data = 0x436174;
run_modem(data);
return 0;
}