Statistics
| Branch: | Tag: | Revision:

amiro-lld / drivers / DW1000 / v1 / alld_DW1000.c @ f69ec051

History | View | Annotate | Download (150.876 KB)

</
1 69a601a5 Cung Sang
/*
2
AMiRo-LLD is a compilation of low-level hardware drivers for the Autonomous Mini Robot (AMiRo) platform.
3 f69ec051 Thomas Schöpping
Copyright (C) 2016..2020  Thomas Schöpping et al.
4 69a601a5 Cung Sang

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 9466e34d Thomas Schöpping
#include <alld_DW1000_regs.h>
33 69a601a5 Cung Sang
#include <assert.h>
34
#include <string.h>
35
#include <stdlib.h>
36
#include <math.h>
37
38
39 33f54213 Cung Sang
// 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 69a601a5 Cung Sang
// 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 26dead12 Cung Sang
    int rangeint25cm = (int) ((double)range * 4.00) ;       // convert range to integer number of 25cm values.
866 69a601a5 Cung Sang
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 26dead12 Cung Sang
    mOffset = (double) cmoffseti ;                                       // offset result in centimmetres
912 69a601a5 Cung Sang
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 26dead12 Cung Sang
int32_t _dwt_otpprogword32(uint32_t data, uint16_t address);
934 69a601a5 Cung Sang
// 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 33f54213 Cung Sang
int dwt_initialise(const uint16_t config, DW1000Driver* drv)
1002 69a601a5 Cung Sang
{
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 26dead12 Cung Sang
    pdw1000local->driver = drv;
1016 69a601a5 Cung Sang
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
/*! ------------------------------------------------------------------------------------------------------------------