-
Georg von Zengen authoredGeorg von Zengen authored
dw1000_isr.c 2.75 KiB
#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 xHigherPriorityTaskWoken = pdFALSE;
dw1000Util_enableRX();
if (dw1000local.sendCB != NULL) {
xHigherPriorityTaskWoken |= dw1000local.sendCB();
}
return xHigherPriorityTaskWoken;
}
BaseType_t dw1000Hal_handleRx(uint64_t * event, uint64_t * event_clear) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
//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;
uint64_t event = 0;
uint64_t event_clear = 0;
dw1000Hal_readRegisterFromIsr(SYS_STATUS_ID, (uint8_t*) &event,
SYS_STATUS_LEN);
// 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) {
event_clear |= SYS_STATUS_CPLOCK;
trace_printf("dw1000Hal_extiCallback:Clock PLL Losing Lock\n");
event &= ~(SYS_STATUS_CPLOCK);
}
event &= ~(SYS_STATUS_CLKPLL_LL);
}
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 {
dw1000Hal_handleRx(&event, &event_clear);
}
//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);
}