Hello,
I am using the DWM1000 for the first time in the development of a product. I designed a pcb to house the module with, and the MCU I am using is an AVR Atmega328. Using the software API provided, I can communicate via SPI to the registers and everything seems OK.
When I use the basic tx/rx example, the tx seems to work, as I can check the registers, and they seem OK. I do not receive anything on the rx end, it stays in the inf loop waiting to recieve a frame.
Just to test to make sure my hardware is fine, I used a DWM1000 library that was written for arduino, and it works fine, I am able to tx and rx perfectly.
Any suggestions?
Thanks!
For these examples, I am still using arduino as the bootloader, just so I am comparing apples to apples.
For my debug function I get the CLKPLL_LL set in the rx code. In the tx it is not set. It’s not a hardware issue since I checked with the arduino library and it is not set. In the arduino example, i’m using basic reciever/senderhttps://github.com/thotro/arduino-dw1000/tree/e20c3b91c3d6cee0ef848aa41e72c942cb0ac7df/examples
Tx Code:
[code]#include <Arduino.h>
#include <SPI.h>
#include “decadriver/deca_device_api.h”
#include “decadriver/deca_regs.h”
/*! ----------------------------------------------------------------------------
- @file main.c
- @brief Simple TX example code
- @attention
- Copyright 2015 © Decawave Ltd, Dublin, Ireland.
- All rights reserved.
-
@author Decawave
*/
static dwt_config_t config = {
2, /* Channel number. /
DWT_PRF_64M, / Pulse repetition frequency. /
DWT_PLEN_1024, / Preamble length. Used in TX only. /
DWT_PAC32, / 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 SFD, 1 to use non-standard SFD. /
DWT_BR_110K, / Data rate. /
DWT_PHRMODE_STD, / PHY header mode. /
(1025 + 64 - 32) / SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */
};
static uint8 tx_msg[] = {0xC5, 0, ‘D’, ‘E’, ‘C’, ‘A’, ‘W’, ‘A’, ‘V’, ‘E’, 0, 0};
#define BLINK_FRAME_SN_IDX 1
#define TX_DELAY_MS 1000
void reset_DW1000()
{
digitalWrite(5, LOW);
pinMode(5, OUTPUT);
delay(10);
pinMode(5, INPUT);
delay(10);
}
void spi_set_rate_low()
{
CLKPR = (1 << CLKPCE);
CLKPR = 1;
}
void spi_set_rate_high()
{
CLKPR = (1 << CLKPCE);
CLKPR = 0;
}
void debug_register(uint16_t reg, uint8_t len)
{
uint8_t ar[len];
dwt_readfromdevice (reg, 0, len, ar) ;
for (int i=0; i<len; i++)
{
Serial.print(i); Serial.print(" = "); Serial.println(ar[i]);
}
}
void setup()
{
SPI.begin();
Serial.begin(9600);
debug_register(0x0F, 5);
reset_DW1000(); /* Target specific drive of RSTn line into DW1000 low for a period. */
spi_set_rate_low();
if (dwt_initialise(DWT_LOADNONE) == DWT_ERROR)
{
Serial.println(“INIT FAILED”);
while (1)
{ };
}
spi_set_rate_high();
dwt_configure(&config);
}
void loop()
{
dwt_writetxdata(sizeof(tx_msg), tx_msg, 0); /* Zero offset in TX buffer. /
dwt_writetxfctrl(sizeof(tx_msg), 0, 0); / Zero offset in TX buffer, no ranging. */
dwt_starttx(DWT_START_TX_IMMEDIATE);
while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
{ };
debug_register(0x0F, 5);
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);
delay(TX_DELAY_MS);
tx_msg[BLINK_FRAME_SN_IDX]++;
}
[/code]
Rx:
[code]#include <Arduino.h>
#include <SPI.h>
#include “decadriver/deca_device_api.h”
#include “decadriver/deca_regs.h”
/*! ----------------------------------------------------------------------------
- @file main.c
- @brief Simple RX example code
- @attention
- Copyright 2015 © Decawave Ltd, Dublin, Ireland.
- All rights reserved.
-
@author Decawave
*/
static dwt_config_t config = {
2, /* Channel number. /
DWT_PRF_64M, / Pulse repetition frequency. /
DWT_PLEN_1024, / Preamble length. Used in TX only. /
DWT_PAC32, / 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 SFD, 1 to use non-standard SFD. /
DWT_BR_110K, / Data rate. /
DWT_PHRMODE_STD, / PHY header mode. /
(1025 + 64 - 32) / SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */
};
#define FRAME_LEN_MAX 127
static uint8 rx_buffer[FRAME_LEN_MAX];
static uint32 status_reg = 0;
static uint16 frame_len = 0;
void reset_DW1000()
{
digitalWrite(5, LOW);
pinMode(5, OUTPUT);
delay(10);
pinMode(5, INPUT);
delay(10);
}
void spi_set_rate_low()
{
CLKPR = (1 << CLKPCE);
CLKPR = 1;
}
void spi_set_rate_high()
{
CLKPR = (1 << CLKPCE);
CLKPR = 0;
}
void debug_register(uint16_t reg, uint8_t len)
{
uint8_t ar[len];
dwt_readfromdevice (reg, 0, len, ar) ;
for (int i=0; i<len; i++)
{
Serial.print(i); Serial.print(" = "); Serial.println(ar[i]);
}
}
void setup()
{
SPI.begin();
Serial.begin(9600);
reset_DW1000();
spi_set_rate_low();
if (dwt_initialise(DWT_LOADNONE) == DWT_ERROR)
{
Serial.println(“INIT FAILED”);
while (1)
{ };
}
spi_set_rate_high();
dwt_configure(&config);
}
void loop()
{
int i;
for (i = 0 ; i < FRAME_LEN_MAX; i++ )
{
rx_buffer[i] = 0;
}
dwt_rxenable(DWT_START_RX_IMMEDIATE);
while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))
{
debug_register(0x0F, 5);
};
if (status_reg & SYS_STATUS_RXFCG)
{
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);
}
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);
}
else
{
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
}
}
[/code]
spi:
[code]int openspi(/SPI_TypeDef SPIx*/)
{
return 0;
} // end openspi()
/*! ------------------------------------------------------------------------------------------------------------------
-
Function: closespi()
-
Low level abstract function to close the the SPI device.
-
returns 0 for success, or -1 for error
*/
int closespi(void)
{return 0;
} // end closespi()
/*! ------------------------------------------------------------------------------------------------------------------
- Function: writetospi()
- Low level abstract function to write to the SPI
- Takes two separate byte buffers for write header and write data
- returns 0 for success, or -1 for error
*/
uint8_t spi_recieve_byte(uint8_t b)
{
SPDR = b;
while(!(SPSR & (1<<SPIF)));
return SPDR;
}
int writetospi(uint16 headerLength, const uint8 *headerBuffer, uint32 bodylength, const uint8 *bodyBuffer)
{
decaIrqStatus_t stat ;
//stat = decamutexon() ;
digitalWrite(10, LOW);
for (uint8_t i = 0; i < headerLength; i++)
spi_recieve_byte(headerBuffer[i]);
for (uint8_t i = 0; i < bodylength; i++)
spi_recieve_byte(bodyBuffer[i]);
digitalWrite(10, HIGH);
//decamutexoff(stat) ;
return 0;
} // end writetospi()
/*! ------------------------------------------------------------------------------------------------------------------
-
Function: readfromspi()
-
Low level abstract function to read from the SPI
-
Takes two separate byte buffers for write header and read data
-
returns the offset into read buffer where first byte of read data may be found,
-
or returns -1 if there was an error
*/
int readfromspi(uint16 headerLength, const uint8 *headerBuffer, uint32 readlength, uint8 *readBuffer)
{
decaIrqStatus_t stat ;//stat = decamutexon() ;
digitalWrite(10, LOW);
for (uint8_t i = 0; i < headerLength; i++)
spi_recieve_byte(headerBuffer[i]);for (uint8_t i = 0; i < readlength; i++)
readBuffer[i] = spi_recieve_byte(0);digitalWrite(10, HIGH);
//decamutexoff(stat) ;
return 0;
} // end readfromspi()[/code]