My Marlin configs for Fabrikator Mini and CTC i3 Pro B
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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /******************************************************************************
  2. * The MIT License
  3. *
  4. * Copyright (c) 2010 Perry Hung.
  5. *
  6. * Permission is hereby granted, free of charge, to any person
  7. * obtaining a copy of this software and associated documentation
  8. * files (the "Software"), to deal in the Software without
  9. * restriction, including without limitation the rights to use, copy,
  10. * modify, merge, publish, distribute, sublicense, and/or sell copies
  11. * of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  21. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  22. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24. * SOFTWARE.
  25. *****************************************************************************/
  26. #pragma once
  27. #include <libmaple/libmaple_types.h>
  28. #include <libmaple/spi.h>
  29. #include <libmaple/dma.h>
  30. #include <boards.h>
  31. #include <stdint.h>
  32. #include <wirish.h>
  33. // SPI_HAS_TRANSACTION means SPI has
  34. // - beginTransaction()
  35. // - endTransaction()
  36. // - usingInterrupt()
  37. // - SPISetting(clock, bitOrder, dataMode)
  38. //#define SPI_HAS_TRANSACTION
  39. #define SPI_CLOCK_DIV2 SPI_BAUD_PCLK_DIV_2
  40. #define SPI_CLOCK_DIV4 SPI_BAUD_PCLK_DIV_4
  41. #define SPI_CLOCK_DIV8 SPI_BAUD_PCLK_DIV_8
  42. #define SPI_CLOCK_DIV16 SPI_BAUD_PCLK_DIV_16
  43. #define SPI_CLOCK_DIV32 SPI_BAUD_PCLK_DIV_32
  44. #define SPI_CLOCK_DIV64 SPI_BAUD_PCLK_DIV_64
  45. #define SPI_CLOCK_DIV128 SPI_BAUD_PCLK_DIV_128
  46. #define SPI_CLOCK_DIV256 SPI_BAUD_PCLK_DIV_256
  47. /*
  48. * Roger Clark. 20150106
  49. * Commented out redundant AVR defined
  50. *
  51. #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR
  52. #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
  53. #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
  54. // define SPI_AVR_EIMSK for AVR boards with external interrupt pins
  55. #ifdef EIMSK
  56. #define SPI_AVR_EIMSK EIMSK
  57. #elif defined(GICR)
  58. #define SPI_AVR_EIMSK GICR
  59. #elif defined(GIMSK)
  60. #define SPI_AVR_EIMSK GIMSK
  61. #endif
  62. */
  63. #ifndef STM32_LSBFIRST
  64. #define STM32_LSBFIRST 0
  65. #endif
  66. #ifndef STM32_MSBFIRST
  67. #define STM32_MSBFIRST 1
  68. #endif
  69. // PC13 or PA4
  70. #define BOARD_SPI_DEFAULT_SS PA4
  71. //#define BOARD_SPI_DEFAULT_SS PC13
  72. #define SPI_MODE0 SPI_MODE_0
  73. #define SPI_MODE1 SPI_MODE_1
  74. #define SPI_MODE2 SPI_MODE_2
  75. #define SPI_MODE3 SPI_MODE_3
  76. #define DATA_SIZE_8BIT SPI_CR1_DFF_8_BIT
  77. #define DATA_SIZE_16BIT SPI_CR1_DFF_16_BIT
  78. typedef enum {
  79. SPI_STATE_IDLE,
  80. SPI_STATE_READY,
  81. SPI_STATE_RECEIVE,
  82. SPI_STATE_TRANSMIT,
  83. SPI_STATE_TRANSFER
  84. } spi_mode_t;
  85. class SPISettings {
  86. public:
  87. SPISettings(uint32_t inClock, BitOrder inBitOrder, uint8_t inDataMode) {
  88. if (__builtin_constant_p(inClock))
  89. init_AlwaysInline(inClock, inBitOrder, inDataMode, DATA_SIZE_8BIT);
  90. else
  91. init_MightInline(inClock, inBitOrder, inDataMode, DATA_SIZE_8BIT);
  92. }
  93. SPISettings(uint32_t inClock, BitOrder inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
  94. if (__builtin_constant_p(inClock))
  95. init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize);
  96. else
  97. init_MightInline(inClock, inBitOrder, inDataMode, inDataSize);
  98. }
  99. SPISettings(uint32_t inClock) {
  100. if (__builtin_constant_p(inClock))
  101. init_AlwaysInline(inClock, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
  102. else
  103. init_MightInline(inClock, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
  104. }
  105. SPISettings() {
  106. init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
  107. }
  108. private:
  109. void init_MightInline(uint32_t inClock, BitOrder inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
  110. init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize);
  111. }
  112. void init_AlwaysInline(uint32_t inClock, BitOrder inBitOrder, uint8_t inDataMode, uint32_t inDataSize) __attribute__((__always_inline__)) {
  113. clock = inClock;
  114. bitOrder = inBitOrder;
  115. dataMode = inDataMode;
  116. dataSize = inDataSize;
  117. }
  118. uint32_t clock;
  119. uint32_t dataSize;
  120. uint32_t clockDivider;
  121. BitOrder bitOrder;
  122. uint8_t dataMode;
  123. uint8_t _SSPin;
  124. volatile spi_mode_t state;
  125. spi_dev *spi_d;
  126. dma_channel spiRxDmaChannel, spiTxDmaChannel;
  127. dma_dev* spiDmaDev;
  128. void (*receiveCallback)() = NULL;
  129. void (*transmitCallback)() = NULL;
  130. friend class SPIClass;
  131. };
  132. /*
  133. * Kept for compat.
  134. */
  135. static const uint8_t ff = 0xFF;
  136. /**
  137. * @brief Wirish SPI interface.
  138. *
  139. * This implementation uses software slave management, so the caller
  140. * is responsible for controlling the slave select line.
  141. */
  142. class SPIClass {
  143. public:
  144. /**
  145. * @param spiPortNumber Number of the SPI port to manage.
  146. */
  147. SPIClass(uint32_t spiPortNumber);
  148. /**
  149. * @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0).
  150. */
  151. void begin();
  152. /**
  153. * @brief Turn on a SPI port and set its GPIO pin modes for use as a slave.
  154. *
  155. * SPI port is enabled in full duplex mode, with software slave management.
  156. *
  157. * @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST(big-endian)
  158. * @param mode SPI mode to use
  159. */
  160. void beginSlave(uint32_t bitOrder, uint32_t mode);
  161. /**
  162. * @brief Equivalent to beginSlave(MSBFIRST, 0).
  163. */
  164. void beginSlave();
  165. /**
  166. * @brief Disables the SPI port, but leaves its GPIO pin modes unchanged.
  167. */
  168. void end();
  169. void beginTransaction(SPISettings settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); }
  170. void beginTransaction(uint8_t pin, SPISettings settings);
  171. void endTransaction();
  172. void beginTransactionSlave(SPISettings settings);
  173. void setClockDivider(uint32_t clockDivider);
  174. void setBitOrder(BitOrder bitOrder);
  175. void setDataMode(uint8_t dataMode);
  176. // SPI Configuration methods
  177. void attachInterrupt();
  178. void detachInterrupt();
  179. /* Victor Perez. Added to change datasize from 8 to 16 bit modes on the fly.
  180. * Input parameter should be SPI_CR1_DFF set to 0 or 1 on a 32bit word.
  181. * Requires an added function spi_data_size on STM32F1 / cores / maple / libmaple / spi.c
  182. */
  183. void setDataSize(uint32_t ds);
  184. /* Victor Perez 2017. Added to set and clear callback functions for callback
  185. * on DMA transfer completion.
  186. * onReceive used to set the callback in case of dmaTransfer (tx/rx), once rx is completed
  187. * onTransmit used to set the callback in case of dmaSend (tx only). That function
  188. * will NOT be called in case of TX/RX
  189. */
  190. void onReceive(void(*)());
  191. void onTransmit(void(*)());
  192. /*
  193. * I/O
  194. */
  195. /**
  196. * @brief Return the next unread byte/word.
  197. *
  198. * If there is no unread byte/word waiting, this function will block
  199. * until one is received.
  200. */
  201. uint16_t read();
  202. /**
  203. * @brief Read length bytes, storing them into buffer.
  204. * @param buffer Buffer to store received bytes into.
  205. * @param length Number of bytes to store in buffer. This
  206. * function will block until the desired number of
  207. * bytes have been read.
  208. */
  209. void read(uint8_t *buffer, uint32_t length);
  210. /**
  211. * @brief Transmit one byte/word.
  212. * @param data to transmit.
  213. */
  214. void write(uint16_t data);
  215. void write16(uint16_t data); // write 2 bytes in 8 bit mode (DFF=0)
  216. /**
  217. * @brief Transmit one byte/word a specified number of times.
  218. * @param data to transmit.
  219. */
  220. void write(uint16_t data, uint32_t n);
  221. /**
  222. * @brief Transmit multiple bytes/words.
  223. * @param buffer Bytes/words to transmit.
  224. * @param length Number of bytes/words in buffer to transmit.
  225. */
  226. void write(const void * buffer, uint32_t length);
  227. /**
  228. * @brief Transmit a byte, then return the next unread byte.
  229. *
  230. * This function transmits before receiving.
  231. *
  232. * @param data Byte to transmit.
  233. * @return Next unread byte.
  234. */
  235. uint8_t transfer(uint8_t data) const;
  236. uint16_t transfer16(uint16_t data) const;
  237. /**
  238. * @brief Sets up a DMA Transfer for "length" bytes.
  239. * The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting.
  240. *
  241. * This function transmits and receives to buffers.
  242. *
  243. * @param transmitBuf buffer Bytes to transmit. If passed as 0, it sends FF repeatedly for "length" bytes
  244. * @param receiveBuf buffer Bytes to save received data.
  245. * @param length Number of bytes in buffer to transmit.
  246. */
  247. uint8_t dmaTransfer(const void * transmitBuf, void * receiveBuf, uint16_t length);
  248. void dmaTransferSet(const void *transmitBuf, void *receiveBuf);
  249. uint8_t dmaTransferRepeat(uint16_t length);
  250. /**
  251. * @brief Sets up a DMA Transmit for SPI 8 or 16 bit transfer mode.
  252. * The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting.
  253. *
  254. * This function only transmits and does not care about the RX fifo.
  255. *
  256. * @param data buffer half words to transmit,
  257. * @param length Number of bytes in buffer to transmit.
  258. * @param minc Set to use Memory Increment mode, clear to use Circular mode.
  259. */
  260. uint8_t dmaSend(const void * transmitBuf, uint16_t length, bool minc = 1);
  261. void dmaSendSet(const void * transmitBuf, bool minc);
  262. uint8_t dmaSendRepeat(uint16_t length);
  263. uint8_t dmaSendAsync(const void * transmitBuf, uint16_t length, bool minc = 1);
  264. /*
  265. * Pin accessors
  266. */
  267. /**
  268. * @brief Return the number of the MISO (master in, slave out) pin
  269. */
  270. uint8_t misoPin();
  271. /**
  272. * @brief Return the number of the MOSI (master out, slave in) pin
  273. */
  274. uint8_t mosiPin();
  275. /**
  276. * @brief Return the number of the SCK (serial clock) pin
  277. */
  278. uint8_t sckPin();
  279. /**
  280. * @brief Return the number of the NSS (slave select) pin
  281. */
  282. uint8_t nssPin();
  283. /* Escape hatch */
  284. /**
  285. * @brief Get a pointer to the underlying libmaple spi_dev for
  286. * this HardwareSPI instance.
  287. */
  288. spi_dev* c_dev() { return _currentSetting->spi_d; }
  289. spi_dev* dev() { return _currentSetting->spi_d; }
  290. /**
  291. * @brief Sets the number of the SPI peripheral to be used by
  292. * this HardwareSPI instance.
  293. *
  294. * @param spi_num Number of the SPI port. 1-2 in low density devices
  295. * or 1-3 in high density devices.
  296. */
  297. void setModule(int spi_num) {
  298. _currentSetting = &_settings[spi_num - 1];// SPI channels are called 1 2 and 3 but the array is zero indexed
  299. }
  300. /* -- The following methods are deprecated --------------------------- */
  301. /**
  302. * @brief Deprecated.
  303. *
  304. * Use HardwareSPI::transfer() instead.
  305. *
  306. * @see HardwareSPI::transfer()
  307. */
  308. uint8_t send(uint8_t data);
  309. /**
  310. * @brief Deprecated.
  311. *
  312. * Use HardwareSPI::write() in combination with
  313. * HardwareSPI::read() (or HardwareSPI::transfer()) instead.
  314. *
  315. * @see HardwareSPI::write()
  316. * @see HardwareSPI::read()
  317. * @see HardwareSPI::transfer()
  318. */
  319. uint8_t send(uint8_t *data, uint32_t length);
  320. /**
  321. * @brief Deprecated.
  322. *
  323. * Use HardwareSPI::read() instead.
  324. *
  325. * @see HardwareSPI::read()
  326. */
  327. uint8_t recv();
  328. private:
  329. SPISettings _settings[BOARD_NR_SPI];
  330. SPISettings *_currentSetting;
  331. void updateSettings();
  332. /*
  333. * Functions added for DMA transfers with Callback.
  334. * Experimental.
  335. */
  336. void EventCallback();
  337. #if BOARD_NR_SPI >= 1
  338. static void _spi1EventCallback();
  339. #endif
  340. #if BOARD_NR_SPI >= 2
  341. static void _spi2EventCallback();
  342. #endif
  343. #if BOARD_NR_SPI >= 3
  344. static void _spi3EventCallback();
  345. #endif
  346. /*
  347. spi_dev *spi_d;
  348. uint8_t _SSPin;
  349. uint32_t clockDivider;
  350. uint8_t dataMode;
  351. BitOrder bitOrder;
  352. */
  353. };
  354. /**
  355. * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset.
  356. */
  357. static inline void waitSpiTxEnd(spi_dev *spi_d) {
  358. while (spi_is_tx_empty(spi_d) == 0) { /* nada */ } // wait until TXE=1
  359. while (spi_is_busy(spi_d) != 0) { /* nada */ } // wait until BSY=0
  360. }
  361. extern SPIClass SPI;