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.cpp 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /* **************************************************************************
  2. Marlin 3D Printer Firmware
  3. Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. ****************************************************************************/
  16. #ifdef TARGET_LPC1768
  17. #include "../../inc/MarlinConfig.h"
  18. #include "../Delay.h"
  19. HalSerial usb_serial;
  20. // U8glib required functions
  21. extern "C" void u8g_xMicroDelay(uint16_t val) {
  22. DELAY_US(val);
  23. }
  24. extern "C" void u8g_MicroDelay(void) {
  25. u8g_xMicroDelay(1);
  26. }
  27. extern "C" void u8g_10MicroDelay(void) {
  28. u8g_xMicroDelay(10);
  29. }
  30. extern "C" void u8g_Delay(uint16_t val) {
  31. delay(val);
  32. }
  33. //************************//
  34. // return free heap space
  35. int freeMemory() {
  36. char stack_end;
  37. void *heap_start = malloc(sizeof(uint32_t));
  38. if (heap_start == 0) return 0;
  39. uint32_t result = (uint32_t)&stack_end - (uint32_t)heap_start;
  40. free(heap_start);
  41. return result;
  42. }
  43. // --------------------------------------------------------------------------
  44. // ADC
  45. // --------------------------------------------------------------------------
  46. #define ADC_DONE 0x80000000
  47. #define ADC_OVERRUN 0x40000000
  48. void HAL_adc_init(void) {
  49. LPC_SC->PCONP |= (1 << 12); // Enable CLOCK for internal ADC controller
  50. LPC_SC->PCLKSEL0 &= ~(0x3 << 24);
  51. LPC_SC->PCLKSEL0 |= (0x1 << 24); // 0: 25MHz, 1: 100MHz, 2: 50MHz, 3: 12.5MHZ to ADC clock divider
  52. LPC_ADC->ADCR = (0 << 0) // SEL: 0 = no channels selected
  53. | (0xFF << 8) // select slowest clock for A/D conversion 150 - 190 uS for a complete conversion
  54. | (0 << 16) // BURST: 0 = software control
  55. | (0 << 17) // CLKS: not applicable
  56. | (1 << 21) // PDN: 1 = operational
  57. | (0 << 24) // START: 0 = no start
  58. | (0 << 27); // EDGE: not applicable
  59. }
  60. // externals need to make the call to KILL compile
  61. #include "../../core/language.h"
  62. extern void kill(const char*);
  63. extern const char errormagic[];
  64. void HAL_adc_enable_channel(int ch) {
  65. pin_t pin = analogInputToDigitalPin(ch);
  66. if (pin == -1) {
  67. SERIAL_PRINTF("%sINVALID ANALOG PORT:%d\n", errormagic, ch);
  68. kill(MSG_KILLED);
  69. }
  70. int8_t pin_port = LPC1768_PIN_PORT(pin),
  71. pin_port_pin = LPC1768_PIN_PIN(pin),
  72. pinsel_start_bit = pin_port_pin > 15 ? 2 * (pin_port_pin - 16) : 2 * pin_port_pin;
  73. uint8_t pin_sel_register = (pin_port == 0 && pin_port_pin <= 15) ? 0 :
  74. pin_port == 0 ? 1 :
  75. pin_port == 1 ? 3 : 10;
  76. switch (pin_sel_register) {
  77. case 1:
  78. LPC_PINCON->PINSEL1 &= ~(0x3 << pinsel_start_bit);
  79. LPC_PINCON->PINSEL1 |= (0x1 << pinsel_start_bit);
  80. break;
  81. case 3:
  82. LPC_PINCON->PINSEL3 &= ~(0x3 << pinsel_start_bit);
  83. LPC_PINCON->PINSEL3 |= (0x3 << pinsel_start_bit);
  84. break;
  85. case 0:
  86. LPC_PINCON->PINSEL0 &= ~(0x3 << pinsel_start_bit);
  87. LPC_PINCON->PINSEL0 |= (0x2 << pinsel_start_bit);
  88. break;
  89. };
  90. }
  91. void HAL_adc_start_conversion(const uint8_t ch) {
  92. if (analogInputToDigitalPin(ch) == -1) {
  93. SERIAL_PRINTF("HAL: HAL_adc_start_conversion: invalid channel %d\n", ch);
  94. return;
  95. }
  96. LPC_ADC->ADCR &= ~0xFF; // Reset
  97. SBI(LPC_ADC->ADCR, ch); // Select Channel
  98. SBI(LPC_ADC->ADCR, 24); // Start conversion
  99. }
  100. bool HAL_adc_finished(void) {
  101. return LPC_ADC->ADGDR & ADC_DONE;
  102. }
  103. // possible config options if something similar is extended to more platforms.
  104. #define ADC_USE_MEDIAN_FILTER // Filter out erroneous readings
  105. #define ADC_MEDIAN_FILTER_SIZE (23) // Higher values increase step delay (phase shift),
  106. // (ADC_MEDIAN_FILTER_SIZE + 1) / 2 sample step delay (12 samples @ 500Hz: 24ms phase shift)
  107. // Memory usage per ADC channel (bytes): (6 * ADC_MEDIAN_FILTER_SIZE) + 16
  108. // 8 * ((6 * 23) + 16 ) = 1232 Bytes for 8 channels
  109. #define ADC_USE_LOWPASS_FILTER // Filter out high frequency noise
  110. #define ADC_LOWPASS_K_VALUE (6) // Higher values increase rise time
  111. // Rise time sample delays for 100% signal convergence on full range step
  112. // (1 : 13, 2 : 32, 3 : 67, 4 : 139, 5 : 281, 6 : 565, 7 : 1135, 8 : 2273)
  113. // K = 6, 565 samples, 500Hz sample rate, 1.13s convergence on full range step
  114. // Memory usage per ADC channel (bytes): 4 (32 Bytes for 8 channels)
  115. // Sourced from https://embeddedgurus.com/stack-overflow/tag/median-filter/
  116. struct MedianFilter {
  117. #define STOPPER 0 // Smaller than any datum
  118. struct Pair {
  119. Pair *point; // Pointers forming list linked in sorted order
  120. uint16_t value; // Values to sort
  121. };
  122. Pair buffer[ADC_MEDIAN_FILTER_SIZE] = {}; // Buffer of nwidth pairs
  123. Pair *datpoint = buffer; // Pointer into circular buffer of data
  124. Pair small = {NULL, STOPPER}; // Chain stopper
  125. Pair big = {&small, 0}; // Pointer to head (largest) of linked list.
  126. uint16_t update(uint16_t datum) {
  127. Pair *successor; // Pointer to successor of replaced data item
  128. Pair *scan; // Pointer used to scan down the sorted list
  129. Pair *scanold; // Previous value of scan
  130. Pair *median; // Pointer to median
  131. uint16_t i;
  132. if (datum == STOPPER) {
  133. datum = STOPPER + 1; // No stoppers allowed.
  134. }
  135. if ( (++datpoint - buffer) >= ADC_MEDIAN_FILTER_SIZE) {
  136. datpoint = buffer; // Increment and wrap data in pointer.
  137. }
  138. datpoint->value = datum; // Copy in new datum
  139. successor = datpoint->point; // Save pointer to old value's successor
  140. median = &big; // Median initially to first in chain
  141. scanold = NULL; // Scanold initially null.
  142. scan = &big; // Points to pointer to first (largest) datum in chain
  143. // Handle chain-out of first item in chain as special case
  144. if (scan->point == datpoint) {
  145. scan->point = successor;
  146. }
  147. scanold = scan; // Save this pointer and
  148. scan = scan->point ; // step down chain
  149. // Loop through the chain, normal loop exit via break.
  150. for (i = 0 ; i < ADC_MEDIAN_FILTER_SIZE; ++i) {
  151. // Handle odd-numbered item in chain
  152. if (scan->point == datpoint) {
  153. scan->point = successor; // Chain out the old datum
  154. }
  155. if (scan->value < datum) { // If datum is larger than scanned value
  156. datpoint->point = scanold->point; // Chain it in here
  157. scanold->point = datpoint; // Mark it chained in
  158. datum = STOPPER;
  159. }
  160. // Step median pointer down chain after doing odd-numbered element
  161. median = median->point; // Step median pointer
  162. if (scan == &small) {
  163. break; // Break at end of chain
  164. }
  165. scanold = scan; // Save this pointer and
  166. scan = scan->point; // step down chain
  167. // Handle even-numbered item in chain.
  168. if (scan->point == datpoint) {
  169. scan->point = successor;
  170. }
  171. if (scan->value < datum) {
  172. datpoint->point = scanold->point;
  173. scanold->point = datpoint;
  174. datum = STOPPER;
  175. }
  176. if (scan == &small) {
  177. break;
  178. }
  179. scanold = scan;
  180. scan = scan->point;
  181. }
  182. return median->value;
  183. }
  184. };
  185. struct LowpassFilter {
  186. uint32_t data_delay = 0;
  187. uint16_t update(uint16_t value) {
  188. data_delay = data_delay - (data_delay >> ADC_LOWPASS_K_VALUE) + value;
  189. return (uint16_t)(data_delay >> ADC_LOWPASS_K_VALUE);
  190. }
  191. };
  192. uint16_t HAL_adc_get_result(void) {
  193. uint32_t adgdr = LPC_ADC->ADGDR;
  194. CBI(LPC_ADC->ADCR, 24); // Stop conversion
  195. if (adgdr & ADC_OVERRUN) return 0;
  196. uint16_t data = (adgdr >> 4) & 0xFFF; // copy the 12bit data value
  197. uint8_t adc_channel = (adgdr >> 24) & 0x7; // copy the 3bit used channel
  198. #ifdef ADC_USE_MEDIAN_FILTER
  199. static MedianFilter median_filter[NUM_ANALOG_INPUTS];
  200. data = median_filter[adc_channel].update(data);
  201. #endif
  202. #ifdef ADC_USE_LOWPASS_FILTER
  203. static LowpassFilter lowpass_filter[NUM_ANALOG_INPUTS];
  204. data = lowpass_filter[adc_channel].update(data);
  205. #endif
  206. return ((data >> 2) & 0x3FF); // return 10bit value as Marlin expects
  207. }
  208. #define SBIT_CNTEN 0
  209. #define SBIT_PWMEN 2
  210. #define SBIT_PWMMR0R 1
  211. #define PWM_1 0 //P2_00 (0-1 Bits of PINSEL4)
  212. #define PWM_2 2 //P2_01 (2-3 Bits of PINSEL4)
  213. #define PWM_3 4 //P2_02 (4-5 Bits of PINSEL4)
  214. #define PWM_4 6 //P2_03 (6-7 Bits of PINSEL4)
  215. #define PWM_5 8 //P2_04 (8-9 Bits of PINSEL4)
  216. #define PWM_6 10 //P2_05 (10-11 Bits of PINSEL4)
  217. void HAL_pwm_init(void) {
  218. LPC_PINCON->PINSEL4 = _BV(PWM_5) | _BV(PWM_6);
  219. LPC_PWM1->TCR = _BV(SBIT_CNTEN) | _BV(SBIT_PWMEN);
  220. LPC_PWM1->PR = 0x0; // No prescalar
  221. LPC_PWM1->MCR = _BV(SBIT_PWMMR0R); // Reset on PWMMR0, reset TC if it matches MR0
  222. LPC_PWM1->MR0 = 255; // set PWM cycle(Ton+Toff)=255)
  223. LPC_PWM1->MR5 = 0; // Set 50% Duty Cycle for the channels
  224. LPC_PWM1->MR6 = 0;
  225. // Trigger the latch Enable Bits to load the new Match Values MR0, MR5, MR6
  226. LPC_PWM1->LER = _BV(0) | _BV(5) | _BV(6);
  227. // Enable the PWM output pins for PWM_5-PWM_6(P2_04 - P2_05)
  228. LPC_PWM1->PCR = _BV(13) | _BV(14);
  229. }
  230. #endif // TARGET_LPC1768