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 Dec 16 08:15:08 2014 +0000
Revision:
440:8a0b45cd594f
Parent:
424:73631a54077f
Child:
552:a1b9575155a3
Synchronized with git revision 67fbbf0b635d0c0d93fbe433306c537c2ad206aa

Full URL: https://github.com/mbedmicro/mbed/commit/67fbbf0b635d0c0d93fbe433306c537c2ad206aa/

Targets: nrf51 - updating app_timer.c from Norid'c SDKv7.1.0

Who changed what in which revision?

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