1 /*
2 * Copyright (c) 2022 - 2024, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <nrfx_example.h>
35 #include <nrfx_spim.h>
36 #include <nrfx_spis.h>
37
38 #define NRFX_LOG_MODULE EXAMPLE
39 #define NRFX_EXAMPLE_CONFIG_LOG_ENABLED 1
40 #define NRFX_EXAMPLE_CONFIG_LOG_LEVEL 3
41 #include <nrfx_log.h>
42
43 /**
44 * @defgroup nrfx_spim_spis_non_blocking Non-blocking SPIM with SPIS example
45 * @{
46 * @ingroup nrfx_spim_spis_examples
47 *
48 * @brief Example showing the basic functionality of nrfx_spim and nrfx_spis drivers operating in the non-blocking mode.
49 *
50 * @details Application initializes nrfx_spim and nrfx_spis drivers. Then starts operating in the non-blocking mode.
51 * Message @ref MSG_TO_SEND_MASTER from @ref m_tx_buffer_master is transmitted to @ref m_rx_buffer_slave.
52 * Simultaneously message @ref MSG_TO_SEND_SLAVE from @ref m_tx_buffer_slave is transmitted to @ref m_rx_buffer_master.
53 * When the transactions are completed @ref spim_handler() and @ref spis_handler() are executed.
54 * Then received messages are read from @ref m_rx_buffer_master and @ref m_rx_buffer_slave.
55 */
56
57 /** @brief Symbol specifying SPIM instance to be used. */
58 #define SPIM_INST_IDX 1
59
60 /** @brief Symbol specifying SPIS instance to be used. */
61 #define SPIS_INST_IDX 2
62
63 /** @brief Symbol specifying master's pin number for MOSI. */
64 #define MOSI_PIN_MASTER LOOPBACK_PIN_1A
65
66 /** @brief Symbol specifying slave's pin number for MOSI. */
67 #define MOSI_PIN_SLAVE LOOPBACK_PIN_1B
68
69 /** @brief Symbol specifying master's pin number for MISO. */
70 #define MISO_PIN_MASTER LOOPBACK_PIN_2A
71
72 /** @brief Symbol specifying slave's pin number for MISO. */
73 #define MISO_PIN_SLAVE LOOPBACK_PIN_2B
74
75 /** @brief Symbol specifying master's pin number for SCK. */
76 #define SCK_PIN_MASTER LOOPBACK_PIN_3A
77
78 /** @brief Symbol specifying slave's pin number for SCK. */
79 #define SCK_PIN_SLAVE LOOPBACK_PIN_3B
80
81 /** @brief Symbol specifying master's pin number for SS. */
82 #define SS_PIN_MASTER LOOPBACK_PIN_4A
83
84 /** @brief Symbol specifying slave's pin number for CSN. */
85 #define CSN_PIN_SLAVE LOOPBACK_PIN_4B
86
87 /** @brief Symbol specifying message to be sent via SPIM data transfer. */
88 #define MSG_TO_SEND_MASTER "Semiconductor"
89
90 /** @brief Symbol specifying message to be sent via SPIS data transfer. */
91 #define MSG_TO_SEND_SLAVE "Nordic"
92
93 /** @brief Transmit buffer initialized with the specified message ( @ref MSG_TO_SEND_MASTER ). */
94 static uint8_t m_tx_buffer_master[] = MSG_TO_SEND_MASTER;
95
96 /** @brief Transmit buffer initialized with the specified message ( @ref MSG_TO_SEND_SLAVE ). */
97 static uint8_t m_tx_buffer_slave[] = MSG_TO_SEND_SLAVE;
98
99 /** @brief Receive buffer defined with the size to store specified message ( @ref MSG_TO_SEND_SLAVE ). */
100 static uint8_t m_rx_buffer_master[sizeof(MSG_TO_SEND_SLAVE)];
101
102 /** @brief Receive buffer defined with the size to store specified message ( @ref MSG_TO_SEND_MASTER ). */
103 static uint8_t m_rx_buffer_slave[sizeof(MSG_TO_SEND_MASTER)];
104
105 /**
106 * @brief Function for handling SPIM driver events.
107 *
108 * @param[in] p_event Pointer to the SPIM driver event.
109 * @param[in] p_context Pointer to the context passed from the driver.
110 */
spim_handler(nrfx_spim_evt_t const * p_event,void * p_context)111 static void spim_handler(nrfx_spim_evt_t const * p_event, void * p_context)
112 {
113 if (p_event->type == NRFX_SPIM_EVENT_DONE)
114 {
115 char * p_msg = p_context;
116 NRFX_LOG_INFO("SPIM finished. Context passed to the handler: >%s<", p_msg);
117 NRFX_LOG_INFO("SPIM rx buffer: %s", m_rx_buffer_master);
118 }
119 }
120
121 /**
122 * @brief Function for handling SPIS driver events.
123 *
124 * @param[in] p_event Pointer to the SPIS driver event.
125 * @param[in] p_context Pointer to the context passed from the driver.
126 */
spis_handler(nrfx_spis_evt_t const * p_event,void * p_context)127 static void spis_handler(nrfx_spis_evt_t const * p_event, void * p_context)
128 {
129 if (p_event->evt_type == NRFX_SPIS_XFER_DONE)
130 {
131 char * p_msg = p_context;
132 NRFX_LOG_INFO("SPIS finished. Context passed to the handler: >%s<", p_msg);
133 NRFX_LOG_INFO("SPIS rx buffer: %s", m_rx_buffer_slave);
134 }
135 }
136
137 /**
138 * @brief Function for application main entry.
139 *
140 * @return Nothing.
141 */
main(void)142 int main(void)
143 {
144 nrfx_err_t status;
145 (void)status;
146
147 #if defined(__ZEPHYR__)
148 IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_SPIM_INST_GET(SPIM_INST_IDX)), IRQ_PRIO_LOWEST,
149 NRFX_SPIM_INST_HANDLER_GET(SPIM_INST_IDX), 0, 0);
150 IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_SPIS_INST_GET(SPIS_INST_IDX)), IRQ_PRIO_LOWEST,
151 NRFX_SPIS_INST_HANDLER_GET(SPIS_INST_IDX), 0, 0);
152 #endif
153
154 NRFX_EXAMPLE_LOG_INIT();
155
156 NRFX_LOG_INFO("Starting nrfx_spim_spis basic non-blocking example.");
157 NRFX_EXAMPLE_LOG_PROCESS();
158
159 nrfx_spim_t spim_inst = NRFX_SPIM_INSTANCE(SPIM_INST_IDX);
160
161 nrfx_spim_config_t spim_config = NRFX_SPIM_DEFAULT_CONFIG(SCK_PIN_MASTER,
162 MOSI_PIN_MASTER,
163 MISO_PIN_MASTER,
164 SS_PIN_MASTER);
165
166 void * p_context = "Some context";
167 status = nrfx_spim_init(&spim_inst, &spim_config, spim_handler, p_context);
168 NRFX_ASSERT(status == NRFX_SUCCESS);
169
170 nrfx_spis_t spis_inst = NRFX_SPIS_INSTANCE(SPIS_INST_IDX);
171 nrfx_spis_config_t spis_config = NRFX_SPIS_DEFAULT_CONFIG(SCK_PIN_SLAVE,
172 MOSI_PIN_SLAVE,
173 MISO_PIN_SLAVE,
174 CSN_PIN_SLAVE);
175
176 status = nrfx_spis_init(&spis_inst, &spis_config, spis_handler, p_context);
177 NRFX_ASSERT(status == NRFX_SUCCESS);
178
179 status = nrfx_spis_buffers_set(&spis_inst,
180 m_tx_buffer_slave, sizeof(m_tx_buffer_slave),
181 m_rx_buffer_slave, sizeof(m_rx_buffer_slave));
182 NRFX_ASSERT(status == NRFX_SUCCESS);
183
184 nrfx_spim_xfer_desc_t spim_xfer_desc = NRFX_SPIM_XFER_TRX(m_tx_buffer_master,
185 sizeof(m_tx_buffer_master),
186 m_rx_buffer_master,
187 sizeof(m_rx_buffer_master));
188
189 status = nrfx_spim_xfer(&spim_inst, &spim_xfer_desc, 0);
190 NRFX_ASSERT(status == NRFX_SUCCESS);
191
192 while (1)
193 {
194 NRFX_EXAMPLE_LOG_PROCESS();
195 }
196 }
197
198 /** @} */
199