Skip to content
Snippets Groups Projects
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);

}