SilentSensors / mbed-dev

Fork of mbed-dev by mbed official

Committer:
AnnaBridge
Date:
Thu Sep 06 13:40:20 2018 +0100
Revision:
187:0387e8f68319
mbed-dev library. Release version 163

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 187:0387e8f68319 1 /* mbed Microcontroller Library
AnnaBridge 187:0387e8f68319 2 * (C)Copyright TOSHIBA ELECTRONIC DEVICES & STORAGE CORPORATION 2018 All rights reserved
AnnaBridge 187:0387e8f68319 3 *
AnnaBridge 187:0387e8f68319 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 187:0387e8f68319 5 * you may not use this file except in compliance with the License.
AnnaBridge 187:0387e8f68319 6 * You may obtain a copy of the License at
AnnaBridge 187:0387e8f68319 7 *
AnnaBridge 187:0387e8f68319 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 187:0387e8f68319 9 *
AnnaBridge 187:0387e8f68319 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 187:0387e8f68319 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 187:0387e8f68319 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 187:0387e8f68319 13 * See the License for the specific language governing permissions and
AnnaBridge 187:0387e8f68319 14 * limitations under the License.
AnnaBridge 187:0387e8f68319 15 */
AnnaBridge 187:0387e8f68319 16 #include "spi_api.h"
AnnaBridge 187:0387e8f68319 17 #include "mbed_error.h"
AnnaBridge 187:0387e8f68319 18 #include "pinmap.h"
AnnaBridge 187:0387e8f68319 19 #include "gpio_include.h"
AnnaBridge 187:0387e8f68319 20 #include "txz_tspi.h"
AnnaBridge 187:0387e8f68319 21
AnnaBridge 187:0387e8f68319 22 static const PinMap PinMap_SPI_SCLK[] = {
AnnaBridge 187:0387e8f68319 23 {PM0, SPI_0, PIN_DATA(3, 2)},
AnnaBridge 187:0387e8f68319 24 {PP0, SPI_1, PIN_DATA(1, 2)},
AnnaBridge 187:0387e8f68319 25 {NC, NC, 0}
AnnaBridge 187:0387e8f68319 26 };
AnnaBridge 187:0387e8f68319 27
AnnaBridge 187:0387e8f68319 28 static const PinMap PinMap_SPI_MOSI[] = {
AnnaBridge 187:0387e8f68319 29 {PM1, SPI_0, PIN_DATA(3, 1)},
AnnaBridge 187:0387e8f68319 30 {PP1, SPI_1, PIN_DATA(1, 1)},
AnnaBridge 187:0387e8f68319 31 {NC, NC, 0}
AnnaBridge 187:0387e8f68319 32 };
AnnaBridge 187:0387e8f68319 33
AnnaBridge 187:0387e8f68319 34 static const PinMap PinMap_SPI_MISO[] = {
AnnaBridge 187:0387e8f68319 35 {PM2, SPI_0, PIN_DATA(3, 0)},
AnnaBridge 187:0387e8f68319 36 {PP2, SPI_1, PIN_DATA(1, 0)},
AnnaBridge 187:0387e8f68319 37 {NC, NC, 0}
AnnaBridge 187:0387e8f68319 38 };
AnnaBridge 187:0387e8f68319 39
AnnaBridge 187:0387e8f68319 40 static const PinMap PinMap_SPI_SSEL[] = {
AnnaBridge 187:0387e8f68319 41 {PM3, SPI_0, PIN_DATA(3, 1)},
AnnaBridge 187:0387e8f68319 42 {PL6, SPI_1, PIN_DATA(1, 2)},
AnnaBridge 187:0387e8f68319 43 {NC, NC, 0}
AnnaBridge 187:0387e8f68319 44 };
AnnaBridge 187:0387e8f68319 45
AnnaBridge 187:0387e8f68319 46 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
AnnaBridge 187:0387e8f68319 47 {
AnnaBridge 187:0387e8f68319 48 // Check pin parameters
AnnaBridge 187:0387e8f68319 49 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
AnnaBridge 187:0387e8f68319 50 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
AnnaBridge 187:0387e8f68319 51 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
AnnaBridge 187:0387e8f68319 52 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
AnnaBridge 187:0387e8f68319 53 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
AnnaBridge 187:0387e8f68319 54 SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
AnnaBridge 187:0387e8f68319 55
AnnaBridge 187:0387e8f68319 56 obj->module = (SPIName)pinmap_merge(spi_data, spi_sclk);
AnnaBridge 187:0387e8f68319 57 obj->module = (SPIName)pinmap_merge(spi_data, spi_cntl);
AnnaBridge 187:0387e8f68319 58 MBED_ASSERT((int)obj->module!= NC);
AnnaBridge 187:0387e8f68319 59
AnnaBridge 187:0387e8f68319 60 // Identify SPI module to use
AnnaBridge 187:0387e8f68319 61 switch ((int)obj->module) {
AnnaBridge 187:0387e8f68319 62 case SPI_0:
AnnaBridge 187:0387e8f68319 63 obj->p_obj.p_instance = TSB_TSPI0;
AnnaBridge 187:0387e8f68319 64 TSB_CG_FSYSENA_IPENA18 = ENABLE;
AnnaBridge 187:0387e8f68319 65 TSB_CG_FSYSENA_IPENA11 = ENABLE;
AnnaBridge 187:0387e8f68319 66 break;
AnnaBridge 187:0387e8f68319 67 case SPI_1:
AnnaBridge 187:0387e8f68319 68 obj->p_obj.p_instance = TSB_TSPI1;
AnnaBridge 187:0387e8f68319 69 TSB_CG_FSYSENA_IPENA19 = ENABLE;
AnnaBridge 187:0387e8f68319 70 TSB_CG_FSYSENA_IPENA13 = ENABLE;
AnnaBridge 187:0387e8f68319 71 TSB_CG_FSYSENA_IPENA10 = ENABLE;
AnnaBridge 187:0387e8f68319 72 break;
AnnaBridge 187:0387e8f68319 73 default:
AnnaBridge 187:0387e8f68319 74 error("Cannot found SPI module corresponding with input pins.");
AnnaBridge 187:0387e8f68319 75 break;
AnnaBridge 187:0387e8f68319 76 }
AnnaBridge 187:0387e8f68319 77
AnnaBridge 187:0387e8f68319 78 // pin out the spi pins
AnnaBridge 187:0387e8f68319 79 pinmap_pinout(mosi, PinMap_SPI_MOSI);
AnnaBridge 187:0387e8f68319 80 pinmap_pinout(miso, PinMap_SPI_MISO);
AnnaBridge 187:0387e8f68319 81 pinmap_pinout(sclk, PinMap_SPI_SCLK);
AnnaBridge 187:0387e8f68319 82
AnnaBridge 187:0387e8f68319 83 if (ssel != NC) {
AnnaBridge 187:0387e8f68319 84 pinmap_pinout(ssel, PinMap_SPI_SSEL);
AnnaBridge 187:0387e8f68319 85 }
AnnaBridge 187:0387e8f68319 86
AnnaBridge 187:0387e8f68319 87 //Control 1 configurations
AnnaBridge 187:0387e8f68319 88 obj->p_obj.init.id = (uint32_t)obj->module;
AnnaBridge 187:0387e8f68319 89 obj->p_obj.init.cnt1.trgen = TSPI_TRGEN_DISABLE; // Trigger disabled
AnnaBridge 187:0387e8f68319 90 obj->p_obj.init.cnt1.trxe = TSPI_DISABLE; // Enable Communication
AnnaBridge 187:0387e8f68319 91 obj->p_obj.init.cnt1.tspims = TSPI_SPI_MODE; // SPI mode
AnnaBridge 187:0387e8f68319 92 obj->p_obj.init.cnt1.mstr = TSPI_MASTER_OPEARTION; // master mode operation
AnnaBridge 187:0387e8f68319 93 obj->p_obj.init.cnt1.tmmd = TSPI_TWO_WAY; // Full-duplex mode (Transmit/receive)
AnnaBridge 187:0387e8f68319 94 obj->p_obj.init.cnt1.cssel = TSPI_TSPIxCS0_ENABLE; // Chip select of pin CS0 is valid
AnnaBridge 187:0387e8f68319 95 obj->p_obj.init.cnt1.fc = TSPI_TRANS_RANGE_SINGLE; // transfer single frame at a time continuously
AnnaBridge 187:0387e8f68319 96
AnnaBridge 187:0387e8f68319 97 //Control 2 configurations
AnnaBridge 187:0387e8f68319 98 obj->p_obj.init.cnt2.tidle = TSPI_TIDLE_HI;
AnnaBridge 187:0387e8f68319 99 obj->p_obj.init.cnt2.txdemp = TSPI_TXDEMP_HI; // when slave underruns TxD fixed to low
AnnaBridge 187:0387e8f68319 100 obj->p_obj.init.cnt2.rxdly = TSPI_RXDLY_40MHz_OVER;
AnnaBridge 187:0387e8f68319 101 obj->p_obj.init.cnt2.til = TSPI_TX_FILL_LEVEL_0; // transmit FIFO Level
AnnaBridge 187:0387e8f68319 102 obj->p_obj.init.cnt2.ril = TSPI_RX_FILL_LEVEL_1; // receive FIFO Level
AnnaBridge 187:0387e8f68319 103 obj->p_obj.init.cnt2.inttxwe = TSPI_TX_INT_DISABLE;
AnnaBridge 187:0387e8f68319 104 obj->p_obj.init.cnt2.intrxwe = TSPI_RX_INT_DISABLE;
AnnaBridge 187:0387e8f68319 105 obj->p_obj.init.cnt2.inttxfe = TSPI_TX_FIFO_INT_DISABLE;
AnnaBridge 187:0387e8f68319 106 obj->p_obj.init.cnt2.intrxfe = TSPI_RX_FIFO_INT_DISABLE;
AnnaBridge 187:0387e8f68319 107 obj->p_obj.init.cnt2.interr = TSPI_ERR_INT_DISABLE;
AnnaBridge 187:0387e8f68319 108 obj->p_obj.init.cnt2.dmate = TSPI_TX_DMA_INT_DISABLE;
AnnaBridge 187:0387e8f68319 109 obj->p_obj.init.cnt2.dmare = TSPI_RX_DMA_INT_DISABLE;
AnnaBridge 187:0387e8f68319 110
AnnaBridge 187:0387e8f68319 111 //Control 3 configurations
AnnaBridge 187:0387e8f68319 112 obj->p_obj.init.cnt3.tfempclr = TSPI_TX_BUFF_CLR_DONE; // transmit buffer clear
AnnaBridge 187:0387e8f68319 113 obj->p_obj.init.cnt3.rffllclr = TSPI_RX_BUFF_CLR_DONE; // receive buffer clear
AnnaBridge 187:0387e8f68319 114
AnnaBridge 187:0387e8f68319 115 //baudrate settings
AnnaBridge 187:0387e8f68319 116 spi_frequency(obj, (int)INITIAL_SPI_FREQ);
AnnaBridge 187:0387e8f68319 117
AnnaBridge 187:0387e8f68319 118 //Format Control 0 settings
AnnaBridge 187:0387e8f68319 119 obj->p_obj.init.fmr0.dir = TSPI_DATA_DIRECTION_MSB; // MSB bit first
AnnaBridge 187:0387e8f68319 120 obj->p_obj.init.fmr0.fl = TSPI_DATA_LENGTH_8;
AnnaBridge 187:0387e8f68319 121 obj->p_obj.init.fmr0.fint = TSPI_INTERVAL_TIME_0;
AnnaBridge 187:0387e8f68319 122
AnnaBridge 187:0387e8f68319 123 //Special control on polarity of signal and generation timing
AnnaBridge 187:0387e8f68319 124 obj->p_obj.init.fmr0.cs3pol = TSPI_TSPIxCS3_NEGATIVE;
AnnaBridge 187:0387e8f68319 125 obj->p_obj.init.fmr0.cs2pol = TSPI_TSPIxCS2_NEGATIVE;
AnnaBridge 187:0387e8f68319 126 obj->p_obj.init.fmr0.cs1pol = TSPI_TSPIxCS1_NEGATIVE;
AnnaBridge 187:0387e8f68319 127 obj->p_obj.init.fmr0.cs0pol = TSPI_TSPIxCS0_NEGATIVE;
AnnaBridge 187:0387e8f68319 128
AnnaBridge 187:0387e8f68319 129 obj->p_obj.init.fmr0.ckpha = TSPI_SERIAL_CK_1ST_EDGE;
AnnaBridge 187:0387e8f68319 130 obj->p_obj.init.fmr0.ckpol = TSPI_SERIAL_CK_IDLE_LOW;
AnnaBridge 187:0387e8f68319 131 obj->p_obj.init.fmr0.csint = TSPI_MIN_IDLE_TIME_1;
AnnaBridge 187:0387e8f68319 132 obj->p_obj.init.fmr0.cssckdl = TSPI_SERIAL_CK_DELAY_1;
AnnaBridge 187:0387e8f68319 133 obj->p_obj.init.fmr0.sckcsdl = TSPI_NEGATE_1;
AnnaBridge 187:0387e8f68319 134
AnnaBridge 187:0387e8f68319 135 //Format Control 1 settings tspi_fmtr1_t
AnnaBridge 187:0387e8f68319 136 obj->p_obj.init.fmr1.vpe = TSPI_PARITY_DISABLE;
AnnaBridge 187:0387e8f68319 137 obj->p_obj.init.fmr1.vpm = TSPI_PARITY_BIT_ODD;
AnnaBridge 187:0387e8f68319 138
AnnaBridge 187:0387e8f68319 139 obj->bits = (uint8_t)TSPI_DATA_LENGTH_8;
AnnaBridge 187:0387e8f68319 140 //initialize SPI
AnnaBridge 187:0387e8f68319 141 tspi_init(&obj->p_obj);
AnnaBridge 187:0387e8f68319 142 }
AnnaBridge 187:0387e8f68319 143
AnnaBridge 187:0387e8f68319 144 void spi_free(spi_t *obj)
AnnaBridge 187:0387e8f68319 145 {
AnnaBridge 187:0387e8f68319 146 tspi_deinit(&obj->p_obj);
AnnaBridge 187:0387e8f68319 147 obj->module = (SPIName)NC;
AnnaBridge 187:0387e8f68319 148 }
AnnaBridge 187:0387e8f68319 149
AnnaBridge 187:0387e8f68319 150 void spi_format(spi_t *obj, int bits, int mode, int slave)
AnnaBridge 187:0387e8f68319 151 {
AnnaBridge 187:0387e8f68319 152 MBED_ASSERT((slave == 0U) || (slave == 1U)); // 0: master mode, 1: slave mode
AnnaBridge 187:0387e8f68319 153 MBED_ASSERT((bits >= 8) && (bits <= 32));
AnnaBridge 187:0387e8f68319 154
AnnaBridge 187:0387e8f68319 155 obj->bits = bits;
AnnaBridge 187:0387e8f68319 156 obj->p_obj.init.fmr0.fl = (bits << 24);
AnnaBridge 187:0387e8f68319 157
AnnaBridge 187:0387e8f68319 158 if ((mode >> 1) & 0x1) {
AnnaBridge 187:0387e8f68319 159 obj->p_obj.init.fmr0.ckpol = TSPI_SERIAL_CK_IDLE_HI;
AnnaBridge 187:0387e8f68319 160 } else {
AnnaBridge 187:0387e8f68319 161 obj->p_obj.init.fmr0.ckpol = TSPI_SERIAL_CK_IDLE_LOW;
AnnaBridge 187:0387e8f68319 162 }
AnnaBridge 187:0387e8f68319 163
AnnaBridge 187:0387e8f68319 164 if (mode & 0x1) {
AnnaBridge 187:0387e8f68319 165 obj->p_obj.init.fmr0.ckpha = TSPI_SERIAL_CK_2ND_EDGE;
AnnaBridge 187:0387e8f68319 166 } else {
AnnaBridge 187:0387e8f68319 167 obj->p_obj.init.fmr0.ckpha = TSPI_SERIAL_CK_1ST_EDGE;
AnnaBridge 187:0387e8f68319 168 }
AnnaBridge 187:0387e8f68319 169
AnnaBridge 187:0387e8f68319 170 tspi_init(&obj->p_obj);
AnnaBridge 187:0387e8f68319 171 }
AnnaBridge 187:0387e8f68319 172
AnnaBridge 187:0387e8f68319 173 void spi_frequency(spi_t *obj, int hz)
AnnaBridge 187:0387e8f68319 174 {
AnnaBridge 187:0387e8f68319 175 uint8_t brs = 0;
AnnaBridge 187:0387e8f68319 176 uint8_t brck = 0;
AnnaBridge 187:0387e8f68319 177 uint16_t prsck = 1;
AnnaBridge 187:0387e8f68319 178 uint64_t fscl = 0;
AnnaBridge 187:0387e8f68319 179 uint64_t tmp_fscl = 0;
AnnaBridge 187:0387e8f68319 180 uint64_t fx = 0;
AnnaBridge 187:0387e8f68319 181 uint64_t tmpvar = SystemCoreClock;
AnnaBridge 187:0387e8f68319 182
AnnaBridge 187:0387e8f68319 183 SystemCoreClockUpdate();
AnnaBridge 187:0387e8f68319 184
AnnaBridge 187:0387e8f68319 185 tmpvar = tmpvar / 2;
AnnaBridge 187:0387e8f68319 186
AnnaBridge 187:0387e8f68319 187 for (prsck = 1; prsck <= 512; prsck *= 2) {
AnnaBridge 187:0387e8f68319 188 fx = ((uint64_t)tmpvar / prsck);
AnnaBridge 187:0387e8f68319 189 for (brs = 1; brs <= 16; brs++) {
AnnaBridge 187:0387e8f68319 190 fscl = fx /brs;
AnnaBridge 187:0387e8f68319 191 if ((fscl <= (uint64_t)hz) && (fscl > tmp_fscl)) {
AnnaBridge 187:0387e8f68319 192 tmp_fscl = fscl;
AnnaBridge 187:0387e8f68319 193 obj->p_obj.init.brd.brck = (brck << 4);
AnnaBridge 187:0387e8f68319 194 if (brs == 16) {
AnnaBridge 187:0387e8f68319 195 obj->p_obj.init.brd.brs = 0;
AnnaBridge 187:0387e8f68319 196 } else {
AnnaBridge 187:0387e8f68319 197 obj->p_obj.init.brd.brs = brs;
AnnaBridge 187:0387e8f68319 198 }
AnnaBridge 187:0387e8f68319 199 }
AnnaBridge 187:0387e8f68319 200 }
AnnaBridge 187:0387e8f68319 201 brck ++;
AnnaBridge 187:0387e8f68319 202 }
AnnaBridge 187:0387e8f68319 203 tspi_init(&obj->p_obj);
AnnaBridge 187:0387e8f68319 204 }
AnnaBridge 187:0387e8f68319 205
AnnaBridge 187:0387e8f68319 206 int spi_master_write(spi_t *obj, int value)
AnnaBridge 187:0387e8f68319 207 {
AnnaBridge 187:0387e8f68319 208 uint8_t ret_value = 0;
AnnaBridge 187:0387e8f68319 209
AnnaBridge 187:0387e8f68319 210 tspi_transmit_t send_obj;
AnnaBridge 187:0387e8f68319 211 tspi_receive_t rec_obj;
AnnaBridge 187:0387e8f68319 212
AnnaBridge 187:0387e8f68319 213 // Transmit data
AnnaBridge 187:0387e8f68319 214 send_obj.tx8.p_data = (uint8_t *)&value;
AnnaBridge 187:0387e8f68319 215 send_obj.tx8.num = 1;
AnnaBridge 187:0387e8f68319 216 tspi_master_write(&obj->p_obj, &send_obj, TIMEOUT);
AnnaBridge 187:0387e8f68319 217
AnnaBridge 187:0387e8f68319 218 // Read received data
AnnaBridge 187:0387e8f68319 219 rec_obj.rx8.p_data = &ret_value;
AnnaBridge 187:0387e8f68319 220 rec_obj.rx8.num = 1;
AnnaBridge 187:0387e8f68319 221 tspi_master_read(&obj->p_obj, &rec_obj, TIMEOUT);
AnnaBridge 187:0387e8f68319 222
AnnaBridge 187:0387e8f68319 223 return ret_value;
AnnaBridge 187:0387e8f68319 224 }
AnnaBridge 187:0387e8f68319 225
AnnaBridge 187:0387e8f68319 226 int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
AnnaBridge 187:0387e8f68319 227 char *rx_buffer, int rx_length, char write_fill)
AnnaBridge 187:0387e8f68319 228 {
AnnaBridge 187:0387e8f68319 229 int total = (tx_length > rx_length) ? tx_length : rx_length;
AnnaBridge 187:0387e8f68319 230
AnnaBridge 187:0387e8f68319 231 for (int i = 0; i < total; i++) {
AnnaBridge 187:0387e8f68319 232 char out = (i < tx_length) ? tx_buffer[i] : write_fill;
AnnaBridge 187:0387e8f68319 233 char in = spi_master_write(obj, out);
AnnaBridge 187:0387e8f68319 234 if (i < rx_length) {
AnnaBridge 187:0387e8f68319 235 rx_buffer[i] = in;
AnnaBridge 187:0387e8f68319 236 }
AnnaBridge 187:0387e8f68319 237 }
AnnaBridge 187:0387e8f68319 238
AnnaBridge 187:0387e8f68319 239 return total;
AnnaBridge 187:0387e8f68319 240 }
AnnaBridge 187:0387e8f68319 241
AnnaBridge 187:0387e8f68319 242 int spi_busy(spi_t *obj)
AnnaBridge 187:0387e8f68319 243 {
AnnaBridge 187:0387e8f68319 244 int ret = 1;
AnnaBridge 187:0387e8f68319 245 uint32_t status = 0;
AnnaBridge 187:0387e8f68319 246
AnnaBridge 187:0387e8f68319 247 tspi_get_status(&obj->p_obj, &status);
AnnaBridge 187:0387e8f68319 248
AnnaBridge 187:0387e8f68319 249 if ((status & (TSPI_TX_FLAG_ACTIVE | TSPI_RX_FLAG_ACTIVE)) == 0) {
AnnaBridge 187:0387e8f68319 250 ret = 0;
AnnaBridge 187:0387e8f68319 251 }
AnnaBridge 187:0387e8f68319 252
AnnaBridge 187:0387e8f68319 253 return ret;
AnnaBridge 187:0387e8f68319 254 }
AnnaBridge 187:0387e8f68319 255
AnnaBridge 187:0387e8f68319 256 uint8_t spi_get_module(spi_t *obj)
AnnaBridge 187:0387e8f68319 257 {
AnnaBridge 187:0387e8f68319 258 return (uint8_t)(obj->module);
AnnaBridge 187:0387e8f68319 259 }