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:
Mon Jul 21 07:45:07 2014 +0100
Revision:
261:ee1cf08b7bc7
Parent:
251:de9a1e4ffd79
Child:
266:69e8a32876bd
Synchronized with git revision d712c8f2f24ccef06c8c41cd5373c28370fc4497

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

[LPC1549] Fixed SPI frequency issue

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 251:de9a1e4ffd79 22 #include "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 261:ee1cf08b7bc7 46 static int get_available_spi(void)
mbed_official 261:ee1cf08b7bc7 47 {
mbed_official 103:9b881da47c92 48 int i;
mbed_official 103:9b881da47c92 49 for (i=0; i<2; i++) {
mbed_official 103:9b881da47c92 50 if ((spi_used & (1 << i)) == 0)
mbed_official 103:9b881da47c92 51 return i;
mbed_official 103:9b881da47c92 52 }
mbed_official 103:9b881da47c92 53 return -1;
mbed_official 103:9b881da47c92 54 }
mbed_official 103:9b881da47c92 55
mbed_official 103:9b881da47c92 56 static inline void spi_disable(spi_t *obj);
mbed_official 103:9b881da47c92 57 static inline void spi_enable(spi_t *obj);
mbed_official 103:9b881da47c92 58
mbed_official 261:ee1cf08b7bc7 59 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
mbed_official 261:ee1cf08b7bc7 60 {
mbed_official 103:9b881da47c92 61 int spi_n = get_available_spi();
mbed_official 103:9b881da47c92 62 if (spi_n == -1) {
mbed_official 103:9b881da47c92 63 error("No available SPI");
mbed_official 103:9b881da47c92 64 }
mbed_official 103:9b881da47c92 65
mbed_official 103:9b881da47c92 66 obj->spi_n = spi_n;
mbed_official 103:9b881da47c92 67 spi_used |= (1 << spi_n);
mbed_official 261:ee1cf08b7bc7 68
mbed_official 103:9b881da47c92 69 obj->spi = (spi_n) ? (LPC_SPI0_Type *)(LPC_SPI1_BASE) : (LPC_SPI0_Type *)(LPC_SPI0_BASE);
mbed_official 261:ee1cf08b7bc7 70
mbed_official 103:9b881da47c92 71 const SWM_Map *swm;
mbed_official 103:9b881da47c92 72 uint32_t regVal;
mbed_official 261:ee1cf08b7bc7 73
mbed_official 103:9b881da47c92 74 if (sclk != NC) {
mbed_official 103:9b881da47c92 75 swm = &SWM_SPI_SCLK[obj->spi_n];
mbed_official 103:9b881da47c92 76 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 103:9b881da47c92 77 LPC_SWM->PINASSIGN[swm->n] = regVal | (sclk << swm->offset);
mbed_official 103:9b881da47c92 78 }
mbed_official 261:ee1cf08b7bc7 79
mbed_official 103:9b881da47c92 80 if (mosi != NC) {
mbed_official 103:9b881da47c92 81 swm = &SWM_SPI_MOSI[obj->spi_n];
mbed_official 103:9b881da47c92 82 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 103:9b881da47c92 83 LPC_SWM->PINASSIGN[swm->n] = regVal | (mosi << swm->offset);
mbed_official 103:9b881da47c92 84 }
mbed_official 261:ee1cf08b7bc7 85
mbed_official 103:9b881da47c92 86 if (miso != NC) {
mbed_official 103:9b881da47c92 87 swm = &SWM_SPI_MISO[obj->spi_n];
mbed_official 103:9b881da47c92 88 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 103:9b881da47c92 89 LPC_SWM->PINASSIGN[swm->n] = regVal | (miso << swm->offset);
mbed_official 103:9b881da47c92 90 }
mbed_official 103:9b881da47c92 91
mbed_official 103:9b881da47c92 92 if (ssel != NC) {
mbed_official 103:9b881da47c92 93 swm = &SWM_SPI_SSEL[obj->spi_n];
mbed_official 103:9b881da47c92 94 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
mbed_official 103:9b881da47c92 95 LPC_SWM->PINASSIGN[swm->n] = regVal | (ssel << swm->offset);
mbed_official 103:9b881da47c92 96 }
mbed_official 103:9b881da47c92 97
mbed_official 103:9b881da47c92 98 // clear interrupts
mbed_official 103:9b881da47c92 99 obj->spi->INTENCLR = 0x3f;
mbed_official 103:9b881da47c92 100
mbed_official 261:ee1cf08b7bc7 101 // enable power and clocking
mbed_official 261:ee1cf08b7bc7 102 LPC_SYSCON->SYSAHBCLKCTRL1 |= (0x1 << (obj->spi_n + 9));
mbed_official 261:ee1cf08b7bc7 103 LPC_SYSCON->PRESETCTRL1 |= (0x1 << (obj->spi_n + 9));
mbed_official 261:ee1cf08b7bc7 104 LPC_SYSCON->PRESETCTRL1 &= ~(0x1 << (obj->spi_n + 9));
mbed_official 261:ee1cf08b7bc7 105
mbed_official 103:9b881da47c92 106 // set default format and frequency
mbed_official 103:9b881da47c92 107 if (ssel == NC) {
mbed_official 103:9b881da47c92 108 spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
mbed_official 103:9b881da47c92 109 } else {
mbed_official 103:9b881da47c92 110 spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
mbed_official 103:9b881da47c92 111 }
mbed_official 103:9b881da47c92 112 spi_frequency(obj, 1000000);
mbed_official 261:ee1cf08b7bc7 113
mbed_official 103:9b881da47c92 114 // enable the spi channel
mbed_official 103:9b881da47c92 115 spi_enable(obj);
mbed_official 103:9b881da47c92 116 }
mbed_official 103:9b881da47c92 117
mbed_official 261:ee1cf08b7bc7 118 void spi_free(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 119 {
mbed_official 261:ee1cf08b7bc7 120 }
mbed_official 103:9b881da47c92 121
mbed_official 261:ee1cf08b7bc7 122 void spi_format(spi_t *obj, int bits, int mode, int slave)
mbed_official 261:ee1cf08b7bc7 123 {
mbed_official 103:9b881da47c92 124 spi_disable(obj);
mbed_official 227:7bd0639b8911 125 MBED_ASSERT((bits >= 1 && bits <= 16) && (mode >= 0 && mode <= 3));
mbed_official 261:ee1cf08b7bc7 126
mbed_official 103:9b881da47c92 127 int polarity = (mode & 0x2) ? 1 : 0;
mbed_official 103:9b881da47c92 128 int phase = (mode & 0x1) ? 1 : 0;
mbed_official 261:ee1cf08b7bc7 129
mbed_official 103:9b881da47c92 130 // set it up
mbed_official 103:9b881da47c92 131 int LEN = bits - 1; // LEN - Data Length
mbed_official 103:9b881da47c92 132 int CPOL = (polarity) ? 1 : 0; // CPOL - Clock Polarity select
mbed_official 103:9b881da47c92 133 int CPHA = (phase) ? 1 : 0; // CPHA - Clock Phase select
mbed_official 261:ee1cf08b7bc7 134
mbed_official 103:9b881da47c92 135 uint32_t tmp = obj->spi->CFG;
mbed_official 103:9b881da47c92 136 tmp &= ~((1 << 5) | (1 << 4) | (1 << 2));
mbed_official 103:9b881da47c92 137 tmp |= (CPOL << 5) | (CPHA << 4) | ((slave ? 0 : 1) << 2);
mbed_official 103:9b881da47c92 138 obj->spi->CFG = tmp;
mbed_official 261:ee1cf08b7bc7 139
mbed_official 103:9b881da47c92 140 // select frame length
mbed_official 103:9b881da47c92 141 tmp = obj->spi->TXDATCTL;
mbed_official 103:9b881da47c92 142 tmp &= ~(0xf << 24);
mbed_official 103:9b881da47c92 143 tmp |= (LEN << 24);
mbed_official 103:9b881da47c92 144 obj->spi->TXDATCTL = tmp;
mbed_official 261:ee1cf08b7bc7 145
mbed_official 103:9b881da47c92 146 spi_enable(obj);
mbed_official 103:9b881da47c92 147 }
mbed_official 103:9b881da47c92 148
mbed_official 261:ee1cf08b7bc7 149 void spi_frequency(spi_t *obj, int hz)
mbed_official 261:ee1cf08b7bc7 150 {
mbed_official 103:9b881da47c92 151 spi_disable(obj);
mbed_official 261:ee1cf08b7bc7 152
mbed_official 261:ee1cf08b7bc7 153 // rise DIV value if it cannot be divided
mbed_official 261:ee1cf08b7bc7 154 obj->spi->DIV = (SystemCoreClock + (hz - 1))/hz - 1;
mbed_official 103:9b881da47c92 155 obj->spi->DLY = 0;
mbed_official 261:ee1cf08b7bc7 156
mbed_official 103:9b881da47c92 157 spi_enable(obj);
mbed_official 103:9b881da47c92 158 }
mbed_official 103:9b881da47c92 159
mbed_official 261:ee1cf08b7bc7 160 static inline void spi_disable(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 161 {
mbed_official 103:9b881da47c92 162 obj->spi->CFG &= ~(1 << 0);
mbed_official 103:9b881da47c92 163 }
mbed_official 103:9b881da47c92 164
mbed_official 261:ee1cf08b7bc7 165 static inline void spi_enable(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 166 {
mbed_official 103:9b881da47c92 167 obj->spi->CFG |= (1 << 0);
mbed_official 103:9b881da47c92 168 }
mbed_official 103:9b881da47c92 169
mbed_official 261:ee1cf08b7bc7 170 static inline int spi_readable(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 171 {
mbed_official 103:9b881da47c92 172 return obj->spi->STAT & (1 << 0);
mbed_official 103:9b881da47c92 173 }
mbed_official 103:9b881da47c92 174
mbed_official 261:ee1cf08b7bc7 175 static inline int spi_writeable(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 176 {
mbed_official 103:9b881da47c92 177 return obj->spi->STAT & (1 << 1);
mbed_official 103:9b881da47c92 178 }
mbed_official 103:9b881da47c92 179
mbed_official 261:ee1cf08b7bc7 180 static inline void spi_write(spi_t *obj, int value)
mbed_official 261:ee1cf08b7bc7 181 {
mbed_official 103:9b881da47c92 182 while (!spi_writeable(obj));
mbed_official 103:9b881da47c92 183 // end of transfer
mbed_official 103:9b881da47c92 184 obj->spi->TXDATCTL |= (1 << 20);
mbed_official 103:9b881da47c92 185 obj->spi->TXDAT = value;
mbed_official 103:9b881da47c92 186 }
mbed_official 103:9b881da47c92 187
mbed_official 261:ee1cf08b7bc7 188 static inline int spi_read(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 189 {
mbed_official 103:9b881da47c92 190 while (!spi_readable(obj));
mbed_official 103:9b881da47c92 191 return obj->spi->RXDAT;
mbed_official 103:9b881da47c92 192 }
mbed_official 103:9b881da47c92 193
mbed_official 261:ee1cf08b7bc7 194 int spi_busy(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 195 {
mbed_official 103:9b881da47c92 196 // checking RXOV(Receiver Overrun interrupt flag)
mbed_official 103:9b881da47c92 197 return obj->spi->STAT & (1 << 2);
mbed_official 261:ee1cf08b7bc7 198 }
mbed_official 103:9b881da47c92 199
mbed_official 261:ee1cf08b7bc7 200 int spi_master_write(spi_t *obj, int value)
mbed_official 261:ee1cf08b7bc7 201 {
mbed_official 103:9b881da47c92 202 spi_write(obj, value);
mbed_official 103:9b881da47c92 203 return spi_read(obj);
mbed_official 103:9b881da47c92 204 }
mbed_official 103:9b881da47c92 205
mbed_official 261:ee1cf08b7bc7 206 int spi_slave_receive(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 207 {
mbed_official 103:9b881da47c92 208 return (spi_readable(obj) && !spi_busy(obj)) ? (1) : (0);
mbed_official 103:9b881da47c92 209 }
mbed_official 103:9b881da47c92 210
mbed_official 261:ee1cf08b7bc7 211 int spi_slave_read(spi_t *obj)
mbed_official 261:ee1cf08b7bc7 212 {
mbed_official 103:9b881da47c92 213 return obj->spi->RXDAT;
mbed_official 103:9b881da47c92 214 }
mbed_official 103:9b881da47c92 215
mbed_official 261:ee1cf08b7bc7 216 void spi_slave_write(spi_t *obj, int value)
mbed_official 261:ee1cf08b7bc7 217 {
mbed_official 103:9b881da47c92 218 while (spi_writeable(obj) == 0) ;
mbed_official 103:9b881da47c92 219 obj->spi->TXDAT = value;
mbed_official 103:9b881da47c92 220 }