Statistics
| Branch: | Tag: | Revision:

amiro-lld / source / DW1000 / v1 / alld_dw1000_v1.c @ 69a601a5

History | View | Annotate | Download (151.183 KB)

1
/*
2
AMiRo-LLD is a compilation of low-level hardware drivers for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  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 Lesser 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 Lesser General Public License for more details.
14

15
You should have received a copy of the GNU Lesser General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

    
19
/*! ------------------------------------------------------------------------------------------------------------------
20
 * @file    deca_device.c
21
 * @brief   Decawave device configuration and control functions
22
 *
23
 * @attention
24
 *
25
 * Copyright 2013 (c) Decawave Ltd, Dublin, Ireland.
26
 *
27
 * All rights reserved.
28
 *
29
 */
30

    
31

    
32
#include <alld_DW1000.h>
33

    
34
#if (defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)) || defined(__DOXYGEN__)
35

    
36
#include <aos_thread.h>
37
#include <assert.h>
38
#include <string.h>
39
#include <stdlib.h>
40
#include <math.h>
41

    
42

    
43
// Defines for enable_clocks function
44
#define FORCE_SYS_XTI  0
45
#define ENABLE_ALL_SEQ 1
46
#define FORCE_SYS_PLL  2
47
#define READ_ACC_ON    7
48
#define READ_ACC_OFF   8
49
#define FORCE_OTP_ON   11
50
#define FORCE_OTP_OFF  12
51
#define FORCE_TX_PLL   13
52
#define FORCE_LDE      14
53

    
54
// Defines for ACK request bitmask in DATA and MAC COMMAND frame control (first byte) - Used to detect AAT bit wrongly set.
55
#define FCTRL_ACK_REQ_MASK 0x20
56
// Frame control maximum length in bytes.
57
#define FCTRL_LEN_MAX 2
58

    
59

    
60
/**
61
 * Move to the header file <alld_dw1000_v1.h>
62
*/
63
//#define NUM_BR 3
64
//#define NUM_PRF 2
65
//#define NUM_PACS 4
66
//#define NUM_BW 2            //2 bandwidths are supported
67
//#define NUM_SFD 2           //supported number of SFDs - standard = 0, non-standard = 1
68
//#define NUM_CH 6            //supported channels are 1, 2, 3, 4, 5, 7
69
//#define NUM_CH_SUPPORTED 8  //supported channels are '0', 1, 2, 3, 4, 5, '6', 7
70
//#define PCODES 25           //supported preamble codes
71

    
72

    
73
typedef struct {
74
    uint32_t lo32;
75
    uint16_t target[NUM_PRF];
76
} agc_cfg_struct ;
77

    
78
extern const agc_cfg_struct agc_config ;
79

    
80
//SFD threshold settings for 110k, 850k, 6.8Mb standard and non-standard
81
extern const uint16_t sftsh[NUM_BR][NUM_SFD];
82

    
83
extern const uint16_t dtune1[NUM_PRF];
84

    
85
#define XMLPARAMS_VERSION   (1.17f)
86

    
87
extern const uint32_t fs_pll_cfg[NUM_CH];
88
extern const uint8_t fs_pll_tune[NUM_CH];
89
extern const uint8_t rx_config[NUM_BW];
90
extern const uint32_t tx_config[NUM_CH];
91
extern const uint8_t dwnsSFDlen[NUM_BR]; //length of SFD for each of the bitrates
92
extern const uint32_t digital_bb_config[NUM_PRF][NUM_PACS];
93
//extern const uint8_t chan_idx[NUM_CH_SUPPORTED]; // move to header file
94
extern const double txpwr_compensation[NUM_CH];
95

    
96
#define PEAK_MULTPLIER  (0x60) //3 -> (0x3 * 32) & 0x00E0
97
#define N_STD_FACTOR    (13)
98
#define LDE_PARAM1      (PEAK_MULTPLIER | N_STD_FACTOR)
99

    
100
#define LDE_PARAM3_16 (0x1607)
101
#define LDE_PARAM3_64 (0x0607)
102

    
103
#define MIXER_GAIN_STEP (0.5)
104
#define DA_ATTN_STEP    (2.5)
105

    
106
// #define DWT_API_ERROR_CHECK     // define so API checks config input parameters
107

    
108
//-----------------------------------------
109
// map the channel number to the index in the configuration arrays below
110
// 0th element is chan 1, 1st is chan 2, 2nd is chan 3, 3rd is chan 4, 4th is chan 5, 5th is chan 7
111
const uint8_t chan_idx[NUM_CH_SUPPORTED] = {0, 0, 1, 2, 3, 4, 0, 5};
112

    
113
//-----------------------------------------
114
const uint32_t tx_config[NUM_CH] =
115
{
116
    RF_TXCTRL_CH1,
117
    RF_TXCTRL_CH2,
118
    RF_TXCTRL_CH3,
119
    RF_TXCTRL_CH4,
120
    RF_TXCTRL_CH5,
121
    RF_TXCTRL_CH7,
122
};
123

    
124
//Frequency Synthesiser - PLL configuration
125
const uint32_t fs_pll_cfg[NUM_CH] =
126
{
127
    FS_PLLCFG_CH1,
128
    FS_PLLCFG_CH2,
129
    FS_PLLCFG_CH3,
130
    FS_PLLCFG_CH4,
131
    FS_PLLCFG_CH5,
132
    FS_PLLCFG_CH7
133
};
134

    
135
//Frequency Synthesiser - PLL tuning
136
const uint8_t fs_pll_tune[NUM_CH] =
137
{
138
    FS_PLLTUNE_CH1,
139
    FS_PLLTUNE_CH2,
140
    FS_PLLTUNE_CH3,
141
    FS_PLLTUNE_CH4,
142
    FS_PLLTUNE_CH5,
143
    FS_PLLTUNE_CH7
144
};
145

    
146
//bandwidth configuration
147
const uint8_t rx_config[NUM_BW] =
148
{
149
    RF_RXCTRLH_NBW,
150
    RF_RXCTRLH_WBW
151
};
152

    
153

    
154
const agc_cfg_struct agc_config =
155
{
156
    AGC_TUNE2_VAL,
157
    { AGC_TUNE1_16M , AGC_TUNE1_64M }  //adc target
158
};
159

    
160
//DW non-standard SFD length for 110k, 850k and 6.81M
161
const uint8_t dwnsSFDlen[NUM_BR] =
162
{
163
    DW_NS_SFD_LEN_110K,
164
    DW_NS_SFD_LEN_850K,
165
    DW_NS_SFD_LEN_6M8
166
};
167

    
168
// SFD Threshold
169
const uint16_t sftsh[NUM_BR][NUM_SFD] =
170
{
171
    {
172
        DRX_TUNE0b_110K_STD,
173
        DRX_TUNE0b_110K_NSTD
174
    },
175
    {
176
        DRX_TUNE0b_850K_STD,
177
        DRX_TUNE0b_850K_NSTD
178
    },
179
    {
180
        DRX_TUNE0b_6M8_STD,
181
        DRX_TUNE0b_6M8_NSTD
182
    }
183
};
184

    
185
const uint16_t dtune1[NUM_PRF] =
186
{
187
    DRX_TUNE1a_PRF16,
188
    DRX_TUNE1a_PRF64
189
};
190

    
191
const uint32_t digital_bb_config[NUM_PRF][NUM_PACS] =
192
{
193
    {
194
        DRX_TUNE2_PRF16_PAC8,
195
        DRX_TUNE2_PRF16_PAC16,
196
        DRX_TUNE2_PRF16_PAC32,
197
        DRX_TUNE2_PRF16_PAC64
198
    },
199
    {
200
        DRX_TUNE2_PRF64_PAC8,
201
        DRX_TUNE2_PRF64_PAC16,
202
        DRX_TUNE2_PRF64_PAC32,
203
        DRX_TUNE2_PRF64_PAC64
204
    }
205
};
206

    
207
const uint16_t lde_replicaCoeff[PCODES] =
208
{
209
    0, // No preamble code 0
210
    LDE_REPC_PCODE_1,
211
    LDE_REPC_PCODE_2,
212
    LDE_REPC_PCODE_3,
213
    LDE_REPC_PCODE_4,
214
    LDE_REPC_PCODE_5,
215
    LDE_REPC_PCODE_6,
216
    LDE_REPC_PCODE_7,
217
    LDE_REPC_PCODE_8,
218
    LDE_REPC_PCODE_9,
219
    LDE_REPC_PCODE_10,
220
    LDE_REPC_PCODE_11,
221
    LDE_REPC_PCODE_12,
222
    LDE_REPC_PCODE_13,
223
    LDE_REPC_PCODE_14,
224
    LDE_REPC_PCODE_15,
225
    LDE_REPC_PCODE_16,
226
    LDE_REPC_PCODE_17,
227
    LDE_REPC_PCODE_18,
228
    LDE_REPC_PCODE_19,
229
    LDE_REPC_PCODE_20,
230
    LDE_REPC_PCODE_21,
231
    LDE_REPC_PCODE_22,
232
    LDE_REPC_PCODE_23,
233
    LDE_REPC_PCODE_24
234
};
235

    
236
const double txpwr_compensation[NUM_CH] = {
237
    0.0,
238
    0.035,
239
    0.0,
240
    0.0,
241
    0.065,
242
    0.0
243
};
244

    
245

    
246
#define NUM_16M_OFFSET  (37)
247
#define NUM_16M_OFFSETWB  (68)
248
#define NUM_64M_OFFSET  (26)
249
#define NUM_64M_OFFSETWB  (59)
250

    
251
const uint8_t chan_idxnb[NUM_CH_SUPPORTED] = {0, 0, 1, 2, 0, 3, 0, 0}; //only channels 1,2,3 and 5 are in the narrow band tables
252
const uint8_t chan_idxwb[NUM_CH_SUPPORTED] = {0, 0, 0, 0, 0, 0, 0, 1}; //only channels 4 and 7 are in in the wide band tables
253

    
254
//---------------------------------------------------------------------------------------------------------------------------
255
// Range Bias Correction TABLES of range values in integer units of 25 CM, for 8-bit unsigned storage, MUST END IN 255 !!!!!!
256
//---------------------------------------------------------------------------------------------------------------------------
257

    
258
// offsets to nearest centimeter for index 0, all rest are +1 cm per value
259

    
260
#define CM_OFFSET_16M_NB    (-23)   // for normal band channels at 16 MHz PRF
261
#define CM_OFFSET_16M_WB    (-28)   // for wider  band channels at 16 MHz PRF
262
#define CM_OFFSET_64M_NB    (-17)   // for normal band channels at 64 MHz PRF
263
#define CM_OFFSET_64M_WB    (-30)   // for wider  band channels at 64 MHz PRF
264

    
265

    
266
//---------------------------------------------------------------------------------------------------------------------------
267
// range25cm16PRFnb: Range Bias Correction table for narrow band channels at 16 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
268
//---------------------------------------------------------------------------------------------------------------------------
269

    
270
const uint8_t range25cm16PRFnb[4][NUM_16M_OFFSET] =
271
{
272
    // ch 1 - range25cm16PRFnb
273
    {
274
           1,
275
           3,
276
           4,
277
           5,
278
           7,
279
           9,
280
          11,
281
          12,
282
          13,
283
          15,
284
          18,
285
          20,
286
          23,
287
          25,
288
          28,
289
          30,
290
          33,
291
          36,
292
          40,
293
          43,
294
          47,
295
          50,
296
          54,
297
          58,
298
          63,
299
          66,
300
          71,
301
          76,
302
          82,
303
          89,
304
          98,
305
         109,
306
         127,
307
         155,
308
         222,
309
         255,
310
         255
311
    },
312

    
313
    // ch 2 - range25cm16PRFnb
314
    {
315
           1,
316
           2,
317
           4,
318
           5,
319
           6,
320
           8,
321
           9,
322
          10,
323
          12,
324
          13,
325
          15,
326
          18,
327
          20,
328
          22,
329
          24,
330
          27,
331
          29,
332
          32,
333
          35,
334
          38,
335
          41,
336
          44,
337
          47,
338
          51,
339
          55,
340
          58,
341
          62,
342
          66,
343
          71,
344
          78,
345
          85,
346
          96,
347
         111,
348
         135,
349
         194,
350
         240,
351
         255
352
    },
353

    
354
    // ch 3 - range25cm16PRFnb
355
    {
356
           1,
357
           2,
358
           3,
359
           4,
360
           5,
361
           7,
362
           8,
363
           9,
364
          10,
365
          12,
366
          14,
367
          16,
368
          18,
369
          20,
370
          22,
371
          24,
372
          26,
373
          28,
374
          31,
375
          33,
376
          36,
377
          39,
378
          42,
379
          45,
380
          49,
381
          52,
382
          55,
383
          59,
384
          63,
385
          69,
386
          76,
387
          85,
388
          98,
389
         120,
390
         173,
391
         213,
392
         255
393
    },
394

    
395
    // ch 5 - range25cm16PRFnb
396
    {
397
           1,
398
           1,
399
           2,
400
           3,
401
           4,
402
           5,
403
           6,
404
           6,
405
           7,
406
           8,
407
           9,
408
          11,
409
          12,
410
          14,
411
          15,
412
          16,
413
          18,
414
          20,
415
          21,
416
          23,
417
          25,
418
          27,
419
          29,
420
          31,
421
          34,
422
          36,
423
          38,
424
          41,
425
          44,
426
          48,
427
          53,
428
          59,
429
          68,
430
          83,
431
         120,
432
         148,
433
         255
434
    }
435
}; // end range25cm16PRFnb
436

    
437

    
438
//---------------------------------------------------------------------------------------------------------------------------
439
// range25cm16PRFwb: Range Bias Correction table for wide band channels at 16 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
440
//---------------------------------------------------------------------------------------------------------------------------
441

    
442
const uint8_t range25cm16PRFwb[2][NUM_16M_OFFSETWB] =
443
{
444
    // ch 4 - range25cm16PRFwb
445
    {
446
           7,
447
           7,
448
           8,
449
           9,
450
           9,
451
          10,
452
          11,
453
          11,
454
          12,
455
          13,
456
          14,
457
          15,
458
          16,
459
          17,
460
          18,
461
          19,
462
          20,
463
          21,
464
          22,
465
          23,
466
          24,
467
          26,
468
          27,
469
          28,
470
          30,
471
          31,
472
          32,
473
          34,
474
          36,
475
          38,
476
          40,
477
          42,
478
          44,
479
          46,
480
          48,
481
          50,
482
          52,
483
          55,
484
          57,
485
          59,
486
          61,
487
          63,
488
          66,
489
          68,
490
          71,
491
          74,
492
          78,
493
          81,
494
          85,
495
          89,
496
          94,
497
          99,
498
         104,
499
         110,
500
         116,
501
         123,
502
         130,
503
         139,
504
         150,
505
         164,
506
         182,
507
         207,
508
         238,
509
         255,
510
         255,
511
         255,
512
         255,
513
         255
514
    },
515

    
516
    // ch 7 - range25cm16PRFwb
517
    {
518
           4,
519
           5,
520
           5,
521
           5,
522
           6,
523
           6,
524
           7,
525
           7,
526
           7,
527
           8,
528
           9,
529
           9,
530
          10,
531
          10,
532
          11,
533
          11,
534
          12,
535
          13,
536
          13,
537
          14,
538
          15,
539
          16,
540
          17,
541
          17,
542
          18,
543
          19,
544
          20,
545
          21,
546
          22,
547
          23,
548
          25,
549
          26,
550
          27,
551
          29,
552
          30,
553
          31,
554
          32,
555
          34,
556
          35,
557
          36,
558
          38,
559
          39,
560
          40,
561
          42,
562
          44,
563
          46,
564
          48,
565
          50,
566
          52,
567
          55,
568
          58,
569
          61,
570
          64,
571
          68,
572
          72,
573
          75,
574
          80,
575
          85,
576
          92,
577
         101,
578
         112,
579
         127,
580
         147,
581
         168,
582
         182,
583
         194,
584
         205,
585
         255
586
    }
587
}; // end range25cm16PRFwb
588

    
589
//---------------------------------------------------------------------------------------------------------------------------
590
// range25cm64PRFnb: Range Bias Correction table for narrow band channels at 64 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
591
//---------------------------------------------------------------------------------------------------------------------------
592

    
593
const uint8_t range25cm64PRFnb[4][NUM_64M_OFFSET] =
594
{
595
    // ch 1 - range25cm64PRFnb
596
    {
597
           1,
598
           2,
599
           2,
600
           3,
601
           4,
602
           5,
603
           7,
604
          10,
605
          13,
606
          16,
607
          19,
608
          22,
609
          24,
610
          27,
611
          30,
612
          32,
613
          35,
614
          38,
615
          43,
616
          48,
617
          56,
618
          78,
619
         101,
620
         120,
621
         157,
622
         255
623
    },
624

    
625
    // ch 2 - range25cm64PRFnb
626
    {
627
           1,
628
           2,
629
           2,
630
           3,
631
           4,
632
           4,
633
           6,
634
           9,
635
          12,
636
          14,
637
          17,
638
          19,
639
          21,
640
          24,
641
          26,
642
          28,
643
          31,
644
          33,
645
          37,
646
          42,
647
          49,
648
          68,
649
          89,
650
         105,
651
         138,
652
         255
653
    },
654

    
655
    // ch 3 - range25cm64PRFnb
656
    {
657
           1,
658
           1,
659
           2,
660
           3,
661
           3,
662
           4,
663
           5,
664
           8,
665
          10,
666
          13,
667
          15,
668
          17,
669
          19,
670
          21,
671
          23,
672
          25,
673
          27,
674
          30,
675
          33,
676
          37,
677
          44,
678
          60,
679
          79,
680
          93,
681
         122,
682
         255
683
    },
684

    
685
    // ch 5 - range25cm64PRFnb
686
    {
687
           1,
688
           1,
689
           1,
690
           2,
691
           2,
692
           3,
693
           4,
694
           6,
695
           7,
696
           9,
697
          10,
698
          12,
699
          13,
700
          15,
701
          16,
702
          17,
703
          19,
704
          21,
705
          23,
706
          26,
707
          30,
708
          42,
709
          55,
710
          65,
711
          85,
712
         255
713
    }
714
}; // end range25cm64PRFnb
715

    
716
//---------------------------------------------------------------------------------------------------------------------------
717
// range25cm64PRFwb: Range Bias Correction table for wide band channels at 64 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
718
//---------------------------------------------------------------------------------------------------------------------------
719

    
720
const uint8_t range25cm64PRFwb[2][NUM_64M_OFFSETWB] =
721
{
722
    // ch 4 - range25cm64PRFwb
723
    {
724
           7,
725
           8,
726
           8,
727
           9,
728
           9,
729
          10,
730
          11,
731
          12,
732
          13,
733
          13,
734
          14,
735
          15,
736
          16,
737
          16,
738
          17,
739
          18,
740
          19,
741
          19,
742
          20,
743
          21,
744
          22,
745
          24,
746
          25,
747
          27,
748
          28,
749
          29,
750
          30,
751
          32,
752
          33,
753
          34,
754
          35,
755
          37,
756
          39,
757
          41,
758
          43,
759
          45,
760
          48,
761
          50,
762
          53,
763
          56,
764
          60,
765
          64,
766
          68,
767
          74,
768
          81,
769
          89,
770
          98,
771
         109,
772
         122,
773
         136,
774
         146,
775
         154,
776
         162,
777
         178,
778
         220,
779
         249,
780
         255,
781
         255,
782
         255
783
    },
784

    
785
    // ch 7 - range25cm64PRFwb
786
    {
787
           4,
788
           5,
789
           5,
790
           5,
791
           6,
792
           6,
793
           7,
794
           7,
795
           8,
796
           8,
797
           9,
798
           9,
799
          10,
800
          10,
801
          10,
802
          11,
803
          11,
804
          12,
805
          13,
806
          13,
807
          14,
808
          15,
809
          16,
810
          16,
811
          17,
812
          18,
813
          19,
814
          19,
815
          20,
816
          21,
817
          22,
818
          23,
819
          24,
820
          25,
821
          26,
822
          28,
823
          29,
824
          31,
825
          33,
826
          35,
827
          37,
828
          39,
829
          42,
830
          46,
831
          50,
832
          54,
833
          60,
834
          67,
835
          75,
836
          83,
837
          90,
838
          95,
839
         100,
840
         110,
841
         135,
842
         153,
843
         172,
844
         192,
845
         255
846
    }
847
}; // end range25cm64PRFwb
848

    
849

    
850

    
851

    
852

    
853
/*! ------------------------------------------------------------------------------------------------------------------
854
 * Function: dwt_getrangebias()
855
 *
856
 * Description: This function is used to return the range bias correction need for TWR with DW1000 units.
857
 *
858
 * input parameters:        
859
 * @param chan  - specifies the operating channel (e.g. 1, 2, 3, 4, 5, 6 or 7) 
860
 * @param range - the calculated distance before correction
861
 * @param prf        - this is the PRF e.g. DWT_PRF_16M or DWT_PRF_64M
862
 *
863
 * output parameters
864
 *
865
 * returns correction needed in meters
866
 */
