added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
107:414e9c822e99
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

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
mbed_official 107:414e9c822e99 299 /** Check if a value is available to read
mbed_official 107:414e9c822e99 300 *
mbed_official 107:414e9c822e99 301 * @param[in] obj The SPI peripheral to check
mbed_official 107:414e9c822e99 302 * @return non-zero if a value is available
mbed_official 107:414e9c822e99 303 */
mbed_official 107:414e9c822e99 304 int spi_slave_receive(spi_t *obj)
mbed_official 107:414e9c822e99 305 {
mbed_official 107:414e9c822e99 306 if(obj->spi.spi_base->SPI_SR & SPI_SR_RDRF)
mbed_official 107:414e9c822e99 307 return 1;
mbed_official 107:414e9c822e99 308 return 0;
mbed_official 107:414e9c822e99 309 }
mbed_official 107:414e9c822e99 310
mbed_official 107:414e9c822e99 311 /** Get a received value out of the SPI receive buffer in slave mode
mbed_official 107:414e9c822e99 312 *
mbed_official 107:414e9c822e99 313 * Blocks until a value is available
mbed_official 107:414e9c822e99 314 * @param[in] obj The SPI peripheral to read
mbed_official 107:414e9c822e99 315 * @return The value received
mbed_official 107:414e9c822e99 316 */
mbed_official 107:414e9c822e99 317 int spi_slave_read(spi_t *obj)
mbed_official 107:414e9c822e99 318 {
mbed_official 107:414e9c822e99 319 uint16_t data;
mbed_official 107:414e9c822e99 320 spi_status_t status =spi_read(obj->spi.spi_base, &data, &obj->spi.cs);
mbed_official 107:414e9c822e99 321 if(status == SPI_OK)
mbed_official 107:414e9c822e99 322 return data;
mbed_official 107:414e9c822e99 323 return 0;
mbed_official 107:414e9c822e99 324 }
mbed_official 107:414e9c822e99 325
mbed_official 107:414e9c822e99 326 /** Write a value to the SPI peripheral in slave mode
mbed_official 107:414e9c822e99 327 *
mbed_official 107:414e9c822e99 328 * Blocks until the SPI peripheral can be written to
mbed_official 107:414e9c822e99 329 * @param[in] obj The SPI peripheral to write
mbed_official 107:414e9c822e99 330 * @param[in] value The value to write
mbed_official 107:414e9c822e99 331 */
mbed_official 107:414e9c822e99 332 void spi_slave_write(spi_t *obj, int value)
mbed_official 107:414e9c822e99 333 {
mbed_official 107:414e9c822e99 334 spi_write(obj->spi.spi_base,(uint16_t)value,obj->spi.cs,SPI_LAST);
mbed_official 107:414e9c822e99 335 }
mbed_official 107:414e9c822e99 336
mbed_official 107:414e9c822e99 337 /** Checks if the specified SPI peripheral is in use
mbed_official 107:414e9c822e99 338 *
mbed_official 107:414e9c822e99 339 * @param[in] obj The SPI peripheral to check
mbed_official 107:414e9c822e99 340 * @return non-zero if the peripheral is currently transmitting
mbed_official 107:414e9c822e99 341 */
mbed_official 107:414e9c822e99 342 int spi_busy(spi_t *obj)
mbed_official 107:414e9c822e99 343 {
mbed_official 107:414e9c822e99 344 if(obj->spi.spi_base->SPI_SR & SPI_SR_TDRE) //Transmit Data Register Empty
mbed_official 107:414e9c822e99 345 return 0;
mbed_official 107:414e9c822e99 346 return 1;
mbed_official 107:414e9c822e99 347 }
mbed_official 107:414e9c822e99 348
mbed_official 107:414e9c822e99 349 /** Get the module number
mbed_official 107:414e9c822e99 350 *
mbed_official 107:414e9c822e99 351 * @param[in] obj The SPI peripheral to check
mbed_official 107:414e9c822e99 352 * @return The module number
mbed_official 107:414e9c822e99 353 */
mbed_official 107:414e9c822e99 354 uint8_t spi_get_module(spi_t *obj)
mbed_official 107:414e9c822e99 355 {
mbed_official 107:414e9c822e99 356 return obj->spi.module_number;
mbed_official 107:414e9c822e99 357 }
mbed_official 107:414e9c822e99 358
mbed_official 107:414e9c822e99 359
mbed_official 107:414e9c822e99 360 /**@}*/
mbed_official 107:414e9c822e99 361 #if DEVICE_SPI_ASYNCH
mbed_official 107:414e9c822e99 362 /**
mbed_official 107:414e9c822e99 363 * \defgroup AsynchSPI Asynchronous SPI Hardware Abstraction Layer
mbed_official 107:414e9c822e99 364 * @{
mbed_official 107:414e9c822e99 365 */
mbed_official 107:414e9c822e99 366
mbed_official 107:414e9c822e99 367 /** Begin the SPI transfer. Buffer pointers and lengths are specified in tx_buff and rx_buff
mbed_official 107:414e9c822e99 368 *
mbed_official 107:414e9c822e99 369 * @param[in] obj The SPI object which holds the transfer information
mbed_official 107:414e9c822e99 370 * @param[in] tx The buffer to send
mbed_official 107:414e9c822e99 371 * @param[in] tx_length The number of words to transmit
mbed_official 107:414e9c822e99 372 * @param[in] rx The buffer to receive
mbed_official 107:414e9c822e99 373 * @param[in] rx_length The number of words to receive
mbed_official 107:414e9c822e99 374 * @param[in] bit_width The bit width of buffer words
mbed_official 107:414e9c822e99 375 * @param[in] event The logical OR of events to be registered
mbed_official 107:414e9c822e99 376 * @param[in] handler SPI interrupt handler
mbed_official 107:414e9c822e99 377 * @param[in] hint A suggestion for how to use DMA with this transfer
mbed_official 107:414e9c822e99 378 */
mbed_official 107:414e9c822e99 379 #warning "Only DMA async supported by SPI master transfer"
mbed_official 107:414e9c822e99 380
mbed_official 107:414e9c822e99 381 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 382 {
mbed_official 107:414e9c822e99 383 uint32_t pdcenable=0;
mbed_official 107:414e9c822e99 384
mbed_official 107:414e9c822e99 385 if(bit_width) {
mbed_official 107:414e9c822e99 386 uint32_t transferrate= get_transfer_rate(bit_width);
mbed_official 107:414e9c822e99 387 spi_set_bits_per_transfer(obj->spi.spi_base, obj->spi.cs, transferrate);
mbed_official 107:414e9c822e99 388 }
mbed_official 107:414e9c822e99 389
mbed_official 107:414e9c822e99 390 if(tx) {
mbed_official 107:414e9c822e99 391 pdc_packet_t pdc_packet_tx;
mbed_official 107:414e9c822e99 392 pdc_packet_tx.ul_addr=(uint32_t)tx;
mbed_official 107:414e9c822e99 393 pdc_packet_tx.ul_size=tx_length;
mbed_official 107:414e9c822e99 394
mbed_official 107:414e9c822e99 395 pdcenable|=PERIPH_PTCR_TXTEN;
mbed_official 107:414e9c822e99 396 /* Configure PDC for data send */
mbed_official 107:414e9c822e99 397 pdc_tx_init(obj->spi.pdc, &pdc_packet_tx, NULL);
mbed_official 107:414e9c822e99 398 }
mbed_official 107:414e9c822e99 399
mbed_official 107:414e9c822e99 400 if(rx) {
mbed_official 107:414e9c822e99 401 pdc_rx_clear_cnt(obj->spi.pdc);
mbed_official 107:414e9c822e99 402 pdc_packet_t pdc_packet_rx;
mbed_official 107:414e9c822e99 403 pdc_packet_rx.ul_addr=(uint32_t)rx;
mbed_official 107:414e9c822e99 404 pdc_packet_rx.ul_size=rx_length;
mbed_official 107:414e9c822e99 405 pdcenable|=PERIPH_PTCR_RXTEN;
mbed_official 107:414e9c822e99 406 char *rxbuffer=(char *)rx;
mbed_official 107:414e9c822e99 407 for(uint8_t index=0; index<rx_length; index++, rxbuffer++)
mbed_official 107:414e9c822e99 408 *rxbuffer=SPI_FILL_WORD;
mbed_official 107:414e9c822e99 409
mbed_official 107:414e9c822e99 410 /* Configure PDC for data receive */
mbed_official 107:414e9c822e99 411 pdc_rx_init(obj->spi.pdc, &pdc_packet_rx, NULL);
mbed_official 107:414e9c822e99 412 }
mbed_official 107:414e9c822e99 413
mbed_official 107:414e9c822e99 414 obj->spi.dma_usage=hint;
mbed_official 107:414e9c822e99 415 obj->spi.event=event;
mbed_official 107:414e9c822e99 416
mbed_official 107:414e9c822e99 417 NVIC_ClearPendingIRQ(obj->spi.irq_type);
mbed_official 107:414e9c822e99 418 NVIC_DisableIRQ(obj->spi.irq_type);
mbed_official 107:414e9c822e99 419 NVIC_SetVector(obj->spi.irq_type,handler);
mbed_official 107:414e9c822e99 420 NVIC_EnableIRQ(obj->spi.irq_type);
mbed_official 107:414e9c822e99 421
mbed_official 107:414e9c822e99 422 /* Enable SPI IRQ */
mbed_official 107:414e9c822e99 423 spi_enable_interrupt(obj->spi.spi_base, SPI_IER_RXBUFF| SPI_IER_TXBUFE | SPI_IER_MODF | SPI_IER_OVRES);
mbed_official 107:414e9c822e99 424
mbed_official 107:414e9c822e99 425 /* Enable PDC transfers */
mbed_official 107:414e9c822e99 426 pdc_enable_transfer(obj->spi.pdc, pdcenable );
mbed_official 107:414e9c822e99 427
mbed_official 107:414e9c822e99 428 }
mbed_official 107:414e9c822e99 429
mbed_official 107:414e9c822e99 430 /** The asynchronous IRQ handler
mbed_official 107:414e9c822e99 431 *
mbed_official 107:414e9c822e99 432 * Reads the received values out of the RX FIFO, writes values into the TX FIFO and checks for transfer termination
mbed_official 107:414e9c822e99 433 * conditions, such as buffer overflows or transfer complete.
mbed_official 107:414e9c822e99 434 * @param[in] obj The SPI object which holds the transfer information
mbed_official 107:414e9c822e99 435 * @return event flags if a transfer termination condition was met or 0 otherwise.
mbed_official 107:414e9c822e99 436 */
mbed_official 107:414e9c822e99 437 uint32_t spi_irq_handler_asynch(spi_t *obj)
mbed_official 107:414e9c822e99 438 {
mbed_official 107:414e9c822e99 439 uint32_t event=0;
mbed_official 107:414e9c822e99 440
mbed_official 107:414e9c822e99 441 // Data transferred via DMA
mbed_official 107:414e9c822e99 442 if((obj->spi.spi_base->SPI_SR & SPI_IER_TXBUFE)) {
mbed_official 107:414e9c822e99 443 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_TXBUFE | SPI_IDR_MODF | SPI_IDR_OVRES);
mbed_official 107:414e9c822e99 444 if(obj->spi.event | SPI_EVENT_COMPLETE)
mbed_official 107:414e9c822e99 445 event |=SPI_EVENT_COMPLETE;
mbed_official 107:414e9c822e99 446 }
mbed_official 107:414e9c822e99 447
mbed_official 107:414e9c822e99 448 if((obj->spi.spi_base->SPI_SR & SPI_IER_RXBUFF)) {
mbed_official 107:414e9c822e99 449 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_RXBUFF | SPI_IDR_MODF | SPI_IDR_OVRES);
mbed_official 107:414e9c822e99 450 if(obj->spi.event | SPI_EVENT_COMPLETE)
mbed_official 107:414e9c822e99 451 event |=SPI_EVENT_COMPLETE;
mbed_official 107:414e9c822e99 452 }
mbed_official 107:414e9c822e99 453
mbed_official 107:414e9c822e99 454 if(obj->spi.spi_base->SPI_SR & SPI_SR_MODF) {
mbed_official 107:414e9c822e99 455 if(obj->spi.event | SPI_EVENT_ERROR)
mbed_official 107:414e9c822e99 456 event |=SPI_EVENT_ERROR;
mbed_official 107:414e9c822e99 457 }
mbed_official 107:414e9c822e99 458
mbed_official 107:414e9c822e99 459 if(obj->spi.spi_base->SPI_SR & SPI_SR_OVRES) {
mbed_official 107:414e9c822e99 460 if(obj->spi.event | SPI_EVENT_RX_OVERFLOW)
mbed_official 107:414e9c822e99 461 event |=SPI_EVENT_RX_OVERFLOW;
mbed_official 107:414e9c822e99 462 }
mbed_official 107:414e9c822e99 463
mbed_official 107:414e9c822e99 464 return event;
mbed_official 107:414e9c822e99 465 }
mbed_official 107:414e9c822e99 466
mbed_official 107:414e9c822e99 467 /** Attempts to determine if the SPI peripheral is already in use.
mbed_official 107:414e9c822e99 468 *
mbed_official 107:414e9c822e99 469 * If a temporary DMA channel has been allocated, peripheral is in use.
mbed_official 107:414e9c822e99 470 * 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 471 * channel were allocated.
mbed_official 107:414e9c822e99 472 * If no DMA channel is allocated, check whether tx and rx buffers have been assigned. For each assigned buffer, check
mbed_official 107:414e9c822e99 473 * if the corresponding buffer position is less than the buffer length. If buffers do not indicate activity, check if
mbed_official 107:414e9c822e99 474 * there are any bytes in the FIFOs.
mbed_official 107:414e9c822e99 475 * @param[in] obj The SPI object to check for activity
mbed_official 107:414e9c822e99 476 * @return non-zero if the SPI port is active or zero if it is not.
mbed_official 107:414e9c822e99 477 */
mbed_official 107:414e9c822e99 478
mbed_official 107:414e9c822e99 479 uint8_t spi_active(spi_t *obj)
mbed_official 107:414e9c822e99 480 {
mbed_official 107:414e9c822e99 481 if(obj->spi.spi_base->SPI_SR & SPI_SR_ENDTX && obj->spi.spi_base->SPI_SR & SPI_SR_ENDRX)
mbed_official 107:414e9c822e99 482 return 0;
mbed_official 107:414e9c822e99 483 return 1;
mbed_official 107:414e9c822e99 484 }
mbed_official 107:414e9c822e99 485
mbed_official 107:414e9c822e99 486 /** Abort an SPI transfer
mbed_official 107:414e9c822e99 487 *
mbed_official 107:414e9c822e99 488 * @param obj The SPI peripheral to stop
mbed_official 107:414e9c822e99 489 */
mbed_official 107:414e9c822e99 490 void spi_abort_asynch(spi_t *obj)
mbed_official 107:414e9c822e99 491 {
mbed_official 107:414e9c822e99 492 /* Disable PDC transfers */
mbed_official 107:414e9c822e99 493 pdc_disable_transfer(obj->spi.pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
mbed_official 107:414e9c822e99 494
mbed_official 107:414e9c822e99 495 /* Clear PDC buffer receive counter */
mbed_official 107:414e9c822e99 496 pdc_rx_clear_cnt(obj->spi.pdc);
mbed_official 107:414e9c822e99 497
mbed_official 107:414e9c822e99 498 /* Disable SPI IRQ */
mbed_official 107:414e9c822e99 499 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_TXBUFE);
mbed_official 107:414e9c822e99 500 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_RXBUFF);
mbed_official 107:414e9c822e99 501
mbed_official 107:414e9c822e99 502 /* Disable SPI interrupt */
mbed_official 107:414e9c822e99 503 NVIC_DisableIRQ(obj->spi.irq_type);
mbed_official 107:414e9c822e99 504 }
mbed_official 107:414e9c822e99 505
mbed_official 107:414e9c822e99 506 #endif