Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • master
  • final_version_project_thesis_colin_wulf
2 results

Target

Select target project
  • garlichs/dw1000_driver_freertos
  • cwulf/dw1000_driver_freertos
  • cm-projects/dw1000_driver_freertos
3 results
Select Git revision
  • master
1 result
Show changes
Commits on Source (7)
......@@ -98,7 +98,7 @@ extern "C" {
**/
#define SYS_TIME_ID 0x06 /* System Time Counter (40-bit) */
#define SYS_TIME_LEN (5) /* Note 40 bit register */
#define SYS_TIME_MASK 0x000000FFFFFFFFFFULL
/****************************************************************************//**
* @brief Bit definitions for register 0x07
......
......@@ -4,26 +4,16 @@
#include <stdint.h>
#include "cmsis_os.h"
#include "dw1000_util.h"
//DECA:DW1000 SLEEP and WAKEUP configuration parameters
#define DWT_LOADLDO 0x1000 // ONW_LLDO - on wakeup load the LDO tune value
#define DWT_LOADUCODE 0x0800 // ONW_LLDE - on wakeup load the LDE ucode
#define DWT_PRESRV_SLEEP 0x0100 // PRES_SLEEP - on wakeup preserve sleep bit
#define DWT_LOADOPSET 0x0080 // ONW_L64P - on wakeup load operating parameter set for 64 PSR
#define DWT_CONFIG 0x0040 // ONW_LDC - on wakeup restore (load) the saved configurations (from AON array into HIF)
#define DWT_TANDV 0x0001 // ONW_RADC - on wakeup run ADC to sample temperature and voltage sensor values
#define DWT_XTAL_EN 0x10 // keep XTAL running during sleep
#define DWT_WAKE_SLPCNT 0x8 // wake up after sleep count
#define DWT_WAKE_CS 0x4 // wake up on chip select
#define DWT_WAKE_WK 0x2 // wake up on WAKEUP PIN
#define DWT_SLP_EN 0x1 // enable sleep/deep sleep functionality
#define MAXIMUM_FRAME_LENGTH 127
#define FRAME_OVERHEAD sizeof(dw1000_frame_t) - MAXIMUM_FRAME_LENGTH
/**
* Defines for channel and prf selection and Preamble Code.
* Refer to Page 204 in the dw1000 User Manual 2.04
*/
#define PRF_SHIFT 0
#define CHANNEL_SHIFT 1
#define PREAMBLE_SHIFT 4
......@@ -73,22 +63,45 @@
#define CH7_64MHZ_19 (1 << PRF_SHIFT) | (7 << CHANNEL_SHIFT) | (19 << PREAMBLE_SHIFT)
#define CH7_64MHZ_20 (1 << PRF_SHIFT) | (7 << CHANNEL_SHIFT) | (20 << PREAMBLE_SHIFT)
/**
* Defines various return codes for driver functions
*/
#define DW1000_RET_OK 0
#define DW1000_RET_MSG_TO_LONG -1
#define DW1000_RET_TX_BUFFER_OVERFLOW -2
//
////DECA:DW1000 SLEEP and WAKEUP configuration parameters
#define DWT_LOADUCODE 0x0800 // ONW_LLDE - on wakeup load the LDE ucode
//FIXME: delete them
//#define DWT_LOADLDO 0x1000 // ONW_LLDO - on wakeup load the LDO tune value
//#define DWT_PRESRV_SLEEP 0x0100 // PRES_SLEEP - on wakeup preserve sleep bit
//#define DWT_LOADOPSET 0x0080 // ONW_L64P - on wakeup load operating parameter set for 64 PSR
//#define DWT_CONFIG 0x0040 // ONW_LDC - on wakeup restore (load) the saved configurations (from AON array into HIF)
//#define DWT_TANDV 0x0001 // ONW_RADC - on wakeup run ADC to sample temperature and voltage sensor values
//
//#define DWT_XTAL_EN 0x10 // keep XTAL running during sleep
//#define DWT_WAKE_SLPCNT 0x8 // wake up after sleep count
//#define DWT_WAKE_CS 0x4 // wake up on chip select
//#define DWT_WAKE_WK 0x2 // wake up on WAKEUP PIN
//#define DWT_SLP_EN 0x1 // enable sleep/deep sleep functionality
//DECA:DW1000 INIT configuration parameters
#define DWT_LOADLDOTUNE 0x8
#define DWT_LOADTXCONFIG 0x4
#define DWT_LOADANTDLY 0x2
#define DWT_LOADXTALTRIM 0x1
#define DWT_LOADNONE 0x0
//#define DWT_LOADLDOTUNE 0x8
//#define DWT_LOADTXCONFIG 0x4
//#define DWT_LOADANTDLY 0x2
//#define DWT_LOADXTALTRIM 0x1
//#define DWT_LOADNONE 0x0
//DECA:DW1000 OTP operating parameter set selection
#define DWT_OPSET_64LEN 0x0
#define DWT_OPSET_TIGHT 0x1
#define DWT_OPSET_DEFLT 0x2
//#define DWT_OPSET_64LEN 0x0
//#define DWT_OPSET_TIGHT 0x1
//#define DWT_OPSET_DEFLT 0x2
#define DWT_SFDTOC_DEF 0x1041 // default SFD timeout value
#define DWT_PHRMODE_STD 0x0 // standard PHR mode
#define DWT_PHRMODE_EXT 0x3 // DW proprietary extended frames PHR mode
//#define DWT_PHRMODE_STD 0x0 // standard PHR mode
//#define DWT_PHRMODE_EXT 0x3 // DW proprietary extended frames PHR mode
//! constants for selecting the bit rate for data TX (and RX)
//! These are defined for write (with just a shift) the TX_FCTRL register
......@@ -119,43 +132,39 @@
#define DWT_PLEN_256 0x24 //! Non-standard preamble length 256 symbols
#define DWT_PLEN_128 0x14 //! Non-standard preamble length 128 symbols
#define DWT_PLEN_64 0x04 //! Standard preamble length 64 symbols
typedef struct {
typedef struct __attribute__((packed)){
uint8_t chan; //!< channel number {1, 2, 3, 4, 5, 7 }
uint8_t prf; //!< Pulse Repetition Frequency {DWT_PRF_16M or DWT_PRF_64M}
uint8_t txPreambLength; //!< DWT_PLEN_64..DWT_PLEN_4096
uint8_t rxPAC; //!< Acquisition Chunk Size (Relates to RX preamble length)
uint8_t txCode; //!< TX preamble code
uint8_t rxCode; //!< RX preamble code
uint8_t nsSFD; //!< Boolean should we use non-standard SFD for better performance
uint8_t dataRate; //!< Data Rate {DWT_BR_110K, DWT_BR_850K or DWT_BR_6M8}
uint16_t sfdTO; //!< SFD timeout value (in symbols)
} dwt_config_t;
uint8_t phrMode; //!< PHR mode {0x0 - standard DWT_PHRMODE_STD, 0x3 - extended frames DWT_PHRMODE_EXT}
uint8_t smartPowerEn; //!< Smart Power enable / disable
typedef struct __attribute__((packed)){
uint8_t timestamp_valid;
uint8_t rx_timestamp[5];
uint16_t length;
uint8_t buffer[MAXIMUM_FRAME_LENGTH];
uint16_t sfdTO; //!< SFD timeout value (in symbols)
} dw1000_frame_t;
} dwt_config_t;
int dw1000_init(uint16_t config, BaseType_t (*sendCallback)(),
BaseType_t (*receiveCallback)(uint32_t bufferLength, uint8_t ts_valid));
BaseType_t (*receiveCallback)());
int dw1000_configure(dwt_config_t *config, uint8_t use_otpconfigvalues);
int dw1000_sendFrame(uint8_t *payload, uint16_t len);
int dw1000_writeFrameIntoBuffer(uint16_t txBufferOffset, uint8_t *payload, uint16_t len);
int dw1000_transmitFrame(uint16_t txBufferOffset, uint16_t len);
int dw_1000_receiveFrameFromIsr(uint8_t * buffer, uint32_t length);
int dw1000_receiveFrameFromIsr(dw1000_frame_t *frame);
void dw1000_extiCallback(void);
void vTaskGlobalTimeIncrement(void *pvParameters);
void dw1000_generateConfig(uint16_t mode, dwt_config_t *config);
void dw1000_generateConfigFromByteBuffer(uint8_t * buffer, uint32_t length, dwt_config_t *config);
#endif /*__ dw1000_H */
/**
* Defines various return codes for driver functions
*/
#define DW1000_RET_OK 0
#define DW1000_RET_MSG_TO_LONG -1
#define DW1000_RET_TX_BUFFER_OVERFLOW -2
......@@ -4,6 +4,7 @@
#include <stdint.h>
#include <string.h>
#include "deca_regs.h"
#include "task.h"
//#define DOUBLE_BUFFER
//DECA:Defines for enable_clocks function
......@@ -33,12 +34,6 @@
#define PCODES 25 //supported preamble codes
#define ever ;;
#define GLOBAL_TIME_TICK_MS 17592
typedef struct {
uint64_t ms;
uint64_t subms;
} dw1000_global_time_t;
typedef struct {//DECA
uint32_t txFCTRL; // keep TX_FCTRL register config
......@@ -50,14 +45,13 @@ typedef struct {//DECA
uint32_t sysCFGreg; // local copy of system config register
uint32_t txPowCfg[12]; // stores the Tx power configuration read from OTP (6 channels consecutively with PRF16 then 64, e.g. Ch 1 PRF16 is index 0 and 64 index 1)
BaseType_t (*sendCB)();
BaseType_t (*receiveCB)(uint32_t bufferLength, uint8_t ts_valid);
BaseType_t (*receiveCB)();
uint16_t frame_length;
uint8_t timestamp_valid;
TaskHandle_t taskHandle;
int prfIndex;
uint8_t longFrames ; // flag in non-standard long frame mode
uint32_t ldoTune; //low 32 bits of LDO tune value
uint8_t chan; // added chan here - used in the reading of acc
dw1000_global_time_t last_rx_time;
} dw1000_local_data_t;
extern dw1000_local_data_t dw1000local; // Static local device data
......@@ -94,8 +88,10 @@ uint32_t dw1000Util_otpread(uint32_t address);
void dw1000Util_forceTrxOff(void);
void dw1000Util_reset(void);
void dw1000Util_resetRxOnly(void);
void dw1000Util_getRxTimestamp(dw1000_global_time_t *timeBuffer);
void dw1000Util_printGlobalTimestamp(dw1000_global_time_t *time);
void dw1000Util_getRxTimestamp(uint64_t *rx_time);
//void dw1000Util_printGlobalTimestamp(uint64_t *rx_time);
void dw1000Util_getSysTime(uint8_t *nt);
void lltoa(int64_t val, char *dest_buf, uint8_t base);
#ifdef DEBUG
void hexdump(uint8_t * buffer, uint8_t len);
......
......@@ -15,11 +15,8 @@
volatile uint32_t global_time = 0;
uint16_t maximum_message_length = 1024; //Fixme: put right message length
int dw1000_init(uint16_t config, BaseType_t (*sendCallback)(),
BaseType_t (*receiveCallback)(uint32_t bufferlength, uint8_t ts_valid)) {
BaseType_t (*receiveCallback)()) {
// Clear control-structure
......@@ -35,13 +32,12 @@ int dw1000_init(uint16_t config, BaseType_t (*sendCallback)(),
// Soft-Reset
dw1000Util_reset();
// Set allowed interrupts
// TODO: MLDEDONE
uint32_t sys_mask = 0;
dw1000Hal_readRegister(SYS_MASK_ID, (uint8_t *) &sys_mask, SYS_MASK_LEN);
trace_printf("SYS_MASK: %x\n", sys_mask);
sys_mask |= ( SYS_MASK_MTXFRS | SYS_MASK_MRXDFR | SYS_MASK_MLDEDONE);
sys_mask |= ( SYS_MASK_MTXFRS | SYS_MASK_MRXDFR | SYS_MASK_MLDEDONE );
trace_printf("SYS_MASK: %x\n", sys_mask);
dw1000Hal_writeRegister(SYS_MASK_ID, (uint8_t *) &sys_mask, SYS_MASK_LEN);
......@@ -68,10 +64,10 @@ int dw1000_init(uint16_t config, BaseType_t (*sendCallback)(),
//DECA: set system clock to XTI - this is necessary to make sure the values read by _dwt_otpread are reliable
dw1000Util_enableclocks(FORCE_SYS_XTI);
if(config & DWT_LOADLDOTUNE)
{
dw1000local.ldoTune = dw1000Util_otpread(LDOTUNE_ADDRESS);
}
// if(config & DWT_LOADLDOTUNE)
// {
// dw1000local.ldoTune = dw1000Util_otpread(LDOTUNE_ADDRESS);
// }
if ((dw1000local.ldoTune & 0xFF) != 0) //LDO tune values are stored in the OTP
{
......@@ -104,12 +100,8 @@ int dw1000_init(uint16_t config, BaseType_t (*sendCallback)(),
dw1000Hal_writeSubRegister(OTP_IF_ID, OTP_CTRL,
(uint8_t *) &otp_ctrl_ldeload, 2);
//FIXME: Sleep in FreeRTOS? Sleep(1); // Allow time for code to upload (should take up to 120 us)
osDelay(1);
wr_buf[1] = 0x02; //Force TX clock off.
wr_buf[0] = 0x00; //Force system clock to be the 19.2 MHz XTI clock.
//DECA:dwt_writetodevice(PMSC_ID, PMSC_CTRL0_OFFSET, 2, wr_buf);
......@@ -174,9 +166,9 @@ int dw1000_configure(dwt_config_t *config, uint8_t use_otpconfigvalues) {
} else {
dw1000local.sysCFGreg &= (~SYS_CFG_RXM110K);
}
dw1000local.longFrames = config->phrMode;
//dw1000local.longFrames = config->phrMode;
dw1000local.sysCFGreg |= (SYS_CFG_PHR_MODE_11 & (config->phrMode << 16)); //Set to enable PhyHdr for long frames
// dw1000local.sysCFGreg |= (SYS_CFG_PHR_MODE_11 & (config->phrMode << 16)); //Set to enable PhyHdr for long frames
dw1000local.sysCFGreg |= (SYS_CFG_RXAUTR); //Automatic reenable of the receiver
......@@ -225,7 +217,7 @@ int dw1000_configure(dwt_config_t *config, uint8_t use_otpconfigvalues) {
//DECA: Configure the baseband parameters (for specified prf, bit rate, pac, and SFD settings)
//DECA:DTUNE0
dw1000Hal_writeSubRegister(DRX_CONF_ID, DRX_TUNE0b_OFFSET,
(uint8_t *) &sftsh[config->dataRate][config->nsSFD],
(uint8_t *) &sftsh[config->dataRate][0/*use standard sfd*/],
DRX_TUNE0b_LEN);
//DTUNE1 FIXME: Führt zu Abbruch vom Senden, bei zulangen ISR oder zu vielen interrupts
......@@ -273,8 +265,6 @@ int dw1000_configure(dwt_config_t *config, uint8_t use_otpconfigvalues) {
//// hexdump(&temp, 4);
////#endif
//DTUNE3 set SFD detection timeout count
if (config->sfdTO != DWT_SFDTOC_DEF) { //if default value no need to program it
dw1000Hal_writeSubRegister(DRX_CONF_ID, DRX_SFDTOC_OFFSET,
......@@ -293,15 +283,6 @@ int dw1000_configure(dwt_config_t *config, uint8_t use_otpconfigvalues) {
dwt_write16bitoffsetreg( AGC_CFG_STS_ID, 0x4, agc_config.target[prfIndex]);
*/
//DECA: set (non-standard) user SFD for improved performance,
if (config->nsSFD) {
//Write non standard (DW) SFD length
dw1000Hal_writeSubRegister(USR_SFD_ID, 0x00,
(uint8_t *) &dwnsSFDlen[config->dataRate], 1);
nsSfd_result = 3;
useDWnsSFD = 1;
}
//Set CHAN_CTRL, Channel Number etc
regval = (CHAN_CTRL_TX_CHAN_MASK & (chan << CHAN_CTRL_TX_CHAN_SHIFT)) | // Transmit Channel
(CHAN_CTRL_RX_CHAN_MASK & (chan << CHAN_CTRL_RX_CHAN_SHIFT)) | // Receive Channel
......@@ -326,22 +307,22 @@ int dw1000_configure(dwt_config_t *config, uint8_t use_otpconfigvalues) {
dw1000Hal_writeRegister(TX_FCTRL_ID, (uint8_t *) &dw1000local.txFCTRL,
TX_FCTRL_LEN - 1); // Just first 4 byte
}
if (use_otpconfigvalues & DWT_LOADXTALTRIM) {
//This is used adjust the crystal frequency
uint8_t write_buf;
//DECA: dwt_readfromdevice(FS_CTRL_ID,FS_XTALT_OFFSET,1,&write_buf);
dw1000Hal_readSubRegister(FS_CTRL_ID, FS_XTALT_OFFSET, &write_buf,
FS_XTALT_LEN);
write_buf &= ~FS_XTALT_MASK;
write_buf |= (FS_XTALT_MASK & dw1000local.xtrim); // we should not change high bits, cause it will cause malfunction
dw1000Hal_writeSubRegister(FS_CTRL_ID, FS_XTALT_OFFSET, &write_buf,
FS_XTALT_LEN);
}
// Fixme: Really needed?
// if (use_otpconfigvalues & DWT_LOADXTALTRIM) {
// //This is used adjust the crystal frequency
// uint8_t write_buf;
//
// //DECA: dwt_readfromdevice(FS_CTRL_ID,FS_XTALT_OFFSET,1,&write_buf);
// dw1000Hal_readSubRegister(FS_CTRL_ID, FS_XTALT_OFFSET, &write_buf,
// FS_XTALT_LEN);
//
// write_buf &= ~FS_XTALT_MASK;
//
// write_buf |= (FS_XTALT_MASK & dw1000local.xtrim); // we should not change high bits, cause it will cause malfunction
//
// dw1000Hal_writeSubRegister(FS_CTRL_ID, FS_XTALT_OFFSET, &write_buf,
// FS_XTALT_LEN);
// }
/* TODO notwendig?
if (use_otpconfigvalues & DWT_LOADANTDLY)
......@@ -351,9 +332,6 @@ int dw1000_configure(dwt_config_t *config, uint8_t use_otpconfigvalues) {
dwt_settxantennadelay(((dw1000local.antennaDly >> (16*prfIndex)) & 0xFFFF) >> 1);
}
*/
return 0;
}
......@@ -369,7 +347,7 @@ int dw1000_sendFrame(uint8_t *payload, uint16_t len) {
}
int dw1000_writeFrameIntoBuffer(uint16_t txBufferOffset, uint8_t *payload, uint16_t len){
if ((len + 2) > maximum_message_length){
if ((len + 2) > MAXIMUM_FRAME_LENGTH){
// Message + CRC is longer than the allowed msg length (usually 127, but decawave
return DW1000_RET_MSG_TO_LONG;
}
......@@ -385,7 +363,7 @@ int dw1000_writeFrameIntoBuffer(uint16_t txBufferOffset, uint8_t *payload, uint1
int dw1000_transmitFrame(uint16_t txBufferOffset, uint16_t len){
//Set length and offset
uint32_t reg32 = dw1000local.txFCTRL | len+2 | (txBufferOffset << 22);
uint32_t reg32 = ((dw1000local.txFCTRL | len+2) | (txBufferOffset << 22));
dw1000Hal_writeSubRegister(TX_FCTRL_ID, 0, (uint8_t *) &reg32, TX_FCTRL_LEN-1);
/* WITHOUT THE NEXT PART: SECOND TIME NO SENDING POSSIBLE, BUT CAN'T BE FOUND IN ORIGINAL DRIVER */
dw1000Util_forceTrxOff();
......@@ -396,24 +374,17 @@ int dw1000_transmitFrame(uint16_t txBufferOffset, uint16_t len){
return DW1000_RET_OK;
}
void vTaskGlobalTimeIncrement(void *pvParameters) {
TickType_t xNextWakeTime;
xNextWakeTime = xTaskGetTickCount();
for(ever) {
// Task is delayed until radio timestamp approximately overflows
vTaskDelayUntil(&xNextWakeTime, GLOBAL_TIME_TICK_MS / portTICK_PERIOD_MS);
global_time++;
}
vTaskDelete( NULL);
}
void dw1000_extiCallback(void) {
dw1000Isr_handleInterrupt();
}
int dw_1000_receiveFrameFromIsr(uint8_t * buffer, uint32_t length) {
dw1000Hal_readRegisterFromIsr(RX_BUFFER_ID, buffer, length); //FromIsr important!
trace_printf("%d\n", buffer[0]);
int dw1000_receiveFrameFromIsr(dw1000_frame_t *frame) {
frame->length = dw1000local.frame_length;
frame->timestamp_valid = dw1000local.timestamp_valid;
if(frame->timestamp_valid){
dw1000Util_getRxTimestamp(&frame->rx_timestamp);
}
dw1000Hal_readRegisterFromIsr(RX_BUFFER_ID, frame->buffer, frame->length); //FromIsr important!
return 0;
}
......@@ -450,13 +421,13 @@ void dw1000_generateConfig(uint16_t mode, dwt_config_t *config){
config->sfdTO = (129 + 8 - 8); //Fixme: How to calculate SFD Timeout
config->dataRate = DWT_BR_6M8;
config->rxPAC = DWT_PAC8;
//Use IEEE Conform Header and SFD Fixme: Support Decawave later?
config->nsSFD = 0;
config->phrMode = 0;
config->rxPAC = DWT_PAC8;
config->txPreambLength = DWT_PLEN_128;
}
void dw1000_generateConfigFromByteBuffer(uint8_t * buffer, uint32_t length, dwt_config_t *config){
//TODO: Build config from byteBuffer
}
......@@ -192,6 +192,7 @@ int dw1000Hal_readRegister(uint8_t regID, uint8_t *dest, uint16_t len) {
while (hspi->State != HAL_SPI_STATE_READY) {
}
xSemaphoreGive(spiSema);
} else {
ret = HAL_LOCKED;
//trace_printf("nb");
......
......@@ -29,11 +29,12 @@ BaseType_t dw1000Hal_handleRx(uint64_t * event, uint64_t * event_clear) {
rx_buffer_len = rx_frame_info & RX_FINFO_RXFLEN_MASK; // No shifting required
uint8_t lde_done = (*event & SYS_STATUS_LDEDONE) ? 1 : 0;
dw1000local.timestamp_valid = lde_done;
dw1000local.frame_length = rx_buffer_len;
//Trigger Callback
if (dw1000local.receiveCB != NULL) {
xHigherPriorityTaskWoken = dw1000local.receiveCB(rx_buffer_len,
lde_done);
xHigherPriorityTaskWoken = dw1000local.receiveCB();
} else if (dw1000local.taskHandle != NULL) {
//TODO Notify taskHandle
}
......
......@@ -273,59 +273,70 @@ uint32_t dw1000Util_otpread(uint32_t address)
return (ret_data);
}
void dw1000Util_getRxTimestamp(dw1000_global_time_t *time_buffer){
uint8_t buf[5] = {0};
uint64_t radio_rx_time = 0;
void dw1000Util_getRxTimestamp(uint64_t *radio_rx_time){
// Read rx timestamp from radio
dw1000Hal_readSubRegisterFromIsr(RX_TIME_ID, RX_TIME_RX_STAMP_OFFSET, buf, RX_TIME_RX_STAMP_LEN);
radio_rx_time = ((uint64_t) buf[4]) << 32 |
((uint64_t) buf[3]) << 24 |
((uint64_t) buf[2]) << 16 |
((uint64_t) buf[1]) << 8 |
((uint64_t) buf[0]) << 0;
// multiply by 16 to get picoseconds (actually ~15.65 is right)
radio_rx_time <<= 4;
// Calculate timestamp in milliseconds and sub-milliseconds parts separately
uint64_t ms_buf = global_time * GLOBAL_TIME_TICK_MS + radio_rx_time / 1000000000llu;
uint64_t subms_buf = radio_rx_time - (global_time * 1000000000llu);
if(ms_buf < dw1000local.last_rx_time.ms) {
// The radio timer had an overflow, but the global timer didn't, yet
ms_buf += GLOBAL_TIME_TICK_MS;
}
// Write calculated timestamp to provided structure
time_buffer->ms = ms_buf;
time_buffer->subms = subms_buf;
// Store new timestamp to be able to detect asynchronous overflows
dw1000local.last_rx_time.ms = ms_buf;
dw1000Hal_readSubRegisterFromIsr(RX_TIME_ID, RX_TIME_RX_STAMP_OFFSET, (uint8_t *)radio_rx_time, RX_TIME_RX_STAMP_LEN);
}
void lltoa(uint64_t val, char *dest_buf, uint8_t base) {
void lltoa(int64_t val, char *dest_buf, uint8_t base) {
uint8_t sign = 0;
char buf[64] = {0};
uint32_t i = 62;
uint32_t i = 0;
if(val == 0) {
dest_buf[0] = '0';
dest_buf[1] = '\0';
return;
}
else if(val < 0) {
sign = 1;
val = -val;
}
for(; val && i ; --i, val /= base) {
for(i = 62; val && i ; --i, val /= base) {
buf[i] = "0123456789abcdef"[val % base];
}
if(sign) {
buf[i--] = '-';
}
memcpy(dest_buf, &buf[i + 1], 64);
}
void dw1000Util_printGlobalTimestamp(dw1000_global_time_t *time) {
char ms_buf[64] = {0};
char subms_buf[64] = {0};
// Convert uint64_t timestamp to strings, because printf can't handle 64-bit integers
lltoa(time->ms, ms_buf, 10);
lltoa(time->subms, subms_buf, 10);
printf("RX time = %s.%sms\n", ms_buf, subms_buf);
}
//void dw1000Util_printGlobalTimestamp(dw1000_global_time_t *time) {
//
// /*
// // multiply by 16 to get picoseconds (actually ~15.65 is right)
// radio_rx_time <<= 4;
//
// // Calculate timestamp in milliseconds and sub-milliseconds parts separately
// uint64_t ms_buf = global_time * GLOBAL_TIME_TICK_MS + radio_rx_time / 1000000000llu;
// uint64_t subms_buf = radio_rx_time - (global_time * 1000000000llu);
//
// if(ms_buf < dw1000local.last_rx_time.ms) {
// // The radio timer had an overflow, but the global timer didn't, yet
// ms_buf += GLOBAL_TIME_TICK_MS;
// }
//
// // Write calculated timestamp to provided structure
// time_buffer->ms = ms_buf;
// time_buffer->subms = subms_buf;
//
// // Store new timestamp to be able to detect asynchronous overflows
// dw1000local.last_rx_time.ms = ms_buf;
// */
// char ms_buf[64] = {0};
// char subms_buf[64] = {0};
//
// // Convert uint64_t timestamp to strings, because printf can't handle 64-bit integers
// lltoa(time->ms, ms_buf, 10);
// lltoa(time->subms, subms_buf, 10);
//
// printf("RX time = %s.%sms\n", ms_buf, subms_buf);
//}
void dw1000Util_forceTrxOff(void) {
uint32_t sys_ctrl = 0;
......@@ -404,6 +415,16 @@ void dw1000Util_resetRxOnly(void) {
(uint8_t*) &subreg, PMSC_CTRL0_LEN);
}
void dw1000Util_getSysTime(uint8_t *nt) {
uint8_t rev_buf[SYS_TIME_LEN];
dw1000Hal_readRegister(SYS_TIME_ID, rev_buf, SYS_TIME_LEN);
for(uint8_t i = 0; i < SYS_TIME_LEN; i++) {
nt[i] = rev_buf[i];
//nt[i] = rev_buf[(SYS_TIME_LEN -1) - i];
}
}
#ifdef DEBUG
void hexdump(uint8_t * buffer, uint8_t len){
......