Add nrf52 spi driver abstraction

This commit is contained in:
Thomas Klaehn 2020-03-28 08:45:36 +01:00
parent 3729c0e2c0
commit 004793fcc5
2 changed files with 115 additions and 0 deletions

29
include/spi.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef __NRF52_SPI_H__
#define __NRF52_SPI_H__
#include <stdint.h>
#include "driver.h"
int spi_open(const struct driver *drv);
int spi_close(const struct driver *drv);
int spi_read(const struct driver *drv, char *buffer, unsigned int len);
int spi_write(const struct driver *drv, const char *buffer, unsigned int len);
struct spi {
uint8_t sck_pin;
uint8_t mosi_pin;
uint8_t miso_pin;
uint8_t ss_pin;
};
static const struct driver_fp spi_fp = {
.open = spi_open,
.close = spi_close,
.read = spi_read,
.write = spi_write,
.ioctl = NULL
};
#endif

86
src/platform/nrf52/spi.c Normal file
View File

@ -0,0 +1,86 @@
#include <assert.h>
#include "nrf_drv_spi.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "driver.h"
#include "spi.h"
#define SPI_INSTANCE 0
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);
static volatile bool spi_xfer_done;
struct spi_object {
uint8_t *rx_buf;
uint8_t *tx_buf;
uint32_t rx_len;
uint32_t tx_len;
};
uint8_t rx_buffer[1];
uint8_t tx_buffer[20];
static struct spi_object spi_obj = {
.rx_buf = rx_buffer,
.tx_buf = tx_buffer,
.rx_len = sizeof(rx_buffer),
.tx_len = sizeof(tx_buffer)
};
void spi_event_handler(nrf_drv_spi_evt_t const * p_event, void * p_context)
{
spi_xfer_done = true;
NRF_LOG_INFO("Transfer completed.");
}
int spi_open(const struct driver *drv)
{
assert(NULL != drv);
struct spi *this = (struct spi *)(drv->dev);
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_config.ss_pin = this->ss_pin;
spi_config.miso_pin = this->miso_pin;
spi_config.mosi_pin = this->mosi_pin;
spi_config.sck_pin = this->sck_pin;
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
return 0;
}
int spi_close(const struct driver *drv)
{
assert(NULL != drv);
return 0;
}
int spi_read(const struct driver *drv, char *buffer, unsigned int len)
{
assert((NULL != drv) && (NULL != buffer));
NRF_LOG_INFO("spi read not implemented yet.");
return 0;
}
int spi_write(const struct driver *drv, const char *buffer, unsigned int len)
{
if(len > spi_obj.tx_len) {
NRF_LOG_ERROR("buffer too small");
return 0;
}
memcpy(spi_obj.tx_buf, buffer, len);
// Reset transfer done flag
spi_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, spi_obj.tx_buf, spi_obj.tx_len, spi_obj.rx_buf, spi_obj.rx_len));
while(!spi_xfer_done) {
__WFE();
}
return (int)len;
}