Hi,
Here is a function to do simple_tx (no interrupts so you make sure it works, disable DWM3000 interrupts before!!!). It works, and we used some functions built by ourselves that I attached at the end of the simple_tx() function. Try it !
int simple_tx(void)
{
uint32_t dev_id;
/* Configure SPI rate, DW3000 supports up to 36 MHz */
port_set_dw_ic_spi_slowrate();
wakeup_device_with_io(); //without this it hardfaults
/* 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)
/* Probe for the correct device driver. */
dwt_probe((struct dwt_probe_s *)&dw3000_probe_interf); // if no hard fault it is ok
dev_id = dwt_readdevid();
// dev_id = my_dwm3000_read32bitoffsetreg_packeted(0,0); //reads the devID directly. CHECKING THAT myRead32bit works, the code should work normally.
while (!dwt_checkidlerc()) /* Need to make sure DW IC is in IDLE_RC before proceeding */ { };
port_set_dw_ic_spi_fastrate();
if (dwt_initialise(DWT_DW_INIT) == DWT_ERROR)
{
while (1) { }; // you can retry but in this case just a forever loop
}
uint32_t CHAN_CTRL_reg = my_dwm3000_read32bitoffsetreg_packeted(0x01,0x14);
uint32_t RX_FINFO_reg = my_dwm3000_read32bitoffsetreg_packeted(0x00,0x4C); //we want to read RXPRF
/* if the dwt_configure returns DWT_ERROR either the PLL or RX calibration has failed the host should reset the device */
if (dwt_configure(&config2))
{
while (1) { }; // you can retry but in this case just a forever loop
}
CHAN_CTRL_reg = my_dwm3000_read32bitoffsetreg_packeted(0x01,0x14);
RX_FINFO_reg = my_dwm3000_read32bitoffsetreg_packeted(0x00,0x4C); //we want to read RXPRF
/**
* Setup the txconfig options. these ones are in an extern in the examples, we don't know if its necessary to do it
* or if it has preloaded default values. let's put them in for good measure.
* THIS WAS NOT IN THE FILE EXAMPLE. IT IS ADDED BY US FOR DEBUGGING PURPOSES.
*/
dwt_txconfig_t txconfig_options2 = {
0x34, /* PG delay. */
0xfdfdfdfd, /* TX power. */ //alternate, 0x3e3e3e3e
0x0 /*PG count*/
};
/* Configure the TX spectrum parameters (power PG delay and PG Count) */
dwt_configuretxrf(&txconfig_options2);
/* Loop forever sending frames periodically. */
while (1)
{
dwt_error_e dw_error = DWT_ERROR; //read them using breakpoints and debugging
/* Write frame data to DW IC and prepare transmission. See NOTE 3 below.*/
dw_error = 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. */
uint32_t TX_FCTRL_low_reg = my_dwm3000_read32bitoffsetreg_packeted(0x00,0x24); //we want TXBR
/* Start transmission. */
dw_error = dwt_starttx(DWT_START_TX_IMMEDIATE);
/* Hold copy of status register state here for reference so that it can be examined at a debug breakpoint. */
uint32_t status_reg;
/* 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.*/
waitforsysstatus(&status_reg, NULL, DWT_INT_TXFRS_BIT_MASK, 0);
status_reg = dwt_readsysstatuslo();
//uint32_t status_reg_byHand = my_dwm3000_read32bitoffsetreg_packeted(0x00,0x44);
uint32_t DWT_INT_TXFRS_BIT_flag = !(!(status_reg & DWT_INT_TXFRS_BIT_MASK ) ) ; //turns from "zero or non-zero value" to logic 1 or 0 so the debugger puts nicer numbers
uint32_t DWT_INT_TXPHS_BIT_flag = !(!(status_reg & DWT_INT_TXPHS_BIT_MASK ) ) ;
uint32_t DWT_INT_TXPRS_BIT_flag = !(!(status_reg & DWT_INT_TXPRS_BIT_MASK ) ) ;
uint32_t DWT_INT_TXFRB_BIT_flag = !(!(status_reg & DWT_INT_TXFRB_BIT_MASK ) ) ;
uint32_t DWT_INT_CP_LOCK_BIT_flag = !(!(status_reg & DWT_INT_CP_LOCK_BIT_MASK ) ) ;
if(status_reg & (DWT_INT_TXFRS_BIT_MASK | DWT_INT_CP_LOCK_BIT_MASK) ){ //we want to make sure both flags are on to describe a "txOK".
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}
/* Clear TX frame sent event. */
dwt_writesysstatuslo(DWT_INT_TXFRS_BIT_MASK |DWT_INT_TXPHS_BIT_MASK | DWT_INT_TXPRS_BIT_MASK| DWT_INT_TXFRB_BIT_MASK);
// status_reg = dwt_readsysstatuslo(); //commented this out because we already know it works.
// DWT_INT_TXFRS_BIT_flag = !(!(status_reg & DWT_INT_TXFRS_BIT_MASK ) ) ;
// DWT_INT_TXPHS_BIT_flag = !(!(status_reg & DWT_INT_TXPHS_BIT_MASK ) ) ;
// DWT_INT_TXPRS_BIT_flag = !(!(status_reg & DWT_INT_TXPRS_BIT_MASK ) ) ;
// DWT_INT_TXFRB_BIT_flag = !(!(status_reg & DWT_INT_TXFRB_BIT_MASK ) ) ;
// DWT_INT_CP_LOCK_BIT_flag = !(!(status_reg & DWT_INT_CP_LOCK_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]++;
}
}
// auxiliaryFunctions
uint32_t usTime_to_dwTime(uint32_t usTime){
return usTime * 5120 / 4992;
}
void my_dwt_goSleep(void){
dwt_configuresleep(DWT_CONFIG, 0x20 | 0x08 | 0x02 | 0x01 ); //not real thought behind the flags, just something that should make it sleep without a wakeuptimer
dwt_entersleep(DWT_DW_IDLE);
return;
}
void my_dwm3000_wakeup(void){
HAL_GPIO_WritePin(DW_CS_GPIO_Port, DW_CS_Pin, 0);
HAL_Delay(1); //documentation states 500us, we may lower this whenever we have the time to do so.
HAL_GPIO_WritePin(DW_CS_GPIO_Port, DW_CS_Pin, 1);
HAL_Delay(2);
}
void my_dwm3000_disableFF(void){
dwt_configureframefilter(DWT_FF_DISABLE, 0);
}
void my_dwt_setDeviceID(uint8_t* our_deviceID){
dwt_seteui(our_deviceID);
return;
}
uint32_t my_dwm3000_read32bitoffsetreg_packeted(uint8_t regfile, uint8_t offset){
//Create the header
uint16_t tempHeader = ( (regfile << 9) | 0x4000 ) | (offset<<2);
uint8_t myBuffer[4] = {0xff,0xff,0xff,0xff};
uint8_t* checkBuffer = myBuffer;
uint8_t myHeader[2] = { (uint8_t)(tempHeader >> 8) , (uint8_t) tempHeader};
readfromspi(2, myHeader, 4, myBuffer); //we try to read SYS_STATUS directly.
uint32_t myBufferPacketed = 0;
for(int i = 3; i >= 0 ; i--){
myBufferPacketed |= myBuffer[i];
if (i > 0){
myBufferPacketed = myBufferPacketed << 8;
}
}
return myBufferPacketed;
}
void my_dwm3000_readRXBuffer(uint8_t regfile, uint8_t offset, uint8_t* buffer, uint8_t len){
//Create the header
uint16_t tempHeader = ( (regfile << 9) | 0x4000 ) | (offset<<2);
uint8_t myBuffer[4] = {0};
uint8_t myHeader[2] = { (uint8_t)(tempHeader >> 8) , (uint8_t) tempHeader};
readfromspi(2, myHeader, len, buffer); //we try to read SYS_STATUS directly.
}