added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Fri Apr 29 01:15:11 2016 +0100
Revision:
119:3921aeca8633
Parent:
71:a5b1c83f05dc
Child:
144:ef7eb2e8f9f7
Synchronized with git revision fe9720f24b1adc71ab6962506ec51290f6afd270

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

[Renesas RZ/A1H] Enable asynchronous communications

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 0:9b334a45a8ff 1 /* mbed Microcontroller Library
bogdanm 0:9b334a45a8ff 2 * Copyright (c) 2006-2013 ARM Limited
bogdanm 0:9b334a45a8ff 3 *
bogdanm 0:9b334a45a8ff 4 * Licensed under the Apache License, Version 2.0 (the "License");
bogdanm 0:9b334a45a8ff 5 * you may not use this file except in compliance with the License.
bogdanm 0:9b334a45a8ff 6 * You may obtain a copy of the License at
bogdanm 0:9b334a45a8ff 7 *
bogdanm 0:9b334a45a8ff 8 * http://www.apache.org/licenses/LICENSE-2.0
bogdanm 0:9b334a45a8ff 9 *
bogdanm 0:9b334a45a8ff 10 * Unless required by applicable law or agreed to in writing, software
bogdanm 0:9b334a45a8ff 11 * distributed under the License is distributed on an "AS IS" BASIS,
bogdanm 0:9b334a45a8ff 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bogdanm 0:9b334a45a8ff 13 * See the License for the specific language governing permissions and
bogdanm 0:9b334a45a8ff 14 * limitations under the License.
bogdanm 0:9b334a45a8ff 15 */
bogdanm 0:9b334a45a8ff 16 #include "mbed_assert.h"
bogdanm 0:9b334a45a8ff 17 #include <math.h>
bogdanm 0:9b334a45a8ff 18
bogdanm 0:9b334a45a8ff 19 #include "spi_api.h"
bogdanm 0:9b334a45a8ff 20 #include "cmsis.h"
bogdanm 0:9b334a45a8ff 21 #include "pinmap.h"
bogdanm 0:9b334a45a8ff 22 #include "mbed_error.h"
bogdanm 0:9b334a45a8ff 23 #include "RZ_A1_Init.h"
bogdanm 0:9b334a45a8ff 24
bogdanm 0:9b334a45a8ff 25 static const PinMap PinMap_SPI_SCLK[] = {
bogdanm 0:9b334a45a8ff 26 {P10_12, SPI_0, 4},
bogdanm 0:9b334a45a8ff 27 {P4_4 , SPI_1, 2},
bogdanm 0:9b334a45a8ff 28 {P11_12, SPI_1, 2},
bogdanm 0:9b334a45a8ff 29 {P8_3 , SPI_2, 3},
mbed_official 71:a5b1c83f05dc 30 {P5_0 , SPI_3, 8},
bogdanm 0:9b334a45a8ff 31 {NC , NC , 0}
bogdanm 0:9b334a45a8ff 32 };
bogdanm 0:9b334a45a8ff 33
bogdanm 0:9b334a45a8ff 34 static const PinMap PinMap_SPI_SSEL[] = {
bogdanm 0:9b334a45a8ff 35 {P10_13, SPI_0, 4},
bogdanm 0:9b334a45a8ff 36 {P4_5 , SPI_1, 2},
bogdanm 0:9b334a45a8ff 37 {P11_13, SPI_1, 2},
bogdanm 0:9b334a45a8ff 38 {P8_4 , SPI_2, 3},
mbed_official 71:a5b1c83f05dc 39 {P5_1 , SPI_3, 8},
bogdanm 0:9b334a45a8ff 40 {NC , NC , 0}
bogdanm 0:9b334a45a8ff 41 };
bogdanm 0:9b334a45a8ff 42
bogdanm 0:9b334a45a8ff 43 static const PinMap PinMap_SPI_MOSI[] = {
bogdanm 0:9b334a45a8ff 44 {P10_14, SPI_0, 4},
bogdanm 0:9b334a45a8ff 45 {P4_6 , SPI_1, 2},
bogdanm 0:9b334a45a8ff 46 {P11_14, SPI_1, 2},
bogdanm 0:9b334a45a8ff 47 {P8_5 , SPI_2, 3},
mbed_official 71:a5b1c83f05dc 48 {P5_2 , SPI_3, 8},
bogdanm 0:9b334a45a8ff 49 {NC , NC , 0}
bogdanm 0:9b334a45a8ff 50 };
bogdanm 0:9b334a45a8ff 51
bogdanm 0:9b334a45a8ff 52 static const PinMap PinMap_SPI_MISO[] = {
bogdanm 0:9b334a45a8ff 53 {P10_15, SPI_0, 4},
bogdanm 0:9b334a45a8ff 54 {P4_7 , SPI_1, 2},
bogdanm 0:9b334a45a8ff 55 {P11_15, SPI_1, 2},
bogdanm 0:9b334a45a8ff 56 {P8_6 , SPI_2, 3},
mbed_official 71:a5b1c83f05dc 57 {P5_3 , SPI_3, 8},
bogdanm 0:9b334a45a8ff 58 {NC , NC , 0}
bogdanm 0:9b334a45a8ff 59 };
bogdanm 0:9b334a45a8ff 60
bogdanm 0:9b334a45a8ff 61 static const struct st_rspi *RSPI[] = RSPI_ADDRESS_LIST;
bogdanm 0:9b334a45a8ff 62
bogdanm 0:9b334a45a8ff 63 static inline void spi_disable(spi_t *obj);
bogdanm 0:9b334a45a8ff 64 static inline void spi_enable(spi_t *obj);
bogdanm 0:9b334a45a8ff 65 static inline int spi_readable(spi_t *obj);
bogdanm 0:9b334a45a8ff 66 static inline void spi_write(spi_t *obj, int value);
bogdanm 0:9b334a45a8ff 67 static inline int spi_read(spi_t *obj);
bogdanm 0:9b334a45a8ff 68
bogdanm 0:9b334a45a8ff 69 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) {
bogdanm 0:9b334a45a8ff 70 // determine the SPI to use
bogdanm 0:9b334a45a8ff 71 volatile uint8_t dummy;
bogdanm 0:9b334a45a8ff 72 uint32_t spi_mosi = pinmap_peripheral(mosi, PinMap_SPI_MOSI);
bogdanm 0:9b334a45a8ff 73 uint32_t spi_miso = pinmap_peripheral(miso, PinMap_SPI_MISO);
bogdanm 0:9b334a45a8ff 74 uint32_t spi_sclk = pinmap_peripheral(sclk, PinMap_SPI_SCLK);
bogdanm 0:9b334a45a8ff 75 uint32_t spi_ssel = pinmap_peripheral(ssel, PinMap_SPI_SSEL);
bogdanm 0:9b334a45a8ff 76 uint32_t spi_data = pinmap_merge(spi_mosi, spi_miso);
bogdanm 0:9b334a45a8ff 77 uint32_t spi_cntl = pinmap_merge(spi_sclk, spi_ssel);
bogdanm 0:9b334a45a8ff 78 uint32_t spi = pinmap_merge(spi_data, spi_cntl);
mbed_official 119:3921aeca8633 79
bogdanm 0:9b334a45a8ff 80 MBED_ASSERT((int)spi != NC);
mbed_official 119:3921aeca8633 81
mbed_official 119:3921aeca8633 82 obj->spi.spi = (struct st_rspi *)RSPI[spi];
mbed_official 119:3921aeca8633 83 obj->spi.index = spi;
mbed_official 119:3921aeca8633 84
bogdanm 0:9b334a45a8ff 85 // enable power and clocking
bogdanm 0:9b334a45a8ff 86 switch (spi) {
bogdanm 0:9b334a45a8ff 87 case SPI_0: CPGSTBCR10 &= ~(0x80); break;
bogdanm 0:9b334a45a8ff 88 case SPI_1: CPGSTBCR10 &= ~(0x40); break;
bogdanm 0:9b334a45a8ff 89 case SPI_2: CPGSTBCR10 &= ~(0x20); break;
mbed_official 71:a5b1c83f05dc 90 case SPI_3: CPGSTBCR10 &= ~(0x10); break;
bogdanm 0:9b334a45a8ff 91 }
bogdanm 0:9b334a45a8ff 92 dummy = CPGSTBCR10;
mbed_official 119:3921aeca8633 93
mbed_official 119:3921aeca8633 94 obj->spi.spi->SPCR = 0x00; // CTRL to 0
mbed_official 119:3921aeca8633 95 obj->spi.spi->SPSCR = 0x00; // no sequential operation
mbed_official 119:3921aeca8633 96 obj->spi.spi->SSLP = 0x00; // SSL 'L' active
mbed_official 119:3921aeca8633 97 obj->spi.spi->SPDCR = 0x20; // byte access
mbed_official 119:3921aeca8633 98 obj->spi.spi->SPCKD = 0x00; // SSL -> enable CLK delay : 1RSPCK
mbed_official 119:3921aeca8633 99 obj->spi.spi->SSLND = 0x00; // CLK end -> SSL neg delay : 1RSPCK
mbed_official 119:3921aeca8633 100 obj->spi.spi->SPND = 0x00; // delay between CMD : 1RSPCK + 2P1CLK
mbed_official 119:3921aeca8633 101 obj->spi.spi->SPPCR = 0x20; // MOSI Idle fixed value equals 0
mbed_official 119:3921aeca8633 102 obj->spi.spi->SPBFCR = 0xf0; // and set trigger count: read 1, write 1
mbed_official 119:3921aeca8633 103 obj->spi.spi->SPBFCR = 0x30; // and reset buffer
mbed_official 119:3921aeca8633 104
bogdanm 0:9b334a45a8ff 105 // pin out the spi pins
bogdanm 0:9b334a45a8ff 106 pinmap_pinout(mosi, PinMap_SPI_MOSI);
bogdanm 0:9b334a45a8ff 107 pinmap_pinout(miso, PinMap_SPI_MISO);
bogdanm 0:9b334a45a8ff 108 pinmap_pinout(sclk, PinMap_SPI_SCLK);
bogdanm 0:9b334a45a8ff 109 if ((int)ssel != NC) {
bogdanm 0:9b334a45a8ff 110 pinmap_pinout(ssel, PinMap_SPI_SSEL);
bogdanm 0:9b334a45a8ff 111 }
bogdanm 0:9b334a45a8ff 112 }
bogdanm 0:9b334a45a8ff 113
bogdanm 0:9b334a45a8ff 114 void spi_free(spi_t *obj) {}
bogdanm 0:9b334a45a8ff 115
bogdanm 0:9b334a45a8ff 116 void spi_format(spi_t *obj, int bits, int mode, int slave) {
bogdanm 0:9b334a45a8ff 117 int DSS; // DSS (data select size)
bogdanm 0:9b334a45a8ff 118 int polarity = (mode & 0x2) ? 1 : 0;
bogdanm 0:9b334a45a8ff 119 int phase = (mode & 0x1) ? 1 : 0;
bogdanm 0:9b334a45a8ff 120 uint16_t tmp = 0;
bogdanm 0:9b334a45a8ff 121 uint16_t mask = 0xf03;
bogdanm 0:9b334a45a8ff 122 uint16_t wk_spcmd0;
bogdanm 0:9b334a45a8ff 123 uint8_t splw;
mbed_official 119:3921aeca8633 124
bogdanm 0:9b334a45a8ff 125 switch (mode) {
bogdanm 0:9b334a45a8ff 126 case 0:
bogdanm 0:9b334a45a8ff 127 case 1:
bogdanm 0:9b334a45a8ff 128 case 2:
bogdanm 0:9b334a45a8ff 129 case 3:
bogdanm 0:9b334a45a8ff 130 // Do Nothing
bogdanm 0:9b334a45a8ff 131 break;
bogdanm 0:9b334a45a8ff 132 default:
bogdanm 0:9b334a45a8ff 133 error("SPI format error");
bogdanm 0:9b334a45a8ff 134 return;
bogdanm 0:9b334a45a8ff 135 }
mbed_official 119:3921aeca8633 136
bogdanm 0:9b334a45a8ff 137 switch (bits) {
bogdanm 0:9b334a45a8ff 138 case 8:
bogdanm 0:9b334a45a8ff 139 DSS = 0x7;
bogdanm 0:9b334a45a8ff 140 splw = 0x20;
bogdanm 0:9b334a45a8ff 141 break;
bogdanm 0:9b334a45a8ff 142 case 16:
bogdanm 0:9b334a45a8ff 143 DSS = 0xf;
bogdanm 0:9b334a45a8ff 144 splw = 0x40;
bogdanm 0:9b334a45a8ff 145 break;
bogdanm 0:9b334a45a8ff 146 case 32:
bogdanm 0:9b334a45a8ff 147 DSS = 0x2;
bogdanm 0:9b334a45a8ff 148 splw = 0x60;
bogdanm 0:9b334a45a8ff 149 break;
bogdanm 0:9b334a45a8ff 150 default:
bogdanm 0:9b334a45a8ff 151 error("SPI module don't support other than 8/16/32bits");
bogdanm 0:9b334a45a8ff 152 return;
bogdanm 0:9b334a45a8ff 153 }
bogdanm 0:9b334a45a8ff 154 tmp |= phase;
bogdanm 0:9b334a45a8ff 155 tmp |= (polarity << 1);
bogdanm 0:9b334a45a8ff 156 tmp |= (DSS << 8);
mbed_official 119:3921aeca8633 157 obj->spi.bits = bits;
mbed_official 119:3921aeca8633 158
bogdanm 0:9b334a45a8ff 159 spi_disable(obj);
mbed_official 119:3921aeca8633 160 wk_spcmd0 = obj->spi.spi->SPCMD0;
bogdanm 0:9b334a45a8ff 161 wk_spcmd0 &= ~mask;
bogdanm 0:9b334a45a8ff 162 wk_spcmd0 |= (mask & tmp);
mbed_official 119:3921aeca8633 163 obj->spi.spi->SPCMD0 = wk_spcmd0;
mbed_official 119:3921aeca8633 164 obj->spi.spi->SPDCR = splw;
bogdanm 0:9b334a45a8ff 165 if (slave) {
mbed_official 119:3921aeca8633 166 obj->spi.spi->SPCR &=~(1 << 3); // MSTR to 0
bogdanm 0:9b334a45a8ff 167 } else {
mbed_official 119:3921aeca8633 168 obj->spi.spi->SPCR |= (1 << 3); // MSTR to 1
bogdanm 0:9b334a45a8ff 169 }
bogdanm 0:9b334a45a8ff 170 spi_enable(obj);
bogdanm 0:9b334a45a8ff 171 }
bogdanm 0:9b334a45a8ff 172
bogdanm 0:9b334a45a8ff 173 void spi_frequency(spi_t *obj, int hz) {
bogdanm 0:9b334a45a8ff 174 uint32_t pclk_base;
bogdanm 0:9b334a45a8ff 175 uint32_t div;
bogdanm 0:9b334a45a8ff 176 uint32_t brdv = 0;
bogdanm 0:9b334a45a8ff 177 uint32_t hz_max;
bogdanm 0:9b334a45a8ff 178 uint32_t hz_min;
bogdanm 0:9b334a45a8ff 179 uint16_t mask = 0x000c;
bogdanm 0:9b334a45a8ff 180 uint16_t wk_spcmd0;
mbed_official 119:3921aeca8633 181
bogdanm 0:9b334a45a8ff 182 /* set PCLK */
bogdanm 0:9b334a45a8ff 183 if (RZ_A1_IsClockMode0() == false) {
bogdanm 0:9b334a45a8ff 184 pclk_base = CM1_RENESAS_RZ_A1_P1_CLK;
bogdanm 0:9b334a45a8ff 185 } else {
bogdanm 0:9b334a45a8ff 186 pclk_base = CM0_RENESAS_RZ_A1_P1_CLK;
bogdanm 0:9b334a45a8ff 187 }
mbed_official 119:3921aeca8633 188
bogdanm 0:9b334a45a8ff 189 hz_min = pclk_base / 2 / 256 / 8;
bogdanm 0:9b334a45a8ff 190 hz_max = pclk_base / 2;
bogdanm 0:9b334a45a8ff 191 if ((hz < hz_min) || (hz > hz_max)) {
bogdanm 0:9b334a45a8ff 192 error("Couldn't setup requested SPI frequency");
bogdanm 0:9b334a45a8ff 193 return;
bogdanm 0:9b334a45a8ff 194 }
mbed_official 119:3921aeca8633 195
bogdanm 0:9b334a45a8ff 196 div = (pclk_base / hz / 2);
bogdanm 0:9b334a45a8ff 197 while (div > 256) {
bogdanm 0:9b334a45a8ff 198 div >>= 1;
bogdanm 0:9b334a45a8ff 199 brdv++;
bogdanm 0:9b334a45a8ff 200 }
bogdanm 0:9b334a45a8ff 201 div -= 1;
bogdanm 0:9b334a45a8ff 202 brdv = (brdv << 2);
mbed_official 119:3921aeca8633 203
bogdanm 0:9b334a45a8ff 204 spi_disable(obj);
mbed_official 119:3921aeca8633 205 obj->spi.spi->SPBR = div;
mbed_official 119:3921aeca8633 206 wk_spcmd0 = obj->spi.spi->SPCMD0;
bogdanm 0:9b334a45a8ff 207 wk_spcmd0 &= ~mask;
bogdanm 0:9b334a45a8ff 208 wk_spcmd0 |= (mask & brdv);
mbed_official 119:3921aeca8633 209 obj->spi.spi->SPCMD0 = wk_spcmd0;
bogdanm 0:9b334a45a8ff 210 spi_enable(obj);
bogdanm 0:9b334a45a8ff 211 }
bogdanm 0:9b334a45a8ff 212
bogdanm 0:9b334a45a8ff 213 static inline void spi_disable(spi_t *obj) {
mbed_official 119:3921aeca8633 214 obj->spi.spi->SPCR &= ~(1 << 6); // SPE to 0
bogdanm 0:9b334a45a8ff 215 }
bogdanm 0:9b334a45a8ff 216
bogdanm 0:9b334a45a8ff 217 static inline void spi_enable(spi_t *obj) {
mbed_official 119:3921aeca8633 218 obj->spi.spi->SPCR |= (1 << 6); // SPE to 1
bogdanm 0:9b334a45a8ff 219 }
bogdanm 0:9b334a45a8ff 220
bogdanm 0:9b334a45a8ff 221 static inline int spi_readable(spi_t *obj) {
mbed_official 119:3921aeca8633 222 return obj->spi.spi->SPSR & (1 << 7); // SPRF
bogdanm 0:9b334a45a8ff 223 }
bogdanm 0:9b334a45a8ff 224
bogdanm 0:9b334a45a8ff 225 static inline int spi_tend(spi_t *obj) {
mbed_official 119:3921aeca8633 226 return obj->spi.spi->SPSR & (1 << 6); // TEND
bogdanm 0:9b334a45a8ff 227 }
bogdanm 0:9b334a45a8ff 228
bogdanm 0:9b334a45a8ff 229 static inline void spi_write(spi_t *obj, int value) {
mbed_official 119:3921aeca8633 230 if (obj->spi.bits == 8) {
mbed_official 119:3921aeca8633 231 obj->spi.spi->SPDR.UINT8[0] = (uint8_t)value;
mbed_official 119:3921aeca8633 232 } else if (obj->spi.bits == 16) {
mbed_official 119:3921aeca8633 233 obj->spi.spi->SPDR.UINT16[0] = (uint16_t)value;
bogdanm 0:9b334a45a8ff 234 } else {
mbed_official 119:3921aeca8633 235 obj->spi.spi->SPDR.UINT32 = (uint32_t)value;
bogdanm 0:9b334a45a8ff 236 }
bogdanm 0:9b334a45a8ff 237 }
bogdanm 0:9b334a45a8ff 238
bogdanm 0:9b334a45a8ff 239 static inline int spi_read(spi_t *obj) {
bogdanm 0:9b334a45a8ff 240 int read_data;
mbed_official 119:3921aeca8633 241
mbed_official 119:3921aeca8633 242 if (obj->spi.bits == 8) {
mbed_official 119:3921aeca8633 243 read_data = obj->spi.spi->SPDR.UINT8[0];
mbed_official 119:3921aeca8633 244 } else if (obj->spi.bits == 16) {
mbed_official 119:3921aeca8633 245 read_data = obj->spi.spi->SPDR.UINT16[0];
bogdanm 0:9b334a45a8ff 246 } else {
mbed_official 119:3921aeca8633 247 read_data = obj->spi.spi->SPDR.UINT32;
bogdanm 0:9b334a45a8ff 248 }
mbed_official 119:3921aeca8633 249
bogdanm 0:9b334a45a8ff 250 return read_data;
bogdanm 0:9b334a45a8ff 251 }
bogdanm 0:9b334a45a8ff 252
bogdanm 0:9b334a45a8ff 253 int spi_master_write(spi_t *obj, int value) {
bogdanm 0:9b334a45a8ff 254 spi_write(obj, value);
bogdanm 0:9b334a45a8ff 255 while(!spi_tend(obj));
bogdanm 0:9b334a45a8ff 256 return spi_read(obj);
bogdanm 0:9b334a45a8ff 257 }
bogdanm 0:9b334a45a8ff 258
bogdanm 0:9b334a45a8ff 259 int spi_slave_receive(spi_t *obj) {
bogdanm 0:9b334a45a8ff 260 return (spi_readable(obj) && !spi_busy(obj)) ? (1) : (0);
bogdanm 0:9b334a45a8ff 261 }
bogdanm 0:9b334a45a8ff 262
bogdanm 0:9b334a45a8ff 263 int spi_slave_read(spi_t *obj) {
bogdanm 0:9b334a45a8ff 264 return spi_read(obj);
bogdanm 0:9b334a45a8ff 265 }
bogdanm 0:9b334a45a8ff 266
bogdanm 0:9b334a45a8ff 267 void spi_slave_write(spi_t *obj, int value) {
bogdanm 0:9b334a45a8ff 268 spi_write(obj, value);
bogdanm 0:9b334a45a8ff 269 }
bogdanm 0:9b334a45a8ff 270
bogdanm 0:9b334a45a8ff 271 int spi_busy(spi_t *obj) {
bogdanm 0:9b334a45a8ff 272 return 0;
bogdanm 0:9b334a45a8ff 273 }
mbed_official 119:3921aeca8633 274
mbed_official 119:3921aeca8633 275 #if DEVICE_SPI_ASYNCH
mbed_official 119:3921aeca8633 276
mbed_official 119:3921aeca8633 277 #define IRQ_NUM 2
mbed_official 119:3921aeca8633 278
mbed_official 119:3921aeca8633 279 static void spi_irqs_set(spi_t *obj, uint32_t enable);
mbed_official 119:3921aeca8633 280 static void spi_async_write(spi_t *obj);
mbed_official 119:3921aeca8633 281 static void spi_async_read(spi_t *obj);
mbed_official 119:3921aeca8633 282
mbed_official 119:3921aeca8633 283 static void spi0_rx_irq(void);
mbed_official 119:3921aeca8633 284 static void spi1_rx_irq(void);
mbed_official 119:3921aeca8633 285 static void spi2_rx_irq(void);
mbed_official 119:3921aeca8633 286 static void spi3_rx_irq(void);
mbed_official 119:3921aeca8633 287 static void spi4_rx_irq(void);
mbed_official 119:3921aeca8633 288 static void spi0_er_irq(void);
mbed_official 119:3921aeca8633 289 static void spi1_er_irq(void);
mbed_official 119:3921aeca8633 290 static void spi2_er_irq(void);
mbed_official 119:3921aeca8633 291 static void spi3_er_irq(void);
mbed_official 119:3921aeca8633 292 static void spi4_er_irq(void);
mbed_official 119:3921aeca8633 293
mbed_official 119:3921aeca8633 294 static const IRQn_Type irq_set_tbl[RSPI_COUNT][IRQ_NUM] = {
mbed_official 119:3921aeca8633 295 {RSPISPRI0_IRQn, RSPISPEI0_IRQn},
mbed_official 119:3921aeca8633 296 {RSPISPRI1_IRQn, RSPISPEI1_IRQn},
mbed_official 119:3921aeca8633 297 {RSPISPRI2_IRQn, RSPISPEI2_IRQn},
mbed_official 119:3921aeca8633 298 {RSPISPRI3_IRQn, RSPISPEI3_IRQn},
mbed_official 119:3921aeca8633 299 {RSPISPRI4_IRQn, RSPISPEI4_IRQn}
mbed_official 119:3921aeca8633 300 };
mbed_official 119:3921aeca8633 301
mbed_official 119:3921aeca8633 302 static const IRQHandler hander_set_tbl[RSPI_COUNT][IRQ_NUM] = {
mbed_official 119:3921aeca8633 303 {spi0_rx_irq, spi0_er_irq},
mbed_official 119:3921aeca8633 304 {spi1_rx_irq, spi1_er_irq},
mbed_official 119:3921aeca8633 305 {spi2_rx_irq, spi2_er_irq},
mbed_official 119:3921aeca8633 306 {spi3_rx_irq, spi3_er_irq},
mbed_official 119:3921aeca8633 307 {spi4_rx_irq, spi4_er_irq}
mbed_official 119:3921aeca8633 308 };
mbed_official 119:3921aeca8633 309
mbed_official 119:3921aeca8633 310 struct spi_global_data_s {
mbed_official 119:3921aeca8633 311 spi_t *async_obj;
mbed_official 119:3921aeca8633 312 uint32_t async_callback, event, wanted_events;
mbed_official 119:3921aeca8633 313 };
mbed_official 119:3921aeca8633 314
mbed_official 119:3921aeca8633 315 static struct spi_global_data_s spi_data[RSPI_COUNT];
mbed_official 119:3921aeca8633 316
mbed_official 119:3921aeca8633 317 static void spi_rx_irq(IRQn_Type irq_num, uint32_t index)
mbed_official 119:3921aeca8633 318 {
mbed_official 119:3921aeca8633 319 spi_t *obj = spi_data[index].async_obj;
mbed_official 119:3921aeca8633 320 if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
mbed_official 119:3921aeca8633 321 spi_async_read(obj);
mbed_official 119:3921aeca8633 322 } else {
mbed_official 119:3921aeca8633 323 if (obj->rx_buff.buffer && obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) {
mbed_official 119:3921aeca8633 324 spi_data[obj->spi.index].event = SPI_EVENT_INTERNAL_TRANSFER_COMPLETE;
mbed_official 119:3921aeca8633 325 if (spi_data[obj->spi.index].wanted_events & SPI_EVENT_COMPLETE) {
mbed_official 119:3921aeca8633 326 spi_data[obj->spi.index].event |= SPI_EVENT_COMPLETE;
mbed_official 119:3921aeca8633 327 }
mbed_official 119:3921aeca8633 328 spi_irqs_set(obj, 0);
mbed_official 119:3921aeca8633 329 spi_data[obj->spi.index].async_obj = NULL;
mbed_official 119:3921aeca8633 330 ((void (*)())spi_data[obj->spi.index].async_callback)();
mbed_official 119:3921aeca8633 331 return;
mbed_official 119:3921aeca8633 332 }
mbed_official 119:3921aeca8633 333 spi_read(obj);
mbed_official 119:3921aeca8633 334 }
mbed_official 119:3921aeca8633 335 if (obj->tx_buff.buffer) {
mbed_official 119:3921aeca8633 336 if (obj->tx_buff.pos == obj->tx_buff.length) {
mbed_official 119:3921aeca8633 337 spi_data[obj->spi.index].event = SPI_EVENT_INTERNAL_TRANSFER_COMPLETE;
mbed_official 119:3921aeca8633 338 if (spi_data[obj->spi.index].wanted_events & SPI_EVENT_COMPLETE) {
mbed_official 119:3921aeca8633 339 spi_data[obj->spi.index].event |= SPI_EVENT_COMPLETE;
mbed_official 119:3921aeca8633 340 }
mbed_official 119:3921aeca8633 341 spi_irqs_set(obj, 0);
mbed_official 119:3921aeca8633 342 spi_data[obj->spi.index].async_obj = NULL;
mbed_official 119:3921aeca8633 343 ((void (*)())spi_data[obj->spi.index].async_callback)();
mbed_official 119:3921aeca8633 344 } else {
mbed_official 119:3921aeca8633 345 spi_async_write(obj);
mbed_official 119:3921aeca8633 346 }
mbed_official 119:3921aeca8633 347 } else {
mbed_official 119:3921aeca8633 348 if (obj->rx_buff.pos == obj->rx_buff.length) {
mbed_official 119:3921aeca8633 349 spi_data[obj->spi.index].event = SPI_EVENT_INTERNAL_TRANSFER_COMPLETE;
mbed_official 119:3921aeca8633 350 if (spi_data[obj->spi.index].wanted_events & SPI_EVENT_COMPLETE) {
mbed_official 119:3921aeca8633 351 spi_data[obj->spi.index].event |= SPI_EVENT_COMPLETE;
mbed_official 119:3921aeca8633 352 }
mbed_official 119:3921aeca8633 353 spi_irqs_set(obj, 0);
mbed_official 119:3921aeca8633 354 spi_data[obj->spi.index].async_obj = NULL;
mbed_official 119:3921aeca8633 355 ((void (*)())spi_data[obj->spi.index].async_callback)();
mbed_official 119:3921aeca8633 356 } else {
mbed_official 119:3921aeca8633 357 spi_async_write(obj);
mbed_official 119:3921aeca8633 358 }
mbed_official 119:3921aeca8633 359 }
mbed_official 119:3921aeca8633 360 }
mbed_official 119:3921aeca8633 361
mbed_official 119:3921aeca8633 362 static void spi_err_irq(IRQn_Type irq_num, uint32_t index)
mbed_official 119:3921aeca8633 363 {
mbed_official 119:3921aeca8633 364 spi_t *obj = spi_data[index].async_obj;
mbed_official 119:3921aeca8633 365 spi_abort_asynch(obj);
mbed_official 119:3921aeca8633 366 spi_data[index].event = SPI_EVENT_ERROR;
mbed_official 119:3921aeca8633 367 if (spi_data[index].wanted_events & SPI_EVENT_ERROR) {
mbed_official 119:3921aeca8633 368 ((void (*)())spi_data[index].async_callback)();
mbed_official 119:3921aeca8633 369 }
mbed_official 119:3921aeca8633 370 }
mbed_official 119:3921aeca8633 371
mbed_official 119:3921aeca8633 372 static void spi0_rx_irq(void)
mbed_official 119:3921aeca8633 373 {
mbed_official 119:3921aeca8633 374 spi_rx_irq(RSPISPRI0_IRQn, 0);
mbed_official 119:3921aeca8633 375 }
mbed_official 119:3921aeca8633 376
mbed_official 119:3921aeca8633 377 static void spi1_rx_irq(void)
mbed_official 119:3921aeca8633 378 {
mbed_official 119:3921aeca8633 379 spi_rx_irq(RSPISPRI1_IRQn, 1);
mbed_official 119:3921aeca8633 380 }
mbed_official 119:3921aeca8633 381
mbed_official 119:3921aeca8633 382 static void spi2_rx_irq(void)
mbed_official 119:3921aeca8633 383 {
mbed_official 119:3921aeca8633 384 spi_rx_irq(RSPISPRI2_IRQn, 2);
mbed_official 119:3921aeca8633 385 }
mbed_official 119:3921aeca8633 386
mbed_official 119:3921aeca8633 387 static void spi3_rx_irq(void)
mbed_official 119:3921aeca8633 388 {
mbed_official 119:3921aeca8633 389 spi_rx_irq(RSPISPRI3_IRQn, 3);
mbed_official 119:3921aeca8633 390 }
mbed_official 119:3921aeca8633 391
mbed_official 119:3921aeca8633 392 static void spi4_rx_irq(void)
mbed_official 119:3921aeca8633 393 {
mbed_official 119:3921aeca8633 394 spi_rx_irq(RSPISPRI4_IRQn, 4);
mbed_official 119:3921aeca8633 395 }
mbed_official 119:3921aeca8633 396
mbed_official 119:3921aeca8633 397 static void spi0_er_irq(void)
mbed_official 119:3921aeca8633 398 {
mbed_official 119:3921aeca8633 399 spi_err_irq(RSPISPEI0_IRQn, 0);
mbed_official 119:3921aeca8633 400 }
mbed_official 119:3921aeca8633 401
mbed_official 119:3921aeca8633 402 static void spi1_er_irq(void)
mbed_official 119:3921aeca8633 403 {
mbed_official 119:3921aeca8633 404 spi_err_irq(RSPISPEI1_IRQn, 1);
mbed_official 119:3921aeca8633 405 }
mbed_official 119:3921aeca8633 406
mbed_official 119:3921aeca8633 407 static void spi2_er_irq(void)
mbed_official 119:3921aeca8633 408 {
mbed_official 119:3921aeca8633 409 spi_err_irq(RSPISPEI2_IRQn, 2);
mbed_official 119:3921aeca8633 410 }
mbed_official 119:3921aeca8633 411
mbed_official 119:3921aeca8633 412 static void spi3_er_irq(void)
mbed_official 119:3921aeca8633 413 {
mbed_official 119:3921aeca8633 414 spi_err_irq(RSPISPEI3_IRQn, 3);
mbed_official 119:3921aeca8633 415 }
mbed_official 119:3921aeca8633 416
mbed_official 119:3921aeca8633 417 static void spi4_er_irq(void)
mbed_official 119:3921aeca8633 418 {
mbed_official 119:3921aeca8633 419 spi_err_irq(RSPISPEI4_IRQn, 4);
mbed_official 119:3921aeca8633 420 }
mbed_official 119:3921aeca8633 421
mbed_official 119:3921aeca8633 422 static void spi_irqs_set(spi_t *obj, uint32_t enable)
mbed_official 119:3921aeca8633 423 {
mbed_official 119:3921aeca8633 424 int i;
mbed_official 119:3921aeca8633 425 const IRQn_Type *irqTable = irq_set_tbl[obj->spi.index];
mbed_official 119:3921aeca8633 426 const IRQHandler *handlerTable = hander_set_tbl[obj->spi.index];
mbed_official 119:3921aeca8633 427 for (i = 0; i < IRQ_NUM; ++i) {
mbed_official 119:3921aeca8633 428 if (enable) {
mbed_official 119:3921aeca8633 429 InterruptHandlerRegister(irqTable[i], handlerTable[i]);
mbed_official 119:3921aeca8633 430 GIC_SetPriority(irqTable[i], 5);
mbed_official 119:3921aeca8633 431 GIC_EnableIRQ(irqTable[i]);
mbed_official 119:3921aeca8633 432 } else {
mbed_official 119:3921aeca8633 433 GIC_DisableIRQ(irqTable[i]);
mbed_official 119:3921aeca8633 434 }
mbed_official 119:3921aeca8633 435 }
mbed_official 119:3921aeca8633 436 if (enable) {
mbed_official 119:3921aeca8633 437 obj->spi.spi->SPCR |= (1 << 4) | (1 << 7);
mbed_official 119:3921aeca8633 438 } else {
mbed_official 119:3921aeca8633 439 obj->spi.spi->SPCR &= ~((1 << 4) | (1 << 7));
mbed_official 119:3921aeca8633 440 }
mbed_official 119:3921aeca8633 441 }
mbed_official 119:3921aeca8633 442
mbed_official 119:3921aeca8633 443 static void spi_async_write(spi_t *obj)
mbed_official 119:3921aeca8633 444 {
mbed_official 119:3921aeca8633 445 uint8_t **width8;
mbed_official 119:3921aeca8633 446 uint16_t **width16;
mbed_official 119:3921aeca8633 447 uint32_t **width32;
mbed_official 119:3921aeca8633 448
mbed_official 119:3921aeca8633 449 if (obj->tx_buff.buffer) {
mbed_official 119:3921aeca8633 450 switch (obj->tx_buff.width) {
mbed_official 119:3921aeca8633 451 case 8:
mbed_official 119:3921aeca8633 452 width8 = (uint8_t **)&obj->tx_buff.buffer;
mbed_official 119:3921aeca8633 453 spi_write(obj, **width8);
mbed_official 119:3921aeca8633 454 ++*width8;
mbed_official 119:3921aeca8633 455 obj->tx_buff.pos += sizeof(uint8_t);
mbed_official 119:3921aeca8633 456 break;
mbed_official 119:3921aeca8633 457
mbed_official 119:3921aeca8633 458 case 16:
mbed_official 119:3921aeca8633 459 width16 = (uint16_t **)&obj->tx_buff.buffer;
mbed_official 119:3921aeca8633 460 spi_write(obj, **width16);
mbed_official 119:3921aeca8633 461 ++*width16;
mbed_official 119:3921aeca8633 462 obj->tx_buff.pos += sizeof(uint16_t);
mbed_official 119:3921aeca8633 463 break;
mbed_official 119:3921aeca8633 464
mbed_official 119:3921aeca8633 465 case 32:
mbed_official 119:3921aeca8633 466 width32 = (uint32_t **)&obj->tx_buff.buffer;
mbed_official 119:3921aeca8633 467 spi_write(obj, **width32);
mbed_official 119:3921aeca8633 468 ++*width32;
mbed_official 119:3921aeca8633 469 obj->tx_buff.pos += sizeof(uint32_t);
mbed_official 119:3921aeca8633 470 break;
mbed_official 119:3921aeca8633 471
mbed_official 119:3921aeca8633 472 default:
mbed_official 119:3921aeca8633 473 MBED_ASSERT(0);
mbed_official 119:3921aeca8633 474 break;
mbed_official 119:3921aeca8633 475 }
mbed_official 119:3921aeca8633 476 } else {
mbed_official 119:3921aeca8633 477 spi_write(obj, SPI_FILL_WORD);
mbed_official 119:3921aeca8633 478 }
mbed_official 119:3921aeca8633 479 }
mbed_official 119:3921aeca8633 480
mbed_official 119:3921aeca8633 481 static void spi_async_read(spi_t *obj)
mbed_official 119:3921aeca8633 482 {
mbed_official 119:3921aeca8633 483 uint8_t **width8;
mbed_official 119:3921aeca8633 484 uint16_t **width16;
mbed_official 119:3921aeca8633 485 uint32_t **width32;
mbed_official 119:3921aeca8633 486
mbed_official 119:3921aeca8633 487 switch (obj->rx_buff.width) {
mbed_official 119:3921aeca8633 488 case 8:
mbed_official 119:3921aeca8633 489 width8 = (uint8_t **)&obj->rx_buff.buffer;
mbed_official 119:3921aeca8633 490 **width8 = spi_read(obj);
mbed_official 119:3921aeca8633 491 ++*width8;
mbed_official 119:3921aeca8633 492 obj->rx_buff.pos += sizeof(uint8_t);
mbed_official 119:3921aeca8633 493 break;
mbed_official 119:3921aeca8633 494
mbed_official 119:3921aeca8633 495 case 16:
mbed_official 119:3921aeca8633 496 width16 = (uint16_t **)&obj->rx_buff.buffer;
mbed_official 119:3921aeca8633 497 **width16 = spi_read(obj);
mbed_official 119:3921aeca8633 498 ++*width16;
mbed_official 119:3921aeca8633 499 obj->rx_buff.pos += sizeof(uint16_t);
mbed_official 119:3921aeca8633 500 break;
mbed_official 119:3921aeca8633 501
mbed_official 119:3921aeca8633 502 case 32:
mbed_official 119:3921aeca8633 503 width32 = (uint32_t **)&obj->rx_buff.buffer;
mbed_official 119:3921aeca8633 504 **width32 = spi_read(obj);
mbed_official 119:3921aeca8633 505 ++*width32;
mbed_official 119:3921aeca8633 506 obj->rx_buff.pos += sizeof(uint32_t);
mbed_official 119:3921aeca8633 507 break;
mbed_official 119:3921aeca8633 508
mbed_official 119:3921aeca8633 509 default:
mbed_official 119:3921aeca8633 510 MBED_ASSERT(0);
mbed_official 119:3921aeca8633 511 break;
mbed_official 119:3921aeca8633 512 }
mbed_official 119:3921aeca8633 513 }
mbed_official 119:3921aeca8633 514
mbed_official 119:3921aeca8633 515 /******************************************************************************
mbed_official 119:3921aeca8633 516 * ASYNCHRONOUS HAL
mbed_official 119:3921aeca8633 517 ******************************************************************************/
mbed_official 119:3921aeca8633 518
mbed_official 119:3921aeca8633 519 void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint)
mbed_official 119:3921aeca8633 520 {
mbed_official 119:3921aeca8633 521 int i;
mbed_official 119:3921aeca8633 522 MBED_ASSERT(obj);
mbed_official 119:3921aeca8633 523 MBED_ASSERT(tx || rx);
mbed_official 119:3921aeca8633 524 MBED_ASSERT(tx && ! rx ? tx_length : 1);
mbed_official 119:3921aeca8633 525 MBED_ASSERT(rx && ! tx ? rx_length : 1);
mbed_official 119:3921aeca8633 526 MBED_ASSERT(obj->spi.spi->SPCR & (1 << 3)); /* Slave mode */
mbed_official 119:3921aeca8633 527 MBED_ASSERT(bit_width == 8 || bit_width == 16 || bit_width == 32);
mbed_official 119:3921aeca8633 528
mbed_official 119:3921aeca8633 529 if (tx_length) {
mbed_official 119:3921aeca8633 530 obj->tx_buff.buffer = (void *)tx;
mbed_official 119:3921aeca8633 531 } else {
mbed_official 119:3921aeca8633 532 obj->tx_buff.buffer = NULL;
mbed_official 119:3921aeca8633 533 }
mbed_official 119:3921aeca8633 534 obj->tx_buff.length = tx_length * bit_width / 8;
mbed_official 119:3921aeca8633 535 obj->tx_buff.pos = 0;
mbed_official 119:3921aeca8633 536 obj->tx_buff.width = bit_width;
mbed_official 119:3921aeca8633 537 if (rx_length) {
mbed_official 119:3921aeca8633 538 obj->rx_buff.buffer = rx;
mbed_official 119:3921aeca8633 539 } else {
mbed_official 119:3921aeca8633 540 obj->rx_buff.buffer = NULL;
mbed_official 119:3921aeca8633 541 }
mbed_official 119:3921aeca8633 542 obj->rx_buff.length = rx_length * bit_width / 8;
mbed_official 119:3921aeca8633 543 obj->rx_buff.pos = 0;
mbed_official 119:3921aeca8633 544 obj->rx_buff.width = bit_width;
mbed_official 119:3921aeca8633 545 for (i = 0; i < obj->rx_buff.length; i++) {
mbed_official 119:3921aeca8633 546 ((uint8_t *)obj->rx_buff.buffer)[i] = SPI_FILL_WORD;
mbed_official 119:3921aeca8633 547 }
mbed_official 119:3921aeca8633 548
mbed_official 119:3921aeca8633 549 spi_data[obj->spi.index].async_callback = handler;
mbed_official 119:3921aeca8633 550 spi_data[obj->spi.index].async_obj = obj;
mbed_official 119:3921aeca8633 551 spi_data[obj->spi.index].event = 0;
mbed_official 119:3921aeca8633 552 spi_data[obj->spi.index].wanted_events = event;
mbed_official 119:3921aeca8633 553
mbed_official 119:3921aeca8633 554 spi_irqs_set(obj, 1);
mbed_official 119:3921aeca8633 555
mbed_official 119:3921aeca8633 556 spi_async_write(obj);
mbed_official 119:3921aeca8633 557 }
mbed_official 119:3921aeca8633 558
mbed_official 119:3921aeca8633 559 uint32_t spi_irq_handler_asynch(spi_t *obj)
mbed_official 119:3921aeca8633 560 {
mbed_official 119:3921aeca8633 561 return spi_data[obj->spi.index].event;
mbed_official 119:3921aeca8633 562 }
mbed_official 119:3921aeca8633 563
mbed_official 119:3921aeca8633 564 uint8_t spi_active(spi_t *obj)
mbed_official 119:3921aeca8633 565 {
mbed_official 119:3921aeca8633 566 return spi_data[obj->spi.index].async_obj != NULL;
mbed_official 119:3921aeca8633 567 }
mbed_official 119:3921aeca8633 568
mbed_official 119:3921aeca8633 569 void spi_abort_asynch(spi_t *obj)
mbed_official 119:3921aeca8633 570 {
mbed_official 119:3921aeca8633 571 spi_disable(obj);
mbed_official 119:3921aeca8633 572 spi_irqs_set(obj, 0);
mbed_official 119:3921aeca8633 573 spi_data[obj->spi.index].async_obj = NULL;
mbed_official 119:3921aeca8633 574 spi_enable(obj);
mbed_official 119:3921aeca8633 575 }
mbed_official 119:3921aeca8633 576
mbed_official 119:3921aeca8633 577 #endif