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.

arduino.cpp 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #ifdef TARGET_LPC1768
  23. #include <lpc17xx_pinsel.h>
  24. #include "HAL.h"
  25. #include "../../core/macros.h"
  26. #include "../../core/types.h"
  27. // Interrupts
  28. void cli(void) { __disable_irq(); } // Disable
  29. void sei(void) { __enable_irq(); } // Enable
  30. // Time functions
  31. void _delay_ms(const int delay_ms) {
  32. delay(delay_ms);
  33. }
  34. uint32_t millis() {
  35. return _millis;
  36. }
  37. void delayMicroseconds(uint32_t us) {
  38. static const int nop_factor = (SystemCoreClock / 11000000);
  39. static volatile int loops = 0;
  40. //previous ops already burned most of 1us, burn the rest
  41. loops = nop_factor / 4; //measured at 1us
  42. while (loops > 0) --loops;
  43. if (us < 2) return;
  44. us--;
  45. //redirect to delay for large values, then set new delay to remainder
  46. if (us > 1000) {
  47. delay(us / 1000);
  48. us = us % 1000;
  49. }
  50. if (us < 5) { // burn cycles, time in interrupts will not be taken into account
  51. loops = us * nop_factor;
  52. while (loops > 0) --loops;
  53. }
  54. else { // poll systick, more accurate through interrupts
  55. int32_t start = SysTick->VAL;
  56. int32_t load = SysTick->LOAD;
  57. int32_t end = start - (load / 1000) * us;
  58. if (end >> 31)
  59. while (!(SysTick->VAL > start && SysTick->VAL < (load + end))) __NOP();
  60. else
  61. while (SysTick->VAL > end) __NOP();
  62. }
  63. }
  64. extern "C" void delay(const int msec) {
  65. volatile millis_t end = _millis + msec;
  66. SysTick->VAL = SysTick->LOAD; // reset systick counter so next systick is in exactly 1ms
  67. // this could extend the time between systicks by upto 1ms
  68. while PENDING(_millis, end) __WFE();
  69. }
  70. // IO functions
  71. // As defined by Arduino INPUT(0x0), OUPUT(0x1), INPUT_PULLUP(0x2)
  72. void pinMode(uint8_t pin, uint8_t mode) {
  73. if (!WITHIN(pin, 0, NUM_DIGITAL_PINS - 1) || pin_map[pin].port == 0xFF)
  74. return;
  75. PINSEL_CFG_Type config = { pin_map[pin].port,
  76. pin_map[pin].pin,
  77. PINSEL_FUNC_0,
  78. PINSEL_PINMODE_TRISTATE,
  79. PINSEL_PINMODE_NORMAL };
  80. switch(mode) {
  81. case INPUT:
  82. LPC_GPIO(pin_map[pin].port)->FIODIR &= ~LPC_PIN(pin_map[pin].pin);
  83. PINSEL_ConfigPin(&config);
  84. break;
  85. case OUTPUT:
  86. LPC_GPIO(pin_map[pin].port)->FIODIR |= LPC_PIN(pin_map[pin].pin);
  87. PINSEL_ConfigPin(&config);
  88. break;
  89. case INPUT_PULLUP:
  90. LPC_GPIO(pin_map[pin].port)->FIODIR &= ~LPC_PIN(pin_map[pin].pin);
  91. config.Pinmode = PINSEL_PINMODE_PULLUP;
  92. PINSEL_ConfigPin(&config);
  93. break;
  94. default:
  95. break;
  96. }
  97. }
  98. void digitalWrite(uint8_t pin, uint8_t pin_status) {
  99. if (!WITHIN(pin, 0, NUM_DIGITAL_PINS - 1) || pin_map[pin].port == 0xFF)
  100. return;
  101. if (pin_status)
  102. LPC_GPIO(pin_map[pin].port)->FIOSET = LPC_PIN(pin_map[pin].pin);
  103. else
  104. LPC_GPIO(pin_map[pin].port)->FIOCLR = LPC_PIN(pin_map[pin].pin);
  105. pinMode(pin, OUTPUT); // Set pin mode on every write (Arduino version does this)
  106. /**
  107. * Must be done AFTER the output state is set. Doing this before will cause a
  108. * 2uS glitch if writing a "1".
  109. *
  110. * When the Port Direction bit is written to a "1" the output is immediately set
  111. * to the value of the FIOPIN bit which is "0" because of power up defaults.
  112. */
  113. }
  114. bool digitalRead(uint8_t pin) {
  115. if (!WITHIN(pin, 0, NUM_DIGITAL_PINS - 1) || pin_map[pin].port == 0xFF) {
  116. return false;
  117. }
  118. return LPC_GPIO(pin_map[pin].port)->FIOPIN & LPC_PIN(pin_map[pin].pin) ? 1 : 0;
  119. }
  120. void analogWrite(uint8_t pin, int pwm_value) { // 1 - 254: pwm_value, 0: LOW, 255: HIGH
  121. extern bool LPC1768_PWM_attach_pin(uint8_t, uint32_t, uint32_t, uint8_t);
  122. extern bool LPC1768_PWM_write(uint8_t, uint32_t);
  123. extern bool LPC1768_PWM_detach_pin(uint8_t);
  124. #define MR0_MARGIN 200 // if channel value too close to MR0 the system locks up
  125. static bool out_of_PWM_slots = false;
  126. if (!WITHIN(pin, 0, NUM_DIGITAL_PINS - 1) || pin_map[pin].port == 0xFF)
  127. return;
  128. uint value = MAX(MIN(pwm_value, 255), 0);
  129. if (value == 0 || value == 255) { // treat as digital pin
  130. LPC1768_PWM_detach_pin(pin); // turn off PWM
  131. digitalWrite(pin, value);
  132. }
  133. else {
  134. if (LPC1768_PWM_attach_pin(pin, 1, (LPC_PWM1->MR0 - MR0_MARGIN), 0xff)) // locks up if get too close to MR0 value
  135. LPC1768_PWM_write(pin, map(value, 1, 254, 1, (LPC_PWM1->MR0 - MR0_MARGIN))); // map 1-254 onto PWM range
  136. else { // out of PWM channels
  137. if (!out_of_PWM_slots) usb_serial.printf(".\nWARNING - OUT OF PWM CHANNELS\n.\n"); //only warn once
  138. out_of_PWM_slots = true;
  139. digitalWrite(pin, value); // treat as a digital pin if out of channels
  140. }
  141. }
  142. }
  143. extern bool HAL_adc_finished();
  144. uint16_t analogRead(uint8_t adc_pin) {
  145. HAL_adc_start_conversion(adc_pin);
  146. while (!HAL_adc_finished()); // Wait for conversion to finish
  147. return HAL_adc_get_result();
  148. }
  149. // **************************
  150. // Persistent Config Storage
  151. // **************************
  152. void eeprom_write_byte(unsigned char *pos, unsigned char value) {
  153. }
  154. unsigned char eeprom_read_byte(uint8_t * pos) { return '\0'; }
  155. void eeprom_read_block (void *__dst, const void *__src, size_t __n) { }
  156. void eeprom_update_block (const void *__src, void *__dst, size_t __n) { }
  157. char *dtostrf (double __val, signed char __width, unsigned char __prec, char *__s) {
  158. char format_string[20];
  159. snprintf(format_string, 20, "%%%d.%df", __width, __prec);
  160. sprintf(__s, format_string, __val);
  161. return __s;
  162. }
  163. int32_t random(int32_t max) {
  164. return rand() % max;
  165. }
  166. int32_t random(int32_t min, int32_t max) {
  167. return min + rand() % (max - min);
  168. }
  169. void randomSeed(uint32_t value) {
  170. srand(value);
  171. }
  172. int map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) {
  173. return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  174. }
  175. #endif // TARGET_LPC1768