Statistics
| Branch: | Tag: | Revision:

amiro-os / unittests / periphery-lld / src / ut_alld_dw1000_v1.c @ d3710331

History | View | Annotate | Download (12.199 KB)

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

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
#include <amiroos.h>
20

    
21
#if ((AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)) || defined(__DOXYGEN__)
22

    
23
#include <aos_debug.h>
24
#include <chprintf.h>
25
#include <aos_thread.h>
26
#include <math.h>
27
#include <module.h>
28
#include <alld_DW1000.h>
29
#include <v1/deca_instance_v1.h>
30

    
31

    
32
/******************************************************************************/
33
/* LOCAL DEFINITIONS                                                          */
34
/******************************************************************************/
35

    
36
//#define UNIT_TEST_SNIPPETS_DW1000   // switch between unit test and demo apps
37

    
38
#define SWS1_SHF_MODE 0x02  //short frame mode (6.81M)
39
#define SWS1_CH5_MODE 0x04  //channel 5 mode
40
#define SWS1_ANC_MODE 0x08  //anchor mode
41
#define SWS1_A1A_MODE 0x10  //anchor/tag address A1
42
#define SWS1_A2A_MODE 0x20  //anchor/tag address A2
43
#define SWS1_A3A_MODE 0x40  //anchor/tag address A3
44
#define SWS1_USB2SPI_MODE 0x78  //USB to SPI mode
45

    
46
#define S1_SWITCH_ON  (1)
47
#define S1_SWITCH_OFF (0)
48

    
49
/******************************************************************************/
50
/* EXPORTED VARIABLES                                                         */
51
/******************************************************************************/
52

    
53
/******************************************************************************/
54
/* LOCAL TYPES                                                                */
55
/******************************************************************************/
56

    
57
/******************************************************************************/
58
/* LOCAL VARIABLES                                                            */
59
/******************************************************************************/
60
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
DW1000Driver* spiDrv;
67

    
68

    
69
/******************************************************************************/
70
/* LOCAL FUNCTIONS                                                            */
71
/******************************************************************************/
72

    
73
/*! @brief Change the SPI speed configuration  on the fly */
74
void setHighSpeed_SPI(bool speedValue){
75

    
76
  spiStop(&MODULE_HAL_SPI_UWB);
77
  //  spiAcquireBus(&MODULE_HAL_SPI_UWB);
78

    
79
  if (speedValue == FALSE){
80
    spiStart(&MODULE_HAL_SPI_UWB, &moduleHalSpiUwbLsConfig);  // low speed spi configuration
81
  }
82
  else{
83
    spiStart(&MODULE_HAL_SPI_UWB, &moduleHalSpiUwbHsConfig); // high speed spi configuration
84
  }
85
}
86
/* void setHighSpeed_SPI(bool speedValue){
87

88
  spiStop(spiDrv->spid);
89
  //  spiAcquireBus(&MODULE_HAL_SPI_UWB);
90

91
  if (speedValue == FALSE){
92
    spiStart(spiDrv->spid, &moduleHalSpiUwbLsConfig);  // low speed spi configuration
93
  }
94
  else{
95
    spiStart(spiDrv->spid, &moduleHalSpiUwbHsConfig); // high speed spi configuration
96
  }
97
} */
98

    
99
/*! @brief Manually set the chip select pin of the SPI */
100
void port_SPIx_set_chip_select(void){
101
  apalGpioWrite(moduleGpioSpiChipSelect.gpio, APAL_GPIO_HIGH);
102
}
103

    
104
/*! @brief Manually reset the chip select pin of the SPI */
105
void port_SPIx_clear_chip_select(void){
106
  apalGpioWrite(moduleGpioSpiChipSelect.gpio, APAL_GPIO_LOW);
107
}
108

    
109
/*! @brief Manually reset the DW1000 module  */
110
void reset_DW1000(void){
111

    
112
  // Set the pin as output
113
  palSetPadMode(moduleGpioDw1000Reset.gpio->port, moduleGpioDw1000Reset.gpio->pad, APAL_GPIO_DIRECTION_OUTPUT);
114

    
115
  //drive the RSTn pin low
116
  apalGpioWrite(moduleGpioDw1000Reset.gpio, APAL_GPIO_LOW);
117

    
118
  //put the pin back to tri-state ... as input
119
//  palSetPadMode(moduleGpioDw1000Reset.gpio->port, moduleGpioDw1000Reset.gpio->pad, APAL_GPIO_DIRECTION_INPUT); // TODO:
120

    
121
  aosThdMSleep(2);
122
}
123

    
124

    
125
/*! @brief Configure instance tag/anchor/etc... addresses
126
 *
127
 * */
