System Hardfault when calling dwt_probe()

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.

}

1 Like