samples: boards: nrf: Add an nrfx peripheral resource sharing sample
Add a sample that shows how to use in Zephyr nRF peripherals that share the same ID and base address. Such peripherals cannot be used simultaneously, but it is possible to switch between them. However, currently it is not possible with Zephyr APIs, only using nrfx drivers directly. This sample shows how to realize such switching for selected peripheral instances while using standard Zephyr drivers for others. Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
This commit is contained in:
parent
6024bbc601
commit
069bac094d
8
samples/boards/nrf/nrfx_prs/CMakeLists.txt
Normal file
8
samples/boards/nrf/nrfx_prs/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.13.1)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(nrfx_prs)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
59
samples/boards/nrf/nrfx_prs/README.rst
Normal file
59
samples/boards/nrf/nrfx_prs/README.rst
Normal file
|
@ -0,0 +1,59 @@
|
|||
.. _nrfx_prs_sample:
|
||||
|
||||
nrfx peripheral resource sharing example
|
||||
########################################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
This sample shows how to use in Zephyr nRF perpipherals that share the same ID
|
||||
and base address. Such peripherals cannot be used simultaneously because they
|
||||
share certain hardware resources, but it is possible to switch between them and
|
||||
use one or the other alternately. Because of the current driver model in Zephyr
|
||||
and the lack of possibility to deinitialize a peripheral that is initialized by
|
||||
a driver at boot, such switching cannot be achieved with Zephyr APIs. Therefore,
|
||||
this sample uses the nrfx drivers directly for those peripheral instances that
|
||||
are to be switched (SPIM2 and UARTE2) while the standard Zephyr drivers are used
|
||||
for other instances of the same peripheral types (UARTE0 is used by the standard
|
||||
Zephyr console and SPIM1 is used for performing additional sample transfers).
|
||||
|
||||
The sample uses two buttons:
|
||||
- by pressing Button 1 user can request a transfer to be performed using the
|
||||
currently initialized peripheral (SPIM2 or UARTE2)
|
||||
- by pressing Button 2 user can switch between the two peripherals
|
||||
|
||||
When no button is pressed, every 5 seconds a background transfer using SPIM1
|
||||
is performed.
|
||||
|
||||
The sample outputs on the standard console the hex codes of all sent and
|
||||
received bytes, so when the proper loopback wiring is provided on the used
|
||||
board (between the MOSI and MISO pins for SPIMs and between the TX and RX pins
|
||||
for the UARTE), it can be checked that what is sent by a given peripheral
|
||||
is also received back. Without such wiring, no data is received by UARTE and
|
||||
all zeros are received by SPIMs. Refer to the overlay files provided in the
|
||||
:zephyr_file:`samples/boards/nrf/nrfx_prs/boards` directory to check which pins
|
||||
on the boards supported by the sample are assigned as MOSI/MISO and TX/RX pins.
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
This sample has been tested on the Nordic Semiconductor nRF9160 DK
|
||||
(nrf9160dk_nrf9160) and nRF5340 DK (nrf5340dk_nrf5340_cpuapp) boards.
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
The code can be found in :zephyr_file:`samples/boards/nrf/nrfx_prs`.
|
||||
|
||||
To build and flash the application:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/boards/nrf/nrfx_prs
|
||||
:board: nrf9160dk_nrf9160
|
||||
:goals: build flash
|
||||
:compact:
|
||||
|
||||
Press Button 1 to trigger a sample transfer on SPIM2 or UARTE2.
|
||||
Press Button 2 to switch the type of peripheral to be used for the transfer.
|
||||
|
||||
When no button is pressed, a background transfer on SPIM1 is performed.
|
|
@ -0,0 +1,41 @@
|
|||
/* This node corresponds to the SPIM1 peripheral that is to be used via
|
||||
* the Zephyr driver, so it must have the status set to "okay".
|
||||
*/
|
||||
&spi1 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
status = "okay";
|
||||
sck-pin = <6>;
|
||||
mosi-pin = <7>;
|
||||
miso-pin = <25>;
|
||||
cs-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
|
||||
miso-pull-down;
|
||||
};
|
||||
|
||||
/* The UARTE1 peripheral share the same ID with SPIM1, hence these two
|
||||
* peripherals cannot be used simultaneously and this node must be disabled.
|
||||
*/
|
||||
&uart1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
/* The following two nodes (corresponding to the SPIM2 and UARTE2 peripherals,
|
||||
* respectively) need to be disabled so that Zephyr drivers won't initialize
|
||||
* those instances; the application will use them via nrfx drivers. But their
|
||||
* pins must be specified, as the application expects to get this information
|
||||
* from devicetree.
|
||||
*/
|
||||
&spi2 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
status = "disabled";
|
||||
sck-pin = <41>;
|
||||
mosi-pin = <40>;
|
||||
miso-pin = <39>;
|
||||
cs-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
&uart2 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
status = "disabled";
|
||||
tx-pin = <43>;
|
||||
rx-pin = <42>;
|
||||
};
|
48
samples/boards/nrf/nrfx_prs/boards/nrf9160dk_nrf9160.overlay
Normal file
48
samples/boards/nrf/nrfx_prs/boards/nrf9160dk_nrf9160.overlay
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* This node corresponds to the SPIM1 peripheral that is to be used via
|
||||
* the Zephyr driver, so it must have the status set to "okay".
|
||||
*/
|
||||
&spi1 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
status = "okay";
|
||||
sck-pin = <16>;
|
||||
mosi-pin = <17>;
|
||||
miso-pin = <18>;
|
||||
cs-gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
|
||||
miso-pull-down;
|
||||
};
|
||||
|
||||
/* The UARTE1 peripheral share the same ID with SPIM1, hence these two
|
||||
* peripherals cannot be used simultaneously and this node must be disabled.
|
||||
*/
|
||||
&uart1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
/* The following two nodes (corresponding to the SPIM2 and UARTE2 peripherals,
|
||||
* respectively) need to be disabled so that Zephyr drivers won't initialize
|
||||
* those instances; the application will use them via nrfx drivers. But their
|
||||
* pins must be specified, as the application expects to get this information
|
||||
* from devicetree.
|
||||
*/
|
||||
&spi2 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
status = "disabled";
|
||||
sck-pin = <13>;
|
||||
mosi-pin = <12>;
|
||||
miso-pin = <11>;
|
||||
cs-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
&uart2 {
|
||||
status = "disabled";
|
||||
tx-pin = <9>;
|
||||
rx-pin = <8>;
|
||||
};
|
||||
|
||||
/* This node also needs to be disabled, as in the default nrf9160dk_nrf9160
|
||||
* board configuration it uses the same pin numbers that are above assigned
|
||||
* to the spi1 node (17, 18, and 19).
|
||||
*/
|
||||
&spi3 {
|
||||
status = "disabled";
|
||||
};
|
9
samples/boards/nrf/nrfx_prs/prj.conf
Normal file
9
samples/boards/nrf/nrfx_prs/prj.conf
Normal file
|
@ -0,0 +1,9 @@
|
|||
# This is needed for using SPIM2 and UARTE2 via nrfx drivers and for switching
|
||||
# between those peripherals, as they share the same ID and hence cannot be used
|
||||
# simultaneously.
|
||||
CONFIG_NRFX_SPIM2=y
|
||||
CONFIG_NRFX_UARTE2=y
|
||||
CONFIG_NRFX_PRS_BOX_2=y
|
||||
|
||||
# This is needed for using another SPIM instance via the Zephyr SPI driver.
|
||||
CONFIG_SPI=y
|
17
samples/boards/nrf/nrfx_prs/sample.yaml
Normal file
17
samples/boards/nrf/nrfx_prs/sample.yaml
Normal file
|
@ -0,0 +1,17 @@
|
|||
sample:
|
||||
name: nrfx Peripheral Resource Sharing example
|
||||
tests:
|
||||
sample.boards.nrf.nrfx_prs:
|
||||
platform_allow: nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160
|
||||
integration_platforms:
|
||||
- nrf5340dk_nrf5340_cpuapp
|
||||
- nrf9160dk_nrf9160
|
||||
tags: nrfx
|
||||
harness: console
|
||||
harness_config:
|
||||
type: multi_line
|
||||
ordered: true
|
||||
regex:
|
||||
- "nrfx PRS example on .*"
|
||||
- "-> press \".*\" to trigger a transfer"
|
||||
- "-> press \".*\" to switch the type of peripheral"
|
396
samples/boards/nrf/nrfx_prs/src/main.c
Normal file
396
samples/boards/nrf/nrfx_prs/src/main.c
Normal file
|
@ -0,0 +1,396 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <drivers/spi.h>
|
||||
|
||||
#include <nrfx_spim.h>
|
||||
#include <nrfx_uarte.h>
|
||||
#include <drivers/src/prs/nrfx_prs.h>
|
||||
|
||||
#define TRANSFER_LENGTH 10
|
||||
|
||||
/* Devicetree nodes corresponding to the peripherals to be used directly via
|
||||
* nrfx drivers (SPIM2 and UARTE2).
|
||||
*/
|
||||
#define SPIM_NODE DT_NODELABEL(spi2)
|
||||
#define UARTE_NODE DT_NODELABEL(uart2)
|
||||
|
||||
/* Devicetree node corresponding to the peripheral to be used via Zephyr SPI
|
||||
* driver (SPIM1), in the background transfer.
|
||||
*/
|
||||
#define SPI_DEV_NODE DT_NODELABEL(spi1)
|
||||
|
||||
static nrfx_spim_t spim = NRFX_SPIM_INSTANCE(2);
|
||||
static nrfx_uarte_t uarte = NRFX_UARTE_INSTANCE(2);
|
||||
static bool spim_initialized;
|
||||
static bool uarte_initialized;
|
||||
static volatile size_t received;
|
||||
static K_SEM_DEFINE(transfer_finished, 0, 1);
|
||||
|
||||
static enum {
|
||||
PERFORM_TRANSFER,
|
||||
SWITCH_PERIPHERAL
|
||||
} user_request;
|
||||
static K_SEM_DEFINE(button_pressed, 0, 1);
|
||||
|
||||
static void sw0_handler(const struct device *dev, struct gpio_callback *cb,
|
||||
uint32_t pins)
|
||||
{
|
||||
user_request = PERFORM_TRANSFER;
|
||||
k_sem_give(&button_pressed);
|
||||
}
|
||||
|
||||
static void sw1_handler(const struct device *dev, struct gpio_callback *cb,
|
||||
uint32_t pins)
|
||||
{
|
||||
user_request = SWITCH_PERIPHERAL;
|
||||
k_sem_give(&button_pressed);
|
||||
}
|
||||
|
||||
static bool init_buttons(void)
|
||||
{
|
||||
static const struct button_spec {
|
||||
struct gpio_dt_spec gpio;
|
||||
char const *label;
|
||||
char const *action;
|
||||
gpio_callback_handler_t handler;
|
||||
} btn_spec[] = {
|
||||
{
|
||||
GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios),
|
||||
DT_PROP(DT_ALIAS(sw0), label),
|
||||
"trigger a transfer",
|
||||
sw0_handler
|
||||
},
|
||||
{
|
||||
GPIO_DT_SPEC_GET(DT_ALIAS(sw1), gpios),
|
||||
DT_PROP(DT_ALIAS(sw1), label),
|
||||
"switch the type of peripheral",
|
||||
sw1_handler
|
||||
},
|
||||
};
|
||||
static struct gpio_callback btn_cb_data[ARRAY_SIZE(btn_spec)];
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(btn_spec); ++i) {
|
||||
const struct button_spec *btn = &btn_spec[i];
|
||||
int ret;
|
||||
|
||||
if (!device_is_ready(btn->gpio.port)) {
|
||||
printk("%s is not ready\n", btn->gpio.port->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = gpio_pin_configure_dt(&btn->gpio, GPIO_INPUT);
|
||||
if (ret < 0) {
|
||||
printk("Failed to configure %s pin %d: %d\n",
|
||||
btn->gpio.port->name, btn->gpio.pin, ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = gpio_pin_interrupt_configure_dt(&btn->gpio,
|
||||
GPIO_INT_EDGE_TO_ACTIVE);
|
||||
if (ret < 0) {
|
||||
printk("Failed to configure interrupt on %s pin %d: %d\n",
|
||||
btn->gpio.port->name, btn->gpio.pin, ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
gpio_init_callback(&btn_cb_data[i],
|
||||
btn->handler, BIT(btn->gpio.pin));
|
||||
gpio_add_callback(btn->gpio.port, &btn_cb_data[i]);
|
||||
printk("-> press \"%s\" to %s\n", btn->label, btn->action);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void spim_handler(const nrfx_spim_evt_t *p_event, void *p_context)
|
||||
{
|
||||
if (p_event->type == NRFX_SPIM_EVENT_DONE) {
|
||||
k_sem_give(&transfer_finished);
|
||||
}
|
||||
}
|
||||
|
||||
static bool switch_to_spim(void)
|
||||
{
|
||||
if (spim_initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If the UARTE is currently initialized, it must be deinitialized
|
||||
* before the SPIM can be used.
|
||||
*/
|
||||
if (uarte_initialized) {
|
||||
nrfx_uarte_uninit(&uarte);
|
||||
uarte_initialized = false;
|
||||
}
|
||||
|
||||
nrfx_err_t err;
|
||||
nrfx_spim_config_t spim_config = NRFX_SPIM_DEFAULT_CONFIG(
|
||||
/* Take pin numbers from devicetree. */
|
||||
DT_PROP(SPIM_NODE, sck_pin),
|
||||
DT_PROP(SPIM_NODE, mosi_pin),
|
||||
DT_PROP(SPIM_NODE, miso_pin),
|
||||
NRF_DT_GPIOS_TO_PSEL(SPIM_NODE, cs_gpios));
|
||||
spim_config.frequency = NRF_SPIM_FREQ_1M;
|
||||
spim_config.miso_pull = NRF_GPIO_PIN_PULLDOWN;
|
||||
|
||||
err = nrfx_spim_init(&spim, &spim_config, spim_handler, NULL);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
printk("nrfx_spim_init() failed: 0x%08x\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
spim_initialized = true;
|
||||
printk("Switched to SPIM\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool spim_transfer(const uint8_t *tx_data, size_t tx_data_len,
|
||||
uint8_t *rx_buf, size_t rx_buf_size)
|
||||
{
|
||||
nrfx_err_t err;
|
||||
nrfx_spim_xfer_desc_t xfer_desc = {
|
||||
.p_tx_buffer = tx_data,
|
||||
.tx_length = tx_data_len,
|
||||
.p_rx_buffer = rx_buf,
|
||||
.rx_length = rx_buf_size,
|
||||
};
|
||||
|
||||
err = nrfx_spim_xfer(&spim, &xfer_desc, 0);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
printk("nrfx_spim_xfer() failed: 0x%08x\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (k_sem_take(&transfer_finished, K_MSEC(100)) != 0) {
|
||||
printk("SPIM transfer timeout\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
received = rx_buf_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void uarte_handler(const nrfx_uarte_event_t *p_event, void *p_context)
|
||||
{
|
||||
if (p_event->type == NRFX_UARTE_EVT_RX_DONE) {
|
||||
received = p_event->data.rxtx.bytes;
|
||||
k_sem_give(&transfer_finished);
|
||||
} else if (p_event->type == NRFX_UARTE_EVT_ERROR) {
|
||||
received = 0;
|
||||
k_sem_give(&transfer_finished);
|
||||
}
|
||||
}
|
||||
|
||||
static bool switch_to_uarte(void)
|
||||
{
|
||||
if (uarte_initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If the SPIM is currently initialized, it must be deinitialized
|
||||
* before the UARTE can be used.
|
||||
*/
|
||||
if (spim_initialized) {
|
||||
nrfx_spim_uninit(&spim);
|
||||
spim_initialized = false;
|
||||
}
|
||||
|
||||
nrfx_err_t err;
|
||||
nrfx_uarte_config_t uarte_config = NRFX_UARTE_DEFAULT_CONFIG(
|
||||
/* Take pin numbers from devicetree. */
|
||||
DT_PROP(UARTE_NODE, tx_pin),
|
||||
DT_PROP(UARTE_NODE, rx_pin));
|
||||
uarte_config.baudrate = NRF_UARTE_BAUDRATE_1000000;
|
||||
|
||||
err = nrfx_uarte_init(&uarte, &uarte_config, uarte_handler);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
printk("nrfx_uarte_init() failed: 0x%08x\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
uarte_initialized = true;
|
||||
printk("Switched to UARTE\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool uarte_transfer(const uint8_t *tx_data, size_t tx_data_len,
|
||||
uint8_t *rx_buf, size_t rx_buf_size)
|
||||
{
|
||||
nrfx_err_t err;
|
||||
|
||||
err = nrfx_uarte_rx(&uarte, rx_buf, rx_buf_size);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
printk("nrfx_uarte_rx() failed: 0x%08x\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
err = nrfx_uarte_tx(&uarte, tx_data, tx_data_len);
|
||||
if (err != NRFX_SUCCESS) {
|
||||
printk("nrfx_uarte_tx() failed: 0x%08x\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (k_sem_take(&transfer_finished, K_MSEC(100)) != 0) {
|
||||
/* The UARTE transfer finishes when the RX buffer is completely
|
||||
* filled. In case the UARTE receives less data (or nothing at
|
||||
* all) within the specified time, taking the semaphore will
|
||||
* fail. In such case, stop the reception and end the transfer
|
||||
* this way. Now taking the semaphore should be successful.
|
||||
*/
|
||||
nrfx_uarte_rx_abort(&uarte);
|
||||
if (k_sem_take(&transfer_finished, K_MSEC(10)) != 0) {
|
||||
printk("UARTE transfer timeout\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void buffer_dump(const uint8_t *buffer, size_t length)
|
||||
{
|
||||
for (int i = 0; i < length; ++i) {
|
||||
printk(" %02X", buffer[i]);
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
static bool background_transfer(const struct device *spi_dev)
|
||||
{
|
||||
static const uint8_t tx_buffer[] = "Nordic Semiconductor";
|
||||
static uint8_t rx_buffer[sizeof(tx_buffer)];
|
||||
static const struct spi_cs_control spi_dev_cs_ctrl = {
|
||||
.gpio_dev = DEVICE_DT_GET(DT_GPIO_CTLR(SPI_DEV_NODE, cs_gpios)),
|
||||
.gpio_pin = DT_GPIO_PIN(SPI_DEV_NODE, cs_gpios),
|
||||
.gpio_dt_flags = DT_GPIO_FLAGS(SPI_DEV_NODE, cs_gpios)
|
||||
};
|
||||
static const struct spi_config spi_dev_cfg = {
|
||||
.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8) |
|
||||
SPI_TRANSFER_MSB,
|
||||
.frequency = 1000000,
|
||||
.cs = &spi_dev_cs_ctrl
|
||||
};
|
||||
static const struct spi_buf tx_buf = {
|
||||
.buf = (void *)tx_buffer,
|
||||
.len = sizeof(tx_buffer)
|
||||
};
|
||||
static const struct spi_buf_set tx = {
|
||||
.buffers = &tx_buf,
|
||||
.count = 1
|
||||
};
|
||||
static const struct spi_buf rx_buf = {
|
||||
.buf = rx_buffer,
|
||||
.len = sizeof(rx_buffer),
|
||||
};
|
||||
static const struct spi_buf_set rx = {
|
||||
.buffers = &rx_buf,
|
||||
.count = 1
|
||||
};
|
||||
int ret;
|
||||
|
||||
printk("-- Background transfer on \"%s\" --\n", spi_dev->name);
|
||||
|
||||
ret = spi_transceive(spi_dev, &spi_dev_cfg, &tx, &rx);
|
||||
if (ret < 0) {
|
||||
printk("Background transfer failed: %d\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
printk("Tx:");
|
||||
buffer_dump(tx_buf.buf, tx_buf.len);
|
||||
printk("Rx:");
|
||||
buffer_dump(rx_buf.buf, rx_buf.len);
|
||||
return true;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
printk("nrfx PRS example on %s\n", CONFIG_BOARD);
|
||||
|
||||
static uint8_t tx_buffer[TRANSFER_LENGTH];
|
||||
static uint8_t rx_buffer[sizeof(tx_buffer)];
|
||||
uint8_t fill_value = 0;
|
||||
const struct device *spi_dev = DEVICE_DT_GET(SPI_DEV_NODE);
|
||||
|
||||
if (!device_is_ready(spi_dev)) {
|
||||
printk("%s is not ready\n", spi_dev->name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Install a shared interrupt handler for peripherals used via
|
||||
* nrfx drivers. It will dispatch the interrupt handling to the
|
||||
* driver for the currently initialized peripheral.
|
||||
*/
|
||||
BUILD_ASSERT(
|
||||
DT_IRQ(SPIM_NODE, priority) == DT_IRQ(UARTE_NODE, priority),
|
||||
"Interrupt priorities for " DT_LABEL(SPIM_NODE) " and "
|
||||
DT_LABEL(UARTE_NODE) " need to be equal.");
|
||||
IRQ_CONNECT(DT_IRQN(SPIM_NODE), DT_IRQ(SPIM_NODE, priority),
|
||||
nrfx_isr, nrfx_prs_box_2_irq_handler, 0);
|
||||
|
||||
if (!init_buttons()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initially use the SPIM. */
|
||||
if (!switch_to_spim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
/* Wait 5 seconds for the user to press a button. If no button
|
||||
* is pressed within this time, perform the background transfer.
|
||||
* Otherwise, realize the operation requested by the user.
|
||||
*/
|
||||
if (k_sem_take(&button_pressed, K_MSEC(5000)) != 0) {
|
||||
if (!background_transfer(spi_dev)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
bool res;
|
||||
|
||||
switch (user_request) {
|
||||
case PERFORM_TRANSFER:
|
||||
printk("-- %s transfer --\n",
|
||||
spim_initialized ? "SPIM" : "UARTE");
|
||||
received = 0;
|
||||
for (int i = 0; i < sizeof(tx_buffer); ++i) {
|
||||
tx_buffer[i] = fill_value++;
|
||||
}
|
||||
res = (spim_initialized
|
||||
? spim_transfer(tx_buffer,
|
||||
sizeof(tx_buffer),
|
||||
rx_buffer,
|
||||
sizeof(rx_buffer))
|
||||
: uarte_transfer(tx_buffer,
|
||||
sizeof(tx_buffer),
|
||||
rx_buffer,
|
||||
sizeof(rx_buffer)));
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Tx:");
|
||||
buffer_dump(tx_buffer, sizeof(tx_buffer));
|
||||
printk("Rx:");
|
||||
buffer_dump(rx_buffer, received);
|
||||
break;
|
||||
|
||||
case SWITCH_PERIPHERAL:
|
||||
res = (spim_initialized
|
||||
? switch_to_uarte()
|
||||
: switch_to_spim());
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue