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