128
void addressconfigure(uint8_t s1switch, uint8_t mode){
129
  uint16_t instAddress ;
130

    
131
  instance_anchaddr = (((s1switch & SWS1_A1A_MODE) << 2) + (s1switch & SWS1_A2A_MODE) + ((s1switch & SWS1_A3A_MODE) >> 2)) >> 4;
132

    
133
  if(mode == ANCHOR) {
134
    if(instance_anchaddr > 3) {
135
      instAddress = GATEWAY_ANCHOR_ADDR | 0x4 ; //listener
136
    }
137
    else {
138
      instAddress = GATEWAY_ANCHOR_ADDR | (uint16_t)instance_anchaddr;
139
    }
140
  }
141
  else{
142
    instAddress = (uint16_t)instance_anchaddr;
143
  }
144

    
145
  instancesetaddresses(instAddress);
146
}
147

    
148

    
149
/*! @brief returns the use case / operational mode
150
 *
151
 * */
152
int decarangingmode(uint8_t s1switch){
153
  int mode = 0;
154

    
155
  if(s1switch & SWS1_SHF_MODE)  {
156
    mode = 1;
157
  }
158

    
159
  if(s1switch & SWS1_CH5_MODE) {
160
    mode = mode + 2;
161
  }
162

    
163
  return mode;
164
}
165

    
166
/*! @brief Check connection setting and initialize DW1000 module
167
 *
168
 **/
169
uint32_t inittestapplication(uint8_t s1switch){
170
  uint32_t devID ;
171
  int result;
172

    
173
  setHighSpeed_SPI(FALSE);          //low speed spi max. ~4M
174
  devID = instancereaddeviceid() ;
175

    
176
  if(DWT_DEVICE_ID != devID) {
177
    port_SPIx_clear_chip_select();
178
    Sleep(1);
179
    port_SPIx_set_chip_select();
180
    Sleep(7);
181
    devID = instancereaddeviceid() ;
182
    if(DWT_DEVICE_ID != devID){
183
      return(-1) ;  // SPI not working or Unsupported Device ID
184
    }    
185
    dwt_softreset();//clear the sleep bit - so that after the hard reset below the DW does not go into sleep
186
  }
187

    
188
    reset_DW1000();  //reset the DW1000 by driving the RSTn line low
189

    
190
  if((s1switch & SWS1_ANC_MODE) == 0){
191
    instance_mode = TAG;
192
  }
193
  else{
194
    instance_mode = ANCHOR;
195
  }
196

    
197
  result = instance_init(spiDrv) ; // TODO
198
//  result = instance_init() ;
199

    
200
  if (0 > result){
201
    return(-1) ;
202
  }
203

    
204
  setHighSpeed_SPI(TRUE);               // high speed spi max. ~ 20M
205
  devID = instancereaddeviceid() ;
206

    
207
  if (DWT_DEVICE_ID != devID){
208
    return(-1) ;
209
  }
210

    
211
  addressconfigure(s1switch, (uint8_t)instance_mode) ;
212

    
213
  if((instance_mode == ANCHOR) && (instance_anchaddr > 0x3)){
214
    instance_mode = LISTENER;
215
  }
216

    
217
  instancesetrole(instance_mode) ;       // Set this instance role
218
  dr_mode = decarangingmode(s1switch);
219
  chan = chConfig[dr_mode].channelNumber ;
220
  instance_config(&chConfig[dr_mode], &sfConfig[dr_mode]) ;
221

    
222
  return devID;
223
}
224

    
225
/*! @brief Main Entry point to Initialization of UWB DW1000 configuration
226
 *
227
 * */
