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:
Tue Nov 05 21:45:05 2013 +0000
Revision:
44:2ce89a25b635
Parent:
33:e214068ab66c
Child:
72:248c61396e08
Synchronized with git revision 887fd2ba3aa83c1c285196ff1cae1341a3e00bec

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 31:42176bc3c368 1 /* mbed Microcontroller Library
mbed_official 31:42176bc3c368 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 31:42176bc3c368 3 *
mbed_official 31:42176bc3c368 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 31:42176bc3c368 5 * you may not use this file except in compliance with the License.
mbed_official 31:42176bc3c368 6 * You may obtain a copy of the License at
mbed_official 31:42176bc3c368 7 *
mbed_official 31:42176bc3c368 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 31:42176bc3c368 9 *
mbed_official 31:42176bc3c368 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 31:42176bc3c368 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 31:42176bc3c368 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 31:42176bc3c368 13 * See the License for the specific language governing permissions and
mbed_official 31:42176bc3c368 14 * limitations under the License.
mbed_official 31:42176bc3c368 15 */
mbed_official 31:42176bc3c368 16 #include "spi_api.h"
mbed_official 31:42176bc3c368 17
mbed_official 31:42176bc3c368 18 #include <math.h>
mbed_official 31:42176bc3c368 19
mbed_official 31:42176bc3c368 20 #include "cmsis.h"
mbed_official 31:42176bc3c368 21 #include "pinmap.h"
mbed_official 31:42176bc3c368 22 #include "error.h"
mbed_official 31:42176bc3c368 23
mbed_official 31:42176bc3c368 24 static const PinMap PinMap_SPI_SCLK[] = {
mbed_official 31:42176bc3c368 25 {PTA15, SPI_0, 2},
mbed_official 33:e214068ab66c 26 {PTB9, SPI_1, 2},
mbed_official 31:42176bc3c368 27 {PTB11, SPI_1, 2},
mbed_official 31:42176bc3c368 28 {PTC5, SPI_0, 2},
mbed_official 31:42176bc3c368 29 {PTD1, SPI_0, 2},
mbed_official 31:42176bc3c368 30 {PTD5, SPI_1, 2},
mbed_official 31:42176bc3c368 31 {PTE2, SPI_1, 2},
mbed_official 33:e214068ab66c 32 {PTE17, SPI_0, 2},
mbed_official 31:42176bc3c368 33 {NC , NC , 0}
mbed_official 31:42176bc3c368 34 };
mbed_official 31:42176bc3c368 35
mbed_official 31:42176bc3c368 36 static const PinMap PinMap_SPI_MOSI[] = {
mbed_official 31:42176bc3c368 37 {PTA16, SPI_0, 2},
mbed_official 31:42176bc3c368 38 {PTA17, SPI_0, 5},
mbed_official 31:42176bc3c368 39 {PTB16, SPI_1, 2},
mbed_official 31:42176bc3c368 40 {PTB17, SPI_1, 5},
mbed_official 31:42176bc3c368 41 {PTC6, SPI_0, 2},
mbed_official 31:42176bc3c368 42 {PTC7, SPI_0, 5},
mbed_official 31:42176bc3c368 43 {PTD2, SPI_0, 2},
mbed_official 31:42176bc3c368 44 {PTD3, SPI_0, 5},
mbed_official 31:42176bc3c368 45 {PTD6, SPI_1, 2},
mbed_official 31:42176bc3c368 46 {PTD7, SPI_1, 5},
mbed_official 31:42176bc3c368 47 {PTE1, SPI_1, 2},
mbed_official 31:42176bc3c368 48 {PTE3, SPI_1, 5},
mbed_official 33:e214068ab66c 49 {PTE18, SPI_0, 2},
mbed_official 33:e214068ab66c 50 {PTE19, SPI_0, 5},
mbed_official 31:42176bc3c368 51 {NC , NC , 0}
mbed_official 31:42176bc3c368 52 };
mbed_official 31:42176bc3c368 53
mbed_official 31:42176bc3c368 54 static const PinMap PinMap_SPI_MISO[] = {
mbed_official 31:42176bc3c368 55 {PTA16, SPI_0, 5},
mbed_official 31:42176bc3c368 56 {PTA17, SPI_0, 2},
mbed_official 31:42176bc3c368 57 {PTB16, SPI_1, 5},
mbed_official 31:42176bc3c368 58 {PTB17, SPI_1, 2},
mbed_official 31:42176bc3c368 59 {PTC6, SPI_0, 5},
mbed_official 31:42176bc3c368 60 {PTC7, SPI_0, 2},
mbed_official 31:42176bc3c368 61 {PTD2, SPI_0, 5},
mbed_official 31:42176bc3c368 62 {PTD3, SPI_0, 2},
mbed_official 31:42176bc3c368 63 {PTD6, SPI_1, 5},
mbed_official 31:42176bc3c368 64 {PTD7, SPI_1, 2},
mbed_official 31:42176bc3c368 65 {PTE1, SPI_1, 5},
mbed_official 31:42176bc3c368 66 {PTE3, SPI_1, 2},
mbed_official 33:e214068ab66c 67 {PTE18, SPI_0, 5},
mbed_official 33:e214068ab66c 68 {PTE19, SPI_0, 2},
mbed_official 31:42176bc3c368 69 {NC , NC , 0}
mbed_official 31:42176bc3c368 70 };
mbed_official 31:42176bc3c368 71
mbed_official 31:42176bc3c368 72 static const PinMap PinMap_SPI_SSEL[] = {
mbed_official 31:42176bc3c368 73 {PTA14, SPI_0, 2},
mbed_official 31:42176bc3c368 74 {PTB10, SPI_1, 2},
mbed_official 31:42176bc3c368 75 {PTC4, SPI_0, 2},
mbed_official 31:42176bc3c368 76 {PTD0, SPI_0, 2},
mbed_official 31:42176bc3c368 77 {PTD4, SPI_1, 2},
mbed_official 31:42176bc3c368 78 {PTE4, SPI_1, 2},
mbed_official 33:e214068ab66c 79 {PTE16, SPI_0, 2},
mbed_official 31:42176bc3c368 80 {NC , NC , 0}
mbed_official 31:42176bc3c368 81 };
mbed_official 31:42176bc3c368 82
mbed_official 31:42176bc3c368 83 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
mbed_official 31:42176bc3c368 84 // determine the SPI to use
mbed_official 31:42176bc3c368 85 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
mbed_official 31:42176bc3c368 86 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
mbed_official 31:42176bc3c368 87 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
mbed_official 31:42176bc3c368 88 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
mbed_official 31:42176bc3c368 89 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
mbed_official 31:42176bc3c368 90 SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
mbed_official 31:42176bc3c368 91
mbed_official 31:42176bc3c368 92 obj->spi = (SPI_Type*)pinmap_merge(spi_data, spi_cntl);
mbed_official 31:42176bc3c368 93 if ((int)obj->spi == NC) {
mbed_official 31:42176bc3c368 94 error("SPI pinout mapping failed");
mbed_official 31:42176bc3c368 95 }
mbed_official 31:42176bc3c368 96
mbed_official 31:42176bc3c368 97 // enable power and clocking
mbed_official 31:42176bc3c368 98 switch ((int)obj->spi) {
mbed_official 44:2ce89a25b635 99 case SPI_0: SIM->SCGC5 |= 1 << 13; SIM->SCGC4 |= 1 << 22; break;
mbed_official 31:42176bc3c368 100 case SPI_1: SIM->SCGC5 |= 1 << 13; SIM->SCGC4 |= 1 << 23; break;
mbed_official 31:42176bc3c368 101 }
mbed_official 31:42176bc3c368 102
mbed_official 31:42176bc3c368 103 // set default format and frequency
mbed_official 31:42176bc3c368 104 if (ssel == NC) {
mbed_official 31:42176bc3c368 105 spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
mbed_official 31:42176bc3c368 106 } else {
mbed_official 31:42176bc3c368 107 spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
mbed_official 31:42176bc3c368 108 }
mbed_official 31:42176bc3c368 109 spi_frequency(obj, 1000000);
mbed_official 31:42176bc3c368 110
mbed_official 31:42176bc3c368 111 // enable SPI
mbed_official 31:42176bc3c368 112 obj->spi->C1 |= SPI_C1_SPE_MASK;
mbed_official 44:2ce89a25b635 113 obj->spi->C2 &= ~SPI_C2_SPIMODE_MASK; //8bit
mbed_official 31:42176bc3c368 114
mbed_official 31:42176bc3c368 115 // pin out the spi pins
mbed_official 31:42176bc3c368 116 pinmap_pinout(mosi, PinMap_SPI_MOSI);
mbed_official 31:42176bc3c368 117 pinmap_pinout(miso, PinMap_SPI_MISO);
mbed_official 31:42176bc3c368 118 pinmap_pinout(sclk, PinMap_SPI_SCLK);
mbed_official 31:42176bc3c368 119 if (ssel != NC) {
mbed_official 31:42176bc3c368 120 pinmap_pinout(ssel, PinMap_SPI_SSEL);
mbed_official 31:42176bc3c368 121 }
mbed_official 31:42176bc3c368 122 }
mbed_official 31:42176bc3c368 123
mbed_official 31:42176bc3c368 124 void spi_free(spi_t *obj) {
mbed_official 31:42176bc3c368 125 // [TODO]
mbed_official 31:42176bc3c368 126 }
mbed_official 31:42176bc3c368 127 void spi_format(spi_t *obj, int bits, int mode, int slave) {
mbed_official 44:2ce89a25b635 128 if ((bits != 8) && (bits != 16)) {
mbed_official 44:2ce89a25b635 129 error("Only 8/16 bits SPI supported");
mbed_official 31:42176bc3c368 130 }
mbed_official 31:42176bc3c368 131
mbed_official 31:42176bc3c368 132 if ((mode < 0) || (mode > 3)) {
mbed_official 31:42176bc3c368 133 error("SPI mode unsupported");
mbed_official 31:42176bc3c368 134 }
mbed_official 31:42176bc3c368 135
mbed_official 31:42176bc3c368 136 uint8_t polarity = (mode & 0x2) ? 1 : 0;
mbed_official 31:42176bc3c368 137 uint8_t phase = (mode & 0x1) ? 1 : 0;
mbed_official 31:42176bc3c368 138 uint8_t c1_data = ((!slave) << 4) | (polarity << 3) | (phase << 2);
mbed_official 31:42176bc3c368 139
mbed_official 31:42176bc3c368 140 // clear MSTR, CPOL and CPHA bits
mbed_official 31:42176bc3c368 141 obj->spi->C1 &= ~(0x7 << 2);
mbed_official 31:42176bc3c368 142
mbed_official 31:42176bc3c368 143 // write new value
mbed_official 31:42176bc3c368 144 obj->spi->C1 |= c1_data;
mbed_official 44:2ce89a25b635 145 if (bits == 8) {
mbed_official 44:2ce89a25b635 146 obj->spi->C2 &= ~SPI_C2_SPIMODE_MASK;
mbed_official 44:2ce89a25b635 147 } else {
mbed_official 44:2ce89a25b635 148 obj->spi->C2 |= SPI_C2_SPIMODE_MASK;
mbed_official 44:2ce89a25b635 149 }
mbed_official 31:42176bc3c368 150 }
mbed_official 31:42176bc3c368 151
mbed_official 31:42176bc3c368 152 void spi_frequency(spi_t *obj, int hz) {
mbed_official 31:42176bc3c368 153 uint32_t error = 0;
mbed_official 31:42176bc3c368 154 uint32_t p_error = 0xffffffff;
mbed_official 31:42176bc3c368 155 uint32_t ref = 0;
mbed_official 31:42176bc3c368 156 uint8_t spr = 0;
mbed_official 31:42176bc3c368 157 uint8_t ref_spr = 0;
mbed_official 31:42176bc3c368 158 uint8_t ref_prescaler = 0;
mbed_official 31:42176bc3c368 159
mbed_official 31:42176bc3c368 160 // bus clk
mbed_official 31:42176bc3c368 161 uint32_t PCLK = 48000000u;
mbed_official 31:42176bc3c368 162 uint8_t prescaler = 1;
mbed_official 31:42176bc3c368 163 uint8_t divisor = 2;
mbed_official 31:42176bc3c368 164
mbed_official 31:42176bc3c368 165 for (prescaler = 1; prescaler <= 8; prescaler++) {
mbed_official 31:42176bc3c368 166 divisor = 2;
mbed_official 31:42176bc3c368 167 for (spr = 0; spr <= 8; spr++, divisor *= 2) {
mbed_official 31:42176bc3c368 168 ref = PCLK / (prescaler*divisor);
mbed_official 31:42176bc3c368 169 if (ref > (uint32_t)hz)
mbed_official 31:42176bc3c368 170 continue;
mbed_official 31:42176bc3c368 171 error = hz - ref;
mbed_official 31:42176bc3c368 172 if (error < p_error) {
mbed_official 31:42176bc3c368 173 ref_spr = spr;
mbed_official 31:42176bc3c368 174 ref_prescaler = prescaler - 1;
mbed_official 31:42176bc3c368 175 p_error = error;
mbed_official 31:42176bc3c368 176 }
mbed_official 31:42176bc3c368 177 }
mbed_official 31:42176bc3c368 178 }
mbed_official 31:42176bc3c368 179
mbed_official 31:42176bc3c368 180 // set SPPR and SPR
mbed_official 31:42176bc3c368 181 obj->spi->BR = ((ref_prescaler & 0x7) << 4) | (ref_spr & 0xf);
mbed_official 31:42176bc3c368 182 }
mbed_official 31:42176bc3c368 183
mbed_official 31:42176bc3c368 184 static inline int spi_writeable(spi_t * obj) {
mbed_official 31:42176bc3c368 185 return (obj->spi->S & SPI_S_SPTEF_MASK) ? 1 : 0;
mbed_official 31:42176bc3c368 186 }
mbed_official 31:42176bc3c368 187
mbed_official 31:42176bc3c368 188 static inline int spi_readable(spi_t * obj) {
mbed_official 31:42176bc3c368 189 return (obj->spi->S & SPI_S_SPRF_MASK) ? 1 : 0;
mbed_official 31:42176bc3c368 190 }
mbed_official 31:42176bc3c368 191
mbed_official 31:42176bc3c368 192 int spi_master_write(spi_t *obj, int value) {
mbed_official 44:2ce89a25b635 193 int ret;
mbed_official 44:2ce89a25b635 194 if (obj->spi->C2 & SPI_C2_SPIMODE_MASK) {
mbed_official 44:2ce89a25b635 195 // 16bit
mbed_official 44:2ce89a25b635 196 while(!spi_writeable(obj));
mbed_official 44:2ce89a25b635 197 obj->spi->DL = (value & 0xff);
mbed_official 44:2ce89a25b635 198 obj->spi->DH = ((value >> 8) & 0xff);
mbed_official 31:42176bc3c368 199
mbed_official 44:2ce89a25b635 200 // wait rx buffer full
mbed_official 44:2ce89a25b635 201 while (!spi_readable(obj));
mbed_official 44:2ce89a25b635 202 ret = obj->spi->DH;
mbed_official 44:2ce89a25b635 203 ret = (ret << 8) | obj->spi->DL;
mbed_official 44:2ce89a25b635 204 } else {
mbed_official 44:2ce89a25b635 205 //8bit
mbed_official 44:2ce89a25b635 206 while(!spi_writeable(obj));
mbed_official 44:2ce89a25b635 207 obj->spi->DL = (value & 0xff);
mbed_official 44:2ce89a25b635 208
mbed_official 44:2ce89a25b635 209 // wait rx buffer full
mbed_official 44:2ce89a25b635 210 while (!spi_readable(obj));
mbed_official 44:2ce89a25b635 211 ret = (obj->spi->DL & 0xff);
mbed_official 44:2ce89a25b635 212 }
mbed_official 44:2ce89a25b635 213
mbed_official 44:2ce89a25b635 214 return ret;
mbed_official 31:42176bc3c368 215 }
mbed_official 31:42176bc3c368 216
mbed_official 31:42176bc3c368 217 int spi_slave_receive(spi_t *obj) {
mbed_official 31:42176bc3c368 218 return spi_readable(obj);
mbed_official 31:42176bc3c368 219 }
mbed_official 31:42176bc3c368 220
mbed_official 31:42176bc3c368 221 int spi_slave_read(spi_t *obj) {
mbed_official 44:2ce89a25b635 222 int ret;
mbed_official 44:2ce89a25b635 223 if (obj->spi->C2 & SPI_C2_SPIMODE_MASK) {
mbed_official 44:2ce89a25b635 224 ret = obj->spi->DH;
mbed_official 44:2ce89a25b635 225 ret = ((ret << 8) | obj->spi->DL);
mbed_official 44:2ce89a25b635 226 } else {
mbed_official 44:2ce89a25b635 227 ret = obj->spi->DL;
mbed_official 44:2ce89a25b635 228 }
mbed_official 44:2ce89a25b635 229 return ret;
mbed_official 31:42176bc3c368 230 }
mbed_official 31:42176bc3c368 231
mbed_official 31:42176bc3c368 232 void spi_slave_write(spi_t *obj, int value) {
mbed_official 31:42176bc3c368 233 while (!spi_writeable(obj));
mbed_official 44:2ce89a25b635 234 if (obj->spi->C2 & SPI_C2_SPIMODE_MASK) {
mbed_official 44:2ce89a25b635 235 obj->spi->DL = (value & 0xff);
mbed_official 44:2ce89a25b635 236 obj->spi->DH = ((value >> 8) & 0xff);
mbed_official 44:2ce89a25b635 237 } else {
mbed_official 44:2ce89a25b635 238 obj->spi->DL = value;
mbed_official 44:2ce89a25b635 239 }
mbed_official 44:2ce89a25b635 240
mbed_official 31:42176bc3c368 241 }