From 437ba90bc2bb90e2e307584b3246671a05f77739 Mon Sep 17 00:00:00 2001 From: Thomas Klaehn Date: Sun, 29 Mar 2020 12:12:42 +0200 Subject: [PATCH] Add nrf spi driver --- include/platform/nrf52/nrf52-dk.h | 12 ++++ include/spi.h | 18 ++++++ src/application/spi/main.c | 94 ++++--------------------------- src/platform/nrf52/spi.c | 62 ++++++++++++++++++++ 4 files changed, 102 insertions(+), 84 deletions(-) create mode 100644 include/spi.h create mode 100644 src/platform/nrf52/spi.c diff --git a/include/platform/nrf52/nrf52-dk.h b/include/platform/nrf52/nrf52-dk.h index 473651c..f180883 100644 --- a/include/platform/nrf52/nrf52-dk.h +++ b/include/platform/nrf52/nrf52-dk.h @@ -4,6 +4,7 @@ #include "driver.h" #include "gpio.h" +#include "spi.h" // LED 1 const struct gpio nrf_led_1 = { @@ -49,4 +50,15 @@ const struct driver led_4 = { .dev = &nrf_led_4 }; +const struct spi nrf_spi_0 = { + .sck_pin = 2, + .mosi_pin = 3, + .miso_pin = 4 +}; +const struct driver spi_0 = { + .name = "SPI0", + .fp = &spi_fp, + .dev = &nrf_spi_0 +}; + #endif diff --git a/include/spi.h b/include/spi.h new file mode 100644 index 0000000..0b68c32 --- /dev/null +++ b/include/spi.h @@ -0,0 +1,18 @@ +int spi_open(const struct driver *drv); +int spi_close(const struct driver *drv); + +int spi_write(const struct driver *drv, const char *buffer, unsigned int len); + +struct spi { + unsigned int sck_pin; + unsigned int mosi_pin; + unsigned int miso_pin; +}; + +static const struct driver_fp spi_fp = { + .open = spi_open, + .close = spi_close, + .read = NULL, + .write = spi_write, + .ioctl = NULL +}; diff --git a/src/application/spi/main.c b/src/application/spi/main.c index b0a485c..3a8a0ef 100644 --- a/src/application/spi/main.c +++ b/src/application/spi/main.c @@ -1,43 +1,3 @@ -/** - * Copyright (c) 2015 - 2019, Nordic Semiconductor ASA - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -#include "nrf_drv_spi.h" #include "app_util_platform.h" #include "nrf_gpio.h" #include "nrf_delay.h" @@ -48,63 +8,29 @@ #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" -#define SPI_INSTANCE 0 /**< SPI instance index. */ -static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */ -static volatile bool spi_xfer_done; /**< Flag used to indicate that SPI instance completed the transfer. */ +#include "board.h" +#include "driver.h" -#define TEST_STRING "Nordic" -static uint8_t m_tx_buf[] = TEST_STRING; /**< TX buffer. */ -static uint8_t m_rx_buf[sizeof(TEST_STRING) + 1]; /**< RX buffer. */ -static const uint8_t m_length = sizeof(m_tx_buf); /**< Transfer length. */ - -/** - * @brief SPI user event handler. - * @param event - */ -void spi_event_handler(nrf_drv_spi_evt_t const * p_event, - void * p_context) -{ - spi_xfer_done = true; - NRF_LOG_INFO("Transfer completed."); - if (m_rx_buf[0] != 0) - { - NRF_LOG_INFO(" Received:"); - NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf)); - } -} +const char buf[] = "Test"; int main(void) { - bsp_board_init(BSP_INIT_LEDS); - + unsigned int cnt = 0; APP_ERROR_CHECK(NRF_LOG_INIT(NULL)); NRF_LOG_DEFAULT_BACKENDS_INIT(); - nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; - spi_config.ss_pin = SPI_SS_PIN; - spi_config.miso_pin = SPI_MISO_PIN; - spi_config.mosi_pin = SPI_MOSI_PIN; - spi_config.sck_pin = SPI_SCK_PIN; - APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL)); + drv_open(&led_1); + drv_open(&spi_0); NRF_LOG_INFO("SPI example started."); - while (1) - { - // Reset rx buffer and transfer done flag - memset(m_rx_buf, 0, m_length); - spi_xfer_done = false; - - APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length)); - - while (!spi_xfer_done) - { - __WFE(); - } + while(1) { + char c = (cnt++ % 2) + 0x30; + drv_write(&led_1, &c, 1); + drv_write(&spi_0, buf, sizeof(buf)); NRF_LOG_FLUSH(); - bsp_board_led_invert(BSP_BOARD_LED_0); nrf_delay_ms(200); } } diff --git a/src/platform/nrf52/spi.c b/src/platform/nrf52/spi.c new file mode 100644 index 0000000..cbcea76 --- /dev/null +++ b/src/platform/nrf52/spi.c @@ -0,0 +1,62 @@ +#include +#include + +#include "nrf.h" + +#include "driver.h" +#include "spi.h" + +static inline int spi_transfer(uint32_t t); + + +int spi_open(const struct driver *drv) +{ + assert(NULL != drv); + + struct spi *this = (struct spi *)drv->dev; + + NRF_SPI0->ENABLE = 0; + NRF_SPI0->PSELSCK = this->sck_pin; + NRF_SPI0->PSELMOSI = this->mosi_pin; + NRF_SPI0->PSELMISO = this->miso_pin; + NRF_SPI0->FREQUENCY = SPI_FREQUENCY_FREQUENCY_M8; + + NRF_SPI0->CONFIG = (0x03 << 1); //Sample on trailing edge of clock, shift serial data on leading edge, SCK polarity Active low + NRF_SPI0->EVENTS_READY = 0; + NRF_SPI0->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); + + return 0; +} + +int spi_close(const struct driver *drv) +{ + NRF_SPI0->ENABLE = 0; + + return 0; +} + +int spi_write(const struct driver *drv, const char *buffer, unsigned int len) +{ + assert(NULL != buffer); + + //FIXME: missing CS handling + + for(unsigned int i = 0; i < len; i++) { + spi_transfer(buffer[i]); + } + + //FIXME: missing CS handling + + return len; +} + +static inline int spi_transfer(uint32_t t) +{ + volatile uint32_t r; + NRF_SPI0->EVENTS_READY = 0; // ready + NRF_SPI0->TXD = t; // out + while(NRF_SPI0->EVENTS_READY == 0) { + } + r = NRF_SPI0->RXD; // in + return (int)r; +} -- 2.45.2