867
double dwt_getrangebias(uint8_t chan, float range, uint8_t prf)
868
{
869
    //first get the lookup index that corresponds to given range for a particular channel at 16M PRF
870
    int i = 0 ;
871
    int chanIdx ;
872
    int cmoffseti ;                                 // integer number of CM offset
873

    
874
    double mOffset ;                                // final offset result in metres
875

    
876
    // NB: note we may get some small negitive values e.g. up to -50 cm.
877

    
878
    int rangeint25cm = (int) (range * 4.00) ;       // convert range to integer number of 25cm values.
879

    
880
    if (rangeint25cm > 255) rangeint25cm = 255 ;    // make sure it matches largest value in table (all tables end in 255 !!!!)
881

    
882
    if (prf == DWT_PRF_16M)
883
    {
884
        switch(chan)
885
        {
886
            case 4:
887
            case 7:
888
            {
889
                chanIdx = chan_idxwb[chan];
890
                while (rangeint25cm > range25cm16PRFwb[chanIdx][i]) i++ ;       // find index in table corresponding to range
891
                cmoffseti = i + CM_OFFSET_16M_WB ;                              // nearest centimeter correction
892
            }
893
            break;
894
            default:
895
            {
896
                chanIdx = chan_idxnb[chan];
897
                while (rangeint25cm > range25cm16PRFnb[chanIdx][i]) i++ ;       // find index in table corresponding to range
898
                cmoffseti = i + CM_OFFSET_16M_NB ;                              // nearest centimeter correction
899
            }
900
        }//end of switch
901
    }
902
    else // 64M PRF
903
    {
904
        switch(chan)
905
        {
906
            case 4:
907
            case 7:
908
            {
909
                chanIdx = chan_idxwb[chan];
910
                while (rangeint25cm > range25cm64PRFwb[chanIdx][i]) i++ ;       // find index in table corresponding to range
911
                cmoffseti = i + CM_OFFSET_64M_WB ;                              // nearest centimeter correction
912
            }
913
            break;
914
            default:
915
            {
916
                chanIdx = chan_idxnb[chan];
917
                while (rangeint25cm > range25cm64PRFnb[chanIdx][i]) i++ ;       // find index in table corresponding to range
918
                cmoffseti = i + CM_OFFSET_64M_NB ;                              // nearest centimeter correction
919
            }
920
        }//end of switch
921
    } // end else
922

    
923

    
924
    mOffset = (float) cmoffseti ;                                       // offset result in centimmetres
925

    
926
    mOffset *= 0.01 ;                                                   // convert to metres
927

    
928
    return (mOffset) ;
929
}
930

    
931

    
932

    
933
// -------------------------------------------------------------------------------------------------------------------
934
//
935
// Internal functions for controlling and configuring the device
936
//
937
// -------------------------------------------------------------------------------------------------------------------
938

    
939
// Enable and Configure specified clocks
940
void _dwt_enableclocks(int clocks) ;
941
// Configure the ucode (FP algorithm) parameters
942
void _dwt_configlde(int prf);
943
// Load ucode from OTP/ROM
944
void _dwt_loaducodefromrom(void);
945
// Read non-volatile memory
946
uint32_t _dwt_otpread(uint32_t address);
947
// Program the non-volatile memory
948
uint32_t _dwt_otpprogword32(uint32_t data, uint16_t address);
949
// Upload the device configuration into always on memory
950
void _dwt_aonarrayupload(void);
951
// -------------------------------------------------------------------------------------------------------------------
952

    
953
/*!
954
 * Static data for DW1000 DecaWave Transceiver control
955
 */
