amiro-lld / source / deca_instance_common.c @ 9e45662e
History | View | Annotate | Download (34.084 KB)
1 |
/*! ----------------------------------------------------------------------------
|
---|---|
2 |
* @file instance_common.c
|
3 |
* @brief DecaWave application level common instance functions
|
4 |
*
|
5 |
* @attention
|
6 |
*
|
7 |
* Copyright 2015 (c) DecaWave Ltd, Dublin, Ireland.
|
8 |
*
|
9 |
* All rights reserved.
|
10 |
*
|
11 |
* @author DecaWave
|
12 |
*/
|
13 |
|
14 |
|
15 |
|
16 |
#include <deca_instance.h> |
17 |
#if defined(AMIROLLD_CFG_USE_DW1000) || defined(__DOXYGEN__)
|
18 |
|
19 |
|
20 |
#include <alld_dw1000.h> |
21 |
#include <string.h> |
22 |
#include <math.h> |
23 |
|
24 |
|
25 |
|
26 |
extern double dwt_getrangebias(uint8_t chan, float range, uint8_t prf); |
27 |
|
28 |
extern const uint16_t rfDelays[2]; |
29 |
extern const uint16_t rfDelaysTREK[2]; |
30 |
extern const tx_struct txSpectrumConfig[8]; |
31 |
|
32 |
|
33 |
|
34 |
// -------------------------------------------------------------------------------------------------------------------
|
35 |
// Deca Calibration Values
|
36 |
// -------------------------------------------------------------------------------------------------------------------
|
37 |
|
38 |
#define DWT_PRF_64M_RFDLY (514.462f) |
39 |
#define DWT_PRF_16M_RFDLY (513.9067f) |
40 |
|
41 |
// -------------------------------------------------------------------------------------------------------------------
|
42 |
|
43 |
//The table below specifies the default TX spectrum configuration parameters... this has been tuned for DW EVK hardware units
|
44 |
//the table is set for smart power - see below in the instance_config function how this is used when not using smart power
|
45 |
const tx_struct txSpectrumConfig[8] = |
46 |
{ |
47 |
//Channel 0 ----- this is just a place holder so the next array element is channel 1
|
48 |
{ |
49 |
0x0, //0 |
50 |
{ |
51 |
0x0, //0 |
52 |
0x0 //0 |
53 |
} |
54 |
}, |
55 |
//Channel 1
|
56 |
{ |
57 |
0xc9, //PG_DELAY |
58 |
{ |
59 |
0x15355575, //16M prf power |
60 |
0x07274767 //64M prf power |
61 |
} |
62 |
|
63 |
}, |
64 |
//Channel 2
|
65 |
{ |
66 |
0xc2, //PG_DELAY |
67 |
{ |
68 |
0x15355575, //16M prf power |
69 |
0x07274767 //64M prf power |
70 |
} |
71 |
}, |
72 |
//Channel 3
|
73 |
{ |
74 |
0xc5, //PG_DELAY |
75 |
{ |
76 |
0x0f2f4f6f, //16M prf power |
77 |
0x2b4b6b8b //64M prf power |
78 |
} |
79 |
}, |
80 |
//Channel 4
|
81 |
{ |
82 |
0x95, //PG_DELAY |
83 |
{ |
84 |
0x1f1f3f5f, //16M prf power |
85 |
0x3a5a7a9a //64M prf power |
86 |
} |
87 |
}, |
88 |
//Channel 5
|
89 |
{ |
90 |
0xc0, //PG_DELAY |
91 |
{ |
92 |
0x0E082848, //16M prf power |
93 |
0x25456585 //64M prf power |
94 |
} |
95 |
}, |
96 |
//Channel 6 ----- this is just a place holder so the next array element is channel 7
|
97 |
{ |
98 |
0x0, //0 |
99 |
{ |
100 |
0x0, //0 |
101 |
0x0 //0 |
102 |
} |
103 |
}, |
104 |
//Channel 7
|
105 |
{ |
106 |
0x93, //PG_DELAY |
107 |
{ |
108 |
0x32527292, //16M prf power |
109 |
0x5171B1d1 //64M prf power |
110 |
} |
111 |
} |
112 |
}; |
113 |
|
114 |
//these are default antenna delays for EVB1000, these can be used if there is no calibration data in the DW1000,
|
115 |
//or instead of the calibration data
|
116 |
const uint16_t rfDelays[2] = { |
117 |
(uint16_t) ((DWT_PRF_16M_RFDLY/ 2.0) * 1e-9 / DWT_TIME_UNITS),//PRF 16 |
118 |
(uint16_t) ((DWT_PRF_64M_RFDLY/ 2.0) * 1e-9 / DWT_TIME_UNITS) |
119 |
}; |
120 |
|
121 |
//these are default TREK Tag/Anchor antenna delays
|
122 |
const uint16_t rfDelaysTREK[2] = { |
123 |
(uint16_t) ((514.83f/ 2.0) * 1e-9 / DWT_TIME_UNITS),//channel 2 |
124 |
(uint16_t) ((514.65f/ 2.0) * 1e-9 / DWT_TIME_UNITS) //channel 5 |
125 |
}; |
126 |
|
127 |
//int instance_starttxtest(int framePeriod)
|
128 |
//{
|
129 |
// //define some test data for the tx buffer
|
130 |
// uint8 msg[127] = "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the l";
|
131 |
|
132 |
// //NOTE: SPI frequency must be < 3MHz
|
133 |
// port_set_dw1000_slowrate(); //max SPI before PLLs configured is ~4M
|
134 |
|
135 |
// // the value here 0x1000 gives a period of 32.82 µs
|
136 |
// //this is setting 0x1000 as frame period (125MHz clock cycles) (time from Tx en - to next - Tx en)
|
137 |
// dwt_configcontinuousframemode(framePeriod);
|
138 |
|
139 |
// dwt_writetxdata(127, (uint8 *) msg, 0) ;
|
140 |
// dwt_writetxfctrl(127, 0, 0);
|
141 |
|
142 |
// //to start the first frame - set TXSTRT
|
143 |
// dwt_starttx(DWT_START_TX_IMMEDIATE);
|
144 |
|
145 |
// //measure the power
|
146 |
// //Spectrum Analyser set:
|
147 |
// //FREQ to be channel default e.g. 3.9936 GHz for channel 2
|
148 |
// //SPAN to 1GHz
|
149 |
// //SWEEP TIME 1s
|
150 |
// //RBW and VBW 1MHz
|
151 |
// //measure channel power
|
152 |
|
153 |
// return DWT_SUCCESS ;
|
154 |
//}
|
155 |
|
156 |
// -------------------------------------------------------------------------------------------------------------------
|
157 |
// Data Definitions
|
158 |
// -------------------------------------------------------------------------------------------------------------------
|
159 |
|
160 |
static instance_data_t instance_data[NUM_INST] ;
|
161 |
|
162 |
static double inst_tdist[MAX_TAG_LIST_SIZE] ; |
163 |
static double inst_idist[MAX_ANCHOR_LIST_SIZE] ; |
164 |
static double inst_idistraw[MAX_ANCHOR_LIST_SIZE] ; |
165 |
|
166 |
// -------------------------------------------------------------------------------------------------------------------
|
167 |
// Functions
|
168 |
// -------------------------------------------------------------------------------------------------------------------
|
169 |
|
170 |
|
171 |
/* @fn instance_get_local_structure_ptr
|
172 |
* @brief function to return the pointer to local instance data structure
|
173 |
* */
|
174 |
instance_data_t* instance_get_local_structure_ptr(unsigned int x) |
175 |
{ |
176 |
if (x >= NUM_INST)
|
177 |
{ |
178 |
return NULL; |
179 |
} |
180 |
|
181 |
return &instance_data[x];
|
182 |
} |
183 |
|
184 |
|
185 |
// -------------------------------------------------------------------------------------------------------------------
|
186 |
/* @fn instance_convert_usec_to_devtimeu
|
187 |
* @brief function to convert microseconds to device time
|
188 |
* */
|
189 |
uint64_t instance_convert_usec_to_devtimeu (double microsecu)
|
190 |
{ |
191 |
uint64_t dt; |
192 |
long double dtime; |
193 |
|
194 |
dtime = (microsecu / (double) DWT_TIME_UNITS) / 1e6 ; |
195 |
|
196 |
dt = (uint64_t) (dtime) ; |
197 |
|
198 |
return dt;
|
199 |
} |
200 |
|
201 |
/* @fn instance_calculate_rangefromTOF
|
202 |
* @brief function to calculate and the range from given Time of Flight
|
203 |
* */
|
204 |
int instance_calculate_rangefromTOF(int idx, uint32_t tofx) |
205 |
{ |
206 |
instance_data_t* inst = instance_get_local_structure_ptr(0);
|
207 |
double distance ;
|
208 |
double distance_to_correct;
|
209 |
double tof ;
|
210 |
int32_t tofi ; |
211 |
|
212 |
// check for negative results and accept them making them proper negative integers
|
213 |
tofi = (int32_t) tofx ; // make it signed
|
214 |
if (tofi > 0x7FFFFFFF) // close up TOF may be negative |
215 |
{ |
216 |
tofi -= 0x80000000 ; // |
217 |
} |
218 |
|
219 |
// convert device time units to seconds (as floating point)
|
220 |
tof = tofi * DWT_TIME_UNITS ; |
221 |
inst_idistraw[idx] = distance = tof * SPEED_OF_LIGHT; |
222 |
|
223 |
#if (CORRECT_RANGE_BIAS == 1) |
224 |
//for the 6.81Mb data rate we assume gating gain of 6dB is used,
|
225 |
//thus a different range bias needs to be applied
|
226 |
//if(inst->configData.dataRate == DWT_BR_6M8)
|
227 |
if(inst->smartPowerEn)
|
228 |
{ |
229 |
//1.31 for channel 2 and 1.51 for channel 5
|
230 |
if(inst->configData.chan == 5) |
231 |
{ |
232 |
distance_to_correct = distance/1.51; |
233 |
} |
234 |
else //channel 2 |
235 |
{ |
236 |
distance_to_correct = distance/1.31; |
237 |
} |
238 |
} |
239 |
else
|
240 |
{ |
241 |
distance_to_correct = distance; |
242 |
} |
243 |
|
244 |
distance = distance - dwt_getrangebias(inst->configData.chan, (float) distance_to_correct, inst->configData.prf);
|
245 |
#endif
|
246 |
|
247 |
if ((distance < 0) || (distance > 20000.000)) // discard any results less than <0 cm or >20 km |
248 |
return 0; |
249 |
|
250 |
inst_idist[idx] = distance; |
251 |
|
252 |
inst->longTermRangeCount++ ; // for computing a long term average
|
253 |
|
254 |
return 1; |
255 |
}// end of calculateRangeFromTOF
|
256 |
|
257 |
void instance_set_tagdist(int tidx, int aidx) |
258 |
{ |
259 |
inst_tdist[tidx] = inst_idist[aidx]; |
260 |
} |
261 |
|
262 |
double instance_get_tagdist(int idx) |
263 |
{ |
264 |
return inst_tdist[idx];
|
265 |
} |
266 |
|
267 |
void instance_cleardisttable(int idx) |
268 |
{ |
269 |
inst_idistraw[idx] = 0;
|
270 |
inst_idist[idx] = 0;
|
271 |
} |
272 |
|
273 |
void instance_cleardisttableall(void) |
274 |
{ |
275 |
int i;
|
276 |
|
277 |
for(i=0; i<MAX_ANCHOR_LIST_SIZE; i++) |
278 |
{ |
279 |
inst_idistraw[i] = 0xffff;
|
280 |
inst_idist[i] = 0xffff;
|
281 |
} |
282 |
} |
283 |
|
284 |
// -------------------------------------------------------------------------------------------------------------------
|
285 |
// Set this instance role as the Tag, Anchor
|
286 |
/*void instance_set_role(int inst_mode)
|
287 |
{
|
288 |
// assume instance 0, for this
|
289 |
inst->mode = inst_mode; // set the role
|
290 |
}
|
291 |
*/
|
292 |
int instance_get_role(void) |
293 |
{ |
294 |
instance_data_t* inst = instance_get_local_structure_ptr(0);
|
295 |
|
296 |
return inst->mode;
|
297 |
} |
298 |
|
299 |
int instance_newrange(void) |
300 |
{ |
301 |
instance_data_t* inst = instance_get_local_structure_ptr(0);
|
302 |
int x = inst->newRange;
|
303 |
inst->newRange = TOF_REPORT_NUL; |
304 |
return x;
|
305 |
} |
306 |
|
307 |
int instance_newrangeancadd(void) |
308 |
{ |
309 |
instance_data_t* inst = instance_get_local_structure_ptr(0);
|
310 |
return inst->newRangeAncAddress;
|
311 |
} |
312 |
|
313 |
int instance_newrangetagadd(void) |
314 |
{ |
315 |
instance_data_t* inst = instance_get_local_structure_ptr(0);
|
316 |
return inst->newRangeTagAddress;
|
317 |
} |
318 |
|
319 |
int instance_newrangetim(void) |
320 |
{ |
321 |
instance_data_t* inst = instance_get_local_structure_ptr(0);
|
322 |
return inst->newRangeTime;
|
323 |
} |
324 |
|
325 |
// -------------------------------------------------------------------------------------------------------------------
|
326 |
// function to clear counts/averages/range values
|
327 |
//
|
328 |
void instance_clearcounts(void) |
329 |
{ |
330 |
instance_data_t* inst = instance_get_local_structure_ptr(0);
|
331 |
int i= 0 ; |
332 |
|
333 |
//inst->rxTimeouts = 0 ;
|
334 |
//inst->txMsgCount = 0 ;
|
335 |
//inst->rxMsgCount = 0 ;
|
336 |
|
337 |
dwt_configeventcounters(1); //enable and clear - NOTE: the counters are not preserved when in DEEP SLEEP |
338 |
|
339 |
inst->frameSN = 0;
|
340 |
|
341 |
inst->longTermRangeCount = 0;
|
342 |
|
343 |
|
344 |
for(i=0; i<MAX_ANCHOR_LIST_SIZE; i++) |
345 |
{ |
346 |
inst->tofArray[i] = INVALID_TOF; |
347 |
} |
348 |
|
349 |
for(i=0; i<MAX_TAG_LIST_SIZE; i++) |
350 |
{ |
351 |
inst->tof[i] = INVALID_TOF; |
352 |
} |
353 |
|
354 |
} // end instanceclearcounts()
|
355 |
|
356 |
|
357 |
// -------------------------------------------------------------------------------------------------------------------
|
358 |
// function to initialise instance structures
|
359 |
//
|
360 |
// Returns 0 on success and -1 on error
|
361 |
int instance_init(int inst_mode, DW1000Driver* drv) |
362 |
{ |
363 |
instance_data_t* inst = instance_get_local_structure_ptr(0);
|
364 |
int result;
|
365 |
|
366 |
inst->mode = inst_mode; // assume listener,
|
367 |
inst->twrMode = LISTENER; |
368 |
inst->testAppState = TA_INIT ; |
369 |
inst->instToSleep = FALSE; |
370 |
|
371 |
|
372 |
// Reset the IC (might be needed if not getting here from POWER ON)
|
373 |
// ARM code: Remove soft reset here as using hard reset in the inittestapplication() in the main.c file
|
374 |
//dwt_softreset();
|
375 |
|
376 |
//this initialises DW1000 and uses specified configurations from OTP/ROM
|
377 |