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.

fastio.h 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  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. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #pragma once
  23. /**
  24. * Fast I/O Routines for SAM3X8E
  25. * Use direct port manipulation to save scads of processor time.
  26. * Contributed by Triffid_Hunter and modified by Kliment, thinkyhead, Bob-the-Kuhn, et.al.
  27. */
  28. /**
  29. * Description: Fast IO functions for Arduino Due and compatible (SAM3X8E)
  30. *
  31. * For ARDUINO_ARCH_SAM
  32. * Note the code here was specifically crafted by disassembling what GCC produces
  33. * out of it, so GCC is able to optimize it out as much as possible to the least
  34. * amount of instructions. Be very carefull if you modify them, as "clean code"
  35. * leads to less efficient compiled code!!
  36. */
  37. #include <pins_arduino.h>
  38. #include "../../inc/MarlinConfigPre.h"
  39. /**
  40. * Utility functions
  41. */
  42. // Due has 12 PWMs assigned to logical pins 2-13.
  43. // 6, 7, 8 & 9 come from the PWM controller. The others come from the timers.
  44. #define PWM_PIN(P) WITHIN(P, 2, 13)
  45. #ifndef MASK
  46. #define MASK(PIN) (1 << PIN)
  47. #endif
  48. /**
  49. * Magic I/O routines
  50. *
  51. * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW);
  52. *
  53. * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
  54. */
  55. // Read a pin
  56. #define _READ(IO) bool(DIO ## IO ## _WPORT -> PIO_PDSR & MASK(DIO ## IO ## _PIN))
  57. // Write to a pin
  58. #define _WRITE(IO,V) do { \
  59. volatile Pio* port = (DIO ## IO ## _WPORT); \
  60. const uint32_t mask = MASK(DIO ## IO ## _PIN); \
  61. if (V) port->PIO_SODR = mask; \
  62. else port->PIO_CODR = mask; \
  63. }while(0)
  64. // Toggle a pin
  65. #define _TOGGLE(IO) _WRITE(IO, !READ(IO))
  66. #if MB(PRINTRBOARD_G2)
  67. #include "fastio/G2_pins.h"
  68. // Set pin as input
  69. #define _SET_INPUT(IO) do{ \
  70. pmc_enable_periph_clk(G2_g_APinDescription[IO].ulPeripheralId); \
  71. PIO_Configure((DIO ## IO ## _WPORT), PIO_INPUT, MASK(DIO ## IO ## _PIN), 0); \
  72. }while(0)
  73. // Set pin as output
  74. #define _SET_OUTPUT(IO) do{ \
  75. uint32_t mask = MASK(G2_g_APinDescription[IO].ulPeripheralId); \
  76. if ((PMC->PMC_PCSR0 & mask) != (mask)) PMC->PMC_PCER0 = mask; \
  77. volatile Pio* port = (DIO ## IO ## _WPORT); \
  78. mask = MASK(DIO ## IO ## _PIN); \
  79. if (_READ(IO)) port->PIO_SODR = mask; \
  80. else port->PIO_CODR = mask; \
  81. port->PIO_IDR = mask; \
  82. const uint32_t pin_config = G2_g_APinDescription[IO].ulPinConfiguration; \
  83. if (pin_config & PIO_PULLUP) port->PIO_PUER = mask; \
  84. else port->PIO_PUDR = mask; \
  85. if (pin_config & PIO_OPENDRAIN) port->PIO_MDER = mask; \
  86. else port->PIO_MDDR = mask; \
  87. port->PIO_PER = mask; \
  88. port->PIO_OER = mask; \
  89. g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \
  90. }while(0)
  91. /**
  92. * Set pin as output with comments
  93. * #define _SET_OUTPUT(IO) do{ \
  94. * uint32_t mask = MASK(G2_g_APinDescription[IO].ulPeripheralId); \
  95. * if ((PMC->PMC_PCSR0 & mask ) != (mask)) PMC->PMC_PCER0 = mask; \ // enable PIO clock if not already enabled
  96. *
  97. * volatile Pio* port = (DIO ## IO ## _WPORT); \
  98. * const uint32_t mask = MASK(DIO ## IO ## _PIN); \
  99. * if (_READ(IO)) port->PIO_SODR = mask; \ // set output to match input BEFORE setting direction or will glitch the output
  100. * else port->PIO_CODR = mask; \
  101. *
  102. * port->PIO_IDR = mask; \ // disable interrupt
  103. *
  104. * uint32_t pin_config = G2_g_APinDescription[IO].ulPinConfiguration; \
  105. * if (pin_config & PIO_PULLUP) pPio->PIO_PUER = mask; \ // enable pullup if necessary
  106. * else pPio->PIO_PUDR = mask; \
  107. *
  108. * if (pin_config & PIO_OPENDRAIN) port->PIO_MDER = mask; \ // Enable multi-drive if necessary
  109. * else port->PIO_MDDR = mask; \
  110. *
  111. * port->PIO_PER = mask; \
  112. * port->PIO_OER = mask; \ // set to output
  113. *
  114. * g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \
  115. * }while(0)
  116. */
  117. #else
  118. // Set pin as input
  119. #define _SET_INPUT(IO) do{ \
  120. pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
  121. PIO_Configure(digitalPinToPort(IO), PIO_INPUT, digitalPinToBitMask(IO), 0); \
  122. }while(0)
  123. // Set pin as output
  124. #define _SET_OUTPUT(IO) do{ \
  125. pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
  126. PIO_Configure(digitalPinToPort(IO), _READ(IO) ? PIO_OUTPUT_1 : PIO_OUTPUT_0, digitalPinToBitMask(IO), g_APinDescription[IO].ulPinConfiguration); \
  127. g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \
  128. }while(0)
  129. #endif
  130. // Set pin as input with pullup mode
  131. #define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT)
  132. // Read a pin (wrapper)
  133. #define READ(IO) _READ(IO)
  134. // Write to a pin (wrapper)
  135. #define WRITE(IO,V) _WRITE(IO,V)
  136. // Toggle a pin (wrapper)
  137. #define TOGGLE(IO) _TOGGLE(IO)
  138. // Set pin as input (wrapper)
  139. #define SET_INPUT(IO) _SET_INPUT(IO)
  140. // Set pin as input with pullup (wrapper)
  141. #define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
  142. // Set pin as output (wrapper) - reads the pin and sets the output to that value
  143. #define SET_OUTPUT(IO) _SET_OUTPUT(IO)
  144. // Set pin as PWM
  145. #define SET_PWM SET_OUTPUT
  146. // Check if pin is an input
  147. #define IS_INPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) == 0)
  148. // Check if pin is an output
  149. #define IS_OUTPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) != 0)
  150. // Shorthand
  151. #define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
  152. // digitalRead/Write wrappers
  153. #define extDigitalRead(IO) digitalRead(IO)
  154. #define extDigitalWrite(IO,V) digitalWrite(IO,V)
  155. /**
  156. * Ports and functions
  157. * Added as necessary or if I feel like it- not a comprehensive list!
  158. */
  159. // UART
  160. #define RXD DIO0
  161. #define TXD DIO1
  162. // TWI (I2C)
  163. #define SCL DIO21
  164. #define SDA DIO20
  165. /**
  166. * pins
  167. */
  168. #define DIO0_PIN 8
  169. #define DIO0_WPORT PIOA
  170. #define DIO1_PIN 9
  171. #define DIO1_WPORT PIOA
  172. #define DIO2_PIN 25
  173. #define DIO2_WPORT PIOB
  174. #define DIO3_PIN 28
  175. #define DIO3_WPORT PIOC
  176. #define DIO4_PIN 26
  177. #define DIO4_WPORT PIOC
  178. #define DIO5_PIN 25
  179. #define DIO5_WPORT PIOC
  180. #define DIO6_PIN 24
  181. #define DIO6_WPORT PIOC
  182. #define DIO7_PIN 23
  183. #define DIO7_WPORT PIOC
  184. #define DIO8_PIN 22
  185. #define DIO8_WPORT PIOC
  186. #define DIO9_PIN 21
  187. #define DIO9_WPORT PIOC
  188. #define DIO10_PIN 29
  189. #define DIO10_WPORT PIOC
  190. #define DIO11_PIN 7
  191. #define DIO11_WPORT PIOD
  192. #define DIO12_PIN 8
  193. #define DIO12_WPORT PIOD
  194. #define DIO13_PIN 27
  195. #define DIO13_WPORT PIOB
  196. #define DIO14_PIN 4
  197. #define DIO14_WPORT PIOD
  198. #define DIO15_PIN 5
  199. #define DIO15_WPORT PIOD
  200. #define DIO16_PIN 13
  201. #define DIO16_WPORT PIOA
  202. #define DIO17_PIN 12
  203. #define DIO17_WPORT PIOA
  204. #define DIO18_PIN 11
  205. #define DIO18_WPORT PIOA
  206. #define DIO19_PIN 10
  207. #define DIO19_WPORT PIOA
  208. #define DIO20_PIN 12
  209. #define DIO20_WPORT PIOB
  210. #define DIO21_PIN 13
  211. #define DIO21_WPORT PIOB
  212. #define DIO22_PIN 26
  213. #define DIO22_WPORT PIOB
  214. #define DIO23_PIN 14
  215. #define DIO23_WPORT PIOA
  216. #define DIO24_PIN 15
  217. #define DIO24_WPORT PIOA
  218. #define DIO25_PIN 0
  219. #define DIO25_WPORT PIOD
  220. #define DIO26_PIN 1
  221. #define DIO26_WPORT PIOD
  222. #define DIO27_PIN 2
  223. #define DIO27_WPORT PIOD
  224. #define DIO28_PIN 3
  225. #define DIO28_WPORT PIOD
  226. #define DIO29_PIN 6
  227. #define DIO29_WPORT PIOD
  228. #define DIO30_PIN 9
  229. #define DIO30_WPORT PIOD
  230. #define DIO31_PIN 7
  231. #define DIO31_WPORT PIOA
  232. #define DIO32_PIN 10
  233. #define DIO32_WPORT PIOD
  234. #define DIO33_PIN 1
  235. #define DIO33_WPORT PIOC
  236. #if !MB(PRINTRBOARD_G2) // normal DUE pin mapping
  237. #define DIO34_PIN 2
  238. #define DIO34_WPORT PIOC
  239. #define DIO35_PIN 3
  240. #define DIO35_WPORT PIOC
  241. #define DIO36_PIN 4
  242. #define DIO36_WPORT PIOC
  243. #define DIO37_PIN 5
  244. #define DIO37_WPORT PIOC
  245. #define DIO38_PIN 6
  246. #define DIO38_WPORT PIOC
  247. #define DIO39_PIN 7
  248. #define DIO39_WPORT PIOC
  249. #define DIO40_PIN 8
  250. #define DIO40_WPORT PIOC
  251. #define DIO41_PIN 9
  252. #define DIO41_WPORT PIOC
  253. #endif // !PRINTRBOARD_G2
  254. #define DIO42_PIN 19
  255. #define DIO42_WPORT PIOA
  256. #define DIO43_PIN 20
  257. #define DIO43_WPORT PIOA
  258. #define DIO44_PIN 19
  259. #define DIO44_WPORT PIOC
  260. #define DIO45_PIN 18
  261. #define DIO45_WPORT PIOC
  262. #define DIO46_PIN 17
  263. #define DIO46_WPORT PIOC
  264. #define DIO47_PIN 16
  265. #define DIO47_WPORT PIOC
  266. #define DIO48_PIN 15
  267. #define DIO48_WPORT PIOC
  268. #define DIO49_PIN 14
  269. #define DIO49_WPORT PIOC
  270. #define DIO50_PIN 13
  271. #define DIO50_WPORT PIOC
  272. #define DIO51_PIN 12
  273. #define DIO51_WPORT PIOC
  274. #define DIO52_PIN 21
  275. #define DIO52_WPORT PIOB
  276. #define DIO53_PIN 14
  277. #define DIO53_WPORT PIOB
  278. #define DIO54_PIN 16
  279. #define DIO54_WPORT PIOA
  280. #define DIO55_PIN 24
  281. #define DIO55_WPORT PIOA
  282. #define DIO56_PIN 23
  283. #define DIO56_WPORT PIOA
  284. #define DIO57_PIN 22
  285. #define DIO57_WPORT PIOA
  286. #define DIO58_PIN 6
  287. #define DIO58_WPORT PIOA
  288. #define DIO59_PIN 4
  289. #define DIO59_WPORT PIOA
  290. #define DIO60_PIN 3
  291. #define DIO60_WPORT PIOA
  292. #define DIO61_PIN 2
  293. #define DIO61_WPORT PIOA
  294. #define DIO62_PIN 17
  295. #define DIO62_WPORT PIOB
  296. #define DIO63_PIN 18
  297. #define DIO63_WPORT PIOB
  298. #define DIO64_PIN 19
  299. #define DIO64_WPORT PIOB
  300. #define DIO65_PIN 20
  301. #define DIO65_WPORT PIOB
  302. #define DIO66_PIN 15
  303. #define DIO66_WPORT PIOB
  304. #define DIO67_PIN 16
  305. #define DIO67_WPORT PIOB
  306. #define DIO68_PIN 1
  307. #define DIO68_WPORT PIOA
  308. #define DIO69_PIN 0
  309. #define DIO69_WPORT PIOA
  310. #define DIO70_PIN 17
  311. #define DIO70_WPORT PIOA
  312. #define DIO71_PIN 18
  313. #define DIO71_WPORT PIOA
  314. #define DIO72_PIN 30
  315. #define DIO72_WPORT PIOC
  316. #define DIO73_PIN 21
  317. #define DIO73_WPORT PIOA
  318. #define DIO74_PIN 25
  319. #define DIO74_WPORT PIOA
  320. #define DIO75_PIN 26
  321. #define DIO75_WPORT PIOA
  322. #define DIO76_PIN 27
  323. #define DIO76_WPORT PIOA
  324. #define DIO77_PIN 28
  325. #define DIO77_WPORT PIOA
  326. #define DIO78_PIN 23
  327. #define DIO78_WPORT PIOB
  328. #define DIO79_PIN 17
  329. #define DIO79_WPORT PIOA
  330. #define DIO80_PIN 12
  331. #define DIO80_WPORT PIOB
  332. #define DIO81_PIN 8
  333. #define DIO81_WPORT PIOA
  334. #define DIO82_PIN 11
  335. #define DIO82_WPORT PIOA
  336. #define DIO83_PIN 13
  337. #define DIO83_WPORT PIOA
  338. #define DIO84_PIN 4
  339. #define DIO84_WPORT PIOD
  340. #define DIO85_PIN 11
  341. #define DIO85_WPORT PIOB
  342. #define DIO86_PIN 21
  343. #define DIO86_WPORT PIOB
  344. #define DIO87_PIN 29
  345. #define DIO87_WPORT PIOA
  346. #define DIO88_PIN 15
  347. #define DIO88_WPORT PIOB
  348. #define DIO89_PIN 14
  349. #define DIO89_WPORT PIOB
  350. #define DIO90_PIN 1
  351. #define DIO90_WPORT PIOA
  352. #define DIO91_PIN 15
  353. #define DIO91_WPORT PIOB
  354. #if ARDUINO_SAM_ARCHIM
  355. #define DIO92_PIN 11
  356. #define DIO92_WPORT PIOC
  357. #define DIO93_PIN 2
  358. #define DIO93_WPORT PIOB
  359. #define DIO94_PIN 1
  360. #define DIO94_WPORT PIOB
  361. #define DIO95_PIN 0
  362. #define DIO95_WPORT PIOB
  363. #define DIO96_PIN 10
  364. #define DIO96_WPORT PIOC
  365. #define DIO97_PIN 24
  366. #define DIO97_WPORT PIOB
  367. #define DIO98_PIN 7
  368. #define DIO98_WPORT PIOB
  369. #define DIO99_PIN 6
  370. #define DIO99_WPORT PIOB
  371. #define DIO100_PIN 8
  372. #define DIO100_WPORT PIOB
  373. #define DIO101_PIN 5
  374. #define DIO101_WPORT PIOB
  375. #define DIO102_PIN 4
  376. #define DIO102_WPORT PIOB
  377. #define DIO103_PIN 3
  378. #define DIO103_WPORT PIOB
  379. #define DIO104_PIN 20
  380. #define DIO104_WPORT PIOC
  381. #define DIO105_PIN 22
  382. #define DIO105_WPORT PIOB
  383. #define DIO106_PIN 27
  384. #define DIO106_WPORT PIOC
  385. #define DIO107_PIN 10
  386. #define DIO107_WPORT PIOB
  387. #define DIO108_PIN 9
  388. #define DIO108_WPORT PIOB
  389. #else // !ARDUINO_SAM_ARCHIM
  390. #define DIO92_PIN 5
  391. #define DIO92_WPORT PIOA
  392. #define DIO93_PIN 12
  393. #define DIO93_WPORT PIOB
  394. #define DIO94_PIN 22
  395. #define DIO94_WPORT PIOB
  396. #define DIO95_PIN 23
  397. #define DIO95_WPORT PIOB
  398. #define DIO96_PIN 24
  399. #define DIO96_WPORT PIOB
  400. #define DIO97_PIN 20
  401. #define DIO97_WPORT PIOC
  402. #define DIO98_PIN 27
  403. #define DIO98_WPORT PIOC
  404. #define DIO99_PIN 10
  405. #define DIO99_WPORT PIOC
  406. #define DIO100_PIN 11
  407. #define DIO100_WPORT PIOC
  408. #endif // !ARDUINO_SAM_ARCHIM