956

    
957
static dwt_local_data_t dw1000local[DWT_NUM_DW_DEV] ; // Static local device data, can be an array to support multiple DW1000 testing applications/platforms
958
static dwt_local_data_t *pdw1000local = dw1000local ; // Static local data structure pointer
959

    
960

    
961
/*! ------------------------------------------------------------------------------------------------------------------
962
 * @fn dwt_setdevicedataptr()
963
 *
964
 * @brief This function sets the local data structure pointer to point to the structure in the local array as given by the index.
965
 *
966
 * input parameters
967
 * @param index    - selects the array object to point to. Must be within the array bounds, i.e. < DWT_NUM_DW_DEV
968
 *
969
 * output parameters
970
 *
971
 * returns DWT_SUCCESS for success, or DWT_ERROR for error
972
 */
973
int dwt_setdevicedataptr(unsigned int index)
974
{
975
    // Check the index is within the array bounds
976
    if (DWT_NUM_DW_DEV > index) // return error if index outside the array bounds
977
    {
978
        return DWT_ERROR ;
979
    }
980

    
981
    pdw1000local = &dw1000local[index];
982

    
983
    return DWT_SUCCESS ;
984
}
985

    
986
/*! ------------------------------------------------------------------------------------------------------------------
987
 * @fn dwt_initialise()
988
 *
989
 * @brief This function initiates communications with the DW1000 transceiver
990
 * and reads its DEV_ID register (address 0x00) to verify the IC is one supported
991
 * by this software (e.g. DW1000 32-bit device ID value is 0xDECA0130).  Then it
992
 * does any initial once only device configurations needed for use and initialises
993
 * as necessary any static data items belonging to this low-level driver.
994
 *
995
 * NOTES:
996
 * 1.this function needs to be run before dwt_configuresleep, also the SPI frequency has to be < 3MHz
997
 * 2.it also reads and applies LDO tune and crystal trim values from OTP memory
998
 *
999
 * input parameters
1000
 * @param config    -   specifies what configuration to load
1001
 *                  DWT_LOADUCODE     0x1 - load the LDE microcode from ROM - enabled accurate RX timestamp
1002
 *                  DWT_LOADNONE      0x0 - do not load any values from OTP memory
1003
 *
1004
 * output parameters
1005
 *
1006
 * returns DWT_SUCCESS for success, or DWT_ERROR for error
1007
 */
