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:
Tue Jan 07 11:00:05 2014 +0000
Revision:
70:c1fbde68b492
Parent:
19:398f4c622e1b
Child:
72:248c61396e08
Synchronized with git revision 3f438a307904431f2782db3c8fa49946b9fc1d85

Full URL: https://github.com/mbedmicro/mbed/commit/3f438a307904431f2782db3c8fa49946b9fc1d85/

[NUCLEO_F103RB] license text changed + sleep hal updated

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"
bogdanm 15:4892fe388435 23
bogdanm 15:4892fe388435 24 static const PinMap PinMap_SPI_SCLK[] = {
bogdanm 15:4892fe388435 25 {PTA15, SPI_0, 2},
bogdanm 15:4892fe388435 26 {PTB11, SPI_1, 2},
bogdanm 15:4892fe388435 27 {PTC5, SPI_0, 2},
bogdanm 15:4892fe388435 28 {PTD1, SPI_0, 2},
bogdanm 15:4892fe388435 29 {PTD5, SPI_1, 2},
bogdanm 15:4892fe388435 30 {PTE2, SPI_1, 2},
bogdanm 15:4892fe388435 31 {NC , NC , 0}
bogdanm 15:4892fe388435 32 };
bogdanm 15:4892fe388435 33
bogdanm 15:4892fe388435 34 static const PinMap PinMap_SPI_MOSI[] = {
bogdanm 15:4892fe388435 35 {PTA16, SPI_0, 2},
bogdanm 15:4892fe388435 36 {PTA17, SPI_0, 5},
bogdanm 15:4892fe388435 37 {PTB16, SPI_1, 2},
bogdanm 15:4892fe388435 38 {PTB17, SPI_1, 5},
bogdanm 15:4892fe388435 39 {PTC6, SPI_0, 2},
bogdanm 15:4892fe388435 40 {PTC7, SPI_0, 5},
bogdanm 15:4892fe388435 41 {PTD2, SPI_0, 2},
bogdanm 15:4892fe388435 42 {PTD3, SPI_0, 5},
bogdanm 15:4892fe388435 43 {PTD6, SPI_1, 2},
bogdanm 15:4892fe388435 44 {PTD7, SPI_1, 5},
bogdanm 15:4892fe388435 45 {PTE1, SPI_1, 2},
bogdanm 15:4892fe388435 46 {PTE3, SPI_1, 5},
bogdanm 15:4892fe388435 47 {NC , NC , 0}
bogdanm 15:4892fe388435 48 };
bogdanm 15:4892fe388435 49
bogdanm 15:4892fe388435 50 static const PinMap PinMap_SPI_MISO[] = {
bogdanm 15:4892fe388435 51 {PTA16, SPI_0, 5},
bogdanm 15:4892fe388435 52 {PTA17, SPI_0, 2},
bogdanm 15:4892fe388435 53 {PTB16, SPI_1, 5},
bogdanm 15:4892fe388435 54 {PTB17, SPI_1, 2},
bogdanm 15:4892fe388435 55 {PTC6, SPI_0, 5},
bogdanm 15:4892fe388435 56 {PTC7, SPI_0, 2},
bogdanm 15:4892fe388435 57 {PTD2, SPI_0, 5},
bogdanm 15:4892fe388435 58 {PTD3, SPI_0, 2},
bogdanm 15:4892fe388435 59 {PTD6, SPI_1, 5},
bogdanm 15:4892fe388435 60 {PTD7, SPI_1, 2},
bogdanm 15:4892fe388435 61 {PTE1, SPI_1, 5},
bogdanm 15:4892fe388435 62 {PTE3, SPI_1, 2},
bogdanm 15:4892fe388435 63 {NC , NC , 0}
bogdanm 15:4892fe388435 64 };
bogdanm 15:4892fe388435 65
bogdanm 15:4892fe388435 66 static const PinMap PinMap_SPI_SSEL[] = {
bogdanm 15:4892fe388435 67 {PTA14, SPI_0, 2},
bogdanm 15:4892fe388435 68 {PTB10, SPI_1, 2},
bogdanm 15:4892fe388435 69 {PTC4, SPI_0, 2},
bogdanm 15:4892fe388435 70 {PTD0, SPI_0, 2},
bogdanm 15:4892fe388435 71 {PTD4, SPI_1, 2},
bogdanm 15:4892fe388435 72 {PTE4, SPI_1, 2},
bogdanm 15:4892fe388435 73 {NC , NC , 0}
bogdanm 15:4892fe388435 74 };
bogdanm 15:4892fe388435 75
bogdanm 15:4892fe388435 76 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
bogdanm 15:4892fe388435 77 // determine the SPI to use
bogdanm 15:4892fe388435 78 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
bogdanm 15:4892fe388435 79 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
bogdanm 15:4892fe388435 80 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
bogdanm 15:4892fe388435 81 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
bogdanm 15:4892fe388435 82 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
bogdanm 15:4892fe388435 83 SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
bogdanm 15:4892fe388435 84
bogdanm 15:4892fe388435 85 obj->spi = (SPI_Type*)pinmap_merge(spi_data, spi_cntl);
bogdanm 15:4892fe388435 86 if ((int)obj->spi == NC) {
bogdanm 15:4892fe388435 87 error("SPI pinout mapping failed");
bogdanm 15:4892fe388435 88 }
bogdanm 15:4892fe388435 89
bogdanm 15:4892fe388435 90 // enable power and clocking
bogdanm 15:4892fe388435 91 switch ((int)obj->spi) {
bogdanm 15:4892fe388435 92 case SPI_0: SIM->SCGC5 |= 1 << 11; SIM->SCGC4 |= 1 << 22; break;
bogdanm 15:4892fe388435 93 case SPI_1: SIM->SCGC5 |= 1 << 13; SIM->SCGC4 |= 1 << 23; break;
bogdanm 15:4892fe388435 94 }
bogdanm 15:4892fe388435 95
bogdanm 15:4892fe388435 96 // set default format and frequency
bogdanm 15:4892fe388435 97 if (ssel == NC) {
bogdanm 15:4892fe388435 98 spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
bogdanm 15:4892fe388435 99 } else {
bogdanm 15:4892fe388435 100 spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
bogdanm 15:4892fe388435 101 }
bogdanm 15:4892fe388435 102 spi_frequency(obj, 1000000);
bogdanm 15:4892fe388435 103
bogdanm 15:4892fe388435 104 // enable SPI
bogdanm 15:4892fe388435 105 obj->spi->C1 |= SPI_C1_SPE_MASK;
bogdanm 15:4892fe388435 106
bogdanm 15:4892fe388435 107 // pin out the spi pins
bogdanm 15:4892fe388435 108 pinmap_pinout(mosi, PinMap_SPI_MOSI);
bogdanm 15:4892fe388435 109 pinmap_pinout(miso, PinMap_SPI_MISO);
bogdanm 15:4892fe388435 110 pinmap_pinout(sclk, PinMap_SPI_SCLK);
bogdanm 15:4892fe388435 111 if (ssel != NC) {
bogdanm 15:4892fe388435 112 pinmap_pinout(ssel, PinMap_SPI_SSEL);
bogdanm 15:4892fe388435 113 }
bogdanm 15:4892fe388435 114 }
bogdanm 15:4892fe388435 115
bogdanm 15:4892fe388435 116 void spi_free(spi_t *obj) {
bogdanm 15:4892fe388435 117 // [TODO]
bogdanm 15:4892fe388435 118 }
bogdanm 15:4892fe388435 119 void spi_format(spi_t *obj, int bits, int mode, int slave) {
bogdanm 15:4892fe388435 120 if (bits != 8) {
bogdanm 15:4892fe388435 121 error("Only 8bits SPI supported");
bogdanm 15:4892fe388435 122 }
bogdanm 15:4892fe388435 123
bogdanm 15:4892fe388435 124 if ((mode < 0) || (mode > 3)) {
bogdanm 15:4892fe388435 125 error("SPI mode unsupported");
bogdanm 15:4892fe388435 126 }
bogdanm 15:4892fe388435 127
bogdanm 15:4892fe388435 128 uint8_t polarity = (mode & 0x2) ? 1 : 0;
bogdanm 15:4892fe388435 129 uint8_t phase = (mode & 0x1) ? 1 : 0;
bogdanm 15:4892fe388435 130 uint8_t c1_data = ((!slave) << 4) | (polarity << 3) | (phase << 2);
bogdanm 15:4892fe388435 131
bogdanm 15:4892fe388435 132 // clear MSTR, CPOL and CPHA bits
bogdanm 15:4892fe388435 133 obj->spi->C1 &= ~(0x7 << 2);
bogdanm 15:4892fe388435 134
bogdanm 15:4892fe388435 135 // write new value
bogdanm 15:4892fe388435 136 obj->spi->C1 |= c1_data;
bogdanm 15:4892fe388435 137 }
bogdanm 15:4892fe388435 138
bogdanm 15:4892fe388435 139 void spi_frequency(spi_t *obj, int hz) {
bogdanm 15:4892fe388435 140 uint32_t error = 0;
bogdanm 15:4892fe388435 141 uint32_t p_error = 0xffffffff;
bogdanm 15:4892fe388435 142 uint32_t ref = 0;
bogdanm 15:4892fe388435 143 uint8_t spr = 0;
bogdanm 15:4892fe388435 144 uint8_t ref_spr = 0;
bogdanm 15:4892fe388435 145 uint8_t ref_prescaler = 0;
bogdanm 15:4892fe388435 146
bogdanm 15:4892fe388435 147 // bus clk
bogdanm 15:4892fe388435 148 uint32_t PCLK = 48000000u;
bogdanm 15:4892fe388435 149 uint8_t prescaler = 1;
bogdanm 15:4892fe388435 150 uint8_t divisor = 2;
bogdanm 15:4892fe388435 151
bogdanm 15:4892fe388435 152 for (prescaler = 1; prescaler <= 8; prescaler++) {
bogdanm 15:4892fe388435 153 divisor = 2;
bogdanm 15:4892fe388435 154 for (spr = 0; spr <= 8; spr++, divisor *= 2) {
bogdanm 15:4892fe388435 155 ref = PCLK / (prescaler*divisor);
bogdanm 19:398f4c622e1b 156 if (ref > (uint32_t)hz)
bogdanm 15:4892fe388435 157 continue;
bogdanm 15:4892fe388435 158 error = hz - ref;
bogdanm 15:4892fe388435 159 if (error < p_error) {
bogdanm 15:4892fe388435 160 ref_spr = spr;
bogdanm 15:4892fe388435 161 ref_prescaler = prescaler - 1;
bogdanm 15:4892fe388435 162 p_error = error;
bogdanm 15:4892fe388435 163 }
bogdanm 15:4892fe388435 164 }
bogdanm 15:4892fe388435 165 }
bogdanm 15:4892fe388435 166
bogdanm 15:4892fe388435 167 // set SPPR and SPR
bogdanm 15:4892fe388435 168 obj->spi->BR = ((ref_prescaler & 0x7) << 4) | (ref_spr & 0xf);
bogdanm 15:4892fe388435 169 }
bogdanm 13:0645d8841f51 170
bogdanm 13:0645d8841f51 171 static inline int spi_writeable(spi_t * obj) {
bogdanm 13:0645d8841f51 172 return (obj->spi->S & SPI_S_SPTEF_MASK) ? 1 : 0;
bogdanm 13:0645d8841f51 173 }
bogdanm 13:0645d8841f51 174
bogdanm 13:0645d8841f51 175 static inline int spi_readable(spi_t * obj) {
bogdanm 13:0645d8841f51 176 return (obj->spi->S & SPI_S_SPRF_MASK) ? 1 : 0;
bogdanm 15:4892fe388435 177 }
bogdanm 15:4892fe388435 178
bogdanm 15:4892fe388435 179 int spi_master_write(spi_t *obj, int value) {
bogdanm 15:4892fe388435 180 // wait tx buffer empty
bogdanm 15:4892fe388435 181 while(!spi_writeable(obj));
bogdanm 15:4892fe388435 182 obj->spi->D = (value & 0xff);
bogdanm 15:4892fe388435 183
bogdanm 15:4892fe388435 184 // wait rx buffer full
bogdanm 15:4892fe388435 185 while (!spi_readable(obj));
bogdanm 15:4892fe388435 186 return obj->spi->D & 0xff;
bogdanm 13:0645d8841f51 187 }
bogdanm 13:0645d8841f51 188
bogdanm 13:0645d8841f51 189 int spi_slave_receive(spi_t *obj) {
bogdanm 13:0645d8841f51 190 return spi_readable(obj);
bogdanm 13:0645d8841f51 191 }
bogdanm 13:0645d8841f51 192
bogdanm 13:0645d8841f51 193 int spi_slave_read(spi_t *obj) {
bogdanm 13:0645d8841f51 194 return obj->spi->D;
bogdanm 13:0645d8841f51 195 }
bogdanm 13:0645d8841f51 196
bogdanm 13:0645d8841f51 197 void spi_slave_write(spi_t *obj, int value) {
bogdanm 13:0645d8841f51 198 while (!spi_writeable(obj));
bogdanm 13:0645d8841f51 199 obj->spi->D = value;
bogdanm 15:4892fe388435 200 }