Revision 4cb40108

View differences:

modules/NUCLEO-F103RB/alldconf.h
43 43
 */
44 44
#define AMIROLLD_CFG_TIME_SIZE                  32
45 45

  
46
#define AMIROLLD_CFG_DW1000              1
46
#define AMIROLLD_CFG_DW1000                     1
47 47

  
48 48
#endif /* ALLDCONF_H */
49 49

  
periphery-lld/AMiRo-LLD
1
Subproject commit 7df78c60db679f32c180cc23776e5e449fc7fab5
1
Subproject commit fe058578399582fb138f1a3379972a2b519ff717
unittests/periphery-lld/inc/ut_alld_DW1000_v1.h
16 16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 17
*/
18 18

  
19
#ifndef AMIROOS_UT_ALLD_DW1000_V1_H
20
#define AMIROOS_UT_ALLD_DW1000_V1_H
19
#ifndef AMIROOS_UT_ALLD_DW1000_V1_LLD_H
20
#define AMIROOS_UT_ALLD_DW1000_V1_LLD_H
21 21

  
22
#include <amiroos.h>
22
#include <aos_unittest.h>
23
#include <amiro-lld.h>
23 24

  
24
#if ((AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 0)) || defined(__DOXYGEN__)
25
#if ((AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)) || defined(__DOXYGEN__)
25 26

  
26 27
#include <alld_DW1000.h>
27 28

  
......
53 54
extern "C" {
54 55
#endif /* defined(__cplusplus) */
55 56
  aos_utresult_t utAlldDw1000Func(BaseSequentialStream* stream, aos_unittest_t* ut);
57

  
58
  extern uint8_t s1switch;
59
  extern int instance_anchaddr;
60
  extern int dr_mode;
61
  extern int chan, tagaddr, ancaddr;
62
  extern int instance_mode;
63

  
64
  int UWB_Init(DW1000Driver* drv);
65
  int32_t inittestapplication(uint8_t s1switch, DW1000Driver* drv);
66
  int decarangingmode(uint8_t s1switch);
67
  void addressconfigure(uint8_t s1switch, uint8_t mode);
68
  void set_SPI_chip_select(void);
69
  void clear_SPI_chip_select(void);
70
  void reset_DW1000(void);
71
  void setHighSpeed_SPI(bool speedValue, DW1000Driver* drv);
72
  apalGpioState_t port_CheckEXT_IRQ(void) ;
73
  void process_deca_irq(void);
74

  
56 75
#if defined(__cplusplus)
57 76
}
58 77
#endif /* defined(__cplusplus) */
......
61 80
/* INLINE FUNCTIONS                                                           */
62 81
/******************************************************************************/
63 82

  
64
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 0) */
65 83

  
66
#endif /* AMIROOS_UT_ALLD_DW1000_V1_H */
84
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1) */
85

  
86
#endif /* AMIROOS_UT_ALLD_DW1000_V1_LLD_H */
unittests/periphery-lld/inc/ut_alld_dw1000_v1.h
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
#ifndef _AMIROOS_UT_DW1000_LLD_H_
20
#define _AMIROOS_UT_DW1000_LLD_H_
21

  
22
#include <aos_unittest.h>
23
#include <amiro-lld.h>
24

  
25
#if ((AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)) || defined(__DOXYGEN__)
26

  
27
#include <alld_DW1000.h>
28

  
29
/******************************************************************************/
30
/* CONSTANTS                                                                  */
31
/******************************************************************************/
32

  
33
/******************************************************************************/
34
/* SETTINGS                                                                   */
35
/******************************************************************************/
36

  
37
/******************************************************************************/
38
/* CHECKS                                                                     */
39
/******************************************************************************/
40

  
41
/******************************************************************************/
42
/* DATA STRUCTURES AND TYPES                                                  */
43
/******************************************************************************/
44

  
45
/******************************************************************************/
46
/* MACROS                                                                     */
47
/******************************************************************************/
48

  
49
/******************************************************************************/
50
/* EXTERN DECLARATIONS                                                        */
51
/******************************************************************************/
52

  
53
#if defined(__cplusplus)
54
extern "C" {
55
#endif /* defined(__cplusplus) */
56
  aos_utresult_t utAlldDw1000Func(BaseSequentialStream* stream, aos_unittest_t* ut);
57

  
58
  extern uint8_t s1switch;
59
  extern int instance_anchaddr;
60
  extern int dr_mode;
61
  extern int chan, tagaddr, ancaddr;
62
  extern int instance_mode;
63

  
64
  int UWB_Init(DW1000Driver* drv);
65
  int32_t inittestapplication(uint8_t s1switch, DW1000Driver* drv);
66
  int decarangingmode(uint8_t s1switch);
67
  void addressconfigure(uint8_t s1switch, uint8_t mode);
68
  void set_SPI_chip_select(void);
69
  void clear_SPI_chip_select(void);
70
  void reset_DW1000(void);
71
  void setHighSpeed_SPI(bool speedValue, DW1000Driver* drv);
72
  apalGpioState_t port_CheckEXT_IRQ(void) ;
73
  void process_deca_irq(void);
74

  
75
#if defined(__cplusplus)
76
}
77
#endif /* defined(__cplusplus) */
78

  
79
/******************************************************************************/
80
/* INLINE FUNCTIONS                                                           */
81
/******************************************************************************/
82

  
83

  
84
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 0) */
85

  
86
#endif /* _AMIROOS_UT_DW1000_LLD_H_ */
unittests/periphery-lld/src/ut_alld_DW1000_v1.c
17 17
*/
18 18

  
19 19
#include <amiroos.h>
20
#include <ut_alld_DW1000_v1.h>
21 20

  
22
#if ((AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 0)) || defined(__DOXYGEN__)
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

  
23 31

  
24 32
/******************************************************************************/
25 33
/* LOCAL DEFINITIONS                                                          */
26 34
/******************************************************************************/
27 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

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

  
28 48
/******************************************************************************/
29 49
/* EXPORTED VARIABLES                                                         */
30 50
/******************************************************************************/
......
36 56
/******************************************************************************/
37 57
/* LOCAL VARIABLES                                                            */
38 58
/******************************************************************************/
59
uint8_t s1switch = 0;
60
int instance_anchaddr = 0;
61
int dr_mode = 0;
62
int chan, tagaddr, ancaddr;
63
int instance_mode = ANCHOR;
64

  
39 65

  
40 66
/******************************************************************************/
41 67
/* LOCAL FUNCTIONS                                                            */
42 68
/******************************************************************************/
43 69

  
70
/*! @brief Change the SPI speed configuration on the fly */
71
void setHighSpeed_SPI(bool speedValue, DW1000Driver* drv){
72

  
73
  spiStop(drv->spid);
74

  
75
  if (speedValue == FALSE){
76
    spiStart(drv->spid, &moduleHalSpiUwbLsConfig);  // low speed spi configuration
77
  }
78
  else{
79
    spiStart(drv->spid, &moduleHalSpiUwbHsConfig); // high speed spi configuration
80
  }
81
}
82

  
83
/*! @brief entry point to the IRQn event in DW1000 module
84
 *
85
 * */
86
void process_deca_irq(void){
87
  do{
88
    dwt_isr();
89
    //while IRS line active (ARM can only do edge sensitive interrupts)
90
  }while(port_CheckEXT_IRQ() == 1);
91
}
92

  
93
/*! @brief Check the current value of GPIO pin and return the value */
94
apalGpioState_t port_CheckEXT_IRQ(void) {
95
  apalGpioState_t  val;
96
  apalGpioRead(moduleGpioDw1000Irqn.gpio, &val);
97
  return val;
98
}
99

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

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

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

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

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

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

  
122
  aosThdMSleep(2);
123
}
124

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

  
129
  instance_anchaddr = (((s1switch & SWS1_A1A_MODE) << 2) + (s1switch & SWS1_A2A_MODE) + ((s1switch & SWS1_A3A_MODE) >> 2)) >> 4;
130

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

  
143
  instancesetaddresses(instAddress);
144
}
145

  
146
/*! @brief returns the use case / operational mode */
147
int decarangingmode(uint8_t s1switch){
148
  int mode = 0;
149

  
150
  if(s1switch & SWS1_SHF_MODE)  {
151
    mode = 1;
152
  }
153

  
154
  if(s1switch & SWS1_CH5_MODE) {
155
    mode = mode + 2;
156
  }
157

  
158
  return mode;
159
}
160

  
161
/*! @brief Check connection setting and initialize DW1000 module */
162
int32_t inittestapplication(uint8_t s1switch, DW1000Driver* drv){
163
  uint32_t devID ;
164
  int result;
165

  
166
  setHighSpeed_SPI(FALSE, drv);          //low speed spi max. ~4M
167
  devID = instancereaddeviceid() ;
168

  
169
  if(DWT_DEVICE_ID != devID) {
170
    clear_SPI_chip_select();
171
    Sleep(1);
172
    set_SPI_chip_select();
173
    Sleep(7);
174
    devID = instancereaddeviceid() ;
175
    if(DWT_DEVICE_ID != devID){
176
      return(-1) ;
177
    }    
178
    dwt_softreset();
179
  }
180

  
181
    reset_DW1000();  //reset the DW1000 by driving the RSTn line low
182

  
183
  if((s1switch & SWS1_ANC_MODE) == 0){
184
    instance_mode = TAG;
185
  }
186
  else{
187
    instance_mode = ANCHOR;
188
  }
189

  
190
  result = instance_init(drv) ;
191

  
192
  if (0 > result){
193
    return(-1) ;
194
  }
195

  
196
  setHighSpeed_SPI(TRUE, drv);       // high speed spi max. ~ 20M
197
  devID = instancereaddeviceid() ;
198

  
199
  if (DWT_DEVICE_ID != devID){
200
    return(-1) ;
201
  }
202

  
203
  addressconfigure(s1switch, (uint8_t)instance_mode) ;
204

  
205
  if((instance_mode == ANCHOR) && (instance_anchaddr > 0x3)){
206
    instance_mode = LISTENER;
207
  }
208

  
209
  instancesetrole(instance_mode) ;       // Set this instance role
210
  dr_mode = decarangingmode(s1switch);
211
  chan = chConfig[dr_mode].channelNumber ;
212
  instance_config(&chConfig[dr_mode], &sfConfig[dr_mode], drv) ;
213

  
214
  return (int32_t)devID;
215
}
216

  
217
/*! @brief Main Entry point to Initialization of UWB DW1000 configuration  */
218
#pragma GCC optimize ("O3")
219
int UWB_Init(DW1000Driver* drv){
220

  
221
  /*! Software defined Configurartion for TAG, ANC, and other settings as needed */
222
  s1switch = S1_SWITCH_OFF << 1  // (on = 6.8 Mbps, off = 110 kbps)
223
           | S1_SWITCH_OFF << 2  // (on = CH5, off = CH2)
224
           | S1_SWITCH_OFF << 3  // (on = Anchor, off = TAG)
225
           | S1_SWITCH_OFF << 4  // (configure Tag or anchor ID no.)
226
           | S1_SWITCH_OFF << 5  // (configure Tag or anchor ID no.)
227
           | S1_SWITCH_OFF << 6  // (configure Tag or anchor ID no.)
228
           | S1_SWITCH_OFF << 7; // Not use in this demo
229

  
230

  
231
  port_DisableEXT_IRQ();           //disable ScenSor IRQ until we configure the device
232

  
233
  if(inittestapplication(s1switch, drv) == -1) {
234
    return (-1); //error
235
  }
236

  
237
  aosThdMSleep(5);
238

  
239
  port_EnableEXT_IRQ();  //enable DW1000 IRQ before starting
240

  
241
  return 0;
242
}
243

  
244

  
44 245
/******************************************************************************/
45 246
/* EXPORTED FUNCTIONS                                                         */
46 247
/******************************************************************************/
47 248

  
249

  
48 250
aos_utresult_t utAlldDw1000Func(BaseSequentialStream* stream, aos_unittest_t* ut) {
49 251

  
50
    aosDbgCheck(ut->data != NULL);
252
  aosDbgCheck(ut->data != NULL);
51 253

  
52
    aos_utresult_t result = {0, 0};
254
  aos_utresult_t result = {0, 0};
53 255

  
54
    chprintf(stream, "init DW1000...\n");
55
    dwt_initialise(DWT_LOADUCODE, (DW1000Driver*) ut->data);
56
    chprintf(stream, "device ID should be: 0xDECA0130\nget device ID...\n");
57
    uint32_t actual_deviceId = dwt_readdevid();
58
    chprintf(stream, "actual device ID is: 0x%x\n", actual_deviceId);
59
    aosThdMSleep(1);
256
  chprintf(stream, "init DW1000...\n");
257
  dwt_initialise(DWT_LOADUCODE, (DW1000Driver*) ut->data);
258
  aosThdMSleep(5);
60 259

  
61
    if (actual_deviceId == DWT_DEVICE_ID){
62
      aosUtPassed(stream, &result);
63
    } else {
64
      aosUtFailed(stream, &result);
65
    }
66 260

  
67
    /*chprintf(stream, "write-read test...\n");
68
    uint32_t testvalue = 0x0A;
69
    uint16_t panid = 0x00;
261
/*! Unit Test snippets for DW1000.
262
 * @Note: Event IRQ for DW1000 should be tested separately
263
 */
264
#if defined(UNIT_TEST_SNIPPETS_DW1000)
70 265

  
71
    dwt_readfromdevice(PANADR_ID, PANADR_PAN_ID_OFFSET, 2, (uint8_t*) &panid);
72
    chprintf(stream, "value PANADR register before write: %x\n", panid);
73
    chprintf(stream, "write 0x%x to PANADR register...\n", testvalue);
74
    dwt_setpanid(testvalue);
75
    dwt_readfromdevice(PANADR_ID, PANADR_PAN_ID_OFFSET, 2, (uint8_t*) &panid);
266
  uint32_t actual_deviceId;
76 267

  
77
    chprintf(stream, "PANADR register is now: 0x%x\n", panid);
268
  port_DisableEXT_IRQ();
78 269

  
79
    if (panid == testvalue){
80
      aosUtPassed(stream, &result);
81
    } else {
82
      aosUtFailed(stream, &result);
83
    }
84
*/
270
  setHighSpeed_SPI(false, (DW1000Driver*) ut->data);
271
  chprintf(stream, "expected device ID (LS SPI): 0xDECA0130 \n");
272
  aosThdMSleep(5);
273
  actual_deviceId = instancereaddeviceid();
274
  chprintf(stream, "actual read ID: 0x%x\n", actual_deviceId);
275
  aosThdMSleep(5);
85 276

  
86
    dwt_setleds(0x03);
87

  
88
    // RUN DECA-DEMO
89

  
90
    instanceConfig_t chConfig;
91
    chConfig.channelNumber = 2;            // channel
92
    chConfig.preambleCode = 4;             // preambleCode
93
    chConfig.pulseRepFreq = DWT_PRF_16M;   // prf
94
    chConfig.dataRate = DWT_BR_6M8;        // datarate
95
    chConfig.preambleLen = DWT_PLEN_128;   // preambleLength
96
    chConfig.pacSize = DWT_PAC8;           // pacSize
97
    chConfig.nsSFD = 0;                    // non-standard SFD
98
    chConfig.sfdTO = (129 + 8 - 8);        // SFD timeout
99

  
100
    sfConfig_t sfConfig;
101
    sfConfig.slotDuration_ms = (10);        //slot duration in milliseconds (NOTE: the ranging exchange must be able to complete in this time
102
                                            //e.g. tag sends a poll, 4 anchors send responses and tag sends the final + processing time
103
    sfConfig.numSlots = (10);               //number of slots in the superframe (8 tag slots and 2 used for anchor to anchor ranging),
104
    sfConfig.sfPeriod_ms = (10*10);         //in ms => 100 ms frame means 10 Hz location rate
105
    sfConfig.tagPeriod_ms = (10*10);        //tag period in ms (sleep time + ranging time)
106
    sfConfig.pollTxToFinalTxDly_us = (2500); //poll to final delay in microseconds (needs to be adjusted according to lengths of ranging frames)
107

  
108
    //TODO Disable EXTI IRQ
109
    //port_DisableEXT_IRQ();
110

  
111
    // inittestapplication
112
    // dwt_softreset(); // already done in instance_init()
113

  
114
    // Set this instance mode (tag/anchor)
115
    (void) instance_init(TAG, (DW1000Driver*) ut->data);
116
    //int err = instance_init(TAG, (DW1000Driver*) ut->data);
117
    (void) instance_readdeviceid();
118
    //uint32_t deca_dev_id = instance_readdeviceid();
119

  
120
    // TAG ID 0
121
    instance_set_16bit_address(0);
122
    // simulate DECA config Mode 2 (DIP 1100000)
123
    instance_config(&chConfig, &sfConfig) ;
124

  
125
    //TODO Enable EXTI IRQ
126
    //port_EnableEXT_IRQ();
127

  
128
    // Start Ranging
129

  
130
    chprintf(stream, "start ranging...\n");
131

  
132

  
133
    while(1) {
134
        //int n = 0;
135
        instance_data_t* inst = instance_get_local_structure_ptr(0);
136

  
137
        int monitor_local = inst->monitor ;
138
        int txdiff = (chVTGetSystemTimeX() - inst->timeofTx);
139

  
140
        tag_run();
141
        //if delayed TX scheduled but did not happen after expected time then it has failed... (has to be < slot period)
142
        //if anchor just go into RX and wait for next message from tags/anchors
143
        //if tag handle as a timeout
144
        if( (monitor_local == 1) && ( txdiff > inst->slotDuration_ms) )  {
145
            inst->wait4ack = 0;
146
            tag_process_rx_timeout(inst);
147
            inst->monitor = 0;
148
        }
149
    }
277
  //if the read of device ID fails, the DW1000 could be asleep
278
  if(DWT_DEVICE_ID != actual_deviceId){
150 279

  
151
    (void) instance_newrange();
152
    //int rx = instance_newrange();
280
    clear_SPI_chip_select();
281
    aosThdMSleep(1);
282
    set_SPI_chip_select();
283
    aosThdMSleep(7);
284
    actual_deviceId = instancereaddeviceid() ;
285

  
286
    if(DWT_DEVICE_ID != actual_deviceId){
287
      chprintf(stream, "SPI is not working or Unsupported Device ID\n");
288
      chprintf(stream, "actual device ID is: 0x%x\n", actual_deviceId);
289
      chprintf(stream, "expected device ID: 0xDECA0130 \n");
290
      aosThdMSleep(5);
291
    }
153 292

  
154
    return result;
293
    //clear the sleep bit - so that after the hard reset below the DW does not go into sleep
294
    dwt_softreset();
295
  }
296

  
297
  /*! UT1: Low speed SPI result */
298
  if (actual_deviceId == DWT_DEVICE_ID){
299
    aosUtPassed(stream, &result);
300
  } else {
301
    aosUtFailed(stream, &result);
302
  }
303

  
304
  reset_DW1000();
305

  
306
  chprintf(stream, "initialise instance for DW1000 \n");
307
  aosThdSleep(1);
308

  
309
  int x_init = instance_init((DW1000Driver*) ut->data) ;
310

  
311
  if (0 != x_init){
312
    chprintf(stream, "init error with return value: %d \n", x_init);
313
    aosThdSleep(1);
314
  }
315
  else {
316
    chprintf(stream, "init success with return value: %d \n", x_init);
317
    aosThdSleep(1);
318
  }
319

  
320
  /*! UT2: Initialization  result*/
321
  if (x_init == 0){
322
    aosUtPassed(stream, &result);
323
  } else {
324
    aosUtFailed(stream, &result);
325
  }
326

  
327
  setHighSpeed_SPI(true, (DW1000Driver*) ut->data);
328

  
329
  chprintf(stream, "expected device ID (HS SPI): 0xDECA0130\n");
330
  actual_deviceId = instancereaddeviceid();
331
  chprintf(stream, "actual read ID: 0x%x\n", actual_deviceId);
332
  aosThdMSleep(1);
333

  
334
  /*! UT3: High speed SPI result*/
335
  if (actual_deviceId == DWT_DEVICE_ID){
336
    aosUtPassed(stream, &result);
337
  } else {
338
    aosUtFailed(stream, &result);
339
  }
340

  
341
  port_EnableEXT_IRQ();
342
  reset_DW1000();
343

  
344
  chprintf(stream, "initialise the configuration for UWB application \n");
345
  aosThdSleep(1);
346

  
347
  int uwb_init = UWB_Init((DW1000Driver*) ut->data);
348

  
349
  if (0 != uwb_init){
350
    chprintf(stream, "UWB config error with return value: %d \n", uwb_init);
351
    aosThdSleep(1);
352
  }
353
  else {
354
    chprintf(stream, "UWB config success with return value: %d \n", uwb_init);
355
    aosThdSleep(1);
356
  }
357

  
358
  /*! UT4: UWB configuration result
359
   * If all the four unit tests are passed, the module is ready to run.
360
   * Note that the interrupt IRQn should be tested separately.
361
   */
362
  if (uwb_init == 0){
363
    aosUtPassed(stream, &result);
364
  } else {
365
    aosUtFailed(stream, &result);
366
  }
367

  
368
  /************** End of UNIT_TEST_SNIPPETS_DW1000*****************/
369

  
370
#else /* defined(UNIT_TEST_SNIPPETS_DW1000) */
371

  
372

  
373
  /*! RUN THE STATE MACHINE DEMO APP (RTLS) */
374

  
375
  chprintf(stream, "initialise the State Machine \n");
376
  aosThdSleep(2);
377

  
378
  /* Initialize UWB system with user defined configuration  */
379
  int uwb_init = UWB_Init((DW1000Driver*) ut->data);
380

  
381
  if (0 != uwb_init){
382
    chprintf(stream, "error in UWB config with return value: %d \n", uwb_init);
383
  }
384
  else {
385
    chprintf(stream, "succeed the init of UWB config \n");
386
  }
387
  aosThdSleep(1);
388

  
389
  chprintf(stream, "running the RTLS demo application ... \n");
390
  aosThdSleep(1);
391

  
392
  /*! Run the localization system demo app as a thread */
393
  while(1){
394
    instance_run();
395
//    aosThdUSleep(10);
396
  }
397

  
398
#endif  /* defined(UNIT_TEST_SNIPPETS_DW1000) */
399

  
400
  return result;
155 401
}
156 402

  
157
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 0) */
403

  
404
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1) */
unittests/periphery-lld/src/ut_alld_dw1000_v1.c
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

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

  
48
/******************************************************************************/
49
/* EXPORTED VARIABLES                                                         */
50
/******************************************************************************/
51

  
52
/******************************************************************************/
53
/* LOCAL TYPES                                                                */
54
/******************************************************************************/
55

  
56
/******************************************************************************/
57
/* LOCAL VARIABLES                                                            */
58
/******************************************************************************/
59
uint8_t s1switch = 0;
60
int instance_anchaddr = 0;
61
int dr_mode = 0;
62
int chan, tagaddr, ancaddr;
63
int instance_mode = ANCHOR;
64

  
65

  
66
/******************************************************************************/
67
/* LOCAL FUNCTIONS                                                            */
68
/******************************************************************************/
69

  
70
/*! @brief Change the SPI speed configuration on the fly */
71
void setHighSpeed_SPI(bool speedValue, DW1000Driver* drv){
72

  
73
  spiStop(drv->spid);
74

  
75
  if (speedValue == FALSE){
76
    spiStart(drv->spid, &moduleHalSpiUwbLsConfig);  // low speed spi configuration
77
  }
78
  else{
79
    spiStart(drv->spid, &moduleHalSpiUwbHsConfig); // high speed spi configuration
80
  }
81
}
82

  
83
/*! @brief entry point to the IRQn event in DW1000 module
84
 *
85
 * */
86
void process_deca_irq(void){
87
  do{
88
    dwt_isr();
89
    //while IRS line active (ARM can only do edge sensitive interrupts)
90
  }while(port_CheckEXT_IRQ() == 1);
91
}
92

  
93
/*! @brief Check the current value of GPIO pin and return the value */
94
apalGpioState_t port_CheckEXT_IRQ(void) {
95
  apalGpioState_t  val;
96
  apalGpioRead(moduleGpioDw1000Irqn.gpio, &val);
97
  return val;
98
}
99

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

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

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

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

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

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

  
122
  aosThdMSleep(2);
123
}
124

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

  
129
  instance_anchaddr = (((s1switch & SWS1_A1A_MODE) << 2) + (s1switch & SWS1_A2A_MODE) + ((s1switch & SWS1_A3A_MODE) >> 2)) >> 4;
130

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

  
143
  instancesetaddresses(instAddress);
144
}
145

  
146
/*! @brief returns the use case / operational mode */
147
int decarangingmode(uint8_t s1switch){
148
  int mode = 0;
149

  
150
  if(s1switch & SWS1_SHF_MODE)  {
151
    mode = 1;
152
  }
153

  
154
  if(s1switch & SWS1_CH5_MODE) {
155
    mode = mode + 2;
156
  }
157

  
158
  return mode;
159
}
160

  
161
/*! @brief Check connection setting and initialize DW1000 module */
162
int32_t inittestapplication(uint8_t s1switch, DW1000Driver* drv){
163
  uint32_t devID ;
164
  int result;
165

  
166
  setHighSpeed_SPI(FALSE, drv);          //low speed spi max. ~4M
167
  devID = instancereaddeviceid() ;
168

  
169
  if(DWT_DEVICE_ID != devID) {
170
    clear_SPI_chip_select();
171
    Sleep(1);
172
    set_SPI_chip_select();
173
    Sleep(7);
174
    devID = instancereaddeviceid() ;
175
    if(DWT_DEVICE_ID != devID){
176
      return(-1) ;
177
    }    
178
    dwt_softreset();
179
  }
180

  
181
    reset_DW1000();  //reset the DW1000 by driving the RSTn line low
182

  
183
  if((s1switch & SWS1_ANC_MODE) == 0){
184
    instance_mode = TAG;
185
  }
186
  else{
187
    instance_mode = ANCHOR;
188
  }
189

  
190
  result = instance_init(drv) ;
191

  
192
  if (0 > result){
193
    return(-1) ;
194
  }
195

  
196
  setHighSpeed_SPI(TRUE, drv);       // high speed spi max. ~ 20M
197
  devID = instancereaddeviceid() ;
198

  
199
  if (DWT_DEVICE_ID != devID){
200
    return(-1) ;
201
  }
202

  
203
  addressconfigure(s1switch, (uint8_t)instance_mode) ;
204

  
205
  if((instance_mode == ANCHOR) && (instance_anchaddr > 0x3)){
206
    instance_mode = LISTENER;
207
  }
208

  
209
  instancesetrole(instance_mode) ;       // Set this instance role
210
  dr_mode = decarangingmode(s1switch);
211
  chan = chConfig[dr_mode].channelNumber ;
212
  instance_config(&chConfig[dr_mode], &sfConfig[dr_mode], drv) ;
213

  
214
  return (int32_t)devID;
215
}
216

  
217
/*! @brief Main Entry point to Initialization of UWB DW1000 configuration  */
218
#pragma GCC optimize ("O3")
219
int UWB_Init(DW1000Driver* drv){
220

  
221
  /*! Software defined Configurartion for TAG, ANC, and other settings as needed */
222
  s1switch = S1_SWITCH_OFF << 1  // (on = 6.8 Mbps, off = 110 kbps)
223
           | S1_SWITCH_OFF << 2  // (on = CH5, off = CH2)
224
           | S1_SWITCH_OFF << 3  // (on = Anchor, off = TAG)
225
           | S1_SWITCH_OFF << 4  // (configure Tag or anchor ID no.)
226
           | S1_SWITCH_OFF << 5  // (configure Tag or anchor ID no.)
227
           | S1_SWITCH_OFF << 6  // (configure Tag or anchor ID no.)
228
           | S1_SWITCH_OFF << 7; // Not use in this demo
229

  
230

  
231
  port_DisableEXT_IRQ();           //disable ScenSor IRQ until we configure the device
232

  
233
  if(inittestapplication(s1switch, drv) == -1) {
234
    return (-1); //error
235
  }
236

  
237
  aosThdMSleep(5);
238

  
239
  port_EnableEXT_IRQ();  //enable DW1000 IRQ before starting
240

  
241
  return 0;
242
}
243

  
244

  
245
/******************************************************************************/
246
/* EXPORTED FUNCTIONS                                                         */
247
/******************************************************************************/
248

  
249

  
250
aos_utresult_t utAlldDw1000Func(BaseSequentialStream* stream, aos_unittest_t* ut) {
251

  
252
  aosDbgCheck(ut->data != NULL);
253

  
254
  aos_utresult_t result = {0, 0};
255

  
256
  chprintf(stream, "init DW1000...\n");
257
  dwt_initialise(DWT_LOADUCODE, (DW1000Driver*) ut->data);
258
  aosThdMSleep(5);
259

  
260

  
261
/*! Unit Test snippets for DW1000.
262
 * @Note: Event IRQ for DW1000 should be tested separately
263
 */
264
#if defined(UNIT_TEST_SNIPPETS_DW1000)
265

  
266
  uint32_t actual_deviceId;
267

  
268
  port_DisableEXT_IRQ();
269

  
270
  setHighSpeed_SPI(false, (DW1000Driver*) ut->data);
271
  chprintf(stream, "expected device ID (LS SPI): 0xDECA0130 \n");
272
  aosThdMSleep(5);
273
  actual_deviceId = instancereaddeviceid();
274
  chprintf(stream, "actual read ID: 0x%x\n", actual_deviceId);
275
  aosThdMSleep(5);
276

  
277
  //if the read of device ID fails, the DW1000 could be asleep
278
  if(DWT_DEVICE_ID != actual_deviceId){
279

  
280
    clear_SPI_chip_select();
281
    aosThdMSleep(1);
282
    set_SPI_chip_select();
283
    aosThdMSleep(7);
284
    actual_deviceId = instancereaddeviceid() ;
285

  
286
    if(DWT_DEVICE_ID != actual_deviceId){
287
      chprintf(stream, "SPI is not working or Unsupported Device ID\n");
288
      chprintf(stream, "actual device ID is: 0x%x\n", actual_deviceId);
289
      chprintf(stream, "expected device ID: 0xDECA0130 \n");
290
      aosThdMSleep(5);
291
    }
292

  
293
    //clear the sleep bit - so that after the hard reset below the DW does not go into sleep
294
    dwt_softreset();
295
  }
296

  
297
  /*! UT1: Low speed SPI result */
298
  if (actual_deviceId == DWT_DEVICE_ID){
299
    aosUtPassed(stream, &result);
300
  } else {
301
    aosUtFailed(stream, &result);
302
  }
303

  
304
  reset_DW1000();
305

  
306
  chprintf(stream, "initialise instance for DW1000 \n");
307
  aosThdSleep(1);
308

  
309
  int x_init = instance_init((DW1000Driver*) ut->data) ;
310

  
311
  if (0 != x_init){
312
    chprintf(stream, "init error with return value: %d \n", x_init);
313
    aosThdSleep(1);
314
  }
315
  else {
316
    chprintf(stream, "init success with return value: %d \n", x_init);
317
    aosThdSleep(1);
318
  }
319

  
320
  /*! UT2: Initialization  result*/
321
  if (x_init == 0){
322
    aosUtPassed(stream, &result);
323
  } else {
324
    aosUtFailed(stream, &result);
325
  }
326

  
327
  setHighSpeed_SPI(true, (DW1000Driver*) ut->data);
328

  
329
  chprintf(stream, "expected device ID (HS SPI): 0xDECA0130\n");
330
  actual_deviceId = instancereaddeviceid();
331
  chprintf(stream, "actual read ID: 0x%x\n", actual_deviceId);
332
  aosThdMSleep(1);
333

  
334
  /*! UT3: High speed SPI result*/
335
  if (actual_deviceId == DWT_DEVICE_ID){
336
    aosUtPassed(stream, &result);
337
  } else {
338
    aosUtFailed(stream, &result);
339
  }
340

  
341
  port_EnableEXT_IRQ();
342
  reset_DW1000();
343

  
344
  chprintf(stream, "initialise the configuration for UWB application \n");
345
  aosThdSleep(1);
346

  
347
  int uwb_init = UWB_Init((DW1000Driver*) ut->data);
348

  
349
  if (0 != uwb_init){
350
    chprintf(stream, "UWB config error with return value: %d \n", uwb_init);
351
    aosThdSleep(1);
352
  }
353
  else {
354
    chprintf(stream, "UWB config success with return value: %d \n", uwb_init);
355
    aosThdSleep(1);
356
  }
357

  
358
  /*! UT4: UWB configuration result
359
   * If all the four unit tests are passed, the module is ready to run.
360
   * Note that the interrupt IRQn should be tested separately.
361
   */
362
  if (uwb_init == 0){
363
    aosUtPassed(stream, &result);
364
  } else {
365
    aosUtFailed(stream, &result);
366
  }
367

  
368
  /************** End of UNIT_TEST_SNIPPETS_DW1000*****************/
369

  
370
#else /* defined(UNIT_TEST_SNIPPETS_DW1000) */
371

  
372

  
373
  /*! RUN THE STATE MACHINE DEMO APP (RTLS) */
374

  
375
  chprintf(stream, "initialise the State Machine \n");
376
  aosThdSleep(2);
377

  
378
  /* Initialize UWB system with user defined configuration  */
379
  int uwb_init = UWB_Init((DW1000Driver*) ut->data);
380

  
381
  if (0 != uwb_init){
382
    chprintf(stream, "error in UWB config with return value: %d \n", uwb_init);
383
  }
384
  else {
385
    chprintf(stream, "succeed the init of UWB config \n");
386
  }
387
  aosThdSleep(1);
388

  
389
  chprintf(stream, "running the RTLS demo application ... \n");
390
  aosThdSleep(1);
391

  
392
  /*! Run the localization system demo app as a thread */
393
  while(1){
394
    instance_run();
395
//    aosThdUSleep(10);
396
  }
397

  
398
#endif  /* defined(UNIT_TEST_SNIPPETS_DW1000) */
399

  
400
  return result;
401
}
402

  
403

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

Also available in: Unified diff