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 Jan 13 10:45:05 2014 +0000
Revision:
72:248c61396e08
Parent:
19:398f4c622e1b
Synchronized with git revision f1904ba15c06215a7530efd2d5a16c25af9d29ff

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

KL46Z: Added Sleep, LED3 and LED4 definitions, switches

Who changed what in which revision?

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