Statistics
| Branch: | Tag: | Revision:

amiro-lld / drivers / DW1000 / v1 / alld_DW1000.c @ 23ab29c0

History | View | Annotate | Download (150.876 KB)

1
/*
2
AMiRo-LLD is a compilation of low-level hardware drivers 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 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
#include <alld_DW1000.h>
32
#include <alld_DW1000_regs.h>
33
#include <assert.h>
34
#include <string.h>
35
#include <stdlib.h>
36
#include <math.h>
37

    
38

    
39
// HW dependent implementation (see bottom of file)
40
static int writetospi(uint16_t headerLength,
41
               const        uint8_t *headerBuffer,
42
               uint32_t bodyLength,
43
               const        uint8_t *bodyBuffer);
44

    
45
static int readfromspi(uint16_t headerLength,
46
                const uint8_t *headerBuffer,
47
                uint32_t readlength,
48
                uint8_t *readBuffer);
49

    
50

    
51
// Defines for enable_clocks function
52
#define FORCE_SYS_XTI  0
53
#define ENABLE_ALL_SEQ 1
54
#define FORCE_SYS_PLL  2
55
#define READ_ACC_ON    7
56
#define READ_ACC_OFF   8
57
#define FORCE_OTP_ON   11
58
#define FORCE_OTP_OFF  12
59
#define FORCE_TX_PLL   13
60
#define FORCE_LDE      14
61

    
62
// Defines for ACK request bitmask in DATA and MAC COMMAND frame control (first byte) - Used to detect AAT bit wrongly set.
63
#define FCTRL_ACK_REQ_MASK 0x20
64
// Frame control maximum length in bytes.
65
#define FCTRL_LEN_MAX 2
66

    
67

    
68
typedef struct {
69
    uint32_t lo32;
70
    uint16_t target[NUM_PRF];
71
} agc_cfg_struct ;
72

    
73
extern const agc_cfg_struct agc_config ;
74

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

    
78
extern const uint16_t dtune1[NUM_PRF];
79

    
80
#define XMLPARAMS_VERSION   (1.17f)
81

    
82
extern const uint32_t fs_pll_cfg[NUM_CH];
83
extern const uint8_t fs_pll_tune[NUM_CH];
84
extern const uint8_t rx_config[NUM_BW];
85
extern const uint32_t tx_config[NUM_CH];
86
extern const uint8_t dwnsSFDlen[NUM_BR]; //length of SFD for each of the bitrates
87
extern const uint32_t digital_bb_config[NUM_PRF][NUM_PACS];
88
//extern const uint8_t chan_idx[NUM_CH_SUPPORTED]; // move to header file
89
extern const double txpwr_compensation[NUM_CH];
90

    
91
#define PEAK_MULTPLIER  (0x60) //3 -> (0x3 * 32) & 0x00E0
92
#define N_STD_FACTOR    (13)
93
#define LDE_PARAM1      (PEAK_MULTPLIER | N_STD_FACTOR)
94

    
95
#define LDE_PARAM3_16 (0x1607)
96
#define LDE_PARAM3_64 (0x0607)
97

    
98
#define MIXER_GAIN_STEP (0.5)
99
#define DA_ATTN_STEP    (2.5)
100

    
101
// #define DWT_API_ERROR_CHECK     // define so API checks config input parameters
102

    
103
//-----------------------------------------
104
// map the channel number to the index in the configuration arrays below
105
// 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
106
const uint8_t chan_idx[NUM_CH_SUPPORTED] = {0, 0, 1, 2, 3, 4, 0, 5};
107

    
108
//-----------------------------------------
109
const uint32_t tx_config[NUM_CH] =
110
{
111
    RF_TXCTRL_CH1,
112
    RF_TXCTRL_CH2,
113
    RF_TXCTRL_CH3,
114
    RF_TXCTRL_CH4,
115
    RF_TXCTRL_CH5,
116
    RF_TXCTRL_CH7,
117
};
118

    
119
//Frequency Synthesiser - PLL configuration
120
const uint32_t fs_pll_cfg[NUM_CH] =
121
{
122
    FS_PLLCFG_CH1,
123
    FS_PLLCFG_CH2,
124
    FS_PLLCFG_CH3,
125
    FS_PLLCFG_CH4,
126
    FS_PLLCFG_CH5,
127
    FS_PLLCFG_CH7
128
};
129

    
130
//Frequency Synthesiser - PLL tuning
131
const uint8_t fs_pll_tune[NUM_CH] =
132
{
133
    FS_PLLTUNE_CH1,
134
    FS_PLLTUNE_CH2,
135
    FS_PLLTUNE_CH3,
136
    FS_PLLTUNE_CH4,
137
    FS_PLLTUNE_CH5,
138
    FS_PLLTUNE_CH7
139
};
140

    
141
//bandwidth configuration
142
const uint8_t rx_config[NUM_BW] =
143
{
144
    RF_RXCTRLH_NBW,
145
    RF_RXCTRLH_WBW
146
};
147

    
148

    
149
const agc_cfg_struct agc_config =
150
{
151
    AGC_TUNE2_VAL,
152
    { AGC_TUNE1_16M , AGC_TUNE1_64M }  //adc target
153
};
154

    
155
//DW non-standard SFD length for 110k, 850k and 6.81M
156
const uint8_t dwnsSFDlen[NUM_BR] =
157
{
158
    DW_NS_SFD_LEN_110K,
159
    DW_NS_SFD_LEN_850K,
160
    DW_NS_SFD_LEN_6M8
161
};
162

    
163
// SFD Threshold
164
const uint16_t sftsh[NUM_BR][NUM_SFD] =
165
{
166
    {
167
        DRX_TUNE0b_110K_STD,
168
        DRX_TUNE0b_110K_NSTD
169
    },
170
    {
171
        DRX_TUNE0b_850K_STD,
172
        DRX_TUNE0b_850K_NSTD
173
    },
174
    {
175
        DRX_TUNE0b_6M8_STD,
176
        DRX_TUNE0b_6M8_NSTD
177
    }
178
};
179

    
180
const uint16_t dtune1[NUM_PRF] =
181
{
182
    DRX_TUNE1a_PRF16,
183
    DRX_TUNE1a_PRF64
184
};
185

    
186
const uint32_t digital_bb_config[NUM_PRF][NUM_PACS] =
187
{
188
    {
189
        DRX_TUNE2_PRF16_PAC8,
190
        DRX_TUNE2_PRF16_PAC16,
191
        DRX_TUNE2_PRF16_PAC32,
192
        DRX_TUNE2_PRF16_PAC64
193
    },
194
    {
195
        DRX_TUNE2_PRF64_PAC8,
196
        DRX_TUNE2_PRF64_PAC16,
197
        DRX_TUNE2_PRF64_PAC32,
198
        DRX_TUNE2_PRF64_PAC64
199
    }
200
};
201

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

    
231
const double txpwr_compensation[NUM_CH] = {
232
    0.0,
233
    0.035,
234
    0.0,
235
    0.0,
236
    0.065,
237
    0.0
238
};
239

    
240

    
241
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
242
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
243

    
244
//---------------------------------------------------------------------------------------------------------------------------
245
// Range Bias Correction TABLES of range values in integer units of 25 CM, for 8-bit unsigned storage, MUST END IN 255 !!!!!!
246
//---------------------------------------------------------------------------------------------------------------------------
247

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

    
250
#define CM_OFFSET_16M_NB    (-23)   // for normal band channels at 16 MHz PRF
251
#define CM_OFFSET_16M_WB    (-28)   // for wider  band channels at 16 MHz PRF
252
#define CM_OFFSET_64M_NB    (-17)   // for normal band channels at 64 MHz PRF
253
#define CM_OFFSET_64M_WB    (-30)   // for wider  band channels at 64 MHz PRF
254

    
255

    
256
//---------------------------------------------------------------------------------------------------------------------------
257
// range25cm16PRFnb: Range Bias Correction table for narrow band channels at 16 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
258
//---------------------------------------------------------------------------------------------------------------------------
259

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

    
303
    // ch 2 - range25cm16PRFnb
304
    {
305
           1,
306
           2,
307
           4,
308
           5,
309
           6,
310
           8,
311
           9,
312
          10,
313
          12,
314
          13,
315
          15,
316
          18,
317
          20,
318
          22,
319
          24,
320
          27,
321
          29,
322
          32,
323
          35,
324
          38,
325
          41,
326
          44,
327
          47,
328
          51,
329
          55,
330
          58,
331
          62,
332
          66,
333
          71,
334
          78,
335
          85,
336
          96,
337
         111,
338
         135,
339
         194,
340
         240,
341
         255
342
    },
343

    
344
    // ch 3 - range25cm16PRFnb
345
    {
346
           1,
347
           2,
348
           3,
349
           4,
350
           5,
351
           7,
352
           8,
353
           9,
354
          10,
355
          12,
356
          14,
357
          16,
358
          18,
359
          20,
360
          22,
361
          24,
362
          26,
363
          28,
364
          31,
365
          33,
366
          36,
367
          39,
368
          42,
369
          45,
370
          49,
371
          52,
372
          55,
373
          59,
374
          63,
375
          69,
376
          76,
377
          85,
378
          98,
379
         120,
380
         173,
381
         213,
382
         255
383
    },
384

    
385
    // ch 5 - range25cm16PRFnb
386
    {
387
           1,
388
           1,
389
           2,
390
           3,
391
           4,
392
           5,
393
           6,
394
           6,
395
           7,
396
           8,
397
           9,
398
          11,
399
          12,
400
          14,
401
          15,
402
          16,
403
          18,
404
          20,
405
          21,
406
          23,
407
          25,
408
          27,
409
          29,
410
          31,
411
          34,
412
          36,
413
          38,
414
          41,
415
          44,
416
          48,
417
          53,
418
          59,
419
          68,
420
          83,
421
         120,
422
         148,
423
         255
424
    }
425
}; // end range25cm16PRFnb
426

    
427

    
428
//---------------------------------------------------------------------------------------------------------------------------
429
// range25cm16PRFwb: Range Bias Correction table for wide band channels at 16 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
430
//---------------------------------------------------------------------------------------------------------------------------
431

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

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

    
579
//---------------------------------------------------------------------------------------------------------------------------
580
// range25cm64PRFnb: Range Bias Correction table for narrow band channels at 64 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
581
//---------------------------------------------------------------------------------------------------------------------------
582

    
583
const uint8_t range25cm64PRFnb[4][NUM_64M_OFFSET] =
584
{
585
    // ch 1 - range25cm64PRFnb
586
    {
587
           1,
588
           2,
589
           2,
590
           3,
591
           4,
592
           5,
593
           7,
594
          10,
595
          13,
596
          16,
597
          19,
598
          22,
599
          24,
600
          27,
601
          30,
602
          32,
603
          35,
604
          38,
605
          43,
606
          48,
607
          56,
608
          78,
609
         101,
610
         120,
611
         157,
612
         255
613
    },
614

    
615
    // ch 2 - range25cm64PRFnb
616
    {
617
           1,
618
           2,
619
           2,
620
           3,
621
           4,
622
           4,
623
           6,
624
           9,
625
          12,
626
          14,
627
          17,
628
          19,
629
          21,
630
          24,
631
          26,
632
          28,
633
          31,
634
          33,
635
          37,
636
          42,
637
          49,
638
          68,
639
          89,
640
         105,
641
         138,
642
         255
643
    },
644

    
645
    // ch 3 - range25cm64PRFnb
646
    {
647
           1,
648
           1,
649
           2,
650
           3,
651
           3,
652
           4,
653
           5,
654
           8,
655
          10,
656
          13,
657
          15,
658
          17,
659
          19,
660
          21,
661
          23,
662
          25,
663
          27,
664
          30,
665
          33,
666
          37,
667
          44,
668
          60,
669
          79,
670
          93,
671
         122,
672
         255
673
    },
674

    
675
    // ch 5 - range25cm64PRFnb
676
    {
677
           1,
678
           1,
679
           1,
680
           2,
681
           2,
682
           3,
683
           4,
684
           6,
685
           7,
686
           9,
687
          10,
688
          12,
689
          13,
690
          15,
691
          16,
692
          17,
693
          19,
694
          21,
695
          23,
696
          26,
697
          30,
698
          42,
699
          55,
700
          65,
701
          85,
702
         255
703
    }
704
}; // end range25cm64PRFnb
705

    
706
//---------------------------------------------------------------------------------------------------------------------------
707
// range25cm64PRFwb: Range Bias Correction table for wide band channels at 64 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
708
//---------------------------------------------------------------------------------------------------------------------------
709

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

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

    
839

    
840
/*! ------------------------------------------------------------------------------------------------------------------
841
 * Function: dwt_getrangebias()
842
 *
843
 * Description: This function is used to return the range bias correction need for TWR with DW1000 units.
844
 *
845
 * input parameters:        
846
 * @param chan  - specifies the operating channel (e.g. 1, 2, 3, 4, 5, 6 or 7) 
847
 * @param range - the calculated distance before correction
848
 * @param prf        - this is the PRF e.g. DWT_PRF_16M or DWT_PRF_64M
849
 *
850
 * output parameters
851
 *
852
 * returns correction needed in meters
853
 */
