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:
Thu Jul 02 16:15:09 2015 +0100
Revision:
580:3c14cb9b87c5
Synchronized with git revision 213caf296f26963a7bea129b8ec4f33bbd1e6588

Full URL: https://github.com/mbedmicro/mbed/commit/213caf296f26963a7bea129b8ec4f33bbd1e6588/

commit of mps2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 580:3c14cb9b87c5 1 /* mbed Microcontroller Library
mbed_official 580:3c14cb9b87c5 2 * Copyright (c) 2006-2015 ARM Limited
mbed_official 580:3c14cb9b87c5 3 *
mbed_official 580:3c14cb9b87c5 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 580:3c14cb9b87c5 5 * you may not use this file except in compliance with the License.
mbed_official 580:3c14cb9b87c5 6 * You may obtain a copy of the License at
mbed_official 580:3c14cb9b87c5 7 *
mbed_official 580:3c14cb9b87c5 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 580:3c14cb9b87c5 9 *
mbed_official 580:3c14cb9b87c5 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 580:3c14cb9b87c5 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 580:3c14cb9b87c5 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 580:3c14cb9b87c5 13 * See the License for the specific language governing permissions and
mbed_official 580:3c14cb9b87c5 14 * limitations under the License.
mbed_official 580:3c14cb9b87c5 15 */
mbed_official 580:3c14cb9b87c5 16 #include <math.h>
mbed_official 580:3c14cb9b87c5 17
mbed_official 580:3c14cb9b87c5 18 #include "spi_api.h"
mbed_official 580:3c14cb9b87c5 19 #include "spi_def.h"
mbed_official 580:3c14cb9b87c5 20 #include "cmsis.h"
mbed_official 580:3c14cb9b87c5 21 #include "pinmap.h"
mbed_official 580:3c14cb9b87c5 22 #include "mbed_error.h"
mbed_official 580:3c14cb9b87c5 23 #include "wait_api.h"
mbed_official 580:3c14cb9b87c5 24
mbed_official 580:3c14cb9b87c5 25 static const PinMap PinMap_SPI_SCLK[] = {
mbed_official 580:3c14cb9b87c5 26 {SCLK_SPI , SPI_0, 0},
mbed_official 580:3c14cb9b87c5 27 {CLCD_SCLK , SPI_1, 0},
mbed_official 580:3c14cb9b87c5 28 {NC , NC , 0}
mbed_official 580:3c14cb9b87c5 29 };
mbed_official 580:3c14cb9b87c5 30
mbed_official 580:3c14cb9b87c5 31 static const PinMap PinMap_SPI_MOSI[] = {
mbed_official 580:3c14cb9b87c5 32 {MOSI_SPI, SPI_0, 0},
mbed_official 580:3c14cb9b87c5 33 {CLCD_MOSI, SPI_1, 0},
mbed_official 580:3c14cb9b87c5 34 {NC , NC , 0}
mbed_official 580:3c14cb9b87c5 35 };
mbed_official 580:3c14cb9b87c5 36
mbed_official 580:3c14cb9b87c5 37 static const PinMap PinMap_SPI_MISO[] = {
mbed_official 580:3c14cb9b87c5 38 {MISO_SPI, SPI_0, 0},
mbed_official 580:3c14cb9b87c5 39 {CLCD_MISO, SPI_1, 0},
mbed_official 580:3c14cb9b87c5 40 {NC , NC , 0}
mbed_official 580:3c14cb9b87c5 41 };
mbed_official 580:3c14cb9b87c5 42
mbed_official 580:3c14cb9b87c5 43 static const PinMap PinMap_SPI_SSEL[] = {
mbed_official 580:3c14cb9b87c5 44 {SSEL_SPI, SPI_0, 0},
mbed_official 580:3c14cb9b87c5 45 {CLCD_SSEL, SPI_1, 0},
mbed_official 580:3c14cb9b87c5 46 {NC , NC , 0}
mbed_official 580:3c14cb9b87c5 47 };
mbed_official 580:3c14cb9b87c5 48
mbed_official 580:3c14cb9b87c5 49 static inline int ssp_disable(spi_t *obj);
mbed_official 580:3c14cb9b87c5 50 static inline int ssp_enable(spi_t *obj);
mbed_official 580:3c14cb9b87c5 51
mbed_official 580:3c14cb9b87c5 52 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
mbed_official 580:3c14cb9b87c5 53 // determine the SPI to use
mbed_official 580:3c14cb9b87c5 54 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
mbed_official 580:3c14cb9b87c5 55 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
mbed_official 580:3c14cb9b87c5 56 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
mbed_official 580:3c14cb9b87c5 57 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
mbed_official 580:3c14cb9b87c5 58 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
mbed_official 580:3c14cb9b87c5 59 SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
mbed_official 580:3c14cb9b87c5 60 obj->spi = (MPS2_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl);
mbed_official 580:3c14cb9b87c5 61 if ((int)obj->spi == NC) {
mbed_official 580:3c14cb9b87c5 62 error("SPI pinout mapping failed");
mbed_official 580:3c14cb9b87c5 63 }
mbed_official 580:3c14cb9b87c5 64
mbed_official 580:3c14cb9b87c5 65 // enable power and clocking
mbed_official 580:3c14cb9b87c5 66 switch ((int)obj->spi) {
mbed_official 580:3c14cb9b87c5 67 case (int)SPI_0:
mbed_official 580:3c14cb9b87c5 68 obj->spi->CR1 = 0;
mbed_official 580:3c14cb9b87c5 69 obj->spi->CR0 = SSP_CR0_SCR_DFLT | SSP_CR0_FRF_MOT | SSP_CR0_DSS_8;
mbed_official 580:3c14cb9b87c5 70 obj->spi->CPSR = SSP_CPSR_DFLT;
mbed_official 580:3c14cb9b87c5 71 obj->spi->IMSC = 0x8;
mbed_official 580:3c14cb9b87c5 72 obj->spi->DMACR = 0;
mbed_official 580:3c14cb9b87c5 73 obj->spi->CR1 = SSP_CR1_SSE_Msk;
mbed_official 580:3c14cb9b87c5 74 obj->spi->ICR = 0x3;
mbed_official 580:3c14cb9b87c5 75 break;
mbed_official 580:3c14cb9b87c5 76 case (int)SPI_1:
mbed_official 580:3c14cb9b87c5 77 /* Configure SSP used for LCD */
mbed_official 580:3c14cb9b87c5 78 obj->spi->CR1 = 0; /* Synchronous serial port disable */
mbed_official 580:3c14cb9b87c5 79 obj->spi->DMACR = 0; /* Disable FIFO DMA */
mbed_official 580:3c14cb9b87c5 80 obj->spi->IMSC = 0; /* Mask all FIFO/IRQ interrupts */
mbed_official 580:3c14cb9b87c5 81 obj->spi->ICR = ((1ul << 0) | /* Clear SSPRORINTR interrupt */
mbed_official 580:3c14cb9b87c5 82 (1ul << 1) ); /* Clear SSPRTINTR interrupt */
mbed_official 580:3c14cb9b87c5 83 obj->spi->CR0 = ((7ul << 0) | /* 8 bit data size */
mbed_official 580:3c14cb9b87c5 84 (0ul << 4) | /* Motorola frame format */
mbed_official 580:3c14cb9b87c5 85 (0ul << 6) | /* CPOL = 0 */
mbed_official 580:3c14cb9b87c5 86 (0ul << 7) | /* CPHA = 0 */
mbed_official 580:3c14cb9b87c5 87 (1ul << 8) ); /* Set serial clock rate */
mbed_official 580:3c14cb9b87c5 88 obj->spi->CPSR = (2ul << 0); /* set SSP clk to 6MHz (6.6MHz max) */
mbed_official 580:3c14cb9b87c5 89 obj->spi->CR1 = ((1ul << 1) | /* Synchronous serial port enable */
mbed_official 580:3c14cb9b87c5 90 (0ul << 2) ); /* Device configured as master */
mbed_official 580:3c14cb9b87c5 91 break;
mbed_official 580:3c14cb9b87c5 92 }
mbed_official 580:3c14cb9b87c5 93
mbed_official 580:3c14cb9b87c5 94 // set default format and frequency
mbed_official 580:3c14cb9b87c5 95 if (ssel == NC) {
mbed_official 580:3c14cb9b87c5 96 spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
mbed_official 580:3c14cb9b87c5 97 } else {
mbed_official 580:3c14cb9b87c5 98 spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
mbed_official 580:3c14cb9b87c5 99 }
mbed_official 580:3c14cb9b87c5 100 spi_frequency(obj, 1000000);
mbed_official 580:3c14cb9b87c5 101
mbed_official 580:3c14cb9b87c5 102 // enable the ssp channel
mbed_official 580:3c14cb9b87c5 103 ssp_enable(obj);
mbed_official 580:3c14cb9b87c5 104
mbed_official 580:3c14cb9b87c5 105 // pin out the spi pins
mbed_official 580:3c14cb9b87c5 106 pinmap_pinout(mosi, PinMap_SPI_MOSI);
mbed_official 580:3c14cb9b87c5 107 pinmap_pinout(miso, PinMap_SPI_MISO);
mbed_official 580:3c14cb9b87c5 108 pinmap_pinout(sclk, PinMap_SPI_SCLK);
mbed_official 580:3c14cb9b87c5 109 if (ssel != NC) {
mbed_official 580:3c14cb9b87c5 110 pinmap_pinout(ssel, PinMap_SPI_SSEL);
mbed_official 580:3c14cb9b87c5 111 }
mbed_official 580:3c14cb9b87c5 112 }
mbed_official 580:3c14cb9b87c5 113
mbed_official 580:3c14cb9b87c5 114 void spi_free(spi_t *obj) {}
mbed_official 580:3c14cb9b87c5 115
mbed_official 580:3c14cb9b87c5 116 void spi_format(spi_t *obj, int bits, int mode, int slave) {
mbed_official 580:3c14cb9b87c5 117 ssp_disable(obj);
mbed_official 580:3c14cb9b87c5 118 if (!(bits >= 4 && bits <= 16) || !(mode >= 0 && mode <= 3)) {
mbed_official 580:3c14cb9b87c5 119 error("SPI format error");
mbed_official 580:3c14cb9b87c5 120 }
mbed_official 580:3c14cb9b87c5 121
mbed_official 580:3c14cb9b87c5 122 int polarity = (mode & 0x2) ? 1 : 0;
mbed_official 580:3c14cb9b87c5 123 int phase = (mode & 0x1) ? 1 : 0;
mbed_official 580:3c14cb9b87c5 124
mbed_official 580:3c14cb9b87c5 125 // set it up
mbed_official 580:3c14cb9b87c5 126 int DSS = bits - 1; // DSS (data select size)
mbed_official 580:3c14cb9b87c5 127 int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity
mbed_official 580:3c14cb9b87c5 128 int SPH = (phase) ? 1 : 0; // SPH - clock out phase
mbed_official 580:3c14cb9b87c5 129
mbed_official 580:3c14cb9b87c5 130 int FRF = 0; // FRF (frame format) = SPI
mbed_official 580:3c14cb9b87c5 131 uint32_t tmp = obj->spi->CR0;
mbed_official 580:3c14cb9b87c5 132 tmp &= ~(0xFFFF);
mbed_official 580:3c14cb9b87c5 133 tmp |= DSS << 0
mbed_official 580:3c14cb9b87c5 134 | FRF << 4
mbed_official 580:3c14cb9b87c5 135 | SPO << 6
mbed_official 580:3c14cb9b87c5 136 | SPH << 7;
mbed_official 580:3c14cb9b87c5 137 obj->spi->CR0 = tmp;
mbed_official 580:3c14cb9b87c5 138
mbed_official 580:3c14cb9b87c5 139 tmp = obj->spi->CR1;
mbed_official 580:3c14cb9b87c5 140 tmp &= ~(0xD);
mbed_official 580:3c14cb9b87c5 141 tmp |= 0 << 0 // LBM - loop back mode - off
mbed_official 580:3c14cb9b87c5 142 | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave
mbed_official 580:3c14cb9b87c5 143 | 0 << 3; // SOD - slave output disable - na
mbed_official 580:3c14cb9b87c5 144 obj->spi->CR1 = tmp;
mbed_official 580:3c14cb9b87c5 145
mbed_official 580:3c14cb9b87c5 146 ssp_enable(obj);
mbed_official 580:3c14cb9b87c5 147 }
mbed_official 580:3c14cb9b87c5 148
mbed_official 580:3c14cb9b87c5 149 void spi_frequency(spi_t *obj, int hz) {
mbed_official 580:3c14cb9b87c5 150 ssp_disable(obj);
mbed_official 580:3c14cb9b87c5 151
mbed_official 580:3c14cb9b87c5 152 uint32_t PCLK = SystemCoreClock;
mbed_official 580:3c14cb9b87c5 153
mbed_official 580:3c14cb9b87c5 154 int prescaler;
mbed_official 580:3c14cb9b87c5 155
mbed_official 580:3c14cb9b87c5 156 for (prescaler = 2; prescaler <= 254; prescaler += 2) {
mbed_official 580:3c14cb9b87c5 157 int prescale_hz = PCLK / prescaler;
mbed_official 580:3c14cb9b87c5 158
mbed_official 580:3c14cb9b87c5 159 // calculate the divider
mbed_official 580:3c14cb9b87c5 160 int divider = floor(((float)prescale_hz / (float)hz) + 0.5f);
mbed_official 580:3c14cb9b87c5 161
mbed_official 580:3c14cb9b87c5 162 // check we can support the divider
mbed_official 580:3c14cb9b87c5 163 if (divider < 256) {
mbed_official 580:3c14cb9b87c5 164 // prescaler
mbed_official 580:3c14cb9b87c5 165 obj->spi->CPSR = prescaler;
mbed_official 580:3c14cb9b87c5 166
mbed_official 580:3c14cb9b87c5 167 // divider
mbed_official 580:3c14cb9b87c5 168 obj->spi->CR0 &= ~(0xFFFF << 8);
mbed_official 580:3c14cb9b87c5 169 obj->spi->CR0 |= (divider - 1) << 8;
mbed_official 580:3c14cb9b87c5 170 ssp_enable(obj);
mbed_official 580:3c14cb9b87c5 171 return;
mbed_official 580:3c14cb9b87c5 172 }
mbed_official 580:3c14cb9b87c5 173 }
mbed_official 580:3c14cb9b87c5 174 error("Couldn't setup requested SPI frequency");
mbed_official 580:3c14cb9b87c5 175 }
mbed_official 580:3c14cb9b87c5 176
mbed_official 580:3c14cb9b87c5 177 static inline int ssp_disable(spi_t *obj) {
mbed_official 580:3c14cb9b87c5 178 return obj->spi->CR1 &= ~(1 << 1);
mbed_official 580:3c14cb9b87c5 179 }
mbed_official 580:3c14cb9b87c5 180
mbed_official 580:3c14cb9b87c5 181 static inline int ssp_enable(spi_t *obj) {
mbed_official 580:3c14cb9b87c5 182 return obj->spi->CR1 |= SSP_CR1_SSE_Msk;
mbed_official 580:3c14cb9b87c5 183 }
mbed_official 580:3c14cb9b87c5 184
mbed_official 580:3c14cb9b87c5 185 static inline int ssp_readable(spi_t *obj) {
mbed_official 580:3c14cb9b87c5 186 return obj->spi->SR & (1 << 2);
mbed_official 580:3c14cb9b87c5 187 }
mbed_official 580:3c14cb9b87c5 188
mbed_official 580:3c14cb9b87c5 189 static inline int ssp_writeable(spi_t *obj) {
mbed_official 580:3c14cb9b87c5 190 return obj->spi->SR & SSP_SR_BSY_Msk;
mbed_official 580:3c14cb9b87c5 191 }
mbed_official 580:3c14cb9b87c5 192
mbed_official 580:3c14cb9b87c5 193 static inline void ssp_write(spi_t *obj, int value) {
mbed_official 580:3c14cb9b87c5 194 obj->spi->DR = value;
mbed_official 580:3c14cb9b87c5 195 while (ssp_writeable(obj));
mbed_official 580:3c14cb9b87c5 196 }
mbed_official 580:3c14cb9b87c5 197 static inline int ssp_read(spi_t *obj) {
mbed_official 580:3c14cb9b87c5 198 int read_DR = obj->spi->DR;
mbed_official 580:3c14cb9b87c5 199 return read_DR;
mbed_official 580:3c14cb9b87c5 200 }
mbed_official 580:3c14cb9b87c5 201
mbed_official 580:3c14cb9b87c5 202 static inline int ssp_busy(spi_t *obj) {
mbed_official 580:3c14cb9b87c5 203 return (obj->spi->SR & (1 << 4)) ? (1) : (0);
mbed_official 580:3c14cb9b87c5 204 }
mbed_official 580:3c14cb9b87c5 205
mbed_official 580:3c14cb9b87c5 206 int spi_master_write(spi_t *obj, int value) {
mbed_official 580:3c14cb9b87c5 207 ssp_write(obj, value);
mbed_official 580:3c14cb9b87c5 208 while (MPS2_SSP0->SR & SSP_SR_BSY_Msk); /* Wait for send to finish */
mbed_official 580:3c14cb9b87c5 209 return (ssp_read(obj));
mbed_official 580:3c14cb9b87c5 210 }
mbed_official 580:3c14cb9b87c5 211
mbed_official 580:3c14cb9b87c5 212 int spi_slave_receive(spi_t *obj) {
mbed_official 580:3c14cb9b87c5 213 return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
mbed_official 580:3c14cb9b87c5 214 }
mbed_official 580:3c14cb9b87c5 215
mbed_official 580:3c14cb9b87c5 216 int spi_slave_read(spi_t *obj) {
mbed_official 580:3c14cb9b87c5 217 return obj->spi->DR;
mbed_official 580:3c14cb9b87c5 218 }
mbed_official 580:3c14cb9b87c5 219
mbed_official 580:3c14cb9b87c5 220 void spi_slave_write(spi_t *obj, int value) {
mbed_official 580:3c14cb9b87c5 221 while (ssp_writeable(obj) == 0) ;
mbed_official 580:3c14cb9b87c5 222 obj->spi->DR = value;
mbed_official 580:3c14cb9b87c5 223 }
mbed_official 580:3c14cb9b87c5 224
mbed_official 580:3c14cb9b87c5 225 int spi_busy(spi_t *obj) {
mbed_official 580:3c14cb9b87c5 226 return ssp_busy(obj);
mbed_official 580:3c14cb9b87c5 227 }