228
#pragma GCC optimize ("O3")
229
int UWB_Init(void){
230

    
231
  /*! Software defined Configurartion for TAG, ANC, and other settings as needed */
232
  s1switch = S1_SWITCH_OFF << 1 // is_switch_on(TA_SW1_2) << 2  // (on = 6.8 Mbps, off = 110 kbps)
233
                              | S1_SWITCH_OFF << 2  // (on = CH5, off = CH2)
234
                              | S1_SWITCH_OFF << 3  // (on = Anchor, off = TAG)
235
                              | S1_SWITCH_OFF << 4  // (configure Tag or anchor ID no.)
236
                              | S1_SWITCH_OFF << 5  // (configure Tag or anchor ID no.)
237
                              | S1_SWITCH_OFF << 6  // (configure Tag or anchor ID no.)
238
                              | S1_SWITCH_OFF << 7; // Not use in this demo
239

    
240

    
241
  port_DisableEXT_IRQ();           //disable ScenSor IRQ until we configure the device
242

    
243
  if((s1switch & SWS1_USB2SPI_MODE) == SWS1_USB2SPI_MODE){
244
    return 1;
245
  }
246
  else{
247
    //run RTLS application
248
    if(inittestapplication(s1switch) == (uint32_t)-1) {
249
      return 0; //error
250
    }
251

    
252
    aosThdMSleep(5);
253
  }
254

    
255
  port_EnableEXT_IRQ();           //enable ScenSor IRQ before starting
256

    
257
  return 0;
258
}
259

    
260

    
261
/******************************************************************************/
262
/* EXPORTED FUNCTIONS                                                         */
263
/******************************************************************************/
264

    
265

    
266
aos_utresult_t utAlldDw1000Func(BaseSequentialStream* stream, aos_unittest_t* ut) {
267

    
268
  aosDbgCheck(ut->data != NULL);
269

    
270
  aos_utresult_t result = {0, 0};
271

    
272

    
273
  /*! Unit Test snippets for DW1000.
274
     * @Note: Passed all 4 unit tests. Event IRQ should be tested separately
275
     */
276
#ifdef UNIT_TEST_SNIPPETS_DW1000
277

    
278
  uint32_t actual_deviceId;
279

    
280
  chprintf(stream, "init DW1000...\n");
281
  dwt_initialise(DWT_LOADUCODE, (DW1000Driver*) ut->data);
282
  aosThdMSleep(5);
283

    
284
  port_DisableEXT_IRQ();
285

    
286
  setHighSpeed_SPI(false);
287
  chprintf(stream, "expected device ID (LS SPI): 0xDECA0130 \n");
288
  aosThdMSleep(5);
289
  actual_deviceId = instancereaddeviceid();
290
  chprintf(stream, "actual read ID: 0x%x\n", actual_deviceId);
291
  aosThdMSleep(5);
292

    
293
  if(DWT_DEVICE_ID != actual_deviceId) //if the read of device ID fails, the DW1000 could be asleep
294
  {
295
    port_SPIx_clear_chip_select();  //CS low
296
    aosThdMSleep(1);   //200 us to wake up then waits 5ms for DW1000 XTAL to stabilise
297
    port_SPIx_set_chip_select();  //CS high
298
    aosThdMSleep(7);
299
    actual_deviceId = instancereaddeviceid() ;
300

    
301
    // SPI not working or Unsupported Device ID
302
    if(DWT_DEVICE_ID != actual_deviceId){
303
      chprintf(stream, "SPI not working or Unsupported Device ID\n");
304
      chprintf(stream, "actual device ID is: 0x%x\n", actual_deviceId);
305
      chprintf(stream, "expected device ID: 0xDECA0130 \n");
306
      aosThdMSleep(5);
307
      //          return(-1) ;
308
    }
309

    
310
    //clear the sleep bit - so that after the hard reset below the DW does not go into sleep
311
    dwt_softreset();
312
  }
313

    
314
  /*! Low speed SPI unit test result */
315
  if (actual_deviceId == DWT_DEVICE_ID){
316
    aosUtPassed(stream, &result);
317
  } else {
318
    aosUtFailed(stream, &result);
319
  }
320
  reset_DW1000();
321

    
322

    
323
  chprintf(stream, " Initialise instance for DW1000 \n");
324
  aosThdSleep(5);
325

    
326
  int x_init = instance_init((DW1000Driver*) ut->data) ;   // TODO
327
//  int x_init = instance_init() ;
328

    
329
  if (0 != x_init){
330
    chprintf(stream, "Init error with return value: %d \n", x_init);
331
    aosThdSleep(5);
332
  }
333
  else {
334
    chprintf(stream, "Init success with return value: %d \n", x_init);
335
    aosThdSleep(5);
336
  }
337

    
338

    
339
  /* Initialization unit test result */
340
  if (x_init == 0){
341
    aosUtPassed(stream, &result);
342
  } else {
343
    aosUtFailed(stream, &result);
344
  }
345

    
346

    
347
  setHighSpeed_SPI(true);
348

    
349
  chprintf(stream, "expected device ID (HS SPI): 0xDECA0130\n");
350
  actual_deviceId = instancereaddeviceid();
351
  chprintf(stream, "actual read ID: 0x%x\n", actual_deviceId);
352
  aosThdMSleep(5);
353

    
354
  /* High speed SPI unit test result */
355
  if (actual_deviceId == DWT_DEVICE_ID){
356
    aosUtPassed(stream, &result);
357
  } else {
358
    aosUtFailed(stream, &result);
359
  }
360

    
361
  port_EnableEXT_IRQ();
362
  reset_DW1000();
363

    
364

    
365

    
366
  chprintf(stream, " Initialise the configuration for UWB application \n");
367
  aosThdSleep(5);
368

    
369
  int uwb_init = UWB_Init();
370

    
371
  if (0 != uwb_init){
372
    chprintf(stream, "UWB config error with return value: %d \n", uwb_init);
373
    aosThdSleep(5);
374
  }
375
  else {
376
    chprintf(stream, "UWB config success with return value: %d \n", uwb_init);
377
    aosThdSleep(5);
378
  }
379

    
380
  /* UWB configuration unit test.
381
   * If all the four unit tests are passed, the module is ready to run.
382
   * Note that the interrupt IRQn should be tested separately.
383
   */
384
  if (uwb_init == 0){
385
    aosUtPassed(stream, &result);
386
  } else {
387
    aosUtFailed(stream, &result);
388
  }
389

    
390
  /************** End of UNIT_TEST_SNIPPETS_DW1000*****************/
391

    
392
#else
393

    
394
  // RUN THE STATE MACHINE DEMO APP
395

    
396
  chprintf(stream, " Initialise the State Machine \n");
397
  aosThdSleep(2);
398

    
399
  /* Initialize UWB system with the configuration provided in module_uwb_conf.c */
400
  int uwb_init = UWB_Init();
401

    
402
  if (0 != uwb_init){
403
    chprintf(stream, "UWB config error with return value: %d \n", uwb_init);
404
  }
405
  else {
406
    chprintf(stream, "UWB config success with return value: %d \n", uwb_init);
407
  }
408
  aosThdSleep(1);
409

    
410
  chprintf(stream, " Running the RTLS demo application \n");
411
  aosThdSleep(1);
412

    
413

    
414
  /* Run the localization system demo app as a thread */
415
  while(1){
416
    instance_run();
417
//    aosThdUSleep(10);
418
  }
419

    
420
#endif  /*  UNIT_TEST_SNIPPETS_DW1000 */
421

    
422
  return result;
423
}
424

    
425

    
426
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1) */