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 Jun 11 16:00:09 2014 +0100
Revision:
227:7bd0639b8911
Parent:
222:96162ccfbf43
Child:
250:a49055e7a707
Synchronized with git revision d58d532ebc0e0a96f4fffb8edefc082b71b964af

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

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