mbed library sources

Dependents:   FRDM-KL46Z_LCD_Test FRDM-KL46Z_LCD_Test FRDM-KL46Z_Plantilla FRDM-KL46Z_Plantilla ... more

Committer:
ebrus
Date:
Thu Jul 28 15:56:34 2016 +0000
Revision:
0:6bc4ac881c8e
1;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ebrus 0:6bc4ac881c8e 1 /* mbed Microcontroller Library
ebrus 0:6bc4ac881c8e 2 *******************************************************************************
ebrus 0:6bc4ac881c8e 3 * Copyright (c) 2014, STMicroelectronics
ebrus 0:6bc4ac881c8e 4 * All rights reserved.
ebrus 0:6bc4ac881c8e 5 *
ebrus 0:6bc4ac881c8e 6 * Redistribution and use in source and binary forms, with or without
ebrus 0:6bc4ac881c8e 7 * modification, are permitted provided that the following conditions are met:
ebrus 0:6bc4ac881c8e 8 *
ebrus 0:6bc4ac881c8e 9 * 1. Redistributions of source code must retain the above copyright notice,
ebrus 0:6bc4ac881c8e 10 * this list of conditions and the following disclaimer.
ebrus 0:6bc4ac881c8e 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
ebrus 0:6bc4ac881c8e 12 * this list of conditions and the following disclaimer in the documentation
ebrus 0:6bc4ac881c8e 13 * and/or other materials provided with the distribution.
ebrus 0:6bc4ac881c8e 14 * 3. Neither the name of STMicroelectronics nor the names of its contributors
ebrus 0:6bc4ac881c8e 15 * may be used to endorse or promote products derived from this software
ebrus 0:6bc4ac881c8e 16 * without specific prior written permission.
ebrus 0:6bc4ac881c8e 17 *
ebrus 0:6bc4ac881c8e 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
ebrus 0:6bc4ac881c8e 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ebrus 0:6bc4ac881c8e 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ebrus 0:6bc4ac881c8e 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
ebrus 0:6bc4ac881c8e 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ebrus 0:6bc4ac881c8e 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
ebrus 0:6bc4ac881c8e 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
ebrus 0:6bc4ac881c8e 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
ebrus 0:6bc4ac881c8e 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
ebrus 0:6bc4ac881c8e 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ebrus 0:6bc4ac881c8e 28 *******************************************************************************
ebrus 0:6bc4ac881c8e 29 */
ebrus 0:6bc4ac881c8e 30 #include "mbed_assert.h"
ebrus 0:6bc4ac881c8e 31 #include "spi_api.h"
ebrus 0:6bc4ac881c8e 32
ebrus 0:6bc4ac881c8e 33 #if DEVICE_SPI
ebrus 0:6bc4ac881c8e 34
ebrus 0:6bc4ac881c8e 35 #include <math.h>
ebrus 0:6bc4ac881c8e 36 #include "cmsis.h"
ebrus 0:6bc4ac881c8e 37 #include "pinmap.h"
ebrus 0:6bc4ac881c8e 38
ebrus 0:6bc4ac881c8e 39 static const PinMap PinMap_SPI_MOSI[] = {
ebrus 0:6bc4ac881c8e 40 {PA_1, SPI_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI4)},
ebrus 0:6bc4ac881c8e 41 {PA_7, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, // ARDUINO
ebrus 0:6bc4ac881c8e 42 {PA_10, SPI_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI5)},
ebrus 0:6bc4ac881c8e 43 // {PB_5, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
ebrus 0:6bc4ac881c8e 44 {PB_5, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
ebrus 0:6bc4ac881c8e 45 {PB_8, SPI_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI5)},
ebrus 0:6bc4ac881c8e 46 {PB_15, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
ebrus 0:6bc4ac881c8e 47 {PC_3, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
ebrus 0:6bc4ac881c8e 48 {PC_12, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
ebrus 0:6bc4ac881c8e 49 {NC, NC, 0}
ebrus 0:6bc4ac881c8e 50 };
ebrus 0:6bc4ac881c8e 51
ebrus 0:6bc4ac881c8e 52 static const PinMap PinMap_SPI_MISO[] = {
ebrus 0:6bc4ac881c8e 53 {PA_6, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, // ARDUINO
ebrus 0:6bc4ac881c8e 54 {PA_11, SPI_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI4)},
ebrus 0:6bc4ac881c8e 55 {PA_12, SPI_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI5)},
ebrus 0:6bc4ac881c8e 56 // {PB_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
ebrus 0:6bc4ac881c8e 57 {PB_4, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
ebrus 0:6bc4ac881c8e 58 {PB_14, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
ebrus 0:6bc4ac881c8e 59 {PC_2, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
ebrus 0:6bc4ac881c8e 60 {PC_11, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
ebrus 0:6bc4ac881c8e 61 {NC, NC, 0}
ebrus 0:6bc4ac881c8e 62 };
ebrus 0:6bc4ac881c8e 63
ebrus 0:6bc4ac881c8e 64 static const PinMap PinMap_SPI_SCLK[] = {
ebrus 0:6bc4ac881c8e 65 {PA_5, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, // ARDUINO
ebrus 0:6bc4ac881c8e 66 {PB_0, SPI_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI5)},
ebrus 0:6bc4ac881c8e 67 // {PB_3, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
ebrus 0:6bc4ac881c8e 68 {PB_3, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
ebrus 0:6bc4ac881c8e 69 {PB_10, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
ebrus 0:6bc4ac881c8e 70 // {PB_12, SPI_3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF7_SPI3)}, // Warning: also on NSS
ebrus 0:6bc4ac881c8e 71 {PB_13, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
ebrus 0:6bc4ac881c8e 72 // {PB_13, SPI_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI4)},
ebrus 0:6bc4ac881c8e 73 {PC_7, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
ebrus 0:6bc4ac881c8e 74 {PC_10, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
ebrus 0:6bc4ac881c8e 75 {NC, NC, 0}
ebrus 0:6bc4ac881c8e 76 };
ebrus 0:6bc4ac881c8e 77
ebrus 0:6bc4ac881c8e 78 static const PinMap PinMap_SPI_SSEL[] = {
ebrus 0:6bc4ac881c8e 79 {PA_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)},
ebrus 0:6bc4ac881c8e 80 // {PA_4, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF6_SPI3)},
ebrus 0:6bc4ac881c8e 81 {PA_15, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)},
ebrus 0:6bc4ac881c8e 82 // {PA_15, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF6_SPI3)},
ebrus 0:6bc4ac881c8e 83 {PB_1, SPI_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI5)},
ebrus 0:6bc4ac881c8e 84 {PB_9, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI2)},
ebrus 0:6bc4ac881c8e 85 {PB_12, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI2)}, // Warning: also on SCLK
ebrus 0:6bc4ac881c8e 86 // {PB_12, SPI_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF6_SPI4)}, // Warning: also on SCLK
ebrus 0:6bc4ac881c8e 87 {NC, NC, 0}
ebrus 0:6bc4ac881c8e 88 };
ebrus 0:6bc4ac881c8e 89
ebrus 0:6bc4ac881c8e 90 static SPI_HandleTypeDef SpiHandle;
ebrus 0:6bc4ac881c8e 91
ebrus 0:6bc4ac881c8e 92 static void init_spi(spi_t *obj)
ebrus 0:6bc4ac881c8e 93 {
ebrus 0:6bc4ac881c8e 94 SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
ebrus 0:6bc4ac881c8e 95
ebrus 0:6bc4ac881c8e 96 __HAL_SPI_DISABLE(&SpiHandle);
ebrus 0:6bc4ac881c8e 97
ebrus 0:6bc4ac881c8e 98 SpiHandle.Init.Mode = obj->mode;
ebrus 0:6bc4ac881c8e 99 SpiHandle.Init.BaudRatePrescaler = obj->br_presc;
ebrus 0:6bc4ac881c8e 100 SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
ebrus 0:6bc4ac881c8e 101 SpiHandle.Init.CLKPhase = obj->cpha;
ebrus 0:6bc4ac881c8e 102 SpiHandle.Init.CLKPolarity = obj->cpol;
ebrus 0:6bc4ac881c8e 103 SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
ebrus 0:6bc4ac881c8e 104 SpiHandle.Init.CRCPolynomial = 7;
ebrus 0:6bc4ac881c8e 105 SpiHandle.Init.DataSize = obj->bits;
ebrus 0:6bc4ac881c8e 106 SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
ebrus 0:6bc4ac881c8e 107 SpiHandle.Init.NSS = obj->nss;
ebrus 0:6bc4ac881c8e 108 SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED;
ebrus 0:6bc4ac881c8e 109
ebrus 0:6bc4ac881c8e 110 HAL_SPI_Init(&SpiHandle);
ebrus 0:6bc4ac881c8e 111
ebrus 0:6bc4ac881c8e 112 __HAL_SPI_ENABLE(&SpiHandle);
ebrus 0:6bc4ac881c8e 113 }
ebrus 0:6bc4ac881c8e 114
ebrus 0:6bc4ac881c8e 115 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
ebrus 0:6bc4ac881c8e 116 {
ebrus 0:6bc4ac881c8e 117 // Determine the SPI to use
ebrus 0:6bc4ac881c8e 118 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
ebrus 0:6bc4ac881c8e 119 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
ebrus 0:6bc4ac881c8e 120 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
ebrus 0:6bc4ac881c8e 121 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
ebrus 0:6bc4ac881c8e 122
ebrus 0:6bc4ac881c8e 123 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
ebrus 0:6bc4ac881c8e 124 SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
ebrus 0:6bc4ac881c8e 125
ebrus 0:6bc4ac881c8e 126 obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
ebrus 0:6bc4ac881c8e 127 MBED_ASSERT(obj->spi != (SPIName)NC);
ebrus 0:6bc4ac881c8e 128
ebrus 0:6bc4ac881c8e 129 // Enable SPI clock
ebrus 0:6bc4ac881c8e 130 if (obj->spi == SPI_1) {
ebrus 0:6bc4ac881c8e 131 __SPI1_CLK_ENABLE();
ebrus 0:6bc4ac881c8e 132 }
ebrus 0:6bc4ac881c8e 133 if (obj->spi == SPI_2) {
ebrus 0:6bc4ac881c8e 134 __SPI2_CLK_ENABLE();
ebrus 0:6bc4ac881c8e 135 }
ebrus 0:6bc4ac881c8e 136 if (obj->spi == SPI_3) {
ebrus 0:6bc4ac881c8e 137 __SPI3_CLK_ENABLE();
ebrus 0:6bc4ac881c8e 138 }
ebrus 0:6bc4ac881c8e 139 if (obj->spi == SPI_4) {
ebrus 0:6bc4ac881c8e 140 __SPI4_CLK_ENABLE();
ebrus 0:6bc4ac881c8e 141 }
ebrus 0:6bc4ac881c8e 142 if (obj->spi == SPI_5) {
ebrus 0:6bc4ac881c8e 143 __SPI5_CLK_ENABLE();
ebrus 0:6bc4ac881c8e 144 }
ebrus 0:6bc4ac881c8e 145
ebrus 0:6bc4ac881c8e 146 // Configure the SPI pins
ebrus 0:6bc4ac881c8e 147 pinmap_pinout(mosi, PinMap_SPI_MOSI);
ebrus 0:6bc4ac881c8e 148 pinmap_pinout(miso, PinMap_SPI_MISO);
ebrus 0:6bc4ac881c8e 149 pinmap_pinout(sclk, PinMap_SPI_SCLK);
ebrus 0:6bc4ac881c8e 150
ebrus 0:6bc4ac881c8e 151 // Save new values
ebrus 0:6bc4ac881c8e 152 obj->bits = SPI_DATASIZE_8BIT;
ebrus 0:6bc4ac881c8e 153 obj->cpol = SPI_POLARITY_LOW;
ebrus 0:6bc4ac881c8e 154 obj->cpha = SPI_PHASE_1EDGE;
ebrus 0:6bc4ac881c8e 155 obj->br_presc = SPI_BAUDRATEPRESCALER_256;
ebrus 0:6bc4ac881c8e 156
ebrus 0:6bc4ac881c8e 157 obj->pin_miso = miso;
ebrus 0:6bc4ac881c8e 158 obj->pin_mosi = mosi;
ebrus 0:6bc4ac881c8e 159 obj->pin_sclk = sclk;
ebrus 0:6bc4ac881c8e 160 obj->pin_ssel = ssel;
ebrus 0:6bc4ac881c8e 161
ebrus 0:6bc4ac881c8e 162 if (ssel == NC) { // SW NSS Master mode
ebrus 0:6bc4ac881c8e 163 obj->mode = SPI_MODE_MASTER;
ebrus 0:6bc4ac881c8e 164 obj->nss = SPI_NSS_SOFT;
ebrus 0:6bc4ac881c8e 165 } else { // Slave
ebrus 0:6bc4ac881c8e 166 pinmap_pinout(ssel, PinMap_SPI_SSEL);
ebrus 0:6bc4ac881c8e 167 obj->mode = SPI_MODE_SLAVE;
ebrus 0:6bc4ac881c8e 168 obj->nss = SPI_NSS_HARD_INPUT;
ebrus 0:6bc4ac881c8e 169 }
ebrus 0:6bc4ac881c8e 170
ebrus 0:6bc4ac881c8e 171 init_spi(obj);
ebrus 0:6bc4ac881c8e 172 }
ebrus 0:6bc4ac881c8e 173
ebrus 0:6bc4ac881c8e 174 void spi_free(spi_t *obj)
ebrus 0:6bc4ac881c8e 175 {
ebrus 0:6bc4ac881c8e 176 // Reset SPI and disable clock
ebrus 0:6bc4ac881c8e 177 if (obj->spi == SPI_1) {
ebrus 0:6bc4ac881c8e 178 __SPI1_FORCE_RESET();
ebrus 0:6bc4ac881c8e 179 __SPI1_RELEASE_RESET();
ebrus 0:6bc4ac881c8e 180 __SPI1_CLK_DISABLE();
ebrus 0:6bc4ac881c8e 181 }
ebrus 0:6bc4ac881c8e 182 if (obj->spi == SPI_2) {
ebrus 0:6bc4ac881c8e 183 __SPI2_FORCE_RESET();
ebrus 0:6bc4ac881c8e 184 __SPI2_RELEASE_RESET();
ebrus 0:6bc4ac881c8e 185 __SPI2_CLK_DISABLE();
ebrus 0:6bc4ac881c8e 186 }
ebrus 0:6bc4ac881c8e 187 if (obj->spi == SPI_3) {
ebrus 0:6bc4ac881c8e 188 __SPI3_FORCE_RESET();
ebrus 0:6bc4ac881c8e 189 __SPI3_RELEASE_RESET();
ebrus 0:6bc4ac881c8e 190 __SPI3_CLK_DISABLE();
ebrus 0:6bc4ac881c8e 191 }
ebrus 0:6bc4ac881c8e 192 if (obj->spi == SPI_4) {
ebrus 0:6bc4ac881c8e 193 __SPI4_FORCE_RESET();
ebrus 0:6bc4ac881c8e 194 __SPI4_RELEASE_RESET();
ebrus 0:6bc4ac881c8e 195 __SPI4_CLK_DISABLE();
ebrus 0:6bc4ac881c8e 196 }
ebrus 0:6bc4ac881c8e 197 if (obj->spi == SPI_5) {
ebrus 0:6bc4ac881c8e 198 __SPI5_FORCE_RESET();
ebrus 0:6bc4ac881c8e 199 __SPI5_RELEASE_RESET();
ebrus 0:6bc4ac881c8e 200 __SPI5_CLK_DISABLE();
ebrus 0:6bc4ac881c8e 201 }
ebrus 0:6bc4ac881c8e 202
ebrus 0:6bc4ac881c8e 203 // Configure GPIOs
ebrus 0:6bc4ac881c8e 204 pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
ebrus 0:6bc4ac881c8e 205 pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
ebrus 0:6bc4ac881c8e 206 pin_function(obj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
ebrus 0:6bc4ac881c8e 207 pin_function(obj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
ebrus 0:6bc4ac881c8e 208 }
ebrus 0:6bc4ac881c8e 209
ebrus 0:6bc4ac881c8e 210 void spi_format(spi_t *obj, int bits, int mode, int slave)
ebrus 0:6bc4ac881c8e 211 {
ebrus 0:6bc4ac881c8e 212 // Save new values
ebrus 0:6bc4ac881c8e 213 if (bits == 16) {
ebrus 0:6bc4ac881c8e 214 obj->bits = SPI_DATASIZE_16BIT;
ebrus 0:6bc4ac881c8e 215 } else {
ebrus 0:6bc4ac881c8e 216 obj->bits = SPI_DATASIZE_8BIT;
ebrus 0:6bc4ac881c8e 217 }
ebrus 0:6bc4ac881c8e 218
ebrus 0:6bc4ac881c8e 219 switch (mode) {
ebrus 0:6bc4ac881c8e 220 case 0:
ebrus 0:6bc4ac881c8e 221 obj->cpol = SPI_POLARITY_LOW;
ebrus 0:6bc4ac881c8e 222 obj->cpha = SPI_PHASE_1EDGE;
ebrus 0:6bc4ac881c8e 223 break;
ebrus 0:6bc4ac881c8e 224 case 1:
ebrus 0:6bc4ac881c8e 225 obj->cpol = SPI_POLARITY_LOW;
ebrus 0:6bc4ac881c8e 226 obj->cpha = SPI_PHASE_2EDGE;
ebrus 0:6bc4ac881c8e 227 break;
ebrus 0:6bc4ac881c8e 228 case 2:
ebrus 0:6bc4ac881c8e 229 obj->cpol = SPI_POLARITY_HIGH;
ebrus 0:6bc4ac881c8e 230 obj->cpha = SPI_PHASE_1EDGE;
ebrus 0:6bc4ac881c8e 231 break;
ebrus 0:6bc4ac881c8e 232 default:
ebrus 0:6bc4ac881c8e 233 obj->cpol = SPI_POLARITY_HIGH;
ebrus 0:6bc4ac881c8e 234 obj->cpha = SPI_PHASE_2EDGE;
ebrus 0:6bc4ac881c8e 235 break;
ebrus 0:6bc4ac881c8e 236 }
ebrus 0:6bc4ac881c8e 237
ebrus 0:6bc4ac881c8e 238 if (slave == 0) {
ebrus 0:6bc4ac881c8e 239 obj->mode = SPI_MODE_MASTER;
ebrus 0:6bc4ac881c8e 240 obj->nss = SPI_NSS_SOFT;
ebrus 0:6bc4ac881c8e 241 } else {
ebrus 0:6bc4ac881c8e 242 obj->mode = SPI_MODE_SLAVE;
ebrus 0:6bc4ac881c8e 243 obj->nss = SPI_NSS_HARD_INPUT;
ebrus 0:6bc4ac881c8e 244 }
ebrus 0:6bc4ac881c8e 245
ebrus 0:6bc4ac881c8e 246 init_spi(obj);
ebrus 0:6bc4ac881c8e 247 }
ebrus 0:6bc4ac881c8e 248
ebrus 0:6bc4ac881c8e 249 void spi_frequency(spi_t *obj, int hz)
ebrus 0:6bc4ac881c8e 250 {
ebrus 0:6bc4ac881c8e 251 // Values depend of PCLK2: 100 MHz
ebrus 0:6bc4ac881c8e 252 if ((obj->spi == SPI_1) || (obj->spi == SPI_4) || (obj->spi == SPI_5)) {
ebrus 0:6bc4ac881c8e 253 if (hz < 700000) {
ebrus 0:6bc4ac881c8e 254 obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 391 kHz
ebrus 0:6bc4ac881c8e 255 } else if ((hz >= 700000) && (hz < 1000000)) {
ebrus 0:6bc4ac881c8e 256 obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 781 kHz
ebrus 0:6bc4ac881c8e 257 } else if ((hz >= 1000000) && (hz < 3000000)) {
ebrus 0:6bc4ac881c8e 258 obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.56 MHz
ebrus 0:6bc4ac881c8e 259 } else if ((hz >= 3000000) && (hz < 6000000)) {
ebrus 0:6bc4ac881c8e 260 obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 3.13 MHz
ebrus 0:6bc4ac881c8e 261 } else if ((hz >= 6000000) && (hz < 12000000)) {
ebrus 0:6bc4ac881c8e 262 obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 6.25 MHz
ebrus 0:6bc4ac881c8e 263 } else if ((hz >= 12000000) && (hz < 25000000)) {
ebrus 0:6bc4ac881c8e 264 obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 12.5 MHz
ebrus 0:6bc4ac881c8e 265 } else if ((hz >= 25000000) && (hz < 50000000)) {
ebrus 0:6bc4ac881c8e 266 obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 25 MHz
ebrus 0:6bc4ac881c8e 267 } else { // >= 50000000
ebrus 0:6bc4ac881c8e 268 obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 50 MHz
ebrus 0:6bc4ac881c8e 269 }
ebrus 0:6bc4ac881c8e 270 }
ebrus 0:6bc4ac881c8e 271
ebrus 0:6bc4ac881c8e 272 // Values depend of PCLK1: 50 MHz
ebrus 0:6bc4ac881c8e 273 if ((obj->spi == SPI_2) || (obj->spi == SPI_3)) {
ebrus 0:6bc4ac881c8e 274 if (hz < 400000) {
ebrus 0:6bc4ac881c8e 275 obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 195 kHz
ebrus 0:6bc4ac881c8e 276 } else if ((hz >= 400000) && (hz < 700000)) {
ebrus 0:6bc4ac881c8e 277 obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 391 kHz
ebrus 0:6bc4ac881c8e 278 } else if ((hz >= 700000) && (hz < 1000000)) {
ebrus 0:6bc4ac881c8e 279 obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 781 MHz
ebrus 0:6bc4ac881c8e 280 } else if ((hz >= 1000000) && (hz < 3000000)) {
ebrus 0:6bc4ac881c8e 281 obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.56 MHz
ebrus 0:6bc4ac881c8e 282 } else if ((hz >= 3000000) && (hz < 6000000)) {
ebrus 0:6bc4ac881c8e 283 obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3.13 MHz
ebrus 0:6bc4ac881c8e 284 } else if ((hz >= 6000000) && (hz < 12000000)) {
ebrus 0:6bc4ac881c8e 285 obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6.25 MHz
ebrus 0:6bc4ac881c8e 286 } else if ((hz >= 12000000) && (hz < 25000000)) {
ebrus 0:6bc4ac881c8e 287 obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 12.5 MHz
ebrus 0:6bc4ac881c8e 288 } else { // >= 25000000
ebrus 0:6bc4ac881c8e 289 obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 25 MHz
ebrus 0:6bc4ac881c8e 290 }
ebrus 0:6bc4ac881c8e 291 }
ebrus 0:6bc4ac881c8e 292
ebrus 0:6bc4ac881c8e 293 init_spi(obj);
ebrus 0:6bc4ac881c8e 294 }
ebrus 0:6bc4ac881c8e 295
ebrus 0:6bc4ac881c8e 296 static inline int ssp_readable(spi_t *obj)
ebrus 0:6bc4ac881c8e 297 {
ebrus 0:6bc4ac881c8e 298 int status;
ebrus 0:6bc4ac881c8e 299 SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
ebrus 0:6bc4ac881c8e 300 // Check if data is received
ebrus 0:6bc4ac881c8e 301 status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0);
ebrus 0:6bc4ac881c8e 302 return status;
ebrus 0:6bc4ac881c8e 303 }
ebrus 0:6bc4ac881c8e 304
ebrus 0:6bc4ac881c8e 305 static inline int ssp_writeable(spi_t *obj)
ebrus 0:6bc4ac881c8e 306 {
ebrus 0:6bc4ac881c8e 307 int status;
ebrus 0:6bc4ac881c8e 308 SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
ebrus 0:6bc4ac881c8e 309 // Check if data is transmitted
ebrus 0:6bc4ac881c8e 310 status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) != RESET) ? 1 : 0);
ebrus 0:6bc4ac881c8e 311 return status;
ebrus 0:6bc4ac881c8e 312 }
ebrus 0:6bc4ac881c8e 313
ebrus 0:6bc4ac881c8e 314 static inline void ssp_write(spi_t *obj, int value)
ebrus 0:6bc4ac881c8e 315 {
ebrus 0:6bc4ac881c8e 316 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
ebrus 0:6bc4ac881c8e 317 while (!ssp_writeable(obj));
ebrus 0:6bc4ac881c8e 318 spi->DR = (uint16_t)value;
ebrus 0:6bc4ac881c8e 319 }
ebrus 0:6bc4ac881c8e 320
ebrus 0:6bc4ac881c8e 321 static inline int ssp_read(spi_t *obj)
ebrus 0:6bc4ac881c8e 322 {
ebrus 0:6bc4ac881c8e 323 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
ebrus 0:6bc4ac881c8e 324 while (!ssp_readable(obj));
ebrus 0:6bc4ac881c8e 325 return (int)spi->DR;
ebrus 0:6bc4ac881c8e 326 }
ebrus 0:6bc4ac881c8e 327
ebrus 0:6bc4ac881c8e 328 static inline int ssp_busy(spi_t *obj)
ebrus 0:6bc4ac881c8e 329 {
ebrus 0:6bc4ac881c8e 330 int status;
ebrus 0:6bc4ac881c8e 331 SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
ebrus 0:6bc4ac881c8e 332 status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_BSY) != RESET) ? 1 : 0);
ebrus 0:6bc4ac881c8e 333 return status;
ebrus 0:6bc4ac881c8e 334 }
ebrus 0:6bc4ac881c8e 335
ebrus 0:6bc4ac881c8e 336 int spi_master_write(spi_t *obj, int value)
ebrus 0:6bc4ac881c8e 337 {
ebrus 0:6bc4ac881c8e 338 ssp_write(obj, value);
ebrus 0:6bc4ac881c8e 339 return ssp_read(obj);
ebrus 0:6bc4ac881c8e 340 }
ebrus 0:6bc4ac881c8e 341
ebrus 0:6bc4ac881c8e 342 int spi_slave_receive(spi_t *obj)
ebrus 0:6bc4ac881c8e 343 {
ebrus 0:6bc4ac881c8e 344 return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0);
ebrus 0:6bc4ac881c8e 345 };
ebrus 0:6bc4ac881c8e 346
ebrus 0:6bc4ac881c8e 347 int spi_slave_read(spi_t *obj)
ebrus 0:6bc4ac881c8e 348 {
ebrus 0:6bc4ac881c8e 349 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
ebrus 0:6bc4ac881c8e 350 while (!ssp_readable(obj));
ebrus 0:6bc4ac881c8e 351 return (int)spi->DR;
ebrus 0:6bc4ac881c8e 352 }
ebrus 0:6bc4ac881c8e 353
ebrus 0:6bc4ac881c8e 354 void spi_slave_write(spi_t *obj, int value)
ebrus 0:6bc4ac881c8e 355 {
ebrus 0:6bc4ac881c8e 356 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
ebrus 0:6bc4ac881c8e 357 while (!ssp_writeable(obj));
ebrus 0:6bc4ac881c8e 358 spi->DR = (uint16_t)value;
ebrus 0:6bc4ac881c8e 359 }
ebrus 0:6bc4ac881c8e 360
ebrus 0:6bc4ac881c8e 361 int spi_busy(spi_t *obj)
ebrus 0:6bc4ac881c8e 362 {
ebrus 0:6bc4ac881c8e 363 return ssp_busy(obj);
ebrus 0:6bc4ac881c8e 364 }
ebrus 0:6bc4ac881c8e 365
ebrus 0:6bc4ac881c8e 366 #endif