Revision 26dead12
| include/DW1000/v1/alld_dw1000_v1.h | ||
|---|---|---|
| 62 | 62 |
#define NUM_CH_SUPPORTED 8 //supported channels are '0', 1, 2, 3, 4, 5, '6', 7 |
| 63 | 63 |
#define PCODES 25 //supported preamble codes |
| 64 | 64 |
|
| 65 |
#define NUM_16M_OFFSET (37) |
|
| 66 |
#define NUM_16M_OFFSETWB (68) |
|
| 67 |
#define NUM_64M_OFFSET (26) |
|
| 68 |
#define NUM_64M_OFFSETWB (59) |
|
| 69 |
|
|
| 70 |
#define SPIBUFFLEN (32) |
|
| 71 |
|
|
| 72 |
|
|
| 65 | 73 |
extern const uint8_t chan_idx[NUM_CH_SUPPORTED]; |
| 74 |
extern const uint16_t lde_replicaCoeff[PCODES]; |
|
| 75 |
extern const uint8_t chan_idxnb[NUM_CH_SUPPORTED]; |
|
| 76 |
extern const uint8_t chan_idxwb[NUM_CH_SUPPORTED]; |
|
| 77 |
extern const uint8_t range25cm16PRFnb[4][NUM_16M_OFFSET]; |
|
| 78 |
extern const uint8_t range25cm16PRFwb[2][NUM_16M_OFFSETWB]; |
|
| 79 |
extern const uint8_t range25cm64PRFnb[4][NUM_64M_OFFSET]; |
|
| 80 |
extern const uint8_t range25cm64PRFwb[2][NUM_64M_OFFSETWB]; |
|
| 66 | 81 |
|
| 67 | 82 |
|
| 68 | 83 |
/** |
| ... | ... | |
| 74 | 89 |
const apalControlGpio_t* gpio_reset; /**< @brief The GPIO indicating reset sig*/ |
| 75 | 90 |
// const apalGpio_t* gpio_exti; /**< @brief The GPIO indicating external interrupt */ |
| 76 | 91 |
// const apalGpio_t* gpio_reset; /**< @brief The GPIO indicating reset sig*/ |
| 77 |
/* TODO: better apalControlGpio_t instead of apalGpio_t ? */ |
|
| 78 |
/* TODO: EXTI, GPIO (RESET) */ |
|
| 79 | 92 |
} DW1000Driver; |
| 80 | 93 |
|
| 81 | 94 |
|
| ... | ... | |
| 238 | 251 |
uint8_t nsSFD ; //!< Boolean should we use non-standard SFD for better performance |
| 239 | 252 |
uint8_t dataRate ; //!< Data Rate {DWT_BR_110K, DWT_BR_850K or DWT_BR_6M8}
|
| 240 | 253 |
uint8_t phrMode ; //!< PHR mode {0x0 - standard DWT_PHRMODE_STD, 0x3 - extended frames DWT_PHRMODE_EXT}
|
| 241 |
uint8_t smartPowerEn ; //!< Smart Power enable / disable (TODO: Added smartPowerEn in this struct )
|
|
| 254 |
uint8_t smartPowerEn ; //!< Smart Power enable / disable |
|
| 242 | 255 |
uint16_t sfdTO ; //!< SFD timeout value (in symbols) |
| 243 | 256 |
} dwt_config_t ; |
| 244 | 257 |
|
| ... | ... | |
| 477 | 490 |
* |
| 478 | 491 |
* returns DWT_SUCCESS for success, or DWT_ERROR for error |
| 479 | 492 |
*/ |
| 480 |
//int dwt_initialise(uint16_t config) ; // TODO |
|
| 481 | 493 |
int dwt_initialise(uint16_t config, DW1000Driver* drv) ; |
| 482 | 494 |
|
| 483 | 495 |
/*! ------------------------------------------------------------------------------------------------------------------ |
| include/DW1000/v1/deca_instance_v1.h | ||
|---|---|---|
| 151 | 151 |
#define RX_RESPONSE1_TURNAROUND_6M81 (300) //takes about 100 us for response to come back |
| 152 | 152 |
#define RX_RESPONSE1_TURNAROUND_110K (300) //takes about 100 us for response to come back |
| 153 | 153 |
|
| 154 |
/* For TAG HAL F1 */ |
|
| 155 |
//#define RX_RESPONSE1_TURNAROUND (200) //takes about 200 us for the 1st response to come back (from A0) |
|
| 156 |
//#define RX_RESPONSE1_TURNAROUND_6M81 (300) //takes about 100 us for response to come back |
|
| 157 |
//#define RX_RESPONSE1_TURNAROUND_110K (18700) //takes about 100 us for response to come back |
|
| 158 |
|
|
| 159 |
/* For ANCHOR HAL F1 */ |
|
| 160 |
//#define RX_RESPONSE1_TURNAROUND (300) //takes about 200 us for the 1st response to come back (from A0) |
|
| 161 |
//#define RX_RESPONSE1_TURNAROUND_6M81 (300) //takes about 100 us for response to come back |
|
| 162 |
//#define RX_RESPONSE1_TURNAROUND_110K (4700) //takes about 100 us for response to come back |
|
| 163 |
|
|
| 164 | 154 |
//Tag will range to 3 or 4 anchors |
| 165 | 155 |
//Each ranging exchange will consist of minimum of 3 messages (Poll, Response, Final) |
| 166 | 156 |
//and a maximum of 6 messages (Poll, Response x 4, Final) |
| ... | ... | |
| 248 | 238 |
uint8_t fcs[2] ; // 125-126 we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes. |
| 249 | 239 |
} srd_msg_dssl ; |
| 250 | 240 |
|
| 251 |
typedef struct |
|
| 241 |
typedef struct __attribute__((packed))
|
|
| 252 | 242 |
{
|
| 253 | 243 |
uint8_t channelNumber ; // valid range is 1 to 11 |
| 254 | 244 |
uint8_t preambleCode ; // 00 = use NS code, 1 to 24 selects code |
| ... | ... | |
| 279 | 269 |
//in turn and the event queued up before the instance processed the TX event. |
| 280 | 270 |
#define MAX_EVENT_NUMBER (6) |
| 281 | 271 |
|
| 282 |
typedef struct |
|
| 272 |
typedef struct __attribute__((packed))
|
|
| 283 | 273 |
{
|
| 284 | 274 |
uint8_t type; // event type - if 0 there is no event in the queue |
| 285 | 275 |
uint8_t type_save; // holds the event type - does not clear (used to show what event has been processed) |
| ... | ... | |
| 307 | 297 |
uint8_t gotit; //stores the instance function which processed the event (used for debug) |
| 308 | 298 |
}event_data_t ; |
| 309 | 299 |
|
| 310 |
extern event_data_t dw_event_g; // TODO
|
|
| 300 |
extern event_data_t dw_event_g; |
|
| 311 | 301 |
|
| 312 | 302 |
// TX power and PG delay configuration structure |
| 313 |
typedef struct {
|
|
| 303 |
typedef struct __attribute__((packed)) {
|
|
| 314 | 304 |
uint8_t PGdelay; |
| 315 | 305 |
|
| 316 | 306 |
//TX POWER |
| ... | ... | |
| 321 | 311 |
uint32_t txPwr[2]; // |
| 322 | 312 |
}tx_struct; |
| 323 | 313 |
|
| 324 |
typedef struct |
|
| 314 |
typedef struct __attribute__((packed))
|
|
| 325 | 315 |
{
|
| 326 | 316 |
INST_MODE mode; //instance mode (tag or anchor) |
| 327 | 317 |
|
| ... | ... | |
| 426 | 416 |
int newRange; //flag set when there is a new range to report TOF_REPORT_A2A or TOF_REPORT_T2A |
| 427 | 417 |
int newRangeAncAddress; //last 4 bytes of anchor address - used for printing/range output display |
| 428 | 418 |
int newRangeTagAddress; //last 4 bytes of tag address - used for printing/range output display |
| 429 |
int newRangeTime;
|
|
| 419 |
uint32_t newRangeTime;
|
|
| 430 | 420 |
|
| 431 | 421 |
uint8_t gatewayAnchor ; //set to TRUE = 1 if anchor address == GATEWAY_ANCHOR_ADDR |
| 432 | 422 |
|
| ... | ... | |
| 470 | 460 |
void instance_close(void); |
| 471 | 461 |
// Call init, then call config, then call run. call close when finished |
| 472 | 462 |
// initialise the instance (application) structures and DW1000 device |
| 473 |
// int instance_init(void); |
|
| 474 |
int instance_init(DW1000Driver* drv); //TODO |
|
| 463 |
int instance_init(DW1000Driver* drv); |
|
| 475 | 464 |
|
| 476 | 465 |
// configure the instance and DW1000 device |
| 477 | 466 |
void instance_config(instanceConfig_t *config, sfConfig_t *sfconfig, DW1000Driver* drv) ; |
| ... | ... | |
| 490 | 479 |
// configure TX/RX callback functions that are called from DW1000 ISR |
| 491 | 480 |
void instance_rxcallback(const dwt_cb_data_t *rxd); |
| 492 | 481 |
void instance_txcallback(const dwt_cb_data_t *txd); |
| 493 |
/*TODO: add callbacks */ |
|
| 494 | 482 |
void instance_rxtimeoutcallback(const dwt_cb_data_t *rxd); |
| 495 | 483 |
void instance_rxerrorcallback(const dwt_cb_data_t *rxd); |
| 496 | 484 |
|
| ... | ... | |
| 525 | 513 |
int instancenewrangetagadd(void); |
| 526 | 514 |
int instancenewrangepolltim(void); |
| 527 | 515 |
int instancenewrange(void); |
| 528 |
int instancenewrangetim(void);
|
|
| 516 |
uint32_t instancenewrangetim(void);
|
|
| 529 | 517 |
|
| 530 | 518 |
uint64_t convertmicrosectodevicetimeu (double microsecu); |
| 531 | 519 |
double convertdevicetimetosec(int32_t dt); |
| ... | ... | |
| 562 | 550 |
|
| 563 | 551 |
void instance_notify_DW1000_inIDLE(int idle); |
| 564 | 552 |
|
| 565 |
|
|
| 566 |
// TODO: The following Functions are added in user applciation (previously on the API ) |
|
| 567 |
|
|
| 568 | 553 |
double dwt_getrangebias(uint8_t chan, float range, uint8_t prf); |
| 569 | 554 |
|
| 570 | 555 |
uint32_t dwt_getotptxpower(uint8_t prf, uint8_t chan); |
| ... | ... | |
| 573 | 558 |
|
| 574 | 559 |
uint16_t dwt_readantennadelay(uint8_t prf); |
| 575 | 560 |
|
| 576 |
|
|
| 577 |
/* End of user application functions (Previously on API) */ |
|
| 578 |
|
|
| 579 |
|
|
| 580 | 561 |
// configure TX power |
| 581 | 562 |
void instanceconfigtxpower(uint32_t txpower); |
| 582 | 563 |
void instancesettxpower(void); |
| source/DW1000/v1/alld_dw1000_v1.c | ||
|---|---|---|
| 32 | 32 |
#if (defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)) || defined(__DOXYGEN__) |
| 33 | 33 |
|
| 34 | 34 |
#include <v1/alld_dw1000_regs_v1.h> |
| 35 |
#include <aos_thread.h> |
|
| 36 | 35 |
#include <assert.h> |
| 37 | 36 |
#include <string.h> |
| 38 | 37 |
#include <stdlib.h> |
| ... | ... | |
| 241 | 240 |
}; |
| 242 | 241 |
|
| 243 | 242 |
|
| 244 |
#define NUM_16M_OFFSET (37) |
|
| 245 |
#define NUM_16M_OFFSETWB (68) |
|
| 246 |
#define NUM_64M_OFFSET (26) |
|
| 247 |
#define NUM_64M_OFFSETWB (59) |
|
| 248 |
|
|
| 249 | 243 |
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
|
| 250 | 244 |
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
|
| 251 | 245 |
|
| ... | ... | |
| 845 | 839 |
}; // end range25cm64PRFwb |
| 846 | 840 |
|
| 847 | 841 |
|
| 848 |
|
|
| 849 |
|
|
| 850 |
|
|
| 851 | 842 |
/*! ------------------------------------------------------------------------------------------------------------------ |
| 852 | 843 |
* Function: dwt_getrangebias() |
| 853 | 844 |
* |
| ... | ... | |
| 873 | 864 |
|
| 874 | 865 |
// NB: note we may get some small negitive values e.g. up to -50 cm. |
| 875 | 866 |
|
| 876 |
int rangeint25cm = (int) (range * 4.00) ; // convert range to integer number of 25cm values. |
|
| 867 |
int rangeint25cm = (int) ((double)range * 4.00) ; // convert range to integer number of 25cm values.
|
|
| 877 | 868 |
|
| 878 | 869 |
if (rangeint25cm > 255) rangeint25cm = 255 ; // make sure it matches largest value in table (all tables end in 255 !!!!) |
| 879 | 870 |
|
| ... | ... | |
| 919 | 910 |
} // end else |
| 920 | 911 |
|
| 921 | 912 |
|
| 922 |
mOffset = (float) cmoffseti ; // offset result in centimmetres
|
|
| 913 |
mOffset = (double) cmoffseti ; // offset result in centimmetres
|
|
| 923 | 914 |
|
| 924 | 915 |
mOffset *= 0.01 ; // convert to metres |
| 925 | 916 |
|
| 926 | 917 |
return (mOffset) ; |
| 927 | 918 |
} |
| 928 | 919 |
|
| 929 |
|
|
| 930 |
|
|
| 931 | 920 |
// ------------------------------------------------------------------------------------------------------------------- |
| 932 | 921 |
// |
| 933 | 922 |
// Internal functions for controlling and configuring the device |
| ... | ... | |
| 943 | 932 |
// Read non-volatile memory |
| 944 | 933 |
uint32_t _dwt_otpread(uint32_t address); |
| 945 | 934 |
// Program the non-volatile memory |
| 946 |
uint32_t _dwt_otpprogword32(uint32_t data, uint16_t address);
|
|
| 935 |
int32_t _dwt_otpprogword32(uint32_t data, uint16_t address); |
|
| 947 | 936 |
// Upload the device configuration into always on memory |
| 948 | 937 |
void _dwt_aonarrayupload(void); |
| 949 | 938 |
// ------------------------------------------------------------------------------------------------------------------- |
| ... | ... | |
| 1025 | 1014 |
pdw1000local->cbRxTo = NULL; |
| 1026 | 1015 |
pdw1000local->cbRxErr = NULL; |
| 1027 | 1016 |
|
| 1028 |
pdw1000local->driver = drv; // TODO:
|
|
| 1017 |
pdw1000local->driver = drv; |
|
| 1029 | 1018 |
|
| 1030 | 1019 |
// Read and validate device ID return -1 if not recognised |
| 1031 | 1020 |
if (DWT_DEVICE_ID != dwt_readdevid()) // MP IC ONLY (i.e. DW1000) FOR THIS CODE |
| ... | ... | |
| 1346 | 1335 |
pdw1000local->longFrames = config->phrMode ; |
| 1347 | 1336 |
|
| 1348 | 1337 |
pdw1000local->sysCFGreg &= ~SYS_CFG_PHR_MODE_11; |
| 1349 |
pdw1000local->sysCFGreg |= (SYS_CFG_PHR_MODE_11 & (config->phrMode << SYS_CFG_PHR_MODE_SHFT)); |
|
| 1338 |
pdw1000local->sysCFGreg |= (SYS_CFG_PHR_MODE_11 & (uint32_t)(config->phrMode << SYS_CFG_PHR_MODE_SHFT));
|
|
| 1350 | 1339 |
|
| 1351 | 1340 |
dwt_write32bitreg(SYS_CFG_ID,pdw1000local->sysCFGreg) ; |
| 1352 | 1341 |
// Set the lde_replicaCoeff |
| ... | ... | |
| 1413 | 1402 |
nsSfd_result = 3 ; |
| 1414 | 1403 |
useDWnsSFD = 1 ; |
| 1415 | 1404 |
} |
| 1416 |
regval = (CHAN_CTRL_TX_CHAN_MASK & (chan << CHAN_CTRL_TX_CHAN_SHIFT)) | // Transmit Channel |
|
| 1417 |
(CHAN_CTRL_RX_CHAN_MASK & (chan << CHAN_CTRL_RX_CHAN_SHIFT)) | // Receive Channel |
|
| 1418 |
(CHAN_CTRL_RXFPRF_MASK & (config->prf << CHAN_CTRL_RXFPRF_SHIFT)) | // RX PRF |
|
| 1419 |
((CHAN_CTRL_TNSSFD|CHAN_CTRL_RNSSFD) & (nsSfd_result << CHAN_CTRL_TNSSFD_SHIFT)) | // nsSFD enable RX&TX |
|
| 1420 |
(CHAN_CTRL_DWSFD & (useDWnsSFD << CHAN_CTRL_DWSFD_SHIFT)) | // Use DW nsSFD |
|
| 1421 |
(CHAN_CTRL_TX_PCOD_MASK & (config->txCode << CHAN_CTRL_TX_PCOD_SHIFT)) | // TX Preamble Code |
|
| 1422 |
(CHAN_CTRL_RX_PCOD_MASK & (config->rxCode << CHAN_CTRL_RX_PCOD_SHIFT)) ; // RX Preamble Code |
|
| 1405 |
regval = (CHAN_CTRL_TX_CHAN_MASK & (uint32_t)(chan << CHAN_CTRL_TX_CHAN_SHIFT)) | // Transmit Channel
|
|
| 1406 |
(CHAN_CTRL_RX_CHAN_MASK & (uint32_t)(chan << CHAN_CTRL_RX_CHAN_SHIFT)) | // Receive Channel
|
|
| 1407 |
(CHAN_CTRL_RXFPRF_MASK & (uint32_t)(config->prf << CHAN_CTRL_RXFPRF_SHIFT)) | // RX PRF
|
|
| 1408 |
((CHAN_CTRL_TNSSFD|CHAN_CTRL_RNSSFD) & (uint32_t)(nsSfd_result << CHAN_CTRL_TNSSFD_SHIFT)) | // nsSFD enable RX&TX
|
|
| 1409 |
(CHAN_CTRL_DWSFD & (uint32_t)(useDWnsSFD << CHAN_CTRL_DWSFD_SHIFT)) | // Use DW nsSFD
|
|
| 1410 |
(CHAN_CTRL_TX_PCOD_MASK & (uint32_t)(config->txCode << CHAN_CTRL_TX_PCOD_SHIFT)) | // TX Preamble Code
|
|
| 1411 |
(CHAN_CTRL_RX_PCOD_MASK & (uint32_t)(config->rxCode << CHAN_CTRL_RX_PCOD_SHIFT)) ; // RX Preamble Code
|
|
| 1423 | 1412 |
|
| 1424 | 1413 |
dwt_write32bitreg(CHAN_CTRL_ID,regval) ; |
| 1425 | 1414 |
|
| 1426 | 1415 |
// Set up TX Preamble Size, PRF and Data Rate |
| 1427 |
pdw1000local->txFCTRL = ((config->txPreambLength | config->prf) << TX_FCTRL_TXPRF_SHFT) | (config->dataRate << TX_FCTRL_TXBR_SHFT);
|
|
| 1416 |
pdw1000local->txFCTRL = (uint32_t)(((config->txPreambLength | config->prf) << TX_FCTRL_TXPRF_SHFT) | (config->dataRate << TX_FCTRL_TXBR_SHFT));
|
|
| 1428 | 1417 |
dwt_write32bitreg(TX_FCTRL_ID, pdw1000local->txFCTRL); |
| 1429 | 1418 |
|
| 1430 | 1419 |
// 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 |
| ... | ... | |
| 1538 | 1527 |
|
| 1539 | 1528 |
// Write the frame length to the TX frame control register |
| 1540 | 1529 |
// pdw1000local->txFCTRL has kept configured bit rate information |
| 1541 |
uint32_t reg32 = pdw1000local->txFCTRL | txFrameLength | (txBufferOffset << TX_FCTRL_TXBOFFS_SHFT) | (ranging << TX_FCTRL_TR_SHFT);
|
|
| 1530 |
uint32_t reg32 = pdw1000local->txFCTRL | txFrameLength | (uint16_t)(txBufferOffset << TX_FCTRL_TXBOFFS_SHFT) | (uint16_t)(ranging << TX_FCTRL_TR_SHFT);
|
|
| 1542 | 1531 |
dwt_write32bitreg(TX_FCTRL_ID, reg32); |
| 1543 | 1532 |
} // end dwt_writetxfctrl() |
| 1544 | 1533 |
|
| ... | ... | |
| 1789 | 1778 |
// Write message header selecting WRITE operation and addresses as appropriate (this is one to three bytes long) |
| 1790 | 1779 |
if (index == 0) // For index of 0, no sub-index is required |
| 1791 | 1780 |
{
|
| 1792 |
header[cnt++] = 0x80 | recordNumber ; // Bit-7 is WRITE operation, bit-6 zero=NO sub-addressing, bits 5-0 is reg file id |
|
| 1781 |
header[cnt++] = 0x80 | (uint8_t)recordNumber ; // Bit-7 is WRITE operation, bit-6 zero=NO sub-addressing, bits 5-0 is reg file id
|
|
| 1793 | 1782 |
} |
| 1794 | 1783 |
else |
| 1795 | 1784 |
{
|
| 1796 | 1785 |
#ifdef DWT_API_ERROR_CHECK |
| 1797 | 1786 |
assert((index <= 0x7FFF) && ((index + length) <= 0x7FFF)); // Index and sub-addressable area are limited to 15-bits. |
| 1798 | 1787 |
#endif |
| 1799 |
header[cnt++] = 0xC0 | recordNumber ; // Bit-7 is WRITE operation, bit-6 one=sub-address follows, bits 5-0 is reg file id |
|
| 1788 |
header[cnt++] = 0xC0 | (uint8_t)recordNumber ; // Bit-7 is WRITE operation, bit-6 one=sub-address follows, bits 5-0 is reg file id
|
|
| 1800 | 1789 |
|
| 1801 | 1790 |
if (index <= 127) // For non-zero index < 127, just a single sub-index byte is required |
| 1802 | 1791 |
{
|
| ... | ... | |
| 1810 | 1799 |
} |
| 1811 | 1800 |
|
| 1812 | 1801 |
// Write it to the SPI |
| 1813 |
writetospi(cnt,header,length,buffer); |
|
| 1802 |
writetospi((uint16_t)cnt,header,length,buffer);
|
|
| 1814 | 1803 |
} // end dwt_writetodevice() |
| 1815 | 1804 |
|
| 1816 | 1805 |
/*! ------------------------------------------------------------------------------------------------------------------ |
| ... | ... | |
| 1874 | 1863 |
} |
| 1875 | 1864 |
|
| 1876 | 1865 |
// Do the read from the SPI |
| 1877 |
readfromspi(cnt, header, length, buffer); |
|
| 1866 |
readfromspi((uint16_t)cnt, header, length, buffer);
|
|
| 1878 | 1867 |
} // end dwt_readfromdevice() |
| 1879 | 1868 |
|
| 1880 | 1869 |
|
| ... | ... | |
| 1898 | 1887 |
int j ; |
| 1899 | 1888 |
uint8_t buffer[4] ; |
| 1900 | 1889 |
|
| 1901 |
dwt_readfromdevice(regFileID,regOffset,4,buffer); // Read 4 bytes (32-bits) register into buffer
|
|
| 1890 |
dwt_readfromdevice((uint16_t)regFileID, (uint16_t)regOffset,4,buffer); // Read 4 bytes (32-bits) register into buffer
|
|
| 1902 | 1891 |
|
| 1903 | 1892 |
for (j = 3 ; j >= 0 ; j --) |
| 1904 | 1893 |
{
|
| ... | ... | |
| 1926 | 1915 |
uint16_t regval = 0 ; |
| 1927 | 1916 |
uint8_t buffer[2] ; |
| 1928 | 1917 |
|
| 1929 |
dwt_readfromdevice(regFileID,regOffset,2,buffer); // Read 2 bytes (16-bits) register into buffer
|
|
| 1918 |
dwt_readfromdevice((uint16_t)regFileID, (uint16_t)regOffset,2,buffer); // Read 2 bytes (16-bits) register into buffer
|
|
| 1930 | 1919 |
|
| 1931 |
regval = (buffer[1] << 8) + buffer[0] ;
|
|
| 1920 |
regval = (uint16_t)((buffer[1] << 8) + buffer[0] );
|
|
| 1932 | 1921 |
return regval ; |
| 1933 | 1922 |
|
| 1934 | 1923 |
} // end dwt_read16bitoffsetreg() |
| ... | ... | |
| 1950 | 1939 |
{
|
| 1951 | 1940 |
uint8_t regval; |
| 1952 | 1941 |
|
| 1953 |
dwt_readfromdevice(regFileID, regOffset, 1, ®val);
|
|
| 1942 |
dwt_readfromdevice((uint16_t)regFileID, (uint16_t)regOffset, 1, ®val);
|
|
| 1954 | 1943 |
|
| 1955 | 1944 |
return regval ; |
| 1956 | 1945 |
} |
| ... | ... | |
| 1971 | 1960 |
*/ |
| 1972 | 1961 |
void dwt_write8bitoffsetreg(int regFileID, int regOffset, uint8_t regval) |
| 1973 | 1962 |
{
|
| 1974 |
dwt_writetodevice(regFileID, regOffset, 1, ®val);
|
|
| 1963 |
dwt_writetodevice((uint16_t)regFileID, (uint16_t)regOffset, 1, ®val);
|
|
| 1975 | 1964 |
} |
| 1976 | 1965 |
|
| 1977 | 1966 |
/*! ------------------------------------------------------------------------------------------------------------------ |
| ... | ... | |
| 1995 | 1984 |
buffer[0] = regval & 0xFF; |
| 1996 | 1985 |
buffer[1] = regval >> 8 ; |
| 1997 | 1986 |
|
| 1998 |
dwt_writetodevice(regFileID,regOffset,2,buffer);
|
|
| 1987 |
dwt_writetodevice((uint16_t)regFileID, (uint16_t)regOffset,2,buffer);
|
|
| 1999 | 1988 |
} // end dwt_write16bitoffsetreg() |
| 2000 | 1989 |
|
| 2001 | 1990 |
/*! ------------------------------------------------------------------------------------------------------------------ |
| ... | ... | |
| 2023 | 2012 |
regval >>= 8 ; |
| 2024 | 2013 |
} |
| 2025 | 2014 |
|
| 2026 |
dwt_writetodevice(regFileID,regOffset,4,buffer);
|
|
| 2015 |
dwt_writetodevice((uint16_t)regFileID,(uint16_t)regOffset,4,buffer);
|
|
| 2027 | 2016 |
} // end dwt_write32bitoffsetreg() |
| 2028 | 2017 |
|
| 2029 | 2018 |
/*! ------------------------------------------------------------------------------------------------------------------ |
| ... | ... | |
| 2157 | 2146 |
|
| 2158 | 2147 |
for(i=0; i<length; i++) |
| 2159 | 2148 |
{
|
| 2160 |
array[i] = _dwt_otpread(address + i) ; |
|
| 2149 |
array[i] = _dwt_otpread(address + (uint32_t)i) ;
|
|
| 2161 | 2150 |
} |
| 2162 | 2151 |
|
| 2163 | 2152 |
_dwt_enableclocks(ENABLE_ALL_SEQ); // Restore system clock to PLL |
| ... | ... | |
| 2182 | 2171 |
uint32_t ret_data; |
| 2183 | 2172 |
|
| 2184 | 2173 |
// Write the address |
| 2185 |
dwt_write16bitoffsetreg(OTP_IF_ID, OTP_ADDR, address); |
|
| 2174 |
dwt_write16bitoffsetreg(OTP_IF_ID, OTP_ADDR, (uint16_t)address);
|
|
| 2186 | 2175 |
|
| 2187 | 2176 |
// Perform OTP Read - Manual read mode has to be set |
| 2188 | 2177 |
dwt_write8bitoffsetreg(OTP_IF_ID, OTP_CTRL, OTP_CTRL_OTPREAD | OTP_CTRL_OTPRDEN); |
| ... | ... | |
| 2215 | 2204 |
* |
| 2216 | 2205 |
* returns DWT_SUCCESS for success, or DWT_ERROR for error |
| 2217 | 2206 |
*/ |
| 2218 |
uint32_t _dwt_otpsetmrregs(int mode)
|
|
| 2207 |
int32_t _dwt_otpsetmrregs(int mode) |
|
| 2219 | 2208 |
{
|
| 2220 | 2209 |
uint8_t rd_buf[4]; |
| 2221 | 2210 |
uint8_t wr_buf[4]; |
| ... | ... | |
| 2381 | 2370 |
* |
| 2382 | 2371 |
* returns DWT_SUCCESS for success, or DWT_ERROR for error |
| 2383 | 2372 |
*/ |
| 2384 |
uint32_t _dwt_otpprogword32(uint32_t data, uint16_t address)
|
|
| 2373 |
int32_t _dwt_otpprogword32(uint32_t data, uint16_t address) |
|
| 2385 | 2374 |
{
|
| 2386 | 2375 |
uint8_t rd_buf[1]; |
| 2387 | 2376 |
uint8_t wr_buf[4]; |
| ... | ... | |
| 3538 | 3527 |
if (enable) |
| 3539 | 3528 |
{
|
| 3540 | 3529 |
/* Configure ON/OFF times and enable PLL2 on/off sequencing by SNIFF mode. */ |
| 3541 |
uint16_t sniff_reg = ((timeOff << 8) | timeOn) & RX_SNIFF_MASK; |
|
| 3530 |
uint16_t sniff_reg = (uint16_t)((timeOff << 8) | timeOn) & RX_SNIFF_MASK;
|
|
| 3542 | 3531 |
dwt_write16bitoffsetreg(RX_SNIFF_ID, RX_SNIFF_OFFSET, sniff_reg); |
| 3543 | 3532 |
pmsc_reg = dwt_read32bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET); |
| 3544 | 3533 |
pmsc_reg |= PMSC_CTRL0_PLL2_SEQ_EN; |
| ... | ... | |
| 4099 | 4088 |
wr_buf[0] = 0x00; // Clear SAR enable |
| 4100 | 4089 |
dwt_writetodevice(TX_CAL_ID, TC_SARL_SAR_C,1,wr_buf); |
| 4101 | 4090 |
|
| 4102 |
return ((temp_raw<<8)|(vbat_raw)); |
|
| 4091 |
return (uint16_t)((temp_raw<<8)|(vbat_raw));
|
|
| 4103 | 4092 |
} |
| 4104 | 4093 |
|
| 4105 | 4094 |
/*! ------------------------------------------------------------------------------------------------------------------ |
| ... | ... | |
| 4198 | 4187 |
curr_bw = curr_bw | bit_field; |
| 4199 | 4188 |
|
| 4200 | 4189 |
// Write bw setting to PG_DELAY register |
| 4201 |
dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGDELAY_OFFSET, curr_bw);
|
|
| 4190 |
dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGDELAY_OFFSET,(uint8_t)curr_bw);
|
|
| 4202 | 4191 |
|
| 4203 | 4192 |
// Set cal direction and time |
| 4204 | 4193 |
dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGCCTRL_OFFSET, TC_PGCCTRL_DIR_CONV | TC_PGCCTRL_TMEAS_MASK); |
| ... | ... | |
| 4284 | 4273 |
} |
| 4285 | 4274 |
} |
| 4286 | 4275 |
|
| 4287 |
new_da_attn = current_da_attn + da_attn_change; |
|
| 4288 |
new_mixer_gain = current_mixer_gain + mixer_gain_change; |
|
| 4276 |
new_da_attn = current_da_attn + (uint8_t)da_attn_change;
|
|
| 4277 |
new_mixer_gain = current_mixer_gain + (uint8_t)mixer_gain_change;
|
|
| 4289 | 4278 |
|
| 4290 | 4279 |
new_regval |= ((uint32_t) ((new_da_attn << 5) | new_mixer_gain)) << (i * 8); |
| 4291 | 4280 |
} |
| ... | ... | |
| 4394 | 4383 |
dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET, old_pmsc_ctrl1); |
| 4395 | 4384 |
dwt_write32bitreg(RF_CONF_ID, old_rf_conf_txpow_mask); |
| 4396 | 4385 |
|
| 4397 |
average_count = (int)(sum_count / NUM_SAMPLES);
|
|
| 4386 |
average_count = (uint16_t)(sum_count / NUM_SAMPLES);
|
|
| 4398 | 4387 |
return average_count; |
| 4399 | 4388 |
} |
| 4400 | 4389 |
|
| ... | ... | |
| 4405 | 4394 |
|
| 4406 | 4395 |
0xDECA0130 // DW1000 - MP |
| 4407 | 4396 |
|
| 4408 |
=============================================================================================== |
|
| 4409 |
*/ |
|
| 4397 |
=============================================================================================== */ |
|
| 4410 | 4398 |
|
| 4411 | 4399 |
/**************************************************************************************************************************************************** |
| 4412 | 4400 |
* |
| ... | ... | |
| 4429 | 4417 |
*/ |
| 4430 | 4418 |
#pragma GCC optimize ("O3")
|
| 4431 | 4419 |
static int writetospi(uint16_t headerLength, |
| 4432 |
const uint8_t *headerBuffer, |
|
| 4433 |
uint32_t bodyLength, |
|
| 4434 |
const uint8_t *bodyBuffer) |
|
| 4435 |
{
|
|
| 4436 |
|
|
| 4437 |
uint8_t buffer[bodyLength + 3]; |
|
| 4438 |
memcpy(buffer, headerBuffer, headerLength); //copy data to buffer |
|
| 4439 |
memcpy(&buffer[headerLength], bodyBuffer, bodyLength); //copy data to buffer |
|
| 4440 |
|
|
| 4441 |
apalSPITransmit(pdw1000local->driver->spid, |
|
| 4442 |
buffer, |
|
| 4443 |
bodyLength + headerLength); // send header and data |
|
| 4444 |
|
|
| 4445 |
return 0; |
|
| 4420 |
const uint8_t *headerBuffer, |
|
| 4421 |
uint32_t bodyLength, |
|
| 4422 |
const uint8_t *bodyBuffer) |
|
| 4423 |
{
|
|
| 4424 |
uint8_t buffer[SPIBUFFLEN]; |
|
| 4425 |
memcpy(buffer, headerBuffer, headerLength); //copy header (register id no.) to the buffer |
|
| 4426 |
memcpy(&buffer[headerLength], bodyBuffer, bodyLength); //copy data to the buffer |
|
| 4427 |
|
|
| 4428 |
apalSPITransmit(pdw1000local->driver->spid, |
|
| 4429 |
buffer, |
|
| 4430 |
bodyLength + headerLength); // send header (register id) and data |
|
| 4431 |
|
|
| 4432 |
return 0; |
|
| 4446 | 4433 |
} // end writetospi() |
| 4447 | 4434 |
|
| 4448 | 4435 |
|
| ... | ... | |
| 4533 | 4520 |
/*! @brief sleep or idle the thread in millisecond */ |
| 4534 | 4521 |
void deca_sleep(unsigned int time_ms) |
| 4535 | 4522 |
{
|
| 4536 |
aosThdMSleep(time_ms);
|
|
| 4523 |
usleep(time_ms * 1000);
|
|
| 4537 | 4524 |
} |
| 4538 | 4525 |
|
| 4539 | 4526 |
/*! @brief sleep or idle the thread in millisecond */ |
| 4540 | 4527 |
void Sleep(unsigned int time_ms) |
| 4541 | 4528 |
{
|
| 4542 |
aosThdMSleep(time_ms);
|
|
| 4529 |
usleep(time_ms * 1000);
|
|
| 4543 | 4530 |
} |
| 4544 | 4531 |
|
| 4545 | 4532 |
|
| ... | ... | |
| 4552 | 4539 |
return chVTGetSystemTimeX(); |
| 4553 | 4540 |
} |
| 4554 | 4541 |
|
| 4555 |
//inline uint32_t portGetTickCnt(){
|
|
| 4556 |
// return (uint32_t) chVTGetSystemTimeX(); |
|
| 4557 |
//} |
|
| 4558 |
|
|
| 4559 |
|
|
| 4560 | 4542 |
/*! @brief Disable the interrupt handler */ |
| 4561 | 4543 |
void port_DisableEXT_IRQ(void){
|
| 4562 | 4544 |
nvicDisableVector(DW1000_EXTI_IRQn); |
| 4563 |
|
|
| 4564 | 4545 |
} |
| 4565 | 4546 |
|
| 4566 | 4547 |
/*! @brief Enable the interrupt handler */ |
| source/DW1000/v1/deca_instance_common_v1.c | ||
|---|---|---|
| 202 | 202 |
//these are default antenna delays for EVB1000, these can be used if there is no calibration data in the DW1000, |
| 203 | 203 |
//or instead of the calibration data |
| 204 | 204 |
const uint16_t rfDelays[2] = {
|
| 205 |
(uint16_t) ((DWT_PRF_16M_RFDLY/ 2.0) * 1e-9 / DWT_TIME_UNITS),//PRF 16 |
|
| 206 |
(uint16_t) ((DWT_PRF_64M_RFDLY/ 2.0) * 1e-9 / DWT_TIME_UNITS) |
|
| 205 |
(uint16_t) (((double)DWT_PRF_16M_RFDLY/ 2.0) * 1e-9 / DWT_TIME_UNITS),//PRF 16
|
|
| 206 |
(uint16_t) (((double)DWT_PRF_64M_RFDLY/ 2.0) * 1e-9 / DWT_TIME_UNITS)
|
|
| 207 | 207 |
}; |
| 208 | 208 |
|
| 209 | 209 |
//these are default TREK Tag/Anchor antenna delays |
| 210 | 210 |
const uint16_t rfDelaysTREK[2] = {
|
| 211 |
(uint16_t) ((514.83f/ 2.0) * 1e-9 / DWT_TIME_UNITS),//channel 2 |
|
| 212 |
(uint16_t) ((514.65f/ 2.0) * 1e-9 / DWT_TIME_UNITS) //channel 5 |
|
| 211 |
(uint16_t) (((double)514.83f/ 2.0) * 1e-9 / DWT_TIME_UNITS),//channel 2
|
|
| 212 |
(uint16_t) (((double)514.65f/ 2.0) * 1e-9 / DWT_TIME_UNITS) //channel 5
|
|
| 213 | 213 |
}; |
| 214 | 214 |
|
| 215 |
//int instance_starttxtest(int framePeriod) |
|
| 216 |
//{
|
|
| 217 |
// //define some test data for the tx buffer |
|
| 218 |
// uint8 msg[127] = "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the l"; |
|
| 219 |
|
|
| 220 |
// //NOTE: SPI frequency must be < 3MHz |
|
| 221 |
// port_set_dw1000_slowrate(); //max SPI before PLLs configured is ~4M |
|
| 222 |
|
|
| 223 |
// // the value here 0x1000 gives a period of 32.82 µs |
|
| 224 |
// //this is setting 0x1000 as frame period (125MHz clock cycles) (time from Tx en - to next - Tx en) |
|
| 225 |
// dwt_configcontinuousframemode(framePeriod); |
|
| 226 |
|
|
| 227 |
// dwt_writetxdata(127, (uint8 *) msg, 0) ; |
|
| 228 |
// dwt_writetxfctrl(127, 0, 0); |
|
| 229 |
|
|
| 230 |
// //to start the first frame - set TXSTRT |
|
| 231 |
// dwt_starttx(DWT_START_TX_IMMEDIATE); |
|
| 232 |
|
|
| 233 |
// //measure the power |
|
| 234 |
// //Spectrum Analyser set: |
|
| 235 |
// //FREQ to be channel default e.g. 3.9936 GHz for channel 2 |
|
| 236 |
// //SPAN to 1GHz |
|
| 237 |
// //SWEEP TIME 1s |
|
| 238 |
// //RBW and VBW 1MHz |
|
| 239 |
// //measure channel power |
|
| 240 |
|
|
| 241 |
// return DWT_SUCCESS ; |
|
| 242 |
//} |
|
| 243 | 215 |
|
| 244 | 216 |
// ------------------------------------------------------------------------------------------------------------------- |
| 245 | 217 |
// Data Definitions |
| ... | ... | |
| 251 | 223 |
static double inst_idist[MAX_ANCHOR_LIST_SIZE] ; |
| 252 | 224 |
static double inst_idistraw[MAX_ANCHOR_LIST_SIZE] ; |
| 253 | 225 |
|
| 254 |
// TODO: Instance_data declaration in .c. Not on .h (extern only) |
|
| 255 | 226 |
instance_data_t instance_data[NUM_INST] ; |
| 256 | 227 |
|
| 257 |
/* TODO: Custom data declarations */ |
|
| 258 |
typedef struct |
|
| 228 |
typedef struct __attribute__((packed)) |
|
| 259 | 229 |
{
|
| 260 | 230 |
uint32_t deviceID ; |
| 261 | 231 |
uint8_t chan; // added chan here - used in the reading of acc |
| ... | ... | |
| 282 | 252 |
uint64_t dt; |
| 283 | 253 |
long double dtime; |
| 284 | 254 |
|
| 285 |
dtime = (microsecu / (double) DWT_TIME_UNITS) / 1e6 ;
|
|
| 255 |
dtime = (long double)((microsecu / (double) DWT_TIME_UNITS) / 1e6);
|
|
| 286 | 256 |
|
| 287 | 257 |
dt = (uint64_t) (dtime) ; |
| 288 | 258 |
|
| ... | ... | |
| 302 | 272 |
double distance ; |
| 303 | 273 |
double distance_to_correct; |
| 304 | 274 |
double tof ; |
| 305 |
int32_t tofi ;
|
|
| 275 |
int64_t tofi ;
|
|
| 306 | 276 |
|
| 307 | 277 |
// check for negative results and accept them making them proper negative integers |
| 308 | 278 |
tofi = (int32_t) tofx ; // make it signed |
| ... | ... | |
| 311 | 281 |
} |
| 312 | 282 |
|
| 313 | 283 |
// convert to seconds (as floating point) |
| 314 |
tof = convertdevicetimetosec(tofi) ; //this is divided by 4 to get single time of flight |
|
| 284 |
tof = convertdevicetimetosec((int32_t)tofi) ; //this is divided by 4 to get single time of flight
|
|
| 315 | 285 |
inst_idistraw[idx] = distance = tof * SPEED_OF_LIGHT; |
| 316 | 286 |
|
| 317 | 287 |
#if (CORRECT_RANGE_BIAS == 1) |
| ... | ... | |
| 376 | 346 |
// Set this instance role as the Tag, Anchor or Listener |
| 377 | 347 |
void instancesetrole(int inst_mode){
|
| 378 | 348 |
// assume instance 0, for this |
| 379 |
instance_data[0].mode = inst_mode; // set the role |
|
| 349 |
instance_data[0].mode = (INST_MODE)inst_mode; // set the role
|
|
| 380 | 350 |
} |
| 381 | 351 |
|
| 382 | 352 |
int instancegetrole(void){
|
| 383 |
return instance_data[0].mode; |
|
| 353 |
return (int)instance_data[0].mode;
|
|
| 384 | 354 |
} |
| 385 | 355 |
|
| 386 | 356 |
int instancenewrange(void){
|
| ... | ... | |
| 397 | 367 |
return instance_data[0].newRangeTagAddress; |
| 398 | 368 |
} |
| 399 | 369 |
|
| 400 |
int instancenewrangetim(void){
|
|
| 370 |
uint32_t instancenewrangetim(void){
|
|
| 401 | 371 |
return instance_data[0].newRangeTime; |
| 402 | 372 |
} |
| 403 | 373 |
|
| ... | ... | |
| 447 | 417 |
//dwt_softreset(); |
| 448 | 418 |
|
| 449 | 419 |
//this initialises DW1000 and uses specified configurations from OTP/ROM |
| 450 |
result = dwt_initialise(DWT_LOADUCODE, drv) ; // TODO |
|
| 451 |
// result = dwt_initialise(DWT_LOADUCODE) ; |
|
| 420 |
result = dwt_initialise(DWT_LOADUCODE, drv); |
|
| 452 | 421 |
|
| 453 | 422 |
//this is platform dependent - only program if DW EVK/EVB |
| 454 | 423 |
dwt_setleds(3) ; //configure the GPIOs which control the leds on EVBs |
| ... | ... | |
| 768 | 737 |
|
| 769 | 738 |
dw_event.uTimeStamp = portGetTickCnt(); |
| 770 | 739 |
|
| 771 |
// chprintf((BaseSequentialStream *)&SD2, " TX callback! \r\n"); |
|
| 772 |
|
|
| 773 |
// if(txevent == DWT_SIG_TX_DONE) {
|
|
| 774 |
//uint32_t txtimestamp = 0; |
|
| 775 |
|
|
| 776 |
//NOTE - we can only get TX good (done) while here |
|
| 777 |
//dwt_readtxtimestamp((uint8*) &instance_data[instance].txu.txTimeStamp); |
|
| 778 |
|
|
| 779 |
dwt_readtxtimestamp(txTimeStamp) ; |
|
| 780 |
dw_event.timeStamp32l = (uint32_t)txTimeStamp[0] + ((uint32_t)txTimeStamp[1] << 8) + ((uint32_t)txTimeStamp[2] << 16) + ((uint32_t)txTimeStamp[3] << 24); |
|
| 781 |
dw_event.timeStamp = txTimeStamp[4]; |
|
| 782 |
dw_event.timeStamp <<= 32; |
|
| 783 |
dw_event.timeStamp += dw_event.timeStamp32l; |
|
| 784 |
dw_event.timeStamp32h = ((uint32_t)txTimeStamp[4] << 24) + (dw_event.timeStamp32l >> 8); |
|
| 740 |
dwt_readtxtimestamp(txTimeStamp) ; |
|
| 741 |
dw_event.timeStamp32l = (uint32_t)txTimeStamp[0] + ((uint32_t)txTimeStamp[1] << 8) + ((uint32_t)txTimeStamp[2] << 16) + ((uint32_t)txTimeStamp[3] << 24); |
|
| 742 |
dw_event.timeStamp = txTimeStamp[4]; |
|
| 743 |
dw_event.timeStamp <<= 32; |
|
| 744 |
dw_event.timeStamp += dw_event.timeStamp32l; |
|
| 745 |
dw_event.timeStamp32h = ((uint32_t)txTimeStamp[4] << 24) + (dw_event.timeStamp32l >> 8); |
|
| 785 | 746 |
|
| 786 |
instance_data[instance].stopTimer = 0;
|
|
| 747 |
instance_data[instance].stopTimer = 0; |
|
| 787 | 748 |
|
| 788 |
dw_event.rxLength = instance_data[instance].psduLength;
|
|
| 789 |
dw_event.type = 0;
|
|
| 790 |
dw_event.type_pend = 0;
|
|
| 791 |
dw_event.type_save = DWT_SIG_TX_DONE;
|
|
| 749 |
dw_event.rxLength = instance_data[instance].psduLength; |
|
| 750 |
dw_event.type = 0; |
|
| 751 |
dw_event.type_pend = 0; |
|
| 752 |
dw_event.type_save = DWT_SIG_TX_DONE; |
|
| 792 | 753 |
|
| 793 |
memcpy((uint8_t *)&dw_event.msgu.frame[0], (uint8_t *)&instance_data[instance].msg_f, instance_data[instance].psduLength);
|
|
| 754 |
memcpy((uint8_t *)&dw_event.msgu.frame[0], (uint8_t *)&instance_data[instance].msg_f, instance_data[instance].psduLength); |
|
| 794 | 755 |
|
| 795 |
instance_putevent(dw_event, DWT_SIG_TX_DONE);
|
|
| 756 |
instance_putevent(dw_event, DWT_SIG_TX_DONE); |
|
| 796 | 757 |
|
| 797 |
instance_data[instance].txMsgCount++; |
|
| 798 |
// } |
|
| 799 |
// else if(txevent == DWT_SIG_TX_AA_DONE) {
|
|
| 800 |
// //auto ACK confirmation |
|
| 801 |
// dw_event.rxLength = 0; |
|
| 802 |
// dw_event.type = 0; |
|
| 803 |
// dw_event.type_save = DWT_SIG_TX_AA_DONE; |
|
| 804 |
// |
|
| 805 |
// instance_putevent(dw_event, DWT_SIG_TX_AA_DONE); |
|
| 806 |
// |
|
| 807 |
// //printf("TX AA time %f ecount %d\n",convertdevicetimetosecu(instance_data[instance].txu.txTimeStamp), instance_data[instance].dweventCnt);
|
|
| 808 |
// } |
|
| 758 |
instance_data[instance].txMsgCount++; |
|
| 809 | 759 |
|
| 810 | 760 |
instance_data[instance].monitor = 0; |
| 811 | 761 |
} |
| ... | ... | |
| 834 | 784 |
case 2: |
| 835 | 785 |
default: |
| 836 | 786 |
if(instance_data[instance].responseTO > 0) { //can get here as result of error frame so need to check
|
| 837 |
dwt_setrxtimeout((uint16_t)instance_data[instance].fwtoTime_sy * instance_data[instance].responseTO); //reconfigure the timeout
|
|
| 787 |
dwt_setrxtimeout((uint16_t)(instance_data[instance].fwtoTime_sy * instance_data[instance].responseTO)); //reconfigure the timeout
|
|
| 838 | 788 |
dwt_rxenable(DWT_START_RX_IMMEDIATE) ; |
| 839 | 789 |
type_pend = DWT_SIG_RX_PENDING ; |
| 840 | 790 |
} |
| ... | ... | |
| 1056 | 1006 |
instance_data[instance].msg_f.seqNum = instance_data[instance].frameSN++; |
| 1057 | 1007 |
|
| 1058 | 1008 |
//set the delayed rx on time (the final message will be sent after this delay) |
| 1059 |
dwt_setrxaftertxdelay(instance_data[instance].ancRespRxDelay); //units are 1.0256us - wait for wait4respTIM before RX on (delay RX) |
|
| 1009 |
dwt_setrxaftertxdelay((uint32_t)instance_data[instance].ancRespRxDelay); //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
|
|
| 1060 | 1010 |
|
| 1061 | 1011 |
instance_data[instance].tagSleepCorrection = 0; |
| 1062 | 1012 |
instance_data[instance].msg_f.messageData[RES_TAG_SLP0] = 0 ; |
| ... | ... | |
| 1093 | 1043 |
|
| 1094 | 1044 |
//we have our range - update the own mask entry... |
| 1095 | 1045 |
if(instance_data[instance].tof[tof_idx] != INVALID_TOF) { //check the last ToF entry is valid and copy into the current array
|
| 1096 |
instance_data[instance].rxResponseMask = (0x1 << instance_data[instance].shortAdd_idx); |
|
| 1046 |
instance_data[instance].rxResponseMask = (uint8_t)(0x1 << instance_data[instance].shortAdd_idx);
|
|
| 1097 | 1047 |
instance_data[instance].tofArray[instance_data[instance].shortAdd_idx] = instance_data[instance].tof[tof_idx]; |
| 1098 | 1048 |
} |
| 1099 | 1049 |
else { //reset response mask
|
| ... | ... | |
| 1101 | 1051 |
instance_data[instance].rxResponseMask = 0; //reset the mask of received responses when rx poll |
| 1102 | 1052 |
} |
| 1103 | 1053 |
//set the delayed rx on time (the final message will be sent after this delay) |
| 1104 |
dwt_setrxaftertxdelay(instance_data[instance].ancRespRxDelay); //units are 1.0256us - wait for wait4respTIM before RX on (delay RX) |
|
| 1054 |
dwt_setrxaftertxdelay((uint32_t)instance_data[instance].ancRespRxDelay); //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
|
|
| 1105 | 1055 |
|
| 1106 | 1056 |
//if this is gateway anchor - calculate the slot period correction |
| 1107 | 1057 |
if(instance_data[instance].gatewayAnchor) {
|
| ... | ... | |
| 1187 | 1137 |
|
| 1188 | 1138 |
//if Listener then just report the received frame to the instance (application) |
| 1189 | 1139 |
if(rxd_event == DWT_SIG_RX_OKAY) { //Process good/known frame types
|
| 1190 |
uint16_t sourceAddress = (((uint16_t)dw_event.msgu.frame[srcAddr_index+1]) << 8) + dw_event.msgu.frame[srcAddr_index];
|
|
| 1140 |
uint16_t sourceAddress = (uint16_t)(((uint16_t)dw_event.msgu.frame[srcAddr_index+1]) << 8) + (uint16_t)(dw_event.msgu.frame[srcAddr_index]);
|
|
| 1191 | 1141 |
|
| 1192 | 1142 |
if(instance_data[instance].mode != LISTENER) {
|
| 1193 | 1143 |
if(instance_data[instance].mode == TAG) //if tag got a good frame - this is probably a response, but could also be some other non-ranging frame |
| ... | ... | |
| 1251 | 1201 |
instance_data[instance].rxMsgCount++; |
| 1252 | 1202 |
return; |
| 1253 | 1203 |
} |
| 1254 |
instance_data[instance].rxRespsIdx = (int8_t) ((dw_event.msgu.frame[POLL_RNUM+fcode_index] & 0xf) |
|
| 1204 |
instance_data[instance].rxRespsIdx = (uint8_t) ((dw_event.msgu.frame[POLL_RNUM+fcode_index] & 0xf)
|
|
| 1255 | 1205 |
+ ((sourceAddress&0x7) << 4)); |
| 1256 | 1206 |
instance_data[instance].rxResps[instance_data[instance].rxRespsIdx] = 0; |
| 1257 | 1207 |
|
| ... | ... | |
| 1352 | 1302 |
instance_data[instance].rxMsgCount++; |
| 1353 | 1303 |
return; |
| 1354 | 1304 |
} |
| 1355 |
break; // TODO: fallthourgh for anchor
|
|
| 1305 |
break; |
|
| 1356 | 1306 |
// __attribute__ ((fallthrough)); |
| 1357 | 1307 |
|
| 1358 | 1308 |
//if anchor fall into case below and process the frame |
| ... | ... | |
| 1376 | 1326 |
} |
| 1377 | 1327 |
|
| 1378 | 1328 |
|
| 1379 |
/*TODO: Callback funtion for RX timeout (available from newer driver version) */
|
|
| 1329 |
/*! Callback funtion for RX timeout (available from newer driver version) */
|
|
| 1380 | 1330 |
#pragma GCC optimize ("O3")
|
| 1381 | 1331 |
void instance_rxtimeoutcallback(const dwt_cb_data_t *rxd){
|
| 1382 | 1332 |
|
| ... | ... | |
| 1410 | 1360 |
} |
| 1411 | 1361 |
|
| 1412 | 1362 |
|
| 1413 |
/*TODO: Callback funtion for RX error (available from newer driver version) */
|
|
| 1363 |
/*! Callback funtion for RX error (available from newer driver version) */
|
|
| 1414 | 1364 |
#pragma GCC optimize ("O3")
|
| 1415 | 1365 |
void instance_rxerrorcallback(const dwt_cb_data_t *rxd) {
|
| 1416 | 1366 |
|
| ... | ... | |
| 1503 | 1453 |
dw_event_g.type = instance_data[instance].dwevent[indexOut].type ; |
| 1504 | 1454 |
|
| 1505 | 1455 |
|
| 1506 |
instance_data[instance].dwevent[indexOut].gotit = x; |
|
| 1456 |
instance_data[instance].dwevent[indexOut].gotit = (uint8_t)x;
|
|
| 1507 | 1457 |
|
| 1508 | 1458 |
//instance_data[instance].dwevent[indexOut].eventtimeclr = portGetTickCnt(); |
| 1509 | 1459 |
|
| ... | ... | |
| 1555 | 1505 |
message = 0; |
| 1556 | 1506 |
} |
| 1557 | 1507 |
|
| 1558 |
|
|
| 1559 |
|
|
| 1560 | 1508 |
if(done == INST_DONE_WAIT_FOR_NEXT_EVENT_TO) { //we are in RX and need to timeout (Tag needs to send another poll if no Rx frame)
|
| 1561 | 1509 |
if(instance_data[instance].mode == TAG) { //Tag (is either in RX or sleeping)
|
| 1562 | 1510 |
int32_t nextPeriod ; |
| ... | ... | |
| 1664 | 1612 |
instance_data[0].txPower = txpower ; |
| 1665 | 1613 |
|
| 1666 | 1614 |
instance_data[0].txPowerChanged = 1; |
| 1667 |
|
|
| 1668 | 1615 |
} |
| 1669 | 1616 |
|
| 1670 | 1617 |
void instancesettxpower(void){
|
| ... | ... | |
| 1709 | 1656 |
#endif |
| 1710 | 1657 |
|
| 1711 | 1658 |
|
| 1712 |
/*! TODO: the following Functions are added for user application (previously on the API )*/
|
|
| 1659 |
/*! The following Functions are added for user application (previously on the API )*/ |
|
| 1713 | 1660 |
|
| 1714 | 1661 |
/*! ------------------------------------------------------------------------------------------------------------------ |
| 1715 | 1662 |
* @fn dwt_getotptxpower() |
| source/DW1000/v1/deca_instance_tag_anchor_v1.c | ||
|---|---|---|
| 17 | 17 |
|
| 18 | 18 |
#include <v1/deca_instance_v1.h> |
| 19 | 19 |
#include <string.h> |
| 20 |
#include<math.h> |
|
| 20 |
#include <math.h>
|
|
| 21 | 21 |
#include "module.h" |
| 22 | 22 |
|
| 23 | 23 |
// ------------------------------------------------------------------------------------------------------------------- |
| 24 |
// Data Definitions |
|
| 25 |
// ------------------------------------------------------------------------------------------------------------------- |
|
| 26 |
|
|
| 27 |
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
|
| 28 |
// NOTE: the maximum RX timeout is ~ 65ms |
|
| 29 |
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
|
| 30 |
|
|
| 31 |
|
|
| 32 |
// ------------------------------------------------------------------------------------------------------------------- |
|
| 33 |
// Functions |
|
| 34 |
// ------------------------------------------------------------------------------------------------------------------- |
|
| 35 |
|
|
| 36 |
// ------------------------------------------------------------------------------------------------------------------- |
|
| 37 | 24 |
// |
| 38 | 25 |
// function to construct the message/frame header bytes |
| 39 | 26 |
// |
| ... | ... | |
| 61 | 48 |
} |
| 62 | 49 |
|
| 63 | 50 |
//begin delayed TX of frame |
| 64 |
if (dwt_starttx(delayedTx | inst->wait4ack)){ // delayed start was too late
|
|
| 51 |
if (dwt_starttx((uint8_t)(delayedTx | inst->wait4ack))){ // delayed start was too late
|
|
| 65 | 52 |
result = 1; //late/error |
| 66 | 53 |
inst->lateTX++; |
| 67 | 54 |
} |
| ... | ... | |
| 72 | 59 |
return result; // state changes |
| 73 | 60 |
} |
| 74 | 61 |
|
| 75 |
|
|
| 76 | 62 |
int instance_calcranges(uint32_t *array, uint16_t size, int reportRange, uint8_t* mask){
|
| 77 | 63 |
int i; |
| 78 | 64 |
int newRange = TOF_REPORT_NUL; |
| ... | ... | |
| 135 | 121 |
|
| 136 | 122 |
sleep_mode = (DWT_LOADUCODE|DWT_PRESRV_SLEEP|DWT_CONFIG|DWT_TANDV); |
| 137 | 123 |
|
| 138 |
/* TODO: No need anymore since the driver handle itself */ |
|
| 139 |
// if((dwt_getldotune() != 0)) //if we need to use LDO tune value from OTP kick it after sleep |
|
| 140 |
// sleep_mode |= DWT_LOADOPSET; |
|
| 141 |
|
|
| 142 | 124 |
if(inst->configData.txPreambLength == DWT_PLEN_64) //if using 64 length preamble then use the corresponding OPSet |
| 143 | 125 |
sleep_mode |= DWT_LOADOPSET; |
| 144 | 126 |
|
| ... | ... | |
| 255 | 237 |
dwt_seteui(inst->eui64); |
| 256 | 238 |
} |
| 257 | 239 |
#else |
| 258 |
Sleep(3); //to approximate match the time spent in the #if above //TODO: 3ms default
|
|
| 240 |
Sleep(3); //to approximate match the time spent in the #if above |
|
| 259 | 241 |
#endif |
| 260 | 242 |
|
| 261 | 243 |
instancesetantennadelays(); //this will update the antenna delay if it has changed |
| ... | ... | |
| 426 | 408 |
else { //for anchor make the final half the delay ..... (this is ok, as A0 awaits 2 responses)
|
| 427 | 409 |
tagCalculatedFinalTxTime = (inst->txu.txTimeStamp + inst->pollTx2FinalTxDelayAnc) & MASK_TXDTS; |
| 428 | 410 |
} |
| 429 |
inst->delayedReplyTime = tagCalculatedFinalTxTime >> 8; //high 32-bits
|
|
| 411 |
inst->delayedReplyTime = (uint32_t)(tagCalculatedFinalTxTime >> 8); //high 32-bits
|
|
| 430 | 412 |
// Calculate Time Final message will be sent and write this field of Final message |
| 431 | 413 |
// Sending time will be delayedReplyTime, snapped to ~125MHz or ~250MHz boundary by |
| 432 | 414 |
// zeroing its low 9 bits, and then having the TX antenna delay added |
| ... | ... | |
| 451 | 433 |
message = 0; |
| 452 | 434 |
//fall into the next case (turn on the RX) |
| 453 | 435 |
} |
| 454 |
|
|
| 455 | 436 |
} |
| 456 |
// TODO: fall through to the next case statement in case of debugging |
|
| 457 | 437 |
break ; // end case TA_TX_WAIT_CONF |
| 458 | 438 |
|
| 459 | 439 |
|
| ... | ... | |
| 476 | 456 |
// end case TA_RXE_WAIT, don't break, but fall through into the TA_RX_WAIT_DATA state to process it immediately. |
| 477 | 457 |
if(message == 0) break; |
| 478 | 458 |
} |
| 479 |
// TODO: fall through to the next case statement in case of debugging |
|
| 480 | 459 |
break; |
| 481 | 460 |
|
| 482 |
case TA_RX_WAIT_DATA : // Wait RX data
|
|
| 461 |
case TA_RX_WAIT_DATA : // Wait RX data |
|
| 483 | 462 |
//printf("TA_RX_WAIT_DATA %d", message) ;
|
| 484 | 463 |
switch (message){
|
| 485 | 464 |
|
| ... | ... | |
| 493 | 472 |
//int srclen = 0; |
| 494 | 473 |
//int fctrladdr_len; |
| 495 | 474 |
uint8_t tof_idx = 0; |
| 496 |
uint8_t *messageData; |
|
| 475 |
uint8_t *messageData = NULL;
|
|
| 497 | 476 |
|
| 498 | 477 |
inst->stopTimer = 0; //clear the flag, as we have received a message |
| 499 | 478 |
|
| ... | ... | |
| 629 | 608 |
} |
| 630 | 609 |
} |
| 631 | 610 |
} |
| 632 |
/*else |
|
| 633 |
{
|
|
| 634 |
//stay in RX wait for next frame... |
|
| 635 |
inst->testAppState = TA_RXE_WAIT ; // wait for next frame |
|
| 636 |
}*/ |
|
| 637 | 611 |
|
| 638 | 612 |
if(fcode == RTLS_DEMO_MSG_ANCH_RESP) { //tag to anchor mode
|
| 639 | 613 |
if(currentRangeNum == inst->rangeNum) { //these are the previous ranges...
|
| ... | ... | |
| 692 | 666 |
uint64_t tagFinalRxTime = 0; |
| 693 | 667 |
uint64_t tagPollTxTime = 0; |
| 694 | 668 |
uint64_t anchorRespRxTime = 0; |
| 695 |
uint64_t tof = INVALID_TOF;
|
|
| 669 |
int32_t tof = (int32_t)INVALID_TOF;
|
|
| 696 | 670 |
|
| 697 | 671 |
double RaRbxDaDb = 0; |
| 698 | 672 |
double RbyDb = 0; |
| ... | ... | |
| 758 | 732 |
|
| 759 | 733 |
RayDa = ((double)Ra + (double)Da); |
| 760 | 734 |
|
| 761 |
tof = (int32_t) ( RaRbxDaDb/(RbyDb + RayDa) );
|
|
| 735 |
tof = (int32_t)(RaRbxDaDb/(RbyDb + RayDa));
|
|
| 762 | 736 |
} |
| 763 | 737 |
|
| 764 | 738 |
//tag to anchor ranging |
| 765 | 739 |
if(RTLS_DEMO_MSG_TAG_FINAL == fcode) {
|
| 766 | 740 |
inst->newRangeTagAddress = srcAddr[0] + ((uint16_t) srcAddr[1] << 8); |
| 767 | 741 |
//time-of-flight |
| 768 |
inst->tof[inst->newRangeTagAddress & 0x7] = tof; |
|
| 742 |
inst->tof[inst->newRangeTagAddress & 0x7] = (uint32_t)tof;
|
|
| 769 | 743 |
//calculate all tag - anchor ranges... and report |
| 770 | 744 |
inst->newRange = instance_calcranges(&inst->tofArray[0], MAX_ANCHOR_LIST_SIZE, TOF_REPORT_T2A, &inst->rxResponseMask); |
| 771 | 745 |
inst->rxResponseMaskReport = inst->rxResponseMask; //copy the valid mask to report |
| 772 | 746 |
inst->rxResponseMask = 0; |
| 773 | 747 |
//we have our range - update the own mask entry... |
| 774 |
if(tof != INVALID_TOF) { //check the last ToF entry is valid and copy into the current array
|
|
| 748 |
if(tof != (int32_t)INVALID_TOF) { //check the last ToF entry is valid and copy into the current array
|
|
| 775 | 749 |
setTagDist(srcAddr[0], inst->shortAdd_idx); //copy distance from this anchor to the tag into array |
| 776 | 750 |
|
| 777 |
inst->rxResponseMask = (0x1 << inst->shortAdd_idx); |
|
| 778 |
inst->tofArray[inst->shortAdd_idx] = tof; |
|
| 751 |
inst->rxResponseMask = (uint8_t)(0x1 << inst->shortAdd_idx);
|
|
| 752 |
inst->tofArray[inst->shortAdd_idx] = (uint32_t)tof;
|
|
| 779 | 753 |
} |
| 780 | 754 |
inst->newRangeTime = dw_event->uTimeStamp ; |
| 781 | 755 |
} |
| 782 | 756 |
else { //anchor to anchor ranging
|
| 783 | 757 |
inst->newRangeTagAddress = srcAddr[0] + ((uint16_t) srcAddr[1] << 8); |
| 784 | 758 |
//time-of-flight |
| 785 |
inst->tofAnc[tof_idx] = tof; |
|
| 759 |
inst->tofAnc[tof_idx] = (uint32_t)tof;
|
|
| 786 | 760 |
} |
| 787 | 761 |
|
| 788 | 762 |
//reset the response count |
| ... | ... | |
| 884 | 858 |
float msgdatalen = 0; |
| 885 | 859 |
float preamblelen = 0; |
| 886 | 860 |
int sfdlen = 0; |
| 887 |
int x = 0;
|
|
| 861 |
float x = 0;
|
|
| 888 | 862 |
|
| 889 | 863 |
//Set the RX timeouts based on the longest expected message - the Final message |
| 890 | 864 |
//Poll = 13, Response = 20, Final = 44 bytes |
| 891 | 865 |
//msgdatalen = TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC; |
| 892 | 866 |
msgdatalen = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC; |
| 893 | 867 |
|
| 894 |
x = (int) ceil(msgdatalen*8/330.0f);
|
|
| 868 |
x = (float)ceil((double)(msgdatalen*8)/(double)330.0f);
|
|
| 895 | 869 |
|
| 896 | 870 |
msgdatalen = msgdatalen*8 + x*48; |
| 897 | 871 |
|
| 898 | 872 |
//add some margin so we don't timeout too soon |
| 899 | 873 |
margin = 0; //(TAG_FINAL_MSG_LEN - TAG_POLL_MSG_LEN); |
| 900 | 874 |
|
| 901 |
x = (int) ceil(margin*8/330.0f);
|
|
| 875 |
x = (float) ceil((double)(margin*8)/(double)330.0f);
|
|
| 902 | 876 |
|
| 903 |
margin = margin*8 + x*48;
|
|
| 877 |
margin = (int) (margin*8 + x*48);
|
|
| 904 | 878 |
|
| 905 | 879 |
//assume PHR length is 172308ns for 110k and 21539ns for 850k/6.81M |
| 906 | 880 |
if(instance_data[instance].configData.dataRate == DWT_BR_110K) {
|
| ... | ... | |
| 946 | 920 |
preamblelen = (sfdlen + preamblelen) * 1.01763f; |
| 947 | 921 |
} |
| 948 | 922 |
|
| 949 |
respframe_sy = (16 + (int)((preamblelen + ((msgdatalen + margin)/1000.0))/ 1.0256)) ;
|
|
| 923 |
respframe_sy = (16 + (int)((double)((double)preamblelen + ((double)(msgdatalen + margin)/1000.0))/ 1.0256)) ;
|
|
| 950 | 924 |
|
| 951 | 925 |
//this is the delay used for the delayed transmit (when sending the response, and final messages) |
| 952 | 926 |
instance_data[instance].pollTx2FinalTxDelay = convertmicrosectodevicetimeu (delayus); |
| ... | ... | |
| 959 | 933 |
//andhor 3 will have the delay set to 3 * fixedReplyDelayAnc and so on... |
| 960 | 934 |
//this delay depends on how quickly the tag can receive and process the message from previous anchor |
| 961 | 935 |
//(and also the frame length of course) |
| 962 |
respframe = (int)(preamblelen + (msgdatalen/1000.0)); //length of response frame (micro seconds)
|
|
| 936 |
respframe = (int)((double)preamblelen + ((double)msgdatalen/1000.0)); //length of response frame (micro seconds)
|
|
| 963 | 937 |
if(instance_data[instance].configData.dataRate == DWT_BR_110K) {
|
| 964 | 938 |
|
| 965 | 939 |
//set the frame wait timeout time - total time the frame takes in symbols |
| ... | ... | |
| 967 | 941 |
|
| 968 | 942 |
instance_data[instance].fwtoTimeAnc_sy = respframe_sy; //add some margin so we don't timeout too soon |
| 969 | 943 |
instance_data[instance].fixedReplyDelayAnc = convertmicrosectodevicetimeu (respframe + RX_RESPONSE1_TURNAROUND_110K); |
| 970 |
instance_data[instance].fixedReplyDelayAncP = (uint32_t) (((uint64_t) convertmicrosectodevicetimeu (preamblelen)) >> 8) + 16; |
|
| 944 |
instance_data[instance].fixedReplyDelayAncP = (uint32_t) (((uint64_t) convertmicrosectodevicetimeu ((double)preamblelen)) >> 8) + 16;
|
|
| 971 | 945 |
|
| 972 | 946 |
instance_data[instance].ancRespRxDelay = RX_RESPONSE1_TURNAROUND_110K ; |
| 973 | 947 |
} |
| ... | ... | |
| 978 | 952 |
|
| 979 | 953 |
instance_data[instance].fwtoTimeAnc_sy = respframe_sy; |
| 980 | 954 |
instance_data[instance].fixedReplyDelayAnc = convertmicrosectodevicetimeu (respframe + RX_RESPONSE1_TURNAROUND_6M81); |
| 981 |
instance_data[instance].fixedReplyDelayAncP = (uint32_t) (((uint64_t) convertmicrosectodevicetimeu (preamblelen)) >> 8) + 16; |
|
| 955 |
instance_data[instance].fixedReplyDelayAncP = (uint32_t) (((uint64_t) convertmicrosectodevicetimeu ((double)preamblelen)) >> 8) + 16;
|
|
| 982 | 956 |
|
| 983 | 957 |
instance_data[instance].ancRespRxDelay = RX_RESPONSE1_TURNAROUND_6M81 ; |
| 984 | 958 |
} |
| 985 |
|
|
| 986 | 959 |
} |
| 987 | 960 |
|
| 988 | 961 |
// ------------------------------------------------------------------------------------------------------------------- |
Also available in: Unified diff