1008
// OTP addresses definitions
1009
#define LDOTUNE_ADDRESS (0x04)
1010
#define PARTID_ADDRESS (0x06)
1011
#define LOTID_ADDRESS  (0x07)
1012
#define VBAT_ADDRESS   (0x08)
1013
#define VTEMP_ADDRESS  (0x09)
1014
#define XTRIM_ADDRESS  (0x1E)
1015

    
1016
//int dwt_initialise(const uint16_t config, DW1000Driver* drv)
1017
int dwt_initialise(const uint16_t config)  // TODO:
1018
{
1019
    uint16_t otp_addr = 0;
1020
    uint32_t ldo_tune = 0;
1021

    
1022
    pdw1000local->dblbuffon = 0; // Double buffer mode off by default
1023
    pdw1000local->wait4resp = 0;
1024
    pdw1000local->sleep_mode = 0;
1025

    
1026
    pdw1000local->cbTxDone = NULL;
1027
    pdw1000local->cbRxOk = NULL;
1028
    pdw1000local->cbRxTo = NULL;
1029
    pdw1000local->cbRxErr = NULL;
1030

    
1031
//    pdw1000local->driver = drv;  // TODO:
1032

    
1033
    // Read and validate device ID return -1 if not recognised
1034
    if (DWT_DEVICE_ID != dwt_readdevid()) // MP IC ONLY (i.e. DW1000) FOR THIS CODE
1035
    {
1036
        return DWT_ERROR ;
1037
    }
1038

    
1039
    // Make sure the device is completely reset before starting initialisation
1040
    dwt_softreset();
1041

    
1042
    _dwt_enableclocks(FORCE_SYS_XTI); // NOTE: set system clock to XTI - this is necessary to make sure the values read by _dwt_otpread are reliable
1043

    
1044
    // Configure the CPLL lock detect
1045
    dwt_write8bitoffsetreg(EXT_SYNC_ID, EC_CTRL_OFFSET, EC_CTRL_PLLLCK);
1046

    
1047
    // Read OTP revision number
1048
    otp_addr = _dwt_otpread(XTRIM_ADDRESS) & 0xffff;        // Read 32 bit value, XTAL trim val is in low octet-0 (5 bits)
1049
    pdw1000local->otprev = (otp_addr >> 8) & 0xff;            // OTP revision is next byte
1050

    
1051
    // Load LDO tune from OTP and kick it if there is a value actually programmed.
1052
    ldo_tune = _dwt_otpread(LDOTUNE_ADDRESS);
1053
    if((ldo_tune & 0xFF) != 0)
1054
    {
1055
        // Kick LDO tune
1056
        dwt_write8bitoffsetreg(OTP_IF_ID, OTP_SF, OTP_SF_LDO_KICK); // Set load LDE kick bit
1057
        pdw1000local->sleep_mode |= AON_WCFG_ONW_LLDO; // LDO tune must be kicked at wake-up
1058
    }
1059

    
1060
    // Load Part and Lot ID from OTP
1061
    pdw1000local->partID = _dwt_otpread(PARTID_ADDRESS);
1062
    pdw1000local->lotID = _dwt_otpread(LOTID_ADDRESS);
1063

    
1064
    // XTAL trim value is set in OTP for DW1000 module and EVK/TREK boards but that might not be the case in a custom design
1065
    pdw1000local->init_xtrim = otp_addr & 0x1F;
1066
    if (!pdw1000local->init_xtrim) // A value of 0 means that the crystal has not been trimmed
1067
    {
1068
        pdw1000local->init_xtrim = FS_XTALT_MIDRANGE ; // Set to mid-range if no calibration value inside
1069
    }
1070
    // Configure XTAL trim
1071
    dwt_setxtaltrim(pdw1000local->init_xtrim);
1072

    
1073
    // Load leading edge detect code
1074
    if(config & DWT_LOADUCODE)
1075
    {
1076
        _dwt_loaducodefromrom();
1077
        pdw1000local->sleep_mode |= AON_WCFG_ONW_LLDE; // microcode must be loaded at wake-up
1078
    }
1079
    else // Should disable the LDERUN enable bit in 0x36, 0x4
1080
    {
1081
        uint16_t rega = dwt_read16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1) ;
1082
        rega &= 0xFDFF ; // Clear LDERUN bit
1083
        dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1, rega) ;
1084
    }
1085

    
1086
    _dwt_enableclocks(ENABLE_ALL_SEQ); // Enable clocks for sequencing
1087

    
1088
    // The 3 bits in AON CFG1 register must be cleared to ensure proper operation of the DW1000 in DEEPSLEEP mode.
1089
    dwt_write8bitoffsetreg(AON_ID, AON_CFG1_OFFSET, 0x00);
1090

    
1091
    // Read system register / store local copy
1092
    pdw1000local->sysCFGreg = dwt_read32bitreg(SYS_CFG_ID) ; // Read sysconfig register
1093

    
1094
    return DWT_SUCCESS ;
