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 Jan 14 20:45:05 2014 +0000
Revision:
73:299c67215126
Parent:
68:41613245dfd7
Synchronized with git revision cee9a71069fc940693df076382e8f182cf1a5919

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

K20D50M target - pwm and clocks in HAL

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 73:299c67215126 23 #include "clk_freqs.h"
mbed_official 68:41613245dfd7 24
mbed_official 68:41613245dfd7 25 static const PinMap PinMap_SPI_SCLK[] = {
mbed_official 68:41613245dfd7 26 {PTC5, SPI_0, 2},
mbed_official 68:41613245dfd7 27 {PTD1, SPI_0, 2},
mbed_official 68:41613245dfd7 28 {NC , NC , 0}
mbed_official 68:41613245dfd7 29 };
mbed_official 68:41613245dfd7 30
mbed_official 68:41613245dfd7 31 static const PinMap PinMap_SPI_MOSI[] = {
mbed_official 68:41613245dfd7 32 {PTD2, SPI_0, 2},
mbed_official 68:41613245dfd7 33 {PTC6, SPI_0, 2},
mbed_official 68:41613245dfd7 34 {NC , NC , 0}
mbed_official 68:41613245dfd7 35 };
mbed_official 68:41613245dfd7 36
mbed_official 68:41613245dfd7 37 static const PinMap PinMap_SPI_MISO[] = {
mbed_official 68:41613245dfd7 38 {PTD3, SPI_0, 2},
mbed_official 68:41613245dfd7 39 {PTC7, SPI_0, 2},
mbed_official 68:41613245dfd7 40 {NC , NC , 0}
mbed_official 68:41613245dfd7 41 };
mbed_official 68:41613245dfd7 42
mbed_official 68:41613245dfd7 43 static const PinMap PinMap_SPI_SSEL[] = {
mbed_official 68:41613245dfd7 44 {PTD0, SPI_0, 2},
mbed_official 68:41613245dfd7 45 {PTC4, SPI_0, 2},
mbed_official 68:41613245dfd7 46 {NC , NC , 0}
mbed_official 68:41613245dfd7 47 };
mbed_official 68:41613245dfd7 48
mbed_official 68:41613245dfd7 49 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
mbed_official 68:41613245dfd7 50 // determine the SPI to use
mbed_official 68:41613245dfd7 51 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
mbed_official 68:41613245dfd7 52 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
mbed_official 68:41613245dfd7 53 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
mbed_official 68:41613245dfd7 54 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
mbed_official 68:41613245dfd7 55 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
mbed_official 68:41613245dfd7 56 SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
mbed_official 68:41613245dfd7 57
mbed_official 68:41613245dfd7 58 obj->spi = (SPI_Type*)pinmap_merge(spi_data, spi_cntl);
mbed_official 68:41613245dfd7 59 if ((int)obj->spi == NC) {
mbed_official 68:41613245dfd7 60 error("SPI pinout mapping failed");
mbed_official 68:41613245dfd7 61 }
mbed_official 68:41613245dfd7 62
mbed_official 73:299c67215126 63 SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK;
mbed_official 73:299c67215126 64 SIM->SCGC6 |= SIM_SCGC6_SPI0_MASK;
mbed_official 68:41613245dfd7 65
mbed_official 68:41613245dfd7 66 // halted state
mbed_official 73:299c67215126 67 obj->spi->MCR &= ~SPI_MCR_MDIS_MASK;
mbed_official 73:299c67215126 68 obj->spi->MCR |= SPI_MCR_HALT_MASK | SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK;
mbed_official 68:41613245dfd7 69
mbed_official 68:41613245dfd7 70 // set default format and frequency
mbed_official 68:41613245dfd7 71 if (ssel == NC) {
mbed_official 68:41613245dfd7 72 spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
mbed_official 68:41613245dfd7 73 } else {
mbed_official 68:41613245dfd7 74 spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
mbed_official 68:41613245dfd7 75 }
mbed_official 68:41613245dfd7 76 spi_frequency(obj, 1000000);
mbed_official 68:41613245dfd7 77
mbed_official 68:41613245dfd7 78 // not halt in the debug mode
mbed_official 68:41613245dfd7 79 obj->spi->SR |= SPI_SR_EOQF_MASK;
mbed_official 68:41613245dfd7 80 // enable SPI
mbed_official 68:41613245dfd7 81 obj->spi->MCR &= (~SPI_MCR_HALT_MASK);
mbed_official 68:41613245dfd7 82
mbed_official 68:41613245dfd7 83 // pin out the spi pins
mbed_official 68:41613245dfd7 84 pinmap_pinout(mosi, PinMap_SPI_MOSI);
mbed_official 68:41613245dfd7 85 pinmap_pinout(miso, PinMap_SPI_MISO);
mbed_official 68:41613245dfd7 86 pinmap_pinout(sclk, PinMap_SPI_SCLK);
mbed_official 68:41613245dfd7 87 if (ssel != NC) {
mbed_official 68:41613245dfd7 88 pinmap_pinout(ssel, PinMap_SPI_SSEL);
mbed_official 68:41613245dfd7 89 }
mbed_official 68:41613245dfd7 90 }
mbed_official 68:41613245dfd7 91
mbed_official 68:41613245dfd7 92 void spi_free(spi_t *obj) {
mbed_official 68:41613245dfd7 93 // [TODO]
mbed_official 68:41613245dfd7 94 }
mbed_official 68:41613245dfd7 95 void spi_format(spi_t *obj, int bits, int mode, int slave) {
mbed_official 68:41613245dfd7 96 if ((bits != 8) && (bits != 16)) {
mbed_official 68:41613245dfd7 97 error("Only 8/16 bits SPI supported");
mbed_official 68:41613245dfd7 98 }
mbed_official 68:41613245dfd7 99
mbed_official 68:41613245dfd7 100 if ((mode < 0) || (mode > 3)) {
mbed_official 68:41613245dfd7 101 error("SPI mode unsupported");
mbed_official 68:41613245dfd7 102 }
mbed_official 68:41613245dfd7 103
mbed_official 68:41613245dfd7 104 uint32_t polarity = (mode & 0x2) ? 1 : 0;
mbed_official 68:41613245dfd7 105 uint32_t phase = (mode & 0x1) ? 1 : 0;
mbed_official 68:41613245dfd7 106
mbed_official 68:41613245dfd7 107 // set master/slave
mbed_official 68:41613245dfd7 108 obj->spi->MCR &= ~SPI_MCR_MSTR_MASK;
mbed_official 68:41613245dfd7 109 obj->spi->MCR |= ((!slave) << SPI_MCR_MSTR_SHIFT);
mbed_official 68:41613245dfd7 110
mbed_official 68:41613245dfd7 111 // CTAR0 is used
mbed_official 68:41613245dfd7 112 obj->spi->CTAR[0] &= ~(SPI_CTAR_CPHA_MASK | SPI_CTAR_CPOL_MASK);
mbed_official 68:41613245dfd7 113 obj->spi->CTAR[0] |= (polarity << SPI_CTAR_CPOL_SHIFT) | (phase << SPI_CTAR_CPHA_SHIFT);
mbed_official 68:41613245dfd7 114 }
mbed_official 68:41613245dfd7 115
mbed_official 73:299c67215126 116 static const uint8_t baudrate_prescaler[] = {2,3,5,7};
mbed_official 73:299c67215126 117 static const uint32_t baudrate_scaler[] = {2, 4, 6, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
mbed_official 73:299c67215126 118 static const uint8_t delay_prescaler[] = {1, 3, 5, 7};
mbed_official 73:299c67215126 119
mbed_official 68:41613245dfd7 120 void spi_frequency(spi_t *obj, int hz) {
mbed_official 68:41613245dfd7 121 uint32_t error = 0;
mbed_official 68:41613245dfd7 122 uint32_t p_error = 0xffffffff;
mbed_official 68:41613245dfd7 123 uint32_t ref = 0;
mbed_official 73:299c67215126 124 uint32_t br = 0;
mbed_official 68:41613245dfd7 125 uint32_t ref_spr = 0;
mbed_official 68:41613245dfd7 126 uint32_t ref_prescaler = 0;
mbed_official 68:41613245dfd7 127
mbed_official 68:41613245dfd7 128 // bus clk
mbed_official 73:299c67215126 129 uint32_t PCLK = bus_frequency();
mbed_official 68:41613245dfd7 130 uint32_t divisor = 2;
mbed_official 73:299c67215126 131 uint32_t prescaler;
mbed_official 68:41613245dfd7 132
mbed_official 73:299c67215126 133 /* TODO */
mbed_official 73:299c67215126 134 for (uint32_t i = 0; i < 4; i++) {
mbed_official 73:299c67215126 135 prescaler = baudrate_prescaler[i];
mbed_official 68:41613245dfd7 136 divisor = 2;
mbed_official 73:299c67215126 137 for (br = 0; br <= 15; br++, divisor *= 2) {
mbed_official 73:299c67215126 138 for (uint32_t dr = 0; dr < 2; dr++) {
mbed_official 73:299c67215126 139 ref = (PCLK / prescaler) * ((1U + dr) / divisor);
mbed_official 73:299c67215126 140 if (ref > (uint32_t)hz)
mbed_official 73:299c67215126 141 continue;
mbed_official 73:299c67215126 142 error = hz - ref;
mbed_official 73:299c67215126 143 if (error < p_error) {
mbed_official 73:299c67215126 144 ref_spr = br;
mbed_official 73:299c67215126 145 ref_prescaler = i;
mbed_official 73:299c67215126 146 p_error = error;
mbed_official 73:299c67215126 147 }
mbed_official 68:41613245dfd7 148 }
mbed_official 68:41613245dfd7 149 }
mbed_official 68:41613245dfd7 150 }
mbed_official 68:41613245dfd7 151
mbed_official 73:299c67215126 152 // set PBR and BR
mbed_official 73:299c67215126 153 obj->spi->CTAR[0] = ((ref_prescaler & 0x3) << SPI_CTAR_PBR_SHIFT) | (ref_spr & 0xf);
mbed_official 68:41613245dfd7 154 }
mbed_official 68:41613245dfd7 155
mbed_official 73:299c67215126 156 static inline int spi_writeable(spi_t *obj) {
mbed_official 73:299c67215126 157 return (obj->spi->SR & SPI_SR_TFFF_MASK) ? 1 : 0;
mbed_official 68:41613245dfd7 158 }
mbed_official 68:41613245dfd7 159
mbed_official 73:299c67215126 160 static inline int spi_readable(spi_t *obj) {
mbed_official 73:299c67215126 161 return (obj->spi->SR & SPI_SR_RFDF_MASK) ? 0 : 1;
mbed_official 68:41613245dfd7 162 }
mbed_official 68:41613245dfd7 163
mbed_official 68:41613245dfd7 164 int spi_master_write(spi_t *obj, int value) {
mbed_official 68:41613245dfd7 165 // wait tx buffer empty
mbed_official 68:41613245dfd7 166 while(!spi_writeable(obj));
mbed_official 73:299c67215126 167 obj->spi->PUSHR = SPI_PUSHR_TXDATA(value & 0xff) /*| SPI_PUSHR_EOQ_MASK*/;
mbed_official 73:299c67215126 168
mbed_official 73:299c67215126 169 while (!obj->spi->SR & SPI_SR_TCF_MASK); // wait for transfer to be complete
mbed_official 68:41613245dfd7 170
mbed_official 68:41613245dfd7 171 // wait rx buffer full
mbed_official 68:41613245dfd7 172 while (!spi_readable(obj));
mbed_official 68:41613245dfd7 173 return obj->spi->POPR;
mbed_official 68:41613245dfd7 174 }
mbed_official 68:41613245dfd7 175
mbed_official 68:41613245dfd7 176 int spi_slave_receive(spi_t *obj) {
mbed_official 68:41613245dfd7 177 return spi_readable(obj);
mbed_official 68:41613245dfd7 178 }
mbed_official 68:41613245dfd7 179
mbed_official 68:41613245dfd7 180 int spi_slave_read(spi_t *obj) {
mbed_official 68:41613245dfd7 181 return obj->spi->POPR;
mbed_official 68:41613245dfd7 182 }
mbed_official 68:41613245dfd7 183
mbed_official 68:41613245dfd7 184 void spi_slave_write(spi_t *obj, int value) {
mbed_official 68:41613245dfd7 185 while (!spi_writeable(obj));
mbed_official 68:41613245dfd7 186 }