mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Tue Nov 08 17:45:16 2016 +0000
Revision:
150:02e0a0aed4ec
Parent:
149:156823d33999
Child:
160:d5399cc887bb
This updates the lib to the mbed lib v129

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /*
<> 144:ef7eb2e8f9f7 2 * Copyright (c) 2013 Nordic Semiconductor ASA
<> 144:ef7eb2e8f9f7 3 * All rights reserved.
<> 144:ef7eb2e8f9f7 4 *
<> 144:ef7eb2e8f9f7 5 * Redistribution and use in source and binary forms, with or without modification,
<> 144:ef7eb2e8f9f7 6 * are permitted provided that the following conditions are met:
<> 144:ef7eb2e8f9f7 7 *
<> 144:ef7eb2e8f9f7 8 * 1. Redistributions of source code must retain the above copyright notice, this list
<> 144:ef7eb2e8f9f7 9 * of conditions and the following disclaimer.
<> 144:ef7eb2e8f9f7 10 *
<> 144:ef7eb2e8f9f7 11 * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
<> 144:ef7eb2e8f9f7 12 * integrated circuit in a product or a software update for such product, must reproduce
<> 144:ef7eb2e8f9f7 13 * the above copyright notice, this list of conditions and the following disclaimer in
<> 144:ef7eb2e8f9f7 14 * the documentation and/or other materials provided with the distribution.
<> 144:ef7eb2e8f9f7 15 *
<> 144:ef7eb2e8f9f7 16 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
<> 144:ef7eb2e8f9f7 17 * used to endorse or promote products derived from this software without specific prior
<> 144:ef7eb2e8f9f7 18 * written permission.
<> 144:ef7eb2e8f9f7 19 *
<> 144:ef7eb2e8f9f7 20 * 4. This software, with or without modification, must only be used with a
<> 144:ef7eb2e8f9f7 21 * Nordic Semiconductor ASA integrated circuit.
<> 144:ef7eb2e8f9f7 22 *
<> 144:ef7eb2e8f9f7 23 * 5. Any software provided in binary or object form under this license must not be reverse
<> 144:ef7eb2e8f9f7 24 * engineered, decompiled, modified and/or disassembled.
<> 144:ef7eb2e8f9f7 25 *
<> 144:ef7eb2e8f9f7 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<> 144:ef7eb2e8f9f7 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
<> 144:ef7eb2e8f9f7 28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 144:ef7eb2e8f9f7 29 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
<> 144:ef7eb2e8f9f7 30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
<> 144:ef7eb2e8f9f7 31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
<> 144:ef7eb2e8f9f7 32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
<> 144:ef7eb2e8f9f7 33 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
<> 144:ef7eb2e8f9f7 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
<> 144:ef7eb2e8f9f7 35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 144:ef7eb2e8f9f7 36 *
<> 144:ef7eb2e8f9f7 37 */
<> 144:ef7eb2e8f9f7 38
<> 144:ef7eb2e8f9f7 39
<> 144:ef7eb2e8f9f7 40 #include "spi_api.h"
<> 144:ef7eb2e8f9f7 41
<> 144:ef7eb2e8f9f7 42 #if DEVICE_SPI
<> 144:ef7eb2e8f9f7 43
<> 144:ef7eb2e8f9f7 44 #include "cmsis.h"
<> 144:ef7eb2e8f9f7 45 #include "pinmap.h"
<> 144:ef7eb2e8f9f7 46 #include "mbed_assert.h"
<> 144:ef7eb2e8f9f7 47 #include "mbed_error.h"
<> 144:ef7eb2e8f9f7 48 #include "nrf_drv_spi.h"
<> 144:ef7eb2e8f9f7 49 #include "nrf_drv_spis.h"
<> 144:ef7eb2e8f9f7 50 #include "app_util_platform.h"
<> 144:ef7eb2e8f9f7 51
<> 144:ef7eb2e8f9f7 52 #if DEVICE_SPI_ASYNCH
<> 144:ef7eb2e8f9f7 53 #define SPI_IDX(obj) ((obj)->spi.spi_idx)
<> 144:ef7eb2e8f9f7 54 #else
<> 144:ef7eb2e8f9f7 55 #define SPI_IDX(obj) ((obj)->spi_idx)
<> 144:ef7eb2e8f9f7 56 #endif
<> 144:ef7eb2e8f9f7 57 #define SPI_INFO(obj) (&m_spi_info[SPI_IDX(obj)])
<> 144:ef7eb2e8f9f7 58 #define MASTER_INST(obj) (&m_instances[SPI_IDX(obj)].master)
<> 144:ef7eb2e8f9f7 59 #define SLAVE_INST(obj) (&m_instances[SPI_IDX(obj)].slave)
<> 144:ef7eb2e8f9f7 60
<> 144:ef7eb2e8f9f7 61 typedef struct {
<> 144:ef7eb2e8f9f7 62 bool initialized;
<> 144:ef7eb2e8f9f7 63 bool master;
<> 144:ef7eb2e8f9f7 64 uint8_t sck_pin;
<> 144:ef7eb2e8f9f7 65 uint8_t mosi_pin;
<> 144:ef7eb2e8f9f7 66 uint8_t miso_pin;
<> 144:ef7eb2e8f9f7 67 uint8_t ss_pin;
<> 144:ef7eb2e8f9f7 68 uint8_t spi_mode;
<> 144:ef7eb2e8f9f7 69 nrf_drv_spi_frequency_t frequency;
<> 144:ef7eb2e8f9f7 70 volatile union {
<> 144:ef7eb2e8f9f7 71 bool busy; // master
<> 144:ef7eb2e8f9f7 72 bool readable; // slave
<> 144:ef7eb2e8f9f7 73 } flag;
<> 144:ef7eb2e8f9f7 74 volatile uint8_t tx_buf;
<> 144:ef7eb2e8f9f7 75 volatile uint8_t rx_buf;
<> 144:ef7eb2e8f9f7 76
<> 144:ef7eb2e8f9f7 77 #if DEVICE_SPI_ASYNCH
<> 144:ef7eb2e8f9f7 78 uint32_t handler;
<> 144:ef7eb2e8f9f7 79 uint32_t event;
<> 144:ef7eb2e8f9f7 80 #endif
<> 144:ef7eb2e8f9f7 81 } spi_info_t;
<> 144:ef7eb2e8f9f7 82 static spi_info_t m_spi_info[SPI_COUNT];
<> 144:ef7eb2e8f9f7 83
<> 144:ef7eb2e8f9f7 84 typedef struct {
<> 144:ef7eb2e8f9f7 85 nrf_drv_spi_t master;
<> 144:ef7eb2e8f9f7 86 nrf_drv_spis_t slave;
<> 144:ef7eb2e8f9f7 87 } sdk_driver_instances_t;
<> 150:02e0a0aed4ec 88
<> 150:02e0a0aed4ec 89 void SPI0_TWI0_IRQHandler(void);
<> 150:02e0a0aed4ec 90 void SPI1_TWI1_IRQHandler(void);
<> 150:02e0a0aed4ec 91 void SPIM2_SPIS2_SPI2_IRQHandler(void);
<> 150:02e0a0aed4ec 92
<> 150:02e0a0aed4ec 93 static const peripheral_handler_desc_t spi_hanlder_desc[SPI_COUNT] = {
<> 150:02e0a0aed4ec 94 #if SPI0_ENABLED
<> 150:02e0a0aed4ec 95 {
<> 150:02e0a0aed4ec 96 SPIS0_IRQ,
<> 150:02e0a0aed4ec 97 (uint32_t) SPI0_TWI0_IRQHandler
<> 150:02e0a0aed4ec 98 },
<> 150:02e0a0aed4ec 99 #endif
<> 150:02e0a0aed4ec 100 #if SPI1_ENABLED
<> 150:02e0a0aed4ec 101 {
<> 150:02e0a0aed4ec 102 SPIS1_IRQ,
<> 150:02e0a0aed4ec 103 (uint32_t) SPI1_TWI1_IRQHandler
<> 150:02e0a0aed4ec 104 },
<> 150:02e0a0aed4ec 105 #endif
<> 150:02e0a0aed4ec 106 #if SPI2_ENABLED
<> 150:02e0a0aed4ec 107 {
<> 150:02e0a0aed4ec 108 SPIS2_IRQ,
<> 150:02e0a0aed4ec 109 (uint32_t) SPIM2_SPIS2_SPI2_IRQHandler
<> 150:02e0a0aed4ec 110 },
<> 150:02e0a0aed4ec 111 #endif
<> 150:02e0a0aed4ec 112 };
<> 150:02e0a0aed4ec 113
<> 150:02e0a0aed4ec 114
<> 144:ef7eb2e8f9f7 115 static sdk_driver_instances_t m_instances[SPI_COUNT] = {
<> 150:02e0a0aed4ec 116 #if SPI0_ENABLED
<> 144:ef7eb2e8f9f7 117 {
<> 144:ef7eb2e8f9f7 118 NRF_DRV_SPI_INSTANCE(0),
<> 144:ef7eb2e8f9f7 119 NRF_DRV_SPIS_INSTANCE(0)
<> 144:ef7eb2e8f9f7 120 },
<> 150:02e0a0aed4ec 121 #endif
<> 150:02e0a0aed4ec 122 #if SPI1_ENABLED
<> 144:ef7eb2e8f9f7 123 {
<> 144:ef7eb2e8f9f7 124 NRF_DRV_SPI_INSTANCE(1),
<> 144:ef7eb2e8f9f7 125 NRF_DRV_SPIS_INSTANCE(1)
<> 144:ef7eb2e8f9f7 126 },
<> 150:02e0a0aed4ec 127 #endif
<> 150:02e0a0aed4ec 128 #if SPI2_ENABLED
<> 144:ef7eb2e8f9f7 129 {
<> 144:ef7eb2e8f9f7 130 NRF_DRV_SPI_INSTANCE(2),
<> 144:ef7eb2e8f9f7 131 NRF_DRV_SPIS_INSTANCE(2)
<> 144:ef7eb2e8f9f7 132 },
<> 150:02e0a0aed4ec 133 #endif
<> 144:ef7eb2e8f9f7 134 };
<> 144:ef7eb2e8f9f7 135
<> 144:ef7eb2e8f9f7 136 static void master_event_handler(uint8_t spi_idx,
<> 144:ef7eb2e8f9f7 137 nrf_drv_spi_evt_t const *p_event)
<> 144:ef7eb2e8f9f7 138 {
<> 144:ef7eb2e8f9f7 139 spi_info_t *p_spi_info = &m_spi_info[spi_idx];
<> 144:ef7eb2e8f9f7 140
<> 144:ef7eb2e8f9f7 141 if (p_event->type == NRF_DRV_SPI_EVENT_DONE) {
<> 144:ef7eb2e8f9f7 142 p_spi_info->flag.busy = false;
<> 144:ef7eb2e8f9f7 143 if (p_spi_info->handler) {
<> 144:ef7eb2e8f9f7 144 void (*handler)(void) = (void (*)(void))p_spi_info->handler;
<> 144:ef7eb2e8f9f7 145 p_spi_info->handler = 0;
<> 144:ef7eb2e8f9f7 146 handler();
<> 144:ef7eb2e8f9f7 147 }
<> 144:ef7eb2e8f9f7 148 }
<> 144:ef7eb2e8f9f7 149 }
<> 144:ef7eb2e8f9f7 150 #define MASTER_EVENT_HANDLER(idx) \
<> 144:ef7eb2e8f9f7 151 static void master_event_handler_##idx(nrf_drv_spi_evt_t const *p_event) { \
<> 144:ef7eb2e8f9f7 152 master_event_handler(SPI##idx##_INSTANCE_INDEX, p_event); \
<> 144:ef7eb2e8f9f7 153 }
<> 144:ef7eb2e8f9f7 154 #if SPI0_ENABLED
<> 144:ef7eb2e8f9f7 155 MASTER_EVENT_HANDLER(0)
<> 144:ef7eb2e8f9f7 156 #endif
<> 144:ef7eb2e8f9f7 157 #if SPI1_ENABLED
<> 144:ef7eb2e8f9f7 158 MASTER_EVENT_HANDLER(1)
<> 144:ef7eb2e8f9f7 159 #endif
<> 144:ef7eb2e8f9f7 160 #if SPI2_ENABLED
<> 144:ef7eb2e8f9f7 161 MASTER_EVENT_HANDLER(2)
<> 144:ef7eb2e8f9f7 162 #endif
<> 144:ef7eb2e8f9f7 163
<> 144:ef7eb2e8f9f7 164 static nrf_drv_spi_handler_t const m_master_event_handlers[SPI_COUNT] = {
<> 144:ef7eb2e8f9f7 165 #if SPI0_ENABLED
<> 144:ef7eb2e8f9f7 166 master_event_handler_0,
<> 144:ef7eb2e8f9f7 167 #endif
<> 144:ef7eb2e8f9f7 168 #if SPI1_ENABLED
<> 144:ef7eb2e8f9f7 169 master_event_handler_1,
<> 144:ef7eb2e8f9f7 170 #endif
<> 144:ef7eb2e8f9f7 171 #if SPI2_ENABLED
<> 144:ef7eb2e8f9f7 172 master_event_handler_2,
<> 144:ef7eb2e8f9f7 173 #endif
<> 144:ef7eb2e8f9f7 174 };
<> 144:ef7eb2e8f9f7 175
<> 144:ef7eb2e8f9f7 176
<> 144:ef7eb2e8f9f7 177 static void slave_event_handler(uint8_t spi_idx,
<> 144:ef7eb2e8f9f7 178 nrf_drv_spis_event_t event)
<> 144:ef7eb2e8f9f7 179 {
<> 144:ef7eb2e8f9f7 180 spi_info_t *p_spi_info = &m_spi_info[spi_idx];
<> 144:ef7eb2e8f9f7 181
<> 144:ef7eb2e8f9f7 182 if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) {
<> 144:ef7eb2e8f9f7 183 // Signal that there is some data received that could be read.
<> 144:ef7eb2e8f9f7 184 p_spi_info->flag.readable = true;
<> 144:ef7eb2e8f9f7 185
<> 144:ef7eb2e8f9f7 186 // And prepare for the next transfer.
<> 144:ef7eb2e8f9f7 187 // Previous data set in 'spi_slave_write' (if any) has been transmitted,
<> 144:ef7eb2e8f9f7 188 // now use the default one, until some new is set by 'spi_slave_write'.
<> 144:ef7eb2e8f9f7 189 p_spi_info->tx_buf = NRF_DRV_SPIS_DEFAULT_ORC;
<> 144:ef7eb2e8f9f7 190 nrf_drv_spis_buffers_set(&m_instances[spi_idx].slave,
<> 144:ef7eb2e8f9f7 191 (uint8_t const *)&p_spi_info->tx_buf, 1,
<> 144:ef7eb2e8f9f7 192 (uint8_t *)&p_spi_info->rx_buf, 1);
<> 144:ef7eb2e8f9f7 193 }
<> 144:ef7eb2e8f9f7 194 }
<> 144:ef7eb2e8f9f7 195 #define SLAVE_EVENT_HANDLER(idx) \
<> 144:ef7eb2e8f9f7 196 static void slave_event_handler_##idx(nrf_drv_spis_event_t event) { \
<> 144:ef7eb2e8f9f7 197 slave_event_handler(SPIS##idx##_INSTANCE_INDEX, event); \
<> 144:ef7eb2e8f9f7 198 }
<> 144:ef7eb2e8f9f7 199 #if SPIS0_ENABLED
<> 144:ef7eb2e8f9f7 200 SLAVE_EVENT_HANDLER(0)
<> 144:ef7eb2e8f9f7 201 #endif
<> 144:ef7eb2e8f9f7 202 #if SPIS1_ENABLED
<> 144:ef7eb2e8f9f7 203 SLAVE_EVENT_HANDLER(1)
<> 144:ef7eb2e8f9f7 204 #endif
<> 144:ef7eb2e8f9f7 205 #if SPIS2_ENABLED
<> 144:ef7eb2e8f9f7 206 SLAVE_EVENT_HANDLER(2)
<> 144:ef7eb2e8f9f7 207 #endif
<> 144:ef7eb2e8f9f7 208
<> 144:ef7eb2e8f9f7 209 static nrf_drv_spis_event_handler_t const m_slave_event_handlers[SPIS_COUNT] = {
<> 144:ef7eb2e8f9f7 210 #if SPIS0_ENABLED
<> 144:ef7eb2e8f9f7 211 slave_event_handler_0,
<> 144:ef7eb2e8f9f7 212 #endif
<> 144:ef7eb2e8f9f7 213 #if SPIS1_ENABLED
<> 144:ef7eb2e8f9f7 214 slave_event_handler_1,
<> 144:ef7eb2e8f9f7 215 #endif
<> 144:ef7eb2e8f9f7 216 #if SPIS2_ENABLED
<> 144:ef7eb2e8f9f7 217 slave_event_handler_2,
<> 144:ef7eb2e8f9f7 218 #endif
<> 144:ef7eb2e8f9f7 219 };
<> 144:ef7eb2e8f9f7 220
<> 144:ef7eb2e8f9f7 221 static void prepare_master_config(nrf_drv_spi_config_t *p_config,
<> 144:ef7eb2e8f9f7 222 spi_info_t const *p_spi_info)
<> 144:ef7eb2e8f9f7 223 {
<> 144:ef7eb2e8f9f7 224 p_config->sck_pin = p_spi_info->sck_pin;
<> 144:ef7eb2e8f9f7 225 p_config->mosi_pin = p_spi_info->mosi_pin;
<> 144:ef7eb2e8f9f7 226 p_config->miso_pin = p_spi_info->miso_pin;
<> 144:ef7eb2e8f9f7 227 p_config->ss_pin = p_spi_info->ss_pin;
<> 144:ef7eb2e8f9f7 228 p_config->frequency = p_spi_info->frequency;
<> 144:ef7eb2e8f9f7 229 p_config->mode = (nrf_drv_spi_mode_t)p_spi_info->spi_mode;
<> 144:ef7eb2e8f9f7 230
<> 150:02e0a0aed4ec 231 p_config->irq_priority = SPI1_CONFIG_IRQ_PRIORITY;
<> 144:ef7eb2e8f9f7 232 p_config->orc = 0xFF;
<> 144:ef7eb2e8f9f7 233 p_config->bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
<> 144:ef7eb2e8f9f7 234 }
<> 144:ef7eb2e8f9f7 235
<> 144:ef7eb2e8f9f7 236 static void prepare_slave_config(nrf_drv_spis_config_t *p_config,
<> 144:ef7eb2e8f9f7 237 spi_info_t const *p_spi_info)
<> 144:ef7eb2e8f9f7 238 {
<> 144:ef7eb2e8f9f7 239 p_config->sck_pin = p_spi_info->sck_pin;
<> 144:ef7eb2e8f9f7 240 p_config->mosi_pin = p_spi_info->mosi_pin;
<> 144:ef7eb2e8f9f7 241 p_config->miso_pin = p_spi_info->miso_pin;
<> 144:ef7eb2e8f9f7 242 p_config->csn_pin = p_spi_info->ss_pin;
<> 144:ef7eb2e8f9f7 243 p_config->mode = (nrf_drv_spis_mode_t)p_spi_info->spi_mode;
<> 144:ef7eb2e8f9f7 244
<> 150:02e0a0aed4ec 245 p_config->irq_priority = SPIS1_CONFIG_IRQ_PRIORITY;
<> 144:ef7eb2e8f9f7 246 p_config->orc = NRF_DRV_SPIS_DEFAULT_ORC;
<> 144:ef7eb2e8f9f7 247 p_config->def = NRF_DRV_SPIS_DEFAULT_DEF;
<> 144:ef7eb2e8f9f7 248 p_config->bit_order = NRF_DRV_SPIS_BIT_ORDER_MSB_FIRST;
<> 144:ef7eb2e8f9f7 249 p_config->csn_pullup = NRF_DRV_SPIS_DEFAULT_CSN_PULLUP;
<> 144:ef7eb2e8f9f7 250 p_config->miso_drive = NRF_DRV_SPIS_DEFAULT_MISO_DRIVE;
<> 144:ef7eb2e8f9f7 251 }
<> 144:ef7eb2e8f9f7 252
<> 144:ef7eb2e8f9f7 253 void spi_init(spi_t *obj,
<> 144:ef7eb2e8f9f7 254 PinName mosi, PinName miso, PinName sclk, PinName ssel)
<> 144:ef7eb2e8f9f7 255 {
<> 144:ef7eb2e8f9f7 256 int i;
<> 144:ef7eb2e8f9f7 257 for (i = 0; i < SPI_COUNT; ++i) {
<> 144:ef7eb2e8f9f7 258 spi_info_t *p_spi_info = &m_spi_info[i];
<> 144:ef7eb2e8f9f7 259 if (!p_spi_info->initialized) {
<> 150:02e0a0aed4ec 260
<> 150:02e0a0aed4ec 261 NVIC_SetVector(spi_hanlder_desc[i].IRQn, spi_hanlder_desc[i].vector);
<> 150:02e0a0aed4ec 262
<> 144:ef7eb2e8f9f7 263 p_spi_info->sck_pin = (uint8_t)sclk;
<> 144:ef7eb2e8f9f7 264 p_spi_info->mosi_pin = (mosi != NC) ?
<> 144:ef7eb2e8f9f7 265 (uint8_t)mosi : NRF_DRV_SPI_PIN_NOT_USED;
<> 144:ef7eb2e8f9f7 266 p_spi_info->miso_pin = (miso != NC) ?
<> 144:ef7eb2e8f9f7 267 (uint8_t)miso : NRF_DRV_SPI_PIN_NOT_USED;
<> 144:ef7eb2e8f9f7 268 p_spi_info->ss_pin = (ssel != NC) ?
<> 144:ef7eb2e8f9f7 269 (uint8_t)ssel : NRF_DRV_SPI_PIN_NOT_USED;
<> 144:ef7eb2e8f9f7 270 p_spi_info->spi_mode = (uint8_t)NRF_DRV_SPI_MODE_0;
<> 144:ef7eb2e8f9f7 271 p_spi_info->frequency = NRF_DRV_SPI_FREQ_1M;
<> 144:ef7eb2e8f9f7 272
<> 144:ef7eb2e8f9f7 273 // By default each SPI instance is initialized to work as a master.
<> 144:ef7eb2e8f9f7 274 // Should the slave mode be used, the instance will be reconfigured
<> 144:ef7eb2e8f9f7 275 // appropriately in 'spi_format'.
<> 144:ef7eb2e8f9f7 276 nrf_drv_spi_config_t config;
<> 144:ef7eb2e8f9f7 277 prepare_master_config(&config, p_spi_info);
<> 144:ef7eb2e8f9f7 278
<> 144:ef7eb2e8f9f7 279 nrf_drv_spi_t const *p_spi = &m_instances[i].master;
<> 144:ef7eb2e8f9f7 280 ret_code_t ret_code = nrf_drv_spi_init(p_spi,
<> 144:ef7eb2e8f9f7 281 &config, m_master_event_handlers[i]);
<> 144:ef7eb2e8f9f7 282 if (ret_code == NRF_SUCCESS) {
<> 144:ef7eb2e8f9f7 283 p_spi_info->initialized = true;
<> 144:ef7eb2e8f9f7 284 p_spi_info->master = true;
<> 144:ef7eb2e8f9f7 285 p_spi_info->flag.busy = false;
<> 144:ef7eb2e8f9f7 286 #if DEVICE_SPI_ASYNCH
<> 144:ef7eb2e8f9f7 287 p_spi_info->handler = 0;
<> 144:ef7eb2e8f9f7 288 #endif
<> 144:ef7eb2e8f9f7 289 SPI_IDX(obj) = i;
<> 144:ef7eb2e8f9f7 290
<> 144:ef7eb2e8f9f7 291 return;
<> 144:ef7eb2e8f9f7 292 }
<> 144:ef7eb2e8f9f7 293 }
<> 144:ef7eb2e8f9f7 294 }
<> 144:ef7eb2e8f9f7 295
<> 144:ef7eb2e8f9f7 296 // No available peripheral
<> 144:ef7eb2e8f9f7 297 error("No available SPI peripheral\r\n");
<> 144:ef7eb2e8f9f7 298 }
<> 144:ef7eb2e8f9f7 299
<> 144:ef7eb2e8f9f7 300 void spi_free(spi_t *obj)
<> 144:ef7eb2e8f9f7 301 {
<> 144:ef7eb2e8f9f7 302 spi_info_t *p_spi_info = SPI_INFO(obj);
<> 144:ef7eb2e8f9f7 303 if (p_spi_info->master) {
<> 144:ef7eb2e8f9f7 304 nrf_drv_spi_uninit(MASTER_INST(obj));
<> 144:ef7eb2e8f9f7 305 }
<> 144:ef7eb2e8f9f7 306 else {
<> 144:ef7eb2e8f9f7 307 nrf_drv_spis_uninit(SLAVE_INST(obj));
<> 144:ef7eb2e8f9f7 308 }
<> 144:ef7eb2e8f9f7 309 p_spi_info->initialized = false;
<> 144:ef7eb2e8f9f7 310 }
<> 144:ef7eb2e8f9f7 311
<> 144:ef7eb2e8f9f7 312 int spi_busy(spi_t *obj)
<> 144:ef7eb2e8f9f7 313 {
<> 144:ef7eb2e8f9f7 314 return (int)(SPI_INFO(obj)->flag.busy);
<> 144:ef7eb2e8f9f7 315 }
<> 144:ef7eb2e8f9f7 316
<> 144:ef7eb2e8f9f7 317 void spi_format(spi_t *obj, int bits, int mode, int slave)
<> 144:ef7eb2e8f9f7 318 {
<> 144:ef7eb2e8f9f7 319 if (bits != 8) {
<> 144:ef7eb2e8f9f7 320 error("Only 8-bits SPI is supported\r\n");
<> 144:ef7eb2e8f9f7 321 }
<> 144:ef7eb2e8f9f7 322 if (mode > 3) {
<> 144:ef7eb2e8f9f7 323 error("SPI format error\r\n");
<> 144:ef7eb2e8f9f7 324 }
<> 144:ef7eb2e8f9f7 325
<> 144:ef7eb2e8f9f7 326 spi_info_t *p_spi_info = SPI_INFO(obj);
<> 144:ef7eb2e8f9f7 327
<> 144:ef7eb2e8f9f7 328 if (slave)
<> 144:ef7eb2e8f9f7 329 {
<> 144:ef7eb2e8f9f7 330 nrf_drv_spis_mode_t spi_modes[4] = {
<> 144:ef7eb2e8f9f7 331 NRF_DRV_SPIS_MODE_0,
<> 144:ef7eb2e8f9f7 332 NRF_DRV_SPIS_MODE_1,
<> 144:ef7eb2e8f9f7 333 NRF_DRV_SPIS_MODE_2,
<> 144:ef7eb2e8f9f7 334 NRF_DRV_SPIS_MODE_3,
<> 144:ef7eb2e8f9f7 335 };
<> 144:ef7eb2e8f9f7 336 nrf_drv_spis_mode_t new_mode = spi_modes[mode];
<> 144:ef7eb2e8f9f7 337
<> 144:ef7eb2e8f9f7 338 // If the peripheral is currently working as a master, the SDK driver
<> 144:ef7eb2e8f9f7 339 // it uses needs to be switched from SPI to SPIS.
<> 144:ef7eb2e8f9f7 340 if (p_spi_info->master) {
<> 144:ef7eb2e8f9f7 341 nrf_drv_spi_uninit(MASTER_INST(obj));
<> 144:ef7eb2e8f9f7 342 }
<> 144:ef7eb2e8f9f7 343 // I the SPI mode has to be changed, the SDK's SPIS driver needs to be
<> 144:ef7eb2e8f9f7 344 // re-initialized (there is no other way to change its configuration).
<> 144:ef7eb2e8f9f7 345 else if (p_spi_info->spi_mode != (uint8_t)new_mode) {
<> 144:ef7eb2e8f9f7 346 nrf_drv_spis_uninit(SLAVE_INST(obj));
<> 144:ef7eb2e8f9f7 347 }
<> 144:ef7eb2e8f9f7 348 else {
<> 144:ef7eb2e8f9f7 349 return;
<> 144:ef7eb2e8f9f7 350 }
<> 144:ef7eb2e8f9f7 351
<> 144:ef7eb2e8f9f7 352 p_spi_info->spi_mode = (uint8_t)new_mode;
<> 144:ef7eb2e8f9f7 353 p_spi_info->master = false;
<> 144:ef7eb2e8f9f7 354 p_spi_info->flag.readable = false;
<> 144:ef7eb2e8f9f7 355
<> 144:ef7eb2e8f9f7 356 // Initialize SDK's SPIS driver with the new configuration.
<> 144:ef7eb2e8f9f7 357 nrf_drv_spis_config_t config;
<> 144:ef7eb2e8f9f7 358 prepare_slave_config(&config, p_spi_info);
<> 144:ef7eb2e8f9f7 359 (void)nrf_drv_spis_init(SLAVE_INST(obj), &config,
<> 144:ef7eb2e8f9f7 360 m_slave_event_handlers[SPI_IDX(obj)]);
<> 144:ef7eb2e8f9f7 361
<> 144:ef7eb2e8f9f7 362 // Prepare the slave for transfer.
<> 144:ef7eb2e8f9f7 363 p_spi_info->tx_buf = NRF_DRV_SPIS_DEFAULT_ORC;
<> 144:ef7eb2e8f9f7 364 nrf_drv_spis_buffers_set(SLAVE_INST(obj),
<> 144:ef7eb2e8f9f7 365 (uint8_t const *)&p_spi_info->tx_buf, 1,
<> 144:ef7eb2e8f9f7 366 (uint8_t *)&p_spi_info->rx_buf, 1);
<> 144:ef7eb2e8f9f7 367 }
<> 144:ef7eb2e8f9f7 368 else // master
<> 144:ef7eb2e8f9f7 369 {
<> 144:ef7eb2e8f9f7 370 nrf_drv_spi_mode_t spi_modes[4] = {
<> 144:ef7eb2e8f9f7 371 NRF_DRV_SPI_MODE_0,
<> 144:ef7eb2e8f9f7 372 NRF_DRV_SPI_MODE_1,
<> 144:ef7eb2e8f9f7 373 NRF_DRV_SPI_MODE_2,
<> 144:ef7eb2e8f9f7 374 NRF_DRV_SPI_MODE_3,
<> 144:ef7eb2e8f9f7 375 };
<> 144:ef7eb2e8f9f7 376 nrf_drv_spi_mode_t new_mode = spi_modes[mode];
<> 144:ef7eb2e8f9f7 377
<> 144:ef7eb2e8f9f7 378 // If the peripheral is currently working as a slave, the SDK driver
<> 144:ef7eb2e8f9f7 379 // it uses needs to be switched from SPIS to SPI.
<> 144:ef7eb2e8f9f7 380 if (!p_spi_info->master) {
<> 144:ef7eb2e8f9f7 381 nrf_drv_spis_uninit(SLAVE_INST(obj));
<> 144:ef7eb2e8f9f7 382 }
<> 144:ef7eb2e8f9f7 383 // I the SPI mode has to be changed, the SDK's SPI driver needs to be
<> 144:ef7eb2e8f9f7 384 // re-initialized (there is no other way to change its configuration).
<> 144:ef7eb2e8f9f7 385 else if (p_spi_info->spi_mode != (uint8_t)new_mode) {
<> 144:ef7eb2e8f9f7 386 nrf_drv_spi_uninit(MASTER_INST(obj));
<> 144:ef7eb2e8f9f7 387 }
<> 144:ef7eb2e8f9f7 388 else {
<> 144:ef7eb2e8f9f7 389 return;
<> 144:ef7eb2e8f9f7 390 }
<> 144:ef7eb2e8f9f7 391
<> 144:ef7eb2e8f9f7 392 p_spi_info->spi_mode = (uint8_t)new_mode;
<> 144:ef7eb2e8f9f7 393 p_spi_info->master = true;
<> 144:ef7eb2e8f9f7 394 p_spi_info->flag.busy = false;
<> 144:ef7eb2e8f9f7 395
<> 144:ef7eb2e8f9f7 396 // Initialize SDK's SPI driver with the new configuration.
<> 144:ef7eb2e8f9f7 397 nrf_drv_spi_config_t config;
<> 144:ef7eb2e8f9f7 398 prepare_master_config(&config, p_spi_info);
<> 144:ef7eb2e8f9f7 399 (void)nrf_drv_spi_init(MASTER_INST(obj), &config,
<> 144:ef7eb2e8f9f7 400 m_master_event_handlers[SPI_IDX(obj)]);
<> 144:ef7eb2e8f9f7 401 }
<> 144:ef7eb2e8f9f7 402 }
<> 144:ef7eb2e8f9f7 403
<> 144:ef7eb2e8f9f7 404 static nrf_drv_spi_frequency_t freq_translate(int hz)
<> 144:ef7eb2e8f9f7 405 {
<> 144:ef7eb2e8f9f7 406 nrf_drv_spi_frequency_t frequency;
<> 144:ef7eb2e8f9f7 407 if (hz<250000) { //125Kbps
<> 144:ef7eb2e8f9f7 408 frequency = NRF_DRV_SPI_FREQ_125K;
<> 144:ef7eb2e8f9f7 409 } else if (hz<500000) { //250Kbps
<> 144:ef7eb2e8f9f7 410 frequency = NRF_DRV_SPI_FREQ_250K;
<> 144:ef7eb2e8f9f7 411 } else if (hz<1000000) { //500Kbps
<> 144:ef7eb2e8f9f7 412 frequency = NRF_DRV_SPI_FREQ_500K;
<> 144:ef7eb2e8f9f7 413 } else if (hz<2000000) { //1Mbps
<> 144:ef7eb2e8f9f7 414 frequency = NRF_DRV_SPI_FREQ_1M;
<> 144:ef7eb2e8f9f7 415 } else if (hz<4000000) { //2Mbps
<> 144:ef7eb2e8f9f7 416 frequency = NRF_DRV_SPI_FREQ_2M;
<> 144:ef7eb2e8f9f7 417 } else if (hz<8000000) { //4Mbps
<> 144:ef7eb2e8f9f7 418 frequency = NRF_DRV_SPI_FREQ_4M;
<> 144:ef7eb2e8f9f7 419 } else { //8Mbps
<> 144:ef7eb2e8f9f7 420 frequency = NRF_DRV_SPI_FREQ_8M;
<> 144:ef7eb2e8f9f7 421 }
<> 144:ef7eb2e8f9f7 422 return frequency;
<> 144:ef7eb2e8f9f7 423 }
<> 144:ef7eb2e8f9f7 424
<> 144:ef7eb2e8f9f7 425 void spi_frequency(spi_t *obj, int hz)
<> 144:ef7eb2e8f9f7 426 {
<> 144:ef7eb2e8f9f7 427 spi_info_t *p_spi_info = SPI_INFO(obj);
<> 144:ef7eb2e8f9f7 428 nrf_drv_spi_frequency_t new_frequency = freq_translate(hz);
<> 144:ef7eb2e8f9f7 429
<> 144:ef7eb2e8f9f7 430 if (p_spi_info->master)
<> 144:ef7eb2e8f9f7 431 {
<> 144:ef7eb2e8f9f7 432 if (p_spi_info->frequency != new_frequency) {
<> 144:ef7eb2e8f9f7 433 p_spi_info->frequency = new_frequency;
<> 144:ef7eb2e8f9f7 434
<> 144:ef7eb2e8f9f7 435 nrf_drv_spi_config_t config;
<> 144:ef7eb2e8f9f7 436 prepare_master_config(&config, p_spi_info);
<> 144:ef7eb2e8f9f7 437
<> 144:ef7eb2e8f9f7 438 nrf_drv_spi_t const *p_spi = MASTER_INST(obj);
<> 144:ef7eb2e8f9f7 439 nrf_drv_spi_uninit(p_spi);
<> 144:ef7eb2e8f9f7 440 (void)nrf_drv_spi_init(p_spi, &config,
<> 144:ef7eb2e8f9f7 441 m_master_event_handlers[SPI_IDX(obj)]);
<> 144:ef7eb2e8f9f7 442 }
<> 144:ef7eb2e8f9f7 443 }
<> 144:ef7eb2e8f9f7 444 // There is no need to set anything in slaves when it comes to frequency,
<> 144:ef7eb2e8f9f7 445 // since slaves just synchronize with the clock provided by a master.
<> 144:ef7eb2e8f9f7 446 }
<> 144:ef7eb2e8f9f7 447
<> 144:ef7eb2e8f9f7 448 int spi_master_write(spi_t *obj, int value)
<> 144:ef7eb2e8f9f7 449 {
<> 144:ef7eb2e8f9f7 450 spi_info_t *p_spi_info = SPI_INFO(obj);
<> 144:ef7eb2e8f9f7 451
<> 144:ef7eb2e8f9f7 452 #if DEVICE_SPI_ASYNCH
<> 144:ef7eb2e8f9f7 453 while (p_spi_info->flag.busy) {
<> 144:ef7eb2e8f9f7 454 }
<> 144:ef7eb2e8f9f7 455 #endif
<> 144:ef7eb2e8f9f7 456
<> 144:ef7eb2e8f9f7 457 p_spi_info->tx_buf = value;
<> 144:ef7eb2e8f9f7 458 p_spi_info->flag.busy = true;
<> 144:ef7eb2e8f9f7 459 (void)nrf_drv_spi_transfer(MASTER_INST(obj),
<> 144:ef7eb2e8f9f7 460 (uint8_t const *)&p_spi_info->tx_buf, 1,
<> 144:ef7eb2e8f9f7 461 (uint8_t *)&p_spi_info->rx_buf, 1);
<> 144:ef7eb2e8f9f7 462 while (p_spi_info->flag.busy) {
<> 144:ef7eb2e8f9f7 463 }
<> 144:ef7eb2e8f9f7 464
<> 144:ef7eb2e8f9f7 465 return p_spi_info->rx_buf;
<> 144:ef7eb2e8f9f7 466 }
<> 144:ef7eb2e8f9f7 467
<> 144:ef7eb2e8f9f7 468 int spi_slave_receive(spi_t *obj)
<> 144:ef7eb2e8f9f7 469 {
<> 144:ef7eb2e8f9f7 470 spi_info_t *p_spi_info = SPI_INFO(obj);
<> 144:ef7eb2e8f9f7 471 MBED_ASSERT(!p_spi_info->master);
<> 144:ef7eb2e8f9f7 472 return p_spi_info->flag.readable;
<> 144:ef7eb2e8f9f7 473 ;
<> 144:ef7eb2e8f9f7 474 }
<> 144:ef7eb2e8f9f7 475
<> 144:ef7eb2e8f9f7 476 int spi_slave_read(spi_t *obj)
<> 144:ef7eb2e8f9f7 477 {
<> 144:ef7eb2e8f9f7 478 spi_info_t *p_spi_info = SPI_INFO(obj);
<> 144:ef7eb2e8f9f7 479 MBED_ASSERT(!p_spi_info->master);
<> 144:ef7eb2e8f9f7 480 while (!p_spi_info->flag.readable) {
<> 144:ef7eb2e8f9f7 481 }
<> 144:ef7eb2e8f9f7 482 p_spi_info->flag.readable = false;
<> 144:ef7eb2e8f9f7 483 return p_spi_info->rx_buf;
<> 144:ef7eb2e8f9f7 484 }
<> 144:ef7eb2e8f9f7 485
<> 144:ef7eb2e8f9f7 486 void spi_slave_write(spi_t *obj, int value)
<> 144:ef7eb2e8f9f7 487 {
<> 144:ef7eb2e8f9f7 488 spi_info_t *p_spi_info = SPI_INFO(obj);
<> 144:ef7eb2e8f9f7 489 MBED_ASSERT(!p_spi_info->master);
<> 144:ef7eb2e8f9f7 490
<> 144:ef7eb2e8f9f7 491 p_spi_info->tx_buf = (uint8_t)value;
<> 144:ef7eb2e8f9f7 492 }
<> 144:ef7eb2e8f9f7 493
<> 144:ef7eb2e8f9f7 494 #if DEVICE_SPI_ASYNCH
<> 144:ef7eb2e8f9f7 495
<> 144:ef7eb2e8f9f7 496 void spi_master_transfer(spi_t *obj,
<> 144:ef7eb2e8f9f7 497 const void *tx, size_t tx_length,
<> 144:ef7eb2e8f9f7 498 void *rx, size_t rx_length, uint8_t bit_width,
<> 144:ef7eb2e8f9f7 499 uint32_t handler, uint32_t event, DMAUsage hint)
<> 144:ef7eb2e8f9f7 500 {
<> 144:ef7eb2e8f9f7 501 spi_info_t *p_spi_info = SPI_INFO(obj);
<> 144:ef7eb2e8f9f7 502 MBED_ASSERT(p_spi_info->master);
<> 144:ef7eb2e8f9f7 503 (void)hint;
<> 144:ef7eb2e8f9f7 504 (void)bit_width;
<> 144:ef7eb2e8f9f7 505
<> 144:ef7eb2e8f9f7 506 p_spi_info->handler = handler;
<> 144:ef7eb2e8f9f7 507 p_spi_info->event = event;
<> 144:ef7eb2e8f9f7 508
<> 144:ef7eb2e8f9f7 509 p_spi_info->flag.busy = true;
<> 144:ef7eb2e8f9f7 510 (void)nrf_drv_spi_transfer(MASTER_INST(obj),
<> 144:ef7eb2e8f9f7 511 (uint8_t const *)tx, tx_length,
<> 144:ef7eb2e8f9f7 512 (uint8_t *)rx, rx_length);
<> 144:ef7eb2e8f9f7 513 }
<> 144:ef7eb2e8f9f7 514
<> 144:ef7eb2e8f9f7 515 uint32_t spi_irq_handler_asynch(spi_t *obj)
<> 144:ef7eb2e8f9f7 516 {
<> 144:ef7eb2e8f9f7 517 spi_info_t *p_spi_info = SPI_INFO(obj);
<> 144:ef7eb2e8f9f7 518 MBED_ASSERT(p_spi_info->master);
<> 144:ef7eb2e8f9f7 519 return p_spi_info->event & SPI_EVENT_COMPLETE;
<> 144:ef7eb2e8f9f7 520 }
<> 144:ef7eb2e8f9f7 521
<> 144:ef7eb2e8f9f7 522 uint8_t spi_active(spi_t *obj)
<> 144:ef7eb2e8f9f7 523 {
<> 144:ef7eb2e8f9f7 524 spi_info_t *p_spi_info = SPI_INFO(obj);
<> 144:ef7eb2e8f9f7 525 MBED_ASSERT(p_spi_info->master);
<> 144:ef7eb2e8f9f7 526 return p_spi_info->flag.busy;
<> 144:ef7eb2e8f9f7 527 }
<> 144:ef7eb2e8f9f7 528
<> 144:ef7eb2e8f9f7 529 void spi_abort_asynch(spi_t *obj)
<> 144:ef7eb2e8f9f7 530 {
<> 144:ef7eb2e8f9f7 531 MBED_ASSERT(SPI_INFO(obj)->master);
<> 144:ef7eb2e8f9f7 532 nrf_drv_spi_abort(MASTER_INST(obj));
<> 144:ef7eb2e8f9f7 533 }
<> 144:ef7eb2e8f9f7 534
<> 144:ef7eb2e8f9f7 535 #endif // DEVICE_SPI_ASYNCH
<> 144:ef7eb2e8f9f7 536
<> 144:ef7eb2e8f9f7 537 #endif // DEVICE_SPI