Skip to content
Snippets Groups Projects
dw1000_hal.c 7.27 KiB
Newer Older
#include "dw1000_hal.h"

#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"
#include "stm32f4xx_hal.h"
#include "Trace.h"
#include "deca_regs.h"

#include "spi.h"

SPI_HandleTypeDef *hspi;

uint8_t read3[7];
static void (*spiCallback)(int state, void *data, uint16_t len);
static void *spiCallbackData;
static SemaphoreHandle_t spiSema = NULL;	//semaphore for SPI access

void dw1000Hal_chipSelect(void)
{
	HAL_GPIO_WritePin(DW1000HAL_SS_GPIO, DW1000HAL_SS_PIN, GPIO_PIN_RESET);
}

void dw1000Hal_chipDeselect(void)
{
	HAL_GPIO_WritePin(DW1000HAL_SS_GPIO, DW1000HAL_SS_PIN, GPIO_PIN_SET);
}

int dw1000Hal_readSubRegister(uint8_t regID, uint16_t offset, uint8_t *dest, uint16_t len)
{
	uint8_t dummy[3];
	int ret;
	if ((spiSema != NULL) && (xSemaphoreTake(spiSema, ( TickType_t ) DW1000HAL_SPI_TIMEOUT) == pdTRUE)) {
		if (len <= 127) {
			dummy[0] = regID & 0x3f; //set the first two bit 0 (read access, no subregister)
			dummy[0] |= 0x40; // subregister offset follows in second byte
			dummy[1] = offset & 0x7f; // set first bit 0 ( no third byte present)
			dw1000Hal_chipSelect();
			ret = HAL_SPI_Transmit(hspi, dummy, 2, DW1000HAL_SPI_TIMEOUT);
		} else {
			dummy[0] = regID & 0x3f; //set the first two bit 0 (read access, no subregister)
			dummy[0] |= 0x40; // subregister offset follows in second byte
			dummy[1] = 0x80 | (offset & 0x7f); // set first bit 1 ( third byte present)
			dummy[2] = offset >> 7;
			dw1000Hal_chipSelect();
			ret = HAL_SPI_Transmit(hspi, dummy, 3, DW1000HAL_SPI_TIMEOUT);
		}
		if (ret == HAL_OK) {
			ret = HAL_SPI_Receive(hspi, dest, len, DW1000HAL_SPI_TIMEOUT);
		}
		dw1000Hal_chipDeselect();
		while (hspi->State != HAL_SPI_STATE_READY);
		xSemaphoreGive(spiSema);
	} else {
		ret = HAL_LOCKED;
	}
	return ret;
}

int dw1000Hal_writeSubRegister(uint8_t regID, uint16_t offset, uint8_t *src, uint16_t len)
{
	uint8_t dummy[3];
	int ret;
	if ((spiSema != NULL) && (xSemaphoreTake(spiSema, ( TickType_t ) DW1000HAL_SPI_TIMEOUT) == pdTRUE)) {
		if (len <= 127) {
			dummy[0] = regID & 0x3f; //set the first two bit 0 (read access, no subregister)
			dummy[0] |= 0xC0; //write access, subregister offset follows in second byte
			dummy[1] = offset & 0x7f; // set first bit 0 ( no third byte present)
			dw1000Hal_chipSelect();
			ret = HAL_SPI_Transmit(hspi, dummy, 2, DW1000HAL_SPI_TIMEOUT);

		} else {
			dummy[0] = regID & 0x3f; //set the first two bit 0 (read access, no subregister)
			dummy[0] |= 0xC0; //write access, subregister offset follows in second byte
			dummy[1] = 0x80 | (offset & 0x7f); // set first bit 1 ( third byte present)
			dummy[2] = offset >> 7;
			dw1000Hal_chipSelect();
			ret = HAL_SPI_Transmit(hspi, dummy, 3, DW1000HAL_SPI_TIMEOUT);
		}
		if (ret == HAL_OK) {
			ret = HAL_SPI_Transmit(hspi, src, len, DW1000HAL_SPI_TIMEOUT);
		}
		dw1000Hal_chipDeselect();
		while (hspi->State != HAL_SPI_STATE_READY);
		xSemaphoreGive(spiSema);
	} else {
		ret = HAL_LOCKED;
	}
	return ret;
}

int dw1000Hal_readRegister(uint8_t regID, uint8_t *dest, uint16_t len)
{
	uint8_t dummy;
	dummy = regID & 0x3f; //set the first two bit 0 (read access, no subregister)
	int ret;
	if ((spiSema != NULL) && (xSemaphoreTake(spiSema, ( TickType_t ) DW1000HAL_SPI_TIMEOUT) == pdTRUE)) {
		dw1000Hal_chipSelect();
		ret = HAL_SPI_Transmit(hspi, &dummy, 1, DW1000HAL_SPI_TIMEOUT);
		if (ret == HAL_OK) {
			ret = HAL_SPI_Receive(hspi, dest, len, DW1000HAL_SPI_TIMEOUT);
		}
		dw1000Hal_chipDeselect();
		while (hspi->State != HAL_SPI_STATE_READY) {
		}
		xSemaphoreGive(spiSema);
	} else {
		ret = HAL_LOCKED;
	}
	return ret;
}

