mbed library sources

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Tue Jun 09 15:30:08 2015 +0100
Revision:
563:9f26fcd0c9ce
Parent:
558:0880f51c4036
Synchronized with git revision a140fc60a6f74003a3d46c4ce8bf8c742148b9fd

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 558:0880f51c4036 1 /* mbed Microcontroller Library
mbed_official 558:0880f51c4036 2 *******************************************************************************
mbed_official 558:0880f51c4036 3 * Copyright (c) 2015 WIZnet Co.,Ltd. All rights reserved.
mbed_official 558:0880f51c4036 4 * All rights reserved.
mbed_official 558:0880f51c4036 5 *
mbed_official 558:0880f51c4036 6 * Redistribution and use in source and binary forms, with or without
mbed_official 558:0880f51c4036 7 * modification, are permitted provided that the following conditions are met:
mbed_official 558:0880f51c4036 8 *
mbed_official 558:0880f51c4036 9 * 1. Redistributions of source code must retain the above copyright notice,
mbed_official 558:0880f51c4036 10 * this list of conditions and the following disclaimer.
mbed_official 558:0880f51c4036 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
mbed_official 558:0880f51c4036 12 * this list of conditions and the following disclaimer in the documentation
mbed_official 558:0880f51c4036 13 * and/or other materials provided with the distribution.
mbed_official 558:0880f51c4036 14 * 3. Neither the name of ARM Limited nor the names of its contributors
mbed_official 558:0880f51c4036 15 * may be used to endorse or promote products derived from this software
mbed_official 558:0880f51c4036 16 * without specific prior written permission.
mbed_official 558:0880f51c4036 17 *
mbed_official 558:0880f51c4036 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
mbed_official 558:0880f51c4036 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
mbed_official 558:0880f51c4036 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
mbed_official 558:0880f51c4036 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
mbed_official 558:0880f51c4036 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
mbed_official 558:0880f51c4036 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
mbed_official 558:0880f51c4036 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
mbed_official 558:0880f51c4036 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
mbed_official 558:0880f51c4036 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
mbed_official 558:0880f51c4036 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
mbed_official 558:0880f51c4036 28 *******************************************************************************
mbed_official 558:0880f51c4036 29 */
mbed_official 558:0880f51c4036 30
mbed_official 558:0880f51c4036 31 #include "mbed_assert.h"
mbed_official 558:0880f51c4036 32 #include <math.h>
mbed_official 558:0880f51c4036 33
mbed_official 558:0880f51c4036 34 #include "spi_api.h"
mbed_official 558:0880f51c4036 35 #include "cmsis.h"
mbed_official 558:0880f51c4036 36 #include "pinmap.h"
mbed_official 558:0880f51c4036 37 #include "mbed_error.h"
mbed_official 558:0880f51c4036 38 #include "PeripheralPins.h"
mbed_official 558:0880f51c4036 39
mbed_official 558:0880f51c4036 40 static inline int ssp_disable(spi_t *obj);
mbed_official 558:0880f51c4036 41 static inline int ssp_enable(spi_t *obj);
mbed_official 558:0880f51c4036 42
mbed_official 558:0880f51c4036 43 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
mbed_official 558:0880f51c4036 44 // determine the SPI to use
mbed_official 558:0880f51c4036 45 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
mbed_official 558:0880f51c4036 46 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
mbed_official 558:0880f51c4036 47 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
mbed_official 558:0880f51c4036 48 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
mbed_official 558:0880f51c4036 49 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
mbed_official 558:0880f51c4036 50 SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
mbed_official 558:0880f51c4036 51 obj->spi = (SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl);
mbed_official 558:0880f51c4036 52 MBED_ASSERT((int)obj->spi != NC);
mbed_official 558:0880f51c4036 53
mbed_official 558:0880f51c4036 54 // enable power and clocking
mbed_official 558:0880f51c4036 55 switch ((int)obj->spi) {
mbed_official 558:0880f51c4036 56 case SPI_0: CRG->SSPCLK_SSR = CRG_SSPCLK_SSR_MCLK; break; //PLL output clock
mbed_official 558:0880f51c4036 57 case SPI_1: CRG->SSPCLK_SSR = CRG_SSPCLK_SSR_MCLK; break;
mbed_official 558:0880f51c4036 58 }
mbed_official 558:0880f51c4036 59
mbed_official 558:0880f51c4036 60 // set default format and frequency
mbed_official 558:0880f51c4036 61 if (ssel == NC) {
mbed_official 558:0880f51c4036 62 spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master
mbed_official 558:0880f51c4036 63 } else {
mbed_official 558:0880f51c4036 64 spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave
mbed_official 558:0880f51c4036 65 }
mbed_official 558:0880f51c4036 66 spi_frequency(obj, 1000000);
mbed_official 558:0880f51c4036 67
mbed_official 558:0880f51c4036 68 // enable the ssp channel
mbed_official 558:0880f51c4036 69 ssp_enable(obj);
mbed_official 558:0880f51c4036 70
mbed_official 558:0880f51c4036 71 // pin out the spi pins
mbed_official 558:0880f51c4036 72 pinmap_pinout(mosi, PinMap_SPI_MOSI);
mbed_official 558:0880f51c4036 73 pinmap_pinout(miso, PinMap_SPI_MISO);
mbed_official 558:0880f51c4036 74 pinmap_pinout(sclk, PinMap_SPI_SCLK);
mbed_official 558:0880f51c4036 75 if (ssel != NC) {
mbed_official 558:0880f51c4036 76 pinmap_pinout(ssel, PinMap_SPI_SSEL);
mbed_official 558:0880f51c4036 77 }
mbed_official 558:0880f51c4036 78 }
mbed_official 558:0880f51c4036 79
mbed_official 558:0880f51c4036 80 void spi_free(spi_t *obj) {}
mbed_official 558:0880f51c4036 81
mbed_official 558:0880f51c4036 82 void spi_format(spi_t *obj, int bits, int mode, int slave) {
mbed_official 558:0880f51c4036 83 ssp_disable(obj);
mbed_official 558:0880f51c4036 84 MBED_ASSERT(((bits >= 4) && (bits <= 16)) && (mode >= 0 && mode <= 3));
mbed_official 558:0880f51c4036 85
mbed_official 558:0880f51c4036 86 int polarity = (mode & 0x2) ? 1 : 0;
mbed_official 558:0880f51c4036 87 int phase = (mode & 0x1) ? 1 : 0;
mbed_official 558:0880f51c4036 88
mbed_official 558:0880f51c4036 89 // set it up
mbed_official 558:0880f51c4036 90 int DSS = bits - 1; // DSS (data select size)
mbed_official 558:0880f51c4036 91 int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity
mbed_official 558:0880f51c4036 92 int SPH = (phase) ? 1 : 0; // SPH - clock out phase
mbed_official 558:0880f51c4036 93
mbed_official 558:0880f51c4036 94 int FRF = 0; // FRF (frame format) = SPI
mbed_official 558:0880f51c4036 95 uint32_t tmp = obj->spi->CR0;
mbed_official 558:0880f51c4036 96 tmp &= ~(0xFFFF);
mbed_official 558:0880f51c4036 97 tmp |= DSS << 0
mbed_official 558:0880f51c4036 98 | FRF << 4
mbed_official 558:0880f51c4036 99 | SPO << 6
mbed_official 558:0880f51c4036 100 | SPH << 7;
mbed_official 558:0880f51c4036 101 obj->spi->CR0 = tmp;
mbed_official 558:0880f51c4036 102
mbed_official 558:0880f51c4036 103 tmp = obj->spi->CR1;
mbed_official 558:0880f51c4036 104 tmp &= ~(0xD);
mbed_official 558:0880f51c4036 105 tmp |= 0 << 0 // LBM - loop back mode - off
mbed_official 558:0880f51c4036 106 | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave
mbed_official 558:0880f51c4036 107 | 0 << 3; // SOD - slave output disable - na
mbed_official 558:0880f51c4036 108 obj->spi->CR1 = tmp;
mbed_official 558:0880f51c4036 109
mbed_official 558:0880f51c4036 110 ssp_enable(obj);
mbed_official 558:0880f51c4036 111 }
mbed_official 558:0880f51c4036 112
mbed_official 558:0880f51c4036 113 void spi_frequency(spi_t *obj, int hz) {
mbed_official 558:0880f51c4036 114 ssp_disable(obj);
mbed_official 558:0880f51c4036 115
mbed_official 558:0880f51c4036 116 // setup the spi clock diveder to /1
mbed_official 558:0880f51c4036 117 switch ((int)obj->spi) {
mbed_official 558:0880f51c4036 118 case SPI_0:
mbed_official 558:0880f51c4036 119 CRG->SSPCLK_PVSR = CRG_SSPCLK_PVSR_DIV1; //1/1 (bypass)
mbed_official 558:0880f51c4036 120 break;
mbed_official 558:0880f51c4036 121 case SPI_1:
mbed_official 558:0880f51c4036 122 CRG->SSPCLK_PVSR = CRG_SSPCLK_PVSR_DIV1; //1/1 (bypass)
mbed_official 558:0880f51c4036 123 break;
mbed_official 558:0880f51c4036 124 }
mbed_official 558:0880f51c4036 125
mbed_official 558:0880f51c4036 126 uint32_t HCLK = SystemCoreClock;
mbed_official 558:0880f51c4036 127
mbed_official 558:0880f51c4036 128 int prescaler;
mbed_official 558:0880f51c4036 129
mbed_official 558:0880f51c4036 130 for (prescaler = 2; prescaler <= 254; prescaler += 2) {
mbed_official 558:0880f51c4036 131 int prescale_hz = HCLK / prescaler;
mbed_official 558:0880f51c4036 132
mbed_official 558:0880f51c4036 133 // calculate the divider
mbed_official 558:0880f51c4036 134 int divider = floor(((float)prescale_hz / (float)hz) + 0.5f);
mbed_official 558:0880f51c4036 135
mbed_official 558:0880f51c4036 136 // check we can support the divider
mbed_official 558:0880f51c4036 137 if (divider < 256) {
mbed_official 558:0880f51c4036 138 // prescaler
mbed_official 558:0880f51c4036 139 obj->spi->CPSR = prescaler;
mbed_official 558:0880f51c4036 140
mbed_official 558:0880f51c4036 141 // divider
mbed_official 558:0880f51c4036 142 obj->spi->CR0 &= ~(0xFFFF << 8);
mbed_official 558:0880f51c4036 143 obj->spi->CR0 |= (divider - 1) << 8;
mbed_official 558:0880f51c4036 144 ssp_enable(obj);
mbed_official 558:0880f51c4036 145 return;
mbed_official 558:0880f51c4036 146 }
mbed_official 558:0880f51c4036 147 }
mbed_official 558:0880f51c4036 148 error("Couldn't setup requested SPI frequency");
mbed_official 558:0880f51c4036 149 }
mbed_official 558:0880f51c4036 150
mbed_official 558:0880f51c4036 151 static inline int ssp_disable(spi_t *obj) {
mbed_official 558:0880f51c4036 152 return obj->spi->CR1 &= ~(1 << 1);
mbed_official 558:0880f51c4036 153 }
mbed_official 558:0880f51c4036 154
mbed_official 558:0880f51c4036 155 static inline int ssp_enable(spi_t *obj) {
mbed_official 558:0880f51c4036 156 return obj->spi->CR1 |= (1 << 1);
mbed_official 558:0880f51c4036 157 }
mbed_official 558:0880f51c4036 158
mbed_official 558:0880f51c4036 159 static inline int ssp_readable(spi_t *obj) {
mbed_official 558:0880f51c4036 160 return obj->spi->SR & (1 << 2);
mbed_official 558:0880f51c4036 161 }
mbed_official 558:0880f51c4036 162
mbed_official 558:0880f51c4036 163 static inline int ssp_writeable(spi_t *obj) {
mbed_official 558:0880f51c4036 164 return obj->spi->SR & (1 << 1);
mbed_official 558:0880f51c4036 165 }
mbed_official 558:0880f51c4036 166
mbed_official 558:0880f51c4036 167 static inline void ssp_write(spi_t *obj, int value) {
mbed_official 558:0880f51c4036 168 while (!ssp_writeable(obj));
mbed_official 558:0880f51c4036 169 obj->spi->DR = value;
mbed_official 558:0880f51c4036 170 }
mbed_official 558:0880f51c4036 171
mbed_official 558:0880f51c4036 172 static inline int ssp_read(spi_t *obj) {
mbed_official 558:0880f51c4036 173 while (!ssp_readable(obj));
mbed_official 558:0880f51c4036 174 return obj->spi->DR;
mbed_official 558:0880f51c4036 175 }
mbed_official 558:0880f51c4036 176
mbed_official 558:0880f51c4036 177 static inline int ssp_busy(spi_t *obj) {
mbed_official 558:0880f51c4036 178 return (obj->spi->SR & (1 << 4)) ? (1) : (0);
mbed_official 558:0880f51c4036 179 }
mbed_official 558:0880f51c4036 180
mbed_official 558:0880f51c4036 181 int spi_master_write(spi_t *obj, int value) {
mbed_official 558:0880f51c4036 182 ssp_write(obj, value);
mbed_official 558:0880f51c4036 183 return ssp_read(obj);
mbed_official 558:0880f51c4036 184 }
mbed_official 558:0880f51c4036 185
mbed_official 558:0880f51c4036 186 int spi_slave_receive(spi_t *obj) {
mbed_official 558:0880f51c4036 187 return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
mbed_official 558:0880f51c4036 188 }
mbed_official 558:0880f51c4036 189
mbed_official 558:0880f51c4036 190 int spi_slave_read(spi_t *obj) {
mbed_official 558:0880f51c4036 191 return obj->spi->DR;
mbed_official 558:0880f51c4036 192 }
mbed_official 558:0880f51c4036 193
mbed_official 558:0880f51c4036 194 void spi_slave_write(spi_t *obj, int value) {
mbed_official 558:0880f51c4036 195 while (ssp_writeable(obj) == 0) ;
mbed_official 558:0880f51c4036 196 obj->spi->DR = value;
mbed_official 558:0880f51c4036 197 }
mbed_official 558:0880f51c4036 198
mbed_official 558:0880f51c4036 199 int spi_busy(spi_t *obj) {
mbed_official 558:0880f51c4036 200 return ssp_busy(obj);
mbed_official 558:0880f51c4036 201 }
mbed_official 558:0880f51c4036 202