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

Target

Select target project
  • garlichs/dw1000_driver_freertos
  • cwulf/dw1000_driver_freertos
  • cm-projects/dw1000_driver_freertos
3 results
Show changes
Commits on Source (9)
......@@ -153,3 +153,9 @@ void vTaskGlobalTimeIncrement(void *pvParameters);
void dw1000_generateConfig(uint16_t mode, 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,7 +4,7 @@
#include <stdint.h>
#include <string.h>
#include "deca_regs.h"
//#define DOUBLE_BUFFER
//DECA:Defines for enable_clocks function
#define FORCE_SYS_XTI 0
......@@ -51,6 +51,7 @@ typedef struct {//DECA
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);
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
......@@ -87,8 +88,6 @@ extern const uint16_t lde_replicaCoeff[PCODES];
#define DEBUG
void dw1000Util_enableclocks(int clocks);
void dw1000Util_enableRX();
uint32_t dw1000Util_otpread(uint32_t address);
......
......@@ -137,14 +137,20 @@ int dw1000_init(uint16_t config, BaseType_t (*sendCallback)(),
dw1000Hal_readRegister(SYS_CFG_ID, (uint8_t *) &dw1000local.sysCFGreg,
SYS_CFG_LEN);
#ifdef DOUBLE_BUFFER
//Enable double buffer
dw1000local.sysCFGreg &= (~SYS_CFG_DIS_DRXB);
dw1000Hal_writeRegister(SYS_CFG_ID, (uint8_t *) &dw1000local.sysCFGreg,
SYS_CFG_LEN);
#endif
uint32_t event_clear = 0xFFFFFFFF;
dw1000Hal_writeRegister(SYS_STATUS_ID, (uint8_t*) &event_clear,
SYS_STATUS_LEN);
//Enable Receiver
dw1000Util_enableRX();
uint32_t event_clear = 0xFFFFFFFF;
dw1000Hal_writeRegister(SYS_STATUS_ID, (uint8_t*) &event_clear,
SYS_STATUS_LEN);
return 0;
}
......@@ -172,10 +178,10 @@ int dw1000_configure(dwt_config_t *config, uint8_t use_otpconfigvalues) {
dw1000local.sysCFGreg |= (SYS_CFG_PHR_MODE_11 & (config->phrMode << 16)); //Set to enable PhyHdr for long frames
dw1000local.sysCFGreg |= (1 << 29); //RXAUTR
dw1000local.sysCFGreg |= (SYS_CFG_RXAUTR); //Automatic reenable of the receiver
dw1000Hal_writeRegister(SYS_CFG_ID, (uint8_t *) &dw1000local.sysCFGreg,
SYS_CFG_LEN);
dw1000Hal_writeRegister(SYS_CFG_ID, (uint8_t *) &dw1000local.sysCFGreg, SYS_CFG_LEN);
//DECA:write/set the lde_replicaCoeff
dw1000Hal_writeSubRegister(LDE_IF_ID, LDE_REPC_OFFSET, (uint8_t *) &reg16,
......
......@@ -75,7 +75,7 @@ int dw1000Hal_readSubRegisterFromIsr(uint8_t regID, uint16_t offset,
int ret;
//portENTER_CRITICAL();
if ((spiSema != NULL)
&& (xSemaphoreTakeFromISR(spiSema, ( TickType_t ) DW1000HAL_SPI_TIMEOUT)
&& (xSemaphoreTakeFromISR(spiSema, pdFALSE)
== pdTRUE)) {
if (len <= 127) {
dummy[0] = regID & 0x3f; //set the first two bit 0 (read access, no subregister)
......
#include "dw1000_hal.h"
#include "deca_regs.h"
#include "dw1000_util.h"
#include "Trace.h"
BaseType_t dw1000Hal_handleTx(uint64_t * event, uint64_t * event_clear) {
// Ignore unused parameters, may be needed for later purposes
(void) event;
(void) event_clear;
BaseType_t dw1000Hal_handleTx(uint64_t event) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
dw1000Util_enableRX();
if (dw1000local.sendCB != NULL) {
xHigherPriorityTaskWoken |= dw1000local.sendCB();
} else {
trace_printf("TX handler null\n");
}
return xHigherPriorityTaskWoken;
}
BaseType_t dw1000Hal_handleRx(uint64_t event) {
BaseType_t dw1000Hal_handleRx(uint64_t * event, uint64_t * event_clear) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
//if (event & SYS_STATUS_LDEDONE) // LDE done/finished
{
//trace_printf("LDEDONE\n");
uint16_t len = 0;
if (event & SYS_STATUS_RXOVRR) //NOTE when overrun both HS and RS pointers point to the same buffer
{
trace_printf("SYS_STATUS_RXOVRR\n");
//when the overrun happens the frame info data of the buffer A (which contains the older frame e.g. seq. num = x)
//will be corrupted with the latest frame (seq. num = x + 2) data, both the host and IC are pointing to buffer A
//we are going to discard this frame - turn off transceiver and reset receiver
dw1000Util_forceTrxOff();
dw1000Util_resetRxOnly();
uint32_t sys_ctrl = 0;
dw1000Hal_readRegisterFromIsr(SYS_CTRL_ID, (uint8_t*) &sys_ctrl,
SYS_CTRL_LEN); // switch to rx mode
sys_ctrl |= SYS_CTRL_RXENAB;
dw1000Hal_writeRegisterFromIsr(SYS_CTRL_ID, (uint8_t*) &sys_ctrl,
SYS_CTRL_LEN);
return pdFALSE;
} else //no overrun condition - proceed to process the frame
{
uint32_t rx_frame_info;
dw1000Hal_readRegisterFromIsr(RX_FINFO_ID,
(uint8_t *) &rx_frame_info,
RX_FINFO_LEN);
uint32_t rx_buffer_len;
uint8_t lde_done = (event & SYS_STATUS_LDEDONE) ? 1 : 0;
rx_buffer_len = rx_frame_info & RX_FINFO_RXFLEN_MASK; // No shifting required
trace_printf("Packet length: %u\n", rx_buffer_len);
xHigherPriorityTaskWoken = dw1000local.receiveCB(rx_buffer_len, lde_done);
uint32_t sys_ctrl = 0;
//dw1000Hal_resetRxOnly();
dw1000Hal_readRegisterFromIsr(SYS_CTRL_ID, (uint8_t*) &sys_ctrl,
SYS_CTRL_LEN); // switch to rx mode
sys_ctrl |= SYS_CTRL_RXENAB;
dw1000Hal_writeRegisterFromIsr(SYS_CTRL_ID, (uint8_t*) &sys_ctrl,
SYS_CTRL_LEN);
} //end of no overrun
} //if LDE_DONE is set (this means we have both SYS_STATUS_RXFCG and SYS_STATUS_LDEDONE)
//if(event & SYS_STATUS_LDEDONE) {
//} else { //no LDE_DONE ?
//trace_printf("NO LDE done or LDE error\n");
//}
//Fixme: Wann kann ein Overrun auftreten?
//Get get length
uint32_t rx_frame_info;
dw1000Hal_readRegisterFromIsr(RX_FINFO_ID, (uint8_t *) &rx_frame_info,
RX_FINFO_LEN);
uint32_t rx_buffer_len;
rx_buffer_len = rx_frame_info & RX_FINFO_RXFLEN_MASK; // No shifting required
uint8_t lde_done = (*event & SYS_STATUS_LDEDONE) ? 1 : 0;
//Trigger Callback
if (dw1000local.receiveCB != NULL) {
xHigherPriorityTaskWoken = dw1000local.receiveCB(rx_buffer_len,
lde_done);
} else if (dw1000local.taskHandle != NULL) {
//TODO Notify taskHandle
}
#ifdef DOUBLE_BUFFER
if((*event & SYS_STATUS_HSRBP) != (*event & SYS_STATUS_ICRBP)){
*event_clear |= *event & CLEAR_DBLBUFF_EVENTS ;
}
#endif
//Set the clear bits.
*event_clear |= CLEAR_ALLRXGOOD_EVENTS;
*event_clear |= CLEAR_ALLRXERROR_EVENTS;
dw1000Util_enableRX();
return xHigherPriorityTaskWoken;
}
void dw1000Isr_handleInterrupt(void) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
//trace_printf("ISR ENTRY\n");
uint64_t event = 0;
uint64_t event_clear = 0;
dw1000Hal_readRegisterFromIsr(SYS_STATUS_ID, (uint8_t*) &event,
SYS_STATUS_LEN);
uint64_t event_clear = 0;
//trace_printf("event start = %X\n", event);
// Handle weird somehow random occuring losing lock events
if (event & SYS_STATUS_CLKPLL_LL) { // Clock PLL Losing Lock
event_clear |= SYS_STATUS_CLKPLL_LL;
if (event & SYS_STATUS_CPLOCK) {
......@@ -90,122 +71,32 @@ void dw1000Isr_handleInterrupt(void) {
event &= ~(SYS_STATUS_CLKPLL_LL);
}
//
// if((status & SYS_STATUS_LDEDONE) && (dw1000local.dblbuffon == 0))
// if((event & (SYS_STATUS_LDEDONE | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD)) != (SYS_STATUS_LDEDONE | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD)){
// dw1000_forceTrxOff();
// //trace_printf("SHIT\n");
// dw1000Hal_resetRxOnly();
// }
if(event & SYS_STATUS_LDEDONE){
//trace_printf("LDEDONE\n");
//uint8_t new_time[5];
//dw1000Util_getRxTimestamp(new_time);
//hexdump(new_time, 5);
event_clear |= SYS_STATUS_LDEDONE;
//event &= ~(SYS_STATUS_LDEDONE); //Don't clear here because rx timestamp is handled in handleRX
}
if(event & SYS_STATUS_LDEERR){
//trace_printf("LDEERR\n");
event_clear |= SYS_STATUS_LDEERR;
event &= ~(SYS_STATUS_LDEERR);
}
if (event & SYS_STATUS_TXFRS) { // Frame sent
//trace_printf("TXcomplete\n");
event_clear |= SYS_STATUS_TXFRS; //clear interrupt
event &= ~(SYS_STATUS_TXFRS); //clear interrupt
dw1000Hal_handleTx(event);
if (event & SYS_STATUS_TXFRS) {
// Frame sent
dw1000Hal_handleTx(&event, &event_clear);
} else if ((event
& ( SYS_STATUS_RXFCG | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD))
!= (SYS_STATUS_RXFCG | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD)) {
#ifdef DOUBLE_BUFFER
dw1000Hal_handleRx(&event, &event_clear);
#else
//Error Case
trace_printf("Error!\n");
hexdump(&event, 5);
event_clear |= CLEAR_ALLRXERROR_EVENTS;
event_clear |= CLEAR_ALLRXGOOD_EVENTS;
dw1000Util_enableRX();
#endif
} else {
if ((event
& ( SYS_STATUS_RXFCG | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD))
!= (SYS_STATUS_RXFCG | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD)) {
trace_printf("Error!\n");
event_clear |= CLEAR_ALLRXERROR_EVENTS;
event_clear |= CLEAR_ALLRXGOOD_EVENTS;
//re-enable the receiver - if auto rx re-enable set
dw1000Util_enableRX();
} else {
if (event & SYS_STATUS_RXFCG) {
//trace_printf("RXFCG\n");
event_clear |= CLEAR_ALLRXGOOD_EVENTS;
event_clear |= CLEAR_ALLRXERROR_EVENTS;
dw1000Hal_handleRx(event);
} else if (event & SYS_STATUS_RXDFR) {
//trace_printf("Received\n");
trace_printf("RX DFR\n");
event_clear |= CLEAR_ALLRXGOOD_EVENTS;
dw1000Util_enableRX();
} else if (event & SYS_STATUS_RXPHE) {
trace_printf("PH ERROR\n");
event_clear |= CLEAR_ALLRXERROR_EVENTS;
dw1000Util_enableRX();
}
}
dw1000Hal_handleRx(&event, &event_clear);
}
// if (event & SYS_STATUS_RXDFR){ // Frame received
// event_clear |= SYS_STATUS_RXDFR; //clear interrupt
// trace_printf("dw1000Hal_extiCallback:received %lu\n",event);
//
// uint32_t rx_frame_info;
// dw1000Hal_readRegisterFromIsr(RX_FINFO_ID, (uint8_t *)&rx_frame_info, RX_FINFO_LEN);
// uint32_t rx_buffer_len;
// rx_buffer_len = rx_frame_info & RX_FINFO_RXFLEN_MASK ; // No shifting required
// trace_printf("%d\n", rx_buffer_len);
// xHigherPriorityTaskWoken |= receiveCB(rx_buffer_len);
// uint32_t sys_ctrl = 0;
// //dw1000Hal_resetRxOnly();
// dw1000Hal_readRegisterFromIsr(SYS_CTRL_ID, (uint8_t*)&sys_ctrl, SYS_CTRL_LEN); // switch to rx mode
// sys_ctrl |= SYS_CTRL_RXENAB;
// dw1000Hal_writeRegisterFromIsr(SYS_CTRL_ID, (uint8_t*)&sys_ctrl, SYS_CTRL_LEN);
// }
// if (event & SYS_STATUS_RXSFDD){ // Frame received
// event_clear |= SYS_STATUS_RXSFDD; //clear interrupt
// // trace_printf("dw1000Hal_extiCallback: sfd detected\n");
// uint32_t sys_ctrl = 0;
// dw1000Hal_readRegisterFromIsr(SYS_CTRL_ID, (uint8_t*)&sys_ctrl, SYS_CTRL_LEN); // switch to rx mode
// sys_ctrl |= SYS_CTRL_RXENAB;
// dw1000Hal_writeRegisterFromIsr(SYS_CTRL_ID, (uint8_t*)&sys_ctrl, SYS_CTRL_LEN);
// }
// if (event & SYS_STATUS_RXPRD){ // Frame received
// event_clear |= SYS_STATUS_RXPRD; //clear interrupt
// // trace_printf("dw1000Hal_extiCallback:preamble detected \n");
// uint32_t sys_ctrl = 0;
// dw1000Hal_readRegisterFromIsr(SYS_CTRL_ID, (uint8_t*)&sys_ctrl, SYS_CTRL_LEN); // switch to rx mode
// sys_ctrl |= SYS_CTRL_RXENAB;
// dw1000Hal_writeRegisterFromIsr(SYS_CTRL_ID, (uint8_t*)&sys_ctrl, SYS_CTRL_LEN);
// }
// if (event & SYS_STATUS_RXPHD){ // Frame received
// event_clear |= SYS_STATUS_RXPHD; //clear interrupt
// //trace_printf("dw1000Hal_extiCallback:PHR detected\n");
// uint32_t sys_ctrl = 0;
// dw1000Hal_readRegisterFromIsr(SYS_CTRL_ID, (uint8_t*)&sys_ctrl, SYS_CTRL_LEN); // switch to rx mode
// sys_ctrl |= SYS_CTRL_RXENAB;
// dw1000Hal_writeRegisterFromIsr(SYS_CTRL_ID, (uint8_t*)&sys_ctrl, SYS_CTRL_LEN);
// }
// if (event & SYS_STATUS_RXFCG) { // Frame received
// event_clear = 0x6F00; //clear interrupt
//
// trace_printf("dw1000Hal_extiCallback: CRC stuff %lu\n");
// uint32_t sys_ctrl = 0;
// dw1000Hal_readRegisterFromIsr(SYS_CTRL_ID, (uint8_t*) &sys_ctrl,
// SYS_CTRL_LEN); // switch to rx mode
// sys_ctrl |= SYS_CTRL_RXENAB;
// dw1000Hal_writeRegisterFromIsr(SYS_CTRL_ID, (uint8_t*) &sys_ctrl,
// SYS_CTRL_LEN);
// }
//trace_printf("event rest = %X\n", event);
//Clear the status register
dw1000Hal_writeRegisterFromIsr(SYS_STATUS_ID, (uint8_t*) &event_clear,
SYS_STATUS_LEN);
//Schedule higher priority task ASAP
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
//trace_printf("ISR DONE\n");
}
......@@ -2,6 +2,7 @@
#include "dw1000_hal.h"
#include "dw1000_util.h"
#include <stdio.h>
#include "Trace.h"
extern volatile uint32_t global_time;
......@@ -225,6 +226,19 @@ void dw1000Util_enableclocks(int clocks)
void dw1000Util_enableRX(){
#ifdef DOUBLE_BUFFER
//Align HSRBP and ICRBP if needed (see page 37 in the Usermanual)
uint64_t event = 0;
dw1000Hal_readRegisterFromIsr(SYS_STATUS_ID, (uint8_t*) &event,
SYS_STATUS_LEN);
if((event & SYS_STATUS_HSRBP) != (event & SYS_STATUS_ICRBP)){
uint32_t reg;
dw1000Hal_readRegisterFromIsr(SYS_CTRL_ID, (uint8_t *)&reg, SYS_CTRL_LEN);
reg |= SYS_CTRL_HSRBTOGGLE;
dw1000Hal_writeRegisterFromIsr(SYS_CTRL_ID, (uint8_t *)&reg, SYS_CTRL_LEN);
}
#endif
uint32_t sys_ctrl = 0;
dw1000Hal_readRegisterFromIsr(SYS_CTRL_ID, (uint8_t*) &sys_ctrl,
SYS_CTRL_LEN); // switch to rx mode
......@@ -317,7 +331,7 @@ void dw1000Util_forceTrxOff(void) {
uint32_t sys_ctrl = 0;
//DECA: decaIrqStatus_t stat ; ???
uint32_t sys_mask;
dw1000Hal_readRegister(SYS_MASK_ID, (uint8_t *) &sys_mask, SYS_MASK_LEN);
dw1000Hal_readRegisterFromIsr(SYS_MASK_ID, (uint8_t *) &sys_mask, SYS_MASK_LEN);
// need to beware of interrupts occurring in the middle of following read modify write cycle
......@@ -329,20 +343,20 @@ void dw1000Util_forceTrxOff(void) {
uint32_t tmp_mask = 0;
// No interrupts
dw1000Hal_writeRegister(SYS_MASK_ID, (uint8_t *) &tmp_mask, SYS_MASK_LEN);
dw1000Hal_writeRegisterFromIsr(SYS_MASK_ID, (uint8_t *) &tmp_mask, SYS_MASK_LEN);
//Disable radio
dw1000Hal_readRegister(SYS_CTRL_ID, (uint8_t *) &sys_ctrl, 4);
dw1000Hal_readRegisterFromIsr(SYS_CTRL_ID, (uint8_t *) &sys_ctrl, 4);
sys_ctrl |= SYS_CTRL_TRXOFF;// Immediately cancel all RX and TX operations, bring radio to IDLE state
dw1000Hal_writeRegister(SYS_CTRL_ID, (uint8_t *) &sys_ctrl, 4);
dw1000Hal_writeRegisterFromIsr(SYS_CTRL_ID, (uint8_t *) &sys_ctrl, 4);
uint32_t tmp = (CLEAR_ALLTX_EVENTS | CLEAR_ALLRXERROR_EVENTS | CLEAR_ALLRXGOOD_EVENTS);
dw1000Hal_writeRegister(SYS_STATUS_ID,(uint8_t *) &tmp, 4) ;
dw1000Hal_writeRegisterFromIsr(SYS_STATUS_ID,(uint8_t *) &tmp, 4) ;
//TODO dwt_syncrxbufptrs();
dw1000Hal_writeRegister(SYS_MASK_ID, (uint8_t *) &sys_mask, SYS_MASK_LEN);
dw1000Hal_writeRegisterFromIsr(SYS_MASK_ID, (uint8_t *) &sys_mask, SYS_MASK_LEN);
portENABLE_INTERRUPTS();
......
CFLAGS+=-I"Inc" -I"dw1000/Inc/"
SRC+=$(wildcard dw1000/Src/*.c)
\ No newline at end of file