mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Fri Sep 11 09:30:09 2015 +0100
Revision:
621:9c82b0f79f3d
Parent:
554:edd95c0879f8
Synchronized with git revision 6c1d63e069ab9bd86de92e8296ca783681257538

Full URL: https://github.com/mbedmicro/mbed/commit/6c1d63e069ab9bd86de92e8296ca783681257538/

ignore target files not supported by the yotta module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 554:edd95c0879f8 1 /* mbed Microcontroller Library
mbed_official 554:edd95c0879f8 2 * Copyright (c) 2006-2015 ARM Limited
mbed_official 554:edd95c0879f8 3 *
mbed_official 554:edd95c0879f8 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 554:edd95c0879f8 5 * you may not use this file except in compliance with the License.
mbed_official 554:edd95c0879f8 6 * You may obtain a copy of the License at
mbed_official 554:edd95c0879f8 7 *
mbed_official 554:edd95c0879f8 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 554:edd95c0879f8 9 *
mbed_official 554:edd95c0879f8 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 554:edd95c0879f8 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 554:edd95c0879f8 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 554:edd95c0879f8 13 * See the License for the specific language governing permissions and
mbed_official 554:edd95c0879f8 14 * limitations under the License.
mbed_official 554:edd95c0879f8 15 */
mbed_official 554:edd95c0879f8 16 #include "mbed_assert.h"
mbed_official 554:edd95c0879f8 17 #include <math.h>
mbed_official 554:edd95c0879f8 18
mbed_official 554:edd95c0879f8 19 #include "spi_api.h"
mbed_official 554:edd95c0879f8 20 #include "cmsis.h"
mbed_official 554:edd95c0879f8 21 #include "pinmap.h"
mbed_official 554:edd95c0879f8 22 #include "mbed_error.h"
mbed_official 554:edd95c0879f8 23
mbed_official 554:edd95c0879f8 24 static const PinMap PinMap_SPI_SCLK[] = {
mbed_official 554:edd95c0879f8 25 {P0_7 , SPI_1, 2},
mbed_official 554:edd95c0879f8 26 {P0_15, SPI_0, 2},
mbed_official 554:edd95c0879f8 27 {P1_20, SPI_0, 3},
mbed_official 554:edd95c0879f8 28 {P1_31, SPI_1, 2},
mbed_official 554:edd95c0879f8 29 {NC , NC , 0}
mbed_official 554:edd95c0879f8 30 };
mbed_official 554:edd95c0879f8 31
mbed_official 554:edd95c0879f8 32 static const PinMap PinMap_SPI_MOSI[] = {
mbed_official 554:edd95c0879f8 33 {P0_9 , SPI_1, 2},
mbed_official 554:edd95c0879f8 34 {P0_13, SPI_1, 2},
mbed_official 554:edd95c0879f8 35 {P0_18, SPI_0, 2},
mbed_official 554:edd95c0879f8 36 {P1_24, SPI_0, 3},
mbed_official 554:edd95c0879f8 37 {NC , NC , 0}
mbed_official 554:edd95c0879f8 38 };
mbed_official 554:edd95c0879f8 39
mbed_official 554:edd95c0879f8 40 static const PinMap PinMap_SPI_MISO[] = {
mbed_official 554:edd95c0879f8 41 {P0_8 , SPI_1, 2},
mbed_official 554:edd95c0879f8 42 {P0_12, SPI_1, 2},
mbed_official 554:edd95c0879f8 43 {P0_17, SPI_0, 2},
mbed_official 554:edd95c0879f8 44 {P1_23, SPI_0, 3},
mbed_official 554:edd95c0879f8 45 {NC , NC , 0}
mbed_official 554:edd95c0879f8 46 };
mbed_official 554:edd95c0879f8 47
mbed_official 554:edd95c0879f8 48 static const PinMap PinMap_SPI_SSEL[] = {
mbed_official 554:edd95c0879f8 49 {P0_6 , SPI_1, 2},
mbed_official 554:edd95c0879f8 50 {P0_14, SPI_1, 3},
mbed_official 554:edd95c0879f8 51 {P0_16, SPI_0, 2},
mbed_official 554:edd95c0879f8 52 {P1_21, SPI_0, 3},
mbed_official 554:edd95c0879f8 53 {NC , NC , 0}
mbed_official 554:edd95c0879f8 54 };
mbed_official 554:edd95c0879f8 55
mbed_official 554:edd95c0879f8 56 static inline int ssp_disable(spi_t *obj);
mbed_official 554:edd95c0879f8 57 static inline int ssp_enable(spi_t *obj);
mbed_official 554:edd95c0879f8 58
mbed_official 554:edd95c0879f8 59 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
mbed_official 554:edd95c0879f8 60 // determine the SPI to use
mbed_official 554:edd95c0879f8 61 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
mbed_official 554:edd95c0879f8 62 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
mbed_official 554:edd95c0879f8 63 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
mbed_official 554:edd95c0879f8 64 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
mbed_official 554:edd95c0879f8 65 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
mbed_official 554:edd95c0879f8 66 SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
mbed_official 554:edd95c0879f8 67 obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl);
mbed_official 554:edd95c0879f8 68 MBED_ASSERT((int)obj->spi != NC);
mbed_official 554:edd95c0879f8 69
mbed_official 554:edd95c0879f8 70 // enable power and clocking
mbed_official 554:edd95c0879f8 71 switch ((int)obj->spi) {
mbed_official 554:edd95c0879f8 72 case SPI_0: LPC_SC->PCONP |= 1 << PCSSP0; break;
mbed_official 554:edd95c0879f8 73 case SPI_1: LPC_SC->PCONP |= 1 << PCSSP1; break;
mbed_official 554:edd95c0879f8 74 }
mbed_official 554:edd95c0879f8 75
mbed_official 554:edd95c0879f8 76 // set default format and frequency
mbed_official 554:edd95c0879f8 77 if (ssel == NC) {
mbed_official 554:edd95c0879f8 78 spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
mbed_official 554:edd95c0879f8 79 } else {
mbed_official 554:edd95c0879f8 80 spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
mbed_official 554:edd95c0879f8 81 }
mbed_official 554:edd95c0879f8 82 spi_frequency(obj, 1000000);
mbed_official 554:edd95c0879f8 83
mbed_official 554:edd95c0879f8 84 // enable the ssp channel
mbed_official 554:edd95c0879f8 85 ssp_enable(obj);
mbed_official 554:edd95c0879f8 86
mbed_official 554:edd95c0879f8 87 // pin out the spi pins
mbed_official 554:edd95c0879f8 88 pinmap_pinout(mosi, PinMap_SPI_MOSI);
mbed_official 554:edd95c0879f8 89 pinmap_pinout(miso, PinMap_SPI_MISO);
mbed_official 554:edd95c0879f8 90 pinmap_pinout(sclk, PinMap_SPI_SCLK);
mbed_official 554:edd95c0879f8 91 if (ssel != NC) {
mbed_official 554:edd95c0879f8 92 pinmap_pinout(ssel, PinMap_SPI_SSEL);
mbed_official 554:edd95c0879f8 93 }
mbed_official 554:edd95c0879f8 94 }
mbed_official 554:edd95c0879f8 95
mbed_official 554:edd95c0879f8 96 void spi_free(spi_t *obj) {}
mbed_official 554:edd95c0879f8 97
mbed_official 554:edd95c0879f8 98 void spi_format(spi_t *obj, int bits, int mode, int slave) {
mbed_official 554:edd95c0879f8 99 MBED_ASSERT(((bits >= 4) && (bits <= 16)) && ((mode >= 0) && (mode <= 3)));
mbed_official 554:edd95c0879f8 100 ssp_disable(obj);
mbed_official 554:edd95c0879f8 101
mbed_official 554:edd95c0879f8 102 int polarity = (mode & 0x2) ? 1 : 0;
mbed_official 554:edd95c0879f8 103 int phase = (mode & 0x1) ? 1 : 0;
mbed_official 554:edd95c0879f8 104
mbed_official 554:edd95c0879f8 105 // set it up
mbed_official 554:edd95c0879f8 106 int DSS = bits - 1; // DSS (data select size)
mbed_official 554:edd95c0879f8 107 int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity
mbed_official 554:edd95c0879f8 108 int SPH = (phase) ? 1 : 0; // SPH - clock out phase
mbed_official 554:edd95c0879f8 109
mbed_official 554:edd95c0879f8 110 int FRF = 0; // FRF (frame format) = SPI
mbed_official 554:edd95c0879f8 111 uint32_t tmp = obj->spi->CR0;
mbed_official 554:edd95c0879f8 112 tmp &= ~(0xFFFF);
mbed_official 554:edd95c0879f8 113 tmp |= DSS << 0
mbed_official 554:edd95c0879f8 114 | FRF << 4
mbed_official 554:edd95c0879f8 115 | SPO << 6
mbed_official 554:edd95c0879f8 116 | SPH << 7;
mbed_official 554:edd95c0879f8 117 obj->spi->CR0 = tmp;
mbed_official 554:edd95c0879f8 118
mbed_official 554:edd95c0879f8 119 tmp = obj->spi->CR1;
mbed_official 554:edd95c0879f8 120 tmp &= ~(0xD);
mbed_official 554:edd95c0879f8 121 tmp |= 0 << 0 // LBM - loop back mode - off
mbed_official 554:edd95c0879f8 122 | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave
mbed_official 554:edd95c0879f8 123 | 0 << 3; // SOD - slave output disable - na
mbed_official 554:edd95c0879f8 124 obj->spi->CR1 = tmp;
mbed_official 554:edd95c0879f8 125
mbed_official 554:edd95c0879f8 126 ssp_enable(obj);
mbed_official 554:edd95c0879f8 127 }
mbed_official 554:edd95c0879f8 128
mbed_official 554:edd95c0879f8 129 void spi_frequency(spi_t *obj, int hz) {
mbed_official 554:edd95c0879f8 130 ssp_disable(obj);
mbed_official 554:edd95c0879f8 131
mbed_official 554:edd95c0879f8 132 // setup the spi clock diveder to /1
mbed_official 554:edd95c0879f8 133 switch ((int)obj->spi) {
mbed_official 554:edd95c0879f8 134 case SPI_0:
mbed_official 554:edd95c0879f8 135 LPC_SC->PCLKSEL1 &= ~(3 << 10);
mbed_official 554:edd95c0879f8 136 LPC_SC->PCLKSEL1 |= (1 << 10);
mbed_official 554:edd95c0879f8 137 break;
mbed_official 554:edd95c0879f8 138 case SPI_1:
mbed_official 554:edd95c0879f8 139 LPC_SC->PCLKSEL0 &= ~(3 << 20);
mbed_official 554:edd95c0879f8 140 LPC_SC->PCLKSEL0 |= (1 << 20);
mbed_official 554:edd95c0879f8 141 break;
mbed_official 554:edd95c0879f8 142 }
mbed_official 554:edd95c0879f8 143
mbed_official 554:edd95c0879f8 144 uint32_t PCLK = SystemCoreClock;
mbed_official 554:edd95c0879f8 145
mbed_official 554:edd95c0879f8 146 int prescaler;
mbed_official 554:edd95c0879f8 147
mbed_official 554:edd95c0879f8 148 for (prescaler = 2; prescaler <= 254; prescaler += 2) {
mbed_official 554:edd95c0879f8 149 int prescale_hz = PCLK / prescaler;
mbed_official 554:edd95c0879f8 150
mbed_official 554:edd95c0879f8 151 // calculate the divider
mbed_official 554:edd95c0879f8 152 int divider = floor(((float)prescale_hz / (float)hz) + 0.5f);
mbed_official 554:edd95c0879f8 153
mbed_official 554:edd95c0879f8 154 // check we can support the divider
mbed_official 554:edd95c0879f8 155 if (divider < 256) {
mbed_official 554:edd95c0879f8 156 // prescaler
mbed_official 554:edd95c0879f8 157 obj->spi->CPSR = prescaler;
mbed_official 554:edd95c0879f8 158
mbed_official 554:edd95c0879f8 159 // divider
mbed_official 554:edd95c0879f8 160 obj->spi->CR0 &= ~(0xFFFF << 8);
mbed_official 554:edd95c0879f8 161 obj->spi->CR0 |= (divider - 1) << 8;
mbed_official 554:edd95c0879f8 162 ssp_enable(obj);
mbed_official 554:edd95c0879f8 163 return;
mbed_official 554:edd95c0879f8 164 }
mbed_official 554:edd95c0879f8 165 }
mbed_official 554:edd95c0879f8 166 error("Couldn't setup requested SPI frequency");
mbed_official 554:edd95c0879f8 167 }
mbed_official 554:edd95c0879f8 168
mbed_official 554:edd95c0879f8 169 static inline int ssp_disable(spi_t *obj) {
mbed_official 554:edd95c0879f8 170 return obj->spi->CR1 &= ~(1 << 1);
mbed_official 554:edd95c0879f8 171 }
mbed_official 554:edd95c0879f8 172
mbed_official 554:edd95c0879f8 173 static inline int ssp_enable(spi_t *obj) {
mbed_official 554:edd95c0879f8 174 return obj->spi->CR1 |= (1 << 1);
mbed_official 554:edd95c0879f8 175 }
mbed_official 554:edd95c0879f8 176
mbed_official 554:edd95c0879f8 177 static inline int ssp_readable(spi_t *obj) {
mbed_official 554:edd95c0879f8 178 return obj->spi->SR & (1 << 2);
mbed_official 554:edd95c0879f8 179 }
mbed_official 554:edd95c0879f8 180
mbed_official 554:edd95c0879f8 181 static inline int ssp_writeable(spi_t *obj) {
mbed_official 554:edd95c0879f8 182 return obj->spi->SR & (1 << 1);
mbed_official 554:edd95c0879f8 183 }
mbed_official 554:edd95c0879f8 184
mbed_official 554:edd95c0879f8 185 static inline void ssp_write(spi_t *obj, int value) {
mbed_official 554:edd95c0879f8 186 while (!ssp_writeable(obj));
mbed_official 554:edd95c0879f8 187 obj->spi->DR = value;
mbed_official 554:edd95c0879f8 188 }
mbed_official 554:edd95c0879f8 189
mbed_official 554:edd95c0879f8 190 static inline int ssp_read(spi_t *obj) {
mbed_official 554:edd95c0879f8 191 while (!ssp_readable(obj));
mbed_official 554:edd95c0879f8 192 return obj->spi->DR;
mbed_official 554:edd95c0879f8 193 }
mbed_official 554:edd95c0879f8 194
mbed_official 554:edd95c0879f8 195 static inline int ssp_busy(spi_t *obj) {
mbed_official 554:edd95c0879f8 196 return (obj->spi->SR & (1 << 4)) ? (1) : (0);
mbed_official 554:edd95c0879f8 197 }
mbed_official 554:edd95c0879f8 198
mbed_official 554:edd95c0879f8 199 int spi_master_write(spi_t *obj, int value) {
mbed_official 554:edd95c0879f8 200 ssp_write(obj, value);
mbed_official 554:edd95c0879f8 201 return ssp_read(obj);
mbed_official 554:edd95c0879f8 202 }
mbed_official 554:edd95c0879f8 203
mbed_official 554:edd95c0879f8 204 int spi_slave_receive(spi_t *obj) {
mbed_official 554:edd95c0879f8 205 return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
mbed_official 554:edd95c0879f8 206 }
mbed_official 554:edd95c0879f8 207
mbed_official 554:edd95c0879f8 208 int spi_slave_read(spi_t *obj) {
mbed_official 554:edd95c0879f8 209 return obj->spi->DR;
mbed_official 554:edd95c0879f8 210 }
mbed_official 554:edd95c0879f8 211
mbed_official 554:edd95c0879f8 212 void spi_slave_write(spi_t *obj, int value) {
mbed_official 554:edd95c0879f8 213 while (ssp_writeable(obj) == 0) ;
mbed_official 554:edd95c0879f8 214 obj->spi->DR = value;
mbed_official 554:edd95c0879f8 215 }
mbed_official 554:edd95c0879f8 216
mbed_official 554:edd95c0879f8 217 int spi_busy(spi_t *obj) {
mbed_official 554:edd95c0879f8 218 return ssp_busy(obj);
mbed_official 554:edd95c0879f8 219 }