107 lines
3.5 KiB
C
107 lines
3.5 KiB
C
#include "nrf_drv_spi.h"
|
|
#include "nrf_gpio.h"
|
|
#include "nrf_log.h"
|
|
|
|
#include "FreeRTOS.h"
|
|
#include "semphr.h"
|
|
#include "task.h"
|
|
|
|
#define SPI1_CLK_PIN NRF_GPIO_PIN_MAP(0, 13)
|
|
#define SPI1_MOSI_PIN NRF_GPIO_PIN_MAP(0, 14)
|
|
|
|
#define SPI2_CLK_PIN NRF_GPIO_PIN_MAP(0, 12)
|
|
#define SPI2_MOSI_PIN NRF_GPIO_PIN_MAP(0, 7)
|
|
#define SPI2_MISO_PIN NRF_GPIO_PIN_MAP(1, 9)
|
|
|
|
static const nrf_drv_spi_t spim1 = NRF_DRV_SPI_INSTANCE(1); /**< SPI instance. */
|
|
static const nrf_drv_spi_t spim2 = NRF_DRV_SPI_INSTANCE(2); /**< SPI instance. */
|
|
static SemaphoreHandle_t spim1_sem = NULL;
|
|
static SemaphoreHandle_t spim2_sem = NULL;
|
|
static SemaphoreHandle_t spim2_mutex = NULL;
|
|
|
|
void nrf_drv_spim1_evt_handler(nrf_drv_spi_evt_t const *p_event, void *p_context)
|
|
{
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
switch (p_event->type)
|
|
{
|
|
case NRF_DRV_SPI_EVENT_DONE:
|
|
xSemaphoreGiveFromISR(spim1_sem, &xHigherPriorityTaskWoken);
|
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void nrf_drv_spim2_evt_handler(nrf_drv_spi_evt_t const *p_event, void *p_context)
|
|
{
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
switch (p_event->type)
|
|
{
|
|
case NRF_DRV_SPI_EVENT_DONE:
|
|
xSemaphoreGiveFromISR(spim2_sem, &xHigherPriorityTaskWoken);
|
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void spi_init(void)
|
|
{
|
|
spim1_sem = xSemaphoreCreateBinary();
|
|
|
|
spim2_sem = xSemaphoreCreateBinary();
|
|
spim2_mutex = xSemaphoreCreateMutex();
|
|
|
|
nrf_drv_spi_config_t spi1_config = NRF_DRV_SPI_DEFAULT_CONFIG;
|
|
spi1_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED;
|
|
spi1_config.miso_pin = NRF_DRV_SPI_PIN_NOT_USED;
|
|
spi1_config.mosi_pin = SPI1_MOSI_PIN;
|
|
spi1_config.sck_pin = SPI1_CLK_PIN;
|
|
spi1_config.mode = NRF_DRV_SPI_MODE_0;
|
|
spi1_config.frequency = NRF_DRV_SPI_FREQ_8M;
|
|
APP_ERROR_CHECK(nrf_drv_spi_init(&spim1, &spi1_config, nrf_drv_spim1_evt_handler, NULL));
|
|
|
|
nrf_drv_spi_config_t spi2_config = NRF_DRV_SPI_DEFAULT_CONFIG;
|
|
spi2_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED;
|
|
spi2_config.miso_pin = SPI2_MISO_PIN;
|
|
spi2_config.mosi_pin = SPI2_MOSI_PIN;
|
|
spi2_config.sck_pin = SPI2_CLK_PIN;
|
|
spi2_config.mode = NRF_DRV_SPI_MODE_1;
|
|
spi2_config.frequency = NRF_DRV_SPI_FREQ_8M;
|
|
APP_ERROR_CHECK(nrf_drv_spi_init(&spim2, &spi2_config, nrf_drv_spim2_evt_handler, NULL));
|
|
}
|
|
|
|
void spi1_write(uint8_t *p_tx_buffer, uint8_t tx_buffer_length)
|
|
{
|
|
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spim1, p_tx_buffer, tx_buffer_length, NULL, 0));
|
|
xSemaphoreTake(spim1_sem, portMAX_DELAY);
|
|
}
|
|
|
|
void spi2_write(uint32_t cs_pin, uint8_t *p_tx_buffer, uint8_t tx_buffer_length, uint8_t *p_rx_buf, uint8_t rx_buffer_length)
|
|
{
|
|
xSemaphoreTake(spim2_mutex, portMAX_DELAY);
|
|
|
|
nrf_gpio_pin_clear(cs_pin);
|
|
|
|
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spim2, p_tx_buffer, tx_buffer_length, p_rx_buf, rx_buffer_length));
|
|
if (xSemaphoreTake(spim2_sem, pdMS_TO_TICKS(100)) == pdFALSE)
|
|
{
|
|
// TODO... spi transfer timeout.
|
|
}
|
|
|
|
nrf_gpio_pin_set(cs_pin);
|
|
|
|
xSemaphoreGive(spim2_mutex);
|
|
|
|
NRF_LOG_INFO("spi(W)");
|
|
NRF_LOG_HEXDUMP_INFO(p_tx_buffer, tx_buffer_length);
|
|
|
|
if (rx_buffer_length > 0)
|
|
{
|
|
NRF_LOG_INFO("spi(R)");
|
|
NRF_LOG_HEXDUMP_INFO(p_rx_buf, rx_buffer_length);
|
|
}
|
|
}
|