mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
Anna Bridge
Date:
Tue Mar 20 17:01:51 2018 +0000
Revision:
183:5166a824ec1a
Parent:
170:19eb464bc2be
Fix mbed lib version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 107:414e9c822e99 1 /* mbed Microcontroller Library
mbed_official 107:414e9c822e99 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 107:414e9c822e99 3 *
mbed_official 107:414e9c822e99 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 107:414e9c822e99 5 * you may not use this file except in compliance with the License.
mbed_official 107:414e9c822e99 6 * You may obtain a copy of the License at
mbed_official 107:414e9c822e99 7 *
mbed_official 107:414e9c822e99 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 107:414e9c822e99 9 *
mbed_official 107:414e9c822e99 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 107:414e9c822e99 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 107:414e9c822e99 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 107:414e9c822e99 13 * See the License for the specific language governing permissions and
mbed_official 107:414e9c822e99 14 * limitations under the License.
mbed_official 107:414e9c822e99 15 */
mbed_official 107:414e9c822e99 16
mbed_official 107:414e9c822e99 17 #include "device.h"
mbed_official 107:414e9c822e99 18 #include "dma_api.h"
mbed_official 107:414e9c822e99 19 #include "buffer.h"
mbed_official 107:414e9c822e99 20 #include "spi_api.h"
mbed_official 107:414e9c822e99 21 #include "pinmap.h"
mbed_official 107:414e9c822e99 22 #include "spi_driver.h"
mbed_official 107:414e9c822e99 23 #include "PeripheralPins.h"
mbed_official 107:414e9c822e99 24 #include "pdc.h"
mbed_official 107:414e9c822e99 25
mbed_official 107:414e9c822e99 26
mbed_official 107:414e9c822e99 27 /* Chip select. */
mbed_official 107:414e9c822e99 28 #define SPI_CHIP_SEL 0
mbed_official 107:414e9c822e99 29
mbed_official 107:414e9c822e99 30 /* Clock polarity. */
mbed_official 107:414e9c822e99 31 #define SPI_CLK_POLARITY 0
mbed_official 107:414e9c822e99 32
mbed_official 107:414e9c822e99 33 /* Clock phase. */
mbed_official 107:414e9c822e99 34 #define SPI_CLK_PHASE 0
mbed_official 107:414e9c822e99 35
mbed_official 107:414e9c822e99 36 /* Last data */
mbed_official 107:414e9c822e99 37 #define SPI_LAST 0
mbed_official 107:414e9c822e99 38
mbed_official 107:414e9c822e99 39
mbed_official 107:414e9c822e99 40 /* Delay before SPCK. */
mbed_official 107:414e9c822e99 41 #define SPI_DLYBS 0x40
mbed_official 107:414e9c822e99 42
mbed_official 107:414e9c822e99 43 /* Delay between consecutive transfers. */
mbed_official 107:414e9c822e99 44 #define SPI_DLYBCT 0x10
mbed_official 107:414e9c822e99 45
mbed_official 107:414e9c822e99 46 #define MAX_SPI 8
mbed_official 107:414e9c822e99 47
mbed_official 107:414e9c822e99 48 /* SPI clock setting (Hz). */
mbed_official 107:414e9c822e99 49 uint32_t gSPI_clock=500000;
mbed_official 107:414e9c822e99 50
mbed_official 107:414e9c822e99 51 extern uint8_t g_sys_init;
mbed_official 107:414e9c822e99 52
mbed_official 107:414e9c822e99 53
mbed_official 107:414e9c822e99 54
mbed_official 107:414e9c822e99 55 void pinmap_find_spi_info(Spi *sercombase, spi_t *obj)
mbed_official 107:414e9c822e99 56 {
mbed_official 107:414e9c822e99 57 if(sercombase==SPI0) {
mbed_official 107:414e9c822e99 58 obj->spi.flexcom=FLEXCOM0;
mbed_official 107:414e9c822e99 59 obj->spi.module_number=0;
mbed_official 107:414e9c822e99 60 obj->spi.pdc =PDC_SPI0;
mbed_official 107:414e9c822e99 61 obj->spi.irq_type=FLEXCOM0_IRQn;
mbed_official 107:414e9c822e99 62 } else if(sercombase==SPI1) {
mbed_official 107:414e9c822e99 63 obj->spi.flexcom=FLEXCOM1;
mbed_official 107:414e9c822e99 64 obj->spi.module_number=1;
mbed_official 107:414e9c822e99 65 obj->spi.pdc =PDC_SPI1;
mbed_official 107:414e9c822e99 66 obj->spi.irq_type=FLEXCOM1_IRQn;
mbed_official 107:414e9c822e99 67 } else if(sercombase==SPI2) {
mbed_official 107:414e9c822e99 68 obj->spi.flexcom=FLEXCOM2;
mbed_official 107:414e9c822e99 69 obj->spi.module_number=2;
mbed_official 107:414e9c822e99 70 obj->spi.pdc =PDC_SPI2;
mbed_official 107:414e9c822e99 71 obj->spi.irq_type=FLEXCOM2_IRQn;
mbed_official 107:414e9c822e99 72 } else if(sercombase==SPI3) {
mbed_official 107:414e9c822e99 73 obj->spi.flexcom=FLEXCOM3;
mbed_official 107:414e9c822e99 74 obj->spi.module_number=3;
mbed_official 107:414e9c822e99 75 obj->spi.pdc =PDC_SPI3;
mbed_official 107:414e9c822e99 76 obj->spi.irq_type=FLEXCOM3_IRQn;
mbed_official 107:414e9c822e99 77 } else if(sercombase==SPI4) {
mbed_official 107:414e9c822e99 78 obj->spi.flexcom=FLEXCOM4;
mbed_official 107:414e9c822e99 79 obj->spi.module_number=4;
mbed_official 107:414e9c822e99 80 obj->spi.pdc =PDC_SPI4;
mbed_official 107:414e9c822e99 81 obj->spi.irq_type=FLEXCOM4_IRQn;
mbed_official 107:414e9c822e99 82 } else if(sercombase==SPI5) {
mbed_official 107:414e9c822e99 83 obj->spi.flexcom=FLEXCOM5;
mbed_official 107:414e9c822e99 84 obj->spi.module_number=5;
mbed_official 107:414e9c822e99 85 obj->spi.pdc =PDC_SPI5;
mbed_official 107:414e9c822e99 86 obj->spi.irq_type=FLEXCOM5_IRQn;
mbed_official 107:414e9c822e99 87 } else if(sercombase==SPI6) {
mbed_official 107:414e9c822e99 88 obj->spi.flexcom=FLEXCOM6;
mbed_official 107:414e9c822e99 89 obj->spi.module_number=6;
mbed_official 107:414e9c822e99 90 obj->spi.pdc =PDC_SPI6;
mbed_official 107:414e9c822e99 91 obj->spi.irq_type=FLEXCOM6_IRQn;
mbed_official 107:414e9c822e99 92 } else if(sercombase==SPI7) {
mbed_official 107:414e9c822e99 93 obj->spi.flexcom=FLEXCOM7;
mbed_official 107:414e9c822e99 94 obj->spi.module_number=7;
mbed_official 107:414e9c822e99 95 obj->spi.pdc =PDC_SPI7;
mbed_official 107:414e9c822e99 96 obj->spi.irq_type=FLEXCOM7_IRQn;
mbed_official 107:414e9c822e99 97 } else {
mbed_official 107:414e9c822e99 98 obj->spi.flexcom=(Flexcom *)NC;
mbed_official 107:414e9c822e99 99 obj->spi.module_number=0;
mbed_official 107:414e9c822e99 100 obj->spi.pdc =(Pdc *) NC;
mbed_official 107:414e9c822e99 101 }
mbed_official 107:414e9c822e99 102 }
mbed_official 107:414e9c822e99 103
mbed_official 107:414e9c822e99 104 Spi* pinmap_find_sercom(PinName mosi, PinName miso, PinName sclk)
mbed_official 107:414e9c822e99 105 {
mbed_official 107:414e9c822e99 106 Spi* sercomIndex=(Spi*)pinmap_peripheral (mosi,PinMap_SPI_MOSI);
mbed_official 107:414e9c822e99 107 if(sercomIndex== (Spi*)pinmap_peripheral (miso, PinMap_SPI_MISO) &&
mbed_official 107:414e9c822e99 108 sercomIndex == (Spi*)pinmap_peripheral (sclk, PinMap_SPI_SCLK))
mbed_official 107:414e9c822e99 109 return sercomIndex;
mbed_official 107:414e9c822e99 110
mbed_official 107:414e9c822e99 111 return (Spi*)NC;
mbed_official 107:414e9c822e99 112 }
mbed_official 107:414e9c822e99 113
mbed_official 107:414e9c822e99 114
mbed_official 107:414e9c822e99 115 /** Initialize the SPI peripheral
mbed_official 107:414e9c822e99 116 *
mbed_official 107:414e9c822e99 117 * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
mbed_official 107:414e9c822e99 118 * @param[out] obj The SPI object to initialize
mbed_official 107:414e9c822e99 119 * @param[in] mosi The pin to use for MOSI
mbed_official 107:414e9c822e99 120 * @param[in] miso The pin to use for MISO
mbed_official 107:414e9c822e99 121 * @param[in] sclk The pin to use for SCLK
mbed_official 107:414e9c822e99 122 * @param[in] ssel The pin to use for SSEL <Not Used>
mbed_official 107:414e9c822e99 123 */
mbed_official 107:414e9c822e99 124 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel /*Not Used*/)
mbed_official 107:414e9c822e99 125 {
mbed_official 107:414e9c822e99 126 MBED_ASSERT(obj);
mbed_official 107:414e9c822e99 127 MBED_ASSERT(mosi !=NC && miso!=NC && sclk !=NC );
mbed_official 107:414e9c822e99 128
mbed_official 107:414e9c822e99 129 if (g_sys_init == 0) {
mbed_official 107:414e9c822e99 130 sysclk_init();
mbed_official 107:414e9c822e99 131 system_board_init();
mbed_official 107:414e9c822e99 132 g_sys_init = 1;
mbed_official 107:414e9c822e99 133 }
mbed_official 107:414e9c822e99 134
mbed_official 107:414e9c822e99 135 Spi *sercombase = pinmap_find_sercom(mosi,miso,sclk);
mbed_official 107:414e9c822e99 136 MBED_ASSERT(sercombase!=NC);
mbed_official 107:414e9c822e99 137
mbed_official 107:414e9c822e99 138 pinmap_find_spi_info(sercombase, obj);
mbed_official 107:414e9c822e99 139 MBED_ASSERT(obj->spi.flexcom!=NC);
mbed_official 107:414e9c822e99 140 MBED_ASSERT(obj->spi.pdc!=NC);
mbed_official 107:414e9c822e99 141
mbed_official 107:414e9c822e99 142 /* Configure SPI pins */
mbed_official 107:414e9c822e99 143 pin_function(mosi, pinmap_find_function(mosi, PinMap_SPI_MOSI));
mbed_official 107:414e9c822e99 144 ioport_disable_pin(mosi);
mbed_official 107:414e9c822e99 145
mbed_official 107:414e9c822e99 146 pin_function(miso, pinmap_find_function(miso, PinMap_SPI_MISO));
mbed_official 107:414e9c822e99 147 ioport_disable_pin(miso);
mbed_official 107:414e9c822e99 148
mbed_official 107:414e9c822e99 149 pin_function(sclk, pinmap_find_function(sclk, PinMap_SPI_SCLK));
mbed_official 107:414e9c822e99 150 ioport_disable_pin(sclk);
mbed_official 107:414e9c822e99 151
mbed_official 107:414e9c822e99 152 #if (SAMG55)
mbed_official 107:414e9c822e99 153 /* Enable the peripheral and set SPI mode. */
mbed_official 107:414e9c822e99 154 flexcom_enable(obj->spi.flexcom);
mbed_official 107:414e9c822e99 155 flexcom_set_opmode(obj->spi.flexcom, FLEXCOM_SPI);
mbed_official 107:414e9c822e99 156 #else
mbed_official 107:414e9c822e99 157 /* Configure an SPI peripheral. */
mbed_official 107:414e9c822e99 158 spi_enable_clock(sercombase);
mbed_official 107:414e9c822e99 159 #endif
mbed_official 107:414e9c822e99 160 spi_disable(sercombase);
mbed_official 107:414e9c822e99 161 spi_reset(sercombase);
mbed_official 107:414e9c822e99 162 spi_set_lastxfer(sercombase);
mbed_official 107:414e9c822e99 163 spi_set_master_mode(sercombase);
mbed_official 107:414e9c822e99 164 spi_disable_mode_fault_detect(sercombase);
mbed_official 107:414e9c822e99 165 spi_set_peripheral_chip_select_value(sercombase, SPI_CHIP_SEL);
mbed_official 107:414e9c822e99 166 spi_set_clock_polarity(sercombase, SPI_CHIP_SEL, SPI_CLK_POLARITY);
mbed_official 107:414e9c822e99 167 spi_set_clock_phase(sercombase, SPI_CHIP_SEL, SPI_CLK_PHASE);
mbed_official 107:414e9c822e99 168 spi_set_bits_per_transfer(sercombase, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT);
mbed_official 107:414e9c822e99 169 spi_set_baudrate_div(sercombase, SPI_CHIP_SEL,(sysclk_get_cpu_hz() / gSPI_clock));
mbed_official 107:414e9c822e99 170 spi_set_transfer_delay(sercombase, SPI_CHIP_SEL, SPI_DLYBS,SPI_DLYBCT);
mbed_official 107:414e9c822e99 171
mbed_official 107:414e9c822e99 172 spi_enable(sercombase);
mbed_official 107:414e9c822e99 173
mbed_official 107:414e9c822e99 174 pdc_disable_transfer(obj->spi.pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
mbed_official 107:414e9c822e99 175
mbed_official 107:414e9c822e99 176 obj->spi.spi_base=sercombase;
mbed_official 107:414e9c822e99 177 obj->spi.cs= SPI_CHIP_SEL;
mbed_official 107:414e9c822e99 178 obj->spi.polarity=SPI_CLK_POLARITY;
mbed_official 107:414e9c822e99 179 obj->spi.phase=SPI_CLK_PHASE;
mbed_official 107:414e9c822e99 180 obj->spi.transferrate=SPI_CSR_BITS_8_BIT;
mbed_official 107:414e9c822e99 181 obj->spi.is_slave=0;
mbed_official 107:414e9c822e99 182 }
mbed_official 107:414e9c822e99 183
mbed_official 107:414e9c822e99 184 /** Release a SPI object
mbed_official 107:414e9c822e99 185 *
mbed_official 107:414e9c822e99 186 * TODO: spi_free is currently unimplemented
mbed_official 107:414e9c822e99 187 * This will require reference counting at the C++ level to be safe
mbed_official 107:414e9c822e99 188 *
mbed_official 107:414e9c822e99 189 * Return the pins owned by the SPI object to their reset state
mbed_official 107:414e9c822e99 190 * Disable the SPI peripheral
mbed_official 107:414e9c822e99 191 * Disable the SPI clock
mbed_official 107:414e9c822e99 192 * @param[in] obj The SPI object to deinitialize
mbed_official 107:414e9c822e99 193 */
mbed_official 107:414e9c822e99 194 void spi_free(spi_t *obj)
mbed_official 107:414e9c822e99 195 {
mbed_official 107:414e9c822e99 196 MBED_ASSERT(obj);
mbed_official 107:414e9c822e99 197 spi_disable(obj->spi.spi_base);
mbed_official 107:414e9c822e99 198 spi_reset(obj->spi.spi_base);
mbed_official 107:414e9c822e99 199 flexcom_disable((Flexcom *)obj->spi.flexcom);
mbed_official 107:414e9c822e99 200 }
mbed_official 107:414e9c822e99 201
mbed_official 107:414e9c822e99 202 uint32_t get_transfer_rate(int bits)
mbed_official 107:414e9c822e99 203 {
mbed_official 107:414e9c822e99 204 switch(bits) {
mbed_official 107:414e9c822e99 205 case 8:
mbed_official 107:414e9c822e99 206 return SPI_CSR_BITS_8_BIT;
mbed_official 107:414e9c822e99 207 case 9:
mbed_official 107:414e9c822e99 208 return SPI_CSR_BITS_9_BIT;
mbed_official 107:414e9c822e99 209 case 10:
mbed_official 107:414e9c822e99 210 return SPI_CSR_BITS_10_BIT;
mbed_official 107:414e9c822e99 211 case 11:
mbed_official 107:414e9c822e99 212 return SPI_CSR_BITS_11_BIT;
mbed_official 107:414e9c822e99 213 case 12:
mbed_official 107:414e9c822e99 214 return SPI_CSR_BITS_12_BIT;
mbed_official 107:414e9c822e99 215 case 13:
mbed_official 107:414e9c822e99 216 return SPI_CSR_BITS_13_BIT;
mbed_official 107:414e9c822e99 217 case 14:
mbed_official 107:414e9c822e99 218 return SPI_CSR_BITS_14_BIT;
mbed_official 107:414e9c822e99 219 case 15:
mbed_official 107:414e9c822e99 220 return SPI_CSR_BITS_15_BIT;
mbed_official 107:414e9c822e99 221 case 16:
mbed_official 107:414e9c822e99 222 return SPI_CSR_BITS_16_BIT;
mbed_official 107:414e9c822e99 223 default:
mbed_official 107:414e9c822e99 224 return NC;
mbed_official 107:414e9c822e99 225 }
mbed_official 107:414e9c822e99 226 }
mbed_official 107:414e9c822e99 227
mbed_official 107:414e9c822e99 228 /** Configure the SPI format
mbed_official 107:414e9c822e99 229 *
mbed_official 107:414e9c822e99 230 * Set the number of bits per frame, configure clock polarity and phase, shift order and master/slave mode
mbed_official 107:414e9c822e99 231 * @param[in,out] obj The SPI object to configure
mbed_official 107:414e9c822e99 232 * @param[in] bits The number of bits per frame
mbed_official 107:414e9c822e99 233 * @param[in] mode The SPI mode (clock polarity, phase, and shift direction)
mbed_official 107:414e9c822e99 234 * @param[in] slave Zero for master mode or non-zero for slave mode
mbed_official 107:414e9c822e99 235 */
mbed_official 107:414e9c822e99 236 void spi_format(spi_t *obj, int bits, int mode, int slave)
mbed_official 107:414e9c822e99 237 {
mbed_official 107:414e9c822e99 238 uint32_t transferrate= get_transfer_rate(bits);
mbed_official 107:414e9c822e99 239 MBED_ASSERT(transferrate!=NC);
mbed_official 107:414e9c822e99 240
mbed_official 107:414e9c822e99 241 spi_disable(obj->spi.spi_base);
mbed_official 107:414e9c822e99 242 obj->spi.transferrate=transferrate;
mbed_official 107:414e9c822e99 243 if(slave) {
mbed_official 107:414e9c822e99 244 spi_set_slave_mode(obj->spi.spi_base);
mbed_official 107:414e9c822e99 245 obj->spi.is_slave=1;
mbed_official 107:414e9c822e99 246 } else {
mbed_official 107:414e9c822e99 247 spi_set_master_mode(obj->spi.spi_base);
mbed_official 107:414e9c822e99 248 obj->spi.is_slave=0;
mbed_official 107:414e9c822e99 249 }
mbed_official 107:414e9c822e99 250 spi_set_bits_per_transfer(obj->spi.spi_base, obj->spi.cs, obj->spi.transferrate);
mbed_official 107:414e9c822e99 251 spi_set_clock_phase(obj->spi.spi_base, SPI_CHIP_SEL, (mode & 0x01));
mbed_official 107:414e9c822e99 252 spi_set_clock_polarity(obj->spi.spi_base, SPI_CHIP_SEL, (mode & 0x02));
mbed_official 107:414e9c822e99 253
mbed_official 107:414e9c822e99 254 obj->spi.phase=(mode & 0x01);
mbed_official 107:414e9c822e99 255 obj->spi.polarity=(mode & 0x02);
mbed_official 107:414e9c822e99 256 spi_enable(obj->spi.spi_base);
mbed_official 107:414e9c822e99 257 }
mbed_official 107:414e9c822e99 258
mbed_official 107:414e9c822e99 259 /** Set the SPI baud rate
mbed_official 107:414e9c822e99 260 *
mbed_official 107:414e9c822e99 261 * Actual frequency may differ from the desired frequency due to available dividers and bus clock
mbed_official 107:414e9c822e99 262 * Configures the SPI peripheral's baud rate
mbed_official 107:414e9c822e99 263 * @param[in,out] obj The SPI object to configure
mbed_official 107:414e9c822e99 264 * @param[in] hz The baud rate in Hz
mbed_official 107:414e9c822e99 265 */
mbed_official 107:414e9c822e99 266
mbed_official 107:414e9c822e99 267 void spi_frequency(spi_t *obj, int hz)
mbed_official 107:414e9c822e99 268 {
mbed_official 107:414e9c822e99 269 spi_disable(obj->spi.spi_base);
mbed_official 107:414e9c822e99 270 int16_t baudrate_div=spi_calc_baudrate_div(hz, sysclk_get_cpu_hz());
mbed_official 107:414e9c822e99 271 spi_set_baudrate_div(obj->spi.spi_base,obj->spi.cs,(uint8_t)baudrate_div);
mbed_official 107:414e9c822e99 272 spi_enable(obj->spi.spi_base);
mbed_official 107:414e9c822e99 273 }
mbed_official 107:414e9c822e99 274
mbed_official 107:414e9c822e99 275 /**@}*/
mbed_official 107:414e9c822e99 276 /**
mbed_official 107:414e9c822e99 277 * \defgroup SynchSPI Synchronous SPI Hardware Abstraction Layer
mbed_official 107:414e9c822e99 278 * @{
mbed_official 107:414e9c822e99 279 */
mbed_official 107:414e9c822e99 280
mbed_official 107:414e9c822e99 281 /** Write a byte out in master mode and receive a value
mbed_official 107:414e9c822e99 282 *
mbed_official 107:414e9c822e99 283 * @param[in] obj The SPI peripheral to use for sending
mbed_official 107:414e9c822e99 284 * @param[in] value The value to send
mbed_official 107:414e9c822e99 285 * @return Returns the value received during send
mbed_official 107:414e9c822e99 286 */
mbed_official 107:414e9c822e99 287 int spi_master_write(spi_t *obj, int value)
mbed_official 107:414e9c822e99 288 {
mbed_official 107:414e9c822e99 289 spi_status_t status=spi_write(obj->spi.spi_base,(uint16_t)value,obj->spi.cs,SPI_LAST);
mbed_official 107:414e9c822e99 290 if(status ==SPI_OK) {
mbed_official 107:414e9c822e99 291 uint16_t data;
mbed_official 107:414e9c822e99 292 status =spi_read(obj->spi.spi_base,&data,&obj->spi.cs);
mbed_official 107:414e9c822e99 293 if(status == SPI_OK)
mbed_official 107:414e9c822e99 294 return data;
mbed_official 107:414e9c822e99 295 }
mbed_official 107:414e9c822e99 296 return 0;
mbed_official 107:414e9c822e99 297 }
mbed_official 107:414e9c822e99 298
Kojto 170:19eb464bc2be 299 int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
Kojto 170:19eb464bc2be 300 char *rx_buffer, int rx_length, char _write_fill) {
AnnaBridge 167:e84263d55307 301 int total = (tx_length > rx_length) ? tx_length : rx_length;
AnnaBridge 167:e84263d55307 302
AnnaBridge 167:e84263d55307 303 for (int i = 0; i < total; i++) {
Kojto 170:19eb464bc2be 304 char out = (i < tx_length) ? tx_buffer[i] : _write_fill;
AnnaBridge 167:e84263d55307 305 char in = spi_master_write(obj, out);
AnnaBridge 167:e84263d55307 306 if (i < rx_length) {
AnnaBridge 167:e84263d55307 307 rx_buffer[i] = in;
AnnaBridge 167:e84263d55307 308 }
AnnaBridge 167:e84263d55307 309 }
AnnaBridge 167:e84263d55307 310
AnnaBridge 167:e84263d55307 311 return total;
AnnaBridge 167:e84263d55307 312 }
AnnaBridge 167:e84263d55307 313
mbed_official 107:414e9c822e99 314 /** Check if a value is available to read
mbed_official 107:414e9c822e99 315 *
mbed_official 107:414e9c822e99 316 * @param[in] obj The SPI peripheral to check
mbed_official 107:414e9c822e99 317 * @return non-zero if a value is available
mbed_official 107:414e9c822e99 318 */
mbed_official 107:414e9c822e99 319 int spi_slave_receive(spi_t *obj)
mbed_official 107:414e9c822e99 320 {
mbed_official 107:414e9c822e99 321 if(obj->spi.spi_base->SPI_SR & SPI_SR_RDRF)
mbed_official 107:414e9c822e99 322 return 1;
mbed_official 107:414e9c822e99 323 return 0;
mbed_official 107:414e9c822e99 324 }
mbed_official 107:414e9c822e99 325
mbed_official 107:414e9c822e99 326 /** Get a received value out of the SPI receive buffer in slave mode
mbed_official 107:414e9c822e99 327 *
mbed_official 107:414e9c822e99 328 * Blocks until a value is available
mbed_official 107:414e9c822e99 329 * @param[in] obj The SPI peripheral to read
mbed_official 107:414e9c822e99 330 * @return The value received
mbed_official 107:414e9c822e99 331 */
mbed_official 107:414e9c822e99 332 int spi_slave_read(spi_t *obj)
mbed_official 107:414e9c822e99 333 {
mbed_official 107:414e9c822e99 334 uint16_t data;
mbed_official 107:414e9c822e99 335 spi_status_t status =spi_read(obj->spi.spi_base, &data, &obj->spi.cs);
mbed_official 107:414e9c822e99 336 if(status == SPI_OK)
mbed_official 107:414e9c822e99 337 return data;
mbed_official 107:414e9c822e99 338 return 0;
mbed_official 107:414e9c822e99 339 }
mbed_official 107:414e9c822e99 340
mbed_official 107:414e9c822e99 341 /** Write a value to the SPI peripheral in slave mode
mbed_official 107:414e9c822e99 342 *
mbed_official 107:414e9c822e99 343 * Blocks until the SPI peripheral can be written to
mbed_official 107:414e9c822e99 344 * @param[in] obj The SPI peripheral to write
mbed_official 107:414e9c822e99 345 * @param[in] value The value to write
mbed_official 107:414e9c822e99 346 */
mbed_official 107:414e9c822e99 347 void spi_slave_write(spi_t *obj, int value)
mbed_official 107:414e9c822e99 348 {
mbed_official 107:414e9c822e99 349 spi_write(obj->spi.spi_base,(uint16_t)value,obj->spi.cs,SPI_LAST);
mbed_official 107:414e9c822e99 350 }
mbed_official 107:414e9c822e99 351
mbed_official 107:414e9c822e99 352 /** Checks if the specified SPI peripheral is in use
mbed_official 107:414e9c822e99 353 *
mbed_official 107:414e9c822e99 354 * @param[in] obj The SPI peripheral to check
mbed_official 107:414e9c822e99 355 * @return non-zero if the peripheral is currently transmitting
mbed_official 107:414e9c822e99 356 */
mbed_official 107:414e9c822e99 357 int spi_busy(spi_t *obj)
mbed_official 107:414e9c822e99 358 {
mbed_official 107:414e9c822e99 359 if(obj->spi.spi_base->SPI_SR & SPI_SR_TDRE) //Transmit Data Register Empty
mbed_official 107:414e9c822e99 360 return 0;
mbed_official 107:414e9c822e99 361 return 1;
mbed_official 107:414e9c822e99 362 }
mbed_official 107:414e9c822e99 363
mbed_official 107:414e9c822e99 364 /** Get the module number
mbed_official 107:414e9c822e99 365 *
mbed_official 107:414e9c822e99 366 * @param[in] obj The SPI peripheral to check
mbed_official 107:414e9c822e99 367 * @return The module number
mbed_official 107:414e9c822e99 368 */
mbed_official 107:414e9c822e99 369 uint8_t spi_get_module(spi_t *obj)
mbed_official 107:414e9c822e99 370 {
mbed_official 107:414e9c822e99 371 return obj->spi.module_number;
mbed_official 107:414e9c822e99 372 }
mbed_official 107:414e9c822e99 373
mbed_official 107:414e9c822e99 374
mbed_official 107:414e9c822e99 375 /**@}*/
mbed_official 107:414e9c822e99 376 #if DEVICE_SPI_ASYNCH
mbed_official 107:414e9c822e99 377 /**
mbed_official 107:414e9c822e99 378 * \defgroup AsynchSPI Asynchronous SPI Hardware Abstraction Layer
mbed_official 107:414e9c822e99 379 * @{
mbed_official 107:414e9c822e99 380 */
mbed_official 107:414e9c822e99 381
mbed_official 107:414e9c822e99 382 /** Begin the SPI transfer. Buffer pointers and lengths are specified in tx_buff and rx_buff
mbed_official 107:414e9c822e99 383 *
mbed_official 107:414e9c822e99 384 * @param[in] obj The SPI object which holds the transfer information
mbed_official 107:414e9c822e99 385 * @param[in] tx The buffer to send
mbed_official 107:414e9c822e99 386 * @param[in] tx_length The number of words to transmit
mbed_official 107:414e9c822e99 387 * @param[in] rx The buffer to receive
mbed_official 107:414e9c822e99 388 * @param[in] rx_length The number of words to receive
mbed_official 107:414e9c822e99 389 * @param[in] bit_width The bit width of buffer words
mbed_official 107:414e9c822e99 390 * @param[in] event The logical OR of events to be registered
mbed_official 107:414e9c822e99 391 * @param[in] handler SPI interrupt handler
mbed_official 107:414e9c822e99 392 * @param[in] hint A suggestion for how to use DMA with this transfer
mbed_official 107:414e9c822e99 393 */
mbed_official 107:414e9c822e99 394 #warning "Only DMA async supported by SPI master transfer"
mbed_official 107:414e9c822e99 395
mbed_official 107:414e9c822e99 396 void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint)
mbed_official 107:414e9c822e99 397 {
mbed_official 107:414e9c822e99 398 uint32_t pdcenable=0;
mbed_official 107:414e9c822e99 399
mbed_official 107:414e9c822e99 400 if(bit_width) {
mbed_official 107:414e9c822e99 401 uint32_t transferrate= get_transfer_rate(bit_width);
mbed_official 107:414e9c822e99 402 spi_set_bits_per_transfer(obj->spi.spi_base, obj->spi.cs, transferrate);
mbed_official 107:414e9c822e99 403 }
mbed_official 107:414e9c822e99 404
mbed_official 107:414e9c822e99 405 if(tx) {
mbed_official 107:414e9c822e99 406 pdc_packet_t pdc_packet_tx;
mbed_official 107:414e9c822e99 407 pdc_packet_tx.ul_addr=(uint32_t)tx;
mbed_official 107:414e9c822e99 408 pdc_packet_tx.ul_size=tx_length;
mbed_official 107:414e9c822e99 409
mbed_official 107:414e9c822e99 410 pdcenable|=PERIPH_PTCR_TXTEN;
mbed_official 107:414e9c822e99 411 /* Configure PDC for data send */
mbed_official 107:414e9c822e99 412 pdc_tx_init(obj->spi.pdc, &pdc_packet_tx, NULL);
mbed_official 107:414e9c822e99 413 }
mbed_official 107:414e9c822e99 414
mbed_official 107:414e9c822e99 415 if(rx) {
mbed_official 107:414e9c822e99 416 pdc_rx_clear_cnt(obj->spi.pdc);
mbed_official 107:414e9c822e99 417 pdc_packet_t pdc_packet_rx;
mbed_official 107:414e9c822e99 418 pdc_packet_rx.ul_addr=(uint32_t)rx;
mbed_official 107:414e9c822e99 419 pdc_packet_rx.ul_size=rx_length;
mbed_official 107:414e9c822e99 420 pdcenable|=PERIPH_PTCR_RXTEN;
mbed_official 107:414e9c822e99 421 char *rxbuffer=(char *)rx;
mbed_official 107:414e9c822e99 422 for(uint8_t index=0; index<rx_length; index++, rxbuffer++)
mbed_official 107:414e9c822e99 423 *rxbuffer=SPI_FILL_WORD;
mbed_official 107:414e9c822e99 424
mbed_official 107:414e9c822e99 425 /* Configure PDC for data receive */
mbed_official 107:414e9c822e99 426 pdc_rx_init(obj->spi.pdc, &pdc_packet_rx, NULL);
mbed_official 107:414e9c822e99 427 }
mbed_official 107:414e9c822e99 428
mbed_official 107:414e9c822e99 429 obj->spi.dma_usage=hint;
mbed_official 107:414e9c822e99 430 obj->spi.event=event;
mbed_official 107:414e9c822e99 431
mbed_official 107:414e9c822e99 432 NVIC_ClearPendingIRQ(obj->spi.irq_type);
mbed_official 107:414e9c822e99 433 NVIC_DisableIRQ(obj->spi.irq_type);
mbed_official 107:414e9c822e99 434 NVIC_SetVector(obj->spi.irq_type,handler);
mbed_official 107:414e9c822e99 435 NVIC_EnableIRQ(obj->spi.irq_type);
mbed_official 107:414e9c822e99 436
mbed_official 107:414e9c822e99 437 /* Enable SPI IRQ */
mbed_official 107:414e9c822e99 438 spi_enable_interrupt(obj->spi.spi_base, SPI_IER_RXBUFF| SPI_IER_TXBUFE | SPI_IER_MODF | SPI_IER_OVRES);
mbed_official 107:414e9c822e99 439
mbed_official 107:414e9c822e99 440 /* Enable PDC transfers */
mbed_official 107:414e9c822e99 441 pdc_enable_transfer(obj->spi.pdc, pdcenable );
mbed_official 107:414e9c822e99 442
mbed_official 107:414e9c822e99 443 }
mbed_official 107:414e9c822e99 444
mbed_official 107:414e9c822e99 445 /** The asynchronous IRQ handler
mbed_official 107:414e9c822e99 446 *
mbed_official 107:414e9c822e99 447 * Reads the received values out of the RX FIFO, writes values into the TX FIFO and checks for transfer termination
mbed_official 107:414e9c822e99 448 * conditions, such as buffer overflows or transfer complete.
mbed_official 107:414e9c822e99 449 * @param[in] obj The SPI object which holds the transfer information
mbed_official 107:414e9c822e99 450 * @return event flags if a transfer termination condition was met or 0 otherwise.
mbed_official 107:414e9c822e99 451 */
mbed_official 107:414e9c822e99 452 uint32_t spi_irq_handler_asynch(spi_t *obj)
mbed_official 107:414e9c822e99 453 {
mbed_official 107:414e9c822e99 454 uint32_t event=0;
mbed_official 107:414e9c822e99 455
mbed_official 107:414e9c822e99 456 // Data transferred via DMA
mbed_official 107:414e9c822e99 457 if((obj->spi.spi_base->SPI_SR & SPI_IER_TXBUFE)) {
mbed_official 107:414e9c822e99 458 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_TXBUFE | SPI_IDR_MODF | SPI_IDR_OVRES);
mbed_official 107:414e9c822e99 459 if(obj->spi.event | SPI_EVENT_COMPLETE)
mbed_official 107:414e9c822e99 460 event |=SPI_EVENT_COMPLETE;
mbed_official 107:414e9c822e99 461 }
mbed_official 107:414e9c822e99 462
mbed_official 107:414e9c822e99 463 if((obj->spi.spi_base->SPI_SR & SPI_IER_RXBUFF)) {
mbed_official 107:414e9c822e99 464 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_RXBUFF | SPI_IDR_MODF | SPI_IDR_OVRES);
mbed_official 107:414e9c822e99 465 if(obj->spi.event | SPI_EVENT_COMPLETE)
mbed_official 107:414e9c822e99 466 event |=SPI_EVENT_COMPLETE;
mbed_official 107:414e9c822e99 467 }
mbed_official 107:414e9c822e99 468
mbed_official 107:414e9c822e99 469 if(obj->spi.spi_base->SPI_SR & SPI_SR_MODF) {
mbed_official 107:414e9c822e99 470 if(obj->spi.event | SPI_EVENT_ERROR)
mbed_official 107:414e9c822e99 471 event |=SPI_EVENT_ERROR;
mbed_official 107:414e9c822e99 472 }
mbed_official 107:414e9c822e99 473
mbed_official 107:414e9c822e99 474 if(obj->spi.spi_base->SPI_SR & SPI_SR_OVRES) {
mbed_official 107:414e9c822e99 475 if(obj->spi.event | SPI_EVENT_RX_OVERFLOW)
mbed_official 107:414e9c822e99 476 event |=SPI_EVENT_RX_OVERFLOW;
mbed_official 107:414e9c822e99 477 }
mbed_official 107:414e9c822e99 478
mbed_official 107:414e9c822e99 479 return event;
mbed_official 107:414e9c822e99 480 }
mbed_official 107:414e9c822e99 481
mbed_official 107:414e9c822e99 482 /** Attempts to determine if the SPI peripheral is already in use.
mbed_official 107:414e9c822e99 483 *
mbed_official 107:414e9c822e99 484 * If a temporary DMA channel has been allocated, peripheral is in use.
mbed_official 107:414e9c822e99 485 * If a permanent DMA channel has been allocated, check if the DMA channel is in use. If not, proceed as though no DMA
mbed_official 107:414e9c822e99 486 * channel were allocated.
mbed_official 107:414e9c822e99 487 * If no DMA channel is allocated, check whether tx and rx buffers have been assigned. For each assigned buffer, check
mbed_official 107:414e9c822e99 488 * if the corresponding buffer position is less than the buffer length. If buffers do not indicate activity, check if
mbed_official 107:414e9c822e99 489 * there are any bytes in the FIFOs.
mbed_official 107:414e9c822e99 490 * @param[in] obj The SPI object to check for activity
mbed_official 107:414e9c822e99 491 * @return non-zero if the SPI port is active or zero if it is not.
mbed_official 107:414e9c822e99 492 */
mbed_official 107:414e9c822e99 493
mbed_official 107:414e9c822e99 494 uint8_t spi_active(spi_t *obj)
mbed_official 107:414e9c822e99 495 {
mbed_official 107:414e9c822e99 496 if(obj->spi.spi_base->SPI_SR & SPI_SR_ENDTX && obj->spi.spi_base->SPI_SR & SPI_SR_ENDRX)
mbed_official 107:414e9c822e99 497 return 0;
mbed_official 107:414e9c822e99 498 return 1;
mbed_official 107:414e9c822e99 499 }
mbed_official 107:414e9c822e99 500
mbed_official 107:414e9c822e99 501 /** Abort an SPI transfer
mbed_official 107:414e9c822e99 502 *
mbed_official 107:414e9c822e99 503 * @param obj The SPI peripheral to stop
mbed_official 107:414e9c822e99 504 */
mbed_official 107:414e9c822e99 505 void spi_abort_asynch(spi_t *obj)
mbed_official 107:414e9c822e99 506 {
mbed_official 107:414e9c822e99 507 /* Disable PDC transfers */
mbed_official 107:414e9c822e99 508 pdc_disable_transfer(obj->spi.pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
mbed_official 107:414e9c822e99 509
mbed_official 107:414e9c822e99 510 /* Clear PDC buffer receive counter */
mbed_official 107:414e9c822e99 511 pdc_rx_clear_cnt(obj->spi.pdc);
mbed_official 107:414e9c822e99 512
mbed_official 107:414e9c822e99 513 /* Disable SPI IRQ */
mbed_official 107:414e9c822e99 514 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_TXBUFE);
mbed_official 107:414e9c822e99 515 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_RXBUFF);
mbed_official 107:414e9c822e99 516
mbed_official 107:414e9c822e99 517 /* Disable SPI interrupt */
mbed_official 107:414e9c822e99 518 NVIC_DisableIRQ(obj->spi.irq_type);
mbed_official 107:414e9c822e99 519 }
mbed_official 107:414e9c822e99 520
mbed_official 107:414e9c822e99 521 #endif