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:
Tue Feb 03 17:00:07 2015 +0000
Revision:
463:5c73c3744533
Parent:
285:31249416b6f9
Child:
552:a1b9575155a3
Synchronized with git revision 134a67aab259d410373367cb96b73420b390d385

Full URL: https://github.com/mbedmicro/mbed/commit/134a67aab259d410373367cb96b73420b390d385/

Who changed what in which revision?

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