int dw1000Hal_writeRegister(uint8_t regID, uint8_t *src, uint16_t len)
{
	uint8_t dummy;
	dummy = regID & 0x3f; //set the first two bit 0 (read access, no subregister)
	dummy |= 0x80; 		 //set first byte 1 (write access)
	int ret;
	if ((spiSema != NULL) && (xSemaphoreTake(spiSema, ( TickType_t ) DW1000HAL_SPI_TIMEOUT) == pdTRUE)) {
		dw1000Hal_chipSelect();
		ret = HAL_SPI_Transmit(hspi, &dummy, 1, DW1000HAL_SPI_TIMEOUT);
		if (ret == HAL_OK) {
			ret = HAL_SPI_Transmit(hspi, src, len, DW1000HAL_SPI_TIMEOUT);
		}
		dw1000Hal_chipDeselect();
		while (hspi->State != HAL_SPI_STATE_READY) {
		}
		xSemaphoreGive(spiSema);
	} else {
		ret = HAL_LOCKED;
	}
	return ret;
}
int dw1000Hal_readDmaRegister(uint8_t regID, uint8_t *dest, uint16_t len, void (*callback)(int state, void *data, uint16_t len))
{
	uint8_t dummy;
	dummy = regID & 0x3f; //set the first two bit 0 (read access, no subregister)
	spiCallback = callback;
	spiCallbackData = dest;
	int ret;
	if ((spiSema != NULL) && (xSemaphoreTake(spiSema, ( TickType_t ) DW1000HAL_SPI_TIMEOUT) == pdTRUE)) {
		dw1000Hal_chipSelect();
		ret = HAL_SPI_Transmit(hspi, &dummy, 1, DW1000HAL_SPI_TIMEOUT);
		if (ret == HAL_OK) {
			ret = HAL_SPI_Receive_DMA(hspi, dest, len);
		} else {
			xSemaphoreGive(spiSema);
			dw1000Hal_chipDeselect();
		}
	} else {
		ret = HAL_LOCKED;
	}
	return ret;
}

int dw1000Hal_writeDmaRegister(uint8_t regID, uint8_t *src, uint16_t len, void (*callback)(int state, void *data, uint16_t len))
{
	uint8_t dummy;
	dummy = regID & 0x3f; //set the first two bit 0 (read access, no subregister)
	dummy |= 0x80; 		 //set first byte 1 (write access)
	spiCallback = callback;
	spiCallbackData = src;
	int ret;
	if ((spiSema != NULL) && (xSemaphoreTake(spiSema, ( TickType_t ) DW1000HAL_SPI_TIMEOUT) == pdTRUE)) {
		dw1000Hal_chipSelect();
		ret = HAL_SPI_Transmit(hspi, &dummy, 1, DW1000HAL_SPI_TIMEOUT);
		if (ret == HAL_OK) {
			ret = HAL_SPI_Transmit_DMA(hspi, src, len);
		} else {
			xSemaphoreGive(spiSema);
			dw1000Hal_chipDeselect();
		}
	} else {
		ret = HAL_LOCKED;
	}
	return ret;
}


void vTaskDW1000HAL(void *pvParameters)
{
	hspi = &hspi1;
	spiSema = xSemaphoreCreateMutex(); //creating semaphore for SPI access

	TickType_t xNextWakeTime;
	xNextWakeTime = xTaskGetTickCount();

	// all LED GPIOs as output
	uint8_t gpio_dir = 0xF0;
	dw1000Hal_writeSubRegister(GPIO_CTRL_ID, GPIO_DIR_OFFSET, &gpio_dir, 1);

	// turn on all 4 LEDs
	uint8_t gpio_dout = 0xFF;
	dw1000Hal_writeSubRegister(GPIO_CTRL_ID, GPIO_DOUT_OFFSET, &gpio_dout, 1);

	uint8_t led_values = 0;

	while(1){
		vTaskDelayUntil(&xNextWakeTime, 1000/portTICK_PERIOD_MS);
		HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);

		// count in binary on LEDs
		gpio_dout = led_values | 0xF0;
		dw1000Hal_writeSubRegister(GPIO_CTRL_ID, GPIO_DOUT_OFFSET, &gpio_dout, 1);

		led_values += 1;

		if (led_values > 15) {
			led_values = 0;
		}
	}
	vTaskDelete( NULL );
}

/***********************************************************
 * Callback functions
 */
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
	dw1000Hal_chipDeselect();
	xSemaphoreGiveFromISR(spiSema, pdFALSE);
	if (spiCallback != NULL){
		spiCallback(HAL_ERROR, 0, hspi->TxXferSize);
	}

}

void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
	dw1000Hal_chipDeselect();
	xSemaphoreGiveFromISR(spiSema, pdFALSE);
	if (spiCallback != NULL){
		spiCallback(HAL_ERROR, 0, hspi->TxXferSize);
	}
}

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
	dw1000Hal_chipDeselect();
	xSemaphoreGiveFromISR(spiSema, pdFALSE);
	if (spiCallback != NULL){
		spiCallback(HAL_ERROR, 0, hspi->TxXferSize);
	}
}

void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
	dw1000Hal_chipDeselect();
	xSemaphoreGiveFromISR(spiSema, pdFALSE);
	if (spiCallback != NULL){
		spiCallback(HAL_ERROR, 0, hspi->TxXferSize);
	}
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
}