854
double dwt_getrangebias(uint8_t chan, float range, uint8_t prf)
855
{
856
    //first get the lookup index that corresponds to given range for a particular channel at 16M PRF
857
    int i = 0 ;
858
    int chanIdx ;
859
    int cmoffseti ;                                 // integer number of CM offset
860

    
861
    double mOffset ;                                // final offset result in metres
862

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

    
865
    int rangeint25cm = (int) ((double)range * 4.00) ;       // convert range to integer number of 25cm values.
866

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

    
869
    if (prf == DWT_PRF_16M)
870
    {
871
        switch(chan)
872
        {
873
            case 4:
874
            case 7:
875
            {
876
                chanIdx = chan_idxwb[chan];
877
                while (rangeint25cm > range25cm16PRFwb[chanIdx][i]) i++ ;       // find index in table corresponding to range
878
                cmoffseti = i + CM_OFFSET_16M_WB ;                              // nearest centimeter correction
879
            }
880
            break;
881
            default:
882
            {
883
                chanIdx = chan_idxnb[chan];
884
                while (rangeint25cm > range25cm16PRFnb[chanIdx][i]) i++ ;       // find index in table corresponding to range
885
                cmoffseti = i + CM_OFFSET_16M_NB ;                              // nearest centimeter correction
886
            }
887
        }//end of switch
888
    }
889
    else // 64M PRF
890
    {
891
        switch(chan)
892
        {
893
            case 4:
894
            case 7:
895
            {
896
                chanIdx = chan_idxwb[chan];
897
                while (rangeint25cm > range25cm64PRFwb[chanIdx][i]) i++ ;       // find index in table corresponding to range
898
                cmoffseti = i + CM_OFFSET_64M_WB ;                              // nearest centimeter correction
899
            }
900
            break;
901
            default:
902
            {
903
                chanIdx = chan_idxnb[chan];
904
                while (rangeint25cm > range25cm64PRFnb[chanIdx][i]) i++ ;       // find index in table corresponding to range
905
                cmoffseti = i + CM_OFFSET_64M_NB ;                              // nearest centimeter correction
906
            }
907
        }//end of switch
908
    } // end else
909

    
910

    
911
    mOffset = (double) cmoffseti ;                                       // offset result in centimmetres
912

    
913
    mOffset *= 0.01 ;                                                   // convert to metres
914

    
915
    return (mOffset) ;
916
}
917

    
918
// -------------------------------------------------------------------------------------------------------------------
919
//
920
// Internal functions for controlling and configuring the device
921
//
922
// -------------------------------------------------------------------------------------------------------------------
923

    
924
// Enable and Configure specified clocks
925
void _dwt_enableclocks(int clocks) ;
926
// Configure the ucode (FP algorithm) parameters
927
void _dwt_configlde(int prf);
928
// Load ucode from OTP/ROM
929
void _dwt_loaducodefromrom(void);
930
// Read non-volatile memory
931
uint32_t _dwt_otpread(uint32_t address);
932
// Program the non-volatile memory
933
int32_t _dwt_otpprogword32(uint32_t data, uint16_t address);
934
// Upload the device configuration into always on memory
935
void _dwt_aonarrayupload(void);
936
// -------------------------------------------------------------------------------------------------------------------
937

    
938
/*!
939
 * Static data for DW1000 DecaWave Transceiver control
940
 */
941

    
942
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
943
static dwt_local_data_t *pdw1000local = dw1000local ; // Static local data structure pointer
944

    
945

    
946
/*! ------------------------------------------------------------------------------------------------------------------
947
 * @fn dwt_setdevicedataptr()
948
 *
949
 * @brief This function sets the local data structure pointer to point to the structure in the local array as given by the index.
950
 *
951
 * input parameters
952
 * @param index    - selects the array object to point to. Must be within the array bounds, i.e. < DWT_NUM_DW_DEV
953
 *
954
 * output parameters
955
 *
956
 * returns DWT_SUCCESS for success, or DWT_ERROR for error
957
 */
958
int dwt_setdevicedataptr(unsigned int index)
959
{
960
    // Check the index is within the array bounds
961
    if (DWT_NUM_DW_DEV > index) // return error if index outside the array bounds
962
    {
963
        return DWT_ERROR ;
964
    }
965

    
966
    pdw1000local = &dw1000local[index];
967

    
968
    return DWT_SUCCESS ;
969
}
970

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

    
1001
int dwt_initialise(const uint16_t config, DW1000Driver* drv)
1002
{
1003
    uint16_t otp_addr = 0;
1004
    uint32_t ldo_tune = 0;
1005

    
1006
    pdw1000local->dblbuffon = 0; // Double buffer mode off by default
1007
    pdw1000local->wait4resp = 0;
1008
    pdw1000local->sleep_mode = 0;
1009

    
1010
    pdw1000local->cbTxDone = NULL;
1011
    pdw1000local->cbRxOk = NULL;
1012
    pdw1000local->cbRxTo = NULL;
1013
    pdw1000local->cbRxErr = NULL;
1014

    
1015
    pdw1000local->driver = drv;
1016

    
1017
    // Read and validate device ID return -1 if not recognised
1018
    if (DWT_DEVICE_ID != dwt_readdevid()) // MP IC ONLY (i.e. DW1000) FOR THIS CODE
1019
    {
1020
        return DWT_ERROR ;
1021
    }
1022

    
1023
    // Make sure the device is completely reset before starting initialisation
1024
    dwt_softreset();
1025

    
1026
    _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
1027

    
1028
    // Configure the CPLL lock detect
1029
    dwt_write8bitoffsetreg(EXT_SYNC_ID, EC_CTRL_OFFSET, EC_CTRL_PLLLCK);
1030

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

    
1035
    // Load LDO tune from OTP and kick it if there is a value actually programmed.
1036
    ldo_tune = _dwt_otpread(LDOTUNE_ADDRESS);
1037
    if((ldo_tune & 0xFF) != 0)
1038
    {
1039
        // Kick LDO tune
1040
        dwt_write8bitoffsetreg(OTP_IF_ID, OTP_SF, OTP_SF_LDO_KICK); // Set load LDE kick bit
1041
        pdw1000local->sleep_mode |= AON_WCFG_ONW_LLDO; // LDO tune must be kicked at wake-up
1042
    }
1043

    
1044
    // Load Part and Lot ID from OTP
1045
    pdw1000local->partID = _dwt_otpread(PARTID_ADDRESS);
1046
    pdw1000local->lotID = _dwt_otpread(LOTID_ADDRESS);
1047

    
1048
    // 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
1049
    pdw1000local->init_xtrim = otp_addr & 0x1F;
1050
    if (!pdw1000local->init_xtrim) // A value of 0 means that the crystal has not been trimmed
1051
    {
1052
        pdw1000local->init_xtrim = FS_XTALT_MIDRANGE ; // Set to mid-range if no calibration value inside
1053
    }
1054
    // Configure XTAL trim
1055
    dwt_setxtaltrim(pdw1000local->init_xtrim);
1056

    
1057
    // Load leading edge detect code
1058
    if(config & DWT_LOADUCODE)
1059
    {
1060
        _dwt_loaducodefromrom();
1061
        pdw1000local->sleep_mode |= AON_WCFG_ONW_LLDE; // microcode must be loaded at wake-up
1062
    }
1063
    else // Should disable the LDERUN enable bit in 0x36, 0x4
1064
    {
1065
        uint16_t rega = dwt_read16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1) ;
1066
        rega &= 0xFDFF ; // Clear LDERUN bit
1067
        dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1, rega) ;
1068
    }
1069

    
1070
    _dwt_enableclocks(ENABLE_ALL_SEQ); // Enable clocks for sequencing
1071

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

    
1075
    // Read system register / store local copy
1076
    pdw1000local->sysCFGreg = dwt_read32bitreg(SYS_CFG_ID) ; // Read sysconfig register
1077

    
1078
    return DWT_SUCCESS ;
1079

    
1080
} // end dwt_initialise()
1081

    
1082
/*! ------------------------------------------------------------------------------------------------------------------
1083
 * @fn dwt_otprevision()
1084
 *
1085
 * @brief This is used to return the read OTP revision
1086
 *
1087
 * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
1088
 *
1089
 * input parameters
1090
 *
1091
 * output parameters
1092
 *
1093
 * returns the read OTP revision value
1094
 */
1095
uint8_t dwt_otprevision(void)
1096
{
1097
    return pdw1000local->otprev ;
1098
}
1099

    
1100
/*! ------------------------------------------------------------------------------------------------------------------
1101
 * @fn dwt_setfinegraintxseq()
1102
 *
1103
 * @brief This function enables/disables the fine grain TX sequencing (enabled by default).
1104
 *
1105
 * input parameters
1106
 * @param enable - 1 to enable fine grain TX sequencing, 0 to disable it.
1107
 *
1108
 * output parameters none
1109
 *
1110
 * no return value
1111
 */
1112
void dwt_setfinegraintxseq(int enable)
1113
{
1114
    if (enable)
1115
    {
1116
        dwt_write16bitoffsetreg(PMSC_ID, PMSC_TXFINESEQ_OFFSET, PMSC_TXFINESEQ_ENABLE);
1117
    }
1118
    else
1119
    {
1120
        dwt_write16bitoffsetreg(PMSC_ID, PMSC_TXFINESEQ_OFFSET, PMSC_TXFINESEQ_DISABLE);
1121
    }
1122
}
1123

    
1124
/*! ------------------------------------------------------------------------------------------------------------------
1125
 * @fn dwt_setlnapamode()
1126
 *
1127
 * @brief This is used to enable GPIO for external LNA or PA functionality - HW dependent, consult the DW1000 User Manual.
1128
 *        This can also be used for debug as enabling TX and RX GPIOs is quite handy to monitor DW1000's activity.
1129
 *
1130
 * NOTE: Enabling PA functionality requires that fine grain TX sequencing is deactivated. This can be done using
1131
 *       dwt_setfinegraintxseq().
1132
 *
1133
 * input parameters
1134
 * @param lna - 1 to enable LNA functionality, 0 to disable it
1135
 * @param pa - 1 to enable PA functionality, 0 to disable it
1136
 *
1137
 * output parameters
1138
 *
1139
 * no return value
1140
 */
1141
void dwt_setlnapamode(int lna, int pa)
1142
{
1143
    uint32_t gpio_mode = dwt_read32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET);
1144
    gpio_mode &= ~(GPIO_MSGP4_MASK | GPIO_MSGP5_MASK | GPIO_MSGP6_MASK);
1145
    if (lna)
1146
    {
1147
        gpio_mode |= GPIO_PIN6_EXTRXE;
1148
    }
1149
    if (pa)
1150
    {
1151
        gpio_mode |= (GPIO_PIN5_EXTTXE | GPIO_PIN4_EXTPA);
1152
    }
1153
    dwt_write32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET, gpio_mode);
1154
}
1155

    
1156
/*! ------------------------------------------------------------------------------------------------------------------
1157
 * @fn dwt_setgpiodirection()
1158
 *
1159
 * @brief This is used to set GPIO direction as an input (1) or output (0)
1160
 *
1161
 * input parameters
1162
 * @param gpioNum    -   this is the GPIO to configure - see GxM0... GxM8 in the deca_regs.h file
1163
 * @param direction  -   this sets the GPIO direction - see GxP0... GxP8 in the deca_regs.h file
1164
 *
1165
 * output parameters
1166
 *
1167
 * no return value
1168
 */
1169
void dwt_setgpiodirection(uint32_t gpioNum, uint32_t direction)
1170
{
1171
    uint8_t buf[GPIO_DIR_LEN];
1172
    uint32_t command = direction | gpioNum;
1173

    
1174
    buf[0] = command & 0xff;
1175
    buf[1] = (command >> 8) & 0xff;
1176
    buf[2] = (command >> 16) & 0xff;
1177

    
1178
    dwt_writetodevice(GPIO_CTRL_ID, GPIO_DIR_OFFSET, GPIO_DIR_LEN, buf);
1179
}
1180

    
1181
/*! ------------------------------------------------------------------------------------------------------------------
1182
 * @fn dwt_setgpiovalue()
1183
 *
1184
 * @brief This is used to set GPIO value as (1) or (0) only applies if the GPIO is configured as output
1185
 *
1186
 * input parameters
1187
 * @param gpioNum    -   this is the GPIO to configure - see GxM0... GxM8 in the deca_regs.h file
1188
 * @param value  -   this sets the GPIO value - see GDP0... GDP8 in the deca_regs.h file
1189
 *
1190
 * output parameters
1191
 *
1192
 * no return value
1193
 */
1194
void dwt_setgpiovalue(uint32_t gpioNum, uint32_t value)
1195
{
1196
    uint8_t buf[GPIO_DOUT_LEN];
1197
    uint32_t command = value | gpioNum;
1198

    
1199
    buf[0] = command & 0xff;
1200
    buf[1] = (command >> 8) & 0xff;
1201
    buf[2] = (command >> 16) & 0xff;
1202

    
1203
    dwt_writetodevice(GPIO_CTRL_ID, GPIO_DOUT_OFFSET, GPIO_DOUT_LEN, buf);
1204
}
1205

    
1206
/*! ------------------------------------------------------------------------------------------------------------------
1207
 * @fn dwt_getpartid()
1208
 *
1209
 * @brief This is used to return the read part ID of the device
1210
 *
1211
 * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
1212
 *
1213
 * input parameters
1214
 *
1215
 * output parameters
1216
 *
1217
 * returns the 32 bit part ID value as programmed in the factory
1218
 */
1219
uint32_t dwt_getpartid(void)
1220
{
1221
    return pdw1000local->partID;
1222
}
1223

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

    
1242
/*! ------------------------------------------------------------------------------------------------------------------
1243
 * @fn dwt_readdevid()
1244
 *
1245
 * @brief This is used to return the read device type and revision information of the DW1000 device (MP part is 0xDECA0130)
1246
 *
1247
 * input parameters
1248
 *
1249
 * output parameters
1250
 *
1251
 * returns the read value which for DW1000 is 0xDECA0130
1252
 */
1253
uint32_t dwt_readdevid(void)
1254
{
1255
    return dwt_read32bitoffsetreg(DEV_ID_ID,0);
1256
}
1257

    
1258
/*! ------------------------------------------------------------------------------------------------------------------
1259
 * @fn dwt_configuretxrf()
1260
 *
1261
 * @brief This function provides the API for the configuration of the TX spectrum
1262
 * including the power and pulse generator delay. The input is a pointer to the data structure
1263
 * of type dwt_txconfig_t that holds all the configurable items.
1264
 *
1265
 * input parameters
1266
 * @param config    -   pointer to the txrf configuration structure, which contains the tx rf config data
1267
 *
1268
 * output parameters
1269
 *
1270
 * no return value
1271
 */
1272
void dwt_configuretxrf(dwt_txconfig_t* config)
1273
{
1274

    
1275
    // Configure RF TX PG_DELAY
1276
    dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGDELAY_OFFSET, config->PGdly);
1277

    
1278
    // Configure TX power
1279
    dwt_write32bitreg(TX_POWER_ID, config->power);
1280

    
1281
}
1282

    
1283
/*! ------------------------------------------------------------------------------------------------------------------
1284
 * @fn dwt_configure()
1285
 *
1286
 * @brief This function provides the main API for the configuration of the
1287
 * DW1000 and this low-level driver.  The input is a pointer to the data structure
1288
 * of type dwt_config_t that holds all the configurable items.
1289
 * The dwt_config_t structure shows which ones are supported
1290
 *
1291
 * input parameters
1292
 * @param config    -   pointer to the configuration structure, which contains the device configuration data.
1293
 *
1294
 * output parameters
1295
 *
1296
 * no return value
1297
 */
1298
void dwt_configure(dwt_config_t *config)
1299
{
1300
    uint8_t nsSfd_result  = 0;
1301
    uint8_t useDWnsSFD = 0;
1302
    uint8_t chan = config->chan ;
1303
    uint32_t regval ;
1304
    uint16_t reg16 = lde_replicaCoeff[config->rxCode];
1305
    uint8_t prfIndex = config->prf - DWT_PRF_16M;
1306
    uint8_t bw = ((chan == 4) || (chan == 7)) ? 1 : 0 ; // Select wide or narrow band
1307

    
1308
#ifdef DWT_API_ERROR_CHECK
1309
    assert(config->dataRate <= DWT_BR_6M8);
1310
    assert(config->rxPAC <= DWT_PAC64);
1311
    assert((chan >= 1) && (chan <= 7) && (chan != 6));
1312
    assert(((config->prf == DWT_PRF_64M) && (config->txCode >= 9) && (config->txCode <= 24))
1313
           || ((config->prf == DWT_PRF_16M) && (config->txCode >= 1) && (config->txCode <= 8)));
1314
    assert(((config->prf == DWT_PRF_64M) && (config->rxCode >= 9) && (config->rxCode <= 24))
1315
           || ((config->prf == DWT_PRF_16M) && (config->rxCode >= 1) && (config->rxCode <= 8)));
1316
    assert((config->txPreambLength == DWT_PLEN_64) || (config->txPreambLength == DWT_PLEN_128) || (config->txPreambLength == DWT_PLEN_256)
1317
           || (config->txPreambLength == DWT_PLEN_512) || (config->txPreambLength == DWT_PLEN_1024) || (config->txPreambLength == DWT_PLEN_1536)
1318
           || (config->txPreambLength == DWT_PLEN_2048) || (config->txPreambLength == DWT_PLEN_4096));
1319
    assert((config->phrMode == DWT_PHRMODE_STD) || (config->phrMode == DWT_PHRMODE_EXT));
1320
#endif
1321

    
1322
    // For 110 kbps we need a special setup
1323
    if(DWT_BR_110K == config->dataRate)
1324
    {
1325
        pdw1000local->sysCFGreg |= SYS_CFG_RXM110K ;
1326
        reg16 >>= 3; // lde_replicaCoeff must be divided by 8
1327
    }
1328
    else
1329
    {
1330
        pdw1000local->sysCFGreg &= (~SYS_CFG_RXM110K) ;
1331
    }
1332

    
1333
    pdw1000local->longFrames = config->phrMode ;
1334

    
1335
    pdw1000local->sysCFGreg &= ~SYS_CFG_PHR_MODE_11;
1336
    pdw1000local->sysCFGreg |= (SYS_CFG_PHR_MODE_11 & (uint32_t)(config->phrMode << SYS_CFG_PHR_MODE_SHFT));
1337

    
1338
    dwt_write32bitreg(SYS_CFG_ID,pdw1000local->sysCFGreg) ;
1339
    // Set the lde_replicaCoeff
1340
    dwt_write16bitoffsetreg(LDE_IF_ID, LDE_REPC_OFFSET, reg16) ;
1341

    
1342
    _dwt_configlde(prfIndex);
1343

    
1344
    // Configure PLL2/RF PLL block CFG/TUNE (for a given channel)
1345
    dwt_write32bitoffsetreg(FS_CTRL_ID, FS_PLLCFG_OFFSET, fs_pll_cfg[chan_idx[chan]]);
1346
    dwt_write8bitoffsetreg(FS_CTRL_ID, FS_PLLTUNE_OFFSET, fs_pll_tune[chan_idx[chan]]);
1347

    
1348
    // Configure RF RX blocks (for specified channel/bandwidth)
1349
    dwt_write8bitoffsetreg(RF_CONF_ID, RF_RXCTRLH_OFFSET, rx_config[bw]);
1350

    
1351
    // Configure RF TX blocks (for specified channel and PRF)
1352
    // Configure RF TX control
1353
    dwt_write32bitoffsetreg(RF_CONF_ID, RF_TXCTRL_OFFSET, tx_config[chan_idx[chan]]);
1354

    
1355
    // Configure the baseband parameters (for specified PRF, bit rate, PAC, and SFD settings)
1356
    // DTUNE0
1357
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE0b_OFFSET, sftsh[config->dataRate][config->nsSFD]);
1358

    
1359
    // DTUNE1
1360
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1a_OFFSET, dtune1[prfIndex]);
1361

    
1362
    if(config->dataRate == DWT_BR_110K)
1363
    {
1364
        dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_110K);
1365
    }
1366
    else
1367
    {
1368
        if(config->txPreambLength == DWT_PLEN_64)
1369
        {
1370
            dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_6M8_PRE64);
1371
            dwt_write8bitoffsetreg(DRX_CONF_ID, DRX_TUNE4H_OFFSET, DRX_TUNE4H_PRE64);
1372
        }
1373
        else
1374
        {
1375
            dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_850K_6M8);
1376
            dwt_write8bitoffsetreg(DRX_CONF_ID, DRX_TUNE4H_OFFSET, DRX_TUNE4H_PRE128PLUS);
1377
        }
1378
    }
1379

    
1380
    // DTUNE2
1381
    dwt_write32bitoffsetreg(DRX_CONF_ID, DRX_TUNE2_OFFSET, digital_bb_config[prfIndex][config->rxPAC]);
1382

    
1383
    // DTUNE3 (SFD timeout)
1384
    // Don't allow 0 - SFD timeout will always be enabled
1385
    if(config->sfdTO == 0)
1386
    {
1387
        config->sfdTO = DWT_SFDTOC_DEF;
1388
    }
1389
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_SFDTOC_OFFSET, config->sfdTO);
1390

    
1391
    // Configure AGC parameters
1392
    dwt_write32bitoffsetreg( AGC_CFG_STS_ID, 0xC, agc_config.lo32);
1393
    dwt_write16bitoffsetreg( AGC_CFG_STS_ID, 0x4, agc_config.target[prfIndex]);
1394

    
1395
    // Set (non-standard) user SFD for improved performance,
1396
    if(config->nsSFD)
1397
    {
1398
        // Write non standard (DW) SFD length
1399
        dwt_write8bitoffsetreg(USR_SFD_ID, 0x00, dwnsSFDlen[config->dataRate]);
1400
        nsSfd_result = 3 ;
1401
        useDWnsSFD = 1 ;
1402
    }
1403
    regval =  (CHAN_CTRL_TX_CHAN_MASK & (uint32_t)(chan << CHAN_CTRL_TX_CHAN_SHIFT)) | // Transmit Channel
1404
              (CHAN_CTRL_RX_CHAN_MASK & (uint32_t)(chan << CHAN_CTRL_RX_CHAN_SHIFT)) | // Receive Channel
1405
              (CHAN_CTRL_RXFPRF_MASK & (uint32_t)(config->prf << CHAN_CTRL_RXFPRF_SHIFT)) | // RX PRF
1406
              ((CHAN_CTRL_TNSSFD|CHAN_CTRL_RNSSFD) & (uint32_t)(nsSfd_result << CHAN_CTRL_TNSSFD_SHIFT)) | // nsSFD enable RX&TX
1407
              (CHAN_CTRL_DWSFD & (uint32_t)(useDWnsSFD << CHAN_CTRL_DWSFD_SHIFT)) | // Use DW nsSFD
1408
              (CHAN_CTRL_TX_PCOD_MASK & (uint32_t)(config->txCode << CHAN_CTRL_TX_PCOD_SHIFT)) | // TX Preamble Code
1409
              (CHAN_CTRL_RX_PCOD_MASK & (uint32_t)(config->rxCode << CHAN_CTRL_RX_PCOD_SHIFT)) ; // RX Preamble Code
1410

    
1411
    dwt_write32bitreg(CHAN_CTRL_ID,regval) ;
1412

    
1413
    // Set up TX Preamble Size, PRF and Data Rate
1414
    pdw1000local->txFCTRL = (uint32_t)(((config->txPreambLength | config->prf) << TX_FCTRL_TXPRF_SHFT) | (config->dataRate << TX_FCTRL_TXBR_SHFT));
1415
    dwt_write32bitreg(TX_FCTRL_ID, pdw1000local->txFCTRL);
1416

    
1417
    // 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
1418
    // SYS_CTRL write below works around this issue, by simultaneously initiating and aborting a transmission, which correctly initialises the SFD
1419
    // after its configuration or reconfiguration.
1420
    // 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).
1421
    dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, SYS_CTRL_TXSTRT | SYS_CTRL_TRXOFF); // Request TX start and TRX off at the same time
1422
} // end dwt_configure()
1423

    
1424
/*! ------------------------------------------------------------------------------------------------------------------
1425
 * @fn dwt_setrxantennadelay()
1426
 *
1427
 * @brief This API function writes the antenna delay (in time units) to RX registers
1428
 *
1429
 * input parameters:
1430
 * @param rxDelay - this is the total (RX) antenna delay value, which
1431
 *                          will be programmed into the RX register
1432
 *
1433
 * output parameters
1434
 *
1435
 * no return value
1436
 */
1437
void dwt_setrxantennadelay(uint16_t rxDelay)
1438
{
1439
    // Set the RX antenna delay for auto TX timestamp adjustment
1440
    dwt_write16bitoffsetreg(LDE_IF_ID, LDE_RXANTD_OFFSET, rxDelay);
1441
}
1442

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

    
1462
/*! ------------------------------------------------------------------------------------------------------------------
1463
 * @fn dwt_writetxdata()
1464
 *
1465
 * @brief This API function writes the supplied TX data into the DW1000's
1466
 * TX buffer.  The input parameters are the data length in bytes and a pointer
1467
 * to those data bytes.
1468
 *
1469
 * input parameters
1470
 * @param txFrameLength  - This is the total frame length, including the two byte CRC.
1471
 *                         Note: this is the length of TX message (including the 2 byte CRC) - max is 1023
1472
 *                         standard PHR mode allows up to 127 bytes
1473
 *                         if > 127 is programmed, DWT_PHRMODE_EXT needs to be set in the phrMode configuration
1474
 *                         see dwt_configure function
1475
 * @param txFrameBytes   - Pointer to the user’s buffer containing the data to send.
1476
 * @param txBufferOffset - This specifies an offset in the DW1000’s TX Buffer at which to start writing data.
1477
 *
1478
 * output parameters
1479
 *
1480
 * returns DWT_SUCCESS for success, or DWT_ERROR for error
1481
 */
1482
int dwt_writetxdata(uint16_t txFrameLength, uint8_t *txFrameBytes, uint16_t txBufferOffset)
1483
{
1484
#ifdef DWT_API_ERROR_CHECK
1485
    assert(txFrameLength >= 2);
1486
    assert((pdw1000local->longFrames && (txFrameLength <= 1023)) || (txFrameLength <= 127));
1487
    assert((txBufferOffset + txFrameLength) <= 1024);
1488
#endif
1489

    
1490
    if ((txBufferOffset + txFrameLength) <= 1024)
1491
    {
1492
        // Write the data to the IC TX buffer, (-2 bytes for auto generated CRC)
1493
        dwt_writetodevice( TX_BUFFER_ID, txBufferOffset, txFrameLength-2, txFrameBytes);
1494
        return DWT_SUCCESS;
1495
    }
1496
    else
1497
    {
1498
        return DWT_ERROR;
1499
    }
1500
} // end dwt_writetxdata()
1501

    
1502
/*! ------------------------------------------------------------------------------------------------------------------
1503
 * @fn dwt_writetxfctrl()
1504
 *
1505
 * @brief This API function configures the TX frame control register before the transmission of a frame
1506
 *
1507
 * input parameters:
1508
 * @param txFrameLength - this is the length of TX message (including the 2 byte CRC) - max is 1023
1509
 *                              NOTE: standard PHR mode allows up to 127 bytes
1510
 *                              if > 127 is programmed, DWT_PHRMODE_EXT needs to be set in the phrMode configuration
1511
 *                              see dwt_configure function
1512
 * @param txBufferOffset - the offset in the tx buffer to start writing the data
1513
 * @param ranging - 1 if this is a ranging frame, else 0
1514
 *
1515
 * output parameters
1516
 *
1517
 * no return value
1518
 */
1519
void dwt_writetxfctrl(uint16_t txFrameLength, uint16_t txBufferOffset, int ranging)
1520
{
1521

    
1522
#ifdef DWT_API_ERROR_CHECK
1523
    assert((pdw1000local->longFrames && (txFrameLength <= 1023)) || (txFrameLength <= 127));
1524
#endif
1525

    
1526
    // Write the frame length to the TX frame control register
1527
    // pdw1000local->txFCTRL has kept configured bit rate information
1528
    uint32_t reg32 = pdw1000local->txFCTRL | txFrameLength | (uint16_t)(txBufferOffset << TX_FCTRL_TXBOFFS_SHFT) | (uint16_t)(ranging << TX_FCTRL_TR_SHFT);
1529
    dwt_write32bitreg(TX_FCTRL_ID, reg32);
1530
} // end dwt_writetxfctrl()
1531

    
1532

    
1533
/*! ------------------------------------------------------------------------------------------------------------------
1534
 * @fn dwt_readrxdata()
1535
 *
1536
 * @brief This is used to read the data from the RX buffer, from an offset location give by offset parameter
1537
 *
1538
 * input parameters
1539