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 Oct 07 09:15:08 2013 +0100
Revision:
33:e214068ab66c
Parent:
31:42176bc3c368
Child:
44:2ce89a25b635
Synchronized with git revision 53edc82f7373bbfa01a161700524765f52fdb444

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 31:42176bc3c368 99 case SPI_0: SIM->SCGC5 |= 1 << 11; 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 31:42176bc3c368 113
mbed_official 31:42176bc3c368 114 // pin out the spi pins
mbed_official 31:42176bc3c368 115 pinmap_pinout(mosi, PinMap_SPI_MOSI);
mbed_official 31:42176bc3c368 116 pinmap_pinout(miso, PinMap_SPI_MISO);
mbed_official 31:42176bc3c368 117 pinmap_pinout(sclk, PinMap_SPI_SCLK);
mbed_official 31:42176bc3c368 118 if (ssel != NC) {
mbed_official 31:42176bc3c368 119 pinmap_pinout(ssel, PinMap_SPI_SSEL);
mbed_official 31:42176bc3c368 120 }
mbed_official 31:42176bc3c368 121 }
mbed_official 31:42176bc3c368 122
mbed_official 31:42176bc3c368 123 void spi_free(spi_t *obj) {
mbed_official 31:42176bc3c368 124 // [TODO]
mbed_official 31:42176bc3c368 125 }
mbed_official 31:42176bc3c368 126 void spi_format(spi_t *obj, int bits, int mode, int slave) {
mbed_official 31:42176bc3c368 127 if (bits != 8) {
mbed_official 31:42176bc3c368 128 error("Only 8bits SPI supported");
mbed_official 31:42176bc3c368 129 }
mbed_official 31:42176bc3c368 130
mbed_official 31:42176bc3c368 131 if ((mode < 0) || (mode > 3)) {
mbed_official 31:42176bc3c368 132 error("SPI mode unsupported");
mbed_official 31:42176bc3c368 133 }
mbed_official 31:42176bc3c368 134
mbed_official 31:42176bc3c368 135 uint8_t polarity = (mode & 0x2) ? 1 : 0;
mbed_official 31:42176bc3c368 136 uint8_t phase = (mode & 0x1) ? 1 : 0;
mbed_official 31:42176bc3c368 137 uint8_t c1_data = ((!slave) << 4) | (polarity << 3) | (phase << 2);
mbed_official 31:42176bc3c368 138
mbed_official 31:42176bc3c368 139 // clear MSTR, CPOL and CPHA bits
mbed_official 31:42176bc3c368 140 obj->spi->C1 &= ~(0x7 << 2);
mbed_official 31:42176bc3c368 141
mbed_official 31:42176bc3c368 142 // write new value
mbed_official 31:42176bc3c368 143 obj->spi->C1 |= c1_data;
mbed_official 31:42176bc3c368 144 }
mbed_official 31:42176bc3c368 145
mbed_official 31:42176bc3c368 146 void spi_frequency(spi_t *obj, int hz) {
mbed_official 31:42176bc3c368 147 uint32_t error = 0;
mbed_official 31:42176bc3c368 148 uint32_t p_error = 0xffffffff;
mbed_official 31:42176bc3c368 149 uint32_t ref = 0;
mbed_official 31:42176bc3c368 150 uint8_t spr = 0;
mbed_official 31:42176bc3c368 151 uint8_t ref_spr = 0;
mbed_official 31:42176bc3c368 152 uint8_t ref_prescaler = 0;
mbed_official 31:42176bc3c368 153
mbed_official 31:42176bc3c368 154 // bus clk
mbed_official 31:42176bc3c368 155 uint32_t PCLK = 48000000u;
mbed_official 31:42176bc3c368 156 uint8_t prescaler = 1;
mbed_official 31:42176bc3c368 157 uint8_t divisor = 2;
mbed_official 31:42176bc3c368 158
mbed_official 31:42176bc3c368 159 for (prescaler = 1; prescaler <= 8; prescaler++) {
mbed_official 31:42176bc3c368 160 divisor = 2;
mbed_official 31:42176bc3c368 161 for (spr = 0; spr <= 8; spr++, divisor *= 2) {
mbed_official 31:42176bc3c368 162 ref = PCLK / (prescaler*divisor);
mbed_official 31:42176bc3c368 163 if (ref > (uint32_t)hz)
mbed_official 31:42176bc3c368 164 continue;
mbed_official 31:42176bc3c368 165 error = hz - ref;
mbed_official 31:42176bc3c368 166 if (error < p_error) {
mbed_official 31:42176bc3c368 167 ref_spr = spr;
mbed_official 31:42176bc3c368 168 ref_prescaler = prescaler - 1;
mbed_official 31:42176bc3c368 169 p_error = error;
mbed_official 31:42176bc3c368 170 }
mbed_official 31:42176bc3c368 171 }
mbed_official 31:42176bc3c368 172 }
mbed_official 31:42176bc3c368 173
mbed_official 31:42176bc3c368 174 // set SPPR and SPR
mbed_official 31:42176bc3c368 175 obj->spi->BR = ((ref_prescaler & 0x7) << 4) | (ref_spr & 0xf);
mbed_official 31:42176bc3c368 176 }
mbed_official 31:42176bc3c368 177
mbed_official 31:42176bc3c368 178 static inline int spi_writeable(spi_t * obj) {
mbed_official 31:42176bc3c368 179 return (obj->spi->S & SPI_S_SPTEF_MASK) ? 1 : 0;
mbed_official 31:42176bc3c368 180 }
mbed_official 31:42176bc3c368 181
mbed_official 31:42176bc3c368 182 static inline int spi_readable(spi_t * obj) {
mbed_official 31:42176bc3c368 183 return (obj->spi->S & SPI_S_SPRF_MASK) ? 1 : 0;
mbed_official 31:42176bc3c368 184 }
mbed_official 31:42176bc3c368 185
mbed_official 31:42176bc3c368 186 int spi_master_write(spi_t *obj, int value) {
mbed_official 31:42176bc3c368 187 // wait tx buffer empty
mbed_official 31:42176bc3c368 188 while(!spi_writeable(obj));
mbed_official 31:42176bc3c368 189 obj->spi->D = (value & 0xff);
mbed_official 31:42176bc3c368 190
mbed_official 31:42176bc3c368 191 // wait rx buffer full
mbed_official 31:42176bc3c368 192 while (!spi_readable(obj));
mbed_official 31:42176bc3c368 193 return obj->spi->D & 0xff;
mbed_official 31:42176bc3c368 194 }
mbed_official 31:42176bc3c368 195
mbed_official 31:42176bc3c368 196 int spi_slave_receive(spi_t *obj) {
mbed_official 31:42176bc3c368 197 return spi_readable(obj);
mbed_official 31:42176bc3c368 198 }
mbed_official 31:42176bc3c368 199
mbed_official 31:42176bc3c368 200 int spi_slave_read(spi_t *obj) {
mbed_official 31:42176bc3c368 201 return obj->spi->D;
mbed_official 31:42176bc3c368 202 }
mbed_official 31:42176bc3c368 203
mbed_official 31:42176bc3c368 204 void spi_slave_write(spi_t *obj, int value) {
mbed_official 31:42176bc3c368 205 while (!spi_writeable(obj));
mbed_official 31:42176bc3c368 206 obj->spi->D = value;
mbed_official 31:42176bc3c368 207 }