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:
Thu Dec 26 13:00:06 2013 +0000
Revision:
68:41613245dfd7
Child:
73:299c67215126
Synchronized with git revision fba199a9c4445231b0f38e1e113c118182635546

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

target K20D5M

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 68:41613245dfd7 1 /* mbed Microcontroller Library
mbed_official 68:41613245dfd7 2 * Copyright (c) 2013 ARM Limited
mbed_official 68:41613245dfd7 3 *
mbed_official 68:41613245dfd7 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 68:41613245dfd7 5 * you may not use this file except in compliance with the License.
mbed_official 68:41613245dfd7 6 * You may obtain a copy of the License at
mbed_official 68:41613245dfd7 7 *
mbed_official 68:41613245dfd7 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 68:41613245dfd7 9 *
mbed_official 68:41613245dfd7 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 68:41613245dfd7 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 68:41613245dfd7 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 68:41613245dfd7 13 * See the License for the specific language governing permissions and
mbed_official 68:41613245dfd7 14 * limitations under the License.
mbed_official 68:41613245dfd7 15 */
mbed_official 68:41613245dfd7 16 #include "spi_api.h"
mbed_official 68:41613245dfd7 17
mbed_official 68:41613245dfd7 18 #include <math.h>
mbed_official 68:41613245dfd7 19
mbed_official 68:41613245dfd7 20 #include "cmsis.h"
mbed_official 68:41613245dfd7 21 #include "pinmap.h"
mbed_official 68:41613245dfd7 22 #include "error.h"
mbed_official 68:41613245dfd7 23
mbed_official 68:41613245dfd7 24 static const PinMap PinMap_SPI_SCLK[] = {
mbed_official 68:41613245dfd7 25 {PTC5, SPI_0, 2},
mbed_official 68:41613245dfd7 26 {PTD1, SPI_0, 2},
mbed_official 68:41613245dfd7 27 {NC , NC , 0}
mbed_official 68:41613245dfd7 28 };
mbed_official 68:41613245dfd7 29
mbed_official 68:41613245dfd7 30 static const PinMap PinMap_SPI_MOSI[] = {
mbed_official 68:41613245dfd7 31 {PTD2, SPI_0, 2},
mbed_official 68:41613245dfd7 32 {PTC6, SPI_0, 2},
mbed_official 68:41613245dfd7 33 {NC , NC , 0}
mbed_official 68:41613245dfd7 34 };
mbed_official 68:41613245dfd7 35
mbed_official 68:41613245dfd7 36 static const PinMap PinMap_SPI_MISO[] = {
mbed_official 68:41613245dfd7 37 {PTD3, SPI_0, 2},
mbed_official 68:41613245dfd7 38 {PTC7, SPI_0, 2},
mbed_official 68:41613245dfd7 39 {NC , NC , 0}
mbed_official 68:41613245dfd7 40 };
mbed_official 68:41613245dfd7 41
mbed_official 68:41613245dfd7 42 static const PinMap PinMap_SPI_SSEL[] = {
mbed_official 68:41613245dfd7 43 {PTD0, SPI_0, 2},
mbed_official 68:41613245dfd7 44 {PTC4, SPI_0, 2},
mbed_official 68:41613245dfd7 45 {NC , NC , 0}
mbed_official 68:41613245dfd7 46 };
mbed_official 68:41613245dfd7 47
mbed_official 68:41613245dfd7 48 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
mbed_official 68:41613245dfd7 49 // determine the SPI to use
mbed_official 68:41613245dfd7 50 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
mbed_official 68:41613245dfd7 51 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
mbed_official 68:41613245dfd7 52 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
mbed_official 68:41613245dfd7 53 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
mbed_official 68:41613245dfd7 54 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
mbed_official 68:41613245dfd7 55 SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
mbed_official 68:41613245dfd7 56
mbed_official 68:41613245dfd7 57 obj->spi = (SPI_Type*)pinmap_merge(spi_data, spi_cntl);
mbed_official 68:41613245dfd7 58 if ((int)obj->spi == NC) {
mbed_official 68:41613245dfd7 59 error("SPI pinout mapping failed");
mbed_official 68:41613245dfd7 60 }
mbed_official 68:41613245dfd7 61
mbed_official 68:41613245dfd7 62 SIM->SCGC5 |= (1 << 11) | (1 << 12); // PortC & D
mbed_official 68:41613245dfd7 63 SIM->SCGC6 |= 1 << 12; // spi clocks
mbed_official 68:41613245dfd7 64
mbed_official 68:41613245dfd7 65 // halted state
mbed_official 68:41613245dfd7 66 obj->spi->MCR = SPI_MCR_HALT_MASK;
mbed_official 68:41613245dfd7 67
mbed_official 68:41613245dfd7 68 // set default format and frequency
mbed_official 68:41613245dfd7 69 if (ssel == NC) {
mbed_official 68:41613245dfd7 70 spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
mbed_official 68:41613245dfd7 71 } else {
mbed_official 68:41613245dfd7 72 spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
mbed_official 68:41613245dfd7 73 }
mbed_official 68:41613245dfd7 74 spi_frequency(obj, 1000000);
mbed_official 68:41613245dfd7 75
mbed_official 68:41613245dfd7 76 // not halt in the debug mode
mbed_official 68:41613245dfd7 77 obj->spi->SR |= SPI_SR_EOQF_MASK;
mbed_official 68:41613245dfd7 78 // enable SPI
mbed_official 68:41613245dfd7 79 obj->spi->MCR &= (~SPI_MCR_HALT_MASK);
mbed_official 68:41613245dfd7 80
mbed_official 68:41613245dfd7 81 // pin out the spi pins
mbed_official 68:41613245dfd7 82 pinmap_pinout(mosi, PinMap_SPI_MOSI);
mbed_official 68:41613245dfd7 83 pinmap_pinout(miso, PinMap_SPI_MISO);
mbed_official 68:41613245dfd7 84 pinmap_pinout(sclk, PinMap_SPI_SCLK);
mbed_official 68:41613245dfd7 85 if (ssel != NC) {
mbed_official 68:41613245dfd7 86 pinmap_pinout(ssel, PinMap_SPI_SSEL);
mbed_official 68:41613245dfd7 87 }
mbed_official 68:41613245dfd7 88 }
mbed_official 68:41613245dfd7 89
mbed_official 68:41613245dfd7 90 void spi_free(spi_t *obj) {
mbed_official 68:41613245dfd7 91 // [TODO]
mbed_official 68:41613245dfd7 92 }
mbed_official 68:41613245dfd7 93 void spi_format(spi_t *obj, int bits, int mode, int slave) {
mbed_official 68:41613245dfd7 94 if ((bits != 8) && (bits != 16)) {
mbed_official 68:41613245dfd7 95 error("Only 8/16 bits SPI supported");
mbed_official 68:41613245dfd7 96 }
mbed_official 68:41613245dfd7 97
mbed_official 68:41613245dfd7 98 if ((mode < 0) || (mode > 3)) {
mbed_official 68:41613245dfd7 99 error("SPI mode unsupported");
mbed_official 68:41613245dfd7 100 }
mbed_official 68:41613245dfd7 101
mbed_official 68:41613245dfd7 102 uint32_t polarity = (mode & 0x2) ? 1 : 0;
mbed_official 68:41613245dfd7 103 uint32_t phase = (mode & 0x1) ? 1 : 0;
mbed_official 68:41613245dfd7 104
mbed_official 68:41613245dfd7 105 // set master/slave
mbed_official 68:41613245dfd7 106 obj->spi->MCR &= ~SPI_MCR_MSTR_MASK;
mbed_official 68:41613245dfd7 107 obj->spi->MCR |= ((!slave) << SPI_MCR_MSTR_SHIFT);
mbed_official 68:41613245dfd7 108
mbed_official 68:41613245dfd7 109 // CTAR0 is used
mbed_official 68:41613245dfd7 110 obj->spi->CTAR[0] &= ~(SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK);
mbed_official 68:41613245dfd7 111 obj->spi->CTAR[0] |= (polarity << SPI_CTAR_CPOL_SHIFT) | (phase << SPI_CTAR_CPHA_SHIFT);
mbed_official 68:41613245dfd7 112 }
mbed_official 68:41613245dfd7 113
mbed_official 68:41613245dfd7 114 void spi_frequency(spi_t *obj, int hz) {
mbed_official 68:41613245dfd7 115 uint32_t error = 0;
mbed_official 68:41613245dfd7 116 uint32_t p_error = 0xffffffff;
mbed_official 68:41613245dfd7 117 uint32_t ref = 0;
mbed_official 68:41613245dfd7 118 uint32_t spr = 0;
mbed_official 68:41613245dfd7 119 uint32_t ref_spr = 0;
mbed_official 68:41613245dfd7 120 uint32_t ref_prescaler = 0;
mbed_official 68:41613245dfd7 121
mbed_official 68:41613245dfd7 122 // bus clk
mbed_official 68:41613245dfd7 123 uint32_t PCLK = 48000000u;
mbed_official 68:41613245dfd7 124 uint32_t prescaler = 1;
mbed_official 68:41613245dfd7 125 uint32_t divisor = 2;
mbed_official 68:41613245dfd7 126
mbed_official 68:41613245dfd7 127 for (prescaler = 1; prescaler <= 8; prescaler++) {
mbed_official 68:41613245dfd7 128 divisor = 2;
mbed_official 68:41613245dfd7 129 for (spr = 0; spr <= 8; spr++, divisor *= 2) {
mbed_official 68:41613245dfd7 130 ref = PCLK / (prescaler*divisor);
mbed_official 68:41613245dfd7 131 if (ref > (uint32_t)hz)
mbed_official 68:41613245dfd7 132 continue;
mbed_official 68:41613245dfd7 133 error = hz - ref;
mbed_official 68:41613245dfd7 134 if (error < p_error) {
mbed_official 68:41613245dfd7 135 ref_spr = spr;
mbed_official 68:41613245dfd7 136 ref_prescaler = prescaler - 1;
mbed_official 68:41613245dfd7 137 p_error = error;
mbed_official 68:41613245dfd7 138 }
mbed_official 68:41613245dfd7 139 }
mbed_official 68:41613245dfd7 140 }
mbed_official 68:41613245dfd7 141
mbed_official 68:41613245dfd7 142 // set SPPR and SPR
mbed_official 68:41613245dfd7 143 obj->spi->CTAR[0] = ((ref_prescaler & 0x7) << 4) | (ref_spr & 0xf);
mbed_official 68:41613245dfd7 144 }
mbed_official 68:41613245dfd7 145
mbed_official 68:41613245dfd7 146 static inline int spi_writeable(spi_t * obj) {
mbed_official 68:41613245dfd7 147 return (obj->spi->SR & SPI_SR_TCF_MASK) ? 1 : 0;
mbed_official 68:41613245dfd7 148 }
mbed_official 68:41613245dfd7 149
mbed_official 68:41613245dfd7 150 static inline int spi_readable(spi_t * obj) {
mbed_official 68:41613245dfd7 151 return (obj->spi->SR & SPI_SR_TFFF_MASK) ? 1 : 0;
mbed_official 68:41613245dfd7 152 }
mbed_official 68:41613245dfd7 153
mbed_official 68:41613245dfd7 154 int spi_master_write(spi_t *obj, int value) {
mbed_official 68:41613245dfd7 155 // wait tx buffer empty
mbed_official 68:41613245dfd7 156 while(!spi_writeable(obj));
mbed_official 68:41613245dfd7 157 obj->spi->PUSHR = SPI_PUSHR_TXDATA(value & 0xff);
mbed_official 68:41613245dfd7 158
mbed_official 68:41613245dfd7 159 // wait rx buffer full
mbed_official 68:41613245dfd7 160 while (!spi_readable(obj));
mbed_official 68:41613245dfd7 161 return obj->spi->POPR;
mbed_official 68:41613245dfd7 162 }
mbed_official 68:41613245dfd7 163
mbed_official 68:41613245dfd7 164 int spi_slave_receive(spi_t *obj) {
mbed_official 68:41613245dfd7 165 return spi_readable(obj);
mbed_official 68:41613245dfd7 166 }
mbed_official 68:41613245dfd7 167
mbed_official 68:41613245dfd7 168 int spi_slave_read(spi_t *obj) {
mbed_official 68:41613245dfd7 169 return obj->spi->POPR;
mbed_official 68:41613245dfd7 170 }
mbed_official 68:41613245dfd7 171
mbed_official 68:41613245dfd7 172 void spi_slave_write(spi_t *obj, int value) {
mbed_official 68:41613245dfd7 173 while (!spi_writeable(obj));
mbed_official 68:41613245dfd7 174 }