1 /*
2  * Copyright (c) 2016 Brian Swetland
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 
9 #pragma once
10 
11 #include <lk/compiler.h>
12 
13 // trigger control byte (TRM 23.3.2.5.1)
14 
15 #define TRG_NOW             0x00
16 #define TRG_NEVER           0x01 // except for CMD_TRIGGER if enabled
17 #define TRG_ABSTIME         0x02
18 #define TRG_REL_SUBMIT      0x03 // relative to command submission time
19 #define TRG_REL_START       0x04 // relative to command start (end trg only)
20 #define TRG_REL_PREVSTART   0x05 // relative to start of previous command
21 #define TRG_REL_FIRSTSTART  0x06 // relative to first command in chain
22 #define TRG_REL_PREVEND     0x07 // relative to end of previous command
23 #define TRG_REL_EVT1        0x08 // relative to prev command evt1
24 #define TRG_REL_EVT2        0x09 // relative to prev command evt1
25 #define TRG_EXTERNAL        0x0A // TRG_EXT_* in timer parameter
26 
27 #define TRG_ENA_CMD_O       0x10 // CMD_TRIGGER #0 enabled as alt trigger
28 #define TRG_ENA_CMD_1       0x30 // CMD_TRIGGER #1 enabled as alt trigger
29 #define TRG_ENA_CMD_2       0x50 // CMD_TRIGGER #2 enabled as alt trigger
30 #define TRG_ENA_CMD_3       0x70 // CMD_TRIGGER #3 enabled as alt trigger
31 
32 #define TRG_PAST_OK         0x80 // trigger in the past happens asap
33 #define TRG_PAST_DISALLOW   0x00 // never happens, or for start trg is an error
34 
35 #define TRG_EXT_RISING      0x00
36 #define TRG_EXT_FALLING     0x40
37 #define TRG_EXT_BOTH_EDGE   0x80
38 #define TRG_SRC_RFC_GPI0    (22 << 8)
39 #define TRG_SRC_RFC_GPI1    (23 << 8)
40 
41 // condition byte (TRM 23.3.2.5.2)
42 // - commands return TRUE, FALSE, or ABORT as defined for each command
43 // - a skip of 0 = re-exec current, 1 = exec next, 2 = skip next
44 #define CND_ALWAYS          0x00
45 #define CND_NEVER           0x01
46 #define CND_STOP_ON_FALSE   0x02
47 #define CND_STOP_ON_TRUE    0x03
48 #define CND_SKIP_ON_FALSE   0x04 // if false, skip N commands
49 #define CND_SKIP_ON_TRUE    0x05 // if true, skip N commands
50 #define CND_SKIP(n)     (((n) & 0xF) << 4)
51 
52 
53 #define QE_STATUS_PENDING   0x00 // set before submitting by SysCPU
54 #define QE_STATUS_ACTIVE    0x01 // entry in queue by RadioCPU
55 #define QE_STATUS_BUSY      0x02 // entry is actively being r/w by RadioCPU
56 #define QE_STATUS_DONE      0x03 // RadioCPU is done, SysCPU may reclaim
57 
58 #define QE_CONFIG_GENERAL   0x00
59 #define QE_CONFIG_MULTI     0x01
60 #define QE_CONFIG_POINTER   0x02
61 #define QE_CONFIG_LEN_SZ_0  0x00 // no length prefix
62 #define QE_CONFIG_LEN_SZ_1  0x04 // 1-byte length prefix
63 #define QE_CONFIG_LEN_SZ_2  0x08 // 2-byte length prefix
64 
65 typedef struct rf_queue rf_queue_t;
66 typedef struct rf_queue_entry rf_queue_entry_t;
67 
68 struct rf_queue {
69     rf_queue_entry_t *curr;
70     rf_queue_entry_t *last;
71 };
72 
73 struct rf_queue_entry {
74     rf_queue_entry_t *next;
75     uint8_t status;
76     uint8_t config;
77     uint16_t length;
78     union {
79         uint8_t data[4];
80         uint8_t *ptr;
81     };
82 };
83 
84 #define IMM_CMD(cmd,arg,ext)    (((cmd) << 16) | \
85                 ((arg & 0xFF) << 8) | \
86                 ((ext & 0x3F) << 2) | \
87                 0x01)
88 
89 // direct commands
90 #define CMD_ABORT           0x0401 // stop asap
91 #define CMD_STOP            0x0402 // stop once active rx/tx completes
92 #define CMD_GET_RSSI        0x0403
93 #define CMD_TRIGGER         0x0404
94 #define CMD_TRIGGER_N(n)    (0x0404 | (((n) & 3) << 16))
95 #define CMD_START_RAT       0x0405
96 #define CMD_PING            0x0406 // no op
97 
98 // immediate commands
99 #define CMD_UPDATE_RADIO_SETUP  0x0001
100 #define CMD_GET_FW_INFO     0x0002
101 #define CMD_READ_RFREG      0x0601
102 #define CMD_SET_RAT_CMP     0x000A
103 #define CMD_SET_RAT_CPT     0x0603
104 #define CMD_DISABLE_RAT_CH  0x0408
105 #define CMD_SET_RAT_OUTPUT  0x0604
106 #define CMD_ARM_RAT_CH      0x0409
107 #define CMD_DISARM_RAT_CH   0x040A
108 #define CMD_SET_TX_POWER    0x0010
109 #define CMD_UPDATE_FS       0x0011
110 #define CMD_BUS_REQUEST     0x040E
111 #define CMD_ADD_DATA_ENTRY  0x0005
112 #define CMD_REMOVE_DATA_ENTRY   0x0006
113 #define CMD_FLUSH_QUEUE     0x0007
114 #define CMD_CLEAR_RX        0x0008
115 #define CMD_REMOVE_PENDING  0x0009
116 
117 // queued commands
118 #define CMD_NOP             0x0801 // rf_op_basic_t
119 #define CMD_FS              0x0803 // rf_op_fs_t
120 #define CMD_FS_OFF          0x0804 // rf_op_basic_t
121 #define CMD_RADIO_SETUP     0x0802 // rf_op_radio_setup_t
122 #define CMD_FS_POWERUP      0x080C // rf_op_fs_power_t
123 #define CMD_FS_POWERDOWN    0x080D // rf_op_fs_power_t
124 #define CMD_SYNC_STOP_RAT   0x0809 // rf_op_sync_rat_t
125 #define CMD_SYNC_START_RAT  0x080A // rf_op_sync_rat_t
126 #define CMD_COUNT           0x080B // rf_op_count_t
127 #define CMD_PATTERN_CHECK   0x0813 // rf_op_pattern_check_t
128 
129 // status
130 #define DONE_OK             0x0400 // success
131 #define DONE_COUNTDOWN      0x0401 // count == 0
132 #define DONE_RXERR          0x0402 // crc error
133 #define DONE_TIMEOUT        0x0403
134 #define DONE_STOPPED        0x0404 // stopped by CMD_DONE
135 #define DONE_ABORT          0x0405 // stopped by CMD_ABORT
136 #define DONE_FAILED         0x0406
137 
138 #define ERROR_PAST_START    0x0800 // start trigger is in the past
139 #define ERROR_START_TRIG    0x0801 // bad trigger parameter
140 #define ERROR_CONDITION     0x0802 // bad condition parameter
141 #define ERROR_PAR           0x0803 // invalid parameter (command specific)
142 #define ERROR_POINTER       0x0804 // invalid pointer to next op
143 #define ERROR_CMD_ID        0x0805 // bad command id
144 #define ERROR_WRONG_BG      0x0806 // fg cmd cannot run w/ active bg cmd
145 #define ERROR_NO_SETUP      0x0807 // tx/rx without radio setup
146 #define ERROR_NO_FS         0x0808 // tx/rx with freq synth off
147 #define ERROR_SYNTH_PROG    0x0809 // freq synth calibration failure
148 #define ERROR_TXUNF         0x080A // tx underflow
149 #define ERROR_TXOVF         0x080B // rx overflow
150 #define ERROR_NO_RX         0x080C // no rx data available
151 #define ERROR_PENDING       0x080D // other commands already pending
152 
153 typedef struct rf_op_basic rf_op_basic_t;
154 typedef struct rf_op_radio_setup rf_op_radio_setup_t;
155 typedef struct rf_op_fs rf_op_fs_t;
156 typedef struct rf_op_fs_power rf_op_fs_power_t;
157 typedef struct rf_op_sync_rat rf_op_sync_rat_t;
158 typedef struct rf_op_count rf_op_count_t;
159 typedef struct rf_op_pattern_check rf_op_pattern_check_t;
160 typedef struct rf_op_fw_info rf_op_fw_info_t;
161 
162 struct rf_op_basic {
163     uint16_t cmd;
164     uint16_t status;
165     void *next_op;
166     uint32_t start_time;
167     uint8_t start_trig;
168     uint8_t cond;
169 } __PACKED;
170 
171 struct rf_op_fw_info {
172     uint16_t cmd;
173 
174     uint16_t version;
175     uint16_t free_ram_start;
176     uint16_t free_ram_size;
177     uint16_t avail_rat_ch;
178 } __PACKED;
179 
180 #if 0
181 // warning - docs / headers disagree
182 #define RF_MODE_BLE     0x00
183 #define RF_MODE_802_15_4    0x01
184 #define RF_MODE_2MBPS_GFSK  0x02
185 #define RF_MODE_5MBPS_8FSK  0x05
186 #define RF_MODE_NO_CHANGE   0xFF
187 #endif
188 
189 #define RF_CFG_FE_MODE(n)   ((n) & 7)
190 #define RF_CFG_INT_BIAS     (0 << 3)
191 #define RF_CFG_EXT_BIAS     (1 << 3)
192 #define RF_CFG_FS_POWERUP   (0 << 10)
193 #define RF_CFG_FS_NO_POWERUP    (1 << 10)
194 
195 #define TX_PWR_IB(n)        ((n) & 0x3F)
196 #define TX_PWR_GC(n)        (((n) & 3) << 6)
197 #define TX_PWR_TEMP_COEFF(n)    (((n) & 0xFF) << 8)
198 
199 struct rf_op_radio_setup {
200     uint16_t cmd;
201     uint16_t status;
202     void *next_op;
203     uint32_t start_time;
204     uint8_t start_trig;
205     uint8_t cond;
206 
207     uint8_t mode;
208     uint8_t io_div; // cc13xx (0,2,5,6,10,12,5,30), cc26xx (0,2)
209     uint16_t config;
210     uint16_t tx_pwr;
211     void *reg_override;
212 } __PACKED;
213 
214 struct rf_op_fs {
215     uint16_t cmd;
216     uint16_t status;
217     void *next_op;
218     uint32_t start_time;
219     uint8_t start_trig;
220     uint8_t cond;
221 
222     uint16_t frequency;
223     uint16_t fract_freq;
224     uint8_t synth_conf;
225     uint8_t reserved;
226     uint8_t mid_precal;
227     uint8_t kt_precal;
228     uint16_t tdc_precal;
229 };
230 
231 struct rf_op_fs_power {
232     uint16_t cmd;
233     uint16_t status;
234     void *next_op;
235     uint32_t start_time;
236     uint8_t start_trig;
237     uint8_t cond;
238 
239     uint16_t reserved;
240     void *reg_override;
241 };
242 
243 struct rf_op_sync_rat {
244     uint16_t cmd;
245     uint16_t status;
246     void *next_op;
247     uint32_t start_time;
248     uint8_t start_trig;
249     uint8_t cond;
250 
251     uint16_t reserved;
252     uint32_t rat0;
253 };
254 
255 // - on start, if count == 0 -> ERROR_PARAM (ABORT?), else count--
256 // - if count > 0, status = DONE_OK, res = TRUE
257 // - if count == 0, status = DONE_COUNTDOWN, res = FALSE
258 
259 struct rf_op_count {
260     uint16_t cmd;
261     uint16_t status;
262     void *next_op;
263     uint32_t start_time;
264     uint8_t start_trig;
265     uint8_t cond;
266 
267     uint16_t counter;
268 };
269 
270 #define PTN_OP_EQ       (0 << 0)
271 #define PTN_OP_LT       (1 << 0)
272 #define PTN_OP_GT       (2 << 0)
273 #define PTN_BYTE_REV    (1 << 2) // 0=LE, 1=BE
274 #define PTN_BIT_REV     (1 << 3)
275 #define PTN_SIGN_EXT(n) (((n) & 31) << 4)
276 #define PTN_USE_IDX     (1 << 9)
277 #define PTN_USE_PTR     (0 << 9)
278 
279 // 1. read word x from pointer or index from start of last committed rx data
280 // 2. byteswap x, if requested
281 // 3. bitswap x, if requested
282 // 4. x = x & mask
283 // 5. if sign extend != 0, extend that bit through 31
284 // 6. result = x OP value
285 // if result TRUE, status = DONE_OK
286 // if result FALSE, status = DONE_FAILED
287 // if USE_IDX but no RX data available, status = ERROR_NO_RX, result = ABORT
288 
289 struct rf_op_pattern_check {
290     uint16_t cmd;
291     uint16_t status;
292     void *next_op;
293     uint32_t start_time;
294     uint8_t start_trig;
295     uint8_t cond;
296 
297     uint16_t pattern;
298     void *next_op_if_true;
299     union {
300         void *ptr;
301         int32_t idx;
302     };
303     uint32_t mask;
304     uint32_t value;
305 };
306 
307 // multi element is <COUNT:2> [ <NEXT-DATA-INDEX:2> <DATA:1> ... ]
308 
309 STATIC_ASSERT(sizeof(rf_queue_t) == 8);
310 STATIC_ASSERT(sizeof(rf_queue_entry_t) == 12);
311 STATIC_ASSERT(sizeof(rf_op_basic_t) == 14);
312 STATIC_ASSERT(sizeof(rf_op_radio_setup_t) == 24);
313 STATIC_ASSERT(sizeof(rf_op_fs_t) == 24);
314 STATIC_ASSERT(sizeof(rf_op_fs_power_t) == 20);
315 STATIC_ASSERT(sizeof(rf_op_sync_rat_t) == 20);
316 STATIC_ASSERT(sizeof(rf_op_count_t) == 16);
317 STATIC_ASSERT(sizeof(rf_op_pattern_check_t) == 32);
318 STATIC_ASSERT(sizeof(rf_op_fw_info_t) == 10);
319