/*! ---------------------------------------------------------------------------- * @file simple_tx_pdoa.c * @brief Simple TX PDOA example code, companion to Simple RX PDOA example. * See note 7 regarding information on calibrating the system * * @attention * * Copyright 2015 - 2020 (c) Decawave Ltd, Dublin, Ireland. * * All rights reserved. * * @author Decawave */ #include #include #include #include #include #include #if defined(TEST_SIMPLE_TX_PDOA) extern void test_run_info(unsigned char *data); /* Example application name */ #define APP_NAME "SIMPLE TX v1.0" /* Default communication configuration. We use default non-STS DW mode. See note 6 below*/ static dwt_config_t config = { 5, /* Channel number. */ DWT_PLEN_128, /* Preamble length. Used in TX only. */ DWT_PAC8, /* Preamble acquisition chunk size. Used in RX only. */ 9, /* TX preamble code. Used in TX only. */ 9, /* RX preamble code. Used in RX only. */ 1, /* 0 to use standard 8 symbol SFD, 1 to use non-standard 8 symbol, 2 for non-standard 16 symbol SFD and 3 for 4z 8 symbol SDF type */ DWT_BR_6M8, /* Data rate. */ DWT_PHRMODE_STD, /* PHY header mode. */ DWT_PHRRATE_STD, /* PHY header rate. */ (129 + 8 - 8), /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */ (DWT_STS_MODE_1 | DWT_STS_MODE_SDC), /* STS enabled */ DWT_STS_LEN_256, /* STS length see allowed values in Enum dwt_sts_lengths_e */ DWT_PDOA_M1 /* PDOA mode 3 */ }; /* The frame sent in this example is an 802.15.4e standard blink. It is a 12-byte frame composed of the following fields: * - byte 0: frame type (0xC5 for a blink). * - byte 1: sequence number, incremented for each new frame. * - byte 2 -> 9: device ID, see NOTE 1 below. */ static uint8_t tx_msg[] = {0xC5, 0, 'D', 'E', 'C', 'A', 'W', 'A', 'V', 'E'}; /* Index to access to sequence number of the blink frame in the tx_msg array. */ #define BLINK_FRAME_SN_IDX 1 #define FRAME_LENGTH (sizeof(tx_msg)+FCS_LEN) //The real length that is going to be transmitted /* Inter-frame delay period, in milliseconds. */ #define TX_DELAY_MS 500 /* Values for the PG_DELAY and TX_POWER registers reflect the bandwidth and power of the spectrum at the current * temperature. These values can be calibrated prior to taking reference measurements. See NOTE 2 below. */ extern dwt_txconfig_t txconfig_options; /** * Application entry point. */ int simple_tx_pdoa(void) { /* Display application name on LCD. */ test_run_info((unsigned char *)APP_NAME); /* Configure SPI rate, DW3000 supports up to 38 MHz */ port_set_dw_ic_spi_fastrate(); /* Reset DW IC */ reset_DWIC(); /* Target specific drive of RSTn line into DW IC low for a period. */ Sleep(2); // Time needed for DW3000 to start up (transition from INIT_RC to IDLE_RC, or could wait for SPIRDY event) while (!dwt_checkidlerc()) /* Need to make sure DW IC is in IDLE_RC before proceeding */ { }; if (dwt_initialise(DWT_DW_INIT /*| DWT_READ_OTP_PID*/) == DWT_ERROR) { test_run_info((unsigned char *)"INIT FAILED "); while (1) { }; } /* Enabling LEDs here for debug so that for each TX the D1 LED will flash on DW3000 red eval-shield boards. */ dwt_setleds(DWT_LEDS_ENABLE | DWT_LEDS_INIT_BLINK) ; /* Configure DW IC. See NOTE 5 below. */ if(dwt_configure(&config)) /* if the dwt_configure returns DWT_ERROR either the PLL or RX calibration has failed the host should reset the device */ { test_run_info((unsigned char *)"CONFIG FAILED "); while (1) { }; } /* Configure the TX spectrum parameters (power, PG delay and PG count) */ dwt_configuretxrf(&txconfig_options); /* Loop forever sending frames periodically. */ while(1) { /* Write frame data to DW IC and prepare transmission. See NOTE 3 below.*/ dwt_writetxdata(FRAME_LENGTH-FCS_LEN, tx_msg, 0); /* Zero offset in TX buffer. */ /* In this example since the length of the transmitted frame does not change, * nor the other parameters of the dwt_writetxfctrl function, the * dwt_writetxfctrl call could be outside the main while(1) loop. */ dwt_writetxfctrl(FRAME_LENGTH, 0, 0); /* Zero offset in TX buffer, no ranging. */ /* Start transmission. */ dwt_starttx(DWT_START_TX_IMMEDIATE); /* Poll DW IC until TX frame sent event set. See NOTE 4 below. * STATUS register is 4 bytes long but, as the event we are looking at is in the first byte of the register, we can use this simplest API * function to access it.*/ while (!(dwt_read8bitoffsetreg(SYS_STATUS_ID, 0) & SYS_STATUS_TXFRS_BIT_MASK)) { }; /* Clear TX frame sent event. */ dwt_write8bitoffsetreg(SYS_STATUS_ID, 0, SYS_STATUS_TXFRS_BIT_MASK); /* Execute a delay between transmissions. */ Sleep(TX_DELAY_MS); /* Increment the blink frame sequence number (modulo 256). */ tx_msg[BLINK_FRAME_SN_IDX]++; } } #endif /***************************************************************************************************************************************************** * NOTES: * * 1. The device ID is a hard coded constant in the blink to keep the example simple but for a real product every device should have a unique ID. * For development purposes it is possible to generate a DW IC unique ID by combining the Lot ID & Part Number values programmed into the * DW IC during its manufacture. However there is no guarantee this will not conflict with someone elses implementation. We recommended that * customers buy a block of addresses from the IEEE Registration Authority for their production items. See "EUI" in the DW IC User Manual. * 2. In a real application, for optimum performance within regulatory limits, it may be necessary to set TX pulse bandwidth and TX power, (using * the dwt_configuretxrf API call) to per device calibrated values saved in the target system or the DW IC OTP memory. * 3. dwt_writetxdata() takes the full size of tx_msg as a parameter but only copies (size - 2) bytes as the check-sum at the end of the frame is * automatically appended by the DW IC. This means that our tx_msg could be two bytes shorter without losing any data (but the sizeof would not * work anymore then as we would still have to indicate the full length of the frame to dwt_writetxdata()). * 4. We use polled mode of operation here to keep the example as simple as possible but the TXFRS status event can be used to generate an interrupt. * Please refer to DW IC User Manual for more details on "interrupts". * 5. Desired configuration by user may be different to the current programmed configuration. dwt_configure is called to set desired * configuration. * 6. This is the default configuration recommended for optimum performance. An offset between the clocks of the transmitter and receiver will * occur. The DW3000 can tolerate a difference of +/- 20ppm. For optimum performance an offset of +/- 5ppm is recommended * 7. A natural offset will always occur between any two boards. To combat this offset the transmitter and receiver should be placed * with a real PDOA of 0 degrees. When the PDOA is calculated this will return a non-zero value. This value should be subtracted from all * PDOA values obtained by the receiver in order to obtain a calibrated PDOA. ****************************************************************************************************************************************************/