Statistics
| Branch: | Tag: | Revision:

amiro-os / test / periphery-lld / DW1000_v1 / aos_test_DW1000.c @ 4c72a54c

History | View | Annotate | Download (11.584 KB)

1 e05848a6 Robin Ewers
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3 84f0ce9e Thomas Schöpping
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 e05848a6 Robin Ewers

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19 ddf34c3d Thomas Schöpping
#include <amiroos.h>
20 4c72a54c Thomas Schöpping
#include <aos_test_DW1000.h>
21 ddf34c3d Thomas Schöpping
22 4c72a54c Thomas Schöpping
#if (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
23 4cb40108 Thomas Schöpping
24
#include <aos_debug.h>
25
#include <chprintf.h>
26
#include <aos_thread.h>
27
#include <math.h>
28
#include <module.h>
29
#include <alld_DW1000.h>
30 4c72a54c Thomas Schöpping
#include <deca_instance.h>
31 4cb40108 Thomas Schöpping
32 e05848a6 Robin Ewers
33 f3ac1c96 Thomas Schöpping
/******************************************************************************/
34
/* LOCAL DEFINITIONS                                                          */
35
/******************************************************************************/
36 e05848a6 Robin Ewers
37 4c72a54c Thomas Schöpping
//#define TEST_SNIPPETS_DW1000   // switch between test and demo apps
38 4cb40108 Thomas Schöpping
39
#define SWS1_SHF_MODE 0x02  //short frame mode (6.81M)
40
#define SWS1_CH5_MODE 0x04  //channel 5 mode
41
#define SWS1_ANC_MODE 0x08  //anchor mode
42
#define SWS1_A1A_MODE 0x10  //anchor/tag address A1
43
#define SWS1_A2A_MODE 0x20  //anchor/tag address A2
44
#define SWS1_A3A_MODE 0x40  //anchor/tag address A3
45
46
#define S1_SWITCH_ON  (1)
47
#define S1_SWITCH_OFF (0)
48
49 f3ac1c96 Thomas Schöpping
/******************************************************************************/
50
/* EXPORTED VARIABLES                                                         */
51
/******************************************************************************/
52
53
/******************************************************************************/
54
/* LOCAL TYPES                                                                */
55
/******************************************************************************/
56
57
/******************************************************************************/
58
/* LOCAL VARIABLES                                                            */
59
/******************************************************************************/
60 4cb40108 Thomas Schöpping
uint8_t s1switch = 0;
61
int instance_anchaddr = 0;
62
int dr_mode = 0;
63
int chan, tagaddr, ancaddr;
64
int instance_mode = ANCHOR;
65
66 f3ac1c96 Thomas Schöpping
67
/******************************************************************************/
68
/* LOCAL FUNCTIONS                                                            */
69
/******************************************************************************/
70
71 4cb40108 Thomas Schöpping
/*! @brief Change the SPI speed configuration on the fly */
72
void setHighSpeed_SPI(bool speedValue, DW1000Driver* drv){
73
74
  spiStop(drv->spid);
75
76
  if (speedValue == FALSE){
77
    spiStart(drv->spid, &moduleHalSpiUwbLsConfig);  // low speed spi configuration
78
  }
79
  else{
80
    spiStart(drv->spid, &moduleHalSpiUwbHsConfig); // high speed spi configuration
81
  }
82
}
83
84
/*! @brief entry point to the IRQn event in DW1000 module
85
 *
86
 * */
