Naze32 clone with Frysky receiver
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SPI.h 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /* mbed Microcontroller Library
  2. * Copyright (c) 2006-2015 ARM Limited
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef MBED_SPI_H
  17. #define MBED_SPI_H
  18. #include "platform.h"
  19. #if DEVICE_SPI
  20. #include "spi_api.h"
  21. #if DEVICE_SPI_ASYNCH
  22. #include "CThunk.h"
  23. #include "dma_api.h"
  24. #include "CircularBuffer.h"
  25. #include "FunctionPointer.h"
  26. #include "Transaction.h"
  27. #endif
  28. namespace mbed {
  29. /** A SPI Master, used for communicating with SPI slave devices
  30. *
  31. * The default format is set to 8-bits, mode 0, and a clock frequency of 1MHz
  32. *
  33. * Most SPI devices will also require Chip Select and Reset signals. These
  34. * can be controlled using <DigitalOut> pins
  35. *
  36. * Example:
  37. * @code
  38. * // Send a byte to a SPI slave, and record the response
  39. *
  40. * #include "mbed.h"
  41. *
  42. * // hardware ssel (where applicable)
  43. * //SPI device(p5, p6, p7, p8); // mosi, miso, sclk, ssel
  44. *
  45. * // software ssel
  46. * SPI device(p5, p6, p7); // mosi, miso, sclk
  47. * DigitalOut cs(p8); // ssel
  48. *
  49. * int main() {
  50. * // hardware ssel (where applicable)
  51. * //int response = device.write(0xFF);
  52. *
  53. * // software ssel
  54. * cs = 0;
  55. * int response = device.write(0xFF);
  56. * cs = 1;
  57. * }
  58. * @endcode
  59. */
  60. class SPI {
  61. public:
  62. /** Create a SPI master connected to the specified pins
  63. *
  64. * mosi or miso can be specfied as NC if not used
  65. *
  66. * @param mosi SPI Master Out, Slave In pin
  67. * @param miso SPI Master In, Slave Out pin
  68. * @param sclk SPI Clock pin
  69. * @param ssel SPI chip select pin
  70. */
  71. SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel=NC);
  72. /** Configure the data transmission format
  73. *
  74. * @param bits Number of bits per SPI frame (4 - 16)
  75. * @param mode Clock polarity and phase mode (0 - 3)
  76. *
  77. * @code
  78. * mode | POL PHA
  79. * -----+--------
  80. * 0 | 0 0
  81. * 1 | 0 1
  82. * 2 | 1 0
  83. * 3 | 1 1
  84. * @endcode
  85. */
  86. void format(int bits, int mode = 0);
  87. /** Set the spi bus clock frequency
  88. *
  89. * @param hz SCLK frequency in hz (default = 1MHz)
  90. */
  91. void frequency(int hz = 1000000);
  92. /** Write to the SPI Slave and return the response
  93. *
  94. * @param value Data to be sent to the SPI slave
  95. *
  96. * @returns
  97. * Response from the SPI slave
  98. */
  99. virtual int write(int value);
  100. #if DEVICE_SPI_ASYNCH
  101. /** Start non-blocking SPI transfer using 8bit buffers.
  102. *
  103. * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
  104. * the default SPI value is sent
  105. * @param tx_length The length of TX buffer in bytes
  106. * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
  107. * received data are ignored
  108. * @param rx_length The length of RX buffer in bytes
  109. * @param callback The event callback function
  110. * @param event The logical OR of events to modify. Look at spi hal header file for SPI events.
  111. * @return Zero if the transfer has started, or -1 if SPI peripheral is busy
  112. */
  113. template<typename Type>
  114. 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) {
  115. if (spi_active(&_spi)) {
  116. return queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event);
  117. }
  118. start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event);
  119. return 0;
  120. }
  121. /** Abort the on-going SPI transfer, and continue with transfer's in the queue if any.
  122. */
  123. void abort_transfer();
  124. /** Clear the transaction buffer
  125. */
  126. void clear_transfer_buffer();
  127. /** Clear the transaction buffer and abort on-going transfer.
  128. */
  129. void abort_all_transfers();
  130. /** Configure DMA usage suggestion for non-blocking transfers
  131. *
  132. * @param usage The usage DMA hint for peripheral
  133. * @return Zero if the usage was set, -1 if a transaction is on-going
  134. */
  135. int set_dma_usage(DMAUsage usage);
  136. protected:
  137. /** SPI IRQ handler
  138. *
  139. */
  140. void irq_handler_asynch(void);
  141. /** Common transfer method
  142. *
  143. * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
  144. * the default SPI value is sent
  145. * @param tx_length The length of TX buffer in bytes
  146. * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
  147. * received data are ignored
  148. * @param rx_length The length of RX buffer in bytes
  149. * @param bit_width The buffers element width
  150. * @param callback The event callback function
  151. * @param event The logical OR of events to modify
  152. * @return Zero if the transfer has started or was added to the queue, or -1 if SPI peripheral is busy/buffer is full
  153. */
  154. 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);
  155. /**
  156. *
  157. * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
  158. * the default SPI value is sent
  159. * @param tx_length The length of TX buffer in bytes
  160. * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
  161. * received data are ignored
  162. * @param rx_length The length of RX buffer in bytes
  163. * @param bit_width The buffers element width
  164. * @param callback The event callback function
  165. * @param event The logical OR of events to modify
  166. * @return Zero if a transfer was added to the queue, or -1 if the queue is full
  167. */
  168. 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);
  169. /** Configures a callback, spi peripheral and initiate a new transfer
  170. *
  171. * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
  172. * the default SPI value is sent
  173. * @param tx_length The length of TX buffer in bytes
  174. * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
  175. * received data are ignored
  176. * @param rx_length The length of RX buffer in bytes
  177. * @param bit_width The buffers element width
  178. * @param callback The event callback function
  179. * @param event The logical OR of events to modify
  180. */
  181. 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);
  182. #if TRANSACTION_QUEUE_SIZE_SPI
  183. /** Start a new transaction
  184. *
  185. * @param data Transaction data
  186. */
  187. void start_transaction(transaction_t *data);
  188. /** Dequeue a transaction
  189. *
  190. */
  191. void dequeue_transaction();
  192. static CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> _transaction_buffer;
  193. #endif
  194. #endif
  195. public:
  196. virtual ~SPI() {
  197. }
  198. protected:
  199. spi_t _spi;
  200. #if DEVICE_SPI_ASYNCH
  201. CThunk<SPI> _irq;
  202. event_callback_t _callback;
  203. DMAUsage _usage;
  204. #endif
  205. void aquire(void);
  206. static SPI *_owner;
  207. int _bits;
  208. int _mode;
  209. int _hz;
  210. };
  211. } // namespace mbed
  212. #endif
  213. #endif