1095

    
1096
} // end dwt_initialise()
1097

    
1098
/*! ------------------------------------------------------------------------------------------------------------------
1099
 * @fn dwt_otprevision()
1100
 *
1101
 * @brief This is used to return the read OTP revision
1102
 *
1103
 * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
1104
 *
1105
 * input parameters
1106
 *
1107
 * output parameters
1108
 *
1109
 * returns the read OTP revision value
1110
 */
1111
uint8_t dwt_otprevision(void)
1112
{
1113
    return pdw1000local->otprev ;
1114
}
1115

    
1116
/*! ------------------------------------------------------------------------------------------------------------------
1117
 * @fn dwt_setfinegraintxseq()
1118
 *
1119
 * @brief This function enables/disables the fine grain TX sequencing (enabled by default).
1120
 *
1121
 * input parameters
1122
 * @param enable - 1 to enable fine grain TX sequencing, 0 to disable it.
1123
 *
1124
 * output parameters none
1125
 *
1126
 * no return value
1127
 */
1128
void dwt_setfinegraintxseq(int enable)
1129
{
1130
    if (enable)
1131
    {
1132
        dwt_write16bitoffsetreg(PMSC_ID, PMSC_TXFINESEQ_OFFSET, PMSC_TXFINESEQ_ENABLE);
1133
    }
1134
    else
1135
    {
1136
        dwt_write16bitoffsetreg(PMSC_ID, PMSC_TXFINESEQ_OFFSET, PMSC_TXFINESEQ_DISABLE);
1137
    }
1138
}
1139

    
1140
/*! ------------------------------------------------------------------------------------------------------------------
1141
 * @fn dwt_setlnapamode()
1142
 *
1143
 * @brief This is used to enable GPIO for external LNA or PA functionality - HW dependent, consult the DW1000 User Manual.
1144
 *        This can also be used for debug as enabling TX and RX GPIOs is quite handy to monitor DW1000's activity.
1145
 *
1146
 * NOTE: Enabling PA functionality requires that fine grain TX sequencing is deactivated. This can be done using
1147
 *       dwt_setfinegraintxseq().
1148
 *
1149
 * input parameters
1150
 * @param lna - 1 to enable LNA functionality, 0 to disable it
1151
 * @param pa - 1 to enable PA functionality, 0 to disable it
1152
 *
1153
 * output parameters
1154
 *
1155
 * no return value
1156
 */
1157
void dwt_setlnapamode(int lna, int pa)
1158
{
1159
    uint32_t gpio_mode = dwt_read32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET);
1160
    gpio_mode &= ~(GPIO_MSGP4_MASK | GPIO_MSGP5_MASK | GPIO_MSGP6_MASK);
1161
    if (lna)
1162
    {
1163
        gpio_mode |= GPIO_PIN6_EXTRXE;
1164
    }
1165
    if (pa)
1166
    {
1167
        gpio_mode |= (GPIO_PIN5_EXTTXE | GPIO_PIN4_EXTPA);
1168
    }
1169
    dwt_write32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET, gpio_mode);
1170
}
1171

    
1172
/*! ------------------------------------------------------------------------------------------------------------------
1173
 * @fn dwt_setgpiodirection()
1174
 *
1175
 * @brief This is used to set GPIO direction as an input (1) or output (0)
1176
 *
1177
 * input parameters
1178
 * @param gpioNum    -   this is the GPIO to configure - see GxM0... GxM8 in the deca_regs.h file
1179
 * @param direction  -   this sets the GPIO direction - see GxP0... GxP8 in the deca_regs.h file
1180
 *
1181
 * output parameters
1182
 *
1183
 * no return value
1184
 */
1185
void dwt_setgpiodirection(uint32_t gpioNum, uint32_t direction)
1186
{
1187
    uint8_t buf[GPIO_DIR_LEN];
1188
    uint32_t command = direction | gpioNum;
1189

    
1190
    buf[0] = command & 0xff;
1191
    buf[1] = (command >> 8) & 0xff;
1192
    buf[2] = (command >> 16) & 0xff;
1193

    
1194
    dwt_writetodevice(GPIO_CTRL_ID, GPIO_DIR_OFFSET, GPIO_DIR_LEN, buf);
1195
}
1196

    
1197
/*! ------------------------------------------------------------------------------------------------------------------
1198
 * @fn dwt_setgpiovalue()
1199
 *
1200
 * @brief This is used to set GPIO value as (1) or (0) only applies if the GPIO is configured as output
1201
 *
1202
 * input parameters
1203
 * @param gpioNum    -   this is the GPIO to configure - see GxM0... GxM8 in the deca_regs.h file
1204
 * @param value  -   this sets the GPIO value - see GDP0... GDP8 in the deca_regs.h file
1205
 *
1206
 * output parameters
1207
 *
1208
 * no return value
1209
 */
1210
void dwt_setgpiovalue(uint32_t gpioNum, uint32_t value)
1211
{
1212
    uint8_t buf[GPIO_DOUT_LEN];
1213
    uint32_t command = value | gpioNum;
1214

    
1215
    buf[0] = command & 0xff;
1216
    buf[1] = (command >> 8) & 0xff;
1217
    buf[2] = (command >> 16) & 0xff;
1218

    
1219
    dwt_writetodevice(GPIO_CTRL_ID, GPIO_DOUT_OFFSET, GPIO_DOUT_LEN, buf);
1220
}
1221

    
1222
/*! ------------------------------------------------------------------------------------------------------------------
1223
 * @fn dwt_getpartid()
1224
 *
1225
 * @brief This is used to return the read part ID of the device
1226
 *
1227
 * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
1228
 *
1229
 * input parameters
1230
 *
1231
 * output parameters
1232
 *
1233
 * returns the 32 bit part ID value as programmed in the factory
1234
 */
1235
uint32_t dwt_getpartid(void)
1236
{
1237
    return pdw1000local->partID;
1238
}
1239

    
1240
/*! ------------------------------------------------------------------------------------------------------------------
1241
 * @fn dwt_getlotid()
1242
 *
1243
 * @brief This is used to return the read lot ID of the device
1244
 *
1245
 * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
1246
 *
1247
 * input parameters
1248
 *
1249
 * output parameters
1250
 *
1251
 * returns the 32 bit lot ID value as programmed in the factory
1252
 */
1253
uint32_t dwt_getlotid(void)
1254
{
1255
    return pdw1000local->lotID;
1256
}
1257

    
1258
/*! ------------------------------------------------------------------------------------------------------------------
1259
 * @fn dwt_readdevid()
1260
 *
1261
 * @brief This is used to return the read device type and revision information of the DW1000 device (MP part is 0xDECA0130)
1262
 *
1263
 * input parameters
1264
 *
1265
 * output parameters
1266
 *
1267
 * returns the read value which for DW1000 is 0xDECA0130
1268
 */
1269
uint32_t dwt_readdevid(void)
1270
{
1271
    return dwt_read32bitoffsetreg(DEV_ID_ID,0);
1272
}
1273

    
1274
/*! ------------------------------------------------------------------------------------------------------------------
1275
 * @fn dwt_configuretxrf()
1276
 *
1277
 * @brief This function provides the API for the configuration of the TX spectrum
1278
 * including the power and pulse generator delay. The input is a pointer to the data structure
1279
 * of type dwt_txconfig_t that holds all the configurable items.
1280
 *
1281
 * input parameters
1282
 * @param config    -   pointer to the txrf configuration structure, which contains the tx rf config data
1283
 *
1284
 * output parameters
1285
 *
1286
 * no return value
1287
 */
1288
void dwt_configuretxrf(dwt_txconfig_t* config)
1289
{
1290

    
1291
    // Configure RF TX PG_DELAY
1292
    dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGDELAY_OFFSET, config->PGdly);
1293

    
1294
    // Configure TX power
1295
    dwt_write32bitreg(TX_POWER_ID, config->power);
