added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Tue Apr 05 18:15:12 2016 +0100
Revision:
107:414e9c822e99
Synchronized with git revision dd3c5f7fa8473776950ec6e15c0e4adedb21cf2f

Full URL: https://github.com/mbedmicro/mbed/commit/dd3c5f7fa8473776950ec6e15c0e4adedb21cf2f/

* * Base Commit for SAMG55J19. No errors and no implementations.

* * Added gpio files.

* * Added pinmap files.

* * Base commit for usticker implementation.

* * Added gcc_arm export functionality

* * added files for usticker.
* added template file for samd55j19

* * GPIO IRQ base commit.

* * updated with changes in gpio irq driver.

* * Reverted back unexpected commit in SAM0 gpio driver.

* * updated gpio_irq driver.

* * correction in gpio and gpio_irq drivers.
* added support for some test for gpio.

* * base commit for peripheralpins for usart.
* update in serial apis.

* * updated serial apis.

* * updated serial apis and test.

* * update serial apis for asynch apis.

* * updated peripheral pins for i2c and spi.
* added test support for serial flow control

* * Base commit for low power ticker implementation.

* * base commit for port apis.
* update in lp ticker apis.

* * Added test support for port.

* * base commit for sleep apis.

* * Base commit for spi.

* * updated with corrections in gpio irq.
* usticker file updated with latest source.

* * updated with corrections for unexpected board reset.
* updated gpio irq apis and added test for the same.

* * updated sleep api for deepsleep.

* * updated serial apis.

* Added uc_ticker and SPI api implementations

* Removed unused SPI pin map

* Updated review feedback

* * implemented lpticker with TC module.
* updated files for KnR Coding Statndard.
* updated serial and usticker apis.

* * Base commit for AnalogueIn apis.

* * RTC apis base commit without implementation.

* * Updated with corrections in lpticker implementations.

* * Added implementation for rtc apis.

* * updated with implementations for pwm.
* changed usticker from TC0 to TC1.

* Added I2C support

* * removed setvector usage from usticker and lpticker implementations
* added tests for SAMG55J19

* * Removed unwanted .o and .d files.
* Updated I2C files for KnR Coding Standards.
* Update for reducing compiler warnings in peripheralpins,c
* Updated with PWM free implementation.

* * Removed unwanted headers file inclusion.
* Compiler warning corrections in serial_api.c

* * Updated ADC with 16 bit mode initialization and code refinements.
* Updated PWM with code refinements.

* Updated I2C review feedback and fixed style

* Updated target name for SAMG55

* * Added Test Support for I2C with AT30TSE75X and Added Support for SAMG55J19 in atmelstudio project exporter

* * Added Test Support for I2C with AT30TSE75X and Added Support for SAMG55J19 in atmelstudio project exporter

* Used NVIC_SetVector for interrupt callback

* Removed Target macro define in test

* Updated test cases to have SAMG55 support

* * Updated with corrections in Serial and SPI asynchronous implementations.
* Updated deepsleep api implementation
* Merged LP_Ticker with latest code from mbed 3.0 repository.

* * updated with corrections in I2C Asynch implementation.

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