void set_subsequence_settings(uint8_t subseq_num, int role){ #ifdef DW_DEBUG printf("radio conf -> %u\r\n", subseq_num); #endif //Change the channel depending on what subsequence number we're at uint32_t chan = (uint32_t)(subseq_num_to_chan(subseq_num, false)); global_ranging_config.chan = (uint8_t)chan; dwt_configure(&global_ranging_config, 0);//(DWT_LOADANTDLY | DWT_LOADXTALTRIM)); dwt_setsmarttxpower(global_ranging_config.smartPowerEn); global_tx_config.PGdly = pgDelay[global_ranging_config.chan]; global_tx_config.power = txPower[global_ranging_config.chan]; dwt_configuretxrf(&global_tx_config); dwt_setrxantennadelay(0); dwt_settxantennadelay(0); //Change what antenna we're listening on uint8_t ant_sel; if (role == ANCHOR) { ant_sel = subseq_num_to_anchor_sel(subseq_num); } else { // (role == TAG) ant_sel = subseq_num_to_tag_sel(subseq_num); } dw1000_choose_antenna(ant_sel); }
void DWM1000_Anchor::init() { INFO("HSPI"); //_________________________________________________INIT SPI ESP8266 resetChip(); initSpi(); enableIsr(); uint64_t eui = 0xF1F2F3F4F5F6F7F; dwt_seteui((uint8_t*) &eui); dwt_geteui((uint8_t*) &eui); LOG<< HEX << "EUID : "<< eui <<FLUSH; dwt_seteui((uint8_t*) &eui); dwt_geteui((uint8_t*) &eui); LOG<< HEX << "EUID : "<< eui <<FLUSH; // dwt_softreset(); deca_sleep(100); if (dwt_initialise(DWT_LOADUCODE)) { LOG<< " dwt_initialise failed " << FLUSH; } else LOG<< " dwt_initialise done." << FLUSH; if (dwt_configure(&config)) { LOG<< " dwt_configure failed " << FLUSH; } else LOG<< " dwt_configure done." << FLUSH; uint32_t device_id = dwt_readdevid(); uint32_t part_id = dwt_getpartid(); uint32_t lot_id = dwt_getlotid(); LOG<< HEX << " device id : " << device_id << ", part id : " << part_id << ", lot_id :" << lot_id <<FLUSH; /* Apply default antenna delay value. See NOTE 1 below. */ dwt_setrxantennadelay(RX_ANT_DLY); dwt_settxantennadelay(TX_ANT_DLY); /* Set expected response's delay and timeout. See NOTE 4 and 5 below. * As this example only handles one incoming frame with always the same delay and timeout, those values can be set here once for all. */ dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS); dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS); dwt_initialise(DWT_LOADUCODE); // Configure the callbacks from the dwt library dwt_setcallbacks(txcallback, rxcallback); _count = 0; }
void cph_deca_init_device() { dwt_txconfig_t txconfig; // Setup DECAWAVE reset_DW1000(); spi_set_rate_low(); dwt_initialise(DWT_LOADUCODE); spi_set_rate_high(); dwt_configure(&config); // txconfig.PGdly = 0xC2; // for channel 2 // txconfig.power = 0x07274767; // smart power, channel 2, 64MHz // dwt_setsmarttxpower(1); // dwt_configuretxrf(&txconfig); dwt_setrxantennadelay(RX_ANT_DLY); dwt_settxantennadelay(TX_ANT_DLY); }
/** * Application entry point. */ int simpleTx(void) { /* Reset and initialise DW1000. * For initialisation, DW1000 clocks must be temporarily set to crystal speed. After initialisation SPI rate can be increased for optimum * performance. */ reset_DW1000(); /* Target specific drive of RSTn line into DW1000 low for a period. */ //spi_set_rate_low(); dwt_initialise(DWT_LOADNONE); //spi_set_rate_high(); /* Configure DW1000. See NOTE 2 below. */ dwt_configure(&config); /* Loop forever sending frames periodically. */ while(1) { /* Write frame data to DW1000 and prepare transmission. See NOTE 3 below.*/ dwt_writetxdata(sizeof(tx_msg), tx_msg, 0); dwt_writetxfctrl(sizeof(tx_msg), 0); /* Start transmission. */ dwt_starttx(DWT_START_TX_IMMEDIATE); /* Poll DW1000 until TX frame sent event set. See NOTE 4 below. * STATUS register is 5 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 (!(status_reg = dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS)) { }; printf("Status reg now 0x%x\r\n",status_reg); /* Clear TX frame sent event. */ dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS); /* Execute a delay between transmissions. */ deca_sleep(TX_DELAY_MS); // toggle led ledToggle(); /* Increment the blink frame sequence number (modulo 256). */ tx_msg[BLINK_FRAME_SN_IDX]++; } }
void cph_deca_init_device() { dwt_txconfig_t txconfig; TRACE("ant dly: %d %d\r\n", RX_ANT_DLY, TX_ANT_DLY); // Setup DECAWAVE reset_DW1000(); spi_set_rate_low(); dwt_initialise(DWT_LOADUCODE); spi_set_rate_high(); dwt_configure(&cph_config->dwt_config); dwt_setrxantennadelay(RX_ANT_DLY); dwt_settxantennadelay(TX_ANT_DLY); TRACE("ant dly: %d %d\r\n", RX_ANT_DLY, TX_ANT_DLY); // Clear CLKPLL_LL dwt_write32bitreg(SYS_STATUS_ID, 0x02000000); }
int powertest(void) { dwt_config_t configData ; dwt_txconfig_t configTx ; uint8 pow; 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"; //NOTE: SPI frequency must be < 3MHz //reduce the SPI speed before switching to XTAL // // reset device // dwt_softreset(); // // configure channel paramters // configData.chan = 2 ; configData.rxCode = 9 ; configData.txCode = 9 ; configData.prf = DWT_PRF_64M ; configData.dataRate = DWT_BR_110K ; configData.txPreambLength = DWT_PLEN_2048 ; configData.rxPAC = DWT_PAC64 ; configData.nsSFD = 1 ; configData.smartPowerEn = 0; dwt_configure(&configData, DWT_LOADANTDLY | DWT_LOADXTALTRIM) ; configTx.PGdly = txSpectrumConfig[configData.chan].PGdelay ; if(configData.smartPowerEn == 0) { pow = txSpectrumConfig[configData.chan].txPwr[configData.prf - DWT_PRF_16M] & 0xFF ; configTx.power = (pow | (pow << 8) | (pow << 16) | (pow << 24)); } else { configTx.power = txSpectrumConfig[configData.chan].txPwr[configData.prf - DWT_PRF_16M]; } dwt_configuretxrf(&configTx); // the value here 0x1000 gives a period of 32.82 �s //this is setting 0x1000 as frame period (125MHz clock cycles) (time from Tx en - to next - Tx en) dwt_configcontinuousframemode(0x1000); dwt_writetxdata(127, (uint8 *) msg, 0) ; dwt_writetxfctrl(127, 0); //to start the first frame - set TXSTRT dwt_starttx(DWT_START_TX_IMMEDIATE); //measure the power //Spectrum Analyser set: //FREQ to be channel default e.g. 3.9936 GHz for channel 2 //SPAN to 1GHz //SWEEP TIME 1s //RBW and VBW 1MHz //measure channel power return DWT_SUCCESS ; }
int main() { Xil_ICacheEnable(); Xil_DCacheEnable(); print("---Entering main---\n\r"); { printf("LEDs and switches\r\n"); XGpio_Initialize(&inGpio,XPAR_AXI_GPIO_1_DEVICE_ID); XGpio_Initialize(&outGpio,XPAR_AXI_GPIO_0_DEVICE_ID); XGpio_DiscreteWrite(&outGpio,1,0); // leds off } { printf("Deca SPI test\r\n"); if (0 != openspi()){ printf("Init SPI failed\r\n"); } else { // get switches int sw = XGpio_DiscreteRead(&inGpio,1); XGpio_DiscreteWrite(&outGpio,1,sw); //printf("LED: %x\r\n",XGpio_DiscreteRead(&outGpio,1)); switch (sw & 0x7){ case 1: printf("SS TWR INIT\r\n"); ssTwrInit(); break; case 2: printf("SS TWR RESP\r\n"); ssTwrResp(); break; case 3: printf("Simple TX\r\n"); simpleTx(); break; case 4: printf("Simple RX\r\n"); simpleRx(); break; case 5: printf("TX Wait\r\n"); txWait(); break; case 6: printf("RX Wait\r\n"); rxWait(); break; default: /* Reset and initialise DW1000. */ reset_DW1000(); dwt_initialise(DWT_LOADNONE); /* Configure DW1000. */ printf("UBW configuration sequence\r\n"); dwt_configure(&config); dwt_configuretxrf(&txconfig); /* Activate continuous wave mode. */ dwt_configcwmode(config.chan); /* Wait for the wanted duration of the continuous wave transmission. */ printf("Waiting for UBW continuous wave transmission delay: %ds\r\n",CONT_WAVE_DURATION_MS/1000); deca_sleep(CONT_WAVE_DURATION_MS); /* Software reset of the DW1000 to deactivate continuous wave mode and go back to default state. Initialisation and configuration should be run * again if one wants to get the DW1000 back to normal operation. */ dwt_softreset(); } printf("Deca test done. press any key\r\n"); getchar(); } } print("---Exiting main---\n\r"); Xil_DCacheDisable(); Xil_ICacheDisable(); return 0; }
int app_dw1000_init ( int HACK_role, int HACK_EUI, void (*txcallback)(const dwt_callback_data_t *), void (*rxcallback)(const dwt_callback_data_t *) ) { uint32_t devID; int err; // Start off DW1000 comms slow REG(SSI0_BASE + SSI_CR1) = 0; REG(SSI0_BASE + SSI_CPSR) = 8; REG(SSI0_BASE + SSI_CR1) |= SSI_CR1_SSE; // Reset the DW1000...for some reason dw1000_reset(); // Make sure we can talk to the DW1000 devID = dwt_readdevid(); if (devID != DWT_DEVICE_ID) { #ifdef DW_DEBUG printf("Could not read Device ID from the DW1000\r\n"); printf("Possible the chip is asleep...\r\n"); #endif return -1; } // Select which of the three antennas on the board to use dw1000_choose_antenna(0); // Init the dw1000 hardware err = dwt_initialise(DWT_LOADUCODE | DWT_LOADLDO | DWT_LOADTXCONFIG | DWT_LOADXTALTRIM); if (err != DWT_SUCCESS) { return -1; } // Setup interrupts // Note: using auto rx re-enable so don't need to trigger on error frames dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | DWT_INT_SFDT | DWT_INT_RFTO | DWT_INT_RPHE | DWT_INT_RFCE | DWT_INT_RFSL | DWT_INT_RXPTO | DWT_INT_SFDT, 1); // Configure the callbacks from the dwt library dwt_setcallbacks(txcallback, rxcallback); // Set the parameters of ranging and channel and whatnot global_ranging_config.chan = 2; global_ranging_config.prf = DWT_PRF_64M; global_ranging_config.txPreambLength = DWT_PLEN_64;//DWT_PLEN_4096 // global_ranging_config.txPreambLength = DWT_PLEN_256; global_ranging_config.rxPAC = DWT_PAC8; global_ranging_config.txCode = 9; // preamble code global_ranging_config.rxCode = 9; // preamble code global_ranging_config.nsSFD = 0; global_ranging_config.dataRate = DWT_BR_6M8; global_ranging_config.phrMode = DWT_PHRMODE_EXT; //Enable extended PHR mode (up to 1024-byte packets) global_ranging_config.smartPowerEn = 1; global_ranging_config.sfdTO = 64+8+1;//(1025 + 64 - 32); dwt_configure(&global_ranging_config, 0);//(DWT_LOADANTDLY | DWT_LOADXTALTRIM)); dwt_setsmarttxpower(global_ranging_config.smartPowerEn); // Configure TX power { global_tx_config.PGdly = pgDelay[global_ranging_config.chan]; global_tx_config.power = txPower[global_ranging_config.chan]; dwt_configuretxrf(&global_tx_config); } /* All constants same anyway if(DW1000_ROLE_TYPE == TAG) dwt_xtaltrim(xtaltrim[0]); else dwt_xtaltrim(xtaltrim[ANCHOR_EUI]); */ dwt_xtaltrim(xtaltrim[0]); ////TEST 1: XTAL trim calibration //dwt_configcwmode(global_ranging_config.chan); //dwt_xtaltrim(8); //while(1); //{ // //TEST 2: TX Power level calibration // uint8_t 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"; // dwt_configcontinuousframemode(0x1000); // dwt_writetxdata(127, (uint8 *) msg, 0) ; // dwt_writetxfctrl(127, 0); // dwt_starttx(DWT_START_TX_IMMEDIATE); // while(1); //} // Configure the antenna delay settings { uint16_t antenna_delay; //Antenna delay not really necessary if we're doing an end-to-end calibration antenna_delay = 0; dwt_setrxantennadelay(antenna_delay); dwt_settxantennadelay(antenna_delay); //global_tx_antenna_delay = antenna_delay; //// Shift this over a bit for some reason. Who knows. //// instance_common.c:508 //antenna_delay = dwt_readantennadelay(global_ranging_config.prf) >> 1; //if (antenna_delay == 0) { // printf("resetting antenna delay\r\n"); // // If it's not in the OTP, use a magic value from instance_calib.c // antenna_delay = ((DWT_PRF_64M_RFDLY/ 2.0) * 1e-9 / DWT_TIME_UNITS); // dwt_setrxantennadelay(antenna_delay); // dwt_settxantennadelay(antenna_delay); //} //global_tx_antenna_delay = antenna_delay; //printf("tx antenna delay: %u\r\n", antenna_delay); } // // Set the sleep delay. Not sure what this does actually. // instancesettagsleepdelay(POLL_SLEEP_DELAY, BLINK_SLEEP_DELAY); // Configure as either a tag or anchor if (HACK_role == ANCHOR) { uint8_t eui_array[8]; // Enable frame filtering dwt_enableframefilter(DWT_FF_DATA_EN | DWT_FF_ACK_EN); dw1000_populate_eui(eui_array, HACK_EUI); dwt_seteui(eui_array); dwt_setpanid(DW1000_PANID); // We do want to enable auto RX dwt_setautorxreenable(1); // Let's do double buffering dwt_setdblrxbuffmode(0); // Disable RX timeout by setting to 0 dwt_setrxtimeout(0); // Go for receiving dwt_rxenable(0); } else if (HACK_role == TAG) { uint8_t eui_array[8]; // Allow data and ack frames dwt_enableframefilter(DWT_FF_DATA_EN | DWT_FF_ACK_EN); dw1000_populate_eui(eui_array, HACK_EUI); dwt_seteui(eui_array); dwt_setpanid(DW1000_PANID); // Do this for the tag too dwt_setautorxreenable(1); dwt_setdblrxbuffmode(1); dwt_enableautoack(5 /*ACK_RESPONSE_TIME*/); // Configure sleep { int mode = DWT_LOADUCODE | DWT_PRESRV_SLEEP | DWT_CONFIG | DWT_TANDV; if (dwt_getldotune() != 0) { // If we need to use LDO tune value from OTP kick it after sleep mode |= DWT_LOADLDO; } // NOTE: on the EVK1000 the DEEPSLEEP is not actually putting the // DW1000 into full DEEPSLEEP mode as XTAL is kept on dwt_configuresleep(mode, DWT_WAKE_CS | DWT_SLP_EN); } } // Make it fast REG(SSI0_BASE + SSI_CR1) = 0; REG(SSI0_BASE + SSI_CPSR) = 2; REG(SSI0_BASE + SSI_CR1) |= SSI_CR1_SSE; return 0; }
// First (generic) init of the DW1000 dw1000_err_e dw1000_init () { // Do the STM setup that initializes pin and peripherals and whatnot. if (!_stm_dw1000_interface_setup) { setup(); } // Reset the dw1000...for some reason dw1000_reset(); uDelay(100); // Make sure we can talk to the DW1000 uint32_t devID; devID = dwt_readdevid(); if (devID != DWT_DEVICE_ID) { //if we can't talk to dw1000, return with an error uDelay(1000); return DW1000_COMM_ERR; } GPIO_WriteBit(STM_GPIO3_PORT, STM_GPIO3_PIN, Bit_SET); uDelay(1000); GPIO_WriteBit(STM_GPIO3_PORT, STM_GPIO3_PIN, Bit_RESET); // Choose antenna 0 as a default dw1000_choose_antenna(0); // Initialize the dw1000 hardware uint32_t err; err = dwt_initialise(DWT_LOADUCODE | DWT_LOADLDO | DWT_LOADTXCONFIG | DWT_LOADXTALTRIM); if (err != DWT_SUCCESS) { return DW1000_COMM_ERR; } // Configure interrupts and callbacks dwt_setinterrupt(0xFFFFFFFF, 0); dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | DWT_INT_RPHE | DWT_INT_RFCE | DWT_INT_RFSL | DWT_INT_RFTO | DWT_INT_RXPTO | DWT_INT_SFDT | DWT_INT_ARFE, 1); dwt_setcallbacks(txcallback, rxcallback); // Set the parameters of ranging and channel and whatnot global_ranging_config.chan = 2; global_ranging_config.prf = DWT_PRF_64M; global_ranging_config.txPreambLength = DWT_PLEN_64; global_ranging_config.rxPAC = DWT_PAC8; global_ranging_config.txCode = 9; // preamble code global_ranging_config.rxCode = 9; // preamble code global_ranging_config.nsSFD = 0; global_ranging_config.dataRate = DWT_BR_6M8; global_ranging_config.phrMode = DWT_PHRMODE_EXT; //Enable extended PHR mode (up to 1024-byte packets) global_ranging_config.smartPowerEn = 1; global_ranging_config.sfdTO = 64+8+1;//(1025 + 64 - 32); #if DW1000_USE_OTP dwt_configure(&global_ranging_config, (DWT_LOADANTDLY | DWT_LOADXTALTRIM)); #else dwt_configure(&global_ranging_config, 0); #endif dwt_setsmarttxpower(global_ranging_config.smartPowerEn); // Configure TX power based on the channel used global_tx_config.PGdly = pgDelay[global_ranging_config.chan]; global_tx_config.power = txPower[global_ranging_config.chan]; dwt_configuretxrf(&global_tx_config); // Need to set some radio properties. Ideally these would come from the // OTP memory on the DW1000 #if DW1000_USE_OTP == 0 // This defaults to 8. Don't know why. dwt_xtaltrim(8); // Antenna delay we don't really care about so we just use 0 dwt_setrxantennadelay(DW1000_ANTENNA_DELAY_RX); dwt_settxantennadelay(DW1000_ANTENNA_DELAY_TX); #endif return DW1000_NO_ERR; }
/** * Application entry point. */ int rxWait(void) { /* Reset and initialise DW1000. * For initialisation, DW1000 clocks must be temporarily set to crystal speed. After initialisation SPI rate can be increased for optimum * performance. */ int i; reset_DW1000(); /* Target specific drive of RSTn line into DW1000 low for a period. */ //spi_set_rate_low(); dwt_initialise(DWT_LOADNONE); //spi_set_rate_high(); /* Configure DW1000. See NOTE 2 below. */ dwt_configure(&config); /* Loop forever sending and receiving frames periodically. */ while (1) { /* Activate reception immediately. See NOTE 3 below. */ dwt_rxenable(0); /* Poll until a frame is properly received or an error occurs. See NOTE 4 below. * STATUS register is 5 bytes long but, as the events we are looking at are in the lower bytes of the register, we can use this simplest API * function to access it. */ while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR))) { }; printf("Status reg now 0x%x\r\n",status_reg); if (status_reg & SYS_STATUS_RXFCG) { /* A frame has been received, read it into the local buffer. */ frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023; if (frame_len <= FRAME_LEN_MAX) { dwt_readrxdata(rx_buffer, frame_len, 0); } /* Clear good RX frame event in the DW1000 status register. */ dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG); for (i=0;i<frame_len;i++) { printf("%x ",rx_buffer[i]); } printf("\r\n"); /* Validate the frame is the one expected as sent by "TX then wait for a response" example. */ if ((frame_len == 14) && (rx_buffer[0] == 0xC5) && (rx_buffer[10] == 0x43) && (rx_buffer[11] == 0x2)) { int i; /* Copy source address of blink in response destination address. */ for (i = 0; i < 8; i++) { tx_msg[DATA_FRAME_DEST_IDX + i] = rx_buffer[BLINK_FRAME_SRC_IDX + i]; } /* Write response frame data to DW1000 and prepare transmission. See NOTE 5 below.*/ dwt_writetxdata(sizeof(tx_msg), tx_msg, 0); dwt_writetxfctrl(sizeof(tx_msg), 0); /* Send the response. */ dwt_starttx(DWT_START_TX_IMMEDIATE); /* Poll DW1000 until TX frame sent event set. */ while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS)) { }; /* Clear TX frame sent event. */ dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS); /* Increment the data frame sequence number (modulo 256). */ tx_msg[DATA_FRAME_SN_IDX]++; } } else { /* Clear RX error events in the DW1000 status register. */ dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR); printf("Some RX errors ...\r\n"); } } }
void listener_run(void) { uint32_t announce_coord_ts = 0; uint32_t elapsed = 0; uint32_t last_ts = 0; uint32_t count = 0; irq_init(); pio_disable_interrupt(DW_IRQ_PIO, DW_IRQ_MASK); // Setup DW1000 dwt_txconfig_t txconfig; // Setup DECAWAVE reset_DW1000(); spi_set_rate_low(); dwt_initialise(DWT_LOADUCODE); spi_set_rate_high(); dwt_configure(&cph_config->dwt_config); dwt_setpanid(0x4350); dwt_setaddress16(0x1234); // Clear CLKPLL_LL dwt_write32bitreg(SYS_STATUS_ID, 0x02000000); uint32_t id = dwt_readdevid(); printf("Device ID: %08X\r\n", id); #if 1 dwt_setcallbacks(0, rxcallback); dwt_setinterrupt( DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_ARFE | DWT_INT_RFSL | DWT_INT_SFDT | DWT_INT_RPHE | DWT_INT_RFCE | DWT_INT_RFTO /*| DWT_INT_RXPTO*/), 1); pio_enable_interrupt(DW_IRQ_PIO, DW_IRQ_MASK); dwt_rxenable(0); while (1) { elapsed = cph_get_millis() - last_ts; if (elapsed > 5000) { printf("alive %d\r\n", count++); last_ts = cph_get_millis(); } if (trx_signal == SIGNAL_RCV) { printf("[RCV] %d - ", frame_len); for (int i = 0; i < frame_len; i++) { printf("%02X ", rx_buffer[i]); } printf("\r\n"); trx_signal = SIGNAL_EMPTY; dwt_rxenable(0); } else if(trx_signal == SIGNAL_ERR) { printf("ERROR: %08X\r\n", error_status_reg); trx_signal = SIGNAL_EMPTY; dwt_rxenable(0); } else if(trx_signal == SIGNAL_ERR_LEN) { printf("ERROR LENGTH: %08X\r\n", error_status_reg); trx_signal = SIGNAL_EMPTY; dwt_rxenable(0); } } #else while (1) { /* Activate reception immediately. */ dwt_rxenable(0); while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR))) { }; if (status_reg & SYS_STATUS_RXFCG) { uint32 frame_len; dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG); frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023; if (frame_len <= MAXRXSIXZE) { dwt_readrxdata(rx_buffer, frame_len, 0); } else { frame_len = 0; } if (frame_len > 0) { printf("[RCV] "); for (int i = 0; i < frame_len; i++) { printf("%02X ", rx_buffer[i]); } printf("\r\n"); } else { printf("ERROR: frame_len == %d\r\n", frame_len); } } else { printf("ERROR: dwt_rxenable has status of %08X\r\n", status_reg); /* Clear RX error events in the DW1000 status register. */ dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR | SYS_STATUS_CLKPLL_LL); } } #endif }
/*! ------------------------------------------------------------------------------------------------------------------ * @fn main() * * @brief Application entry point. * * @param none * * @return none */ int ssTwrInit(void) { /* Reset and initialise DW1000. * For initialisation, DW1000 clocks must be temporarily set to crystal speed. After initialisation SPI rate can be increased for optimum * performance. */ int status; reset_DW1000(); /* Target specific drive of RSTn line into DW1000 low for a period. */ //spi_set_rate_low(); status = dwt_initialise(DWT_LOADUCODE); if (DWT_SUCCESS != status) printf("API error line %d\r\n",__LINE__); //spi_set_rate_high(); /* Configure DW1000. See NOTE 6 below. */ status = dwt_configure(&config); if (DWT_SUCCESS != status) printf("API error line %d\r\n",__LINE__); // read otp uint32_t otpVal[0x20]; dwt_otpread(0,otpVal,0x20); printf("OTP 6: 0x%x\r\n",otpVal[6]); printf("OTP 7: 0x%x\r\n",otpVal[7]); printf("OTP x16: 0x%x\r\n",otpVal[0x16]); printf("OTP x17: 0x%x\r\n",otpVal[0x17]); /* Apply default antenna delay value. See NOTE 2 below. */ printf("antenna delays: default TX: %d, default RX: %d, evk 16m: %d, evk 64m: %d\r\n",TX_ANT_DLY,RX_ANT_DLY,DWT_RF_DELAY_16M,DWT_RF_DELAY_64M); tx_delay = TX_ANT_DLY; rx_delay = RX_ANT_DLY; dwt_setrxantennadelay(rx_delay); dwt_settxantennadelay(tx_delay); /* Set expected response's delay and timeout. See NOTE 1 and 5 below. * As this example only handles one incoming frame with always the same delay and timeout, those values can be set here once for all. */ dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS); dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS); btn = buttons(); printf("%s entering main loop\r\n",__FUNCTION__); /* Loop forever initiating ranging exchanges. */ while (1) { /* Write frame data to DW1000 and prepare transmission. See NOTE 7 below. */ tx_poll_msg[ALL_MSG_SN_IDX] = frame_seq_nb; status = dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS); if (DWT_SUCCESS != status) printf("API error line %d\r\n",__LINE__); status = dwt_writetxdata(sizeof(tx_poll_msg), tx_poll_msg, 0); if (DWT_SUCCESS != status) printf("API error line %d\r\n",__LINE__); status = dwt_writetxfctrl(sizeof(tx_poll_msg), 0); if (DWT_SUCCESS != status) printf("API error line %d\r\n",__LINE__); /* Start transmission, indicating that a response is expected so that reception is enabled automatically after the frame is sent and the delay * set by dwt_setrxaftertxdelay() has elapsed. */ status = dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED); if (DWT_SUCCESS != status) printf("API error line %d\r\n",__LINE__); /* We assume that the transmission is achieved correctly, poll for reception of a frame or error/timeout. See NOTE 8 below. */ while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR))) { } ; // printf("Waiting. status reg 0x%x\r\n",status_reg); }; //printf("Status reg now 0x%x\r\n",status_reg); if (SYS_STATUS_RXRFTO & status_reg) printf("RX timeout\r\n"); /* Increment frame sequence number after transmission of the poll message (modulo 256). */ frame_seq_nb++; if (status_reg & SYS_STATUS_RXFCG) { uint32 frame_len; //printf("Check RX\r\n"); /* Clear good RX frame event in the DW1000 status register. */ dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG); /* A frame has been received, read it into the local buffer. */ frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK; if (frame_len <= RX_BUF_LEN) { dwt_readrxdata(rx_buffer, frame_len, 0); } /* Check that the frame is the expected response from the companion "SS TWR responder" example. * As the sequence number field of the frame is not relevant, it is cleared to simplify the validation of the frame. */ rx_buffer[ALL_MSG_SN_IDX] = 0; if (memcmp(rx_buffer, rx_resp_msg, ALL_MSG_COMMON_LEN) == 0) { uint32 poll_tx_ts, resp_rx_ts, poll_rx_ts, resp_tx_ts; int32 rtd_init, rtd_resp; /* Retrieve poll transmission and response reception timestamps. See NOTE 9 below. */ poll_tx_ts = dwt_readtxtimestamplo32(); resp_rx_ts = dwt_readrxtimestamplo32(); /* Get timestamps embedded in response message. */ resp_msg_get_ts(&rx_buffer[RESP_MSG_POLL_RX_TS_IDX], &poll_rx_ts); resp_msg_get_ts(&rx_buffer[RESP_MSG_RESP_TX_TS_IDX], &resp_tx_ts); /* Compute time of flight and distance. */ rtd_init = resp_rx_ts - poll_tx_ts; rtd_resp = resp_tx_ts - poll_rx_ts; tof = ((rtd_init - rtd_resp) / 2.0) * DWT_TIME_UNITS; distance = tof * SPEED_OF_LIGHT; /* Display computed distance on LCD. */ //sprintf(dist_str, "DIST: %3.2f m", distance); sprintf(dist_str, "%3.2f", distance); printf("%s\r\n",dist_str); //lcd_display_str(dist_str); } } else { /* Clear RX error events in the DW1000 status register. */ printf("Errors occured. Clearing up\r\n"); dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR); } /* Execute a delay between ranging exchanges. */ //printf("Delay %dms\r\n",RNG_DELAY_MS); deca_sleep(RNG_DELAY_MS); // toggle led ledToggle(); // update antenna if (buttons() & 1) { tx_delay -= 10; // >>= 1; rx_delay -= 10; //>>= 1; dwt_setrxantennadelay(rx_delay); dwt_settxantennadelay(tx_delay); printf("Decreased antenna delay to 0x%x\r\n",tx_delay); } if (buttons() & 2) { tx_delay += 10; rx_delay += 10; dwt_setrxantennadelay(rx_delay); dwt_settxantennadelay(tx_delay); printf("Increased antenna delay to 0x%x\r\n",tx_delay); } } }
/* ********************************************************************************************************* * * loca_status dwt_config(eCHAN channel, ePRF prf, ePLEN PreambleLength, eCODE code, uint8_t nsSFD, DataRate db) * * 描 述 : 配置DW1000 * * 输入参数 : * channel:DW1000通道 prf: PreambleLength: code: nsSFD: db: * * 输出参数 : DW1000状态 ********************************************************************************************************* */ static loca_status dwt_config(eCHAN channel, ePRF prf, ePLEN PreambleLength, eCODE code, uint8_t nsSFD, DataRate db) { dwt_config_t config; dwt_txconfig_t txconfig; uint8_t buf[2]; uint64_t eui64; uint16_t panid; eui64 = LOC_CFG_EUI; panid = LOC_CFG_PANID; config.chan = channel; config.prf = prf; config.txPreambLength = PreambleLength; switch (PreambleLength) { case PLEN_64: case PLEN_128: config.rxPAC = DWT_PAC8; break; case PLEN_256: case PLEN_512: config.rxPAC = DWT_PAC16; break; case PLEN_1024: config.rxPAC = DWT_PAC32; break; default: config.rxPAC = DWT_PAC64; break; } config.rxCode = code; config.txCode = code; config.nsSFD = nsSFD; config.dataRate = db; config.smartPowerEn = 0; config.phrMode = 0; txconfig.PGdly = dwt_pgdelay[channel]; txconfig.power = dwt_manualpwr[prf - 1][channel]; BSP_ChangeSPIRate(SPI_SLOW); dwt_softreset(); if (dwt_initialise(DWT_LOADNONE) != DWT_SUCCESS) { BSP_ChangeSPIRate(SPI_FAST); return LOCA_FAULT; } BSP_ChangeSPIRate(SPI_FAST); if (dwt_readdevid() != DWT_DEVICE_ID) { return LOCA_FAULT; } buf[0] = 0x10; dwt_writetodevice(GPIO_CTRL_ID,0x02,1,&buf[0]); buf[0] = 0xf0; buf[1] = 0xf0; dwt_writetodevice(GPIO_CTRL_ID,0x08,2,&buf[0]); dwt_configure(&config, 0); dwt_xtaltrim(LOC_CFG_XTALRIM); dwt_setrxantennadelay(0); dwt_settxantennadelay(0); dwt_setsmarttxpower(0); dwt_configuretxrf(&txconfig); dwt_enableframefilter(DWT_FF_NOTYPE_EN); dwt_seteui((uint8_t *)&eui64); dwt_setpanid(panid); //开启硬件中断 //BSP_DWTIntEnable(); // dwt_setinterrupt( DWT_INT_TFRS, 1); dwt_setrxmode(DWT_RX_NORMAL,0,0); return LOCA_OK; }
void config_data(data_t *data) { int use_otpdata = DWT_LOADANTDLY | DWT_LOADXTALTRIM; uint32 power = 0; data->configData.chan = 5 ; data->configData.rxCode = 9; data->configData.txCode = 9 ; data->configData.prf = DWT_PRF_64M ; data->configData.dataRate = DWT_BR_6M8 ; data->configData.txPreambLength = DWT_PLEN_128 ; data->configData.rxPAC = DWT_PAC8 ; data->configData.nsSFD = 0 ; data->configData.phrMode = DWT_PHRMODE_STD ; data->configData.sfdTO = (129 + 8 - 8); //enable gating gain for 6.81Mbps data rate if(data->configData.dataRate == DWT_BR_6M8) data->configData.smartPowerEn = 1; else data->configData.smartPowerEn = 0; //configure the channel parameters dwt_configure(&data->configData, use_otpdata) ; data->configTX.PGdly = txSpectrumConfig[data->configData.chan].PGdelay ; //firstly check if there are calibrated TX power value in the DW1000 OTP power = dwt_getotptxpower(data->configData.prf, data->configData.chan); if((power == 0x0) || (power == 0xFFFFFFFF)) //if there are no calibrated values... need to use defaults { power = txSpectrumConfig[data->configData.chan].txPwr[data->configData.prf- DWT_PRF_16M]; } //Configure TX power //if smart power is used then the value as read from OTP is used directly //if smart power is used the user needs to make sure to transmit only one frame per 1ms or TX spectrum power will be violated if(data->configData.smartPowerEn == 1) { data->configTX.power = power; } else //if the smart power is not used, then the low byte value (repeated) is used for the whole TX power register { uint8 pow = power & 0xFF ; data->configTX.power = (pow | (pow << 8) | (pow << 16) | (pow << 24)); } dwt_setsmarttxpower(data->configData.smartPowerEn); //configure the tx spectrum parameters (power and PG delay) dwt_configuretxrf(&data->configTX); //check if to use the antenna delay calibration values as read from the OTP if((use_otpdata & DWT_LOADANTDLY) == 0) { data->txantennaDelay = rfDelays[data->configData.prf - DWT_PRF_16M]; // ------------------------------------------------------------------------------------------------------------------- // set the antenna delay, we assume that the RX is the same as TX. dwt_setrxantennadelay(data->txantennaDelay); dwt_settxantennadelay(data->txantennaDelay); } else { //get the antenna delay that was read from the OTP calibration area data->txantennaDelay = dwt_readantennadelay(data->configData.prf) >> 1; // if nothing was actually programmed then set a reasonable value anyway if (data->txantennaDelay == 0) { data->txantennaDelay = rfDelays[data->configData.prf - DWT_PRF_16M]; // ------------------------------------------------------------------------------------------------------------------- // set the antenna delay, we assume that the RX is the same as TX. dwt_setrxantennadelay(data->txantennaDelay); dwt_settxantennadelay(data->txantennaDelay); } } if(data->configData.txPreambLength == DWT_PLEN_64) //if preamble length is 64 { SPI_ConfigFastRate(SPI_BaudRatePrescaler_16); //reduce SPI to < 3MHz dwt_loadopsettabfromotp(0); SPI_ConfigFastRate(SPI_BaudRatePrescaler_4); //increase SPI to max } //config is needed before reply delays are configured }
/*! ------------------------------------------------------------------------------------------------------------------ * @fn main() * * @brief Application entry point. * * @param none * * @return none */ int ssTwrResp(void) { /* Reset and initialise DW1000. * For initialisation, DW1000 clocks must be temporarily set to crystal speed. After initialisation SPI rate can be increased for optimum * performance. */ int i; int status; reset_DW1000(); /* Target specific drive of RSTn line into DW1000 low for a period. */ //spi_set_rate_low(); dwt_initialise(DWT_LOADUCODE); //spi_set_rate_high(); /* Configure DW1000. See NOTE 5 below. */ dwt_configure(&config); uint32_t otpVal[0x20]; dwt_otpread(0,otpVal,0x20); printf("OTP 6: 0x%x\r\n",otpVal[6]); printf("OTP 7: 0x%x\r\n",otpVal[7]); printf("OTP x16: 0x%x\r\n",otpVal[0x16]); printf("OTP x17: 0x%x\r\n",otpVal[0x17]); /* Apply default antenna delay value. See NOTE 2 below. */ printf("antenna delays: default TX: %d, default RX: %d, evk 16m: %d, evk 64m: %d\r\n",TX_ANT_DLY,RX_ANT_DLY,DWT_RF_DELAY_16M,DWT_RF_DELAY_64M); tx_delay = TX_ANT_DLY; rx_delay = RX_ANT_DLY; dwt_setrxantennadelay(rx_delay); dwt_settxantennadelay(tx_delay); btn = buttons(); printf("%s entering main loop\r\n",__FUNCTION__); /* Loop forever responding to ranging requests. */ while (1) { /* Activate reception immediately. */ dwt_rxenable(0); /* Poll for reception of a frame or error/timeout. See NOTE 6 below. */ while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR))) { } ; //printf("Waiting. status reg 0x%x\r\n",status_reg); }; //printf("Status reg now 0x%x\r\n",status_reg); if (status_reg & SYS_STATUS_RXFCG) { uint32 frame_len; //printf("Check RX\r\n"); /* Clear good RX frame event in the DW1000 status register. */ dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG); /* A frame has been received, read it into the local buffer. */ frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023; //printf("Frame length %d\r\n",frame_len); if (frame_len <= RX_BUFFER_LEN) { dwt_readrxdata(rx_buffer, frame_len, 0); } /* for (i=0;i<frame_len;i++) { printf("%x ",rx_buffer[i]); } printf("\r\n"); */ /* Check that the frame is a poll sent by "SS TWR initiator" example. * As the sequence number field of the frame is not relevant, it is cleared to simplify the validation of the frame. */ rx_buffer[ALL_MSG_SN_IDX] = 0; if (memcmp(rx_buffer, rx_poll_msg, ALL_MSG_COMMON_LEN) == 0) { uint32 resp_tx_time; //printf("Poll MSG\r\n"); /* Retrieve poll reception timestamp. */ poll_rx_ts = get_rx_timestamp_u64(); //printf("RX timestamp: %lld\r\n",poll_rx_ts); /* Compute final message transmission time. See NOTE 7 below. */ resp_tx_time = (poll_rx_ts + (POLL_RX_TO_RESP_TX_DLY_UUS * UUS_TO_DWT_TIME)) >> 8; dwt_setdelayedtrxtime(resp_tx_time); //printf("TX time: %d\r\n",resp_tx_time); /* Response TX timestamp is the transmission time we programmed plus the antenna delay. */ resp_tx_ts = (((uint64)(resp_tx_time & 0xFFFFFFFE)) << 8) + TX_ANT_DLY; //printf("TX timestamp: %lld\r\n",resp_tx_ts); /* Write all timestamps in the final message. See NOTE 8 below. */ resp_msg_set_ts(&tx_resp_msg[RESP_MSG_POLL_RX_TS_IDX], poll_rx_ts); resp_msg_set_ts(&tx_resp_msg[RESP_MSG_RESP_TX_TS_IDX], resp_tx_ts); /* Write and send the response message. See NOTE 9 below. */ tx_resp_msg[ALL_MSG_SN_IDX] = frame_seq_nb; status = dwt_writetxdata(sizeof(tx_resp_msg), tx_resp_msg, 0); if (DWT_SUCCESS != status) printf("API error line %d\r\n",__LINE__); status = dwt_writetxfctrl(sizeof(tx_resp_msg), 0); if (DWT_SUCCESS != status) printf("API error line %d\r\n",__LINE__); status = dwt_starttx(DWT_START_TX_DELAYED); if (DWT_SUCCESS != status) { printf("API error line %d\r\n",__LINE__); printf("RX timestamp: %llu\r\n",poll_rx_ts); printf("TX time: %llu\r\n",((uint64)resp_tx_time) << 8); printf("TX timestamp: %llu\r\n",resp_tx_ts); } // poll only if starttx was OK if (DWT_SUCCESS == status) { /* Poll DW1000 until TX frame sent event set. See NOTE 6 below. */ u32 tx_stat; while (!(tx_stat = dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS)) { }; //printf("Waiting. status reg 0x%x\r\n",tx_stat); } //printf("After Poll: status reg now 0x%x\r\n",tx_stat); } /* Clear TXFRS event. */ dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS); /* Increment frame sequence number after transmission of the poll message (modulo 256). */ frame_seq_nb++; } }