Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 17 23:23:45 2019 +0000
Revision:
0:5b88d5760320
Child:
1:9db0e321a9f4
mbed-os5 only for TYBLE16

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:5b88d5760320 1 /* mbed Microcontroller Library
kenjiArai 0:5b88d5760320 2 * Copyright (c) 2006-2015 ARM Limited
kenjiArai 0:5b88d5760320 3 * SPDX-License-Identifier: Apache-2.0
kenjiArai 0:5b88d5760320 4 *
kenjiArai 0:5b88d5760320 5 * Licensed under the Apache License, Version 2.0 (the "License");
kenjiArai 0:5b88d5760320 6 * you may not use this file except in compliance with the License.
kenjiArai 0:5b88d5760320 7 * You may obtain a copy of the License at
kenjiArai 0:5b88d5760320 8 *
kenjiArai 0:5b88d5760320 9 * http://www.apache.org/licenses/LICENSE-2.0
kenjiArai 0:5b88d5760320 10 *
kenjiArai 0:5b88d5760320 11 * Unless required by applicable law or agreed to in writing, software
kenjiArai 0:5b88d5760320 12 * distributed under the License is distributed on an "AS IS" BASIS,
kenjiArai 0:5b88d5760320 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kenjiArai 0:5b88d5760320 14 * See the License for the specific language governing permissions and
kenjiArai 0:5b88d5760320 15 * limitations under the License.
kenjiArai 0:5b88d5760320 16 */
kenjiArai 0:5b88d5760320 17 #ifndef MBED_SPI_H
kenjiArai 0:5b88d5760320 18 #define MBED_SPI_H
kenjiArai 0:5b88d5760320 19
kenjiArai 0:5b88d5760320 20 #include "platform/platform.h"
kenjiArai 0:5b88d5760320 21
kenjiArai 0:5b88d5760320 22 #if DEVICE_SPI || defined(DOXYGEN_ONLY)
kenjiArai 0:5b88d5760320 23
kenjiArai 0:5b88d5760320 24 #include "platform/PlatformMutex.h"
kenjiArai 0:5b88d5760320 25 #include "hal/spi_api.h"
kenjiArai 0:5b88d5760320 26 #include "drivers/DigitalOut.h"
kenjiArai 0:5b88d5760320 27 #include "platform/SingletonPtr.h"
kenjiArai 0:5b88d5760320 28 #include "platform/NonCopyable.h"
kenjiArai 0:5b88d5760320 29
kenjiArai 0:5b88d5760320 30 #if defined MBED_CONF_DRIVERS_SPI_COUNT_MAX && DEVICE_SPI_COUNT > MBED_CONF_DRIVERS_SPI_COUNT_MAX
kenjiArai 0:5b88d5760320 31 #define SPI_PERIPHERALS_USED MBED_CONF_DRIVERS_SPI_COUNT_MAX
kenjiArai 0:5b88d5760320 32 #elif defined DEVICE_SPI_COUNT
kenjiArai 0:5b88d5760320 33 #define SPI_PERIPHERALS_USED DEVICE_SPI_COUNT
kenjiArai 0:5b88d5760320 34 #else
kenjiArai 0:5b88d5760320 35 /* Backwards compatibility with HALs not providing DEVICE_SPI_COUNT */
kenjiArai 0:5b88d5760320 36 #define SPI_PERIPHERALS_USED 1
kenjiArai 0:5b88d5760320 37 #endif
kenjiArai 0:5b88d5760320 38
kenjiArai 0:5b88d5760320 39 #if DEVICE_SPI_ASYNCH
kenjiArai 0:5b88d5760320 40 #include "platform/CThunk.h"
kenjiArai 0:5b88d5760320 41 #include "hal/dma_api.h"
kenjiArai 0:5b88d5760320 42 #include "platform/CircularBuffer.h"
kenjiArai 0:5b88d5760320 43 #include "platform/FunctionPointer.h"
kenjiArai 0:5b88d5760320 44 #include "platform/Transaction.h"
kenjiArai 0:5b88d5760320 45 #endif
kenjiArai 0:5b88d5760320 46
kenjiArai 0:5b88d5760320 47 namespace mbed {
kenjiArai 0:5b88d5760320 48 /** \addtogroup drivers */
kenjiArai 0:5b88d5760320 49
kenjiArai 0:5b88d5760320 50 struct use_gpio_ssel_t { };
kenjiArai 0:5b88d5760320 51 const use_gpio_ssel_t use_gpio_ssel;
kenjiArai 0:5b88d5760320 52
kenjiArai 0:5b88d5760320 53 /** A SPI Master, used for communicating with SPI slave devices.
kenjiArai 0:5b88d5760320 54 *
kenjiArai 0:5b88d5760320 55 * The default format is set to 8-bits, mode 0, and a clock frequency of 1MHz.
kenjiArai 0:5b88d5760320 56 *
kenjiArai 0:5b88d5760320 57 * Most SPI devices will also require Chip Select and Reset signals. These
kenjiArai 0:5b88d5760320 58 * can be controlled using DigitalOut pins.
kenjiArai 0:5b88d5760320 59 *
kenjiArai 0:5b88d5760320 60 * @note Synchronization level: Thread safe
kenjiArai 0:5b88d5760320 61 *
kenjiArai 0:5b88d5760320 62 * Example of how to send a byte to a SPI slave and record the response:
kenjiArai 0:5b88d5760320 63 * @code
kenjiArai 0:5b88d5760320 64 * #include "mbed.h"
kenjiArai 0:5b88d5760320 65 *
kenjiArai 0:5b88d5760320 66 * SPI device(SPI_MOSI, SPI_MISO, SPI_SCLK)
kenjiArai 0:5b88d5760320 67 *
kenjiArai 0:5b88d5760320 68 * DigitalOut chip_select(SPI_CS);
kenjiArai 0:5b88d5760320 69 *
kenjiArai 0:5b88d5760320 70 * int main() {
kenjiArai 0:5b88d5760320 71 * device.lock();
kenjiArai 0:5b88d5760320 72 * chip_select = 0;
kenjiArai 0:5b88d5760320 73 *
kenjiArai 0:5b88d5760320 74 * int response = device.write(0xFF);
kenjiArai 0:5b88d5760320 75 *
kenjiArai 0:5b88d5760320 76 * chip_select = 1;
kenjiArai 0:5b88d5760320 77 * device.unlock();
kenjiArai 0:5b88d5760320 78 * }
kenjiArai 0:5b88d5760320 79 * @endcode
kenjiArai 0:5b88d5760320 80 *
kenjiArai 0:5b88d5760320 81 * Example using hardware Chip Select line:
kenjiArai 0:5b88d5760320 82 * @code
kenjiArai 0:5b88d5760320 83 * #include "mbed.h"
kenjiArai 0:5b88d5760320 84 *
kenjiArai 0:5b88d5760320 85 * SPI device(SPI_MOSI, SPI_MISO, SPI_SCLK, SPI_CS)
kenjiArai 0:5b88d5760320 86 *
kenjiArai 0:5b88d5760320 87 * int main() {
kenjiArai 0:5b88d5760320 88 * device.lock();
kenjiArai 0:5b88d5760320 89 * int response = device.write(0xFF);
kenjiArai 0:5b88d5760320 90 * device.unlock();
kenjiArai 0:5b88d5760320 91 * }
kenjiArai 0:5b88d5760320 92 * @endcode
kenjiArai 0:5b88d5760320 93 * @ingroup drivers
kenjiArai 0:5b88d5760320 94 */
kenjiArai 0:5b88d5760320 95 class SPI : private NonCopyable<SPI> {
kenjiArai 0:5b88d5760320 96
kenjiArai 0:5b88d5760320 97 public:
kenjiArai 0:5b88d5760320 98
kenjiArai 0:5b88d5760320 99 /** Create a SPI master connected to the specified pins.
kenjiArai 0:5b88d5760320 100 *
kenjiArai 0:5b88d5760320 101 * @note This constructor passes the SSEL pin selection to the target HAL.
kenjiArai 0:5b88d5760320 102 * Not all targets support SSEL, so this cannot be relied on in portable code.
kenjiArai 0:5b88d5760320 103 * Portable code should use the alternative constructor that uses GPIO
kenjiArai 0:5b88d5760320 104 * for SSEL.
kenjiArai 0:5b88d5760320 105 *
kenjiArai 0:5b88d5760320 106 * @note You can specify mosi or miso as NC if not used.
kenjiArai 0:5b88d5760320 107 *
kenjiArai 0:5b88d5760320 108 * @param mosi SPI Master Out, Slave In pin.
kenjiArai 0:5b88d5760320 109 * @param miso SPI Master In, Slave Out pin.
kenjiArai 0:5b88d5760320 110 * @param sclk SPI Clock pin.
kenjiArai 0:5b88d5760320 111 * @param ssel SPI Chip Select pin.
kenjiArai 0:5b88d5760320 112 */
kenjiArai 0:5b88d5760320 113 SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel = NC);
kenjiArai 0:5b88d5760320 114
kenjiArai 0:5b88d5760320 115 /** Create a SPI master connected to the specified pins.
kenjiArai 0:5b88d5760320 116 *
kenjiArai 0:5b88d5760320 117 * @note This constructor manipulates the SSEL pin as a GPIO output
kenjiArai 0:5b88d5760320 118 * using a DigitalOut object. This should work on any target, and permits
kenjiArai 0:5b88d5760320 119 * the use of select() and deselect() methods to keep the pin asserted
kenjiArai 0:5b88d5760320 120 * between transfers.
kenjiArai 0:5b88d5760320 121 *
kenjiArai 0:5b88d5760320 122 * @note You can specify mosi or miso as NC if not used.
kenjiArai 0:5b88d5760320 123 *
kenjiArai 0:5b88d5760320 124 * @param mosi SPI Master Out, Slave In pin.
kenjiArai 0:5b88d5760320 125 * @param miso SPI Master In, Slave Out pin.
kenjiArai 0:5b88d5760320 126 * @param sclk SPI Clock pin.
kenjiArai 0:5b88d5760320 127 * @param ssel SPI Chip Select pin.
kenjiArai 0:5b88d5760320 128 */
kenjiArai 0:5b88d5760320 129 SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel, use_gpio_ssel_t);
kenjiArai 0:5b88d5760320 130
kenjiArai 0:5b88d5760320 131 virtual ~SPI();
kenjiArai 0:5b88d5760320 132
kenjiArai 0:5b88d5760320 133 /** Configure the data transmission format.
kenjiArai 0:5b88d5760320 134 *
kenjiArai 0:5b88d5760320 135 * @param bits Number of bits per SPI frame (4 - 16).
kenjiArai 0:5b88d5760320 136 * @param mode Clock polarity and phase mode (0 - 3).
kenjiArai 0:5b88d5760320 137 *
kenjiArai 0:5b88d5760320 138 * @code
kenjiArai 0:5b88d5760320 139 * mode | POL PHA
kenjiArai 0:5b88d5760320 140 * -----+--------
kenjiArai 0:5b88d5760320 141 * 0 | 0 0
kenjiArai 0:5b88d5760320 142 * 1 | 0 1
kenjiArai 0:5b88d5760320 143 * 2 | 1 0
kenjiArai 0:5b88d5760320 144 * 3 | 1 1
kenjiArai 0:5b88d5760320 145 * @endcode
kenjiArai 0:5b88d5760320 146 */
kenjiArai 0:5b88d5760320 147 void format(int bits, int mode = 0);
kenjiArai 0:5b88d5760320 148
kenjiArai 0:5b88d5760320 149 /** Set the SPI bus clock frequency.
kenjiArai 0:5b88d5760320 150 *
kenjiArai 0:5b88d5760320 151 * @param hz Clock frequency in Hz (default = 1MHz).
kenjiArai 0:5b88d5760320 152 */
kenjiArai 0:5b88d5760320 153 void frequency(int hz = 1000000);
kenjiArai 0:5b88d5760320 154
kenjiArai 0:5b88d5760320 155 /** Write to the SPI Slave and return the response.
kenjiArai 0:5b88d5760320 156 *
kenjiArai 0:5b88d5760320 157 * @param value Data to be sent to the SPI slave.
kenjiArai 0:5b88d5760320 158 *
kenjiArai 0:5b88d5760320 159 * @return Response from the SPI slave.
kenjiArai 0:5b88d5760320 160 */
kenjiArai 0:5b88d5760320 161 virtual int write(int value);
kenjiArai 0:5b88d5760320 162
kenjiArai 0:5b88d5760320 163 /** Write to the SPI Slave and obtain the response.
kenjiArai 0:5b88d5760320 164 *
kenjiArai 0:5b88d5760320 165 * The total number of bytes sent and received will be the maximum of
kenjiArai 0:5b88d5760320 166 * tx_length and rx_length. The bytes written will be padded with the
kenjiArai 0:5b88d5760320 167 * value 0xff.
kenjiArai 0:5b88d5760320 168 *
kenjiArai 0:5b88d5760320 169 * @param tx_buffer Pointer to the byte-array of data to write to the device.
kenjiArai 0:5b88d5760320 170 * @param tx_length Number of bytes to write, may be zero.
kenjiArai 0:5b88d5760320 171 * @param rx_buffer Pointer to the byte-array of data to read from the device.
kenjiArai 0:5b88d5760320 172 * @param rx_length Number of bytes to read, may be zero.
kenjiArai 0:5b88d5760320 173 * @return
kenjiArai 0:5b88d5760320 174 * The number of bytes written and read from the device. This is
kenjiArai 0:5b88d5760320 175 * maximum of tx_length and rx_length.
kenjiArai 0:5b88d5760320 176 */
kenjiArai 0:5b88d5760320 177 virtual int write(const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length);
kenjiArai 0:5b88d5760320 178
kenjiArai 0:5b88d5760320 179 /** Acquire exclusive access to this SPI bus.
kenjiArai 0:5b88d5760320 180 */
kenjiArai 0:5b88d5760320 181 virtual void lock(void);
kenjiArai 0:5b88d5760320 182
kenjiArai 0:5b88d5760320 183 /** Release exclusive access to this SPI bus.
kenjiArai 0:5b88d5760320 184 */
kenjiArai 0:5b88d5760320 185 virtual void unlock(void);
kenjiArai 0:5b88d5760320 186
kenjiArai 0:5b88d5760320 187 /** Assert the Slave Select line, acquiring exclusive access to this SPI bus.
kenjiArai 0:5b88d5760320 188 *
kenjiArai 0:5b88d5760320 189 * If use_gpio_ssel was not passed to the constructor, this only acquires
kenjiArai 0:5b88d5760320 190 * exclusive access; it cannot assert the Slave Select line.
kenjiArai 0:5b88d5760320 191 */
kenjiArai 0:5b88d5760320 192 void select(void);
kenjiArai 0:5b88d5760320 193
kenjiArai 0:5b88d5760320 194 /** Deassert the Slave Select line, releasing exclusive access to this SPI bus.
kenjiArai 0:5b88d5760320 195 */
kenjiArai 0:5b88d5760320 196 void deselect(void);
kenjiArai 0:5b88d5760320 197
kenjiArai 0:5b88d5760320 198 /** Set default write data.
kenjiArai 0:5b88d5760320 199 * SPI requires the master to send some data during a read operation.
kenjiArai 0:5b88d5760320 200 * Different devices may require different default byte values.
kenjiArai 0:5b88d5760320 201 * For example: A SD Card requires default bytes to be 0xFF.
kenjiArai 0:5b88d5760320 202 *
kenjiArai 0:5b88d5760320 203 * @param data Default character to be transmitted during a read operation.
kenjiArai 0:5b88d5760320 204 */
kenjiArai 0:5b88d5760320 205 void set_default_write_value(char data);
kenjiArai 0:5b88d5760320 206
kenjiArai 0:5b88d5760320 207 #if DEVICE_SPI_ASYNCH
kenjiArai 0:5b88d5760320 208
kenjiArai 0:5b88d5760320 209 /** Start non-blocking SPI transfer using 8bit buffers.
kenjiArai 0:5b88d5760320 210 *
kenjiArai 0:5b88d5760320 211 * This function locks the deep sleep until any event has occurred.
kenjiArai 0:5b88d5760320 212 *
kenjiArai 0:5b88d5760320 213 * @param tx_buffer The TX buffer with data to be transferred. If NULL is passed,
kenjiArai 0:5b88d5760320 214 * the default SPI value is sent.
kenjiArai 0:5b88d5760320 215 * @param tx_length The length of TX buffer in bytes.
kenjiArai 0:5b88d5760320 216 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
kenjiArai 0:5b88d5760320 217 * received data are ignored.
kenjiArai 0:5b88d5760320 218 * @param rx_length The length of RX buffer in bytes.
kenjiArai 0:5b88d5760320 219 * @param callback The event callback function.
kenjiArai 0:5b88d5760320 220 * @param event The event mask of events to modify. @see spi_api.h for SPI events.
kenjiArai 0:5b88d5760320 221 *
kenjiArai 0:5b88d5760320 222 * @return Operation result.
kenjiArai 0:5b88d5760320 223 * @retval 0 If the transfer has started.
kenjiArai 0:5b88d5760320 224 * @retval -1 If SPI peripheral is busy.
kenjiArai 0:5b88d5760320 225 */
kenjiArai 0:5b88d5760320 226 template<typename Type>
kenjiArai 0:5b88d5760320 227 int transfer(const Type *tx_buffer, int tx_length, Type *rx_buffer, int rx_length, const event_callback_t &callback, int event = SPI_EVENT_COMPLETE)
kenjiArai 0:5b88d5760320 228 {
kenjiArai 0:5b88d5760320 229 if (spi_active(&_peripheral->spi)) {
kenjiArai 0:5b88d5760320 230 return queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type) * 8, callback, event);
kenjiArai 0:5b88d5760320 231 }
kenjiArai 0:5b88d5760320 232 start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type) * 8, callback, event);
kenjiArai 0:5b88d5760320 233 return 0;
kenjiArai 0:5b88d5760320 234 }
kenjiArai 0:5b88d5760320 235
kenjiArai 0:5b88d5760320 236 /** Abort the on-going SPI transfer, and continue with transfers in the queue, if any.
kenjiArai 0:5b88d5760320 237 */
kenjiArai 0:5b88d5760320 238 void abort_transfer();
kenjiArai 0:5b88d5760320 239
kenjiArai 0:5b88d5760320 240 /** Clear the queue of transfers.
kenjiArai 0:5b88d5760320 241 */
kenjiArai 0:5b88d5760320 242 void clear_transfer_buffer();
kenjiArai 0:5b88d5760320 243
kenjiArai 0:5b88d5760320 244 /** Clear the queue of transfers and abort the on-going transfer.
kenjiArai 0:5b88d5760320 245 */
kenjiArai 0:5b88d5760320 246 void abort_all_transfers();
kenjiArai 0:5b88d5760320 247
kenjiArai 0:5b88d5760320 248 /** Configure DMA usage suggestion for non-blocking transfers.
kenjiArai 0:5b88d5760320 249 *
kenjiArai 0:5b88d5760320 250 * @param usage The usage DMA hint for peripheral.
kenjiArai 0:5b88d5760320 251 *
kenjiArai 0:5b88d5760320 252 * @return Result of the operation.
kenjiArai 0:5b88d5760320 253 * @retval 0 The usage was set.
kenjiArai 0:5b88d5760320 254 * @retval -1 Usage cannot be set as there is an ongoing transaction.
kenjiArai 0:5b88d5760320 255 */
kenjiArai 0:5b88d5760320 256 int set_dma_usage(DMAUsage usage);
kenjiArai 0:5b88d5760320 257
kenjiArai 0:5b88d5760320 258 #if !defined(DOXYGEN_ONLY)
kenjiArai 0:5b88d5760320 259 protected:
kenjiArai 0:5b88d5760320 260
kenjiArai 0:5b88d5760320 261 /** SPI interrupt handler.
kenjiArai 0:5b88d5760320 262 */
kenjiArai 0:5b88d5760320 263 void irq_handler_asynch(void);
kenjiArai 0:5b88d5760320 264
kenjiArai 0:5b88d5760320 265 /** Start the transfer or put it on the queue.
kenjiArai 0:5b88d5760320 266 *
kenjiArai 0:5b88d5760320 267 * @param tx_buffer The TX buffer with data to be transferred. If NULL is passed,
kenjiArai 0:5b88d5760320 268 * the default SPI value is sent
kenjiArai 0:5b88d5760320 269 * @param tx_length The length of TX buffer in bytes.
kenjiArai 0:5b88d5760320 270 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
kenjiArai 0:5b88d5760320 271 * received data are ignored.
kenjiArai 0:5b88d5760320 272 * @param rx_length The length of RX buffer in bytes.
kenjiArai 0:5b88d5760320 273 * @param bit_width The buffers element width in bits.
kenjiArai 0:5b88d5760320 274 * @param callback The event callback function.
kenjiArai 0:5b88d5760320 275 * @param event The event mask of events to modify.
kenjiArai 0:5b88d5760320 276 *
kenjiArai 0:5b88d5760320 277 * @return Operation success.
kenjiArai 0:5b88d5760320 278 * @retval 0 A transfer was started or added to the queue.
kenjiArai 0:5b88d5760320 279 * @retval -1 Transfer can't be added because queue is full.
kenjiArai 0:5b88d5760320 280 */
kenjiArai 0:5b88d5760320 281 int transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t &callback, int event);
kenjiArai 0:5b88d5760320 282
kenjiArai 0:5b88d5760320 283 /** Put a transfer on the transfer queue.
kenjiArai 0:5b88d5760320 284 *
kenjiArai 0:5b88d5760320 285 * @param tx_buffer The TX buffer with data to be transferred. If NULL is passed,
kenjiArai 0:5b88d5760320 286 * the default SPI value is sent.
kenjiArai 0:5b88d5760320 287 * @param tx_length The length of TX buffer in bytes.
kenjiArai 0:5b88d5760320 288 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
kenjiArai 0:5b88d5760320 289 * received data are ignored.
kenjiArai 0:5b88d5760320 290 * @param rx_length The length of RX buffer in bytes.
kenjiArai 0:5b88d5760320 291 * @param bit_width The buffers element width in bits.
kenjiArai 0:5b88d5760320 292 * @param callback The event callback function.
kenjiArai 0:5b88d5760320 293 * @param event The event mask of events to modify.
kenjiArai 0:5b88d5760320 294 *
kenjiArai 0:5b88d5760320 295 * @return Operation success.
kenjiArai 0:5b88d5760320 296 * @retval 0 A transfer was added to the queue.
kenjiArai 0:5b88d5760320 297 * @retval -1 Transfer can't be added because queue is full.
kenjiArai 0:5b88d5760320 298 */
kenjiArai 0:5b88d5760320 299 int queue_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t &callback, int event);
kenjiArai 0:5b88d5760320 300
kenjiArai 0:5b88d5760320 301 /** Configure a callback, SPI peripheral, and initiate a new transfer.
kenjiArai 0:5b88d5760320 302 *
kenjiArai 0:5b88d5760320 303 * @param tx_buffer The TX buffer with data to be transferred. If NULL is passed,
kenjiArai 0:5b88d5760320 304 * the default SPI value is sent.
kenjiArai 0:5b88d5760320 305 * @param tx_length The length of TX buffer in bytes.
kenjiArai 0:5b88d5760320 306 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
kenjiArai 0:5b88d5760320 307 * received data are ignored.
kenjiArai 0:5b88d5760320 308 * @param rx_length The length of RX buffer in bytes.
kenjiArai 0:5b88d5760320 309 * @param bit_width The buffers element width.
kenjiArai 0:5b88d5760320 310 * @param callback The event callback function.
kenjiArai 0:5b88d5760320 311 * @param event The event mask of events to modify.
kenjiArai 0:5b88d5760320 312 */
kenjiArai 0:5b88d5760320 313 void start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t &callback, int event);
kenjiArai 0:5b88d5760320 314
kenjiArai 0:5b88d5760320 315 private:
kenjiArai 0:5b88d5760320 316 /** Lock deep sleep only if it is not yet locked */
kenjiArai 0:5b88d5760320 317 void lock_deep_sleep();
kenjiArai 0:5b88d5760320 318
kenjiArai 0:5b88d5760320 319 /** Unlock deep sleep in case it is locked */
kenjiArai 0:5b88d5760320 320 void unlock_deep_sleep();
kenjiArai 0:5b88d5760320 321
kenjiArai 0:5b88d5760320 322
kenjiArai 0:5b88d5760320 323 #if TRANSACTION_QUEUE_SIZE_SPI
kenjiArai 0:5b88d5760320 324 /** Start a new transaction.
kenjiArai 0:5b88d5760320 325 *
kenjiArai 0:5b88d5760320 326 * @param data Transaction data.
kenjiArai 0:5b88d5760320 327 */
kenjiArai 0:5b88d5760320 328 void start_transaction(transaction_t *data);
kenjiArai 0:5b88d5760320 329
kenjiArai 0:5b88d5760320 330 /** Dequeue a transaction and start the transfer if there was one pending.
kenjiArai 0:5b88d5760320 331 */
kenjiArai 0:5b88d5760320 332 void dequeue_transaction();
kenjiArai 0:5b88d5760320 333
kenjiArai 0:5b88d5760320 334 #endif // TRANSACTION_QUEUE_SIZE_SPI
kenjiArai 0:5b88d5760320 335 #endif // !defined(DOXYGEN_ONLY)
kenjiArai 0:5b88d5760320 336 #endif // DEVICE_SPI_ASYNCH
kenjiArai 0:5b88d5760320 337
kenjiArai 0:5b88d5760320 338 #if !defined(DOXYGEN_ONLY)
kenjiArai 0:5b88d5760320 339 protected:
kenjiArai 0:5b88d5760320 340 #ifdef DEVICE_SPI_COUNT
kenjiArai 0:5b88d5760320 341 // HAL must have defined this as a global enum
kenjiArai 0:5b88d5760320 342 typedef ::SPIName SPIName;
kenjiArai 0:5b88d5760320 343 #else
kenjiArai 0:5b88d5760320 344 // HAL may or may not have defined it - use a local definition
kenjiArai 0:5b88d5760320 345 enum SPIName { GlobalSPI };
kenjiArai 0:5b88d5760320 346 #endif
kenjiArai 0:5b88d5760320 347
kenjiArai 0:5b88d5760320 348 struct spi_peripheral_s {
kenjiArai 0:5b88d5760320 349 /* Internal SPI name identifying the resources. */
kenjiArai 0:5b88d5760320 350 SPIName name;
kenjiArai 0:5b88d5760320 351 /* Internal SPI object handling the resources' state. */
kenjiArai 0:5b88d5760320 352 spi_t spi;
kenjiArai 0:5b88d5760320 353 /* Used by lock and unlock for thread safety */
kenjiArai 0:5b88d5760320 354 SingletonPtr<PlatformMutex> mutex;
kenjiArai 0:5b88d5760320 355 /* Current user of the SPI */
kenjiArai 0:5b88d5760320 356 SPI *owner;
kenjiArai 0:5b88d5760320 357 #if DEVICE_SPI_ASYNCH && TRANSACTION_QUEUE_SIZE_SPI
kenjiArai 0:5b88d5760320 358 /* Queue of pending transfers */
kenjiArai 0:5b88d5760320 359 SingletonPtr<CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> > transaction_buffer;
kenjiArai 0:5b88d5760320 360 #endif
kenjiArai 0:5b88d5760320 361 };
kenjiArai 0:5b88d5760320 362
kenjiArai 0:5b88d5760320 363 // holds spi_peripheral_s per peripheral on the device.
kenjiArai 0:5b88d5760320 364 // Drawback: it costs ram size even if the device is not used, however
kenjiArai 0:5b88d5760320 365 // application can limit the allocation via JSON.
kenjiArai 0:5b88d5760320 366 static spi_peripheral_s _peripherals[SPI_PERIPHERALS_USED];
kenjiArai 0:5b88d5760320 367 static int _peripherals_used;
kenjiArai 0:5b88d5760320 368
kenjiArai 0:5b88d5760320 369 // Holds the reference to the associated peripheral.
kenjiArai 0:5b88d5760320 370 spi_peripheral_s *_peripheral;
kenjiArai 0:5b88d5760320 371
kenjiArai 0:5b88d5760320 372 #if DEVICE_SPI_ASYNCH
kenjiArai 0:5b88d5760320 373 /* Interrupt */
kenjiArai 0:5b88d5760320 374 CThunk<SPI> _irq;
kenjiArai 0:5b88d5760320 375 /* Interrupt handler callback */
kenjiArai 0:5b88d5760320 376 event_callback_t _callback;
kenjiArai 0:5b88d5760320 377 /* Current preferred DMA mode @see dma_api.h */
kenjiArai 0:5b88d5760320 378 DMAUsage _usage;
kenjiArai 0:5b88d5760320 379 /* Current sate of the sleep manager */
kenjiArai 0:5b88d5760320 380 bool _deep_sleep_locked;
kenjiArai 0:5b88d5760320 381 #endif // DEVICE_SPI_ASYNCH
kenjiArai 0:5b88d5760320 382
kenjiArai 0:5b88d5760320 383 // Configuration.
kenjiArai 0:5b88d5760320 384 PinName _mosi;
kenjiArai 0:5b88d5760320 385 PinName _miso;
kenjiArai 0:5b88d5760320 386 PinName _sclk;
kenjiArai 0:5b88d5760320 387 PinName _hw_ssel;
kenjiArai 0:5b88d5760320 388
kenjiArai 0:5b88d5760320 389 // The Slave Select GPIO if we're doing it ourselves.
kenjiArai 0:5b88d5760320 390 DigitalOut _sw_ssel;
kenjiArai 0:5b88d5760320 391
kenjiArai 0:5b88d5760320 392 /* Size of the SPI frame */
kenjiArai 0:5b88d5760320 393 int _bits;
kenjiArai 0:5b88d5760320 394 /* Clock polairy and phase */
kenjiArai 0:5b88d5760320 395 int _mode;
kenjiArai 0:5b88d5760320 396 /* Clock frequency */
kenjiArai 0:5b88d5760320 397 int _hz;
kenjiArai 0:5b88d5760320 398 /* Default character used for NULL transfers */
kenjiArai 0:5b88d5760320 399 char _write_fill;
kenjiArai 0:5b88d5760320 400 /* Select count to handle re-entrant selection */
kenjiArai 0:5b88d5760320 401 int8_t _select_count;
kenjiArai 0:5b88d5760320 402
kenjiArai 0:5b88d5760320 403 private:
kenjiArai 0:5b88d5760320 404 void _do_construct();
kenjiArai 0:5b88d5760320 405
kenjiArai 0:5b88d5760320 406 /** Private acquire function without locking/unlocking.
kenjiArai 0:5b88d5760320 407 * Implemented in order to avoid duplicate locking and boost performance.
kenjiArai 0:5b88d5760320 408 */
kenjiArai 0:5b88d5760320 409 void _acquire(void);
kenjiArai 0:5b88d5760320 410 void _set_ssel(int);
kenjiArai 0:5b88d5760320 411
kenjiArai 0:5b88d5760320 412 /** Private lookup in the static _peripherals table.
kenjiArai 0:5b88d5760320 413 */
kenjiArai 0:5b88d5760320 414 static spi_peripheral_s *_lookup(SPIName name);
kenjiArai 0:5b88d5760320 415 /** Allocate an entry in the static _peripherals table.
kenjiArai 0:5b88d5760320 416 */
kenjiArai 0:5b88d5760320 417 static spi_peripheral_s *_alloc();
kenjiArai 0:5b88d5760320 418
kenjiArai 0:5b88d5760320 419 #endif //!defined(DOXYGEN_ONLY)
kenjiArai 0:5b88d5760320 420 };
kenjiArai 0:5b88d5760320 421
kenjiArai 0:5b88d5760320 422 } // namespace mbed
kenjiArai 0:5b88d5760320 423
kenjiArai 0:5b88d5760320 424 #endif // DEVICE_SPI || DOXYGEN_ONLY
kenjiArai 0:5b88d5760320 425
kenjiArai 0:5b88d5760320 426 #endif // MBED_SPI_H