1296

    
1297
}
1298

    
1299
/*! ------------------------------------------------------------------------------------------------------------------
1300
 * @fn dwt_configure()
1301
 *
1302
 * @brief This function provides the main API for the configuration of the
1303
 * DW1000 and this low-level driver.  The input is a pointer to the data structure
1304
 * of type dwt_config_t that holds all the configurable items.
1305
 * The dwt_config_t structure shows which ones are supported
1306
 *
1307
 * input parameters
1308
 * @param config    -   pointer to the configuration structure, which contains the device configuration data.
1309
 *
1310
 * output parameters
1311
 *
1312
 * no return value
1313
 */
1314
void dwt_configure(dwt_config_t *config)
1315
{
1316
    uint8_t nsSfd_result  = 0;
1317
    uint8_t useDWnsSFD = 0;
1318
    uint8_t chan = config->chan ;
1319
    uint32_t regval ;
1320
    uint16_t reg16 = lde_replicaCoeff[config->rxCode];
1321
    uint8_t prfIndex = config->prf - DWT_PRF_16M;
1322
    uint8_t bw = ((chan == 4) || (chan == 7)) ? 1 : 0 ; // Select wide or narrow band
1323

    
1324
#ifdef DWT_API_ERROR_CHECK
1325
    assert(config->dataRate <= DWT_BR_6M8);
1326
    assert(config->rxPAC <= DWT_PAC64);
1327
    assert((chan >= 1) && (chan <= 7) && (chan != 6));
1328
    assert(((config->prf == DWT_PRF_64M) && (config->txCode >= 9) && (config->txCode <= 24))
1329
           || ((config->prf == DWT_PRF_16M) && (config->txCode >= 1) && (config->txCode <= 8)));
1330
    assert(((config->prf == DWT_PRF_64M) && (config->rxCode >= 9) && (config->rxCode <= 24))
1331
           || ((config->prf == DWT_PRF_16M) && (config->rxCode >= 1) && (config->rxCode <= 8)));
1332
    assert((config->txPreambLength == DWT_PLEN_64) || (config->txPreambLength == DWT_PLEN_128) || (config->txPreambLength == DWT_PLEN_256)
1333
           || (config->txPreambLength == DWT_PLEN_512) || (config->txPreambLength == DWT_PLEN_1024) || (config->txPreambLength == DWT_PLEN_1536)
1334
           || (config->txPreambLength == DWT_PLEN_2048) || (config->txPreambLength == DWT_PLEN_4096));
1335
    assert((config->phrMode == DWT_PHRMODE_STD) || (config->phrMode == DWT_PHRMODE_EXT));
1336
#endif
1337

    
1338
    // For 110 kbps we need a special setup
1339
    if(DWT_BR_110K == config->dataRate)
1340
    {
1341
        pdw1000local->sysCFGreg |= SYS_CFG_RXM110K ;
1342
        reg16 >>= 3; // lde_replicaCoeff must be divided by 8
1343
    }
1344
    else
1345
    {
1346
        pdw1000local->sysCFGreg &= (~SYS_CFG_RXM110K) ;
1347
    }
1348

    
1349
    pdw1000local->longFrames = config->phrMode ;
1350

    
1351
    pdw1000local->sysCFGreg &= ~SYS_CFG_PHR_MODE_11;
1352
    pdw1000local->sysCFGreg |= (SYS_CFG_PHR_MODE_11 & (config->phrMode << SYS_CFG_PHR_MODE_SHFT));
1353

    
1354
    dwt_write32bitreg(SYS_CFG_ID,pdw1000local->sysCFGreg) ;
1355
    // Set the lde_replicaCoeff
1356
    dwt_write16bitoffsetreg(LDE_IF_ID, LDE_REPC_OFFSET, reg16) ;
1357

    
1358
    _dwt_configlde(prfIndex);
1359

    
1360
    // Configure PLL2/RF PLL block CFG/TUNE (for a given channel)
1361
    dwt_write32bitoffsetreg(FS_CTRL_ID, FS_PLLCFG_OFFSET, fs_pll_cfg[chan_idx[chan]]);
1362
    dwt_write8bitoffsetreg(FS_CTRL_ID, FS_PLLTUNE_OFFSET, fs_pll_tune[chan_idx[chan]]);
1363

    
1364
    // Configure RF RX blocks (for specified channel/bandwidth)
1365
    dwt_write8bitoffsetreg(RF_CONF_ID, RF_RXCTRLH_OFFSET, rx_config[bw]);
1366

    
1367
    // Configure RF TX blocks (for specified channel and PRF)
1368
    // Configure RF TX control
1369
    dwt_write32bitoffsetreg(RF_CONF_ID, RF_TXCTRL_OFFSET, tx_config[chan_idx[chan]]);
1370

    
1371
    // Configure the baseband parameters (for specified PRF, bit rate, PAC, and SFD settings)
1372
    // DTUNE0
1373
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE0b_OFFSET, sftsh[config->dataRate][config->nsSFD]);
1374

    
1375
    // DTUNE1
1376
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1a_OFFSET, dtune1[prfIndex]);
1377

    
1378
    if(config->dataRate == DWT_BR_110K)
1379
    {
1380
        dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_110K);
1381
    }
1382
    else
1383
    {
1384
        if(config->txPreambLength == DWT_PLEN_64)
1385
        {
1386
            dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_6M8_PRE64);
1387
            dwt_write8bitoffsetreg(DRX_CONF_ID, DRX_TUNE4H_OFFSET, DRX_TUNE4H_PRE64);
1388
        }
1389
        else
1390
        {
1391
            dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_850K_6M8);
1392
            dwt_write8bitoffsetreg(DRX_CONF_ID, DRX_TUNE4H_OFFSET, DRX_TUNE4H_PRE128PLUS);
1393
        }
1394
    }
1395

    
1396
    // DTUNE2
1397
    dwt_write32bitoffsetreg(DRX_CONF_ID, DRX_TUNE2_OFFSET, digital_bb_config[prfIndex][config->rxPAC]);
1398

    
1399
    // DTUNE3 (SFD timeout)
1400
    // Don't allow 0 - SFD timeout will always be enabled
1401
    if(config->sfdTO == 0)
1402
    {
1403
        config->sfdTO = DWT_SFDTOC_DEF;
1404
    }
1405
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_SFDTOC_OFFSET, config->sfdTO);
1406

    
1407
    // Configure AGC parameters
1408
    dwt_write32bitoffsetreg( AGC_CFG_STS_ID, 0xC, agc_config.lo32);
1409
    dwt_write16bitoffsetreg( AGC_CFG_STS_ID, 0x4, agc_config.target[prfIndex]);
1410

    
1411
    // Set (non-standard) user SFD for improved performance,
1412
    if(config->nsSFD)
1413
    {
1414
        // Write non standard (DW) SFD length
1415
        dwt_write8bitoffsetreg(USR_SFD_ID, 0x00, dwnsSFDlen[config->dataRate]);
1416
        nsSfd_result = 3 ;
1417
        useDWnsSFD = 1 ;
1418
    }
1419
    regval =  (CHAN_CTRL_TX_CHAN_MASK & (chan << CHAN_CTRL_TX_CHAN_SHIFT)) | // Transmit Channel
1420
              (CHAN_CTRL_RX_CHAN_MASK & (chan << CHAN_CTRL_RX_CHAN_SHIFT)) | // Receive Channel
1421
              (CHAN_CTRL_RXFPRF_MASK & (config->prf << CHAN_CTRL_RXFPRF_SHIFT)) | // RX PRF
1422
              ((CHAN_CTRL_TNSSFD|CHAN_CTRL_RNSSFD) & (nsSfd_result << CHAN_CTRL_TNSSFD_SHIFT)) | // nsSFD enable RX&TX
1423
              (CHAN_CTRL_DWSFD & (useDWnsSFD << CHAN_CTRL_DWSFD_SHIFT)) | // Use DW nsSFD
1424
              (CHAN_CTRL_TX_PCOD_MASK & (config->txCode << CHAN_CTRL_TX_PCOD_SHIFT)) | // TX Preamble Code
1425
              (CHAN_CTRL_RX_PCOD_MASK & (config->rxCode << CHAN_CTRL_RX_PCOD_SHIFT)) ; // RX Preamble Code
1426

    
1427
    dwt_write32bitreg(CHAN_CTRL_ID,regval) ;
1428

    
1429
    // Set up TX Preamble Size, PRF and Data Rate
1430
    pdw1000local->txFCTRL = ((config->txPreambLength | config->prf) << TX_FCTRL_TXPRF_SHFT) | (config->dataRate << TX_FCTRL_TXBR_SHFT);
1431
    dwt_write32bitreg(TX_FCTRL_ID, pdw1000local->txFCTRL);
1432

    
1433
    // The SFD transmit pattern is initialised by the DW1000 upon a user TX request, but (due to an IC issue) it is not done for an auto-ACK TX. The
1434
    // SYS_CTRL write below works around this issue, by simultaneously initiating and aborting a transmission, which correctly initialises the SFD
1435
    // after its configuration or reconfiguration.
1436
    // This issue is not documented at the time of writing this code. It should be in next release of DW1000 User Manual (v2.09, from July 2016).
1437
    dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, SYS_CTRL_TXSTRT | SYS_CTRL_TRXOFF); // Request TX start and TRX off at the same time
1438
} // end dwt_configure()
1439

    
1440
/*! ------------------------------------------------------------------------------------------------------------------
1441
 * @fn dwt_setrxantennadelay()
1442
 *
1443
 * @brief This API function writes the antenna delay (in time units) to RX registers
1444
 *
1445
 * input parameters:
1446
 * @param rxDelay - this is the total (RX) antenna delay value, which
1447
 *                          will be programmed into the RX register
1448
 *
1449
 * output parameters
1450
 *
1451
 * no return value
1452
 */
1453
void dwt_setrxantennadelay(uint16_t rxDelay)
1454
{
1455
    // Set the RX antenna delay for auto TX timestamp adjustment
1456
    dwt_write16bitoffsetreg(LDE_IF_ID, LDE_RXANTD_OFFSET, rxDelay);
1457
}
1458

    
1459
/*! ------------------------------------------------------------------------------------------------------------------
1460
 * @fn dwt_settxantennadelay()
1461
 *
1462
 * @brief This API function writes the antenna delay (in time units) to TX registers
1463
 *
1464
 * input parameters:
1465
 * @param txDelay - this is the total (TX) antenna delay value, which
1466
 *                          will be programmed into the TX delay register
1467
 *
1468
 * output parameters
1469
 *
1470
 * no return value
1471
 */
1472
void dwt_settxantennadelay(uint16_t txDelay)
1473
{
1474
    // Set the TX antenna delay for auto TX timestamp adjustment
1475
    dwt_write16bitoffsetreg(TX_ANTD_ID, TX_ANTD_OFFSET, txDelay);
1476
}
1477

    
1478
/*! ------------------------------------------------------------------------------------------------------------------
1479
 * @fn dwt_writetxdata()
1480
 *
1481
 * @brief This API function writes the supplied TX data into the DW1000's
1482
 * TX buffer.  The input parameters are the data length in bytes and a pointer
1483
 * to those data bytes.
1484
 *
1485
 * input parameters
1486
 * @param txFrameLength  - This is the total frame length, including the two byte CRC.
1487
 *                         Note: this is the length of TX message (including the 2 byte CRC) - max is 1023
1488
 *                         standard PHR mode allows up to 127 bytes
1489
 *                         if > 127 is programmed, DWT_PHRMODE_EXT needs to be set in the phrMode configuration
1490
 *                         see dwt_configure function
1491
 * @param txFrameBytes   - Pointer to the user’s buffer containing the data to send.
1492
 * @param txBufferOffset - This specifies an offset in the DW1000’s TX Buffer at which to start writing data.
1493
 *
1494
 * output parameters
1495
 *
1496
 * returns DWT_SUCCESS for success, or DWT_ERROR for error
1497
 */
1498
int dwt_writetxdata(uint16_t txFrameLength, uint8_t *txFrameBytes, uint16_t txBufferOffset)
1499
{
1500
#ifdef DWT_API_ERROR_CHECK
1501
    assert(txFrameLength >= 2);
1502
    assert((pdw1000local->longFrames && (txFrameLength <= 1023)) || (txFrameLength <= 127));
1503
    assert((txBufferOffset + txFrameLength) <= 1024);
1504
#endif
1505

    
1506
    if ((txBufferOffset + txFrameLength) <= 1024)
1507
    {
1508
        // Write the data to the IC TX buffer, (-2 bytes for auto generated CRC)
1509
        dwt_writetodevice( TX_BUFFER_ID, txBufferOffset, txFrameLength-2, txFrameBytes);
1510
        return DWT_SUCCESS;
1511
    }
1512
    else
1513
    {
1514
        return DWT_ERROR;
1515
    }
1516
} // end dwt_writetxdata()
1517

    
1518
/*! ------------------------------------------------------------------------------------------------------------------
1519
 * @fn dwt_writetxfctrl()
1520
 *
1521
 * @brief This API function configures the TX frame control register before the transmission of a frame
1522
 *
1523
 * input parameters:
1524
 * @param txFrameLength - this is the length of TX message (including the 2 byte CRC) - max is 1023
1525
 *                              NOTE: standard PHR mode allows up to 127 bytes
1526
 *                              if > 127 is programmed, DWT_PHRMODE_EXT needs to be set in the phrMode configuration
1527
 *                              see dwt_configure function
1528
 * @param txBufferOffset - the offset in the tx buffer to start writing the data
1529
 * @param ranging - 1 if this is a ranging frame, else 0
1530
 *
1531
 * output parameters
1532
 *
1533
 * no return value
1534
 */
1535
void dwt_writetxfctrl(uint16_t txFrameLength, uint16_t txBufferOffset, int ranging)
1536
{
1537

    
1538
#ifdef DWT_API_ERROR_CHECK
1539
    assert((pdw1000local->longFrames && (txFrameLength <= 1023)) || (txFrameLength <= 127));
1540
#endif
1541

    
1542
    // Write the frame length to the TX frame control register
1543
    // pdw1000local->txFCTRL has kept configured bit rate information
1544
    uint32_t reg32 = pdw1000local->txFCTRL | txFrameLength | (txBufferOffset << TX_FCTRL_TXBOFFS_SHFT) | (ranging << TX_FCTRL_TR_SHFT);
1545
    dwt_write32bitreg(TX_FCTRL_ID, reg32);
1546
} // end dwt_writetxfctrl()
1547

    
1548

    
1549
/*! ------------------------------------------------------------------------------------------------------------------
1550
 * @fn dwt_readrxdata()
1551
 *
1552
 * @brief This is used to read the data from the RX buffer, from an offset location give by offset parameter
1553
 *
1554
 * input parameters
1555
 * @param buffer - the buffer into which the data will be read
1556
 * @param length - the length of data to read (in bytes)
1557
 * @param rxBufferOffset - the offset in the rx buffer from which to read the data
1558
 *
1559
 * output parameters
1560
 *
1561
 * no return value
1562
 */
1563
void dwt_readrxdata(uint8_t *buffer, uint16_t length, uint16_t rxBufferOffset)
1564
{
1565
    dwt_readfromdevice(RX_BUFFER_ID,rxBufferOffset,length,buffer) ;
1566
}
1567

    
1568
/*! ------------------------------------------------------------------------------------------------------------------
1569
 * @fn dwt_readaccdata()
1570
 *
1571
 * @brief This is used to read the data from the Accumulator buffer, from an offset location give by offset parameter
1572
 *
1573
 * NOTE: Because of an internal memory access delay when reading the accumulator the first octet output is a dummy octet
1574
 *       that should be discarded. This is true no matter what sub-index the read begins at.
1575
 *
1576
 * input parameters
1577
 * @param buffer - the buffer into which the data will be read
1578
 * @param length - the length of data to read (in bytes)
1579
 * @param accOffset - the offset in the acc buffer from which to read the data
1580
 *
1581
 * output parameters
1582
 *
1583
 * no return value
1584
 */
1585
void dwt_readaccdata(uint8_t *buffer, uint16_t len, uint16_t accOffset)
1586
{
1587
    // Force on the ACC clocks if we are sequenced
1588
    _dwt_enableclocks(READ_ACC_ON);
1589

    
1590
    dwt_readfromdevice(ACC_MEM_ID,accOffset,len,buffer) ;
1591

    
1592
    _dwt_enableclocks(READ_ACC_OFF); // Revert clocks back
1593
}
1594

    
1595
/*! ------------------------------------------------------------------------------------------------------------------
1596
 * @fn dwt_readdiagnostics()
1597
 *
1598
 * @brief this function reads the RX signal quality diagnostic data
1599
 *
1600
 * input parameters
1601
 * @param diagnostics - diagnostic structure pointer, this will contain the diagnostic data read from the DW1000
1602
 *
1603
 * output parameters
1604
 *
1605
 * no return value
1606
 */
1607
void dwt_readdiagnostics(dwt_rxdiag_t *diagnostics)
1608
{
1609
    // Read the HW FP index
1610
    diagnostics->firstPath = dwt_read16bitoffsetreg(RX_TIME_ID, RX_TIME_FP_INDEX_OFFSET);
1611

    
1612
    // LDE diagnostic data
1613
    diagnostics->maxNoise = dwt_read16bitoffsetreg(LDE_IF_ID, LDE_THRESH_OFFSET);
1614

    
1615
    // Read all 8 bytes in one SPI transaction
1616
    dwt_readfromdevice(RX_FQUAL_ID, 0x0, 8, (uint8_t*)&diagnostics->stdNoise);
1617

    
1618
    diagnostics->firstPathAmp1 = dwt_read16bitoffsetreg(RX_TIME_ID, RX_TIME_FP_AMPL1_OFFSET);
1619

    
1620
    diagnostics->rxPreamCount = (dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXPACC_MASK) >> RX_FINFO_RXPACC_SHIFT  ;
1621
}
1622

    
1623
/*! ------------------------------------------------------------------------------------------------------------------
1624
 * @fn dwt_readtxtimestamp()
1625
 *
1626
 * @brief This is used to read the TX timestamp (adjusted with the programmed antenna delay)
1627
 *
1628
 * input parameters
1629
 * @param timestamp - a pointer to a 5-byte buffer which will store the read TX timestamp time
1630
 *
1631
 * output parameters - the timestamp buffer will contain the value after the function call
1632
 *
1633
 * no return value
1634
 */
1635
void dwt_readtxtimestamp(uint8_t * timestamp)
1636
{
1637
    dwt_readfromdevice(TX_TIME_ID, TX_TIME_TX_STAMP_OFFSET, TX_TIME_TX_STAMP_LEN, timestamp) ; // Read bytes directly into buffer
1638
}
1639

    
1640
/*! ------------------------------------------------------------------------------------------------------------------
1641
 * @fn dwt_readtxtimestamphi32()
1642
 *
1643
 * @brief This is used to read the high 32-bits of the TX timestamp (adjusted with the programmed antenna delay)
1644
 *
1645
 * input parameters
1646
 *
1647
 * output parameters
1648
 *
1649
 * returns high 32-bits of TX timestamp
1650
 */
1651
uint32_t dwt_readtxtimestamphi32(void)
1652
{
1653
    return dwt_read32bitoffsetreg(TX_TIME_ID, 1); // Offset is 1 to get the 4 upper bytes out of 5
1654
}
1655

    
1656
/*! ------------------------------------------------------------------------------------------------------------------
1657
 * @fn dwt_readtxtimestamplo32()
1658
 *
1659
 * @brief This is used to read the low 32-bits of the TX timestamp (adjusted with the programmed antenna delay)
1660
 *
1661
 * input parameters
1662
 *
1663
 * output parameters
1664
 *
1665
 * returns low 32-bits of TX timestamp
1666
 */
1667
uint32_t dwt_readtxtimestamplo32(void)
1668
{
1669
    return dwt_read32bitreg(TX_TIME_ID); // Read TX TIME as a 32-bit register to get the 4 lower bytes out of 5
1670
}
1671

    
1672
/*! ------------------------------------------------------------------------------------------------------------------
1673
 * @fn dwt_readrxtimestamp()
1674
 *
1675
 * @brief This is used to read the RX timestamp (adjusted time of arrival)
1676
 *
1677
 * input parameters
1678
 * @param timestamp - a pointer to a 5-byte buffer which will store the read RX timestamp time
1679
 *
1680
 * output parameters - the timestamp buffer will contain the value after the function call
1681
 *
1682
 * no return value
1683
 */
1684
void dwt_readrxtimestamp(uint8_t * timestamp)
1685
{
1686
    dwt_readfromdevice(RX_TIME_ID, RX_TIME_RX_STAMP_OFFSET, RX_TIME_RX_STAMP_LEN, timestamp) ; // Get the adjusted time of arrival
1687
}
1688

    
1689
/*! ------------------------------------------------------------------------------------------------------------------
1690
 * @fn dwt_readrxtimestamphi32()
1691
 *
1692
 * @brief This is used to read the high 32-bits of the RX timestamp (adjusted with the programmed antenna delay)
1693
 *
1694
 * input parameters
1695
 *
1696
 * output parameters
1697
 *
1698
 * returns high 32-bits of RX timestamp
1699
 */
1700
uint32_t dwt_readrxtimestamphi32(void)
1701
{
1702
    return dwt_read32bitoffsetreg(RX_TIME_ID, 1); // Offset is 1 to get the 4 upper bytes out of 5
1703
}
1704

    
1705
/*! ------------------------------------------------------------------------------------------------------------------
1706
 * @fn dwt_readrxtimestamplo32()
1707
 *
1708
 * @brief This is used to read the low 32-bits of the RX timestamp (adjusted with the programmed antenna delay)
1709
 *
1710
 * input parameters
1711
 *
1712
 * output parameters
1713
 *
1714
 * returns low 32-bits of RX timestamp
1715
 */
1716
uint32_t dwt_readrxtimestamplo32(void)
1717
{
1718
    return dwt_read32bitreg(RX_TIME_ID); // Read RX TIME as a 32-bit register to get the 4 lower bytes out of 5
1719
}
1720

    
1721
/*! ------------------------------------------------------------------------------------------------------------------
1722
 * @fn dwt_readsystimestamphi32()
1723
 *
1724
 * @brief This is used to read the high 32-bits of the system time
1725
 *
1726
 * input parameters
1727
 *
1728
 * output parameters
1729
 *
1730
 * returns high 32-bits of system time timestamp
1731
 */
1732
uint32_t dwt_readsystimestamphi32(void)
1733
{
1734
    return dwt_read32bitoffsetreg(SYS_TIME_ID, 1); // Offset is 1 to get the 4 upper bytes out of 5
1735
}
1736

    
1737
/*! ------------------------------------------------------------------------------------------------------------------
1738
 * @fn dwt_readsystime()
1739
 *
1740
 * @brief This is used to read the system time
1741
 *
1742
 * input parameters
1743
 * @param timestamp - a pointer to a 5-byte buffer which will store the read system time
1744
 *
1745
 * output parameters
1746
 * @param timestamp - the timestamp buffer will contain the value after the function call
1747
 *
1748
 * no return value
1749
 */
1750
void dwt_readsystime(uint8_t * timestamp)
1751
{
1752
    dwt_readfromdevice(SYS_TIME_ID, SYS_TIME_OFFSET, SYS_TIME_LEN, timestamp) ;
1753
}
1754

    
1755
/*! ------------------------------------------------------------------------------------------------------------------
1756
 * @fn dwt_writetodevice()
1757
 *
1758
 * @brief  this function is used to write to the DW1000 device registers
1759
 * Notes:
1760
 *        1. Firstly we create a header (the first byte is a header byte)
1761
 *        a. check if sub index is used, if subindexing is used - set bit-6 to 1 to signify that the sub-index address follows the register index byte
1762
 *        b. set bit-7 (or with 0x80) for write operation
1763
 *        c. if extended sub address index is used (i.e. if index > 127) set bit-7 of the first sub-index byte following the first header byte
1764
 *
1765
 *        2. Write the header followed by the data bytes to the DW1000 device
1766
 *
1767
 *
1768
 * input parameters: