mbed library sources

Dependents:   frdm_kl05z_gpio_test

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Thu Dec 12 10:45:05 2013 +0000
Revision:
56:99eb381a3269
Parent:
52:a51c77007319
Child:
70:c1fbde68b492
Synchronized with git revision bd51e4eb73a1706f1d5379ec5cebcbd6d978cb4f

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

[NUCLEO_F103RB] Add I2C master, code cleanup, ...

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 52:a51c77007319 1 /* mbed Microcontroller Library
mbed_official 52:a51c77007319 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 52:a51c77007319 3 *
mbed_official 52:a51c77007319 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 52:a51c77007319 5 * you may not use this file except in compliance with the License.
mbed_official 52:a51c77007319 6 * You may obtain a copy of the License at
mbed_official 52:a51c77007319 7 *
mbed_official 52:a51c77007319 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 52:a51c77007319 9 *
mbed_official 52:a51c77007319 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 52:a51c77007319 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 52:a51c77007319 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 52:a51c77007319 13 * See the License for the specific language governing permissions and
mbed_official 52:a51c77007319 14 * limitations under the License.
mbed_official 52:a51c77007319 15 */
mbed_official 52:a51c77007319 16 #include "spi_api.h"
mbed_official 52:a51c77007319 17
mbed_official 52:a51c77007319 18 #if DEVICE_SPI
mbed_official 52:a51c77007319 19
mbed_official 52:a51c77007319 20 #include <math.h>
mbed_official 52:a51c77007319 21 #include "cmsis.h"
mbed_official 52:a51c77007319 22 #include "pinmap.h"
mbed_official 52:a51c77007319 23 #include "error.h"
mbed_official 52:a51c77007319 24
mbed_official 52:a51c77007319 25 static const PinMap PinMap_SPI_MOSI[] = {
mbed_official 52:a51c77007319 26 {PA_7, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)},
mbed_official 52:a51c77007319 27 {PB_5, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 1)}, // Remap
mbed_official 52:a51c77007319 28 {NC, NC, 0}
mbed_official 52:a51c77007319 29 };
mbed_official 52:a51c77007319 30
mbed_official 52:a51c77007319 31 static const PinMap PinMap_SPI_MISO[] = {
mbed_official 52:a51c77007319 32 {PA_6, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)},
mbed_official 52:a51c77007319 33 {PB_4, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 1)}, // Remap
mbed_official 52:a51c77007319 34 {NC, NC, 0}
mbed_official 52:a51c77007319 35 };
mbed_official 52:a51c77007319 36
mbed_official 52:a51c77007319 37 static const PinMap PinMap_SPI_SCLK[] = {
mbed_official 52:a51c77007319 38 {PA_5, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)},
mbed_official 52:a51c77007319 39 {PB_3, SPI_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 1)}, // Remap
mbed_official 52:a51c77007319 40 {NC, NC, 0}
mbed_official 52:a51c77007319 41 };
mbed_official 52:a51c77007319 42
mbed_official 52:a51c77007319 43 // Only used in Slave mode
mbed_official 52:a51c77007319 44 static const PinMap PinMap_SPI_SSEL[] = {
mbed_official 56:99eb381a3269 45 {PB_6, SPI_1, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0)}, // Generic IO, not real H/W NSS pin
mbed_official 56:99eb381a3269 46 //{PA_4, SPI_1, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0)},
mbed_official 56:99eb381a3269 47 //{PA_15, SPI_1, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 1)}, // Remap
mbed_official 52:a51c77007319 48 {NC, NC, 0}
mbed_official 52:a51c77007319 49 };
mbed_official 52:a51c77007319 50
mbed_official 56:99eb381a3269 51 static void init_spi(spi_t *obj) {
mbed_official 56:99eb381a3269 52 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
mbed_official 56:99eb381a3269 53 SPI_InitTypeDef SPI_InitStructure;
mbed_official 56:99eb381a3269 54
mbed_official 56:99eb381a3269 55 SPI_Cmd(spi, DISABLE);
mbed_official 52:a51c77007319 56
mbed_official 56:99eb381a3269 57 SPI_InitStructure.SPI_Mode = obj->mode;
mbed_official 56:99eb381a3269 58 SPI_InitStructure.SPI_NSS = obj->nss;
mbed_official 56:99eb381a3269 59 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
mbed_official 56:99eb381a3269 60 SPI_InitStructure.SPI_DataSize = obj->bits;
mbed_official 56:99eb381a3269 61 SPI_InitStructure.SPI_CPOL = obj->cpol;
mbed_official 56:99eb381a3269 62 SPI_InitStructure.SPI_CPHA = obj->cpha;
mbed_official 56:99eb381a3269 63 SPI_InitStructure.SPI_BaudRatePrescaler = obj->br_presc;
mbed_official 56:99eb381a3269 64 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
mbed_official 56:99eb381a3269 65 SPI_InitStructure.SPI_CRCPolynomial = 7;
mbed_official 56:99eb381a3269 66 SPI_Init(spi, &SPI_InitStructure);
mbed_official 56:99eb381a3269 67
mbed_official 56:99eb381a3269 68 SPI_Cmd(spi, ENABLE);
mbed_official 56:99eb381a3269 69 }
mbed_official 56:99eb381a3269 70
mbed_official 56:99eb381a3269 71 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
mbed_official 52:a51c77007319 72 // Determine the SPI to use
mbed_official 52:a51c77007319 73 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
mbed_official 52:a51c77007319 74 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
mbed_official 52:a51c77007319 75 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
mbed_official 52:a51c77007319 76 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
mbed_official 52:a51c77007319 77
mbed_official 52:a51c77007319 78 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
mbed_official 52:a51c77007319 79 SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
mbed_official 52:a51c77007319 80
mbed_official 52:a51c77007319 81 obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
mbed_official 52:a51c77007319 82
mbed_official 52:a51c77007319 83 if (obj->spi == (SPIName)NC) {
mbed_official 52:a51c77007319 84 error("SPI pinout mapping failed");
mbed_official 52:a51c77007319 85 }
mbed_official 52:a51c77007319 86
mbed_official 52:a51c77007319 87 // Enable SPI clock
mbed_official 52:a51c77007319 88 if (obj->spi == SPI_1) {
mbed_official 52:a51c77007319 89 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
mbed_official 52:a51c77007319 90 }
mbed_official 52:a51c77007319 91 if (obj->spi == SPI_2) {
mbed_official 52:a51c77007319 92 RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
mbed_official 52:a51c77007319 93 }
mbed_official 52:a51c77007319 94
mbed_official 52:a51c77007319 95 // Configure the SPI pins
mbed_official 52:a51c77007319 96 pinmap_pinout(mosi, PinMap_SPI_MOSI);
mbed_official 52:a51c77007319 97 pinmap_pinout(miso, PinMap_SPI_MISO);
mbed_official 52:a51c77007319 98 pinmap_pinout(sclk, PinMap_SPI_SCLK);
mbed_official 52:a51c77007319 99
mbed_official 52:a51c77007319 100 // Save new values
mbed_official 52:a51c77007319 101 obj->bits = SPI_DataSize_8b;
mbed_official 52:a51c77007319 102 obj->cpol = SPI_CPOL_Low;
mbed_official 52:a51c77007319 103 obj->cpha = SPI_CPHA_1Edge;
mbed_official 52:a51c77007319 104 obj->br_presc = SPI_BaudRatePrescaler_64; // Closest to 1MHz (72MHz/64 = 1.125MHz)
mbed_official 52:a51c77007319 105
mbed_official 52:a51c77007319 106 if (ssel == NC) { // Master
mbed_official 52:a51c77007319 107 obj->mode = SPI_Mode_Master;
mbed_official 52:a51c77007319 108 obj->nss = SPI_NSS_Soft;
mbed_official 52:a51c77007319 109 }
mbed_official 52:a51c77007319 110 else { // Slave
mbed_official 52:a51c77007319 111 pinmap_pinout(ssel, PinMap_SPI_SSEL);
mbed_official 52:a51c77007319 112 obj->mode = SPI_Mode_Slave;
mbed_official 56:99eb381a3269 113 obj->nss = SPI_NSS_Soft;
mbed_official 52:a51c77007319 114 }
mbed_official 52:a51c77007319 115
mbed_official 56:99eb381a3269 116 init_spi(obj);
mbed_official 52:a51c77007319 117 }
mbed_official 52:a51c77007319 118
mbed_official 52:a51c77007319 119 void spi_free(spi_t *obj) {
mbed_official 52:a51c77007319 120 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
mbed_official 52:a51c77007319 121 SPI_I2S_DeInit(spi);
mbed_official 52:a51c77007319 122 }
mbed_official 52:a51c77007319 123
mbed_official 56:99eb381a3269 124 void spi_format(spi_t *obj, int bits, int mode, int slave) {
mbed_official 52:a51c77007319 125 // Save new values
mbed_official 52:a51c77007319 126 if (bits == 8) {
mbed_official 52:a51c77007319 127 obj->bits = SPI_DataSize_8b;
mbed_official 52:a51c77007319 128 }
mbed_official 52:a51c77007319 129 else {
mbed_official 52:a51c77007319 130 obj->bits = SPI_DataSize_16b;
mbed_official 52:a51c77007319 131 }
mbed_official 52:a51c77007319 132
mbed_official 52:a51c77007319 133 switch (mode) {
mbed_official 52:a51c77007319 134 case 0:
mbed_official 52:a51c77007319 135 obj->cpol = SPI_CPOL_Low;
mbed_official 52:a51c77007319 136 obj->cpha = SPI_CPHA_1Edge;
mbed_official 52:a51c77007319 137 break;
mbed_official 52:a51c77007319 138 case 1:
mbed_official 52:a51c77007319 139 obj->cpol = SPI_CPOL_Low;
mbed_official 52:a51c77007319 140 obj->cpha = SPI_CPHA_2Edge;
mbed_official 52:a51c77007319 141 break;
mbed_official 52:a51c77007319 142 case 2:
mbed_official 52:a51c77007319 143 obj->cpol = SPI_CPOL_High;
mbed_official 52:a51c77007319 144 obj->cpha = SPI_CPHA_1Edge;
mbed_official 52:a51c77007319 145 break;
mbed_official 52:a51c77007319 146 default:
mbed_official 52:a51c77007319 147 obj->cpol = SPI_CPOL_High;
mbed_official 52:a51c77007319 148 obj->cpha = SPI_CPHA_2Edge;
mbed_official 52:a51c77007319 149 break;
mbed_official 52:a51c77007319 150 }
mbed_official 52:a51c77007319 151
mbed_official 52:a51c77007319 152 if (slave == 0) {
mbed_official 52:a51c77007319 153 obj->mode = SPI_Mode_Master;
mbed_official 52:a51c77007319 154 obj->nss = SPI_NSS_Soft;
mbed_official 52:a51c77007319 155 }
mbed_official 52:a51c77007319 156 else {
mbed_official 52:a51c77007319 157 obj->mode = SPI_Mode_Slave;
mbed_official 52:a51c77007319 158 obj->nss = SPI_NSS_Hard;
mbed_official 52:a51c77007319 159 }
mbed_official 52:a51c77007319 160
mbed_official 56:99eb381a3269 161 init_spi(obj);
mbed_official 52:a51c77007319 162 }
mbed_official 52:a51c77007319 163
mbed_official 52:a51c77007319 164 void spi_frequency(spi_t *obj, int hz) {
mbed_official 52:a51c77007319 165 // Get SPI clock frequency
mbed_official 52:a51c77007319 166 uint32_t PCLK = SystemCoreClock >> 1;
mbed_official 52:a51c77007319 167
mbed_official 52:a51c77007319 168 // Choose the baud rate divisor (between 2 and 256)
mbed_official 52:a51c77007319 169 uint32_t divisor = PCLK / hz;
mbed_official 52:a51c77007319 170
mbed_official 52:a51c77007319 171 // Find the nearest power-of-2
mbed_official 52:a51c77007319 172 divisor = (divisor > 0 ? divisor-1 : 0);
mbed_official 52:a51c77007319 173 divisor |= divisor >> 1;
mbed_official 52:a51c77007319 174 divisor |= divisor >> 2;
mbed_official 52:a51c77007319 175 divisor |= divisor >> 4;
mbed_official 52:a51c77007319 176 divisor |= divisor >> 8;
mbed_official 52:a51c77007319 177 divisor |= divisor >> 16;
mbed_official 52:a51c77007319 178 divisor++;
mbed_official 52:a51c77007319 179
mbed_official 52:a51c77007319 180 uint32_t baud_rate = __builtin_ffs(divisor) - 2;
mbed_official 52:a51c77007319 181
mbed_official 52:a51c77007319 182 // Save new value
mbed_official 52:a51c77007319 183 obj->br_presc = ((baud_rate > 7) ? (7 << 3) : (baud_rate << 3));
mbed_official 52:a51c77007319 184
mbed_official 56:99eb381a3269 185 init_spi(obj);
mbed_official 52:a51c77007319 186 }
mbed_official 52:a51c77007319 187
mbed_official 52:a51c77007319 188 static inline int ssp_readable(spi_t *obj) {
mbed_official 52:a51c77007319 189 int status;
mbed_official 52:a51c77007319 190 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
mbed_official 52:a51c77007319 191 // Check if data is received
mbed_official 52:a51c77007319 192 status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_RXNE) != RESET) ? 1 : 0);
mbed_official 52:a51c77007319 193 return status;
mbed_official 52:a51c77007319 194 }
mbed_official 52:a51c77007319 195
mbed_official 52:a51c77007319 196 static inline int ssp_writeable(spi_t *obj) {
mbed_official 52:a51c77007319 197 int status;
mbed_official 52:a51c77007319 198 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
mbed_official 52:a51c77007319 199 // Check if data is transmitted
mbed_official 52:a51c77007319 200 status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_TXE) != RESET) ? 1 : 0);
mbed_official 52:a51c77007319 201 return status;
mbed_official 52:a51c77007319 202 }
mbed_official 52:a51c77007319 203
mbed_official 52:a51c77007319 204 static inline void ssp_write(spi_t *obj, int value) {
mbed_official 52:a51c77007319 205 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
mbed_official 52:a51c77007319 206 while (!ssp_writeable(obj));
mbed_official 52:a51c77007319 207 SPI_I2S_SendData(spi, (uint16_t)value);
mbed_official 52:a51c77007319 208 }
mbed_official 52:a51c77007319 209
mbed_official 52:a51c77007319 210 static inline int ssp_read(spi_t *obj) {
mbed_official 52:a51c77007319 211 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
mbed_official 52:a51c77007319 212 while (!ssp_readable(obj));
mbed_official 52:a51c77007319 213 return (int)SPI_I2S_ReceiveData(spi);
mbed_official 52:a51c77007319 214 }
mbed_official 52:a51c77007319 215
mbed_official 52:a51c77007319 216 static inline int ssp_busy(spi_t *obj) {
mbed_official 52:a51c77007319 217 int status;
mbed_official 52:a51c77007319 218 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
mbed_official 52:a51c77007319 219 status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_BSY) != RESET) ? 1 : 0);
mbed_official 52:a51c77007319 220 return status;
mbed_official 52:a51c77007319 221 }
mbed_official 52:a51c77007319 222
mbed_official 52:a51c77007319 223 int spi_master_write(spi_t *obj, int value) {
mbed_official 52:a51c77007319 224 ssp_write(obj, value);
mbed_official 52:a51c77007319 225 return ssp_read(obj);
mbed_official 52:a51c77007319 226 }
mbed_official 52:a51c77007319 227
mbed_official 52:a51c77007319 228 int spi_slave_receive(spi_t *obj) {
mbed_official 52:a51c77007319 229 return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
mbed_official 52:a51c77007319 230 };
mbed_official 52:a51c77007319 231
mbed_official 52:a51c77007319 232 int spi_slave_read(spi_t *obj) {
mbed_official 52:a51c77007319 233 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
mbed_official 52:a51c77007319 234 return (int)SPI_I2S_ReceiveData(spi);
mbed_official 52:a51c77007319 235 }
mbed_official 52:a51c77007319 236
mbed_official 52:a51c77007319 237 void spi_slave_write(spi_t *obj, int value) {
mbed_official 52:a51c77007319 238 SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
mbed_official 52:a51c77007319 239 while (!ssp_writeable(obj));
mbed_official 52:a51c77007319 240 SPI_I2S_SendData(spi, (uint16_t)value);
mbed_official 52:a51c77007319 241 }
mbed_official 52:a51c77007319 242
mbed_official 52:a51c77007319 243 int spi_busy(spi_t *obj) {
mbed_official 52:a51c77007319 244 return ssp_busy(obj);
mbed_official 52:a51c77007319 245 }
mbed_official 52:a51c77007319 246
mbed_official 52:a51c77007319 247 #endif