-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzigbee_txer.m
142 lines (112 loc) · 4.95 KB
/
zigbee_txer.m
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
function [waveform, txSyms, numPkt] = zigbee_txer(txBits, OSR, ifWEBeeTweak)
persistent chipLen
persistent chipMap
persistent SHR
persistent PHR
persistent pulse
persistent numSampPerWiFiCP
persistent numBitPerPHYPayload
persistent numBytePerPHYPayload
persistent flipQFactor
if isempty(chipLen)
chipLen = 32;
end
if isempty(chipMap)
% See Table 73 in IEEE 802.15.4, 2011 revision
chipMap = ...
[1 1 0 1 1 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1 0 0 1 0 0 0 1 0 1 1 1 0;
1 1 1 0 1 1 0 1 1 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1 0 0 1 0 0 0 1 0;
0 0 1 0 1 1 1 0 1 1 0 1 1 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1 0 0 1 0;
0 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1 1 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1;
0 1 0 1 0 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1 1 0 0 1 1 1 0 0 0 0 1 1;
0 0 1 1 0 1 0 1 0 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1 1 0 0 1 1 1 0 0;
1 1 0 0 0 0 1 1 0 1 0 1 0 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1 1 0 0 1;
1 0 0 1 1 1 0 0 0 0 1 1 0 1 0 1 0 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1;
1 0 0 0 1 1 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0 1 1;
1 0 1 1 1 0 0 0 1 1 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 1 1 1 0 1 1 1;
0 1 1 1 1 0 1 1 1 0 0 0 1 1 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 1 1 1;
0 1 1 1 0 1 1 1 1 0 1 1 1 0 0 0 1 1 0 0 1 0 0 1 0 1 1 0 0 0 0 0;
0 0 0 0 0 1 1 1 0 1 1 1 1 0 1 1 1 0 0 0 1 1 0 0 1 0 0 1 0 1 1 0;
0 1 1 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0 1 1 1 0 0 0 1 1 0 0 1 0 0 1;
1 0 0 1 0 1 1 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0 1 1 1 0 0 0 1 1 0 0;
1 1 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0 1 1 1 0 0 0];
end
if isempty(numBitPerPHYPayload)
% According to WEBee, each ZigBee packet's PHY payload contains 96 bits (i.e., 24 symbols).
numBitPerPHYPayload = 96;
numBytePerPHYPayload = numBitPerPHYPayload / 8;
end
if isempty(SHR)
% Synchronization header (SHR)
% Preamble is 4 octets, all set to 0.
preamble = zeros(4 * 8, 1);
% Start-of-frame delimiter (SFD)
SFD = [1 1 1 0 0 1 0 1]'; % value from standard (see Fig. 68, IEEE 802.15.4, 2011 Revision)
SHR = [preamble; SFD];
end
if isempty(PHR)
% PHY Header (PHR)
reservedValue = 0;
PHR = [int2bit(numBytePerPHYPayload, 7, false); reservedValue];
end
if isempty(pulse)
% Half-period sine wave
pulse = sin(0:pi / OSR:(OSR - 1) * pi / OSR);
end
% Start to generate waveforms
numPkt = ceil(length(txBits) / numBitPerPHYPayload);
if mod(length(txBits), numBitPerPHYPayload) > 0
numPadBits = numBitPerPHYPayload * numPkt - length(txBits);
txBits = [txBits, zeros(1, numPadBits)];
end
txBits = reshape(txBits, [numBitPerPHYPayload, numPkt]);
numSymPerPkt = (length(SHR) + length(PHR) + numBitPerPHYPayload) / 4;
txSyms = zeros(numSymPerPkt, numPkt);
numSampPerPkt = numSymPerPkt * OSR * 16 + OSR / 2;
waveform = zeros(numSampPerPkt, numPkt);
if isempty(flipQFactor) && ifWEBeeTweak == true
flipQFactor = [-1 * ones(1, 10), ones(1, (4 * OSR - 10))];
flipQFactor = repmat(flipQFactor, 1, (numSampPerPkt - OSR / 2) / length(flipQFactor));
flipQFactor = [ones(1, OSR / 2), flipQFactor]';
else
flipQFactor = ones(1, 4 * OSR);
flipQFactor = repmat(flipQFactor, 1, (numSampPerPkt - OSR / 2) / length(flipQFactor));
flipQFactor = [ones(1, OSR / 2), flipQFactor]';
end
for ithPkt = 1:1:numPkt
% PHY protocol data unit:
PPDU = [SHR; PHR; txBits(:, ithPkt)];
% pre-allocate matrix for performance
chips = zeros(chipLen, length(PPDU) / 4);
for idx = 1:length(PPDU) / 4
% Bit to symbol mapping
currBits = PPDU(1 + (idx - 1) * 4:idx * 4);
symbol = bit2int(currBits, 4, false);
txSyms(idx, ithPkt) = symbol;
% Symbol to chip mapping
chips(:, idx) = chipMap(1 + symbol, :)'; % +1 for 1-based indexing
end
% O-QPSK modulation
% split two 2 parallel streams, also map [0, 1] to [-1, 1]
oddChips = chips(1:2:end) * 2 - 1;
evenChips = chips(2:2:end) * 2 - 1;
% Half-sine pulse filtering
filteredReal = pulse' * oddChips; % each column is now a filtered pulse
filteredImag = pulse' * evenChips; % each column is now a filtered pulse
re = [filteredReal(:); zeros(round(OSR / 2), 1)];
im = [zeros(round(OSR / 2), 1); filteredImag(:)];
% Quadrant flipping of WEBee.
im = im .* flipQFactor;
waveform(:, ithPkt) = complex(re, im);
end
% CP flipping of WEBee.
if isempty(numSampPerWiFiCP)
numSampPerWiFiCP = 16;
end
if ifWEBeeTweak == true
for ith = 2:2:(numSymPerPkt * 4)
waveform(((ith - 1) * 80 + 1):((ith - 1) * 80 + numSampPerWiFiCP), :) = ...
waveform((ith * 80 - numSampPerWiFiCP + 1):(ith * 80), :);
end
end
end