87
void process_deca_irq(void){
88
  do{
89
    dwt_isr();
90
    //while IRS line active (ARM can only do edge sensitive interrupts)
91
  }while(port_CheckEXT_IRQ() == 1);
92
}
93
94
/*! @brief Check the current value of GPIO pin and return the value */
95
apalGpioState_t port_CheckEXT_IRQ(void) {
96
  apalGpioState_t  val;
97
  apalGpioRead(moduleGpioDw1000Irqn.gpio, &val);
98
  return val;
99
}
100
101
/*! @brief Manually set the chip select pin of the SPI */
102
void set_SPI_chip_select(void){
103
  apalGpioWrite(moduleGpioSpiChipSelect.gpio, APAL_GPIO_HIGH);
104
}
105
106
/*! @brief Manually reset the chip select pin of the SPI */
107
void clear_SPI_chip_select(void){
108
  apalGpioWrite(moduleGpioSpiChipSelect.gpio, APAL_GPIO_LOW);
109
}
110
111
/*! @brief Manually reset the DW1000 module  */
112
void reset_DW1000(void){
113
114
  // Set the pin as output
115 3106e8cc Thomas Schöpping
  palSetLineMode(moduleGpioDw1000Reset.gpio->line, APAL_GPIO_DIRECTION_OUTPUT);
116 4cb40108 Thomas Schöpping
117
  //drive the RSTn pin low
118
  apalGpioWrite(moduleGpioDw1000Reset.gpio, APAL_GPIO_LOW);
119
120
  //put the pin back to tri-state ... as input
121 3106e8cc Thomas Schöpping
//  palSetLineMode(moduleGpioDw1000Reset.gpio->line, APAL_GPIO_DIRECTION_INPUT); // TODO:
122 4cb40108 Thomas Schöpping
123
  aosThdMSleep(2);
124
}
125
126
/*! @brief Configure instance tag/anchor/etc... addresses */
127
void addressconfigure(uint8_t s1switch, uint8_t mode){
128
  uint16_t instAddress ;
129
130
  instance_anchaddr = (((s1switch & SWS1_A1A_MODE) << 2) + (s1switch & SWS1_A2A_MODE) + ((s1switch & SWS1_A3A_MODE) >> 2)) >> 4;
131
132
  if(mode == ANCHOR) {
133
    if(instance_anchaddr > 3) {
134
      instAddress = GATEWAY_ANCHOR_ADDR | 0x4 ; //listener
135
    }
136
    else {
137
      instAddress = GATEWAY_ANCHOR_ADDR | (uint16_t)instance_anchaddr;
138
    }
139
  }
140
  else{
141
    instAddress = (uint16_t)instance_anchaddr;
142
  }
143
144
  instancesetaddresses(instAddress);
145
}
146
147
/*! @brief returns the use case / operational mode */
148
int decarangingmode(uint8_t s1switch){
149
  int mode = 0;
150
151
  if(s1switch & SWS1_SHF_MODE)  {
152
    mode = 1;
153
  }
154
155
  if(s1switch & SWS1_CH5_MODE) {
156
    mode = mode + 2;
157
  }
158
159
  return mode;
160
}
161
162
/*! @brief Check connection setting and initialize DW1000 module */
163
int32_t inittestapplication(uint8_t s1switch, DW1000Driver* drv){
164
  uint32_t devID ;
165
  int result;
166
167
  setHighSpeed_SPI(FALSE, drv);          //low speed spi max. ~4M
168
  devID = instancereaddeviceid() ;
169
170
  if(DWT_DEVICE_ID != devID) {
171
    clear_SPI_chip_select();
172
    Sleep(1);
173
    set_SPI_chip_select();
174
    Sleep(7);
175
    devID = instancereaddeviceid() ;
176
    if(DWT_DEVICE_ID != devID){
177
      return(-1) ;
178
    }    
179
    dwt_softreset();
180
  }
181
182
    reset_DW1000();  //reset the DW1000 by driving the RSTn line low
183
184
  if((s1switch & SWS1_ANC_MODE) == 0){
185
    instance_mode = TAG;
186
  }
187
  else{
188
    instance_mode = ANCHOR;
189
  }
190
191
  result = instance_init(drv) ;
192
193
  if (0 > result){
194
    return(-1) ;
195
  }
196
197
  setHighSpeed_SPI(TRUE, drv);       // high speed spi max. ~ 20M
198
  devID = instancereaddeviceid() ;
199
200
  if (DWT_DEVICE_ID != devID){
201
    return(-1) ;
202
  }
203
204
  addressconfigure(s1switch, (uint8_t)instance_mode) ;
205
206
  if((instance_mode == ANCHOR) && (instance_anchaddr > 0x3)){
207
    instance_mode = LISTENER;
208
  }
209
210
  instancesetrole(instance_mode) ;       // Set this instance role
211
  dr_mode = decarangingmode(s1switch);
212
  chan = chConfig[dr_mode].channelNumber ;
213
  instance_config(&chConfig[dr_mode], &sfConfig[dr_mode], drv) ;
214
215
  return (int32_t)devID;
216
}
217
218
/*! @brief Main Entry point to Initialization of UWB DW1000 configuration  */
219
#pragma GCC optimize ("O3")
220
int UWB_Init(DW1000Driver* drv){
221
222
  /*! Software defined Configurartion for TAG, ANC, and other settings as needed */
223
  s1switch = S1_SWITCH_OFF << 1  // (on = 6.8 Mbps, off = 110 kbps)
224
           | S1_SWITCH_OFF << 2  // (on = CH5, off = CH2)
225
           | S1_SWITCH_OFF << 3  // (on = Anchor, off = TAG)
226
           | S1_SWITCH_OFF << 4  // (configure Tag or anchor ID no.)
227
           | S1_SWITCH_OFF << 5  // (configure Tag or anchor ID no.)
228
           | S1_SWITCH_OFF << 6  // (configure Tag or anchor ID no.)
229
           | S1_SWITCH_OFF << 7; // Not use in this demo
230
231
232
  port_DisableEXT_IRQ();           //disable ScenSor IRQ until we configure the device
233
234
  if(inittestapplication(s1switch, drv) == -1) {
235
    return (-1); //error
236
  }
237
238
  aosThdMSleep(5);
239
240
  port_EnableEXT_IRQ();  //enable DW1000 IRQ before starting
241
242
  return 0;
243
}
244
245
246 f3ac1c96 Thomas Schöpping
/******************************************************************************/
247
/* EXPORTED FUNCTIONS                                                         */
248
/******************************************************************************/
249 e05848a6 Robin Ewers
250 4cb40108 Thomas Schöpping
251 4c72a54c Thomas Schöpping
aos_testresult_t aosTestDw1000Func(BaseSequentialStream* stream, aos_test_t* test) {
252 e05848a6 Robin Ewers
253 4c72a54c Thomas Schöpping
  aosDbgCheck(test->data != NULL && ((aos_test_dw1000data_t*)test->data)->driver != NULL);
254 e05848a6 Robin Ewers
255 4c72a54c Thomas Schöpping
  aos_testresult_t result = {0, 0};
256 e05848a6 Robin Ewers
257 4cb40108 Thomas Schöpping
  chprintf(stream, "init DW1000...\n");
258 4c72a54c Thomas Schöpping
  dwt_initialise(DWT_LOADUCODE, ((aos_test_dw1000data_t*)test->data)->driver);
259 4cb40108 Thomas Schöpping
  aosThdMSleep(5);
260 e05848a6 Robin Ewers
261
262 4c72a54c Thomas Schöpping
/*! Test snippets for DW1000.
263 4cb40108 Thomas Schöpping
 * @Note: Event IRQ for DW1000 should be tested separately
264
 */
265 4c72a54c Thomas Schöpping
#if defined(TEST_SNIPPETS_DW1000)
266 e05848a6 Robin Ewers
267 4cb40108 Thomas Schöpping
  uint32_t actual_deviceId;
268 e05848a6 Robin Ewers
269 4cb40108 Thomas Schöpping
  port_DisableEXT_IRQ();
270 e05848a6 Robin Ewers
271 4c72a54c Thomas Schöpping
  setHighSpeed_SPI(false, ((aos_test_dw1000data_t*)test->data)->driver);
272 a193bcf1 Thomas Schöpping
  chprintf(stream, "expected device ID (LS SPI): 0xDECA0130\n");
273 4cb40108 Thomas Schöpping
  aosThdMSleep(5);
274
  actual_deviceId = instancereaddeviceid();
275
  chprintf(stream, "actual read ID: 0x%x\n", actual_deviceId);
276
  aosThdMSleep(5);
277 e05848a6 Robin Ewers
278 4cb40108 Thomas Schöpping
  //if the read of device ID fails, the DW1000 could be asleep
279
  if(DWT_DEVICE_ID != actual_deviceId){
280 e05848a6 Robin Ewers
281 4cb40108 Thomas Schöpping
    clear_SPI_chip_select();
282
    aosThdMSleep(1);
283
    set_SPI_chip_select();
284
    aosThdMSleep(7);
285
    actual_deviceId = instancereaddeviceid() ;
286
287
    if(DWT_DEVICE_ID != actual_deviceId){
288
      chprintf(stream, "SPI is not working or Unsupported Device ID\n");
289
      chprintf(stream, "actual device ID is: 0x%x\n", actual_deviceId);
290 a193bcf1 Thomas Schöpping
      chprintf(stream, "expected device ID: 0xDECA0130\n");
291 4cb40108 Thomas Schöpping
      aosThdMSleep(5);
292
    }
293 e05848a6 Robin Ewers
294 4cb40108 Thomas Schöpping
    //clear the sleep bit - so that after the hard reset below the DW does not go into sleep
295
    dwt_softreset();
296
  }
297
298 4c72a54c Thomas Schöpping
  /*! Test1: Low speed SPI result */
299 4cb40108 Thomas Schöpping
  if (actual_deviceId == DWT_DEVICE_ID){
300 4c72a54c Thomas Schöpping
    aosTestPassed(stream, &result);
301 4cb40108 Thomas Schöpping
  } else {
302 4c72a54c Thomas Schöpping
    aosTestFailed(stream, &result);
303 4cb40108 Thomas Schöpping
  }
304
305
  reset_DW1000();
306
307 a193bcf1 Thomas Schöpping
  chprintf(stream, "initialise instance for DW1000\n");
308 4cb40108 Thomas Schöpping
  aosThdSleep(1);
309
310 4c72a54c Thomas Schöpping
  int x_init = instance_init(((aos_test_dw1000data_t*)test->data)->driver) ;
311 4cb40108 Thomas Schöpping
312
  if (0 != x_init){
313 a193bcf1 Thomas Schöpping
    chprintf(stream, "init error with return value: %d\n", x_init);
314 4cb40108 Thomas Schöpping
    aosThdSleep(1);
315
  }
316
  else {
317 a193bcf1 Thomas Schöpping
    chprintf(stream, "init success with return value: %d\n", x_init);
318 4cb40108 Thomas Schöpping
    aosThdSleep(1);
319
  }
320
321 4c72a54c Thomas Schöpping
  /*! Test2: Initialization  result*/
322 4cb40108 Thomas Schöpping
  if (x_init == 0){
323 4c72a54c Thomas Schöpping
    aosTestPassed(stream, &result);
324 4cb40108 Thomas Schöpping
  } else {
325 4c72a54c Thomas Schöpping
    aosTestFailed(stream, &result);
326 4cb40108 Thomas Schöpping
  }
327
328 4c72a54c Thomas Schöpping
  setHighSpeed_SPI(true, ((aos_test_dw1000data_t*)test->data)->driver);
329 4cb40108 Thomas Schöpping
330
  chprintf(stream, "expected device ID (HS SPI): 0xDECA0130\n");
331
  actual_deviceId = instancereaddeviceid();
332
  chprintf(stream, "actual read ID: 0x%x\n", actual_deviceId);
333
  aosThdMSleep(1);
334
335 4c72a54c Thomas Schöpping
  /*! Test3: High speed SPI result*/
336 4cb40108 Thomas Schöpping
  if (actual_deviceId == DWT_DEVICE_ID){
337 4c72a54c Thomas Schöpping
    aosTestPassed(stream, &result);
338 4cb40108 Thomas Schöpping
  } else {
339 4c72a54c Thomas Schöpping
    aosTestFailed(stream, &result);
340 4cb40108 Thomas Schöpping
  }
341
342
  port_EnableEXT_IRQ();
343
  reset_DW1000();
344
345 a193bcf1 Thomas Schöpping
  chprintf(stream, "initialise the configuration for UWB application\n");
346 4cb40108 Thomas Schöpping
  aosThdSleep(1);
347
348 4c72a54c Thomas Schöpping
  int uwb_init = UWB_Init(((aos_test_dw1000data_t*)test->data)->driver);
349 4cb40108 Thomas Schöpping
350
  if (0 != uwb_init){
351 a193bcf1 Thomas Schöpping
    chprintf(stream, "UWB config error with return value: %d\n", uwb_init);
352 4cb40108 Thomas Schöpping
    aosThdSleep(1);
353
  }
354
  else {
355 a193bcf1 Thomas Schöpping
    chprintf(stream, "UWB config success with return value: %d\n", uwb_init);
356 4cb40108 Thomas Schöpping
    aosThdSleep(1);
357
  }
358
359 4c72a54c Thomas Schöpping
  /*! Test4: UWB configuration result
360
   * If all the four tests are passed, the module is ready to run.
361 4cb40108 Thomas Schöpping
   * Note that the interrupt IRQn should be tested separately.
362
   */
363
  if (uwb_init == 0){
364 4c72a54c Thomas Schöpping
    aosTestPassed(stream, &result);
365 4cb40108 Thomas Schöpping
  } else {
366 4c72a54c Thomas Schöpping
    aosTestFailed(stream, &result);
367 4cb40108 Thomas Schöpping
  }
368
369 4c72a54c Thomas Schöpping
  /************** End of TEST_SNIPPETS_DW1000*****************/
370 4cb40108 Thomas Schöpping
371 4c72a54c Thomas Schöpping
#else /* defined(TEST_SNIPPETS_DW1000) */
372 4cb40108 Thomas Schöpping
373
374
  /*! RUN THE STATE MACHINE DEMO APP (RTLS) */
375
376 a193bcf1 Thomas Schöpping
  chprintf(stream, "initialise the State Machine\n");
377 4cb40108 Thomas Schöpping
  aosThdSleep(2);
378
379
  /* Initialize UWB system with user defined configuration  */
380 4c72a54c Thomas Schöpping
  int uwb_init = UWB_Init(((aos_test_dw1000data_t*)test->data)->driver);
381 4cb40108 Thomas Schöpping
382
  if (0 != uwb_init){
383 a193bcf1 Thomas Schöpping
    chprintf(stream, "error in UWB config with return value: %d\n", uwb_init);
384 4cb40108 Thomas Schöpping
  }
385
  else {
386 a193bcf1 Thomas Schöpping
    chprintf(stream, "succeed the init of UWB config\n");
387 4cb40108 Thomas Schöpping
  }
388
  aosThdSleep(1);
389
390 a193bcf1 Thomas Schöpping
  chprintf(stream, "running the RTLS demo application ...\n");
391 4cb40108 Thomas Schöpping
  aosThdSleep(1);
392
393
  /*! Run the localization system demo app as a thread */
394
  while(1){
395
    instance_run();
396
//    aosThdUSleep(10);
397
  }
398
399 4c72a54c Thomas Schöpping
#endif  /* defined(TEST_SNIPPETS_DW1000) */
400 4cb40108 Thomas Schöpping
401
  return result;
402 e05848a6 Robin Ewers
}
403
404 4cb40108 Thomas Schöpping
405 4c72a54c Thomas Schöpping
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */