-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathmodem.c
118 lines (104 loc) · 3.42 KB
/
modem.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
//#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 24
#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))
/**
* 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_tx(int64_t bits, uint8_t pktStart, uint8_t pktEnd,
uint8_t isHead, uint8_t puncture, uint8_t modulation) {
return bits | (pktStart & 0x1) << BITS_WIDTH |
(pktEnd & 0x1) << (BITS_WIDTH + 1) |
(isHead & 0x1) << (BITS_WIDTH + 2) |
(puncture & 0xf) << (BITS_WIDTH + 3) |
(modulation & 0x3) << (BITS_WIDTH + PUNCTURE_WIDTH + 3);
}
/*
* 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 packSignal = pack_modem_tx(0xd30080, 1, 0, 1, 0xd, 0);
uint64_t packService = pack_modem_tx(0xf0f0f0, 0, 0, 0, 0xd, 0);
uint64_t packData = pack_modem_tx(data, 0, 1, 0, 0xd, 0);
// Write data
while(reg_read8(TX_WRITE_COUNT) > 4) {
printf("Waiting for cordic queue to empty...\n");
}
reg_write64(TX_WRITE, packSignal);
reg_write64(TX_WRITE, packService);
reg_write64(TX_WRITE, packData);
// Read SIGNAL
while (reg_read8(TX_READ_COUNT) == 0) {
printf("Waiting for read queue...\n");
}
uint64_t result = reg_read64(TX_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(TX_READ_COUNT) == 0) {
printf("Waiting for read queue...\n");
}
result = reg_read64(TX_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(TX_READ_COUNT) == 0) {
printf("Waiting for read queue...\n");
}
result = reg_read64(TX_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;
}