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.

HAL_SPI.cpp 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. * Copyright (c) 2017 Victor Perez
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  21. *
  22. */
  23. #include "../platforms.h"
  24. #ifdef HAL_STM32
  25. #include "../../inc/MarlinConfig.h"
  26. #include <SPI.h>
  27. // ------------------------
  28. // Public Variables
  29. // ------------------------
  30. static SPISettings spiConfig;
  31. // ------------------------
  32. // Public functions
  33. // ------------------------
  34. #if ENABLED(SOFTWARE_SPI)
  35. // ------------------------
  36. // Software SPI
  37. // ------------------------
  38. #include "../shared/Delay.h"
  39. void spiBegin(void) {
  40. #if PIN_EXISTS(SD_SS)
  41. OUT_WRITE(SD_SS_PIN, HIGH);
  42. #endif
  43. OUT_WRITE(SD_SCK_PIN, HIGH);
  44. SET_INPUT(SD_MISO_PIN);
  45. OUT_WRITE(SD_MOSI_PIN, HIGH);
  46. }
  47. // Use function with compile-time value so we can actually reach the desired frequency
  48. // Need to adjust this a little bit: on a 72MHz clock, we have 14ns/clock
  49. // and we'll use ~3 cycles to jump to the method and going back, so it'll take ~40ns from the given clock here
  50. #define CALLING_COST_NS (3U * 1000000000U) / (F_CPU)
  51. void (*delaySPIFunc)();
  52. void delaySPI_125() { DELAY_NS(125 - CALLING_COST_NS); }
  53. void delaySPI_250() { DELAY_NS(250 - CALLING_COST_NS); }
  54. void delaySPI_500() { DELAY_NS(500 - CALLING_COST_NS); }
  55. void delaySPI_1000() { DELAY_NS(1000 - CALLING_COST_NS); }
  56. void delaySPI_2000() { DELAY_NS(2000 - CALLING_COST_NS); }
  57. void delaySPI_4000() { DELAY_NS(4000 - CALLING_COST_NS); }
  58. void spiInit(uint8_t spiRate) {
  59. // Use datarates Marlin uses
  60. switch (spiRate) {
  61. case SPI_FULL_SPEED: delaySPIFunc = &delaySPI_125; break; // desired: 8,000,000 actual: ~1.1M
  62. case SPI_HALF_SPEED: delaySPIFunc = &delaySPI_125; break; // desired: 4,000,000 actual: ~1.1M
  63. case SPI_QUARTER_SPEED:delaySPIFunc = &delaySPI_250; break; // desired: 2,000,000 actual: ~890K
  64. case SPI_EIGHTH_SPEED: delaySPIFunc = &delaySPI_500; break; // desired: 1,000,000 actual: ~590K
  65. case SPI_SPEED_5: delaySPIFunc = &delaySPI_1000; break; // desired: 500,000 actual: ~360K
  66. case SPI_SPEED_6: delaySPIFunc = &delaySPI_2000; break; // desired: 250,000 actual: ~210K
  67. default: delaySPIFunc = &delaySPI_4000; break; // desired: 125,000 actual: ~123K
  68. }
  69. SPI.begin();
  70. }
  71. // Begin SPI transaction, set clock, bit order, data mode
  72. void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { /* do nothing */ }
  73. uint8_t HAL_SPI_STM32_SpiTransfer_Mode_3(uint8_t b) { // using Mode 3
  74. for (uint8_t bits = 8; bits--;) {
  75. WRITE(SD_SCK_PIN, LOW);
  76. WRITE(SD_MOSI_PIN, b & 0x80);
  77. delaySPIFunc();
  78. WRITE(SD_SCK_PIN, HIGH);
  79. delaySPIFunc();
  80. b <<= 1; // little setup time
  81. b |= (READ(SD_MISO_PIN) != 0);
  82. }
  83. DELAY_NS(125);
  84. return b;
  85. }
  86. // Soft SPI receive byte
  87. uint8_t spiRec() {
  88. hal.isr_off(); // No interrupts during byte receive
  89. const uint8_t data = HAL_SPI_STM32_SpiTransfer_Mode_3(0xFF);
  90. hal.isr_on(); // Enable interrupts
  91. return data;
  92. }
  93. // Soft SPI read data
  94. void spiRead(uint8_t *buf, uint16_t nbyte) {
  95. for (uint16_t i = 0; i < nbyte; i++)
  96. buf[i] = spiRec();
  97. }
  98. // Soft SPI send byte
  99. void spiSend(uint8_t data) {
  100. hal.isr_off(); // No interrupts during byte send
  101. HAL_SPI_STM32_SpiTransfer_Mode_3(data); // Don't care what is received
  102. hal.isr_on(); // Enable interrupts
  103. }
  104. // Soft SPI send block
  105. void spiSendBlock(uint8_t token, const uint8_t *buf) {
  106. spiSend(token);
  107. for (uint16_t i = 0; i < 512; i++)
  108. spiSend(buf[i]);
  109. }
  110. #else
  111. // ------------------------
  112. // Hardware SPI
  113. // ------------------------
  114. /**
  115. * VGPV SPI speed start and PCLK2/2, by default 108/2 = 54Mhz
  116. */
  117. /**
  118. * @brief Begin SPI port setup
  119. *
  120. * @return Nothing
  121. *
  122. * @details Only configures SS pin since stm32duino creates and initialize the SPI object
  123. */
  124. void spiBegin() {
  125. #if PIN_EXISTS(SD_SS)
  126. OUT_WRITE(SD_SS_PIN, HIGH);
  127. #endif
  128. }
  129. // Configure SPI for specified SPI speed
  130. void spiInit(uint8_t spiRate) {
  131. // Use datarates Marlin uses
  132. uint32_t clock;
  133. switch (spiRate) {
  134. case SPI_FULL_SPEED: clock = 20000000; break; // 13.9mhz=20000000 6.75mhz=10000000 3.38mhz=5000000 .833mhz=1000000
  135. case SPI_HALF_SPEED: clock = 5000000; break;
  136. case SPI_QUARTER_SPEED: clock = 2500000; break;
  137. case SPI_EIGHTH_SPEED: clock = 1250000; break;
  138. case SPI_SPEED_5: clock = 625000; break;
  139. case SPI_SPEED_6: clock = 300000; break;
  140. default:
  141. clock = 4000000; // Default from the SPI library
  142. }
  143. spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
  144. SPI.setMISO(SD_MISO_PIN);
  145. SPI.setMOSI(SD_MOSI_PIN);
  146. SPI.setSCLK(SD_SCK_PIN);
  147. SPI.begin();
  148. }
  149. /**
  150. * @brief Receives a single byte from the SPI port.
  151. *
  152. * @return Byte received
  153. *
  154. * @details
  155. */
  156. uint8_t spiRec() {
  157. uint8_t returnByte = SPI.transfer(0xFF);
  158. return returnByte;
  159. }
  160. /**
  161. * @brief Receive a number of bytes from the SPI port to a buffer
  162. *
  163. * @param buf Pointer to starting address of buffer to write to.
  164. * @param nbyte Number of bytes to receive.
  165. * @return Nothing
  166. *
  167. * @details Uses DMA
  168. */
  169. void spiRead(uint8_t *buf, uint16_t nbyte) {
  170. if (nbyte == 0) return;
  171. memset(buf, 0xFF, nbyte);
  172. SPI.transfer(buf, nbyte);
  173. }
  174. /**
  175. * @brief Send a single byte on SPI port
  176. *
  177. * @param b Byte to send
  178. *
  179. * @details
  180. */
  181. void spiSend(uint8_t b) {
  182. SPI.transfer(b);
  183. }
  184. /**
  185. * @brief Write token and then write from 512 byte buffer to SPI (for SD card)
  186. *
  187. * @param buf Pointer with buffer start address
  188. * @return Nothing
  189. *
  190. * @details Use DMA
  191. */
  192. void spiSendBlock(uint8_t token, const uint8_t *buf) {
  193. uint8_t rxBuf[512];
  194. SPI.transfer(token);
  195. SPI.transfer((uint8_t*)buf, &rxBuf, 512);
  196. }
  197. #endif // SOFTWARE_SPI
  198. #endif // HAL_STM32