IOTON Technology / mbed-ton

Fork of mbed-dev by mbed official

Committer:
AnnaBridge
Date:
Fri May 26 12:39:01 2017 +0100
Revision:
165:e614a9f1c9e2
Parent:
targets/TARGET_NORDIC/TARGET_NRF5_SDK13/sdk/drivers_nrf/spi_master/nrf_drv_spi.c@162:e13f6fdb2ac4
This updates the lib to the mbed lib v 143

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 162:e13f6fdb2ac4 1 /*
<> 162:e13f6fdb2ac4 2 * Copyright (c) 2015 Nordic Semiconductor ASA
<> 162:e13f6fdb2ac4 3 * All rights reserved.
<> 162:e13f6fdb2ac4 4 *
<> 162:e13f6fdb2ac4 5 * Redistribution and use in source and binary forms, with or without modification,
<> 162:e13f6fdb2ac4 6 * are permitted provided that the following conditions are met:
<> 162:e13f6fdb2ac4 7 *
<> 162:e13f6fdb2ac4 8 * 1. Redistributions of source code must retain the above copyright notice, this list
<> 162:e13f6fdb2ac4 9 * of conditions and the following disclaimer.
<> 162:e13f6fdb2ac4 10 *
<> 162:e13f6fdb2ac4 11 * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
<> 162:e13f6fdb2ac4 12 * integrated circuit in a product or a software update for such product, must reproduce
<> 162:e13f6fdb2ac4 13 * the above copyright notice, this list of conditions and the following disclaimer in
<> 162:e13f6fdb2ac4 14 * the documentation and/or other materials provided with the distribution.
<> 162:e13f6fdb2ac4 15 *
<> 162:e13f6fdb2ac4 16 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
<> 162:e13f6fdb2ac4 17 * used to endorse or promote products derived from this software without specific prior
<> 162:e13f6fdb2ac4 18 * written permission.
<> 162:e13f6fdb2ac4 19 *
<> 162:e13f6fdb2ac4 20 * 4. This software, with or without modification, must only be used with a
<> 162:e13f6fdb2ac4 21 * Nordic Semiconductor ASA integrated circuit.
<> 162:e13f6fdb2ac4 22 *
<> 162:e13f6fdb2ac4 23 * 5. Any software provided in binary or object form under this license must not be reverse
<> 162:e13f6fdb2ac4 24 * engineered, decompiled, modified and/or disassembled.
<> 162:e13f6fdb2ac4 25 *
<> 162:e13f6fdb2ac4 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<> 162:e13f6fdb2ac4 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
<> 162:e13f6fdb2ac4 28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 162:e13f6fdb2ac4 29 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
<> 162:e13f6fdb2ac4 30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
<> 162:e13f6fdb2ac4 31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
<> 162:e13f6fdb2ac4 32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
<> 162:e13f6fdb2ac4 33 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
<> 162:e13f6fdb2ac4 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
<> 162:e13f6fdb2ac4 35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 162:e13f6fdb2ac4 36 *
<> 162:e13f6fdb2ac4 37 */
<> 162:e13f6fdb2ac4 38
<> 162:e13f6fdb2ac4 39 #include "sdk_common.h"
<> 162:e13f6fdb2ac4 40 #if NRF_MODULE_ENABLED(SPI)
<> 162:e13f6fdb2ac4 41 #define ENABLED_SPI_COUNT (SPI0_ENABLED+SPI1_ENABLED+SPI2_ENABLED)
<> 162:e13f6fdb2ac4 42 #if ENABLED_SPI_COUNT
<> 162:e13f6fdb2ac4 43
<> 162:e13f6fdb2ac4 44 #include "nrf_drv_spi.h"
<> 162:e13f6fdb2ac4 45 #include "nrf_drv_common.h"
<> 162:e13f6fdb2ac4 46 #include "nrf_gpio.h"
<> 162:e13f6fdb2ac4 47 #include "nrf_assert.h"
<> 162:e13f6fdb2ac4 48 #include "app_util_platform.h"
<> 162:e13f6fdb2ac4 49
<> 162:e13f6fdb2ac4 50 #define NRF_LOG_MODULE_NAME "SPI"
<> 162:e13f6fdb2ac4 51
<> 162:e13f6fdb2ac4 52 #if SPI_CONFIG_LOG_ENABLED
<> 162:e13f6fdb2ac4 53 #define NRF_LOG_LEVEL SPI_CONFIG_LOG_LEVEL
<> 162:e13f6fdb2ac4 54 #define NRF_LOG_INFO_COLOR SPI_CONFIG_INFO_COLOR
<> 162:e13f6fdb2ac4 55 #define NRF_LOG_DEBUG_COLOR SPI_CONFIG_DEBUG_COLOR
<> 162:e13f6fdb2ac4 56 #else //SPI_CONFIG_LOG_ENABLED
<> 162:e13f6fdb2ac4 57 #define NRF_LOG_LEVEL 0
<> 162:e13f6fdb2ac4 58 #endif //SPI_CONFIG_LOG_ENABLED
<> 162:e13f6fdb2ac4 59 #include "nrf_log.h"
<> 162:e13f6fdb2ac4 60
<> 162:e13f6fdb2ac4 61 #ifndef SPIM_PRESENT
<> 162:e13f6fdb2ac4 62 // Make sure SPIx_USE_EASY_DMA is 0 for nRF51 (if a common
<> 162:e13f6fdb2ac4 63 // "nrf_drv_config.h" file is provided for nRF51 and nRF52).
<> 162:e13f6fdb2ac4 64 #undef SPI0_USE_EASY_DMA
<> 162:e13f6fdb2ac4 65 #define SPI0_USE_EASY_DMA 0
<> 162:e13f6fdb2ac4 66 #undef SPI1_USE_EASY_DMA
<> 162:e13f6fdb2ac4 67 #define SPI1_USE_EASY_DMA 0
<> 162:e13f6fdb2ac4 68 #undef SPI2_USE_EASY_DMA
<> 162:e13f6fdb2ac4 69 #define SPI2_USE_EASY_DMA 0
<> 162:e13f6fdb2ac4 70 #endif
<> 162:e13f6fdb2ac4 71
<> 162:e13f6fdb2ac4 72 #ifndef SPI0_USE_EASY_DMA
<> 162:e13f6fdb2ac4 73 #define SPI0_USE_EASY_DMA 0
<> 162:e13f6fdb2ac4 74 #endif
<> 162:e13f6fdb2ac4 75
<> 162:e13f6fdb2ac4 76 #ifndef SPI1_USE_EASY_DMA
<> 162:e13f6fdb2ac4 77 #define SPI1_USE_EASY_DMA 0
<> 162:e13f6fdb2ac4 78 #endif
<> 162:e13f6fdb2ac4 79
<> 162:e13f6fdb2ac4 80 #ifndef SPI2_USE_EASY_DMA
<> 162:e13f6fdb2ac4 81 #define SPI2_USE_EASY_DMA 0
<> 162:e13f6fdb2ac4 82 #endif
<> 162:e13f6fdb2ac4 83
<> 162:e13f6fdb2ac4 84 // This set of macros makes it possible to exclude parts of code when one type
<> 162:e13f6fdb2ac4 85 // of supported peripherals is not used.
<> 162:e13f6fdb2ac4 86 #if ((NRF_MODULE_ENABLED(SPI0) && SPI0_USE_EASY_DMA) || \
<> 162:e13f6fdb2ac4 87 (NRF_MODULE_ENABLED(SPI1) && SPI1_USE_EASY_DMA) || \
<> 162:e13f6fdb2ac4 88 (NRF_MODULE_ENABLED(SPI2) && SPI2_USE_EASY_DMA))
<> 162:e13f6fdb2ac4 89 #define SPIM_IN_USE
<> 162:e13f6fdb2ac4 90 #endif
<> 162:e13f6fdb2ac4 91 #if ((NRF_MODULE_ENABLED(SPI0) && !SPI0_USE_EASY_DMA) || \
<> 162:e13f6fdb2ac4 92 (NRF_MODULE_ENABLED(SPI1) && !SPI1_USE_EASY_DMA) || \
<> 162:e13f6fdb2ac4 93 (NRF_MODULE_ENABLED(SPI2) && !SPI2_USE_EASY_DMA))
<> 162:e13f6fdb2ac4 94 #define SPI_IN_USE
<> 162:e13f6fdb2ac4 95 #endif
<> 162:e13f6fdb2ac4 96 #if defined(SPIM_IN_USE) && defined(SPI_IN_USE)
<> 162:e13f6fdb2ac4 97 // SPIM and SPI combined
<> 162:e13f6fdb2ac4 98 #define CODE_FOR_SPIM(code) if (p_instance->use_easy_dma) { code }
<> 162:e13f6fdb2ac4 99 #define CODE_FOR_SPI(code) else { code }
<> 162:e13f6fdb2ac4 100 #elif defined(SPIM_IN_USE) && !defined(SPI_IN_USE)
<> 162:e13f6fdb2ac4 101 // SPIM only
<> 162:e13f6fdb2ac4 102 #define CODE_FOR_SPIM(code) { code }
<> 162:e13f6fdb2ac4 103 #define CODE_FOR_SPI(code)
<> 162:e13f6fdb2ac4 104 #elif !defined(SPIM_IN_USE) && defined(SPI_IN_USE)
<> 162:e13f6fdb2ac4 105 // SPI only
<> 162:e13f6fdb2ac4 106 #define CODE_FOR_SPIM(code)
<> 162:e13f6fdb2ac4 107 #define CODE_FOR_SPI(code) { code }
<> 162:e13f6fdb2ac4 108 #else
<> 162:e13f6fdb2ac4 109 #error "Wrong configuration."
<> 162:e13f6fdb2ac4 110 #endif
<> 162:e13f6fdb2ac4 111
<> 162:e13f6fdb2ac4 112 #ifdef SPIM_IN_USE
<> 162:e13f6fdb2ac4 113 #define END_INT_MASK NRF_SPIM_INT_END_MASK
<> 162:e13f6fdb2ac4 114 #endif
<> 162:e13f6fdb2ac4 115
<> 162:e13f6fdb2ac4 116 // Control block - driver instance local data.
<> 162:e13f6fdb2ac4 117 typedef struct
<> 162:e13f6fdb2ac4 118 {
<> 162:e13f6fdb2ac4 119 nrf_drv_spi_handler_t handler;
<> 162:e13f6fdb2ac4 120 nrf_drv_spi_evt_t evt; // Keep the struct that is ready for event handler. Less memcpy.
<> 162:e13f6fdb2ac4 121 nrf_drv_state_t state;
<> 162:e13f6fdb2ac4 122 volatile bool transfer_in_progress;
<> 162:e13f6fdb2ac4 123
<> 162:e13f6fdb2ac4 124 // [no need for 'volatile' attribute for the following members, as they
<> 162:e13f6fdb2ac4 125 // are not concurrently used in IRQ handlers and main line code]
<> 162:e13f6fdb2ac4 126 uint8_t ss_pin;
<> 162:e13f6fdb2ac4 127 uint8_t orc;
<> 162:e13f6fdb2ac4 128 uint8_t bytes_transferred;
<> 162:e13f6fdb2ac4 129
<> 162:e13f6fdb2ac4 130 bool tx_done : 1;
<> 162:e13f6fdb2ac4 131 bool rx_done : 1;
<> 162:e13f6fdb2ac4 132 bool abort : 1;
<> 162:e13f6fdb2ac4 133 } spi_control_block_t;
<> 162:e13f6fdb2ac4 134 static spi_control_block_t m_cb[ENABLED_SPI_COUNT];
<> 162:e13f6fdb2ac4 135
<> 162:e13f6fdb2ac4 136 #if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
<> 162:e13f6fdb2ac4 137 #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n
<> 162:e13f6fdb2ac4 138 #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void)
<> 162:e13f6fdb2ac4 139
<> 162:e13f6fdb2ac4 140 #if NRF_MODULE_ENABLED(SPI0)
<> 162:e13f6fdb2ac4 141 IRQ_HANDLER(0);
<> 162:e13f6fdb2ac4 142 #endif
<> 162:e13f6fdb2ac4 143 #if NRF_MODULE_ENABLED(SPI1)
<> 162:e13f6fdb2ac4 144 IRQ_HANDLER(1);
<> 162:e13f6fdb2ac4 145 #endif
<> 162:e13f6fdb2ac4 146 #if NRF_MODULE_ENABLED(SPI2)
<> 162:e13f6fdb2ac4 147 IRQ_HANDLER(2);
<> 162:e13f6fdb2ac4 148 #endif
<> 162:e13f6fdb2ac4 149 static nrf_drv_irq_handler_t const m_irq_handlers[ENABLED_SPI_COUNT] = {
<> 162:e13f6fdb2ac4 150 #if NRF_MODULE_ENABLED(SPI0)
<> 162:e13f6fdb2ac4 151 IRQ_HANDLER_NAME(0),
<> 162:e13f6fdb2ac4 152 #endif
<> 162:e13f6fdb2ac4 153 #if NRF_MODULE_ENABLED(SPI1)
<> 162:e13f6fdb2ac4 154 IRQ_HANDLER_NAME(1),
<> 162:e13f6fdb2ac4 155 #endif
<> 162:e13f6fdb2ac4 156 #if NRF_MODULE_ENABLED(SPI2)
<> 162:e13f6fdb2ac4 157 IRQ_HANDLER_NAME(2),
<> 162:e13f6fdb2ac4 158 #endif
<> 162:e13f6fdb2ac4 159 };
<> 162:e13f6fdb2ac4 160 #else
<> 162:e13f6fdb2ac4 161 #define IRQ_HANDLER(n) void SPI##n##_IRQ_HANDLER(void)
<> 162:e13f6fdb2ac4 162 #endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
<> 162:e13f6fdb2ac4 163
<> 162:e13f6fdb2ac4 164
<> 162:e13f6fdb2ac4 165 ret_code_t nrf_drv_spi_init(nrf_drv_spi_t const * const p_instance,
<> 162:e13f6fdb2ac4 166 nrf_drv_spi_config_t const * p_config,
<> 162:e13f6fdb2ac4 167 nrf_drv_spi_handler_t handler)
<> 162:e13f6fdb2ac4 168 {
<> 162:e13f6fdb2ac4 169 ASSERT(p_config);
<> 162:e13f6fdb2ac4 170 spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
<> 162:e13f6fdb2ac4 171 ret_code_t err_code;
<> 162:e13f6fdb2ac4 172
<> 162:e13f6fdb2ac4 173 if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED)
<> 162:e13f6fdb2ac4 174 {
<> 162:e13f6fdb2ac4 175 err_code = NRF_ERROR_INVALID_STATE;
<> 162:e13f6fdb2ac4 176 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
<> 162:e13f6fdb2ac4 177 return err_code;
<> 162:e13f6fdb2ac4 178 }
<> 162:e13f6fdb2ac4 179
<> 162:e13f6fdb2ac4 180 #if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
<> 162:e13f6fdb2ac4 181 if (nrf_drv_common_per_res_acquire(p_instance->p_registers,
<> 162:e13f6fdb2ac4 182 m_irq_handlers[p_instance->drv_inst_idx]) != NRF_SUCCESS)
<> 162:e13f6fdb2ac4 183 {
<> 162:e13f6fdb2ac4 184 err_code = NRF_ERROR_BUSY;
<> 162:e13f6fdb2ac4 185 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
<> 162:e13f6fdb2ac4 186 return err_code;
<> 162:e13f6fdb2ac4 187 }
<> 162:e13f6fdb2ac4 188 #endif
<> 162:e13f6fdb2ac4 189
<> 162:e13f6fdb2ac4 190 p_cb->handler = handler;
<> 162:e13f6fdb2ac4 191
<> 162:e13f6fdb2ac4 192 uint32_t mosi_pin;
<> 162:e13f6fdb2ac4 193 uint32_t miso_pin;
<> 162:e13f6fdb2ac4 194 // Configure pins used by the peripheral:
<> 162:e13f6fdb2ac4 195 // - SCK - output with initial value corresponding with the SPI mode used:
<> 162:e13f6fdb2ac4 196 // 0 - for modes 0 and 1 (CPOL = 0), 1 - for modes 2 and 3 (CPOL = 1);
<> 162:e13f6fdb2ac4 197 // according to the reference manual guidelines this pin and its input
<> 162:e13f6fdb2ac4 198 // buffer must always be connected for the SPI to work.
<> 162:e13f6fdb2ac4 199 if (p_config->mode <= NRF_DRV_SPI_MODE_1)
<> 162:e13f6fdb2ac4 200 {
<> 162:e13f6fdb2ac4 201 nrf_gpio_pin_clear(p_config->sck_pin);
<> 162:e13f6fdb2ac4 202 }
<> 162:e13f6fdb2ac4 203 else
<> 162:e13f6fdb2ac4 204 {
<> 162:e13f6fdb2ac4 205 nrf_gpio_pin_set(p_config->sck_pin);
<> 162:e13f6fdb2ac4 206 }
<> 162:e13f6fdb2ac4 207 NRF_GPIO->PIN_CNF[p_config->sck_pin] =
<> 162:e13f6fdb2ac4 208 (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos)
<> 162:e13f6fdb2ac4 209 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
<> 162:e13f6fdb2ac4 210 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
<> 162:e13f6fdb2ac4 211 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
<> 162:e13f6fdb2ac4 212 | (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
<> 162:e13f6fdb2ac4 213 // - MOSI (optional) - output with initial value 0,
<> 162:e13f6fdb2ac4 214 if (p_config->mosi_pin != NRF_DRV_SPI_PIN_NOT_USED)
<> 162:e13f6fdb2ac4 215 {
<> 162:e13f6fdb2ac4 216 mosi_pin = p_config->mosi_pin;
<> 162:e13f6fdb2ac4 217 nrf_gpio_pin_clear(mosi_pin);
<> 162:e13f6fdb2ac4 218 nrf_gpio_cfg_output(mosi_pin);
<> 162:e13f6fdb2ac4 219 }
<> 162:e13f6fdb2ac4 220 else
<> 162:e13f6fdb2ac4 221 {
<> 162:e13f6fdb2ac4 222 mosi_pin = NRF_SPI_PIN_NOT_CONNECTED;
<> 162:e13f6fdb2ac4 223 }
<> 162:e13f6fdb2ac4 224 // - MISO (optional) - input,
<> 162:e13f6fdb2ac4 225 if (p_config->miso_pin != NRF_DRV_SPI_PIN_NOT_USED)
<> 162:e13f6fdb2ac4 226 {
<> 162:e13f6fdb2ac4 227 miso_pin = p_config->miso_pin;
<> 162:e13f6fdb2ac4 228 nrf_gpio_cfg_input(miso_pin, NRF_GPIO_PIN_NOPULL);
<> 162:e13f6fdb2ac4 229 }
<> 162:e13f6fdb2ac4 230 else
<> 162:e13f6fdb2ac4 231 {
<> 162:e13f6fdb2ac4 232 miso_pin = NRF_SPI_PIN_NOT_CONNECTED;
<> 162:e13f6fdb2ac4 233 }
<> 162:e13f6fdb2ac4 234 // - Slave Select (optional) - output with initial value 1 (inactive).
<> 162:e13f6fdb2ac4 235 if (p_config->ss_pin != NRF_DRV_SPI_PIN_NOT_USED)
<> 162:e13f6fdb2ac4 236 {
<> 162:e13f6fdb2ac4 237 nrf_gpio_pin_set(p_config->ss_pin);
<> 162:e13f6fdb2ac4 238 nrf_gpio_cfg_output(p_config->ss_pin);
<> 162:e13f6fdb2ac4 239 }
<> 162:e13f6fdb2ac4 240 m_cb[p_instance->drv_inst_idx].ss_pin = p_config->ss_pin;
<> 162:e13f6fdb2ac4 241
<> 162:e13f6fdb2ac4 242 CODE_FOR_SPIM
<> 162:e13f6fdb2ac4 243 (
<> 162:e13f6fdb2ac4 244 NRF_SPIM_Type * p_spim = p_instance->p_registers;
<> 162:e13f6fdb2ac4 245 nrf_spim_pins_set(p_spim, p_config->sck_pin, mosi_pin, miso_pin);
<> 162:e13f6fdb2ac4 246 nrf_spim_frequency_set(p_spim,
<> 162:e13f6fdb2ac4 247 (nrf_spim_frequency_t)p_config->frequency);
<> 162:e13f6fdb2ac4 248 nrf_spim_configure(p_spim,
<> 162:e13f6fdb2ac4 249 (nrf_spim_mode_t)p_config->mode,
<> 162:e13f6fdb2ac4 250 (nrf_spim_bit_order_t)p_config->bit_order);
<> 162:e13f6fdb2ac4 251
<> 162:e13f6fdb2ac4 252 nrf_spim_orc_set(p_spim, p_config->orc);
<> 162:e13f6fdb2ac4 253
<> 162:e13f6fdb2ac4 254 if (p_cb->handler)
<> 162:e13f6fdb2ac4 255 {
<> 162:e13f6fdb2ac4 256 nrf_spim_int_enable(p_spim, END_INT_MASK);
<> 162:e13f6fdb2ac4 257 }
<> 162:e13f6fdb2ac4 258
<> 162:e13f6fdb2ac4 259 nrf_spim_enable(p_spim);
<> 162:e13f6fdb2ac4 260 )
<> 162:e13f6fdb2ac4 261 CODE_FOR_SPI
<> 162:e13f6fdb2ac4 262 (
<> 162:e13f6fdb2ac4 263 NRF_SPI_Type * p_spi = p_instance->p_registers;
<> 162:e13f6fdb2ac4 264 nrf_spi_pins_set(p_spi, p_config->sck_pin, mosi_pin, miso_pin);
<> 162:e13f6fdb2ac4 265 nrf_spi_frequency_set(p_spi,
<> 162:e13f6fdb2ac4 266 (nrf_spi_frequency_t)p_config->frequency);
<> 162:e13f6fdb2ac4 267 nrf_spi_configure(p_spi,
<> 162:e13f6fdb2ac4 268 (nrf_spi_mode_t)p_config->mode,
<> 162:e13f6fdb2ac4 269 (nrf_spi_bit_order_t)p_config->bit_order);
<> 162:e13f6fdb2ac4 270
<> 162:e13f6fdb2ac4 271 m_cb[p_instance->drv_inst_idx].orc = p_config->orc;
<> 162:e13f6fdb2ac4 272
<> 162:e13f6fdb2ac4 273 if (p_cb->handler)
<> 162:e13f6fdb2ac4 274 {
<> 162:e13f6fdb2ac4 275 nrf_spi_int_enable(p_spi, NRF_SPI_INT_READY_MASK);
<> 162:e13f6fdb2ac4 276 }
<> 162:e13f6fdb2ac4 277
<> 162:e13f6fdb2ac4 278 nrf_spi_enable(p_spi);
<> 162:e13f6fdb2ac4 279 )
<> 162:e13f6fdb2ac4 280
<> 162:e13f6fdb2ac4 281 if (p_cb->handler)
<> 162:e13f6fdb2ac4 282 {
<> 162:e13f6fdb2ac4 283 nrf_drv_common_irq_enable(p_instance->irq, p_config->irq_priority);
<> 162:e13f6fdb2ac4 284 }
<> 162:e13f6fdb2ac4 285
<> 162:e13f6fdb2ac4 286 p_cb->transfer_in_progress = false;
<> 162:e13f6fdb2ac4 287 p_cb->state = NRF_DRV_STATE_INITIALIZED;
<> 162:e13f6fdb2ac4 288
<> 162:e13f6fdb2ac4 289 NRF_LOG_INFO("Init\r\n");
<> 162:e13f6fdb2ac4 290
<> 162:e13f6fdb2ac4 291 err_code = NRF_SUCCESS;
<> 162:e13f6fdb2ac4 292 NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
<> 162:e13f6fdb2ac4 293 return err_code;
<> 162:e13f6fdb2ac4 294 }
<> 162:e13f6fdb2ac4 295
<> 162:e13f6fdb2ac4 296 void nrf_drv_spi_uninit(nrf_drv_spi_t const * const p_instance)
<> 162:e13f6fdb2ac4 297 {
<> 162:e13f6fdb2ac4 298 spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
<> 162:e13f6fdb2ac4 299 ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED);
<> 162:e13f6fdb2ac4 300
<> 162:e13f6fdb2ac4 301 if (p_cb->handler)
<> 162:e13f6fdb2ac4 302 {
<> 162:e13f6fdb2ac4 303 nrf_drv_common_irq_disable(p_instance->irq);
<> 162:e13f6fdb2ac4 304 }
<> 162:e13f6fdb2ac4 305
<> 162:e13f6fdb2ac4 306 #define DISABLE_ALL 0xFFFFFFFF
<> 162:e13f6fdb2ac4 307
<> 162:e13f6fdb2ac4 308 CODE_FOR_SPIM
<> 162:e13f6fdb2ac4 309 (
<> 162:e13f6fdb2ac4 310 NRF_SPIM_Type * p_spim = p_instance->p_registers;
<> 162:e13f6fdb2ac4 311 if (p_cb->handler)
<> 162:e13f6fdb2ac4 312 {
<> 162:e13f6fdb2ac4 313 nrf_spim_int_disable(p_spim, DISABLE_ALL);
<> 162:e13f6fdb2ac4 314 if (p_cb->transfer_in_progress)
<> 162:e13f6fdb2ac4 315 {
<> 162:e13f6fdb2ac4 316 // Ensure that SPI is not performing any transfer.
<> 162:e13f6fdb2ac4 317 nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_STOP);
<> 162:e13f6fdb2ac4 318 while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_STOPPED)) {}
<> 162:e13f6fdb2ac4 319 p_cb->transfer_in_progress = false;
<> 162:e13f6fdb2ac4 320 }
<> 162:e13f6fdb2ac4 321 }
<> 162:e13f6fdb2ac4 322 nrf_spim_disable(p_spim);
<> 162:e13f6fdb2ac4 323 )
<> 162:e13f6fdb2ac4 324 CODE_FOR_SPI
<> 162:e13f6fdb2ac4 325 (
<> 162:e13f6fdb2ac4 326 NRF_SPI_Type * p_spi = p_instance->p_registers;
<> 162:e13f6fdb2ac4 327 if (p_cb->handler)
<> 162:e13f6fdb2ac4 328 {
<> 162:e13f6fdb2ac4 329 nrf_spi_int_disable(p_spi, DISABLE_ALL);
<> 162:e13f6fdb2ac4 330 }
<> 162:e13f6fdb2ac4 331 nrf_spi_disable(p_spi);
<> 162:e13f6fdb2ac4 332 )
<> 162:e13f6fdb2ac4 333 #undef DISABLE_ALL
<> 162:e13f6fdb2ac4 334
<> 162:e13f6fdb2ac4 335 #if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
<> 162:e13f6fdb2ac4 336 nrf_drv_common_per_res_release(p_instance->p_registers);
<> 162:e13f6fdb2ac4 337 #endif
<> 162:e13f6fdb2ac4 338
<> 162:e13f6fdb2ac4 339 p_cb->state = NRF_DRV_STATE_UNINITIALIZED;
<> 162:e13f6fdb2ac4 340 }
<> 162:e13f6fdb2ac4 341
<> 162:e13f6fdb2ac4 342 ret_code_t nrf_drv_spi_transfer(nrf_drv_spi_t const * const p_instance,
<> 162:e13f6fdb2ac4 343 uint8_t const * p_tx_buffer,
<> 162:e13f6fdb2ac4 344 uint8_t tx_buffer_length,
<> 162:e13f6fdb2ac4 345 uint8_t * p_rx_buffer,
<> 162:e13f6fdb2ac4 346 uint8_t rx_buffer_length)
<> 162:e13f6fdb2ac4 347 {
<> 162:e13f6fdb2ac4 348 nrf_drv_spi_xfer_desc_t xfer_desc;
<> 162:e13f6fdb2ac4 349 xfer_desc.p_tx_buffer = p_tx_buffer;
<> 162:e13f6fdb2ac4 350 xfer_desc.p_rx_buffer = p_rx_buffer;
<> 162:e13f6fdb2ac4 351 xfer_desc.tx_length = tx_buffer_length;
<> 162:e13f6fdb2ac4 352 xfer_desc.rx_length = rx_buffer_length;
<> 162:e13f6fdb2ac4 353
<> 162:e13f6fdb2ac4 354 NRF_LOG_INFO("Transfer tx_len:%d, rx_len:%d.\r\n", tx_buffer_length, rx_buffer_length);
<> 162:e13f6fdb2ac4 355 NRF_LOG_DEBUG("Tx data:\r\n");
<> 162:e13f6fdb2ac4 356 NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_tx_buffer, tx_buffer_length * sizeof(p_tx_buffer));
<> 162:e13f6fdb2ac4 357 return nrf_drv_spi_xfer(p_instance, &xfer_desc, 0);
<> 162:e13f6fdb2ac4 358 }
<> 162:e13f6fdb2ac4 359
<> 162:e13f6fdb2ac4 360 static void finish_transfer(spi_control_block_t * p_cb)
<> 162:e13f6fdb2ac4 361 {
<> 162:e13f6fdb2ac4 362 // If Slave Select signal is used, this is the time to deactivate it.
<> 162:e13f6fdb2ac4 363 if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED)
<> 162:e13f6fdb2ac4 364 {
<> 162:e13f6fdb2ac4 365 nrf_gpio_pin_set(p_cb->ss_pin);
<> 162:e13f6fdb2ac4 366 }
<> 162:e13f6fdb2ac4 367
<> 162:e13f6fdb2ac4 368 // By clearing this flag before calling the handler we allow subsequent
<> 162:e13f6fdb2ac4 369 // transfers to be started directly from the handler function.
<> 162:e13f6fdb2ac4 370 p_cb->transfer_in_progress = false;
<> 162:e13f6fdb2ac4 371 p_cb->evt.type = NRF_DRV_SPI_EVENT_DONE;
<> 162:e13f6fdb2ac4 372 NRF_LOG_INFO("Transfer rx_len:%d.\r\n", p_cb->evt.data.done.rx_length);
<> 162:e13f6fdb2ac4 373 NRF_LOG_DEBUG("Rx data:\r\n");
<> 162:e13f6fdb2ac4 374 NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_cb->evt.data.done.p_rx_buffer,
<> 162:e13f6fdb2ac4 375 p_cb->evt.data.done.rx_length * sizeof(p_cb->evt.data.done.p_rx_buffer));
<> 162:e13f6fdb2ac4 376 p_cb->handler(&p_cb->evt);
<> 162:e13f6fdb2ac4 377 }
<> 162:e13f6fdb2ac4 378
<> 162:e13f6fdb2ac4 379 #ifdef SPI_IN_USE
<> 162:e13f6fdb2ac4 380 // This function is called from IRQ handler or, in blocking mode, directly
<> 162:e13f6fdb2ac4 381 // from the 'nrf_drv_spi_transfer' function.
<> 162:e13f6fdb2ac4 382 // It returns true as long as the transfer should be continued, otherwise (when
<> 162:e13f6fdb2ac4 383 // there is nothing more to send/receive) it returns false.
<> 162:e13f6fdb2ac4 384 static bool transfer_byte(NRF_SPI_Type * p_spi, spi_control_block_t * p_cb)
<> 162:e13f6fdb2ac4 385 {
<> 162:e13f6fdb2ac4 386 // Read the data byte received in this transfer and store it in RX buffer,
<> 162:e13f6fdb2ac4 387 // if needed.
<> 162:e13f6fdb2ac4 388 volatile uint8_t rx_data = nrf_spi_rxd_get(p_spi);
<> 162:e13f6fdb2ac4 389 if (p_cb->bytes_transferred < p_cb->evt.data.done.rx_length)
<> 162:e13f6fdb2ac4 390 {
<> 162:e13f6fdb2ac4 391 p_cb->evt.data.done.p_rx_buffer[p_cb->bytes_transferred] = rx_data;
<> 162:e13f6fdb2ac4 392 }
<> 162:e13f6fdb2ac4 393
<> 162:e13f6fdb2ac4 394 ++p_cb->bytes_transferred;
<> 162:e13f6fdb2ac4 395
<> 162:e13f6fdb2ac4 396 // Check if there are more bytes to send or receive and write proper data
<> 162:e13f6fdb2ac4 397 // byte (next one from TX buffer or over-run character) to the TXD register
<> 162:e13f6fdb2ac4 398 // when needed.
<> 162:e13f6fdb2ac4 399 // NOTE - we've already used 'p_cb->bytes_transferred + 1' bytes from our
<> 162:e13f6fdb2ac4 400 // buffers, because we take advantage of double buffering of TXD
<> 162:e13f6fdb2ac4 401 // register (so in effect one byte is still being transmitted now);
<> 162:e13f6fdb2ac4 402 // see how the transfer is started in the 'nrf_drv_spi_transfer'
<> 162:e13f6fdb2ac4 403 // function.
<> 162:e13f6fdb2ac4 404 uint16_t bytes_used = p_cb->bytes_transferred + 1;
<> 162:e13f6fdb2ac4 405
<> 162:e13f6fdb2ac4 406 if (p_cb->abort)
<> 162:e13f6fdb2ac4 407 {
<> 162:e13f6fdb2ac4 408 if (bytes_used < p_cb->evt.data.done.tx_length)
<> 162:e13f6fdb2ac4 409 {
<> 162:e13f6fdb2ac4 410 p_cb->evt.data.done.tx_length = bytes_used;
<> 162:e13f6fdb2ac4 411 }
<> 162:e13f6fdb2ac4 412 if (bytes_used < p_cb->evt.data.done.rx_length)
<> 162:e13f6fdb2ac4 413 {
<> 162:e13f6fdb2ac4 414 p_cb->evt.data.done.rx_length = bytes_used;
<> 162:e13f6fdb2ac4 415 }
<> 162:e13f6fdb2ac4 416 }
<> 162:e13f6fdb2ac4 417
<> 162:e13f6fdb2ac4 418 if (bytes_used < p_cb->evt.data.done.tx_length)
<> 162:e13f6fdb2ac4 419 {
<> 162:e13f6fdb2ac4 420 nrf_spi_txd_set(p_spi, p_cb->evt.data.done.p_tx_buffer[bytes_used]);
<> 162:e13f6fdb2ac4 421 return true;
<> 162:e13f6fdb2ac4 422 }
<> 162:e13f6fdb2ac4 423 else if (bytes_used < p_cb->evt.data.done.rx_length)
<> 162:e13f6fdb2ac4 424 {
<> 162:e13f6fdb2ac4 425 nrf_spi_txd_set(p_spi, p_cb->orc);
<> 162:e13f6fdb2ac4 426 return true;
<> 162:e13f6fdb2ac4 427 }
<> 162:e13f6fdb2ac4 428
<> 162:e13f6fdb2ac4 429 return (p_cb->bytes_transferred < p_cb->evt.data.done.tx_length ||
<> 162:e13f6fdb2ac4 430 p_cb->bytes_transferred < p_cb->evt.data.done.rx_length);
<> 162:e13f6fdb2ac4 431 }
<> 162:e13f6fdb2ac4 432
<> 162:e13f6fdb2ac4 433 static void spi_xfer(NRF_SPI_Type * p_spi,
<> 162:e13f6fdb2ac4 434 spi_control_block_t * p_cb,
<> 162:e13f6fdb2ac4 435 nrf_drv_spi_xfer_desc_t const * p_xfer_desc)
<> 162:e13f6fdb2ac4 436 {
<> 162:e13f6fdb2ac4 437 p_cb->bytes_transferred = 0;
<> 162:e13f6fdb2ac4 438 nrf_spi_int_disable(p_spi, NRF_SPI_INT_READY_MASK);
<> 162:e13f6fdb2ac4 439
<> 162:e13f6fdb2ac4 440 nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY);
<> 162:e13f6fdb2ac4 441
<> 162:e13f6fdb2ac4 442 // Start the transfer by writing some byte to the TXD register;
<> 162:e13f6fdb2ac4 443 // if TX buffer is not empty, take the first byte from this buffer,
<> 162:e13f6fdb2ac4 444 // otherwise - use over-run character.
<> 162:e13f6fdb2ac4 445 nrf_spi_txd_set(p_spi,
<> 162:e13f6fdb2ac4 446 (p_xfer_desc->tx_length > 0 ? p_xfer_desc->p_tx_buffer[0] : p_cb->orc));
<> 162:e13f6fdb2ac4 447
<> 162:e13f6fdb2ac4 448 // TXD register is double buffered, so next byte to be transmitted can
<> 162:e13f6fdb2ac4 449 // be written immediately, if needed, i.e. if TX or RX transfer is to
<> 162:e13f6fdb2ac4 450 // be more that 1 byte long. Again - if there is something more in TX
<> 162:e13f6fdb2ac4 451 // buffer send it, otherwise use over-run character.
<> 162:e13f6fdb2ac4 452 if (p_xfer_desc->tx_length > 1)
<> 162:e13f6fdb2ac4 453 {
<> 162:e13f6fdb2ac4 454 nrf_spi_txd_set(p_spi, p_xfer_desc->p_tx_buffer[1]);
<> 162:e13f6fdb2ac4 455 }
<> 162:e13f6fdb2ac4 456 else if (p_xfer_desc->rx_length > 1)
<> 162:e13f6fdb2ac4 457 {
<> 162:e13f6fdb2ac4 458 nrf_spi_txd_set(p_spi, p_cb->orc);
<> 162:e13f6fdb2ac4 459 }
<> 162:e13f6fdb2ac4 460
<> 162:e13f6fdb2ac4 461 // For blocking mode (user handler not provided) wait here for READY
<> 162:e13f6fdb2ac4 462 // events (indicating that the byte from TXD register was transmitted
<> 162:e13f6fdb2ac4 463 // and a new incoming byte was moved to the RXD register) and continue
<> 162:e13f6fdb2ac4 464 // transaction until all requested bytes are transferred.
<> 162:e13f6fdb2ac4 465 // In non-blocking mode - IRQ service routine will do this stuff.
<> 162:e13f6fdb2ac4 466 if (p_cb->handler)
<> 162:e13f6fdb2ac4 467 {
<> 162:e13f6fdb2ac4 468 nrf_spi_int_enable(p_spi, NRF_SPI_INT_READY_MASK);
<> 162:e13f6fdb2ac4 469 }
<> 162:e13f6fdb2ac4 470 else
<> 162:e13f6fdb2ac4 471 {
<> 162:e13f6fdb2ac4 472 do {
<> 162:e13f6fdb2ac4 473 while (!nrf_spi_event_check(p_spi, NRF_SPI_EVENT_READY)) {}
<> 162:e13f6fdb2ac4 474 nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY);
<> 162:e13f6fdb2ac4 475 NRF_LOG_DEBUG("SPI: Event: NRF_SPI_EVENT_READY.\r\n");
<> 162:e13f6fdb2ac4 476 } while (transfer_byte(p_spi, p_cb));
<> 162:e13f6fdb2ac4 477 if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED)
<> 162:e13f6fdb2ac4 478 {
<> 162:e13f6fdb2ac4 479 nrf_gpio_pin_set(p_cb->ss_pin);
<> 162:e13f6fdb2ac4 480 }
<> 162:e13f6fdb2ac4 481 }
<> 162:e13f6fdb2ac4 482 }
<> 162:e13f6fdb2ac4 483 #endif // SPI_IN_USE
<> 162:e13f6fdb2ac4 484
<> 162:e13f6fdb2ac4 485 #ifdef SPIM_IN_USE
<> 162:e13f6fdb2ac4 486 __STATIC_INLINE void spim_int_enable(NRF_SPIM_Type * p_spim, bool enable)
<> 162:e13f6fdb2ac4 487 {
<> 162:e13f6fdb2ac4 488 if (!enable)
<> 162:e13f6fdb2ac4 489 {
<> 162:e13f6fdb2ac4 490 nrf_spim_int_disable(p_spim, END_INT_MASK);
<> 162:e13f6fdb2ac4 491 }
<> 162:e13f6fdb2ac4 492 else
<> 162:e13f6fdb2ac4 493 {
<> 162:e13f6fdb2ac4 494 nrf_spim_int_enable(p_spim, END_INT_MASK);
<> 162:e13f6fdb2ac4 495 }
<> 162:e13f6fdb2ac4 496 }
<> 162:e13f6fdb2ac4 497
<> 162:e13f6fdb2ac4 498 __STATIC_INLINE void spim_list_enable_handle(NRF_SPIM_Type * p_spim, uint32_t flags)
<> 162:e13f6fdb2ac4 499 {
<> 162:e13f6fdb2ac4 500 if (NRF_DRV_SPI_FLAG_TX_POSTINC & flags)
<> 162:e13f6fdb2ac4 501 {
<> 162:e13f6fdb2ac4 502 nrf_spim_tx_list_enable(p_spim);
<> 162:e13f6fdb2ac4 503 }
<> 162:e13f6fdb2ac4 504 else
<> 162:e13f6fdb2ac4 505 {
<> 162:e13f6fdb2ac4 506 nrf_spim_tx_list_disable(p_spim);
<> 162:e13f6fdb2ac4 507 }
<> 162:e13f6fdb2ac4 508
<> 162:e13f6fdb2ac4 509 if (NRF_DRV_SPI_FLAG_RX_POSTINC & flags)
<> 162:e13f6fdb2ac4 510 {
<> 162:e13f6fdb2ac4 511 nrf_spim_rx_list_enable(p_spim);
<> 162:e13f6fdb2ac4 512 }
<> 162:e13f6fdb2ac4 513 else
<> 162:e13f6fdb2ac4 514 {
<> 162:e13f6fdb2ac4 515 nrf_spim_rx_list_disable(p_spim);
<> 162:e13f6fdb2ac4 516 }
<> 162:e13f6fdb2ac4 517 }
<> 162:e13f6fdb2ac4 518
<> 162:e13f6fdb2ac4 519 static ret_code_t spim_xfer(NRF_SPIM_Type * p_spim,
<> 162:e13f6fdb2ac4 520 spi_control_block_t * p_cb,
<> 162:e13f6fdb2ac4 521 nrf_drv_spi_xfer_desc_t const * p_xfer_desc,
<> 162:e13f6fdb2ac4 522 uint32_t flags)
<> 162:e13f6fdb2ac4 523 {
<> 162:e13f6fdb2ac4 524 ret_code_t err_code;
<> 162:e13f6fdb2ac4 525 // EasyDMA requires that transfer buffers are placed in Data RAM region;
<> 162:e13f6fdb2ac4 526 // signal error if they are not.
<> 162:e13f6fdb2ac4 527 if ((p_xfer_desc->p_tx_buffer != NULL && !nrf_drv_is_in_RAM(p_xfer_desc->p_tx_buffer)) ||
<> 162:e13f6fdb2ac4 528 (p_xfer_desc->p_rx_buffer != NULL && !nrf_drv_is_in_RAM(p_xfer_desc->p_rx_buffer)))
<> 162:e13f6fdb2ac4 529 {
<> 162:e13f6fdb2ac4 530 p_cb->transfer_in_progress = false;
<> 162:e13f6fdb2ac4 531 err_code = NRF_ERROR_INVALID_ADDR;
<> 162:e13f6fdb2ac4 532 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
<> 162:e13f6fdb2ac4 533 return err_code;
<> 162:e13f6fdb2ac4 534 }
<> 162:e13f6fdb2ac4 535
<> 162:e13f6fdb2ac4 536 nrf_spim_tx_buffer_set(p_spim, p_xfer_desc->p_tx_buffer, p_xfer_desc->tx_length);
<> 162:e13f6fdb2ac4 537 nrf_spim_rx_buffer_set(p_spim, p_xfer_desc->p_rx_buffer, p_xfer_desc->rx_length);
<> 162:e13f6fdb2ac4 538
<> 162:e13f6fdb2ac4 539 nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END);
<> 162:e13f6fdb2ac4 540
<> 162:e13f6fdb2ac4 541 spim_list_enable_handle(p_spim, flags);
<> 162:e13f6fdb2ac4 542
<> 162:e13f6fdb2ac4 543 if (!(flags & NRF_DRV_SPI_FLAG_HOLD_XFER))
<> 162:e13f6fdb2ac4 544 {
<> 162:e13f6fdb2ac4 545 nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_START);
<> 162:e13f6fdb2ac4 546 }
<> 162:e13f6fdb2ac4 547
<> 162:e13f6fdb2ac4 548 if (!p_cb->handler)
<> 162:e13f6fdb2ac4 549 {
<> 162:e13f6fdb2ac4 550 while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END)){}
<> 162:e13f6fdb2ac4 551 if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED)
<> 162:e13f6fdb2ac4 552 {
<> 162:e13f6fdb2ac4 553 nrf_gpio_pin_set(p_cb->ss_pin);
<> 162:e13f6fdb2ac4 554 }
<> 162:e13f6fdb2ac4 555 }
<> 162:e13f6fdb2ac4 556 else
<> 162:e13f6fdb2ac4 557 {
<> 162:e13f6fdb2ac4 558 spim_int_enable(p_spim, !(flags & NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER));
<> 162:e13f6fdb2ac4 559 }
<> 162:e13f6fdb2ac4 560 err_code = NRF_SUCCESS;
<> 162:e13f6fdb2ac4 561 NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
<> 162:e13f6fdb2ac4 562 return err_code;
<> 162:e13f6fdb2ac4 563 }
<> 162:e13f6fdb2ac4 564 #endif
<> 162:e13f6fdb2ac4 565
<> 162:e13f6fdb2ac4 566 ret_code_t nrf_drv_spi_xfer(nrf_drv_spi_t const * const p_instance,
<> 162:e13f6fdb2ac4 567 nrf_drv_spi_xfer_desc_t const * p_xfer_desc,
<> 162:e13f6fdb2ac4 568 uint32_t flags)
<> 162:e13f6fdb2ac4 569 {
<> 162:e13f6fdb2ac4 570 spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
<> 162:e13f6fdb2ac4 571 ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED);
<> 162:e13f6fdb2ac4 572 ASSERT(p_xfer_desc->p_tx_buffer != NULL || p_xfer_desc->tx_length == 0);
<> 162:e13f6fdb2ac4 573 ASSERT(p_xfer_desc->p_rx_buffer != NULL || p_xfer_desc->rx_length == 0);
<> 162:e13f6fdb2ac4 574
<> 162:e13f6fdb2ac4 575 ret_code_t err_code = NRF_SUCCESS;
<> 162:e13f6fdb2ac4 576
<> 162:e13f6fdb2ac4 577 if (p_cb->transfer_in_progress)
<> 162:e13f6fdb2ac4 578 {
<> 162:e13f6fdb2ac4 579 err_code = NRF_ERROR_BUSY;
<> 162:e13f6fdb2ac4 580 NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
<> 162:e13f6fdb2ac4 581 return err_code;
<> 162:e13f6fdb2ac4 582 }
<> 162:e13f6fdb2ac4 583 else
<> 162:e13f6fdb2ac4 584 {
<> 162:e13f6fdb2ac4 585 if (p_cb->handler && !(flags & (NRF_DRV_SPI_FLAG_REPEATED_XFER | NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER)))
<> 162:e13f6fdb2ac4 586 {
<> 162:e13f6fdb2ac4 587 p_cb->transfer_in_progress = true;
<> 162:e13f6fdb2ac4 588 }
<> 162:e13f6fdb2ac4 589 }
<> 162:e13f6fdb2ac4 590
<> 162:e13f6fdb2ac4 591 p_cb->evt.data.done = *p_xfer_desc;
<> 162:e13f6fdb2ac4 592 p_cb->tx_done = false;
<> 162:e13f6fdb2ac4 593 p_cb->rx_done = false;
<> 162:e13f6fdb2ac4 594 p_cb->abort = false;
<> 162:e13f6fdb2ac4 595
<> 162:e13f6fdb2ac4 596 if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED)
<> 162:e13f6fdb2ac4 597 {
<> 162:e13f6fdb2ac4 598 nrf_gpio_pin_clear(p_cb->ss_pin);
<> 162:e13f6fdb2ac4 599 }
<> 162:e13f6fdb2ac4 600 CODE_FOR_SPIM
<> 162:e13f6fdb2ac4 601 (
<> 162:e13f6fdb2ac4 602 return spim_xfer(p_instance->p_registers, p_cb, p_xfer_desc, flags);
<> 162:e13f6fdb2ac4 603 )
<> 162:e13f6fdb2ac4 604 CODE_FOR_SPI
<> 162:e13f6fdb2ac4 605 (
<> 162:e13f6fdb2ac4 606 if (flags)
<> 162:e13f6fdb2ac4 607 {
<> 162:e13f6fdb2ac4 608 p_cb->transfer_in_progress = false;
<> 162:e13f6fdb2ac4 609 err_code = NRF_ERROR_NOT_SUPPORTED;
<> 162:e13f6fdb2ac4 610 }
<> 162:e13f6fdb2ac4 611 else
<> 162:e13f6fdb2ac4 612 {
<> 162:e13f6fdb2ac4 613 spi_xfer(p_instance->p_registers, p_cb, p_xfer_desc);
<> 162:e13f6fdb2ac4 614 }
<> 162:e13f6fdb2ac4 615 NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
<> 162:e13f6fdb2ac4 616 return err_code;
<> 162:e13f6fdb2ac4 617 )
<> 162:e13f6fdb2ac4 618 }
<> 162:e13f6fdb2ac4 619
<> 162:e13f6fdb2ac4 620 // modification for mbed-os
<> 162:e13f6fdb2ac4 621 #if __MBED__
<> 162:e13f6fdb2ac4 622 void nrf_drv_spi_abort(nrf_drv_spi_t const * p_instance)
<> 162:e13f6fdb2ac4 623 {
<> 162:e13f6fdb2ac4 624 spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
<> 162:e13f6fdb2ac4 625 ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED);
<> 162:e13f6fdb2ac4 626
<> 162:e13f6fdb2ac4 627 CODE_FOR_SPIM
<> 162:e13f6fdb2ac4 628 (
<> 162:e13f6fdb2ac4 629 nrf_spim_task_trigger(p_instance->p_registers, NRF_SPIM_TASK_STOP);
<> 162:e13f6fdb2ac4 630 while (!nrf_spim_event_check(p_instance->p_registers, NRF_SPIM_EVENT_STOPPED)) {}
<> 162:e13f6fdb2ac4 631 p_cb->transfer_in_progress = false;
<> 162:e13f6fdb2ac4 632 )
<> 162:e13f6fdb2ac4 633 CODE_FOR_SPI
<> 162:e13f6fdb2ac4 634 (
<> 162:e13f6fdb2ac4 635 p_cb->abort = true;
<> 162:e13f6fdb2ac4 636 )
<> 162:e13f6fdb2ac4 637 }
<> 162:e13f6fdb2ac4 638 #endif
<> 162:e13f6fdb2ac4 639
<> 162:e13f6fdb2ac4 640 #ifdef SPIM_IN_USE
<> 162:e13f6fdb2ac4 641 static void irq_handler_spim(NRF_SPIM_Type * p_spim, spi_control_block_t * p_cb)
<> 162:e13f6fdb2ac4 642 {
<> 162:e13f6fdb2ac4 643 ASSERT(p_cb->handler);
<> 162:e13f6fdb2ac4 644
<> 162:e13f6fdb2ac4 645 if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END))
<> 162:e13f6fdb2ac4 646 {
<> 162:e13f6fdb2ac4 647 nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END);
<> 162:e13f6fdb2ac4 648 NRF_LOG_DEBUG("SPIM: Event: NRF_SPIM_EVENT_END.\r\n");
<> 162:e13f6fdb2ac4 649 finish_transfer(p_cb);
<> 162:e13f6fdb2ac4 650 }
<> 162:e13f6fdb2ac4 651 }
<> 162:e13f6fdb2ac4 652
<> 162:e13f6fdb2ac4 653 uint32_t nrf_drv_spi_start_task_get(nrf_drv_spi_t const * p_instance)
<> 162:e13f6fdb2ac4 654 {
<> 162:e13f6fdb2ac4 655 NRF_SPIM_Type * p_spim = (NRF_SPIM_Type *)p_instance->p_registers;
<> 162:e13f6fdb2ac4 656 return nrf_spim_task_address_get(p_spim, NRF_SPIM_TASK_START);
<> 162:e13f6fdb2ac4 657 }
<> 162:e13f6fdb2ac4 658
<> 162:e13f6fdb2ac4 659 uint32_t nrf_drv_spi_end_event_get(nrf_drv_spi_t const * p_instance)
<> 162:e13f6fdb2ac4 660 {
<> 162:e13f6fdb2ac4 661 NRF_SPIM_Type * p_spim = (NRF_SPIM_Type *)p_instance->p_registers;
<> 162:e13f6fdb2ac4 662 return nrf_spim_event_address_get(p_spim, NRF_SPIM_EVENT_END);
<> 162:e13f6fdb2ac4 663 }
<> 162:e13f6fdb2ac4 664 #endif // SPIM_IN_USE
<> 162:e13f6fdb2ac4 665
<> 162:e13f6fdb2ac4 666 #ifdef SPI_IN_USE
<> 162:e13f6fdb2ac4 667 static void irq_handler_spi(NRF_SPI_Type * p_spi, spi_control_block_t * p_cb)
<> 162:e13f6fdb2ac4 668 {
<> 162:e13f6fdb2ac4 669 ASSERT(p_cb->handler);
<> 162:e13f6fdb2ac4 670
<> 162:e13f6fdb2ac4 671 nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY);
<> 162:e13f6fdb2ac4 672 NRF_LOG_DEBUG("SPI: Event: NRF_SPI_EVENT_READY.\r\n");
<> 162:e13f6fdb2ac4 673
<> 162:e13f6fdb2ac4 674 if (!transfer_byte(p_spi, p_cb))
<> 162:e13f6fdb2ac4 675 {
<> 162:e13f6fdb2ac4 676 finish_transfer(p_cb);
<> 162:e13f6fdb2ac4 677 }
<> 162:e13f6fdb2ac4 678 }
<> 162:e13f6fdb2ac4 679 #endif // SPI_IN_USE
<> 162:e13f6fdb2ac4 680
<> 162:e13f6fdb2ac4 681 #if NRF_MODULE_ENABLED(SPI0)
<> 162:e13f6fdb2ac4 682 IRQ_HANDLER(0)
<> 162:e13f6fdb2ac4 683 {
<> 162:e13f6fdb2ac4 684 spi_control_block_t * p_cb = &m_cb[SPI0_INSTANCE_INDEX];
<> 162:e13f6fdb2ac4 685 #if SPI0_USE_EASY_DMA
<> 162:e13f6fdb2ac4 686 irq_handler_spim(NRF_SPIM0, p_cb);
<> 162:e13f6fdb2ac4 687 #else
<> 162:e13f6fdb2ac4 688 irq_handler_spi(NRF_SPI0, p_cb);
<> 162:e13f6fdb2ac4 689 #endif
<> 162:e13f6fdb2ac4 690 }
<> 162:e13f6fdb2ac4 691 #endif // NRF_MODULE_ENABLED(SPI0)
<> 162:e13f6fdb2ac4 692
<> 162:e13f6fdb2ac4 693 #if NRF_MODULE_ENABLED(SPI1)
<> 162:e13f6fdb2ac4 694 IRQ_HANDLER(1)
<> 162:e13f6fdb2ac4 695 {
<> 162:e13f6fdb2ac4 696 spi_control_block_t * p_cb = &m_cb[SPI1_INSTANCE_INDEX];
<> 162:e13f6fdb2ac4 697 #if SPI1_USE_EASY_DMA
<> 162:e13f6fdb2ac4 698 irq_handler_spim(NRF_SPIM1, p_cb);
<> 162:e13f6fdb2ac4 699 #else
<> 162:e13f6fdb2ac4 700 irq_handler_spi(NRF_SPI1, p_cb);
<> 162:e13f6fdb2ac4 701 #endif
<> 162:e13f6fdb2ac4 702 }
<> 162:e13f6fdb2ac4 703 #endif // NRF_MODULE_ENABLED(SPI1)
<> 162:e13f6fdb2ac4 704
<> 162:e13f6fdb2ac4 705 #if NRF_MODULE_ENABLED(SPI2)
<> 162:e13f6fdb2ac4 706 IRQ_HANDLER(2)
<> 162:e13f6fdb2ac4 707 {
<> 162:e13f6fdb2ac4 708 spi_control_block_t * p_cb = &m_cb[SPI2_INSTANCE_INDEX];
<> 162:e13f6fdb2ac4 709 #if SPI2_USE_EASY_DMA
<> 162:e13f6fdb2ac4 710 irq_handler_spim(NRF_SPIM2, p_cb);
<> 162:e13f6fdb2ac4 711 #else
<> 162:e13f6fdb2ac4 712 irq_handler_spi(NRF_SPI2, p_cb);
<> 162:e13f6fdb2ac4 713 #endif
<> 162:e13f6fdb2ac4 714 }
<> 162:e13f6fdb2ac4 715 #endif // NRF_MODULE_ENABLED(SPI2)
<> 162:e13f6fdb2ac4 716 #endif // ENABLED_SPI_COUNT
<> 162:e13f6fdb2ac4 717 #endif // NRF_MODULE_ENABLED(SPI)