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:
Wed May 27 13:30:08 2015 +0100
Revision:
552:a1b9575155a3
Parent:
285:31249416b6f9
Synchronized with git revision a74a8f14fd8c4bf3dc09980c4bf9498ebcf4c207

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 103:9b881da47c92 1 /* mbed Microcontroller Library
mbed_official 103:9b881da47c92 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 103:9b881da47c92 3 *
mbed_official 103:9b881da47c92 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 103:9b881da47c92 5 * you may not use this file except in compliance with the License.
mbed_official 103:9b881da47c92 6 * You may obtain a copy of the License at
mbed_official 103:9b881da47c92 7 *
mbed_official 103:9b881da47c92 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 103:9b881da47c92 9 *
mbed_official 103:9b881da47c92 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 103:9b881da47c92 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 103:9b881da47c92 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 103:9b881da47c92 13 * See the License for the specific language governing permissions and
mbed_official 103:9b881da47c92 14 * limitations under the License.
mbed_official 103:9b881da47c92 15 */
mbed_official 227:7bd0639b8911 16 #include "mbed_assert.h"
mbed_official 103:9b881da47c92 17 #include <math.h>
mbed_official 103:9b881da47c92 18
mbed_official 103:9b881da47c92 19 #include "spi_api.h"
mbed_official 103:9b881da47c92 20 #include "cmsis.h"
mbed_official 103:9b881da47c92 21 #include "pinmap.h"
mbed_official 285:31249416b6f9 22 #include "mbed_error.h"
mbed_official 103:9b881da47c92 23
mbed_official 103:9b881da47c92 24 static const SWM_Map SWM_SPI_SSEL[] = {
mbed_official 103:9b881da47c92 25 {4, 0},
mbed_official 103:9b881da47c92 26 {5, 24},
mbed_official 103:9b881da47c92 27 };
mbed_official 103:9b881da47c92 28
mbed_official 103:9b881da47c92 29 static const SWM_Map SWM_SPI_SCLK[] = {
mbed_official 103:9b881da47c92 30 {3, 8},
mbed_official 103:9b881da47c92 31 {5, 0},
mbed_official 103:9b881da47c92 32 };
mbed_official 103:9b881da47c92 33
mbed_official 103:9b881da47c92 34 static const SWM_Map SWM_SPI_MOSI[] = {
mbed_official 103:9b881da47c92 35 {3, 16},
mbed_official 103:9b881da47c92 36 {5, 8},
mbed_official 103:9b881da47c92 37 };
mbed_official 103:9b881da47c92 38
mbed_official 103:9b881da47c92 39 static const SWM_Map SWM_SPI_MISO[] = {
mbed_official 103:9b881da47c92 40 {3, 24},
mbed_official 103:9b881da47c92 41 {5, 16},
mbed_official 103:9b881da47c92 42 };
mbed_official 103:9b881da47c92 43
mbed_official 103:9b881da47c92 44 // bit flags for used SPIs
mbed_official 103:9b881da47c92 45 static unsigned char spi_used = 0;
mbed_official 266:69e8a32876bd 46 static int get_available_spi(PinName mosi, PinName miso, PinName sclk, PinName ssel)
mbed_official 261:ee1cf08b7bc7 47 {
mbed_official 266:69e8a32876bd 48 if (spi_used == 0) {
mbed_official 266:69e8a32876bd 49 return 0; // The first user
mbed_official 103:9b881da47c92 50 }
mbed_official 266:69e8a32876bd 51
mbed_official 266:69e8a32876bd 52 const SWM_Map *swm;
mbed_official 266:69e8a32876bd 53 uint32_t regVal;
mbed_official 266:69e8a32876bd 54
mbed_official 266:69e8a32876bd 55 // Investigate if same pins as the used SPI0/1 - to be able to reuse it
mbed_official 266:69e8a32876bd 56 for (int spi_n = 0; spi_n < 2; spi_n++) {
mbed_official 266:69e8a32876bd 57 if (spi_used & (1<<spi_n)) {
mbed_official 266:69e8a32876bd 58 if (sclk != NC) {
mbed_official 266:69e8a32876bd 59 swm = &SWM_SPI_SCLK[spi_n];
mbed_official 266:69e8a32876bd 60 regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset);
mbed_official 266:69e8a32876bd 61 if (regVal != (sclk << swm->offset)) {
mbed_official 266:69e8a32876bd 62 // Existing pin is not the same as the one we want
mbed_official 266:69e8a32876bd 63 continue;
mbed_official 266:69e8a32876bd 64 }
mbed_official 266:69e8a32876bd 65 }
mbed_official 266:69e8a32876bd 66
mbed_official 266:69e8a32876bd 67 if (mosi != NC) {
mbed_official 266:69e8a32876bd 68 swm = &SWM_SPI_MOSI[spi_n];
mbed_official 266:69e8a32876bd 69 regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset);
mbed_official 266:69e8a32876bd 70 if (regVal != (mosi << swm->offset)) {
mbed_official 266:69e8a32876bd 71 // Existing pin is not the same as the one we want
mbed_official 266:69e8a32876bd 72 continue;
mbed_official 266:69e8a32876bd 73 }
mbed_official 266:69e8a32876bd 74 }
mbed_official 266:69e8a32876bd 75
mbed_official 266:69e8a32876bd 76 if (miso != NC) {
mbed_official 266:69e8a32876bd 77 swm = &SWM_SPI_MISO[spi_n];
mbed_official 266:69e8a32876bd 78 regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset);
mbed_official 266:69e8a32876bd 79 if (regVal != (miso << swm->offset)) {
mbed_official 266:69e8a32876bd 80 // Existing pin is not the same as the one we want
mbed_official 266:69e8a32876bd 81 continue;
mbed_official 266:69e8a32876bd 82 }
mbed_official 266:69e8a32876bd 83 }
mbed_official 266:69e8a32876bd 84
mbed_official 266:69e8a32876bd 85 if (ssel != NC) {
mbed_official 266:69e8a32876bd 86 swm = &SWM_SPI_SSEL[spi_n];
mbed_official 266:69e8a32876bd 87 regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset);
mbed_official 266:69e8a32876bd 88 if (regVal != (ssel << swm->offset)) {
mbed_official 266:69e8a32876bd 89 // Existing pin is not the same as the one we want
mbed_official 266:69e8a32876bd 90 continue;
mbed_official 266:69e8a32876bd 91 }
mbed_official 266:69e8a32876bd 92 }
mbed_official 266:69e8a32876bd 93
mbed_official 266:69e8a32876bd 94 // The pins for the currently used SPIx are the same as the
mbed_official 266:69e8a32876bd 95 // ones we want so we will reuse it
mbed_official 266:69e8a32876bd 96 return spi_n;
mbed_official 266:69e8a32876bd 97 }
mbed_official 266:69e8a32876bd 98 }
mbed_official 266:69e8a32876bd 99
mbed_official 266:69e8a32876bd 100 // None of the existing SPIx pin setups match the pins we want
mbed_official 266:69e8a32876bd 101 // so the last hope is to select one unused SPIx
mbed_official 266:69e8a32876bd 102 if ((spi_used & 1) == 0) {
mbed_official 266:69e8a32876bd 103 return 0;
mbed_official 266:69e8a32876bd 104 } else if ((spi_used & 2) == 0) {
mbed_official 266:69e8a32876bd 105 return 1;
mbed_official 266:69e8a32876bd 106 }
mbed_official 266:69e8a32876bd 107
mbed_official 266:69e8a32876bd 108 // No matching setup and no free SPIx
mbed_official 103:9b881da47c92 109 return -1;
mbed_official 103:9b881da47c92 110 }
mbed_official 103:9b881da47c92 111
mbed_official 103:9b881da47c92 112 static inline void spi_disable(spi_t *obj);
mbed_official 103:9b881da47c92 113 static inline void spi_enable(spi_t *obj);
mbed_official 103:9b881da47c92 114
mbed_official 261:ee1cf08b7bc7 115 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
mbed_official 261:ee1cf08b7bc7 116 {
mbed_official 266:69e8a32876bd 117 int spi_n = get_available_spi(mosi, miso, sclk, ssel);
mbed_official 103:9b881da47c92 118 if (spi_n == -1) {
mbed_official 103:9b881da47c92 119 error("No available SPI");
mbed_official 103:9b881da47c92 120 }
mbed_official 103:9b881da47c92 121
mbed_official 103:9b881da47c92 122 obj->spi_n = spi_n;
mbed_official 103:9b881da47c92 123 spi_used |= (1 << spi_n);
mbed_official 261:ee1cf08b7bc7 124
mbed_official 103:9b881da47c92 125 obj->spi = (spi_n) ? (LPC_SPI0_Type *)(LPC_SPI1_BASE) : (LPC_SPI0_Type *)(LPC_SPI0_BASE);
mbed_official 261:ee1cf08b7bc7 126
mbed_official 103:9b881da47c92 127 const SWM_Map *swm;
mbed_official 103:9b881da47c92 128 uint32_t regVal;
mbed_official 261:ee1cf08b7bc7 129
mbed_official 103:9b881da47c92 130 if (sclk != NC) {
mbed_official 103:9b881da47c92 131 swm = &SWM_SPI_SCLK[obj->spi_n];
mbed_official 103:9b881da47c92 132 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 103:9b881da47c92 133 LPC_SWM->PINASSIGN[swm->n] = regVal | (sclk << swm->offset);
mbed_official 103:9b881da47c92 134 }
mbed_official 261:ee1cf08b7bc7 135
mbed_official 103:9b881da47c92 136 if (mosi != NC) {
mbed_official 103:9b881da47c92 137 swm = &SWM_SPI_MOSI[obj->spi_n];
mbed_official 103:9b881da47c92 138 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 103:9b881da47c92 139 LPC_SWM->PINASSIGN[swm->n] = regVal | (mosi << swm->offset);
mbed_official 103:9b881da47c92 140 }
mbed_official 261:ee1cf08b7bc7 141
mbed_official 103:9b881da47c92 142 if (miso != NC) {
mbed_official 103:9b881da47c92 143 swm = &SWM_SPI_MISO[obj->spi_n];
mbed_official 103:9b881da47c92 144 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 103:9b881da47c92 145 LPC_SWM->PINASSIGN[swm->n] = regVal | (miso << swm->offset);
mbed_official 103:9b881da47c92 146 }
mbed_official 103:9b881da47c92 147
mbed_official 103:9b881da47c92 148 if (ssel != NC) {
mbed_official 103:9b881da47c92 149 swm = &SWM_SPI_SSEL[obj->spi_n];
mbed_official 103:9b881da47c92 150 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 103:9b881da47c92 151 LPC_SWM->PINASSIGN[swm->n] = regVal | (ssel << swm->offset);
mbed_official 103:9b881da47c92 152 }
mbed_official 103:9b881da47c92 153
mbed_official 103:9b881da47c92 154 // clear interrupts
mbed_official 103:9b881da47c92 155 obj->spi->INTENCLR = 0x3f;
mbed_official 103:9b881da47c92 156
mbed_official 261:ee1cf08b7bc7 157 // enable power and clocking
mbed_official 261:ee1cf08b7bc7 158 LPC_SYSCON->SYSAHBCLKCTRL1 |= (0x1 << (obj->spi_n + 9));
mbed_official 261:ee1cf08b7bc7 159 LPC_SYSCON->PRESETCTRL1 |= (0x1 << (obj->spi_n + 9));
mbed_official 261:ee1cf08b7bc7 160 LPC_SYSCON->PRESETCTRL1 &= ~(0x1 << (obj->spi_n + 9));
mbed_official 103:9b881da47c92 161 }
mbed_official 103:9b881da47c92 162
mbed_official 261:ee1cf08b7bc7 163 void spi_free(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 164 {
mbed_official 261:ee1cf08b7bc7 165 }
mbed_official 103:9b881da47c92 166
mbed_official 261:ee1cf08b7bc7 167 void spi_format(spi_t *obj, int bits, int mode, int slave)
mbed_official 261:ee1cf08b7bc7 168 {
mbed_official 103:9b881da47c92 169 spi_disable(obj);
mbed_official 227:7bd0639b8911 170 MBED_ASSERT((bits >= 1 && bits <= 16) && (mode >= 0 && mode <= 3));
mbed_official 261:ee1cf08b7bc7 171
mbed_official 103:9b881da47c92 172 int polarity = (mode & 0x2) ? 1 : 0;
mbed_official 103:9b881da47c92 173 int phase = (mode & 0x1) ? 1 : 0;
mbed_official 261:ee1cf08b7bc7 174
mbed_official 103:9b881da47c92 175 // set it up
mbed_official 103:9b881da47c92 176 int LEN = bits - 1; // LEN - Data Length
mbed_official 103:9b881da47c92 177 int CPOL = (polarity) ? 1 : 0; // CPOL - Clock Polarity select
mbed_official 103:9b881da47c92 178 int CPHA = (phase) ? 1 : 0; // CPHA - Clock Phase select
mbed_official 261:ee1cf08b7bc7 179
mbed_official 103:9b881da47c92 180 uint32_t tmp = obj->spi->CFG;
mbed_official 103:9b881da47c92 181 tmp &= ~((1 << 5) | (1 << 4) | (1 << 2));
mbed_official 103:9b881da47c92 182 tmp |= (CPOL << 5) | (CPHA << 4) | ((slave ? 0 : 1) << 2);
mbed_official 103:9b881da47c92 183 obj->spi->CFG = tmp;
mbed_official 261:ee1cf08b7bc7 184
mbed_official 103:9b881da47c92 185 // select frame length
mbed_official 266:69e8a32876bd 186 tmp = obj->spi->TXCTL;
mbed_official 103:9b881da47c92 187 tmp &= ~(0xf << 24);
mbed_official 103:9b881da47c92 188 tmp |= (LEN << 24);
mbed_official 266:69e8a32876bd 189 obj->spi->TXCTL = tmp;
mbed_official 261:ee1cf08b7bc7 190
mbed_official 103:9b881da47c92 191 spi_enable(obj);
mbed_official 103:9b881da47c92 192 }
mbed_official 103:9b881da47c92 193
mbed_official 261:ee1cf08b7bc7 194 void spi_frequency(spi_t *obj, int hz)
mbed_official 261:ee1cf08b7bc7 195 {
mbed_official 103:9b881da47c92 196 spi_disable(obj);
mbed_official 261:ee1cf08b7bc7 197
mbed_official 261:ee1cf08b7bc7 198 // rise DIV value if it cannot be divided
mbed_official 261:ee1cf08b7bc7 199 obj->spi->DIV = (SystemCoreClock + (hz - 1))/hz - 1;
mbed_official 103:9b881da47c92 200 obj->spi->DLY = 0;
mbed_official 261:ee1cf08b7bc7 201
mbed_official 103:9b881da47c92 202 spi_enable(obj);
mbed_official 103:9b881da47c92 203 }
mbed_official 103:9b881da47c92 204
mbed_official 261:ee1cf08b7bc7 205 static inline void spi_disable(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 206 {
mbed_official 103:9b881da47c92 207 obj->spi->CFG &= ~(1 << 0);
mbed_official 103:9b881da47c92 208 }
mbed_official 103:9b881da47c92 209
mbed_official 261:ee1cf08b7bc7 210 static inline void spi_enable(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 211 {
mbed_official 103:9b881da47c92 212 obj->spi->CFG |= (1 << 0);
mbed_official 103:9b881da47c92 213 }
mbed_official 103:9b881da47c92 214
mbed_official 261:ee1cf08b7bc7 215 static inline int spi_readable(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 216 {
mbed_official 103:9b881da47c92 217 return obj->spi->STAT & (1 << 0);
mbed_official 103:9b881da47c92 218 }
mbed_official 103:9b881da47c92 219
mbed_official 261:ee1cf08b7bc7 220 static inline int spi_writeable(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 221 {
mbed_official 103:9b881da47c92 222 return obj->spi->STAT & (1 << 1);
mbed_official 103:9b881da47c92 223 }
mbed_official 103:9b881da47c92 224
mbed_official 261:ee1cf08b7bc7 225 static inline void spi_write(spi_t *obj, int value)
mbed_official 261:ee1cf08b7bc7 226 {
mbed_official 103:9b881da47c92 227 while (!spi_writeable(obj));
mbed_official 103:9b881da47c92 228 // end of transfer
mbed_official 266:69e8a32876bd 229 obj->spi->TXCTL |= (1 << 20);
mbed_official 266:69e8a32876bd 230 obj->spi->TXDAT = (value & 0xffff);
mbed_official 103:9b881da47c92 231 }
mbed_official 103:9b881da47c92 232
mbed_official 261:ee1cf08b7bc7 233 static inline int spi_read(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 234 {
mbed_official 103:9b881da47c92 235 while (!spi_readable(obj));
mbed_official 266:69e8a32876bd 236 return obj->spi->RXDAT & 0xffff; // Only the lower 16 bits contain data
mbed_official 103:9b881da47c92 237 }
mbed_official 103:9b881da47c92 238
mbed_official 261:ee1cf08b7bc7 239 int spi_busy(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 240 {
mbed_official 103:9b881da47c92 241 // checking RXOV(Receiver Overrun interrupt flag)
mbed_official 103:9b881da47c92 242 return obj->spi->STAT & (1 << 2);
mbed_official 261:ee1cf08b7bc7 243 }
mbed_official 103:9b881da47c92 244
mbed_official 261:ee1cf08b7bc7 245 int spi_master_write(spi_t *obj, int value)
mbed_official 261:ee1cf08b7bc7 246 {
mbed_official 103:9b881da47c92 247 spi_write(obj, value);
mbed_official 103:9b881da47c92 248 return spi_read(obj);
mbed_official 103:9b881da47c92 249 }
mbed_official 103:9b881da47c92 250
mbed_official 261:ee1cf08b7bc7 251 int spi_slave_receive(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 252 {
mbed_official 103:9b881da47c92 253 return (spi_readable(obj) && !spi_busy(obj)) ? (1) : (0);
mbed_official 103:9b881da47c92 254 }
mbed_official 103:9b881da47c92 255
mbed_official 261:ee1cf08b7bc7 256 int spi_slave_read(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 257 {
mbed_official 266:69e8a32876bd 258 return obj->spi->RXDAT & 0xffff; // Only the lower 16 bits contain data
mbed_official 103:9b881da47c92 259 }
mbed_official 103:9b881da47c92 260
mbed_official 261:ee1cf08b7bc7 261 void spi_slave_write(spi_t *obj, int value)
mbed_official 261:ee1cf08b7bc7 262 {
mbed_official 103:9b881da47c92 263 while (spi_writeable(obj) == 0) ;
mbed_official 103:9b881da47c92 264 obj->spi->TXDAT = value;
mbed_official 103:9b881da47c92 265 }