mbed library sources

Dependents:   Freedman_v2 Nucleo_i2c_OLED_BME280_copy

Fork of mbed-src by mbed official

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 }