mbed SDK library sources

Fork of mbed-src by mbed official

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 Sep 30 20:45:04 2013 +0100
Revision:
32:4742f6c694e8
Parent:
30:91c1d09ada54
Child:
81:a9456fdf72fa
Synchronized with git revision e8afb9cd1deecf3a0ef2c140d38e3f2d68a2eb50

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 30:91c1d09ada54 16 #include <math.h>
mbed_official 30:91c1d09ada54 17 #include "spi_api.h"
mbed_official 30:91c1d09ada54 18 #include "cmsis.h"
mbed_official 30:91c1d09ada54 19 #include "pinmap.h"
mbed_official 30:91c1d09ada54 20 #include "error.h"
mbed_official 30:91c1d09ada54 21
mbed_official 32:4742f6c694e8 22 static const PinMap PinMap_SPI_SCLK[] = {
mbed_official 32:4742f6c694e8 23 {P0_6 , SPI_0, 0x02},
mbed_official 32:4742f6c694e8 24 // {P0_10, SPI_0, 0x02}, -- should be mapped to SWCLK only
mbed_official 32:4742f6c694e8 25 {P2_11, SPI_0, 0x01},
mbed_official 32:4742f6c694e8 26 {P2_1 , SPI_1, 0x02},
mbed_official 32:4742f6c694e8 27 {NC , NC , 0}
mbed_official 32:4742f6c694e8 28 };
mbed_official 32:4742f6c694e8 29
mbed_official 32:4742f6c694e8 30 static const PinMap PinMap_SPI_MOSI[] = {
mbed_official 32:4742f6c694e8 31 {P0_9 , SPI_0, 0x01},
mbed_official 32:4742f6c694e8 32 {P2_3 , SPI_1, 0x02},
mbed_official 32:4742f6c694e8 33 {NC , NC , 0}
mbed_official 32:4742f6c694e8 34 };
mbed_official 32:4742f6c694e8 35
mbed_official 32:4742f6c694e8 36 static const PinMap PinMap_SPI_MISO[] = {
mbed_official 32:4742f6c694e8 37 {P0_8 , SPI_0, 0x01},
mbed_official 32:4742f6c694e8 38 {P2_2 , SPI_1, 0x02},
mbed_official 32:4742f6c694e8 39 {NC , NC , 0}
mbed_official 32:4742f6c694e8 40 };
mbed_official 32:4742f6c694e8 41
mbed_official 32:4742f6c694e8 42 static const PinMap PinMap_SPI_SSEL[] = {
mbed_official 32:4742f6c694e8 43 {P0_2 , SPI_0, 0x01},
mbed_official 32:4742f6c694e8 44 {P2_0 , SPI_1, 0x02},
mbed_official 32:4742f6c694e8 45 {NC , NC , 0}
mbed_official 32:4742f6c694e8 46 };
mbed_official 30:91c1d09ada54 47
mbed_official 30:91c1d09ada54 48 static inline int ssp_disable(spi_t *obj);
mbed_official 30:91c1d09ada54 49 static inline int ssp_enable(spi_t *obj);
mbed_official 30:91c1d09ada54 50
mbed_official 30:91c1d09ada54 51 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
mbed_official 30:91c1d09ada54 52 // determine the SPI to use
mbed_official 30:91c1d09ada54 53 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
mbed_official 30:91c1d09ada54 54 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
mbed_official 30:91c1d09ada54 55 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
mbed_official 30:91c1d09ada54 56 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
mbed_official 30:91c1d09ada54 57 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
mbed_official 30:91c1d09ada54 58 SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
mbed_official 30:91c1d09ada54 59
mbed_official 30:91c1d09ada54 60 obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl);
mbed_official 30:91c1d09ada54 61
mbed_official 30:91c1d09ada54 62 if ((int)obj->spi == NC) {
mbed_official 30:91c1d09ada54 63 error("SPI pinout mapping failed");
mbed_official 30:91c1d09ada54 64 }
mbed_official 30:91c1d09ada54 65
mbed_official 30:91c1d09ada54 66 // enable power and clocking
mbed_official 30:91c1d09ada54 67 switch ((int)obj->spi) {
mbed_official 30:91c1d09ada54 68 case SPI_0:
mbed_official 30:91c1d09ada54 69 LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 11;
mbed_official 30:91c1d09ada54 70 LPC_SYSCON->SSP0CLKDIV = 0x01;
mbed_official 30:91c1d09ada54 71 LPC_SYSCON->PRESETCTRL |= 1 << 0;
mbed_official 30:91c1d09ada54 72 break;
mbed_official 30:91c1d09ada54 73 case SPI_1:
mbed_official 30:91c1d09ada54 74 LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 18;
mbed_official 30:91c1d09ada54 75 LPC_SYSCON->SSP1CLKDIV = 0x01;
mbed_official 30:91c1d09ada54 76 LPC_SYSCON->PRESETCTRL |= 1 << 2;
mbed_official 30:91c1d09ada54 77 break;
mbed_official 30:91c1d09ada54 78 }
mbed_official 30:91c1d09ada54 79
mbed_official 30:91c1d09ada54 80 // set default format and frequency
mbed_official 30:91c1d09ada54 81 if (ssel == NC) {
mbed_official 30:91c1d09ada54 82 spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
mbed_official 30:91c1d09ada54 83 } else {
mbed_official 30:91c1d09ada54 84 spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
mbed_official 30:91c1d09ada54 85 }
mbed_official 30:91c1d09ada54 86 spi_frequency(obj, 1000000);
mbed_official 30:91c1d09ada54 87
mbed_official 30:91c1d09ada54 88 // enable the ssp channel
mbed_official 30:91c1d09ada54 89 ssp_enable(obj);
mbed_official 30:91c1d09ada54 90
mbed_official 30:91c1d09ada54 91 // pin out the spi pins
mbed_official 30:91c1d09ada54 92 pinmap_pinout(mosi, PinMap_SPI_MOSI);
mbed_official 30:91c1d09ada54 93 pinmap_pinout(miso, PinMap_SPI_MISO);
mbed_official 30:91c1d09ada54 94 pinmap_pinout(sclk, PinMap_SPI_SCLK);
mbed_official 30:91c1d09ada54 95 if (ssel != NC) {
mbed_official 30:91c1d09ada54 96 pinmap_pinout(ssel, PinMap_SPI_SSEL);
mbed_official 30:91c1d09ada54 97 }
mbed_official 30:91c1d09ada54 98 }
mbed_official 30:91c1d09ada54 99
mbed_official 30:91c1d09ada54 100 void spi_free(spi_t *obj) {}
mbed_official 30:91c1d09ada54 101
mbed_official 30:91c1d09ada54 102 void spi_format(spi_t *obj, int bits, int mode, int slave) {
mbed_official 30:91c1d09ada54 103 ssp_disable(obj);
mbed_official 30:91c1d09ada54 104
mbed_official 30:91c1d09ada54 105 if (!(bits >= 4 && bits <= 16) || !(mode >= 0 && mode <= 3)) {
mbed_official 30:91c1d09ada54 106 error("SPI format error");
mbed_official 30:91c1d09ada54 107 }
mbed_official 30:91c1d09ada54 108
mbed_official 30:91c1d09ada54 109 int polarity = (mode & 0x2) ? 1 : 0;
mbed_official 30:91c1d09ada54 110 int phase = (mode & 0x1) ? 1 : 0;
mbed_official 30:91c1d09ada54 111
mbed_official 30:91c1d09ada54 112 // set it up
mbed_official 30:91c1d09ada54 113 int DSS = bits - 1; // DSS (data select size)
mbed_official 30:91c1d09ada54 114 int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity
mbed_official 30:91c1d09ada54 115 int SPH = (phase) ? 1 : 0; // SPH - clock out phase
mbed_official 30:91c1d09ada54 116
mbed_official 30:91c1d09ada54 117 int FRF = 0; // FRF (frame format) = SPI
mbed_official 30:91c1d09ada54 118 uint32_t tmp = obj->spi->CR0;
mbed_official 30:91c1d09ada54 119 tmp &= ~(0xFFFF);
mbed_official 30:91c1d09ada54 120 tmp |= DSS << 0
mbed_official 30:91c1d09ada54 121 | FRF << 4
mbed_official 30:91c1d09ada54 122 | SPO << 6
mbed_official 30:91c1d09ada54 123 | SPH << 7;
mbed_official 30:91c1d09ada54 124 obj->spi->CR0 = tmp;
mbed_official 30:91c1d09ada54 125
mbed_official 30:91c1d09ada54 126 tmp = obj->spi->CR1;
mbed_official 30:91c1d09ada54 127 tmp &= ~(0xD);
mbed_official 30:91c1d09ada54 128 tmp |= 0 << 0 // LBM - loop back mode - off
mbed_official 30:91c1d09ada54 129 | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave
mbed_official 30:91c1d09ada54 130 | 0 << 3; // SOD - slave output disable - na
mbed_official 30:91c1d09ada54 131 obj->spi->CR1 = tmp;
mbed_official 30:91c1d09ada54 132
mbed_official 30:91c1d09ada54 133 ssp_enable(obj);
mbed_official 30:91c1d09ada54 134 }
mbed_official 30:91c1d09ada54 135
mbed_official 30:91c1d09ada54 136 void spi_frequency(spi_t *obj, int hz) {
mbed_official 30:91c1d09ada54 137 ssp_disable(obj);
mbed_official 30:91c1d09ada54 138
mbed_official 30:91c1d09ada54 139 uint32_t PCLK = SystemCoreClock;
mbed_official 30:91c1d09ada54 140
mbed_official 30:91c1d09ada54 141 int prescaler;
mbed_official 30:91c1d09ada54 142
mbed_official 30:91c1d09ada54 143 for (prescaler = 2; prescaler <= 254; prescaler += 2) {
mbed_official 30:91c1d09ada54 144 int prescale_hz = PCLK / prescaler;
mbed_official 30:91c1d09ada54 145
mbed_official 30:91c1d09ada54 146 // calculate the divider
mbed_official 30:91c1d09ada54 147 int divider = floor(((float)prescale_hz / (float)hz) + 0.5f);
mbed_official 30:91c1d09ada54 148
mbed_official 30:91c1d09ada54 149 // check we can support the divider
mbed_official 30:91c1d09ada54 150 if (divider < 256) {
mbed_official 30:91c1d09ada54 151 // prescaler
mbed_official 30:91c1d09ada54 152 obj->spi->CPSR = prescaler;
mbed_official 30:91c1d09ada54 153
mbed_official 30:91c1d09ada54 154 // divider
mbed_official 30:91c1d09ada54 155 obj->spi->CR0 &= ~(0xFFFF << 8);
mbed_official 30:91c1d09ada54 156 obj->spi->CR0 |= (divider - 1) << 8;
mbed_official 30:91c1d09ada54 157 ssp_enable(obj);
mbed_official 30:91c1d09ada54 158 return;
mbed_official 30:91c1d09ada54 159 }
mbed_official 30:91c1d09ada54 160 }
mbed_official 30:91c1d09ada54 161 error("Couldn't setup requested SPI frequency");
mbed_official 30:91c1d09ada54 162 }
mbed_official 30:91c1d09ada54 163
mbed_official 30:91c1d09ada54 164 static inline int ssp_disable(spi_t *obj) {
mbed_official 30:91c1d09ada54 165 return obj->spi->CR1 &= ~(1 << 1);
mbed_official 30:91c1d09ada54 166 }
mbed_official 30:91c1d09ada54 167
mbed_official 30:91c1d09ada54 168 static inline int ssp_enable(spi_t *obj) {
mbed_official 30:91c1d09ada54 169 return obj->spi->CR1 |= (1 << 1);
mbed_official 30:91c1d09ada54 170 }
mbed_official 30:91c1d09ada54 171
mbed_official 30:91c1d09ada54 172 static inline int ssp_readable(spi_t *obj) {
mbed_official 30:91c1d09ada54 173 return obj->spi->SR & (1 << 2);
mbed_official 30:91c1d09ada54 174 }
mbed_official 30:91c1d09ada54 175
mbed_official 30:91c1d09ada54 176 static inline int ssp_writeable(spi_t *obj) {
mbed_official 30:91c1d09ada54 177 return obj->spi->SR & (1 << 1);
mbed_official 30:91c1d09ada54 178 }
mbed_official 30:91c1d09ada54 179
mbed_official 30:91c1d09ada54 180 static inline void ssp_write(spi_t *obj, int value) {
mbed_official 30:91c1d09ada54 181 while (!ssp_writeable(obj));
mbed_official 30:91c1d09ada54 182 obj->spi->DR = value;
mbed_official 30:91c1d09ada54 183 }
mbed_official 30:91c1d09ada54 184
mbed_official 30:91c1d09ada54 185 static inline int ssp_read(spi_t *obj) {
mbed_official 30:91c1d09ada54 186 while (!ssp_readable(obj));
mbed_official 30:91c1d09ada54 187 return obj->spi->DR;
mbed_official 30:91c1d09ada54 188 }
mbed_official 30:91c1d09ada54 189
mbed_official 30:91c1d09ada54 190 static inline int ssp_busy(spi_t *obj) {
mbed_official 30:91c1d09ada54 191 return (obj->spi->SR & (1 << 4)) ? (1) : (0);
mbed_official 30:91c1d09ada54 192 }
mbed_official 30:91c1d09ada54 193
mbed_official 30:91c1d09ada54 194 int spi_master_write(spi_t *obj, int value) {
mbed_official 30:91c1d09ada54 195 ssp_write(obj, value);
mbed_official 30:91c1d09ada54 196 return ssp_read(obj);
mbed_official 30:91c1d09ada54 197 }
mbed_official 30:91c1d09ada54 198
mbed_official 30:91c1d09ada54 199 int spi_slave_receive(spi_t *obj) {
mbed_official 30:91c1d09ada54 200 return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
mbed_official 30:91c1d09ada54 201 };
mbed_official 30:91c1d09ada54 202
mbed_official 30:91c1d09ada54 203 int spi_slave_read(spi_t *obj) {
mbed_official 30:91c1d09ada54 204 return obj->spi->DR;
mbed_official 30:91c1d09ada54 205 }
mbed_official 30:91c1d09ada54 206
mbed_official 30:91c1d09ada54 207 void spi_slave_write(spi_t *obj, int value) {
mbed_official 30:91c1d09ada54 208 while (ssp_writeable(obj) == 0) ;
mbed_official 30:91c1d09ada54 209 obj->spi->DR = value;
mbed_official 30:91c1d09ada54 210 }
mbed_official 30:91c1d09ada54 211
mbed_official 30:91c1d09ada54 212 int spi_busy(spi_t *obj) {
mbed_official 30:91c1d09ada54 213 return ssp_busy(obj);
mbed_official 30:91c1d09ada54 214 }