Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (11.642 KB)

1
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2020  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
#include <aos_test_DW1000.h>
21

    
22
#if (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
23

    
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
#include <deca_instance.h>
31

    
32

    
33
/******************************************************************************/
34
/* LOCAL DEFINITIONS                                                          */
35
/******************************************************************************/
36

    
37
#define TEST_SNIPPETS_DW1000   // switch between test and demo apps
38

    
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
/******************************************************************************/
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

    
67
/******************************************************************************/
68
/* LOCAL FUNCTIONS                                                            */
69
/******************************************************************************/
70

    
71
/*! @brief Configure instance tag/anchor/etc... addresses */
72
void addressconfigure(uint8_t s1switch, uint8_t mode){
73
  uint16_t instAddress ;
74

    
75
  instance_anchaddr = (((s1switch & SWS1_A1A_MODE) << 2) + (s1switch & SWS1_A2A_MODE) + ((s1switch & SWS1_A3A_MODE) >> 2)) >> 4;
76

    
77
  if(mode == ANCHOR) {
78
    if(instance_anchaddr > 3) {
79
      instAddress = GATEWAY_ANCHOR_ADDR | 0x4 ; //listener
80
    }
81
    else {
82
      instAddress = GATEWAY_ANCHOR_ADDR | (uint16_t)instance_anchaddr;
83
    }
84
  }
85
  else{
86
    instAddress = (uint16_t)instance_anchaddr;
87
  }
88

    
89
  instancesetaddresses(instAddress);
90
}
91

    
92
/*! @brief returns the use case / operational mode */
93
int decarangingmode(uint8_t s1switch){
94
  int mode = 0;
95

    
96
  if(s1switch & SWS1_SHF_MODE)  {
97
    mode = 1;
98
  }
99

    
100
  if(s1switch & SWS1_CH5_MODE) {
101
    mode = mode + 2;
102
  }
103

    
104
  return mode;
105
}
106

    
107
/*! @brief Check connection setting and initialize DW1000 module */
108
int32_t inittestapplication(uint8_t s1switch, DW1000Driver* drv){
109
  uint32_t devID ;
110
  int result;
111

    
112
  setHighSpeed_SPI(FALSE, drv);          //low speed spi max. ~4M
113
  devID = instancereaddeviceid() ;
114

    
115
  if(DWT_DEVICE_ID != devID) {
116
    clear_SPI_chip_select();
117
    Sleep(1);
118
    set_SPI_chip_select();
119
    Sleep(7);
120
    devID = instancereaddeviceid() ;
121
    if(DWT_DEVICE_ID != devID){
122
      return(-1) ;
123
    }    
124
    dwt_softreset();
125
  }
126

    
127
    reset_DW1000();  //reset the DW1000 by driving the RSTn line low
128

    
129
  if((s1switch & SWS1_ANC_MODE) == 0){
130
    instance_mode = TAG;
131
  }
132
  else{
133
    instance_mode = ANCHOR;
134
  }
135

    
136
  result = instance_init(drv) ;
137

    
138
  if (0 > result){
139
    return(-1) ;
140
  }
141

    
142
  setHighSpeed_SPI(TRUE, drv);       // high speed spi max. ~ 20M
143
  devID = instancereaddeviceid() ;
144

    
145
  if (DWT_DEVICE_ID != devID){
146
    return(-1) ;
147
  }
148

    
149
  addressconfigure(s1switch, (uint8_t)instance_mode) ;
150

    
151
  if((instance_mode == ANCHOR) && (instance_anchaddr > 0x3)){
152
    instance_mode = LISTENER;
153
  }
154

    
155
  instancesetrole(instance_mode) ;       // Set this instance role
156
  dr_mode = decarangingmode(s1switch);
157
  chan = chConfig[dr_mode].channelNumber ;
158
  instance_config(&chConfig[dr_mode], &sfConfig[dr_mode], drv) ;
159

    
160
  return (int32_t)devID;
161
}
162

    
163
/*! @brief Main Entry point to Initialization of UWB DW1000 configuration  */
164
#pragma GCC optimize ("O3")
165
int UWB_Init(DW1000Driver* drv){
166

    
167
  /*! Software defined Configurartion for TAG, ANC, and other settings as needed */
168
  s1switch = S1_SWITCH_OFF << 1  // (on = 6.8 Mbps, off = 110 kbps)
169
           | S1_SWITCH_OFF << 2  // (on = CH5, off = CH2)
170
           | S1_SWITCH_OFF << 3  // (on = Anchor, off = TAG)
171
           | S1_SWITCH_OFF << 4  // (configure Tag or anchor ID no.)
172
           | S1_SWITCH_OFF << 5  // (configure Tag or anchor ID no.)
173
           | S1_SWITCH_OFF << 6  // (configure Tag or anchor ID no.)
174
           | S1_SWITCH_OFF << 7; // Not use in this demo
175

    
176

    
177
  port_DisableEXT_IRQ();           //disable ScenSor IRQ until we configure the device
178

    
179
  if(inittestapplication(s1switch, drv) == -1) {
180
    return (-1); //error
181
  }
182

    
183
  aosThdMSleep(5);
184

    
185
  port_EnableEXT_IRQ();  //enable DW1000 IRQ before starting
186

    
187
  return 0;
188
}
189

    
190

    
191
/******************************************************************************/
192
/* EXPORTED FUNCTIONS                                                         */
193
/******************************************************************************/
194

    
195
aos_testresult_t aosTestDw1000Func(BaseSequentialStream* stream, const aos_test_t* test) {
196

    
197
  aosDbgCheck(test->data != NULL &&
198
      ((aos_test_dw1000data_t*)test->data)->driver != NULL &&
199
      ((aos_test_dw1000data_t*)test->data)->evtsource != NULL);
200

    
201
  // local variables
202
  aos_testresult_t result;
203

    
204
  aosTestResultInit(&result);
205

    
206
#if (BOARD_MIC9404x_CONNECTED == true)
207
  // Enable 3.3V and 1.8V supply voltages for powering up the DW1000 module in AMiRo Light Ring
208
  if ((test->data != NULL) && (((aos_test_dw1000data_t*)(test->data))->mic9404xd != NULL)){
209
//      && (((aos_test_dw1000data_t*)(test->data))->driver == NULL)){
210
    mic9404x_lld_state_t state;
211
    uint32_t status = APAL_STATUS_OK;
212

    
213
    chprintf(stream, "reading current status of the Power..\n");
214
    status = mic9404x_lld_get(((aos_test_dw1000data_t*)(test->data))->mic9404xd, &state);
215
    if (status == APAL_STATUS_OK) {
216
      aosTestPassedMsg(stream, &result, "power %s\n", (state == MIC9404x_LLD_STATE_ON) ? "enabled" : "disabled");
217
    } else {
218
      aosTestFailed(stream, &result);
219
    }
220
    if (state == MIC9404x_LLD_STATE_OFF) {
221
      chprintf(stream, "enabling the power ...\n");
222
      status = mic9404x_lld_set(((aos_test_dw1000data_t*)(test->data))->mic9404xd, MIC9404x_LLD_STATE_ON);
223
      status |= mic9404x_lld_get(((aos_test_dw1000data_t*)(test->data))->mic9404xd, &state);
224
      if (state == MIC9404x_LLD_STATE_ON) {
225
        aosThdSSleep(2);
226
        status |= mic9404x_lld_get(((aos_test_dw1000data_t*)(test->data))->mic9404xd, &state);
227
      }
228
      if ((status == APAL_STATUS_OK) && (state == MIC9404x_LLD_STATE_ON)) {
229
        aosTestPassed(stream, &result);
230
      } else {
231
        aosTestFailed(stream, &result);
232
      }
233
    }
234
    aosThdSleep(1);
235
    return result;
236
  }
237
#endif  /* BOARD_MIC9404x_CONNECTED == true */
238

    
239

    
240
  chprintf(stream, "init DW1000...\n");
241
  dwt_initialise(DWT_LOADUCODE, ((aos_test_dw1000data_t*)test->data)->driver);
242
  aosThdMSleep(5);
243

    
244
/*! Test snippets for DW1000.
245
 * @Note: Event IRQ for DW1000 should be tested separately
246
 */
247
#if defined(TEST_SNIPPETS_DW1000)
248

    
249
  uint32_t actual_deviceId;
250

    
251
  port_DisableEXT_IRQ();
252

    
253
  setHighSpeed_SPI(false, ((aos_test_dw1000data_t*)test->data)->driver);
254
  chprintf(stream, "expected device ID (LS SPI): 0xDECA0130\n");
255
  aosThdMSleep(5);
256
  actual_deviceId = instancereaddeviceid();
257
  chprintf(stream, "actual read ID: 0x%x\n", actual_deviceId);
258
  aosThdMSleep(5);
259

    
260
  //if the read of device ID fails, the DW1000 could be asleep
261
  if(DWT_DEVICE_ID != actual_deviceId){
262

    
263
    clear_SPI_chip_select();
264
    aosThdMSleep(1);
265
    set_SPI_chip_select();
266
    aosThdMSleep(7);
267
    actual_deviceId = instancereaddeviceid() ;
268

    
269
    if(DWT_DEVICE_ID != actual_deviceId){
270
      chprintf(stream, "SPI is not working or Unsupported Device ID\n");
271
      chprintf(stream, "actual device ID is: 0x%x\n", actual_deviceId);
272
      chprintf(stream, "expected device ID: 0xDECA0130\n");
273
      aosThdMSleep(5);
274
    }
275

    
276
    //clear the sleep bit - so that after the hard reset below the DW does not go into sleep
277
    dwt_softreset();
278
  }
279

    
280
  /*! Test1: Low speed SPI result */
281
  if (actual_deviceId == DWT_DEVICE_ID){
282
    aosTestPassed(stream, &result);
283
  } else {
284
    aosTestFailed(stream, &result);
285
  }
286

    
287
  reset_DW1000();
288

    
289
  chprintf(stream, "initialise instance for DW1000\n");
290
  aosThdSleep(1);
291

    
292
  int x_init = instance_init(((aos_test_dw1000data_t*)test->data)->driver) ;
293

    
294
  if (0 != x_init){
295
    chprintf(stream, "init error with return value: %d\n", x_init);
296
    aosThdSleep(1);
297
  }
298
  else {
299
    chprintf(stream, "init success with return value: %d\n", x_init);
300
    aosThdSleep(1);
301
  }
302

    
303
  /*! Test2: Initialization  result*/
304
  if (x_init == 0){
305
    aosTestPassed(stream, &result);
306
  } else {
307
    aosTestFailed(stream, &result);
308
  }
309

    
310
  setHighSpeed_SPI(true, ((aos_test_dw1000data_t*)test->data)->driver);
311

    
312
  chprintf(stream, "expected device ID (HS SPI): 0xDECA0130\n");
313
  actual_deviceId = instancereaddeviceid();
314
  chprintf(stream, "actual read ID: 0x%x\n", actual_deviceId);
315
  aosThdMSleep(1);
316

    
317
  /*! Test3: High speed SPI result*/
318
  if (actual_deviceId == DWT_DEVICE_ID){
319
    aosTestPassed(stream, &result);
320
  } else {
321
    aosTestFailed(stream, &result);
322
  }
323

    
324
  port_EnableEXT_IRQ();
325
  reset_DW1000();
326

    
327
  chprintf(stream, "initialise the configuration for UWB application\n");
328
  aosThdSleep(1);
329

    
330
  int uwb_init = UWB_Init(((aos_test_dw1000data_t*)test->data)->driver);
331

    
332
  if (0 != uwb_init){
333
    chprintf(stream, "UWB config error with return value: %d\n", uwb_init);
334
    aosThdSleep(1);
335
  }
336
  else {
337
    chprintf(stream, "UWB config success with return value: %d\n", uwb_init);
338
    aosThdSleep(1);
339
  }
340

    
341
  /*! Test4: UWB configuration result
342
   * If all the four tests are passed, the module is ready to run.
343
   * Note that the interrupt IRQn should be tested separately.
344
   */
345
  if (uwb_init == 0){
346
    aosTestPassed(stream, &result);
347
  } else {
348
    aosTestFailed(stream, &result);
349
  }
350

    
351
  /************** End of TEST_SNIPPETS_DW1000*****************/
352

    
353
#else /* defined(TEST_SNIPPETS_DW1000) */
354

    
355

    
356
  /*! RUN THE STATE MACHINE DEMO APP (RTLS) */
357

    
358
  chprintf(stream, "initialise the State Machine\n");
359
  aosThdSleep(2);
360

    
361
  /* Initialize UWB system with user defined configuration  */
362
  int uwb_init = UWB_Init(((aos_test_dw1000data_t*)test->data)->driver);
363

    
364
  if (0 != uwb_init){
365
    chprintf(stream, "error in UWB config with return value: %d\n", uwb_init);
366
  }
367
  else {
368
    chprintf(stream, "succeed the init of UWB config\n");
369
  }
370
  aosThdSleep(1);
371

    
372
  chprintf(stream, "running the RTLS demo application ...\n");
373
  aosThdSleep(1);
374

    
375
  /*! Run the localization system demo app as a thread */
376
  while(1){
377
    instance_run();
378
//    aosThdUSleep(100);
379
  }
380

    
381
#endif  /* defined(TEST_SNIPPETS_DW1000) */
382

    
383
  return result;
384
}
385

    
386

    
387
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */