Statistics
| Branch: | Tag: | Revision:

amiro-lld / source / alld_dw1000.c @ 9e45662e

History | View | Annotate | Download (150.737 KB)

1 fce9feec Robin Ewers
/*
2
AMiRo-LLD is a compilation of low-level hardware drivers for the Autonomous Mini Robot (AMiRo) platform.
3 f125ae07 Thomas Schöpping
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 fce9feec Robin Ewers

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
#if defined(AMIROLLD_CFG_USE_DW1000) || defined(__DOXYGEN__)
34
35
#include <alld_dw1000_regs.h>
36
#include <aos_thread.h>
37
#include <assert.h>
38
#include <string.h>
39
#include <stdlib.h>
40
#include <math.h>
41
42
43
// HW dependent implementation (see bottom of file)
44
static int _alld_dw1000_writespi(uint16_t headerLength,
45
               const        uint8_t *headerBuffer,
46
               uint32_t bodyLength,
47
               const        uint8_t *bodyBuffer);
48
49
static int _alld_dw1000_readspi(uint16_t headerLength,
50
                const uint8_t *headerBuffer,
51
                uint32_t readlength,
52
                uint8_t *readBuffer);
53
54
// Defines for enable_clocks function
55
#define FORCE_SYS_XTI  0
56
#define ENABLE_ALL_SEQ 1
57
#define FORCE_SYS_PLL  2
58
#define READ_ACC_ON    7
59
#define READ_ACC_OFF   8
60
#define FORCE_OTP_ON   11
61
#define FORCE_OTP_OFF  12
62
#define FORCE_TX_PLL   13
63
#define FORCE_LDE      14
64
65
// Defines for ACK request bitmask in DATA and MAC COMMAND frame control (first byte) - Used to detect AAT bit wrongly set.
66
#define FCTRL_ACK_REQ_MASK 0x20
67
// Frame control maximum length in bytes.
68
#define FCTRL_LEN_MAX 2
69
70
71
#define NUM_BR 3
72
#define NUM_PRF 2
73
#define NUM_PACS 4
74
#define NUM_BW 2            //2 bandwidths are supported
75
#define NUM_SFD 2           //supported number of SFDs - standard = 0, non-standard = 1
76
#define NUM_CH 6            //supported channels are 1, 2, 3, 4, 5, 7
77
#define NUM_CH_SUPPORTED 8  //supported channels are '0', 1, 2, 3, 4, 5, '6', 7
78
#define PCODES 25           //supported preamble codes
79
80
81
typedef struct {
82
    uint32_t lo32;
83
    uint16_t target[NUM_PRF];
84
} agc_cfg_struct ;
85
86
extern const agc_cfg_struct agc_config ;
87
88
//SFD threshold settings for 110k, 850k, 6.8Mb standard and non-standard
89
extern const uint16_t sftsh[NUM_BR][NUM_SFD];
90
91
extern const uint16_t dtune1[NUM_PRF];
92
93
#define XMLPARAMS_VERSION   (1.17f)
94
95
extern const uint32_t fs_pll_cfg[NUM_CH];
96
extern const uint8_t fs_pll_tune[NUM_CH];
97
extern const uint8_t rx_config[NUM_BW];
98
extern const uint32_t tx_config[NUM_CH];
99
extern const uint8_t dwnsSFDlen[NUM_BR]; //length of SFD for each of the bitrates
100
extern const uint32_t digital_bb_config[NUM_PRF][NUM_PACS];
101
extern const uint8_t chan_idx[NUM_CH_SUPPORTED];
102
extern const double txpwr_compensation[NUM_CH];
103
104
#define PEAK_MULTPLIER  (0x60) //3 -> (0x3 * 32) & 0x00E0
105
#define N_STD_FACTOR    (13)
106
#define LDE_PARAM1      (PEAK_MULTPLIER | N_STD_FACTOR)
107
108
#define LDE_PARAM3_16 (0x1607)
109
#define LDE_PARAM3_64 (0x0607)
110
111
#define MIXER_GAIN_STEP (0.5)
112
#define DA_ATTN_STEP    (2.5)
113
114
// #define DWT_API_ERROR_CHECK     // define so API checks config input parameters
115
116
//-----------------------------------------
117
// map the channel number to the index in the configuration arrays below
118
// 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
119
const uint8_t chan_idx[NUM_CH_SUPPORTED] = {0, 0, 1, 2, 3, 4, 0, 5};
120
121
//-----------------------------------------
122
const uint32_t tx_config[NUM_CH] =
123
{
124
    RF_TXCTRL_CH1,
125
    RF_TXCTRL_CH2,
126
    RF_TXCTRL_CH3,
127
    RF_TXCTRL_CH4,
128
    RF_TXCTRL_CH5,
129
    RF_TXCTRL_CH7,
130
};
131
132
//Frequency Synthesiser - PLL configuration
133
const uint32_t fs_pll_cfg[NUM_CH] =
134
{
135
    FS_PLLCFG_CH1,
136
    FS_PLLCFG_CH2,
137
    FS_PLLCFG_CH3,
138
    FS_PLLCFG_CH4,
139
    FS_PLLCFG_CH5,
140
    FS_PLLCFG_CH7
141
};
142
143
//Frequency Synthesiser - PLL tuning
144
const uint8_t fs_pll_tune[NUM_CH] =
145
{
146
    FS_PLLTUNE_CH1,
147
    FS_PLLTUNE_CH2,
148
    FS_PLLTUNE_CH3,
149
    FS_PLLTUNE_CH4,
150
    FS_PLLTUNE_CH5,
151
    FS_PLLTUNE_CH7
152
};
153
154
//bandwidth configuration
155
const uint8_t rx_config[NUM_BW] =
156
{
157
    RF_RXCTRLH_NBW,
158
    RF_RXCTRLH_WBW
159
};
160
161
162
const agc_cfg_struct agc_config =
163
{
164
    AGC_TUNE2_VAL,
165
    { AGC_TUNE1_16M , AGC_TUNE1_64M }  //adc target
166
};
167
168
//DW non-standard SFD length for 110k, 850k and 6.81M
169
const uint8_t dwnsSFDlen[NUM_BR] =
170
{
171
    DW_NS_SFD_LEN_110K,
172
    DW_NS_SFD_LEN_850K,
173
    DW_NS_SFD_LEN_6M8
174
};
175
176
// SFD Threshold
177
const uint16_t sftsh[NUM_BR][NUM_SFD] =
178
{
179
    {
180
        DRX_TUNE0b_110K_STD,
181
        DRX_TUNE0b_110K_NSTD
182
    },
183
    {
184
        DRX_TUNE0b_850K_STD,
185
        DRX_TUNE0b_850K_NSTD
186
    },
187
    {
188
        DRX_TUNE0b_6M8_STD,
189
        DRX_TUNE0b_6M8_NSTD
190
    }
191
};
192
193
const uint16_t dtune1[NUM_PRF] =
194
{
195
    DRX_TUNE1a_PRF16,
196
    DRX_TUNE1a_PRF64
197
};
198
199
const uint32_t digital_bb_config[NUM_PRF][NUM_PACS] =
200
{
201
    {
202
        DRX_TUNE2_PRF16_PAC8,
203
        DRX_TUNE2_PRF16_PAC16,
204
        DRX_TUNE2_PRF16_PAC32,
205
        DRX_TUNE2_PRF16_PAC64
206
    },
207
    {
208
        DRX_TUNE2_PRF64_PAC8,
209
        DRX_TUNE2_PRF64_PAC16,
210
        DRX_TUNE2_PRF64_PAC32,
211
        DRX_TUNE2_PRF64_PAC64
212
    }
213
};
214
215
const uint16_t lde_replicaCoeff[PCODES] =
216
{
217
    0, // No preamble code 0
218
    LDE_REPC_PCODE_1,
219
    LDE_REPC_PCODE_2,
220
    LDE_REPC_PCODE_3,
221
    LDE_REPC_PCODE_4,
222
    LDE_REPC_PCODE_5,
223
    LDE_REPC_PCODE_6,
224
    LDE_REPC_PCODE_7,
225
    LDE_REPC_PCODE_8,
226
    LDE_REPC_PCODE_9,
227
    LDE_REPC_PCODE_10,
228
    LDE_REPC_PCODE_11,
229
    LDE_REPC_PCODE_12,
230
    LDE_REPC_PCODE_13,
231
    LDE_REPC_PCODE_14,
232
    LDE_REPC_PCODE_15,
233
    LDE_REPC_PCODE_16,
234
    LDE_REPC_PCODE_17,
235
    LDE_REPC_PCODE_18,
236
    LDE_REPC_PCODE_19,
237
    LDE_REPC_PCODE_20,
238
    LDE_REPC_PCODE_21,
239
    LDE_REPC_PCODE_22,
240
    LDE_REPC_PCODE_23,
241
    LDE_REPC_PCODE_24
242
};
243
244
const double txpwr_compensation[NUM_CH] = {
245
    0.0,
246
    0.035,
247
    0.0,
248
    0.0,
249
    0.065,
250
    0.0
251
};
252
253
254
#define NUM_16M_OFFSET  (37)
255
#define NUM_16M_OFFSETWB  (68)
256
#define NUM_64M_OFFSET  (26)
257
#define NUM_64M_OFFSETWB  (59)
258
259
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
260
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
261
262
//---------------------------------------------------------------------------------------------------------------------------
263
// Range Bias Correction TABLES of range values in integer units of 25 CM, for 8-bit unsigned storage, MUST END IN 255 !!!!!!
264
//---------------------------------------------------------------------------------------------------------------------------
265
266
// offsets to nearest centimeter for index 0, all rest are +1 cm per value
267
268
#define CM_OFFSET_16M_NB    (-23)   // for normal band channels at 16 MHz PRF
269
#define CM_OFFSET_16M_WB    (-28)   // for wider  band channels at 16 MHz PRF
270
#define CM_OFFSET_64M_NB    (-17)   // for normal band channels at 64 MHz PRF
271
#define CM_OFFSET_64M_WB    (-30)   // for wider  band channels at 64 MHz PRF
272
273
274
//---------------------------------------------------------------------------------------------------------------------------
275
// range25cm16PRFnb: Range Bias Correction table for narrow band channels at 16 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
276
//---------------------------------------------------------------------------------------------------------------------------
277
278
const uint8_t range25cm16PRFnb[4][NUM_16M_OFFSET] =
279
{
280
    // ch 1 - range25cm16PRFnb
281
    {
282
           1,
283
           3,
284
           4,
285
           5,
286
           7,
287
           9,
288
          11,
289
          12,
290
          13,
291
          15,
292
          18,
293
          20,
294
          23,
295
          25,
296
          28,
297
          30,
298
          33,
299
          36,
300
          40,
301
          43,
302
          47,
303
          50,
304
          54,
305
          58,
306
          63,
307
          66,
308
          71,
309
          76,
310
          82,
311
          89,
312
          98,
313
         109,
314
         127,
315
         155,
316
         222,
317
         255,
318
         255
319
    },
320
321
    // ch 2 - range25cm16PRFnb
322
    {
323
           1,
324
           2,
325
           4,
326
           5,
327
           6,
328
           8,
329
           9,
330
          10,
331
          12,
332
          13,
333
          15,
334
          18,
335
          20,
336
          22,
337
          24,
338
          27,
339
          29,
340
          32,
341
          35,
342
          38,
343
          41,
344
          44,
345
          47,
346
          51,
347
          55,
348
          58,
349
          62,
350
          66,
351
          71,
352
          78,
353
          85,
354
          96,
355
         111,
356
         135,
357
         194,
358
         240,
359
         255
360
    },
361
362
    // ch 3 - range25cm16PRFnb
363
    {
364
           1,
365
           2,
366
           3,
367
           4,
368
           5,
369
           7,
370
           8,
371
           9,
372
          10,
373
          12,
374
          14,
375
          16,
376
          18,
377
          20,
378
          22,
379
          24,
380
          26,
381
          28,
382
          31,
383
          33,
384
          36,
385
          39,
386
          42,
387
          45,
388
          49,
389
          52,
390
          55,
391
          59,
392
          63,
393
          69,
394
          76,
395
          85,
396
          98,
397
         120,
398
         173,
399
         213,
400
         255
401
    },
402
403
    // ch 5 - range25cm16PRFnb
404
    {
405
           1,
406
           1,
407
           2,
408
           3,
409
           4,
410
           5,
411
           6,
412
           6,
413
           7,
414
           8,
415
           9,
416
          11,
417
          12,
418
          14,
419
          15,
420
          16,
421
          18,
422
          20,
423
          21,
424
          23,
425
          25,
426
          27,
427
          29,
428
          31,
429
          34,
430
          36,
431
          38,
432
          41,
433
          44,
434
          48,
435
          53,
436
          59,
437
          68,
438
          83,
439
         120,
440
         148,
441
         255
442
    }
443
}; // end range25cm16PRFnb
444
445
446
//---------------------------------------------------------------------------------------------------------------------------
447
// range25cm16PRFwb: Range Bias Correction table for wide band channels at 16 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
448
//---------------------------------------------------------------------------------------------------------------------------
449
450
const uint8_t range25cm16PRFwb[2][NUM_16M_OFFSETWB] =
451
{
452
    // ch 4 - range25cm16PRFwb
453
    {
454
           7,
455
           7,
456
           8,
457
           9,
458
           9,
459
          10,
460
          11,
461
          11,
462
          12,
463
          13,
464
          14,
465
          15,
466
          16,
467
          17,
468
          18,
469
          19,
470
          20,
471
          21,
472
          22,
473
          23,
474
          24,
475
          26,
476
          27,
477
          28,
478
          30,
479
          31,
480
          32,
481
          34,
482
          36,
483
          38,
484
          40,
485
          42,
486
          44,
487
          46,
488
          48,
489
          50,
490
          52,
491
          55,
492
          57,
493
          59,
494
          61,
495
          63,
496
          66,
497
          68,
498
          71,
499
          74,
500
          78,
501
          81,
502
          85,
503
          89,
504
          94,
505
          99,
506
         104,
507
         110,
508
         116,
509
         123,
510
         130,
511
         139,
512
         150,
513
         164,
514
         182,
515
         207,
516
         238,
517
         255,
518
         255,
519
         255,
520
         255,
521
         255
522
    },
523
524
    // ch 7 - range25cm16PRFwb
525
    {
526
           4,
527
           5,
528
           5,
529
           5,
530
           6,
531
           6,
532
           7,
533
           7,
534
           7,
535
           8,
536
           9,
537
           9,
538
          10,
539
          10,
540
          11,
541
          11,
542
          12,
543
          13,
544
          13,
545
          14,
546
          15,
547
          16,
548
          17,
549
          17,
550
          18,
551
          19,
552
          20,
553
          21,
554
          22,
555
          23,
556
          25,
557
          26,
558
          27,
559
          29,
560
          30,
561
          31,
562
          32,
563
          34,
564
          35,
565
          36,
566
          38,
567
          39,
568
          40,
569
          42,
570
          44,
571
          46,
572
          48,
573
          50,
574
          52,
575
          55,
576
          58,
577
          61,
578
          64,
579
          68,
580
          72,
581
          75,
582
          80,
583
          85,
584
          92,
585
         101,
586
         112,
587
         127,
588
         147,
589
         168,
590
         182,
591
         194,
592
         205,
593
         255
594
    }
595
}; // end range25cm16PRFwb
596
597
//---------------------------------------------------------------------------------------------------------------------------
598
// range25cm64PRFnb: Range Bias Correction table for narrow band channels at 64 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
599
//---------------------------------------------------------------------------------------------------------------------------
600
601
const uint8_t range25cm64PRFnb[4][NUM_64M_OFFSET] =
602
{
603
    // ch 1 - range25cm64PRFnb
604
    {
605
           1,
606
           2,
607
           2,
608
           3,
609
           4,
610
           5,
611
           7,
612
          10,
613
          13,
614
          16,
615
          19,
616
          22,
617
          24,
618
          27,
619
          30,
620
          32,
621
          35,
622
          38,
623
          43,
624
          48,
625
          56,
626
          78,
627
         101,
628
         120,
629
         157,
630
         255
631
    },
632
633
    // ch 2 - range25cm64PRFnb
634
    {
635
           1,
636
           2,
637
           2,
638
           3,
639
           4,
640
           4,
641
           6,
642
           9,
643
          12,
644
          14,
645
          17,
646
          19,
647
          21,
648
          24,
649
          26,
650
          28,
651
          31,
652
          33,
653
          37,
654
          42,
655
          49,
656
          68,
657
          89,
658
         105,
659
         138,
660
         255
661
    },
662
663
    // ch 3 - range25cm64PRFnb
664
    {
665
           1,
666
           1,
667
           2,
668
           3,
669
           3,
670
           4,
671
           5,
672
           8,
673
          10,
674
          13,
675
          15,
676
          17,
677
          19,
678
          21,
679
          23,
680
          25,
681
          27,
682
          30,
683
          33,
684
          37,
685
          44,
686
          60,
687
          79,
688
          93,
689
         122,
690
         255
691
    },
692
693
    // ch 5 - range25cm64PRFnb
694
    {
695
           1,
696
           1,
697
           1,
698
           2,
699
           2,
700
           3,
701
           4,
702
           6,
703
           7,
704
           9,
705
          10,
706
          12,
707
          13,
708
          15,
709
          16,
710
          17,
711
          19,
712
          21,
713
          23,
714
          26,
715
          30,
716
          42,
717
          55,
718
          65,
719
          85,
720
         255
721
    }
722
}; // end range25cm64PRFnb
723
724
//---------------------------------------------------------------------------------------------------------------------------
725
// range25cm64PRFwb: Range Bias Correction table for wide band channels at 64 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
726
//---------------------------------------------------------------------------------------------------------------------------
727
728
const uint8_t range25cm64PRFwb[2][NUM_64M_OFFSETWB] =
729
{
730
    // ch 4 - range25cm64PRFwb
731
    {
732
           7,
733
           8,
734
           8,
735
           9,
736
           9,
737
          10,
738
          11,
739
          12,
740
          13,
741
          13,
742
          14,
743
          15,
744
          16,
745
          16,
746
          17,
747
          18,
748
          19,
749
          19,
750
          20,
751
          21,
752
          22,
753
          24,
754
          25,
755
          27,
756
          28,
757
          29,
758
          30,
759
          32,
760
          33,
761
          34,
762
          35,
763
          37,
764
          39,
765
          41,
766
          43,
767
          45,
768
          48,
769
          50,
770
          53,
771
          56,
772
          60,
773
          64,
774
          68,
775
          74,
776
          81,
777
          89,
778
          98,
779
         109,
780
         122,
781
         136,
782
         146,
783
         154,
784
         162,
785
         178,
786
         220,
787
         249,
788
         255,
789
         255,
790
         255
791
    },
792
793
    // ch 7 - range25cm64PRFwb
794
    {
795
           4,
796
           5,
797
           5,
798
           5,
799
           6,
800
           6,
801
           7,
802
           7,
803
           8,
804
           8,
805
           9,
806
           9,
807
          10,
808
          10,
809
          10,
810
          11,
811
          11,
812
          12,
813
          13,
814
          13,
815
          14,
816
          15,
817
          16,
818
          16,
819
          17,
820
          18,
821
          19,
822
          19,
823
          20,
824
          21,
825
          22,
826
          23,
827
          24,
828
          25,
829
          26,
830
          28,
831
          29,
832
          31,
833
          33,
834
          35,
835
          37,
836
          39,
837
          42,
838
          46,
839
          50,
840
          54,
841
          60,
842
          67,
843
          75,
844
          83,
845
          90,
846
          95,
847
         100,
848
         110,
849
         135,
850
         153,
851
         172,
852
         192,
853
         255
854
    }
855
}; // end range25cm64PRFwb
856
857
858
859
860
861
/*! ------------------------------------------------------------------------------------------------------------------
862
 * Function: dwt_getrangebias()
863
 *
864
 * Description: This function is used to return the range bias correction need for TWR with DW1000 units.
865
 *
866
 * input parameters:        
867
 * @param chan  - specifies the operating channel (e.g. 1, 2, 3, 4, 5, 6 or 7) 
868
 * @param range - the calculated distance before correction
869
 * @param prf        - this is the PRF e.g. DWT_PRF_16M or DWT_PRF_64M
870
 *
871
 * output parameters
872
 *
873
 * returns correction needed in meters
874
 */
875
double dwt_getrangebias(uint8_t chan, float range, uint8_t prf)
876
{
877
    //first get the lookup index that corresponds to given range for a particular channel at 16M PRF
878
    int i = 0 ;
879
    int chanIdx ;
880
    int cmoffseti ;                                 // integer number of CM offset
881
882
    double mOffset ;                                // final offset result in metres
883
884
    // NB: note we may get some small negitive values e.g. up to -50 cm.
885
886
    int rangeint25cm = (int) (range * 4.00) ;       // convert range to integer number of 25cm values.
887
888
    if (rangeint25cm > 255) rangeint25cm = 255 ;    // make sure it matches largest value in table (all tables end in 255 !!!!)
889
890
    if (prf == DWT_PRF_16M)
891
    {
892
        switch(chan)
893
        {
894
            case 4:
895
            case 7:
896
            {
897
                chanIdx = chan_idxwb[chan];
898
                while (rangeint25cm > range25cm16PRFwb[chanIdx][i]) i++ ;       // find index in table corresponding to range
899
                cmoffseti = i + CM_OFFSET_16M_WB ;                              // nearest centimeter correction
900
            }
901
            break;
902
            default:
903
            {
904
                chanIdx = chan_idxnb[chan];
905
                while (rangeint25cm > range25cm16PRFnb[chanIdx][i]) i++ ;       // find index in table corresponding to range
906
                cmoffseti = i + CM_OFFSET_16M_NB ;                              // nearest centimeter correction
907
            }
908
        }//end of switch
909
    }
910
    else // 64M PRF
911
    {
912
        switch(chan)
913
        {
914
            case 4:
915
            case 7:
916
            {
917
                chanIdx = chan_idxwb[chan];
918
                while (rangeint25cm > range25cm64PRFwb[chanIdx][i]) i++ ;       // find index in table corresponding to range
919
                cmoffseti = i + CM_OFFSET_64M_WB ;                              // nearest centimeter correction
920
            }
921
            break;
922
            default:
923
            {
924
                chanIdx = chan_idxnb[chan];
925
                while (rangeint25cm > range25cm64PRFnb[chanIdx][i]) i++ ;       // find index in table corresponding to range
926
                cmoffseti = i + CM_OFFSET_64M_NB ;                              // nearest centimeter correction
927
            }
928
        }//end of switch
929
    } // end else
930
931
932
    mOffset = (float) cmoffseti ;                                       // offset result in centimmetres
933
934
    mOffset *= 0.01 ;                                                   // convert to metres
935
936
    return (mOffset) ;
937
}
938
939
940
941
// -------------------------------------------------------------------------------------------------------------------
942
//
943
// Internal functions for controlling and configuring the device
944
//
945
// -------------------------------------------------------------------------------------------------------------------
946
947
// Enable and Configure specified clocks
948
void _dwt_enableclocks(int clocks) ;
949
// Configure the ucode (FP algorithm) parameters
950
void _dwt_configlde(int prf);
951
// Load ucode from OTP/ROM
952
void _dwt_loaducodefromrom(void);
953
// Read non-volatile memory
954
uint32_t _dwt_otpread(uint32_t address);
955
// Program the non-volatile memory
956
uint32_t _dwt_otpprogword32(uint32_t data, uint16_t address);
957
// Upload the device configuration into always on memory
958
void _dwt_aonarrayupload(void);
959
// -------------------------------------------------------------------------------------------------------------------
960
961
/*!
962
 * Static data for DW1000 DecaWave Transceiver control
963
 */
964
965
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
966
static dwt_local_data_t *pdw1000local = dw1000local ; // Static local data structure pointer
967
968
969
/*! ------------------------------------------------------------------------------------------------------------------
970
 * @fn dwt_setdevicedataptr()
971
 *
972
 * @brief This function sets the local data structure pointer to point to the structure in the local array as given by the index.
973
 *
974
 * input parameters
975
 * @param index    - selects the array object to point to. Must be within the array bounds, i.e. < DWT_NUM_DW_DEV
976
 *
977
 * output parameters
978
 *
979
 * returns DWT_SUCCESS for success, or DWT_ERROR for error
980
 */
981
int dwt_setdevicedataptr(unsigned int index)
982
{
983
    // Check the index is within the array bounds
984
    if (DWT_NUM_DW_DEV > index) // return error if index outside the array bounds
985
    {
986
        return DWT_ERROR ;
987
    }
988
989
    pdw1000local = &dw1000local[index];
990
991
    return DWT_SUCCESS ;
992
}
993
994
/*! ------------------------------------------------------------------------------------------------------------------
995
 * @fn dwt_initialise()
996
 *
997
 * @brief This function initiates communications with the DW1000 transceiver
998
 * and reads its DEV_ID register (address 0x00) to verify the IC is one supported
999
 * by this software (e.g. DW1000 32-bit device ID value is 0xDECA0130).  Then it
1000
 * does any initial once only device configurations needed for use and initialises
1001
 * as necessary any static data items belonging to this low-level driver.
1002
 *
1003
 * NOTES:
1004
 * 1.this function needs to be run before dwt_configuresleep, also the SPI frequency has to be < 3MHz
1005
 * 2.it also reads and applies LDO tune and crystal trim values from OTP memory
1006
 *
1007
 * input parameters
1008
 * @param config    -   specifies what configuration to load
1009
 *                  DWT_LOADUCODE     0x1 - load the LDE microcode from ROM - enabled accurate RX timestamp
1010
 *                  DWT_LOADNONE      0x0 - do not load any values from OTP memory
1011
 *
1012
 * output parameters
1013
 *
1014
 * returns DWT_SUCCESS for success, or DWT_ERROR for error
1015
 */
1016
// OTP addresses definitions
1017
#define LDOTUNE_ADDRESS (0x04)
1018
#define PARTID_ADDRESS (0x06)
1019
#define LOTID_ADDRESS  (0x07)
1020
#define VBAT_ADDRESS   (0x08)
1021
#define VTEMP_ADDRESS  (0x09)
1022
#define XTRIM_ADDRESS  (0x1E)
1023
1024
int dwt_initialise(const uint16_t config, DW1000Driver* drv)
1025
{
1026
    uint16_t otp_addr = 0;
1027
    uint32_t ldo_tune = 0;
1028
1029
    pdw1000local->dblbuffon = 0; // Double buffer mode off by default
1030
    pdw1000local->wait4resp = 0;
1031
    pdw1000local->sleep_mode = 0;
1032
1033
    pdw1000local->cbTxDone = NULL;
1034
    pdw1000local->cbRxOk = NULL;
1035
    pdw1000local->cbRxTo = NULL;
1036
    pdw1000local->cbRxErr = NULL;
1037
1038
    pdw1000local->driver = drv;
1039
1040
    // Read and validate device ID return -1 if not recognised
1041
    if (DWT_DEVICE_ID != dwt_readdevid()) // MP IC ONLY (i.e. DW1000) FOR THIS CODE
1042
    {
1043
        return DWT_ERROR ;
1044
    }
1045
1046
    // Make sure the device is completely reset before starting initialisation
1047
    dwt_softreset();
1048
1049
    _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
1050
1051
    // Configure the CPLL lock detect
1052
    dwt_write8bitoffsetreg(EXT_SYNC_ID, EC_CTRL_OFFSET, EC_CTRL_PLLLCK);
1053
1054
    // Read OTP revision number
1055
    otp_addr = _dwt_otpread(XTRIM_ADDRESS) & 0xffff;        // Read 32 bit value, XTAL trim val is in low octet-0 (5 bits)
1056
    pdw1000local->otprev = (otp_addr >> 8) & 0xff;            // OTP revision is next byte
1057
1058
    // Load LDO tune from OTP and kick it if there is a value actually programmed.
1059
    ldo_tune = _dwt_otpread(LDOTUNE_ADDRESS);
1060
    if((ldo_tune & 0xFF) != 0)
1061
    {
1062
        // Kick LDO tune
1063
        dwt_write8bitoffsetreg(OTP_IF_ID, OTP_SF, OTP_SF_LDO_KICK); // Set load LDE kick bit
1064
        pdw1000local->sleep_mode |= AON_WCFG_ONW_LLDO; // LDO tune must be kicked at wake-up
1065
    }
1066
1067
    // Load Part and Lot ID from OTP
1068
    pdw1000local->partID = _dwt_otpread(PARTID_ADDRESS);
1069
    pdw1000local->lotID = _dwt_otpread(LOTID_ADDRESS);
1070
1071
    // 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
1072
    pdw1000local->init_xtrim = otp_addr & 0x1F;
1073
    if (!pdw1000local->init_xtrim) // A value of 0 means that the crystal has not been trimmed
1074
    {
1075
        pdw1000local->init_xtrim = FS_XTALT_MIDRANGE ; // Set to mid-range if no calibration value inside
1076
    }
1077
    // Configure XTAL trim
1078
    dwt_setxtaltrim(pdw1000local->init_xtrim);
1079
1080
    // Load leading edge detect code
1081
    if(config & DWT_LOADUCODE)
1082
    {
1083
        _dwt_loaducodefromrom();
1084
        pdw1000local->sleep_mode |= AON_WCFG_ONW_LLDE; // microcode must be loaded at wake-up
1085
    }
1086
    else // Should disable the LDERUN enable bit in 0x36, 0x4
1087
    {
1088
        uint16_t rega = dwt_read16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1) ;
1089
        rega &= 0xFDFF ; // Clear LDERUN bit
1090
        dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1, rega) ;
1091
    }
1092
1093
    _dwt_enableclocks(ENABLE_ALL_SEQ); // Enable clocks for sequencing
1094
1095
    // The 3 bits in AON CFG1 register must be cleared to ensure proper operation of the DW1000 in DEEPSLEEP mode.
1096
    dwt_write8bitoffsetreg(AON_ID, AON_CFG1_OFFSET, 0x00);
1097
1098
    // Read system register / store local copy
1099
    pdw1000local->sysCFGreg = dwt_read32bitreg(SYS_CFG_ID) ; // Read sysconfig register
1100
1101
    return DWT_SUCCESS ;
1102
1103
} // end dwt_initialise()
1104
1105
/*! ------------------------------------------------------------------------------------------------------------------
1106
 * @fn dwt_otprevision()
1107
 *
1108
 * @brief This is used to return the read OTP revision
1109
 *
1110
 * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
1111
 *
1112
 * input parameters
1113
 *
1114
 * output parameters
1115
 *
1116
 * returns the read OTP revision value
1117
 */
1118
uint8_t dwt_otprevision(void)
1119
{
1120
    return pdw1000local->otprev ;
1121
}
1122
1123
/*! ------------------------------------------------------------------------------------------------------------------
1124
 * @fn dwt_setfinegraintxseq()
1125
 *
1126
 * @brief This function enables/disables the fine grain TX sequencing (enabled by default).
1127
 *
1128
 * input parameters
1129
 * @param enable - 1 to enable fine grain TX sequencing, 0 to disable it.
1130
 *
1131
 * output parameters none
1132
 *
1133
 * no return value
1134
 */
1135
void dwt_setfinegraintxseq(int enable)
1136
{
1137
    if (enable)
1138
    {
1139
        dwt_write16bitoffsetreg(PMSC_ID, PMSC_TXFINESEQ_OFFSET, PMSC_TXFINESEQ_ENABLE);
1140
    }
1141
    else
1142
    {
1143
        dwt_write16bitoffsetreg(PMSC_ID, PMSC_TXFINESEQ_OFFSET, PMSC_TXFINESEQ_DISABLE);
1144
    }
1145
}
1146
1147
/*! ------------------------------------------------------------------------------------------------------------------
1148
 * @fn dwt_setlnapamode()
1149
 *
1150
 * @brief This is used to enable GPIO for external LNA or PA functionality - HW dependent, consult the DW1000 User Manual.
1151
 *        This can also be used for debug as enabling TX and RX GPIOs is quite handy to monitor DW1000's activity.
1152
 *
1153
 * NOTE: Enabling PA functionality requires that fine grain TX sequencing is deactivated. This can be done using
1154
 *       dwt_setfinegraintxseq().
1155
 *
1156
 * input parameters
1157
 * @param lna - 1 to enable LNA functionality, 0 to disable it
1158
 * @param pa - 1 to enable PA functionality, 0 to disable it
1159
 *
1160
 * output parameters
1161
 *
1162
 * no return value
1163
 */
1164
void dwt_setlnapamode(int lna, int pa)
1165
{
1166
    uint32_t gpio_mode = dwt_read32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET);
1167
    gpio_mode &= ~(GPIO_MSGP4_MASK | GPIO_MSGP5_MASK | GPIO_MSGP6_MASK);
1168
    if (lna)
1169
    {
1170
        gpio_mode |= GPIO_PIN6_EXTRXE;
1171
    }
1172
    if (pa)
1173
    {
1174
        gpio_mode |= (GPIO_PIN5_EXTTXE | GPIO_PIN4_EXTPA);
1175
    }
1176
    dwt_write32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET, gpio_mode);
1177
}
1178
1179
/*! ------------------------------------------------------------------------------------------------------------------
1180
 * @fn dwt_setgpiodirection()
1181
 *
1182
 * @brief This is used to set GPIO direction as an input (1) or output (0)
1183
 *
1184
 * input parameters
1185
 * @param gpioNum    -   this is the GPIO to configure - see GxM0... GxM8 in the deca_regs.h file
1186
 * @param direction  -   this sets the GPIO direction - see GxP0... GxP8 in the deca_regs.h file
1187
 *
1188
 * output parameters
1189
 *
1190
 * no return value
1191
 */
1192
void dwt_setgpiodirection(uint32_t gpioNum, uint32_t direction)
1193
{
1194
    uint8_t buf[GPIO_DIR_LEN];
1195
    uint32_t command = direction | gpioNum;
1196
1197
    buf[0] = command & 0xff;
1198
    buf[1] = (command >> 8) & 0xff;
1199
    buf[2] = (command >> 16) & 0xff;
1200
1201
    dwt_writetodevice(GPIO_CTRL_ID, GPIO_DIR_OFFSET, GPIO_DIR_LEN, buf);
1202
}
1203
1204
/*! ------------------------------------------------------------------------------------------------------------------
1205
 * @fn dwt_setgpiovalue()
1206
 *
1207
 * @brief This is used to set GPIO value as (1) or (0) only applies if the GPIO is configured as output
1208
 *
1209
 * input parameters
1210
 * @param gpioNum    -   this is the GPIO to configure - see GxM0... GxM8 in the deca_regs.h file
1211
 * @param value  -   this sets the GPIO value - see GDP0... GDP8 in the deca_regs.h file
1212
 *
1213
 * output parameters
1214
 *
1215
 * no return value
1216
 */
1217
void dwt_setgpiovalue(uint32_t gpioNum, uint32_t value)
1218
{
1219
    uint8_t buf[GPIO_DOUT_LEN];
1220
    uint32_t command = value | gpioNum;
1221
1222
    buf[0] = command & 0xff;
1223
    buf[1] = (command >> 8) & 0xff;
1224
    buf[2] = (command >> 16) & 0xff;
1225
1226
    dwt_writetodevice(GPIO_CTRL_ID, GPIO_DOUT_OFFSET, GPIO_DOUT_LEN, buf);
1227
}
1228
1229
/*! ------------------------------------------------------------------------------------------------------------------
1230
 * @fn dwt_getpartid()
1231
 *
1232
 * @brief This is used to return the read part ID of the device
1233
 *
1234
 * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
1235
 *
1236
 * input parameters
1237
 *
1238
 * output parameters
1239
 *
1240
 * returns the 32 bit part ID value as programmed in the factory
1241
 */
1242
uint32_t dwt_getpartid(void)
1243
{
1244
    return pdw1000local->partID;
1245
}
1246
1247
/*! ------------------------------------------------------------------------------------------------------------------
1248
 * @fn dwt_getlotid()
1249
 *
1250
 * @brief This is used to return the read lot ID of the device
1251
 *
1252
 * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
1253
 *
1254
 * input parameters
1255
 *
1256
 * output parameters
1257
 *
1258
 * returns the 32 bit lot ID value as programmed in the factory
1259
 */
1260
uint32_t dwt_getlotid(void)
1261
{
1262
    return pdw1000local->lotID;
1263
}
1264
1265
/*! ------------------------------------------------------------------------------------------------------------------
1266
 * @fn dwt_readdevid()
1267
 *
1268
 * @brief This is used to return the read device type and revision information of the DW1000 device (MP part is 0xDECA0130)
1269
 *
1270
 * input parameters
1271
 *
1272
 * output parameters
1273
 *
1274
 * returns the read value which for DW1000 is 0xDECA0130
1275
 */
1276
uint32_t dwt_readdevid(void)
1277
{
1278
    return dwt_read32bitoffsetreg(DEV_ID_ID,0);
1279
}
1280
1281
/*! ------------------------------------------------------------------------------------------------------------------
1282
 * @fn dwt_configuretxrf()
1283
 *
1284
 * @brief This function provides the API for the configuration of the TX spectrum
1285
 * including the power and pulse generator delay. The input is a pointer to the data structure
1286
 * of type dwt_txconfig_t that holds all the configurable items.
1287
 *
1288
 * input parameters
1289
 * @param config    -   pointer to the txrf configuration structure, which contains the tx rf config data
1290
 *
1291
 * output parameters
1292
 *
1293
 * no return value
1294
 */
1295
void dwt_configuretxrf(dwt_txconfig_t* config)
1296
{
1297
1298
    // Configure RF TX PG_DELAY
1299
    dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGDELAY_OFFSET, config->PGdly);
1300
1301
    // Configure TX power
1302
    dwt_write32bitreg(TX_POWER_ID, config->power);
1303
1304
}
1305
1306
/*! ------------------------------------------------------------------------------------------------------------------
1307
 * @fn dwt_configure()
1308
 *
1309
 * @brief This function provides the main API for the configuration of the
1310
 * DW1000 and this low-level driver.  The input is a pointer to the data structure
1311
 * of type dwt_config_t that holds all the configurable items.
1312
 * The dwt_config_t structure shows which ones are supported
1313
 *
1314
 * input parameters
1315
 * @param config    -   pointer to the configuration structure, which contains the device configuration data.
1316
 *
1317
 * output parameters
1318
 *
1319
 * no return value
1320
 */
1321
void dwt_configure(dwt_config_t *config)
1322
{
1323
    uint8_t nsSfd_result  = 0;
1324
    uint8_t useDWnsSFD = 0;
1325
    uint8_t chan = config->chan ;
1326
    uint32_t regval ;
1327
    uint16_t reg16 = lde_replicaCoeff[config->rxCode];
1328
    uint8_t prfIndex = config->prf - DWT_PRF_16M;
1329
    uint8_t bw = ((chan == 4) || (chan == 7)) ? 1 : 0 ; // Select wide or narrow band
1330
1331
#ifdef DWT_API_ERROR_CHECK
1332
    assert(config->dataRate <= DWT_BR_6M8);
1333
    assert(config->rxPAC <= DWT_PAC64);
1334
    assert((chan >= 1) && (chan <= 7) && (chan != 6));
1335
    assert(((config->prf == DWT_PRF_64M) && (config->txCode >= 9) && (config->txCode <= 24))
1336
           || ((config->prf == DWT_PRF_16M) && (config->txCode >= 1) && (config->txCode <= 8)));
1337
    assert(((config->prf == DWT_PRF_64M) && (config->rxCode >= 9) && (config->rxCode <= 24))
1338
           || ((config->prf == DWT_PRF_16M) && (config->rxCode >= 1) && (config->rxCode <= 8)));
1339
    assert((config->txPreambLength == DWT_PLEN_64) || (config->txPreambLength == DWT_PLEN_128) || (config->txPreambLength == DWT_PLEN_256)
1340
           || (config->txPreambLength == DWT_PLEN_512) || (config->txPreambLength == DWT_PLEN_1024) || (config->txPreambLength == DWT_PLEN_1536)
1341
           || (config->txPreambLength == DWT_PLEN_2048) || (config->txPreambLength == DWT_PLEN_4096));
1342
    assert((config->phrMode == DWT_PHRMODE_STD) || (config->phrMode == DWT_PHRMODE_EXT));
1343
#endif
1344
1345
    // For 110 kbps we need a special setup
1346
    if(DWT_BR_110K == config->dataRate)
1347
    {
1348
        pdw1000local->sysCFGreg |= SYS_CFG_RXM110K ;
1349
        reg16 >>= 3; // lde_replicaCoeff must be divided by 8
1350
    }
1351
    else
1352
    {
1353
        pdw1000local->sysCFGreg &= (~SYS_CFG_RXM110K) ;
1354
    }
1355
1356
    pdw1000local->longFrames = config->phrMode ;
1357
1358
    pdw1000local->sysCFGreg &= ~SYS_CFG_PHR_MODE_11;
1359
    pdw1000local->sysCFGreg |= (SYS_CFG_PHR_MODE_11 & (config->phrMode << SYS_CFG_PHR_MODE_SHFT));
1360
1361
    dwt_write32bitreg(SYS_CFG_ID,pdw1000local->sysCFGreg) ;
1362
    // Set the lde_replicaCoeff
1363
    dwt_write16bitoffsetreg(LDE_IF_ID, LDE_REPC_OFFSET, reg16) ;
1364
1365
    _dwt_configlde(prfIndex);
1366
1367
    // Configure PLL2/RF PLL block CFG/TUNE (for a given channel)
1368
    dwt_write32bitoffsetreg(FS_CTRL_ID, FS_PLLCFG_OFFSET, fs_pll_cfg[chan_idx[chan]]);
1369
    dwt_write8bitoffsetreg(FS_CTRL_ID, FS_PLLTUNE_OFFSET, fs_pll_tune[chan_idx[chan]]);
1370
1371
    // Configure RF RX blocks (for specified channel/bandwidth)
1372
    dwt_write8bitoffsetreg(RF_CONF_ID, RF_RXCTRLH_OFFSET, rx_config[bw]);
1373
1374
    // Configure RF TX blocks (for specified channel and PRF)
1375
    // Configure RF TX control
1376
    dwt_write32bitoffsetreg(RF_CONF_ID, RF_TXCTRL_OFFSET, tx_config[chan_idx[chan]]);
1377
1378
    // Configure the baseband parameters (for specified PRF, bit rate, PAC, and SFD settings)
1379
    // DTUNE0
1380
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE0b_OFFSET, sftsh[config->dataRate][config->nsSFD]);
1381
1382
    // DTUNE1
1383
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1a_OFFSET, dtune1[prfIndex]);
1384
1385
    if(config->dataRate == DWT_BR_110K)
1386
    {
1387
        dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_110K);
1388
    }
1389
    else
1390
    {
1391
        if(config->txPreambLength == DWT_PLEN_64)
1392
        {
1393
            dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_6M8_PRE64);
1394
            dwt_write8bitoffsetreg(DRX_CONF_ID, DRX_TUNE4H_OFFSET, DRX_TUNE4H_PRE64);
1395
        }
1396
        else
1397
        {
1398
            dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_850K_6M8);
1399
            dwt_write8bitoffsetreg(DRX_CONF_ID, DRX_TUNE4H_OFFSET, DRX_TUNE4H_PRE128PLUS);
1400
        }
1401
    }
1402
1403
    // DTUNE2
1404
    dwt_write32bitoffsetreg(DRX_CONF_ID, DRX_TUNE2_OFFSET, digital_bb_config[prfIndex][config->rxPAC]);
1405
1406
    // DTUNE3 (SFD timeout)
1407
    // Don't allow 0 - SFD timeout will always be enabled
1408
    if(config->sfdTO == 0)
1409
    {
1410
        config->sfdTO = DWT_SFDTOC_DEF;
1411
    }
1412
    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_SFDTOC_OFFSET, config->sfdTO);
1413
1414
    // Configure AGC parameters
1415
    dwt_write32bitoffsetreg( AGC_CFG_STS_ID, 0xC, agc_config.lo32);
1416
    dwt_write16bitoffsetreg( AGC_CFG_STS_ID, 0x4, agc_config.target[prfIndex]);
1417
1418
    // Set (non-standard) user SFD for improved performance,
1419
    if(config->nsSFD)
1420
    {
1421
        // Write non standard (DW) SFD length
1422
        dwt_write8bitoffsetreg(USR_SFD_ID, 0x00, dwnsSFDlen[config->dataRate]);
1423
        nsSfd_result = 3 ;
1424
        useDWnsSFD = 1 ;
1425
    }
1426
    regval =  (CHAN_CTRL_TX_CHAN_MASK & (chan << CHAN_CTRL_TX_CHAN_SHIFT)) | // Transmit Channel
1427
              (CHAN_CTRL_RX_CHAN_MASK & (chan << CHAN_CTRL_RX_CHAN_SHIFT)) | // Receive Channel
1428
              (CHAN_CTRL_RXFPRF_MASK & (config->prf << CHAN_CTRL_RXFPRF_SHIFT)) | // RX PRF
1429
              ((CHAN_CTRL_TNSSFD|CHAN_CTRL_RNSSFD) & (nsSfd_result << CHAN_CTRL_TNSSFD_SHIFT)) | // nsSFD enable RX&TX
1430
              (CHAN_CTRL_DWSFD & (useDWnsSFD << CHAN_CTRL_DWSFD_SHIFT)) | // Use DW nsSFD
1431
              (CHAN_CTRL_TX_PCOD_MASK & (config->txCode << CHAN_CTRL_TX_PCOD_SHIFT)) | // TX Preamble Code
1432
              (CHAN_CTRL_RX_PCOD_MASK & (config->rxCode << CHAN_CTRL_RX_PCOD_SHIFT)) ; // RX Preamble Code
1433
1434
    dwt_write32bitreg(CHAN_CTRL_ID,regval) ;
1435
1436
    // Set up TX Preamble Size, PRF and Data Rate
1437
    pdw1000local->txFCTRL = ((config->txPreambLength | config->prf) << TX_FCTRL_TXPRF_SHFT) | (config->dataRate << TX_FCTRL_TXBR_SHFT);
1438
    dwt_write32bitreg(TX_FCTRL_ID, pdw1000local->txFCTRL);
1439
1440
    // 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
1441
    // SYS_CTRL write below works around this issue, by simultaneously initiating and aborting a transmission, which correctly initialises the SFD
1442
    // after its configuration or reconfiguration.
1443
    // 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).
1444
    dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, SYS_CTRL_TXSTRT | SYS_CTRL_TRXOFF); // Request TX start and TRX off at the same time
1445
} // end dwt_configure()
1446
1447
/*! ------------------------------------------------------------------------------------------------------------------
1448
 * @fn dwt_setrxantennadelay()
1449
 *
1450
 * @brief This API function writes the antenna delay (in time units) to RX registers
1451
 *
1452
 * input parameters:
1453
 * @param rxDelay - this is the total (RX) antenna delay value, which
1454
 *                          will be programmed into the RX register
1455
 *
1456
 * output parameters
1457
 *
1458
 * no return value
1459
 */
1460
void dwt_setrxantennadelay(uint16_t rxDelay)
1461
{
1462
    // Set the RX antenna delay for auto TX timestamp adjustment
1463
    dwt_write16bitoffsetreg(LDE_IF_ID, LDE_RXANTD_OFFSET, rxDelay);
1464
}
1465
1466
/*! ------------------------------------------------------------------------------------------------------------------
1467
 * @fn dwt_settxantennadelay()
1468
 *
1469
 * @brief This API function writes the antenna delay (in time units) to TX registers
1470
 *
1471
 * input parameters:
1472
 * @param txDelay - this is the total (TX) antenna delay value, which
1473
 *                          will be programmed into the TX delay register
1474
 *
1475
 * output parameters
1476
 *
1477
 * no return value
1478
 */
1479
void dwt_settxantennadelay(uint16_t txDelay)
1480
{
1481
    // Set the TX antenna delay for auto TX timestamp adjustment
1482
    dwt_write16bitoffsetreg(TX_ANTD_ID, TX_ANTD_OFFSET, txDelay);
1483
}
1484
1485
/*! ------------------------------------------------------------------------------------------------------------------
1486
 * @fn dwt_writetxdata()
1487
 *
1488
 * @brief This API function writes the supplied TX data into the DW1000's
1489
 * TX buffer.  The input parameters are the data length in bytes and a pointer
1490
 * to those data bytes.
1491
 *
1492
 * input parameters
1493
 * @param txFrameLength  - This is the total frame length, including the two byte CRC.
1494
 *                         Note: this is the length of TX message (including the 2 byte CRC) - max is 1023
1495
 *                         standard PHR mode allows up to 127 bytes
1496
 *                         if > 127 is programmed, DWT_PHRMODE_EXT needs to be set in the phrMode configuration
1497
 *                         see dwt_configure function
1498
 * @param txFrameBytes   - Pointer to the user’s buffer containing the data to send.
1499
 * @param txBufferOffset - This specifies an offset in the DW1000’s TX Buffer at which to start writing data.
1500
 *
1501
 * output parameters
1502
 *
1503
 * returns DWT_SUCCESS for success, or DWT_ERROR for error
1504
 */
1505
int dwt_writetxdata(uint16_t txFrameLength, uint8_t *txFrameBytes, uint16_t txBufferOffset)
1506
{
1507
#ifdef DWT_API_ERROR_CHECK
1508
    assert(txFrameLength >= 2);
1509
    assert((pdw1000local->longFrames && (txFrameLength <= 1023)) || (txFrameLength <= 127));
1510
    assert((txBufferOffset + txFrameLength) <= 1024);
1511
#endif