MRRF Bump

This commit is contained in:
InsanityAutomation
2019-03-29 17:43:34 -04:00
parent ec2c721ca2
commit e3f6f1b12c
600 changed files with 13088 additions and 362334 deletions
+14 -5
View File
@@ -1,3 +1,5 @@
//#define BondtechBMG
//#define FilamentSensorStd
//#define FilamentSensorLerdge
@@ -413,13 +415,13 @@
// When temperature exceeds max temp, your heater will be switched off.
// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure!
// You should use MINTEMP for thermistor short/failure protection.
#define HEATER_0_MAXTEMP 290
#define HEATER_0_MAXTEMP 305
#define HEATER_1_MAXTEMP 275
#define HEATER_2_MAXTEMP 275
#define HEATER_3_MAXTEMP 275
#define HEATER_4_MAXTEMP 275
#define HEATER_5_MAXTEMP 275
#define BED_MAXTEMP 110
#define BED_MAXTEMP 125
//===========================================================================
//============================= PID Settings ================================
@@ -686,8 +688,11 @@
* Override with M92
* X, Y, Z, E0 [, E1[, E2[, E3[, E4[, E5]]]]]
*/
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 100.3 }
#if ENABLED(BondtechBMG)
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 415.0 }
#else
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 100.3 }
#endif
/**
* Default Max Feed Rate (mm/s)
* Override with M203
@@ -956,7 +961,11 @@
// @section extruder
// For direct drive extruder v9 set to true, for geared extruder set to false.
#define INVERT_E0_DIR true
#if ENABLED(BondtechBMG)
#define INVERT_E0_DIR true
#else
#define INVERT_E0_DIR true
#endif
#define INVERT_E1_DIR false
#define INVERT_E2_DIR false
#define INVERT_E3_DIR false
+22 -3
View File
@@ -182,7 +182,7 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t freque
#define TIMER_OCR_0 OCR0A
#define TIMER_COUNTER_0 TCNT0
#define _CAT(a, ...) a ## __VA_ARGS__
#define _CAT(a,V...) a##V
#define HAL_timer_set_compare(timer, compare) (_CAT(TIMER_OCR_, timer) = compare)
#define HAL_timer_get_compare(timer) _CAT(TIMER_OCR_, timer)
#define HAL_timer_get_count(timer) _CAT(TIMER_COUNTER_, timer)
@@ -197,7 +197,7 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t freque
#define HAL_timer_isr_epilogue(TIMER_NUM)
/* 18 cycles maximum latency */
#define HAL_STEP_TIMER_ISR \
#define HAL_STEP_TIMER_ISR() \
extern "C" void TIMER1_COMPA_vect (void) __attribute__ ((signal, naked, used, externally_visible)); \
extern "C" void TIMER1_COMPA_vect_bottom (void) asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
void TIMER1_COMPA_vect (void) { \
@@ -270,7 +270,7 @@ void TIMER1_COMPA_vect (void) { \
void TIMER1_COMPA_vect_bottom(void)
/* 14 cycles maximum latency */
#define HAL_TEMP_TIMER_ISR \
#define HAL_TEMP_TIMER_ISR() \
extern "C" void TIMER0_COMPB_vect (void) __attribute__ ((signal, naked, used, externally_visible)); \
extern "C" void TIMER0_COMPB_vect_bottom(void) asm ("TIMER0_COMPB_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
void TIMER0_COMPB_vect (void) { \
@@ -372,3 +372,22 @@ inline void HAL_adc_init(void) {
// AVR compatibility
#define strtof strtod
/**
* set_pwm_frequency
* Sets the frequency of the timer corresponding to the provided pin
* as close as possible to the provided desired frequency. Internally
* calculates the required waveform generation mode, prescaler and
* resolution values required and sets the timer registers accordingly.
* NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B)
* NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings)
*/
void set_pwm_frequency(const pin_t pin, int f_desired);
/**
* set_pwm_duty
* Sets the PWM duty cycle of the provided pin to the provided value
* Optionally allows inverting the duty cycle [default = false]
* Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
*/
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
+20 -29
View File
@@ -27,8 +27,6 @@
/**
* Description: HAL for AVR - SPI functions
*
* For __AVR__
*/
#ifdef __AVR__
@@ -68,10 +66,12 @@ void spiBegin (void) {
}
//------------------------------------------------------------------------------
#if DISABLED(SOFTWARE_SPI)
// functions for hardware SPI
//------------------------------------------------------------------------------
// Hardware SPI
//------------------------------------------------------------------------------
// make sure SPCR rate is in expected bits
#if (SPR0 != 0 || SPR1 != 1)
#error "unexpected SPCR bits"
@@ -95,14 +95,13 @@ void spiBegin (void) {
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
}
//------------------------------------------------------------------------------
/** SPI receive a byte */
uint8_t spiRec(void) {
SPDR = 0xFF;
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
return SPDR;
}
//------------------------------------------------------------------------------
/** SPI read data */
void spiRead(uint8_t* buf, uint16_t nbyte) {
if (nbyte-- == 0) return;
@@ -115,13 +114,13 @@ void spiBegin (void) {
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
buf[nbyte] = SPDR;
}
//------------------------------------------------------------------------------
/** SPI send a byte */
void spiSend(uint8_t b) {
SPDR = b;
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
}
//------------------------------------------------------------------------------
/** SPI send block */
void spiSendBlock(uint8_t token, const uint8_t* buf) {
SPDR = token;
@@ -191,25 +190,21 @@ void spiBegin (void) {
}
//------------------------------------------------------------------------------
#else // SOFTWARE_SPI
//------------------------------------------------------------------------------
#else
/** nop to tune soft SPI timing */
#define nop asm volatile ("\tnop\n")
/** Set SPI rate */
void spiInit(uint8_t spiRate) {
// nothing to do
UNUSED(spiRate);
UNUSED(spiRate); // nothing to do
}
/** Begin SPI transaction, set clock, bit order, data mode */
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
// nothing to do
UNUSED(spiBeginTransaction);
UNUSED(spiBeginTransaction); // nothing to do
}
//------------------------------------------------------------------------------
/** Soft SPI receive byte */
uint8_t spiRec() {
uint8_t data = 0;
@@ -221,8 +216,7 @@ void spiBegin (void) {
for (uint8_t i = 0; i < 8; i++) {
WRITE(SCK_PIN, HIGH);
// adjust so SCK is nice
nop;
nop; // adjust so SCK is nice
nop;
data <<= 1;
@@ -231,48 +225,45 @@ void spiBegin (void) {
WRITE(SCK_PIN, LOW);
}
// enable interrupts
sei();
return data;
}
//------------------------------------------------------------------------------
/** Soft SPI read data */
void spiRead(uint8_t* buf, uint16_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++)
buf[i] = spiRec();
}
//------------------------------------------------------------------------------
/** Soft SPI send byte */
void spiSend(uint8_t data) {
// no interrupts during byte send - about 8µs
cli();
for (uint8_t i = 0; i < 8; i++) {
WRITE(SCK_PIN, LOW);
WRITE(MOSI_PIN, data & 0x80);
data <<= 1;
WRITE(SCK_PIN, HIGH);
}
// hold SCK high for a few ns
nop;
nop; // hold SCK high for a few ns
nop;
nop;
nop;
WRITE(SCK_PIN, LOW);
// enable interrupts
sei();
}
//------------------------------------------------------------------------------
/** Soft SPI send block */
void spiSendBlock(uint8_t token, const uint8_t* buf) {
spiSend(token);
for (uint16_t i = 0; i < 512; i++)
spiSend(buf[i]);
}
#endif // SOFTWARE_SPI
#endif // SOFTWARE_SPI
#endif // __AVR__
+7
View File
@@ -35,6 +35,13 @@
#endif
#endif
/**
* Checks for FAST PWM
*/
#if ENABLED(FAST_PWM_FAN) && (ENABLED(USE_OCR2A_AS_TOP) && defined(TCCR2))
#error "USE_OCR2A_AS_TOP does not apply to devices with a single output TIMER2"
#endif
/**
* Sanity checks for Spindle / Laser
*/
+250
View File
@@ -0,0 +1,250 @@
#ifdef __AVR__
#include "../../inc/MarlinConfigPre.h"
/**
* get_pwm_timer
* Grabs timer information and registers of the provided pin
* returns Timer struct containing this information
* Used by set_pwm_frequency, set_pwm_duty
*
*/
#if ENABLED(FAST_PWM_FAN)
#include "HAL.h"
struct Timer {
volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer
volatile uint16_t* OCRnQ[3]; // max 3 OCR registers per timer
volatile uint16_t* ICRn; // max 1 ICR register per timer
uint8_t n; // the timer number [0->5]
uint8_t q; // the timer output [0->2] (A->C)
};
Timer get_pwm_timer(pin_t pin) {
uint8_t q = 0;
switch (digitalPinToTimer(pin)) {
// Protect reserved timers (TIMER0 & TIMER1)
#ifdef TCCR0A
#if !AVR_AT90USB1286_FAMILY
case TIMER0A:
#endif
case TIMER0B:
#endif
#ifdef TCCR1A
case TIMER1A: case TIMER1B:
#endif
break;
#if defined(TCCR2) || defined(TCCR2A)
#ifdef TCCR2
case TIMER2: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2, NULL, NULL},
/*OCRnQ*/ { (uint16_t*)&OCR2, NULL, NULL},
/*ICRn*/ NULL,
/*n, q*/ 2, 0
};
}
#elif defined TCCR2A
#if ENABLED(USE_OCR2A_AS_TOP)
case TIMER2A: break; // protect TIMER2A
case TIMER2B: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2A, &TCCR2B, NULL},
/*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, NULL},
/*ICRn*/ NULL,
/*n, q*/ 2, 1
};
return timer;
}
#else
case TIMER2B: ++q;
case TIMER2A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2A, &TCCR2B, NULL},
/*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, NULL},
/*ICRn*/ NULL,
2, q
};
return timer;
}
#endif
#endif
#endif
#ifdef TCCR3A
case TIMER3C: ++q;
case TIMER3B: ++q;
case TIMER3A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR3A, &TCCR3B, &TCCR3C},
/*OCRnQ*/ { &OCR3A, &OCR3B, &OCR3C},
/*ICRn*/ &ICR3,
/*n, q*/ 3, q
};
return timer;
}
#endif
#ifdef TCCR4A
case TIMER4C: ++q;
case TIMER4B: ++q;
case TIMER4A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR4A, &TCCR4B, &TCCR4C},
/*OCRnQ*/ { &OCR4A, &OCR4B, &OCR4C},
/*ICRn*/ &ICR4,
/*n, q*/ 4, q
};
return timer;
}
#endif
#ifdef TCCR5A
case TIMER5C: ++q;
case TIMER5B: ++q;
case TIMER5A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR5A, &TCCR5B, &TCCR5C},
/*OCRnQ*/ { &OCR5A, &OCR5B, &OCR5C },
/*ICRn*/ &ICR5,
/*n, q*/ 5, q
};
return timer;
}
#endif
}
Timer timer = {
/*TCCRnQ*/ { NULL, NULL, NULL},
/*OCRnQ*/ { NULL, NULL, NULL},
/*ICRn*/ NULL,
0, 0
};
return timer;
}
void set_pwm_frequency(const pin_t pin, int f_desired) {
Timer timer = get_pwm_timer(pin);
if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
uint16_t size;
if (timer.n == 2) size = 255; else size = 65535;
uint16_t res = 255; // resolution (TOP value)
uint8_t j = 0; // prescaler index
uint8_t wgm = 1; // waveform generation mode
// Calculating the prescaler and resolution to use to achieve closest frequency
if (f_desired != 0) {
int f = (F_CPU) / (2 * 1024 * size) + 1; // Initialize frequency as lowest (non-zero) achievable
uint16_t prescaler[] = { 0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 };
// loop over prescaler values
for (uint8_t i = 1; i < 8; i++) {
uint16_t res_temp_fast = 255, res_temp_phase_correct = 255;
if (timer.n == 2) {
// No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
#if ENABLED(USE_OCR2A_AS_TOP)
const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
res_temp_fast = rtf - 1;
res_temp_phase_correct = rtf / 2;
#endif
}
else {
// Skip TIMER2 specific prescalers when not TIMER2
if (i == 3 || i == 5) continue;
const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
res_temp_fast = rtf - 1;
res_temp_phase_correct = rtf / 2;
}
LIMIT(res_temp_fast, 1u, size);
LIMIT(res_temp_phase_correct, 1u, size);
// Calculate frequencies of test prescaler and resolution values
const int f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)),
f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct),
f_diff = ABS(f - f_desired),
f_fast_diff = ABS(f_temp_fast - f_desired),
f_phase_diff = ABS(f_temp_phase_correct - f_desired);
// If FAST values are closest to desired f
if (f_fast_diff < f_diff && f_fast_diff <= f_phase_diff) {
// Remember this combination
f = f_temp_fast;
res = res_temp_fast;
j = i;
// Set the Wave Generation Mode to FAST PWM
if (timer.n == 2) {
wgm = (
#if ENABLED(USE_OCR2A_AS_TOP)
WGM2_FAST_PWM_OCR2A
#else
WGM2_FAST_PWM
#endif
);
}
else wgm = WGM_FAST_PWM_ICRn;
}
// If PHASE CORRECT values are closes to desired f
else if (f_phase_diff < f_diff) {
f = f_temp_phase_correct;
res = res_temp_phase_correct;
j = i;
// Set the Wave Generation Mode to PWM PHASE CORRECT
if (timer.n == 2) {
wgm = (
#if ENABLED(USE_OCR2A_AS_TOP)
WGM2_PWM_PC_OCR2A
#else
WGM2_PWM_PC
#endif
);
}
else wgm = WGM_PWM_PC_ICRn;
}
}
}
_SET_WGMnQ(timer.TCCRnQ, wgm);
_SET_CSn(timer.TCCRnQ, j);
if (timer.n == 2) {
#if ENABLED(USE_OCR2A_AS_TOP)
_SET_OCRnQ(timer.OCRnQ, 0, res); // Set OCR2A value (TOP) = res
#endif
}
else
_SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res
}
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
// If v is 0 or v_size (max), digitalWrite to LOW or HIGH.
// Note that digitalWrite also disables pwm output for us (sets COM bit to 0)
if (v == 0)
digitalWrite(pin, invert);
else if (v == v_size)
digitalWrite(pin, !invert);
else {
Timer timer = get_pwm_timer(pin);
if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
// Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted)
_SET_COMnQ(timer.TCCRnQ, (timer.q
#ifdef TCCR2
+ (timer.q == 2) // COM20 is on bit 4 of TCCR2, thus requires q + 1 in the macro
#endif
), COM_CLEAR_SET + invert
);
uint16_t top;
if (timer.n == 2) { // if TIMER2
top = (
#if ENABLED(USE_OCR2A_AS_TOP)
*timer.OCRnQ[0] // top = OCR2A
#else
255 // top = 0xFF (max)
#endif
);
}
else
top = *timer.ICRn; // top = ICRn
_SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top / v_size)); // Scale 8/16-bit v to top value
}
}
#endif // FAST_PWM_FAN
#endif // __AVR__
+6 -3
View File
@@ -24,9 +24,9 @@
/**
* Pin mapping for the 1280 and 2560
*
* Hardware Pin : 02 03 06 07 01 05 15 16 17 18 23 24 25 26 64 63 13 12 46 45 44 43 78 77 76 75 74 73 72 71 60 59 58 57 56 55 54 53 50 70 52 51 42 41 40 39 38 37 36 35 22 21 20 19 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 04 08 09 10 11 14 27 28 29 30 31 32 33 34 47 48 49 61 62 65 66 67 68 69 79 80 81 98 99 100
* Port : E0 E1 E4 E5 G5 E3 H3 H4 H5 H6 B4 B5 B6 B7 J1 J0 H1 H0 D3 D2 D1 D0 A0 A1 A2 A3 A4 A5 A6 A7 C7 C6 C5 C4 C3 C2 C1 C0 D7 G2 G1 G0 L7 L6 L5 L4 L3 L2 L1 L0 B3 B2 B1 B0 F0 F1 F2 F3 F4 F5 F6 F7 K0 K1 K2 K3 K4 K5 K6 K7 E2 E6 E7 xx xx H2 H7 G3 G4 xx xx xx xx xx D4 D5 D6 xx xx J2 J3 J4 J5 J6 J7 xx xx xx xx xx
* Logical Pin : 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
* Hardware Pin : 02 03 06 07 01 05 15 16 17 18 23 24 25 26 64 63 13 12 46 45 44 43 78 77 76 75 74 73 72 71 60 59 58 57 56 55 54 53 50 70 52 51 42 41 40 39 38 37 36 35 22 21 20 19 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 | 04 08 09 10 11 14 27 28 29 30 31 32 33 34 47 48 49 61 62 65 66 67 68 69 79 80 81 98 99 100
* Port : E0 E1 E4 E5 G5 E3 H3 H4 H5 H6 B4 B5 B6 B7 J1 J0 H1 H0 D3 D2 D1 D0 A0 A1 A2 A3 A4 A5 A6 A7 C7 C6 C5 C4 C3 C2 C1 C0 D7 G2 G1 G0 L7 L6 L5 L4 L3 L2 L1 L0 B3 B2 B1 B0 F0 F1 F2 F3 F4 F5 F6 F7 K0 K1 K2 K3 K4 K5 K6 K7 | E2 E6 E7 xx xx H2 H7 G3 G4 xx xx xx xx xx D4 D5 D6 xx xx J2 J3 J4 J5 J6 J7 xx xx xx xx xx
* Logical Pin : 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 78 79 80 xx xx 84 85 71 70 xx xx xx xx xx 81 82 83 xx xx 72 72 75 76 77 74 xx xx xx xx xx
*/
#include "fastio_AVR.h"
@@ -487,6 +487,9 @@
#define DIO69_DDR DDRK
#define DIO69_PWM NULL
//#define FASTIO_EXT_START 70
//#define FASTIO_EXT_END 85
#define DIO70_PIN PING4
#define DIO70_RPORT PING
#define DIO70_WPORT PORTG
+238
View File
@@ -0,0 +1,238 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Fast I/O for extended pins
*/
#ifdef __AVR__
#include "fastio_AVR.h"
#ifdef FASTIO_EXT_START
#include <Arduino.h>
#define _IS_EXT(P) WITHIN(P, FASTIO_EXT_START, FASTIO_EXT_END)
void extDigitalWrite(const int8_t pin, const uint8_t state) {
#define _WCASE(N) case N: WRITE(N, state); break
switch (pin) {
default: digitalWrite(pin, state);
#if _IS_EXT(70)
_WCASE(70);
#endif
#if _IS_EXT(71)
_WCASE(71);
#endif
#if _IS_EXT(72)
_WCASE(72);
#endif
#if _IS_EXT(73)
_WCASE(73);
#endif
#if _IS_EXT(74)
_WCASE(74);
#endif
#if _IS_EXT(75)
_WCASE(75);
#endif
#if _IS_EXT(76)
_WCASE(76);
#endif
#if _IS_EXT(77)
_WCASE(77);
#endif
#if _IS_EXT(78)
_WCASE(78);
#endif
#if _IS_EXT(79)
_WCASE(79);
#endif
#if _IS_EXT(80)
_WCASE(80);
#endif
#if _IS_EXT(81)
_WCASE(81);
#endif
#if _IS_EXT(82)
_WCASE(82);
#endif
#if _IS_EXT(83)
_WCASE(83);
#endif
#if _IS_EXT(84)
_WCASE(84);
#endif
#if _IS_EXT(85)
_WCASE(85);
#endif
#if _IS_EXT(86)
_WCASE(86);
#endif
#if _IS_EXT(87)
_WCASE(87);
#endif
#if _IS_EXT(88)
_WCASE(88);
#endif
#if _IS_EXT(89)
_WCASE(89);
#endif
#if _IS_EXT(90)
_WCASE(90);
#endif
#if _IS_EXT(91)
_WCASE(91);
#endif
#if _IS_EXT(92)
_WCASE(92);
#endif
#if _IS_EXT(93)
_WCASE(93);
#endif
#if _IS_EXT(94)
_WCASE(94);
#endif
#if _IS_EXT(95)
_WCASE(95);
#endif
#if _IS_EXT(96)
_WCASE(96);
#endif
#if _IS_EXT(97)
_WCASE(97);
#endif
#if _IS_EXT(98)
_WCASE(98);
#endif
#if _IS_EXT(99)
_WCASE(99);
#endif
#if _IS_EXT(100)
_WCASE(100);
#endif
}
}
uint8_t extDigitalRead(const int8_t pin) {
#define _RCASE(N) case N: return READ(N)
switch (pin) {
default: return digitalRead(pin);
#if _IS_EXT(70)
_RCASE(70);
#endif
#if _IS_EXT(71)
_RCASE(71);
#endif
#if _IS_EXT(72)
_RCASE(72);
#endif
#if _IS_EXT(73)
_RCASE(73);
#endif
#if _IS_EXT(74)
_RCASE(74);
#endif
#if _IS_EXT(75)
_RCASE(75);
#endif
#if _IS_EXT(76)
_RCASE(76);
#endif
#if _IS_EXT(77)
_RCASE(77);
#endif
#if _IS_EXT(78)
_RCASE(78);
#endif
#if _IS_EXT(79)
_RCASE(79);
#endif
#if _IS_EXT(80)
_RCASE(80);
#endif
#if _IS_EXT(81)
_RCASE(81);
#endif
#if _IS_EXT(82)
_RCASE(82);
#endif
#if _IS_EXT(83)
_RCASE(83);
#endif
#if _IS_EXT(84)
_RCASE(84);
#endif
#if _IS_EXT(85)
_RCASE(85);
#endif
#if _IS_EXT(86)
_RCASE(86);
#endif
#if _IS_EXT(87)
_RCASE(87);
#endif
#if _IS_EXT(88)
_RCASE(88);
#endif
#if _IS_EXT(89)
_RCASE(89);
#endif
#if _IS_EXT(90)
_RCASE(90);
#endif
#if _IS_EXT(91)
_RCASE(91);
#endif
#if _IS_EXT(92)
_RCASE(92);
#endif
#if _IS_EXT(93)
_RCASE(93);
#endif
#if _IS_EXT(94)
_RCASE(94);
#endif
#if _IS_EXT(95)
_RCASE(95);
#endif
#if _IS_EXT(96)
_RCASE(96);
#endif
#if _IS_EXT(97)
_RCASE(97);
#endif
#if _IS_EXT(98)
_RCASE(98);
#endif
#if _IS_EXT(99)
_RCASE(99);
#endif
#if _IS_EXT(100)
_RCASE(100);
#endif
}
}
#endif // FASTIO_EXT_START
#endif // __AVR__
+82 -37
View File
@@ -30,7 +30,7 @@
#include <avr/io.h>
#include "../../core/macros.h"
#define AVR_AT90USB1286_FAMILY (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__))
#define AVR_AT90USB1286_FAMILY (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__))
#define AVR_ATmega1284_FAMILY (defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__))
#define AVR_ATmega2560_FAMILY (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__))
#define AVR_ATmega2561_FAMILY (defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__))
@@ -81,9 +81,18 @@
#define _SET_INPUT(IO) CBI(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
#define _SET_OUTPUT(IO) SBI(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
#define _GET_INPUT(IO) !TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
#define _GET_OUTPUT(IO) TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
#define _GET_TIMER(IO) DIO ## IO ## _PWM
#define _IS_INPUT(IO) !TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
#define _IS_OUTPUT(IO) TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
#define _HAS_TIMER(IO) DIO ## IO ## _PWM
// digitalRead/Write wrappers
#ifdef FASTIO_EXT_START
void extDigitalWrite(const int8_t pin, const uint8_t state);
uint8_t extDigitalRead(const int8_t pin);
#else
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
#define extDigitalRead(IO) digitalRead(IO)
#endif
#define READ(IO) _READ(IO)
#define WRITE(IO,V) _WRITE(IO,V)
@@ -93,9 +102,11 @@
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0)
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
#define GET_INPUT(IO) _GET_INPUT(IO)
#define GET_OUTPUT(IO) _GET_OUTPUT(IO)
#define GET_TIMER(IO) _GET_TIMER(IO)
#define SET_PWM(IO) SET_OUTPUT(IO)
#define IS_INPUT(IO) _IS_INPUT(IO)
#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
#define HAS_TIMER(IO) _HAS_TIMER(IO)
#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
@@ -123,6 +134,18 @@ enum WaveGenMode : char {
WGM_FAST_PWM_OCRnA // 15 COM OCnA
};
// Wavefore Generation Modes (Timer 2 only)
enum WaveGenMode2 : char {
WGM2_NORMAL, // 0
WGM2_PWM_PC, // 1
WGM2_CTC_OCR2A, // 2
WGM2_FAST_PWM, // 3
WGM2_reserved_1, // 4
WGM2_PWM_PC_OCR2A, // 5
WGM2_reserved_2, // 6
WGM2_FAST_PWM_OCR2A, // 7
};
// Compare Modes
enum CompareMode : char {
COM_NORMAL, // 0
@@ -177,6 +200,11 @@ enum ClockSource2 : char {
TCCR##T##B = (TCCR##T##B & ~(0x3 << WGM##T##2)) | (((int(V) >> 2) & 0x3) << WGM##T##2); \
}while(0)
#define SET_WGM(T,V) _SET_WGM(T,WGM_##V)
// Runtime (see set_pwm_frequency):
#define _SET_WGMnQ(TCCRnQ, V) do{ \
*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \
*(TCCRnQ)[1] = (*(TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \
}while(0)
// Set Clock Select bits
// Ex: SET_CS3(PRESCALER_64);
@@ -202,6 +230,10 @@ enum ClockSource2 : char {
#define SET_CS4(V) _SET_CS4(CS_##V)
#define SET_CS5(V) _SET_CS5(CS_##V)
#define SET_CS(T,V) SET_CS##T(V)
// Runtime (see set_pwm_frequency)
#define _SET_CSn(TCCRnQ, V) do{ \
(*(TCCRnQ)[1] = (*(TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0)); \
}while(0)
// Set Compare Mode bits
// Ex: SET_COMS(4,CLEAR_SET,CLEAR_SET,CLEAR_SET);
@@ -211,6 +243,22 @@ enum ClockSource2 : char {
#define SET_COMB(T,V) SET_COM(T,B,V)
#define SET_COMC(T,V) SET_COM(T,C,V)
#define SET_COMS(T,V1,V2,V3) do{ SET_COMA(T,V1); SET_COMB(T,V2); SET_COMC(T,V3); }while(0)
// Runtime (see set_pwm_duty)
#define _SET_COMnQ(TCCRnQ, Q, V) do{ \
(*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q)))); \
}while(0)
// Set OCRnQ register
// Runtime (see set_pwm_duty):
#define _SET_OCRnQ(OCRnQ, Q, V) do{ \
(*(OCRnQ)[(Q)] = (0x0000) | (int(V) & 0xFFFF)); \
}while(0)
// Set ICRn register (one per timer)
// Runtime (see set_pwm_frequency)
#define _SET_ICRn(ICRn, V) do{ \
(*(ICRn) = (0x0000) | (int(V) & 0xFFFF)); \
}while(0)
// Set Noise Canceler bit
// Ex: SET_ICNC(2,1)
@@ -227,86 +275,83 @@ enum ClockSource2 : char {
#define SET_FOCB(T,V) SET_FOC(T,B,V)
#define SET_FOCC(T,V) SET_FOC(T,C,V)
/**
* PWM availability macros
*/
// Determine which harware PWMs are already in use
#if PIN_EXISTS(CONTROLLER_FAN)
#define PWM_CHK_FAN_B(p) (p == CONTROLLER_FAN_PIN || p == E0_AUTO_FAN_PIN || p == E1_AUTO_FAN_PIN || p == E2_AUTO_FAN_PIN || p == E3_AUTO_FAN_PIN || p == E4_AUTO_FAN_PIN || p == CHAMBER_AUTO_FAN_PIN)
#define PWM_CHK_FAN_B(P) (P == CONTROLLER_FAN_PIN || P == E0_AUTO_FAN_PIN || P == E1_AUTO_FAN_PIN || P == E2_AUTO_FAN_PIN || P == E3_AUTO_FAN_PIN || P == E4_AUTO_FAN_PIN || P == E5_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN)
#else
#define PWM_CHK_FAN_B(p) (p == E0_AUTO_FAN_PIN || p == E1_AUTO_FAN_PIN || p == E2_AUTO_FAN_PIN || p == E3_AUTO_FAN_PIN || p == E4_AUTO_FAN_PIN || p == CHAMBER_AUTO_FAN_PIN)
#define PWM_CHK_FAN_B(P) (P == E0_AUTO_FAN_PIN || P == E1_AUTO_FAN_PIN || P == E2_AUTO_FAN_PIN || P == E3_AUTO_FAN_PIN || P == E4_AUTO_FAN_PIN || P == E5_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN)
#endif
#if PIN_EXISTS(FAN) || PIN_EXISTS(FAN1) || PIN_EXISTS(FAN2)
#if ANY_PIN(FAN, FAN1, FAN2)
#if PIN_EXISTS(FAN2)
#define PWM_CHK_FAN_A(p) (p == FAN_PIN || p == FAN1_PIN || p == FAN2_PIN)
#define PWM_CHK_FAN_A(P) (P == FAN_PIN || P == FAN1_PIN || P == FAN2_PIN)
#elif PIN_EXISTS(FAN1)
#define PWM_CHK_FAN_A(p) (p == FAN_PIN || p == FAN1_PIN)
#define PWM_CHK_FAN_A(P) (P == FAN_PIN || P == FAN1_PIN)
#else
#define PWM_CHK_FAN_A(p) (p == FAN_PIN)
#define PWM_CHK_FAN_A(P) (P == FAN_PIN)
#endif
#else
#define PWM_CHK_FAN_A(p) false
#define PWM_CHK_FAN_A(P) false
#endif
#if HAS_MOTOR_CURRENT_PWM
#if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
#define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E || p == MOTOR_CURRENT_PWM_Z || p == MOTOR_CURRENT_PWM_XY)
#define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E || P == MOTOR_CURRENT_PWM_Z || P == MOTOR_CURRENT_PWM_XY)
#elif PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
#define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E || p == MOTOR_CURRENT_PWM_Z)
#define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E || P == MOTOR_CURRENT_PWM_Z)
#else
#define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E)
#define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E)
#endif
#else
#define PWM_CHK_MOTOR_CURRENT(p) false
#define PWM_CHK_MOTOR_CURRENT(P) false
#endif
#ifdef NUM_SERVOS
#if AVR_ATmega2560_FAMILY
#define PWM_CHK_SERVO(p) (p == 5 || (NUM_SERVOS > 12 && p == 6) || (NUM_SERVOS > 24 && p == 46)) // PWMS 3A, 4A & 5A
#define PWM_CHK_SERVO(P) (P == 5 || (NUM_SERVOS > 12 && P == 6) || (NUM_SERVOS > 24 && P == 46)) // PWMS 3A, 4A & 5A
#elif AVR_ATmega2561_FAMILY
#define PWM_CHK_SERVO(p) (p == 5) // PWM3A
#define PWM_CHK_SERVO(P) (P == 5) // PWM3A
#elif AVR_ATmega1284_FAMILY
#define PWM_CHK_SERVO(p) false
#define PWM_CHK_SERVO(P) false
#elif AVR_AT90USB1286_FAMILY
#define PWM_CHK_SERVO(p) (p == 16) // PWM3A
#define PWM_CHK_SERVO(P) (P == 16) // PWM3A
#elif AVR_ATmega328_FAMILY
#define PWM_CHK_SERVO(p) false
#define PWM_CHK_SERVO(P) false
#endif
#else
#define PWM_CHK_SERVO(p) false
#define PWM_CHK_SERVO(P) false
#endif
#if ENABLED(BARICUDA)
#if HAS_HEATER_1 && HAS_HEATER_2
#define PWM_CHK_HEATER(p) (p == HEATER_1_PIN || p == HEATER_2_PIN)
#define PWM_CHK_HEATER(P) (P == HEATER_1_PIN || P == HEATER_2_PIN)
#elif HAS_HEATER_1
#define PWM_CHK_HEATER(p) (p == HEATER_1_PIN)
#define PWM_CHK_HEATER(P) (P == HEATER_1_PIN)
#endif
#else
#define PWM_CHK_HEATER(p) false
#define PWM_CHK_HEATER(P) false
#endif
#define PWM_CHK(p) (PWM_CHK_HEATER(p) || PWM_CHK_SERVO(p) || PWM_CHK_MOTOR_CURRENT(p)\
|| PWM_CHK_FAN_A(p) || PWM_CHK_FAN_B(p))
#define PWM_CHK(P) (PWM_CHK_HEATER(P) || PWM_CHK_SERVO(P) || PWM_CHK_MOTOR_CURRENT(P) || PWM_CHK_FAN_A(P) || PWM_CHK_FAN_B(P))
// define which hardware PWMs are available for the current CPU
// all timer 1 PWMS deleted from this list because they are never available
#if AVR_ATmega2560_FAMILY
#define PWM_PINS(p) ((p >= 2 && p <= 10) || p == 13 || p == 44 || p == 45 || p == 46)
#define PWM_PIN(P) ((P >= 2 && P <= 10) || P == 13 || P == 44 || P == 45 || P == 46)
#elif AVR_ATmega2561_FAMILY
#define PWM_PINS(p) ((p >= 2 && p <= 6) || p == 9)
#define PWM_PIN(P) ((P >= 2 && P <= 6) || P == 9)
#elif AVR_ATmega1284_FAMILY
#define PWM_PINS(p) (p == 3 || p == 4 || p == 14 || p == 15)
#define PWM_PIN(P) (P == 3 || P == 4 || P == 14 || P == 15)
#elif AVR_AT90USB1286_FAMILY
#define PWM_PINS(p) (p == 0 || p == 1 || p == 14 || p == 15 || p == 16 || p == 24)
#define PWM_PIN(P) (P == 0 || P == 1 || P == 14 || P == 15 || P == 16 || P == 24)
#elif AVR_ATmega328_FAMILY
#define PWM_PINS(p) (p == 3 || p == 5 || p == 6 || p == 11)
#define PWM_PIN(P) (P == 3 || P == 5 || P == 6 || P == 11)
#else
#error "unknown CPU"
#endif
// finally - the macro that tells us if a pin is an available hardware PWM
#define USEABLE_HARDWARE_PWM(p) (PWM_PINS(p) && !PWM_CHK(p))
#define USEABLE_HARDWARE_PWM(P) (PWM_PIN(P) && !PWM_CHK(P))
@@ -23,7 +23,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(EEPROM_SETTINGS) || ENABLED(SD_FIRMWARE_UPDATE)
#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE)
#include "../shared/persistent_store_api.h"
@@ -105,7 +105,7 @@ const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
// digitalPinToBitMask(pin) is OK
#define digitalRead_mod(p) digitalRead(p) // Teensyduino's version of digitalRead doesn't
// disable the PWMs so we can use it as is
#define digitalRead_mod(p) extDigitalRead(p) // Teensyduino's version of digitalRead doesn't
// disable the PWMs so we can use it as is
// portModeRegister(pin) is OK
+2 -2
View File
@@ -73,14 +73,14 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t
*TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer
else {
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive)
digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
}
Channel[timer]++; // increment to the next channel
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
*OCRnA = *TCNTn + SERVO(timer, Channel[timer]).ticks;
if (SERVO(timer, Channel[timer]).Pin.isActive) // check if activated
digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
}
else {
// finished all channels so wait for the refresh period to expire before starting over
@@ -34,7 +34,7 @@
#include "../shared/persistent_store_api.h"
#include "../../inc/MarlinConfig.h"
#if ENABLED(EEPROM_SETTINGS) && DISABLED(I2C_EEPROM) && DISABLED(SPI_EEPROM)
#if ENABLED(EEPROM_SETTINGS) && DISABLED(I2C_EEPROM, SPI_EEPROM)
#include <Arduino.h>
@@ -997,5 +997,5 @@ void eeprom_flush(void) {
ee_Flush();
}
#endif // ENABLED(EEPROM_SETTINGS) && DISABLED(I2C_EEPROM) && DISABLED(SPI_EEPROM)
#endif // EEPROM_SETTINGS && (!I2C_EEPROM && !SPI_EEPROM)
#endif // ARDUINO_ARCH_AVR
+145
View File
@@ -0,0 +1,145 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* The PWM module is only used to generate interrupts at specified times. It
* is NOT used to directly toggle pins. The ISR writes to the pin assigned to
* that interrupt.
*
* All PWMs use the same repetition rate. The G2 needs about 10KHz min in order to
* not have obvious ripple on the Vref signals.
*
* The data structures are setup to minimize the computation done by the ISR which
* minimizes ISR execution time. Execution times are 0.8 to 1.1 microseconds.
*
* FIve PWM interrupt sources are used. Channel 0 sets the base period. All Vref
* signals are set active when this counter overflows and resets to zero. The compare
* values in channels 1-4 are set to give the desired duty cycle for that Vref pin.
* When counter 0 matches the compare value then that channel generates an interrupt.
* The ISR checks the source of the interrupt and sets the corresponding pin inactive.
*
* Some jitter in the Vref signal is OK so the interrupt priority is left at its default value.
*/
#include "../../inc/MarlinConfig.h"
#if MB(PRINTRBOARD_G2)
#include "G2_PWM.h"
volatile uint32_t *SODR_A = &PIOA->PIO_SODR,
*SODR_B = &PIOB->PIO_SODR,
*CODR_A = &PIOA->PIO_CODR,
*CODR_B = &PIOB->PIO_CODR;
PWM_map ISR_table[NUM_PWMS] = PWM_MAP_INIT;
void Stepper::digipot_init() {
OUT_WRITE(MOTOR_CURRENT_PWM_X_PIN, 0); // init pins
OUT_WRITE(MOTOR_CURRENT_PWM_Y_PIN, 0);
OUT_WRITE(MOTOR_CURRENT_PWM_Z_PIN, 0);
OUT_WRITE(MOTOR_CURRENT_PWM_E_PIN, 0);
#define WPKEY (0x50574D << 8) // “PWM” in ASCII
#define WPCMD_DIS_SW 0 // command to disable Write Protect SW
#define WPRG_ALL (PWM_WPCR_WPRG0 | PWM_WPCR_WPRG1 | PWM_WPCR_WPRG2 | PWM_WPCR_WPRG3 | PWM_WPCR_WPRG4 | PWM_WPCR_WPRG5) // all Write Protect Groups
#define PWM_CLOCK_F F_CPU / 1000000UL // set clock to 1MHz
PMC->PMC_PCER1 = PMC_PCER1_PID36; // enable PWM controller clock (disabled on power up)
PWM->PWM_WPCR = WPKEY | WPRG_ALL | WPCMD_DIS_SW; // enable setting of all PWM registers
PWM->PWM_CLK = PWM_CLOCK_F; // enable CLK_A and set it to 1MHz, leave CLK_B disabled
PWM->PWM_CH_NUM[0].PWM_CMR = 0b1011; // set channel 0 to Clock A input & to left aligned
PWM->PWM_CH_NUM[1].PWM_CMR = 0b1011; // set channel 1 to Clock A input & to left aligned
PWM->PWM_CH_NUM[2].PWM_CMR = 0b1011; // set channel 2 to Clock A input & to left aligned
PWM->PWM_CH_NUM[3].PWM_CMR = 0b1011; // set channel 3 to Clock A input & to left aligned
PWM->PWM_CH_NUM[4].PWM_CMR = 0b1011; // set channel 4 to Clock A input & to left aligned
PWM->PWM_CH_NUM[0].PWM_CPRD = PWM_PERIOD_US; // set channel 0 Period
PWM->PWM_IER2 = PWM_IER1_CHID0; // generate interrupt when counter0 overflows
PWM->PWM_IER2 = PWM_IER2_CMPM0 | PWM_IER2_CMPM1 | PWM_IER2_CMPM2 | PWM_IER2_CMPM3 | PWM_IER2_CMPM4; // generate interrupt on compare event
PWM->PWM_CMP[1].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 1 PWM inactive
PWM->PWM_CMP[2].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 2 PWM inactive
PWM->PWM_CMP[3].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[1])); // interrupt when counter0 == CMPV - used to set Motor 3 PWM inactive
PWM->PWM_CMP[4].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[2])); // interrupt when counter0 == CMPV - used to set Motor 4 PWM inactive
PWM->PWM_CMP[1].PWM_CMPM = 0x0001; // enable compare event
PWM->PWM_CMP[2].PWM_CMPM = 0x0001; // enable compare event
PWM->PWM_CMP[3].PWM_CMPM = 0x0001; // enable compare event
PWM->PWM_CMP[4].PWM_CMPM = 0x0001; // enable compare event
PWM->PWM_SCM = PWM_SCM_UPDM_MODE0 | PWM_SCM_SYNC0 | PWM_SCM_SYNC1 | PWM_SCM_SYNC2 | PWM_SCM_SYNC3 | PWM_SCM_SYNC4; // sync 1-4 with 0, use mode 0 for updates
PWM->PWM_ENA = PWM_ENA_CHID0 | PWM_ENA_CHID1 | PWM_ENA_CHID2 | PWM_ENA_CHID3 | PWM_ENA_CHID4; // enable the channels used by G2
PWM->PWM_IER1 = PWM_IER1_CHID0 | PWM_IER1_CHID1 | PWM_IER1_CHID2 | PWM_IER1_CHID3 | PWM_IER1_CHID4; // enable interrupts for the channels used by G2
NVIC_EnableIRQ(PWM_IRQn); // Enable interrupt handler
NVIC_SetPriority(PWM_IRQn, NVIC_EncodePriority(0, 10, 0)); // normal priority for PWM module (can stand some jitter on the Vref signals)
}
void Stepper::digipot_current(const uint8_t driver, const int16_t current) {
if (!(PWM->PWM_CH_NUM[0].PWM_CPRD == PWM_PERIOD_US)) digipot_init(); // Init PWM system if needed
switch (driver) {
case 0: PWM->PWM_CMP[1].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update X & Y
PWM->PWM_CMP[2].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current));
PWM->PWM_CMP[1].PWM_CMPMUPD = 0x0001; // enable compare event
PWM->PWM_CMP[2].PWM_CMPMUPD = 0x0001; // enable compare event
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
break;
case 1: PWM->PWM_CMP[3].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update Z
PWM->PWM_CMP[3].PWM_CMPMUPD = 0x0001; // enable compare event
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
break;
default:PWM->PWM_CMP[4].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update E
PWM->PWM_CMP[4].PWM_CMPMUPD = 0x0001; // enable compare event
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
break;
}
}
volatile uint32_t PWM_ISR1_STATUS, PWM_ISR2_STATUS;
void PWM_Handler() {
PWM_ISR1_STATUS = PWM->PWM_ISR1;
PWM_ISR2_STATUS = PWM->PWM_ISR2;
if (PWM_ISR1_STATUS & PWM_IER1_CHID0) { // CHAN_0 interrupt
*ISR_table[0].set_register = ISR_table[0].write_mask; // set X to active
*ISR_table[1].set_register = ISR_table[1].write_mask; // set Y to active
*ISR_table[2].set_register = ISR_table[2].write_mask; // set Z to active
*ISR_table[3].set_register = ISR_table[3].write_mask; // set E to active
}
else {
if (PWM_ISR2_STATUS & PWM_IER2_CMPM1) *ISR_table[0].clr_register = ISR_table[0].write_mask; // set X to inactive
if (PWM_ISR2_STATUS & PWM_IER2_CMPM2) *ISR_table[1].clr_register = ISR_table[1].write_mask; // set Y to inactive
if (PWM_ISR2_STATUS & PWM_IER2_CMPM3) *ISR_table[2].clr_register = ISR_table[2].write_mask; // set Z to inactive
if (PWM_ISR2_STATUS & PWM_IER2_CMPM4) *ISR_table[3].clr_register = ISR_table[3].write_mask; // set E to inactive
}
return;
}
#endif // PRINTRBOARD_G2
+77
View File
@@ -0,0 +1,77 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* This module is stripped down version of the LPC1768_PWM.h file from
* PR #7500. It is hardwired for the PRINTRBOARD_G2 Motor Current needs.
*/
#include "../../inc/MarlinConfigPre.h"
#include "../../module/stepper.h"
//C:\Users\bobku\Documents\GitHub\Marlin-Bob-2\Marlin\src\module\stepper.h
//C:\Users\bobku\Documents\GitHub\Marlin-Bob-2\Marlin\src\HAL\HAL_DUE\G2_PWM.h
#define PWM_PERIOD_US 100 // base repetition rate in micro seconds
typedef struct { // holds the data needed by the ISR to control the Vref pin
volatile uint32_t* set_register;
volatile uint32_t* clr_register;
uint32_t write_mask;
} PWM_map;
#define G2_VREF(I) (uint32_t)(I * 5 * 0.15) // desired Vref * 1000 (scaled so don't loose accuracy in next step)
#define G2_VREF_COUNT(Q) (uint32_t)map(constrain(Q, 500, 3.3 * 1000), 0, 3.3 * 1000, 0, PWM_PERIOD_US) // under 500 the results are very non-linear
extern volatile uint32_t *SODR_A, *SODR_B, *CODR_A, *CODR_B;
#define _PIN(IO) (DIO ## IO ## _PIN)
#define PWM_MAP_INIT_ROW(IO,ZZ) { ZZ == 'A' ? SODR_A : SODR_B, ZZ == 'A' ? CODR_A : CODR_B, 1 << _PIN(IO) }
#define PWM_MAP_INIT { PWM_MAP_INIT_ROW(MOTOR_CURRENT_PWM_X_PIN, 'B'), \
PWM_MAP_INIT_ROW(MOTOR_CURRENT_PWM_Y_PIN, 'B'), \
PWM_MAP_INIT_ROW(MOTOR_CURRENT_PWM_Z_PIN, 'B'), \
PWM_MAP_INIT_ROW(MOTOR_CURRENT_PWM_E_PIN, 'A'), \
};
#define NUM_PWMS 4
extern PWM_map ISR_table[NUM_PWMS];
extern uint32_t motor_current_setting[3];
#define IR_BIT(p) (WITHIN(p, 0, 3) ? (p) : (p) + 4)
#define COPY_ACTIVE_TABLE() do{ for (uint8_t i = 0; i < 6 ; i++) work_table[i] = active_table[i]; }while(0)
#define PWM_MR0 19999 // base repetition rate minus one count - 20mS
#define PWM_PR 24 // prescaler value - prescaler divide by 24 + 1 - 1 MHz output
#define PWM_PCLKSEL0 0x00 // select clock source for prescaler - defaults to 25MHz on power up
// 0: 25MHz, 1: 100MHz, 2: 50MHz, 3: 12.5MHZ to PWM1 prescaler
#define MR0_MARGIN 200 // if channel value too close to MR0 the system locks up
extern bool PWM_table_swap; // flag to tell the ISR that the tables have been swapped
#define HAL_G2_PWM_ISR void PWM_Handler()
extern volatile uint32_t PWM_ISR1_STATUS, PWM_ISR2_STATUS;
+278
View File
@@ -0,0 +1,278 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stdint.h>
/**
* This file contains the custom port/pin definitions for the PRINTRBOARD_G2
* motherboard. This motherboard uses the SAM3X8C which is a subset of the
* SAM3X8E used in the DUE board. It uses port/pin pairs that are not
* available using the DUE definitions.
*
* The first part is a copy of the pin descriptions in the
* "variants\arduino_due_x\variant.cpp" file but with pins 34-41 replaced by
* the G2 pins.
*
* The second part is the FASTIO port/pin definitions.
*
* THESE PINS CAN ONLY BE ACCESSED VIA FASTIO COMMANDS.
*/
/*
Copyright (c) 2011 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
typedef struct _G2_PinDescription {
Pio* pPort;
uint32_t ulPin;
uint32_t ulPeripheralId;
EPioType ulPinType;
uint32_t ulPinConfiguration;
uint32_t ulPinAttribute;
EAnalogChannel ulAnalogChannel; /* Analog pin in the Arduino context (label on the board) */
EAnalogChannel ulADCChannelNumber; /* ADC Channel number in the SAM device */
EPWMChannel ulPWMChannel;
ETCChannel ulTCChannel;
} G2_PinDescription;
/**
* This section is a copy of the pin descriptions in the "variants\arduino_due_x\variant.cpp" file
* with pins 34-41 replaced by the G2 pins.
*/
/**
* Pins descriptions
*/
const G2_PinDescription G2_g_APinDescription[] = {
// 0 .. 53 - Digital pins
// ----------------------
// 0/1 - UART (Serial)
{ PIOA, PIO_PA8A_URXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // URXD
{ PIOA, PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // UTXD
// 2
{ PIOB, PIO_PB25B_TIOA0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHA0 }, // TIOA0
{ PIOC, PIO_PC28B_TIOA7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA7 }, // TIOA7
{ PIOC, PIO_PC26B_TIOB6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB6 }, // TIOB6
// 5
{ PIOC, PIO_PC25B_TIOA6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA6 }, // TIOA6
{ PIOC, PIO_PC24B_PWML7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH7, NOT_ON_TIMER }, // PWML7
{ PIOC, PIO_PC23B_PWML6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH6, NOT_ON_TIMER }, // PWML6
{ PIOC, PIO_PC22B_PWML5, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH5, NOT_ON_TIMER }, // PWML5
{ PIOC, PIO_PC21B_PWML4, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH4, NOT_ON_TIMER }, // PWML4
// 10
{ PIOC, PIO_PC29B_TIOB7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB7 }, // TIOB7
{ PIOD, PIO_PD7B_TIOA8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA8 }, // TIOA8
{ PIOD, PIO_PD8B_TIOB8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB8 }, // TIOB8
// 13 - AMBER LED
{ PIOB, PIO_PB27B_TIOB0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHB0 }, // TIOB0
// 14/15 - USART3 (Serial3)
{ PIOD, PIO_PD4B_TXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD3
{ PIOD, PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD3
// 16/17 - USART1 (Serial2)
{ PIOA, PIO_PA13A_TXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD1
{ PIOA, PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD1
// 18/19 - USART0 (Serial1)
{ PIOA, PIO_PA11A_TXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD0
{ PIOA, PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD0
// 20/21 - TWI1
{ PIOB, PIO_PB12A_TWD1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD1 - SDA0
{ PIOB, PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK1 - SCL0
// 22
{ PIOB, PIO_PB26, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 22
{ PIOA, PIO_PA14, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 23
{ PIOA, PIO_PA15, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 24
{ PIOD, PIO_PD0, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 25
// 26
{ PIOD, PIO_PD1, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 26
{ PIOD, PIO_PD2, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 27
{ PIOD, PIO_PD3, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 28
{ PIOD, PIO_PD6, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 29
// 30
{ PIOD, PIO_PD9, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 30
{ PIOA, PIO_PA7, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 31
{ PIOD, PIO_PD10, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 32
{ PIOC, PIO_PC1, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 33
// 34
// start of custom pins
{ PIOA, PIO_PA29, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 34 Y_STEP_PIN
{ PIOB, PIO_PB1, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 35 Y_DIR_PIN
{ PIOB, PIO_PB0, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 36 Y_ENABLE_PIN
{ PIOB, PIO_PB22, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 37 E0_ENABLE_PIN
{ PIOB, PIO_PB11, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 38 E0_MS1_PIN
{ PIOB, PIO_PB10, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 39 E0_MS3_PIN
{ PIOA, PIO_PA5, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 40 HEATER_0_PIN
{ PIOB, PIO_PB24, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 41 HEATER_BED_PIN
// end of custom pins
// 42
{ PIOA, PIO_PA19, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 42
{ PIOA, PIO_PA20, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 43
{ PIOC, PIO_PC19, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 44
{ PIOC, PIO_PC18, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 45
// 46
{ PIOC, PIO_PC17, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 46
{ PIOC, PIO_PC16, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 47
{ PIOC, PIO_PC15, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 48
{ PIOC, PIO_PC14, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 49
// 50
{ PIOC, PIO_PC13, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 50
{ PIOC, PIO_PC12, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 51
{ PIOB, PIO_PB21, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 52
{ PIOB, PIO_PB14, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 53
// 54 .. 65 - Analog pins
// ----------------------
{ PIOA, PIO_PA16X1_AD7, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC7, NOT_ON_PWM, NOT_ON_TIMER }, // AD0
{ PIOA, PIO_PA24X1_AD6, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC1, ADC6, NOT_ON_PWM, NOT_ON_TIMER }, // AD1
{ PIOA, PIO_PA23X1_AD5, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC2, ADC5, NOT_ON_PWM, NOT_ON_TIMER }, // AD2
{ PIOA, PIO_PA22X1_AD4, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC3, ADC4, NOT_ON_PWM, NOT_ON_TIMER }, // AD3
// 58
{ PIOA, PIO_PA6X1_AD3, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC4, ADC3, NOT_ON_PWM, TC0_CHB2 }, // AD4
{ PIOA, PIO_PA4X1_AD2, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC5, ADC2, NOT_ON_PWM, NOT_ON_TIMER }, // AD5
{ PIOA, PIO_PA3X1_AD1, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC6, ADC1, NOT_ON_PWM, TC0_CHB1 }, // AD6
{ PIOA, PIO_PA2X1_AD0, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC7, ADC0, NOT_ON_PWM, TC0_CHA1 }, // AD7
// 62
{ PIOB, PIO_PB17X1_AD10, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC8, ADC10, NOT_ON_PWM, NOT_ON_TIMER }, // AD8
{ PIOB, PIO_PB18X1_AD11, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC9, ADC11, NOT_ON_PWM, NOT_ON_TIMER }, // AD9
{ PIOB, PIO_PB19X1_AD12, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC10, ADC12, NOT_ON_PWM, NOT_ON_TIMER }, // AD10
{ PIOB, PIO_PB20X1_AD13, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC11, ADC13, NOT_ON_PWM, NOT_ON_TIMER }, // AD11
// 66/67 - DAC0/DAC1
{ PIOB, PIO_PB15X1_DAC0, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC12, DA0, NOT_ON_PWM, NOT_ON_TIMER }, // DAC0
{ PIOB, PIO_PB16X1_DAC1, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC13, DA1, NOT_ON_PWM, NOT_ON_TIMER }, // DAC1
// 68/69 - CANRX0/CANTX0
{ PIOA, PIO_PA1A_CANRX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC14, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX
{ PIOA, PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC15, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX
// 70/71 - TWI0
{ PIOA, PIO_PA17A_TWD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD0 - SDA1
{ PIOA, PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK0 - SCL1
// 72/73 - LEDs
{ PIOC, PIO_PC30, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER RXL
{ PIOA, PIO_PA21, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER TXL
// 74/75/76 - SPI
{ PIOA, PIO_PA25A_SPI0_MISO,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MISO
{ PIOA, PIO_PA26A_SPI0_MOSI,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI
{ PIOA, PIO_PA27A_SPI0_SPCK,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // SPCK
// 77 - SPI CS0
{ PIOA, PIO_PA28A_SPI0_NPCS0,ID_PIOA,PIO_PERIPH_A,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS0
// 78 - SPI CS3 (unconnected)
{ PIOB, PIO_PB23B_SPI0_NPCS3,ID_PIOB,PIO_PERIPH_B,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS3
// 79 .. 84 - "All pins" masks
// 79 - TWI0 all pins
{ PIOA, PIO_PA17A_TWD0|PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
// 80 - TWI1 all pins
{ PIOB, PIO_PB12A_TWD1|PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
// 81 - UART (Serial) all pins
{ PIOA, PIO_PA8A_URXD|PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
// 82 - USART0 (Serial1) all pins
{ PIOA, PIO_PA11A_TXD0|PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
// 83 - USART1 (Serial2) all pins
{ PIOA, PIO_PA13A_TXD1|PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
// 84 - USART3 (Serial3) all pins
{ PIOD, PIO_PD4B_TXD3|PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
// 85 - USB
{ PIOB, PIO_PB11A_UOTGID|PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF
// 86 - SPI CS2
{ PIOB, PIO_PB21B_SPI0_NPCS2, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS2
// 87 - SPI CS1
{ PIOA, PIO_PA29A_SPI0_NPCS1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS1
// 88/89 - CANRX1/CANTX1 (same physical pin for 66/53)
{ PIOB, PIO_PB15A_CANRX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX1
{ PIOB, PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX1
// 90 .. 91 - "All CAN pins" masks
// 90 - CAN0 all pins
{ PIOA, PIO_PA1A_CANRX0|PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
// 91 - CAN1 all pins
{ PIOB, PIO_PB15A_CANRX1|PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
// END
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }
};
// This section replaces the FASTIO definitions of pins 34-41
#define DIO34_PIN 29
#define DIO34_WPORT PIOA // only available via FASTIO // 34 PA29 - Y_STEP_PIN
#define DIO35_PIN 1
#define DIO35_WPORT PIOB // only available via FASTIO // 35 PAB1 - Y_DIR_PIN
#define DIO36_PIN 0
#define DIO36_WPORT PIOB // only available via FASTIO // 36 PB0 - Y_ENABLE_PIN
#define DIO37_PIN 22
#define DIO37_WPORT PIOB // only available via FASTIO // 37 PB22 - E0_ENABLE_PIN
#define DIO38_PIN 11
#define DIO38_WPORT PIOB // only available via FASTIO // 38 PB11 - E0_MS1_PIN
#define DIO39_PIN 10
#define DIO39_WPORT PIOB // only available via FASTIO // 39 PB10 - E0_MS3_PIN
#define DIO40_PIN 5
#define DIO40_WPORT PIOA // only available via FASTIO // 40 PA5 - HEATER_0_PIN
#define DIO41_PIN 24
#define DIO41_WPORT PIOB // only available via FASTIO // 41 PB24 - HEATER_BED_PIN
-2
View File
@@ -112,10 +112,8 @@ uint8_t HAL_get_reset_source(void); // get reset reason
// Write single byte to specified SPI channel
void spiSend(uint32_t chan, byte b);
// Write buffer to specified SPI channel
void spiSend(uint32_t chan, const uint8_t* buf, size_t n);
// Read single byte from specified SPI channel
uint8_t spiRec(uint32_t chan);
+17 -17
View File
@@ -656,8 +656,8 @@
// Read from SPI into buffer
void spiRead(uint8_t* buf, uint16_t nbyte) {
if (nbyte-- == 0) return;
if (!nbyte) return;
--nbyte;
for (int i = 0; i < nbyte; i++) {
//WHILE_TX(0);
SPI0->SPI_TDR = 0x000000FF | SPI_PCS(SPI_CHAN);
@@ -669,7 +669,7 @@
}
// Write single byte to SPI
void spiSend(byte b) {
void spiSend(const byte b) {
// write byte with address and end transmission flag
SPI0->SPI_TDR = (uint32_t)b | SPI_PCS(SPI_CHAN) | SPI_TDR_LASTXFER;
WHILE_TX(0);
@@ -678,16 +678,17 @@
//DELAY_US(1U);
}
void spiSend(const uint8_t* buf, size_t n) {
if (n == 0) return;
for (size_t i = 0; i < n - 1; i++) {
void spiSend(const uint8_t* buf, size_t nbyte) {
if (!nbyte) return;
--nbyte;
for (size_t i = 0; i < nbyte; i++) {
SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(SPI_CHAN);
WHILE_TX(0);
WHILE_RX(0);
SPI0->SPI_RDR;
//DELAY_US(1U);
}
spiSend(buf[n - 1]);
spiSend(buf[nbyte]);
}
void spiSend(uint32_t chan, byte b) {
@@ -698,15 +699,16 @@
FLUSH_RX();
}
void spiSend(uint32_t chan, const uint8_t* buf, size_t n) {
if (n == 0) return;
for (int i = 0; i < (int)n - 1; i++) {
void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {
if (!nbyte) return;
--nbyte;
for (size_t i = 0; i < nbyte; i++) {
WHILE_TX(0);
SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(chan);
WHILE_RX(0);
FLUSH_RX();
}
spiSend(chan, buf[n - 1]);
spiSend(chan, buf[nbyte]);
}
// Write from buffer to SPI
@@ -775,17 +777,15 @@
uint8_t spiRec() { return (uint8_t)spiTransfer(0xFF); }
void spiRead(uint8_t* buf, uint16_t nbyte) {
if (nbyte)
for (int i = 0; i < nbyte; i++)
buf[i] = spiTransfer(0xFF);
for (int i = 0; i < nbyte; i++)
buf[i] = spiTransfer(0xFF);
}
void spiSend(uint8_t data) { spiTransfer(data); }
void spiSend(const uint8_t* buf, size_t nbyte) {
if (nbyte)
for (uint16_t i = 0; i < nbyte; i++)
spiTransfer(buf[i]);
for (uint16_t i = 0; i < nbyte; i++)
spiTransfer(buf[i]);
}
void spiSendBlock(uint8_t token, const uint8_t* buf) {
+2 -2
View File
@@ -63,8 +63,8 @@
const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
{ TC0, 0, TC0_IRQn, 3}, // 0 - [servo timer5]
{ TC0, 1, TC1_IRQn, 0}, // 1
{ TC0, 2, TC2_IRQn, 0}, // 2
{ TC1, 0, TC3_IRQn, 2}, // 3 - stepper
{ TC0, 2, TC2_IRQn, 2}, // 2 - stepper
{ TC1, 0, TC3_IRQn, 0}, // 3
{ TC1, 1, TC4_IRQn, 15}, // 4 - temperature
{ TC1, 2, TC5_IRQn, 3}, // 5 - [servo timer3]
{ TC2, 0, TC6_IRQn, 14}, // 6 - tone
+4 -4
View File
@@ -43,7 +43,7 @@ typedef uint32_t hal_timer_t;
#define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals
#define STEP_TIMER_NUM 3 // index of timer to use for stepper
#define STEP_TIMER_NUM 2 // index of timer to use for stepper
#define TEMP_TIMER_NUM 4 // index of timer to use for temperature
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define TONE_TIMER_NUM 6 // index of timer to use for beeper tones
@@ -65,9 +65,9 @@ typedef uint32_t hal_timer_t;
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define HAL_STEP_TIMER_ISR void TC3_Handler()
#define HAL_TEMP_TIMER_ISR void TC4_Handler()
#define HAL_TONE_TIMER_ISR void TC6_Handler()
#define HAL_STEP_TIMER_ISR() void TC2_Handler()
#define HAL_TEMP_TIMER_ISR() void TC4_Handler()
#define HAL_TONE_TIMER_ISR() void TC6_Handler()
// --------------------------------------------------------------------------
// Types
@@ -114,8 +114,8 @@ bool MarlinSerialUSB::available(void) {
(usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
}
void MarlinSerialUSB::flush(void) {
}
void MarlinSerialUSB::flush(void) { }
void MarlinSerialUSB::flushTX(void) { }
void MarlinSerialUSB::write(const uint8_t c) {
@@ -46,6 +46,7 @@ public:
static int peek(void);
static int read(void);
static void flush(void);
static void flushTX(void);
static bool available(void);
static void write(const uint8_t c);
+4
View File
@@ -50,3 +50,7 @@
#error "DUE software SPI is required but is incompatible with TMC2130 hardware SPI. Enable TMC_USE_SW_SPI to fix."
#endif
#endif
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
+2 -2
View File
@@ -77,13 +77,13 @@ void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel) {
if (Channel[timer] < 0)
tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // channel set to -1 indicated that refresh interval completed so reset the timer
else if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive)
digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
Channel[timer]++; // increment to the next channel
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer,Channel[timer]).ticks;
if (SERVO(timer,Channel[timer]).Pin.isActive) // check if activated
digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // its an active channel so pulse it high
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // its an active channel so pulse it high
}
else {
// finished all channels so wait for the refresh period to expire before starting over
+3 -3
View File
@@ -42,16 +42,16 @@ void tone(const pin_t _pin, const unsigned int frequency, const unsigned long du
void noTone(const pin_t _pin) {
HAL_timer_disable_interrupt(TONE_TIMER_NUM);
digitalWrite(_pin, LOW);
extDigitalWrite(_pin, LOW);
}
HAL_TONE_TIMER_ISR {
HAL_TONE_TIMER_ISR() {
static uint8_t pin_state = 0;
HAL_timer_isr_prologue(TONE_TIMER_NUM);
if (toggles) {
toggles--;
digitalWrite(tone_pin, (pin_state ^= 1));
extDigitalWrite(tone_pin, (pin_state ^= 1));
}
else noTone(tone_pin); // turn off interrupt
}
+117 -43
View File
@@ -45,7 +45,8 @@
// Due has 12 PWMs assigned to logical pins 2-13.
// 6, 7, 8 & 9 come from the PWM controller. The others come from the timers.
#define USEABLE_HARDWARE_PWM(p) WITHIN(p, 2, 13)
#define PWM_PIN(P) WITHIN(P, 2, 13)
#define USEABLE_HARDWARE_PWM(P) PWM_PIN(P)
#ifndef MASK
#define MASK(PIN) (1 << PIN)
@@ -65,7 +66,7 @@
// Write to a pin
#define _WRITE_VAR(IO,V) do { \
volatile Pio* port = digitalPinToPort(IO); \
uint32_t mask = digitalPinToBitMask(IO); \
const uint32_t mask = digitalPinToBitMask(IO); \
if (V) port->PIO_SODR = mask; \
else port->PIO_CODR = mask; \
} while(0)
@@ -73,7 +74,7 @@
// Write to a pin
#define _WRITE(IO,V) do { \
volatile Pio* port = (DIO ## IO ## _WPORT); \
uint32_t mask = MASK(DIO ## IO ## _PIN); \
const uint32_t mask = MASK(DIO ## IO ## _PIN); \
if (V) port->PIO_SODR = mask; \
else port->PIO_CODR = mask; \
} while(0)
@@ -81,48 +82,113 @@
// Toggle a pin
#define _TOGGLE(IO) _WRITE(IO, !READ(IO))
// Set pin as input
#define _SET_INPUT(IO) do{ \
pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
PIO_Configure(digitalPinToPort(IO), PIO_INPUT, digitalPinToBitMask(IO), 0); \
}while(0)
#if MB(PRINTRBOARD_G2)
// Set pin as output
#define _SET_OUTPUT(IO) do{ \
pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
PIO_Configure(digitalPinToPort(IO), _READ(IO) ? PIO_OUTPUT_1 : PIO_OUTPUT_0, digitalPinToBitMask(IO), g_APinDescription[IO].ulPinConfiguration); \
g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT;\
}while(0)
#include "G2_pins.h"
// Set pin as input
#define _SET_INPUT(IO) do{ \
pmc_enable_periph_clk(G2_g_APinDescription[IO].ulPeripheralId); \
PIO_Configure((DIO ## IO ## _WPORT), PIO_INPUT, MASK(DIO ## IO ## _PIN), 0); \
}while(0)
// Set pin as output
#define _SET_OUTPUT(IO) do{ \
uint32_t mask = MASK(G2_g_APinDescription[IO].ulPeripheralId); \
if ((PMC->PMC_PCSR0 & mask) != (mask)) PMC->PMC_PCER0 = mask; \
volatile Pio* port = (DIO ## IO ## _WPORT); \
mask = MASK(DIO ## IO ## _PIN); \
if (_READ(IO)) port->PIO_SODR = mask; \
else port->PIO_CODR = mask; \
port->PIO_IDR = mask; \
const uint32_t pin_config = G2_g_APinDescription[IO].ulPinConfiguration; \
if (pin_config & PIO_PULLUP) port->PIO_PUER = mask; \
else port->PIO_PUDR = mask; \
if (pin_config & PIO_OPENDRAIN) port->PIO_MDER = mask; \
else port->PIO_MDDR = mask; \
port->PIO_PER = mask; \
port->PIO_OER = mask; \
g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \
}while(0)
/**
* Set pin as output with comments
* #define _SET_OUTPUT(IO) do{ \
* uint32_t mask = MASK(G2_g_APinDescription[IO].ulPeripheralId); \
* if ((PMC->PMC_PCSR0 & mask ) != (mask)) PMC->PMC_PCER0 = mask; \ // enable PIO clock if not already enabled
*
* volatile Pio* port = (DIO ## IO ## _WPORT); \
* const uint32_t mask = MASK(DIO ## IO ## _PIN); \
* if (_READ(IO)) port->PIO_SODR = mask; \ // set output to match input BEFORE setting direction or will glitch the output
* else port->PIO_CODR = mask; \
*
* port->PIO_IDR = mask; \ // disable interrupt
*
* uint32_t pin_config = G2_g_APinDescription[IO].ulPinConfiguration; \
* if (pin_config & PIO_PULLUP) pPio->PIO_PUER = mask; \ // enable pullup if necessary
* else pPio->PIO_PUDR = mask; \
*
* if (pin_config & PIO_OPENDRAIN) port->PIO_MDER = mask; \ // Enable multi-drive if necessary
* else port->PIO_MDDR = mask; \
*
* port->PIO_PER = mask; \
* port->PIO_OER = mask; \ // set to output
*
* g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \
* }while(0)
*/
#else
// Set pin as input
#define _SET_INPUT(IO) do{ \
pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
PIO_Configure(digitalPinToPort(IO), PIO_INPUT, digitalPinToBitMask(IO), 0); \
}while(0)
// Set pin as output
#define _SET_OUTPUT(IO) do{ \
pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
PIO_Configure(digitalPinToPort(IO), _READ(IO) ? PIO_OUTPUT_1 : PIO_OUTPUT_0, digitalPinToBitMask(IO), g_APinDescription[IO].ulPinConfiguration); \
g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \
}while(0)
#endif
// Set pin as input with pullup mode
#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT)
#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT)
// Read a pin (wrapper)
#define READ(IO) _READ(IO)
#define READ(IO) _READ(IO)
// Write to a pin (wrapper)
#define WRITE_VAR(IO,V) _WRITE_VAR(IO,V)
#define WRITE(IO,V) _WRITE(IO,V)
#define WRITE_VAR(IO,V) _WRITE_VAR(IO,V)
#define WRITE(IO,V) _WRITE(IO,V)
// Toggle a pin (wrapper)
#define TOGGLE(IO) _TOGGLE(IO)
#define TOGGLE(IO) _TOGGLE(IO)
// Set pin as input (wrapper)
#define SET_INPUT(IO) _SET_INPUT(IO)
#define SET_INPUT(IO) _SET_INPUT(IO)
// Set pin as input with pullup (wrapper)
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
// Set pin as output (wrapper) - reads the pin and sets the output to that value
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
// Set pin as PWM
#define SET_PWM(IO) SET_OUTPUT(IO)
// Check if pin is an input
#define GET_INPUT(IO) !(digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO))
#define IS_INPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) == 0)
// Check if pin is an output
#define GET_OUTPUT(IO) !!(digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO))
#define IS_OUTPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) != 0)
// Check if pin is a timer - Must be a constexpr
#define GET_TIMER(IO) ((IO) >= 2 && (IO) <= 13)
#define HAS_TIMER(IO) ((IO) >= 2 && (IO) <= 13)
// Shorthand
#define OUT_WRITE(IO,V) { SET_OUTPUT(IO); WRITE(IO,V); }
#define OUT_WRITE(IO,V) { SET_OUTPUT(IO); WRITE(IO,V); }
// digitalRead/Write wrappers
#define extDigitalRead(IO) digitalRead(IO)
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
/**
* Ports and functions
@@ -243,29 +309,33 @@
#define DIO33_PIN 1
#define DIO33_WPORT PIOC
#define DIO34_PIN 2
#define DIO34_WPORT PIOC
#if !MB(PRINTRBOARD_G2) // normal DUE pin mapping
#define DIO35_PIN 3
#define DIO35_WPORT PIOC
#define DIO34_PIN 2
#define DIO34_WPORT PIOC
#define DIO36_PIN 4
#define DIO36_WPORT PIOC
#define DIO35_PIN 3
#define DIO35_WPORT PIOC
#define DIO37_PIN 5
#define DIO37_WPORT PIOC
#define DIO36_PIN 4
#define DIO36_WPORT PIOC
#define DIO38_PIN 6
#define DIO38_WPORT PIOC
#define DIO37_PIN 5
#define DIO37_WPORT PIOC
#define DIO39_PIN 7
#define DIO39_WPORT PIOC
#define DIO38_PIN 6
#define DIO38_WPORT PIOC
#define DIO40_PIN 8
#define DIO40_WPORT PIOC
#define DIO39_PIN 7
#define DIO39_WPORT PIOC
#define DIO41_PIN 9
#define DIO41_WPORT PIOC
#define DIO40_PIN 8
#define DIO40_WPORT PIOC
#define DIO41_PIN 9
#define DIO41_WPORT PIOC
#endif // !PRINTRBOARD_G2
#define DIO42_PIN 19
#define DIO42_WPORT PIOA
@@ -418,6 +488,7 @@
#define DIO91_WPORT PIOB
#if ARDUINO_SAM_ARCHIM
#define DIO92_PIN 11
#define DIO92_WPORT PIOC
@@ -468,7 +539,9 @@
#define DIO108_PIN 9
#define DIO108_WPORT PIOB
#else
#else // !ARDUINO_SAM_ARCHIM
#define DIO92_PIN 5
#define DIO92_WPORT PIOA
@@ -495,4 +568,5 @@
#define DIO100_PIN 11
#define DIO100_WPORT PIOC
#endif
#endif // !ARDUINO_SAM_ARCHIM
@@ -29,7 +29,7 @@
#include "../../inc/MarlinConfig.h"
#include "../shared/persistent_store_api.h"
#if DISABLED(I2C_EEPROM) && DISABLED(SPI_EEPROM)
#if DISABLED(I2C_EEPROM, SPI_EEPROM)
#define E2END 0xFFF // Default to Flash emulated EEPROM size (EepromEmulation_Due.cpp)
#endif
@@ -38,7 +38,7 @@ extern void eeprom_flush(void);
bool PersistentStore::access_start() { return true; }
bool PersistentStore::access_finish() {
#if DISABLED(I2C_EEPROM) && DISABLED(SPI_EEPROM)
#if DISABLED(I2C_EEPROM, SPI_EEPROM)
eeprom_flush();
#endif
return true;
@@ -52,6 +52,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
// so only write bytes that have changed!
if (v != eeprom_read_byte(p)) {
eeprom_write_byte(p, v);
delay(2);
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_MSG(MSG_ERR_EEPROM_WRITE);
return true;
+2 -5
View File
@@ -63,12 +63,13 @@
#define NUMBER_PINS_TOTAL PINS_COUNT
#define digitalRead_mod(p) digitalRead(p) // AVR digitalRead disabled PWM before it read the pin
#define digitalRead_mod(p) extDigitalRead(p) // AVR digitalRead disabled PWM before it read the pin
#define PRINT_PORT(p)
#define NAME_FORMAT(p) PSTR("%-##p##s")
#define PRINT_ARRAY_NAME(x) do {sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer);} while (0)
#define PRINT_PIN(p) do {sprintf_P(buffer, PSTR("%02d"), p); SERIAL_ECHO(buffer);} while (0)
#define GET_ARRAY_PIN(p) pin_array[p].pin
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL ? 1 : 0)
#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0))
#define IS_ANALOG(P) WITHIN(P, char(analogInputToDigitalPin(0)), char(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1)))
@@ -85,10 +86,6 @@ bool GET_PINMODE(int8_t pin) { // 1: output, 0: input
|| pwm_status(pin));
}
bool GET_ARRAY_IS_DIGITAL(int8_t pin) {
uint8_t pin_status = g_pinStatus[pin] & 0xF;
return !(pin_status == PIN_STATUS_ANALOG);
}
void pwm_details(int32_t pin) {
if (pwm_status(pin)) {
@@ -65,9 +65,12 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
return CTRL_NO_PRESENT;
#ifdef DEBUG_MMC
{
char buffer[80];
sprintf_P(buffer, PSTR("SDRD: %d @ 0x%08x\n"), nb_sector, addr);
SERIAL_ECHO_P(0, buffer);
PORT_REDIRECT(0);
SERIAL_ECHO(buffer);
}
#endif
// Start reading
@@ -99,9 +102,12 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
return CTRL_NO_PRESENT;
#ifdef DEBUG_MMC
{
char buffer[80];
sprintf_P(buffer, PSTR("SDWR: %d @ 0x%08x\n"), nb_sector, addr);
SERIAL_ECHO_P(0, buffer);
PORT_REDIRECT(0);
SERIAL_ECHO(buffer);
}
#endif
if (!card.getSd2Card().writeStart(addr, nb_sector))
+17 -3
View File
@@ -34,7 +34,14 @@
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(WIFISUPPORT)
#include "ota.h"
#include <ESPAsyncWebServer.h>
#include "wifi.h"
#if ENABLED(OTASUPPORT)
#include "ota.h"
#endif
#if ENABLED(WEBSUPPORT)
#include "web.h"
#endif
#endif
// --------------------------------------------------------------------------
@@ -83,14 +90,21 @@ esp_adc_cal_characteristics_t characteristics;
void HAL_init(void) {
#if ENABLED(WIFISUPPORT)
OTA_init();
wifi_init();
#if ENABLED(OTASUPPORT)
OTA_init();
#endif
#if ENABLED(WEBSUPPORT)
web_init();
#endif
server.begin();
#endif
i2s_init();
}
void HAL_idletask(void) {
#if ENABLED(WIFISUPPORT)
#if ENABLED(OTASUPPORT)
OTA_handle();
#endif
}
+10 -2
View File
@@ -36,7 +36,7 @@
#include <Arduino.h>
#undef DISABLED
#define DISABLED(b) (!_CAT(SWITCH_ENABLED_, b))
#define DISABLED(V...) DO(DIS,&&,V)
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
@@ -47,15 +47,23 @@
#include "HAL_timers_ESP32.h"
#include "WebSocketSerial.h"
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
extern portMUX_TYPE spinlock;
#define NUM_SERIAL 1
#define MYSERIAL0 Serial
#if ENABLED(WIFISUPPORT)
#define NUM_SERIAL 2
#define MYSERIAL1 webSocketSerial
#else
#define NUM_SERIAL 1
#endif
#define CRITICAL_SECTION_START portENTER_CRITICAL(&spinlock)
#define CRITICAL_SECTION_END portEXIT_CRITICAL(&spinlock)
#define ISRS_ENABLED() (spinlock.owner == portMUX_FREE_VAL)
+2 -2
View File
@@ -69,8 +69,8 @@ typedef uint64_t hal_timer_t;
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define HAL_TEMP_TIMER_ISR extern "C" void tempTC_Handler(void)
#define HAL_STEP_TIMER_ISR extern "C" void stepTC_Handler(void)
#define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler(void)
#define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler(void)
extern "C" void tempTC_Handler(void);
extern "C" void stepTC_Handler(void);
+4
View File
@@ -23,3 +23,7 @@
#if ENABLED(EMERGENCY_PARSER)
#error "EMERGENCY_PARSER is not yet implemented for ESP32. Disable EMERGENCY_PARSER to continue."
#endif
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
@@ -0,0 +1,234 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfig.h"
#if ENABLED(WIFISUPPORT)
#include "WebSocketSerial.h"
extern WebSocketSerial webSocketSerial;
#include "wifi.h"
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
struct ring_buffer_r {
unsigned char buffer[RX_BUFFER_SIZE];
volatile ring_buffer_pos_t head, tail;
};
struct ring_buffer_t {
unsigned char buffer[256];
volatile uint8_t head, tail;
};
ring_buffer_r rx_buffer = { { 0 }, 0, 0 };
ring_buffer_t tx_buffer = { { 0 }, 0, 0 };
static bool _written;
#if ENABLED(EMERGENCY_PARSER)
static EmergencyParser::State emergency_state; // = EP_RESET
#endif
AsyncWebSocket ws("/ws"); // access at ws://[esp ip]/ws
FORCE_INLINE int next_rx_index(const int i) { return (ring_buffer_pos_t)(i + 1) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1); }
FORCE_INLINE int next_tx_index(const int i) { return (ring_buffer_pos_t)(i + 1) & (ring_buffer_pos_t)(TX_BUFFER_SIZE - 1); }
static void addToBuffer(uint8_t * const data, const size_t len) {
for (size_t i = 0; i < len; i++) {
ring_buffer_pos_t h = rx_buffer.head;
const ring_buffer_pos_t t = rx_buffer.tail, n = next_rx_index(h);
if (n != t) { rx_buffer.buffer[h] = data[i]; h = n; }
// TODO: buffer is full, handle?
rx_buffer.head = h;
}
}
// Handle WebSocket event
static void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) {
switch (type) {
case WS_EVT_CONNECT: client->ping(); break; // client connected
case WS_EVT_DISCONNECT: // client disconnected
case WS_EVT_ERROR: // error was received from the other end
case WS_EVT_PONG: break; // pong message was received (in response to a ping request maybe)
case WS_EVT_DATA: { // data packet
AwsFrameInfo * info = (AwsFrameInfo*)arg;
if (info->opcode == WS_TEXT || info->message_opcode == WS_TEXT)
addToBuffer(data, len);
}
}
}
// Public Methods
void WebSocketSerial::begin(const long baud_setting) {
ws.onEvent(onEvent);
server.addHandler(&ws); // attach AsyncWebSocket
}
void WebSocketSerial::end() { }
int WebSocketSerial::peek(void) {
const int v = rx_buffer.head == rx_buffer.tail ? -1 : rx_buffer.buffer[rx_buffer.tail];
return v;
}
int WebSocketSerial::read(void) {
const ring_buffer_pos_t h = rx_buffer.head, t = rx_buffer.tail;
if (h == t) return -1; // Nothing to read? Return now
const int v = rx_buffer.buffer[t];
rx_buffer.tail = (ring_buffer_pos_t)(t + 1) & (RX_BUFFER_SIZE - 1); // Advance tail
return v;
}
bool WebSocketSerial::available(void) {
const ring_buffer_pos_t h = rx_buffer.head, t = rx_buffer.tail;
return (ring_buffer_pos_t)(RX_BUFFER_SIZE + h - t) & (RX_BUFFER_SIZE - 1);
}
void WebSocketSerial::flush(void) {
ws.textAll("flush");
rx_buffer.tail = rx_buffer.head;
}
#if TX_BUFFER_SIZE
void WebSocketSerial::write(const uint8_t c) {
_written = true;
const uint8_t i = (tx_buffer.head + 1) & (TX_BUFFER_SIZE - 1);
// Store new char. head is always safe to move
tx_buffer.buffer[tx_buffer.head] = c;
tx_buffer.head = i;
if (c == '\n') {
ws.textAll(tx_buffer.buffer, tx_buffer.head);
tx_buffer.head = 0;
}
}
void WebSocketSerial::flushTx(void) {
ws.textAll("flushTx");
if (!_written) return;
}
#else
//void WebSocketSerial::write(const uint8_t c) { _written = true; }
//void WebSocketSerial::flushTx(void) { if (!_written) return; }
#endif
/**
* Imports from print.h
*/
void WebSocketSerial::print(char c, int base) { print((long)c, base); }
void WebSocketSerial::print(unsigned char b, int base) { print((unsigned long)b, base); }
void WebSocketSerial::print(int n, int base) { print((long)n, base); }
void WebSocketSerial::print(unsigned int n, int base) { print((unsigned long)n, base); }
void WebSocketSerial::print(long n, int base) {
if (base == 0)
write(n);
else if (base == 10) {
if (n < 0) { print('-'); n = -n; }
printNumber(n, 10);
}
else
printNumber(n, base);
}
void WebSocketSerial::print(unsigned long n, int base) {
if (base == 0) write(n); else printNumber(n, base);
}
void WebSocketSerial::print(double n, int digits) { printFloat(n, digits); }
void WebSocketSerial::println(void) { print('\r'); print('\n'); }
void WebSocketSerial::println(const String& s) { print(s); println(); }
void WebSocketSerial::println(const char c[]) { print(c); println(); }
void WebSocketSerial::println(char c, int base) { print(c, base); println(); }
void WebSocketSerial::println(unsigned char b, int base) { print(b, base); println(); }
void WebSocketSerial::println(int n, int base) { print(n, base); println(); }
void WebSocketSerial::println(unsigned int n, int base) { print(n, base); println(); }
void WebSocketSerial::println(long n, int base) { print(n, base); println(); }
void WebSocketSerial::println(unsigned long n, int base) { print(n, base); println(); }
void WebSocketSerial::println(double n, int digits) { print(n, digits); println(); }
// Private Methods
void WebSocketSerial::printNumber(unsigned long n, uint8_t base) {
if (n) {
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
int8_t i = 0;
while (n) {
buf[i++] = n % base;
n /= base;
}
while (i--)
print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
}
else
print('0');
}
void WebSocketSerial::printFloat(double number, uint8_t digits) {
// Handle negative numbers
if (number < 0.0) { print('-'); number = -number; }
// Round correctly so that print(1.999, 2) prints as "2.00"
// Use a lookup table for performance
constexpr double rounds[] = { 0.5, 0.05, 0.005, 0.0005, 0.00005, 0.000005, 0.0000005, 0.00000005 };
number += rounds[digits];
//number += pow(10, -(digits + 1)); // slower single-line equivalent
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
print(int_part);
// Print the decimal point, but only if there are digits beyond
double remainder = number - (double)int_part;
if (digits) {
print('.');
// Extract digits from the remainder one at a time
while (digits--) {
remainder *= 10.0;
const int toPrint = int(remainder);
print(toPrint);
remainder -= toPrint;
}
}
}
#endif // WIFISUPPORT
#endif // ARDUINO_ARCH_ESP32
@@ -0,0 +1,99 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../inc/MarlinConfig.h"
#include <WString.h>
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
#ifndef RX_BUFFER_SIZE
#define RX_BUFFER_SIZE 128
#endif
#ifndef TX_BUFFER_SIZE
#define TX_BUFFER_SIZE 32
#endif
#if TX_BUFFER_SIZE <= 0
#error "TX_BUFFER_SIZE is required for the WebSocket."
#endif
#if RX_BUFFER_SIZE > 256
typedef uint16_t ring_buffer_pos_t;
#else
typedef uint8_t ring_buffer_pos_t;
#endif
class WebSocketSerial {
public:
WebSocketSerial() {};
static void begin(const long);
static void end();
static int peek(void);
static int read(void);
static void flush(void);
static void flushTx(void);
static bool available(void);
static void write(const uint8_t c);
#if ENABLED(SERIAL_STATS_DROPPED_RX)
FORCE_INLINE static uint32_t dropped() { return 0; }
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
FORCE_INLINE static int rxMaxEnqueued() { return 0; }
#endif
FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
FORCE_INLINE static void print(const char* str) { write(str); }
static void print(char, int = 0);
static void print(unsigned char, int = 0);
static void print(int, int = DEC);
static void print(unsigned int, int = DEC);
static void print(long, int = DEC);
static void print(unsigned long, int = DEC);
static void print(double, int = 2);
static void println(const String& s);
static void println(const char[]);
static void println(char, int = 0);
static void println(unsigned char, int = 0);
static void println(int, int = DEC);
static void println(unsigned int, int = DEC);
static void println(long, int = DEC);
static void println(unsigned long, int = DEC);
static void println(double, int = 2);
static void println(void);
operator bool() { return true; }
private:
static void printNumber(unsigned long, const uint8_t);
static void printFloat(double, uint8_t);
};
extern WebSocketSerial webSocketSerial;
+20 -9
View File
@@ -28,30 +28,41 @@
*/
// Set pin as input
#define _SET_INPUT(IO) pinMode(IO, INPUT)
#define _SET_INPUT(IO) pinMode(IO, INPUT)
// Set pin as output
#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT)
#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT)
// Set pin as input with pullup mode
#define _PULLUP(IO, v) pinMode(IO, v ? INPUT_PULLUP : INPUT)
#define _PULLUP(IO, v) pinMode(IO, v ? INPUT_PULLUP : INPUT)
// Read a pin wrapper
#define READ(IO) digitalRead(IO)
#define READ(IO) digitalRead(IO)
// Write to a pin wrapper
#define WRITE(IO, v) (TEST(IO, 7) ? i2s_write(IO & 0x7F, v) : digitalWrite(IO, v))
#define WRITE(IO, v) (TEST(IO, 7) ? i2s_write(IO & 0x7F, v) : digitalWrite(IO, v))
// Set pin as input wrapper
#define SET_INPUT(IO) _SET_INPUT(IO)
#define SET_INPUT(IO) _SET_INPUT(IO)
// Set pin as input with pullup wrapper
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
// Set pin as output wrapper
#define SET_OUTPUT(IO) do{ _SET_OUTPUT(IO); WRITE(IO, LOW); }while(0)
#define SET_OUTPUT(IO) do{ _SET_OUTPUT(IO); }while(0)
#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0)
// Set pin as PWM
#define SET_PWM(IO) SET_OUTPUT(IO)
// Set pin as output and init
#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0)
// digitalRead/Write wrappers
#define extDigitalRead(IO) digitalRead(IO)
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
#define PWM_PIN(P) true
#define USEABLE_HARDWARE_PWM(P) PWM_PIN(P)
//
// Ports and functions
+2 -11
View File
@@ -21,7 +21,7 @@
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(WIFISUPPORT)
#if ENABLED(OTASUPPORT)
#include <WiFi.h>
#include <ESPmDNS.h>
@@ -30,15 +30,6 @@
#include "driver/timer.h"
void OTA_init() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PWD);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
ArduinoOTA
.onStart([]() {
timer_pause(TIMER_GROUP_0, TIMER_0);
@@ -76,6 +67,6 @@ void OTA_handle() {
ArduinoOTA.handle();
}
#endif // WIFISUPPORT
#endif // OTASUPPORT
#endif // ARDUINO_ARCH_ESP32
+49
View File
@@ -0,0 +1,49 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(WEBSUPPORT)
#include "../../core/serial.h"
#include "FS.h"
#include "SPIFFS.h"
#include "wifi.h"
AsyncEventSource events("/events"); // event source (Server-Sent events)
void onNotFound(AsyncWebServerRequest *request){
request->send(404);
}
void web_init() {
server.addHandler(&events); // attach AsyncEventSource
if (SPIFFS.begin()) {
server.serveStatic("/", SPIFFS, "/www").setDefaultFile("index.html");
server.onNotFound(onNotFound);
}
else
SERIAL_ECHO_MSG("SPIFFS Mount Failed");
}
#endif // WEBSUPPORT
#endif // ARDUINO_ARCH_ESP32
+21
View File
@@ -0,0 +1,21 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
void web_init();
+55
View File
@@ -0,0 +1,55 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(WIFISUPPORT)
#include <WiFi.h>
#include <ESPmDNS.h>
#include <ESPAsyncWebServer.h>
#include "wifi.h"
AsyncWebServer server(80);
#ifndef WIFI_HOSTNAME
#define WIFI_HOSTNAME DEFAULT_WIFI_HOSTNAME
#endif
void wifi_init() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PWD);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
delay(5000);
ESP.restart();
}
delay(10);
// Loop forever (watchdog kill) on failure
if (!MDNS.begin(WIFI_HOSTNAME)) for(;;) delay(5000);
MDNS.addService("http", "tcp", 80);
}
#endif // WIFISUPPORT
#endif // ARDUINO_ARCH_ESP32
+27
View File
@@ -0,0 +1,27 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <ESPAsyncWebServer.h>
extern AsyncWebServer server;
#define DEFAULT_WIFI_HOSTNAME "marlin"
void wifi_init();
+82
View File
@@ -0,0 +1,82 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
HalSerial usb_serial;
// U8glib required functions
extern "C" void u8g_xMicroDelay(uint16_t val) {
DELAY_US(val);
}
extern "C" void u8g_MicroDelay(void) {
u8g_xMicroDelay(1);
}
extern "C" void u8g_10MicroDelay(void) {
u8g_xMicroDelay(10);
}
extern "C" void u8g_Delay(uint16_t val) {
delay(val);
}
//************************//
// return free heap space
int freeMemory() {
return 0;
}
// --------------------------------------------------------------------------
// ADC
// --------------------------------------------------------------------------
void HAL_adc_init(void) {
}
void HAL_adc_enable_channel(int ch) {
}
uint8_t active_ch = 0;
void HAL_adc_start_conversion(const uint8_t ch) {
active_ch = ch;
}
bool HAL_adc_finished(void) {
return true;
}
uint16_t HAL_adc_get_result(void) {
pin_t pin = analogInputToDigitalPin(active_ch);
if (!VALID_PIN(pin)) return 0;
uint16_t data = ((Gpio::get(pin) >> 2) & 0x3FF);
return data; // return 10bit value as Marlin expects
}
void HAL_pwm_init(void) {
}
#endif // __PLAT_LINUX__
+109
View File
@@ -0,0 +1,109 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#define CPU_32_BIT
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#define F_CPU 100000000
#define SystemCoreClock F_CPU
#include <iostream>
#include <stdint.h>
#include <stdarg.h>
#undef min
#undef max
#include <algorithm>
void _printf (const char *format, ...);
void _putc(uint8_t c);
uint8_t _getc();
//extern "C" volatile uint32_t _millis;
//arduino: Print.h
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
//arduino: binary.h (weird defines)
#define B01 1
#define B10 2
#include "hardware/Clock.h"
#include <Arduino.h>
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "watchdog.h"
#include "HAL_timers.h"
#include "serial.h"
extern HalSerial usb_serial;
#define MYSERIAL0 usb_serial
#define NUM_SERIAL 1
#define ST7920_DELAY_1 DELAY_NS(600)
#define ST7920_DELAY_2 DELAY_NS(750)
#define ST7920_DELAY_3 DELAY_NS(750)
//
// Interrupts
//
#define CRITICAL_SECTION_START
#define CRITICAL_SECTION_END
#define ISRS_ENABLED()
#define ENABLE_ISRS()
#define DISABLE_ISRS()
//Utility functions
int freeMemory(void);
// SPI: Extended functions which take a channel number (hardware SPI only)
/** Write single byte to specified SPI channel */
void spiSend(uint32_t chan, byte b);
/** Write buffer to specified SPI channel */
void spiSend(uint32_t chan, const uint8_t* buf, size_t n);
/** Read single byte from specified SPI channel */
uint8_t spiRec(uint32_t chan);
// ADC
#define HAL_ANALOG_SELECT(pin) HAL_adc_enable_channel(pin)
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_READ_ADC() HAL_adc_get_result()
#define HAL_ADC_READY() true
void HAL_adc_init(void);
void HAL_adc_enable_channel(int pin);
void HAL_adc_start_conversion(const uint8_t adc_pin);
uint16_t HAL_adc_get_result(void);
/* ---------------- Delay in cycles */
FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {
Clock::delayCycles(x);
}
+73
View File
@@ -0,0 +1,73 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "hardware/Timer.h"
#include "../../inc/MarlinConfig.h"
#include "HAL_timers.h"
/**
* Use POSIX signals to attempt to emulate Interrupts
* This has many limitations and is not fit for the purpose
*/
HAL_STEP_TIMER_ISR();
HAL_TEMP_TIMER_ISR();
Timer timers[2];
void HAL_timer_init(void) {
timers[0].init(0, STEPPER_TIMER_RATE, TIMER0_IRQHandler);
timers[1].init(1, TEMP_TIMER_RATE, TIMER1_IRQHandler);
}
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timers[timer_num].start(frequency);
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
timers[timer_num].enable();
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
timers[timer_num].disable();
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
return timers[timer_num].enabled();
}
void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
timers[timer_num].setCompare(compare);
}
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
return timers[timer_num].getCompare();
}
hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
return timers[timer_num].getCount();
}
#endif // __PLAT_LINUX__
+91
View File
@@ -0,0 +1,91 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* HAL timers for Linux X86_64
*/
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include <stdint.h>
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#define TEMP_TIMER_NUM 1 // Timer Index for Temperature
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define TEMP_TIMER_RATE 1000000
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define HAL_STEP_TIMER_ISR() extern "C" void TIMER0_IRQHandler(void)
#define HAL_TEMP_TIMER_ISR() extern "C" void TIMER1_IRQHandler(void)
// PWM timer
#define HAL_PWM_TIMER
#define HAL_PWM_TIMER_ISR() extern "C" void TIMER3_IRQHandler(void)
#define HAL_PWM_TIMER_IRQn
void HAL_timer_init(void);
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare);
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num);
hal_timer_t HAL_timer_get_count(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_ticks) {
const hal_timer_t mincmp = HAL_timer_get_count(timer_num) + interval_ticks;
if (HAL_timer_get_compare(timer_num) < mincmp) HAL_timer_set_compare(timer_num, mincmp);
}
void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
#define HAL_timer_isr_prologue(TIMER_NUM)
#define HAL_timer_isr_epilogue(TIMER_NUM)
+71
View File
@@ -0,0 +1,71 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Test X86_64 configuration values for errors at compile-time.
*/
#if ENABLED(SPINDLE_LASER_ENABLE)
#if !PIN_EXISTS(SPINDLE_LASER_ENABLE)
#error "SPINDLE_LASER_ENABLE requires SPINDLE_LASER_ENABLE_PIN."
#elif SPINDLE_DIR_CHANGE && !PIN_EXISTS(SPINDLE_DIR)
#error "SPINDLE_DIR_PIN not defined."
#elif ENABLED(SPINDLE_LASER_PWM) && PIN_EXISTS(SPINDLE_LASER_PWM)
#if !PWM_PIN(SPINDLE_LASER_PWM_PIN)
#error "SPINDLE_LASER_PWM_PIN not assigned to a PWM pin."
#elif !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
#error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
#elif SPINDLE_LASER_POWERUP_DELAY < 1
#error "SPINDLE_LASER_POWERUP_DELAY must be greater than 0."
#elif SPINDLE_LASER_POWERDOWN_DELAY < 1
#error "SPINDLE_LASER_POWERDOWN_DELAY must be greater than 0."
#elif !defined(SPINDLE_LASER_PWM_INVERT)
#error "SPINDLE_LASER_PWM_INVERT missing."
#elif !defined(SPEED_POWER_SLOPE) || !defined(SPEED_POWER_INTERCEPT) || !defined(SPEED_POWER_MIN) || !defined(SPEED_POWER_MAX)
#error "SPINDLE_LASER_PWM equation constant(s) missing."
#elif PIN_EXISTS(CASE_LIGHT) && SPINDLE_LASER_PWM_PIN == CASE_LIGHT_PIN
#error "SPINDLE_LASER_PWM_PIN is used by CASE_LIGHT_PIN."
#elif PIN_EXISTS(E0_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E0_AUTO_FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by E0_AUTO_FAN_PIN."
#elif PIN_EXISTS(E1_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E1_AUTO_FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by E1_AUTO_FAN_PIN."
#elif PIN_EXISTS(E2_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E2_AUTO_FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by E2_AUTO_FAN_PIN."
#elif PIN_EXISTS(E3_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E3_AUTO_FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by E3_AUTO_FAN_PIN."
#elif PIN_EXISTS(E4_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E4_AUTO_FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by E4_AUTO_FAN_PIN."
#elif PIN_EXISTS(FAN) && SPINDLE_LASER_PWM_PIN == FAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used FAN_PIN."
#elif PIN_EXISTS(FAN1) && SPINDLE_LASER_PWM_PIN == FAN1_PIN
#error "SPINDLE_LASER_PWM_PIN is used FAN1_PIN."
#elif PIN_EXISTS(FAN2) && SPINDLE_LASER_PWM_PIN == FAN2_PIN
#error "SPINDLE_LASER_PWM_PIN is used FAN2_PIN."
#elif PIN_EXISTS(CONTROLLERFAN) && SPINDLE_LASER_PWM_PIN == CONTROLLERFAN_PIN
#error "SPINDLE_LASER_PWM_PIN is used by CONTROLLERFAN_PIN."
#endif
#endif
#endif // SPINDLE_LASER_ENABLE
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
+116
View File
@@ -0,0 +1,116 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include <iostream>
#include "../../inc/MarlinConfig.h"
#include "hardware/Clock.h"
#include "../shared/Delay.h"
// Interrupts
void cli(void) { } // Disable
void sei(void) { } // Enable
// Time functions
void _delay_ms(const int delay_ms) {
delay(delay_ms);
}
uint32_t millis() {
return (uint32_t)Clock::millis();
}
// This is required for some Arduino libraries we are using
void delayMicroseconds(uint32_t us) {
Clock::delayMicros(us);
}
extern "C" void delay(const int msec) {
Clock::delayMillis(msec);
}
// IO functions
// As defined by Arduino INPUT(0x0), OUTPUT(0x1), INPUT_PULLUP(0x2)
void pinMode(const pin_t pin, const uint8_t mode) {
if (!VALID_PIN(pin)) return;
Gpio::setMode(pin, mode);
}
void digitalWrite(pin_t pin, uint8_t pin_status) {
if (!VALID_PIN(pin)) return;
Gpio::set(pin, pin_status);
}
bool digitalRead(pin_t pin) {
if (!VALID_PIN(pin)) return false;
return Gpio::get(pin);
}
void analogWrite(pin_t pin, int pwm_value) { // 1 - 254: pwm_value, 0: LOW, 255: HIGH
if (!VALID_PIN(pin)) return;
Gpio::set(pin, pwm_value);
}
uint16_t analogRead(pin_t adc_pin) {
if (!VALID_PIN(DIGITAL_PIN_TO_ANALOG_PIN(adc_pin))) return 0;
return Gpio::get(DIGITAL_PIN_TO_ANALOG_PIN(adc_pin));
}
// **************************
// Persistent Config Storage
// **************************
void eeprom_write_byte(unsigned char *pos, unsigned char value) {
}
unsigned char eeprom_read_byte(uint8_t * pos) { return '\0'; }
void eeprom_read_block(void *__dst, const void *__src, size_t __n) { }
void eeprom_update_block(const void *__src, void *__dst, size_t __n) { }
char *dtostrf (double __val, signed char __width, unsigned char __prec, char *__s) {
char format_string[20];
snprintf(format_string, 20, "%%%d.%df", __width, __prec);
sprintf(__s, format_string, __val);
return __s;
}
int32_t random(int32_t max) {
return rand() % max;
}
int32_t random(int32_t min, int32_t max) {
return min + rand() % (max - min);
}
void randomSeed(uint32_t value) {
srand(value);
}
int map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
#endif // __PLAT_LINUX__
+129
View File
@@ -0,0 +1,129 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Fast I/O Routines for X86_64
*/
#include <Arduino.h>
#include <pinmapping.h>
#define SET_DIR_INPUT(IO) Gpio::setDir(IO, 1)
#define SET_DIR_OUTPUT(IO) Gpio::setDir(IO, 0)
#define SET_MODE(IO, mode) Gpio::setMode(IO, mode)
#define WRITE_PIN_SET(IO) Gpio::set(IO)
#define WRITE_PIN_CLR(IO) Gpio::clear(IO)
#define READ_PIN(IO) Gpio::get(IO)
#define WRITE_PIN(IO,V) Gpio::set(IO, V)
/**
* Magic I/O routines
*
* Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW);
*
* Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
*/
/// Read a pin
#define _READ(IO) READ_PIN(IO)
/// Write to a pin
#define _WRITE_VAR(IO,V) digitalWrite(IO,V)
#define _WRITE(IO,V) WRITE_PIN(IO,V)
/// toggle a pin
#define _TOGGLE(IO) _WRITE(IO, !READ(IO))
/// set pin as input
#define _SET_INPUT(IO) SET_DIR_INPUT(IO)
/// set pin as output
#define _SET_OUTPUT(IO) SET_DIR_OUTPUT(IO)
/// set pin as input with pullup mode
#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT)
/// set pin as input with pulldown mode
#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT)
// hg42: all pins can be input or output (I hope)
// hg42: undefined pins create compile error (IO, is no pin)
// hg42: currently not used, but was used by pinsDebug
/// check if pin is an input
#define _IS_INPUT(IO) (LPC1768_PIN_PIN(IO) >= 0)
/// check if pin is an output
#define _IS_OUTPUT(IO) (LPC1768_PIN_PIN(IO) >= 0)
// hg42: HAS_TIMER is used only to check if it's a PWM pin
// hg42: we cannot use USEABLE_HARDWARE_PWM because it uses a function that cannot be used statically
// hg42: instead use PWM bit from the #define
/// check if pin is a timer
#define _HAS_TIMER(IO) true // could be LPC1768_PIN_PWM(IO), but there
// hg42: could be this:
// #define _HAS_TIMER(IO) LPC1768_PIN_PWM(IO)
// but this is an incomplete check (12 pins are PWMable, but only 6 can be used at the same time)
/// Read a pin wrapper
#define READ(IO) _READ(IO)
/// Write to a pin wrapper
#define WRITE_VAR(IO,V) _WRITE_VAR(IO,V)
#define WRITE(IO,V) _WRITE(IO,V)
/// toggle a pin wrapper
#define TOGGLE(IO) _TOGGLE(IO)
/// set pin as input wrapper
#define SET_INPUT(IO) _SET_INPUT(IO)
/// set pin as input with pullup wrapper
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
/// set pin as input with pulldown wrapper
#define SET_INPUT_PULLDOWN(IO) do{ _SET_INPUT(IO); _PULLDOWN(IO, HIGH); }while(0)
/// set pin as output wrapper - reads the pin and sets the output to that value
#define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0)
// set pin as PWM
#define SET_PWM(IO) SET_OUTPUT(IO)
/// check if pin is an input wrapper
#define IS_INPUT(IO) _IS_INPUT(IO)
/// check if pin is an output wrapper
#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
/// check if pin is a timer (wrapper)
#define HAS_TIMER(IO) _HAS_TIMER(IO)
// Shorthand
#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
// digitalRead/Write wrappers
#define extDigitalRead(IO) digitalRead(IO)
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
#define USEABLE_HARDWARE_PWM(P) PWM_PIN(P)
@@ -0,0 +1,32 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "../../../inc/MarlinConfig.h"
#include "Clock.h"
std::chrono::nanoseconds Clock::startup = std::chrono::high_resolution_clock::now().time_since_epoch();
uint32_t Clock::frequency = F_CPU;
double Clock::time_multiplier = 1.0;
#endif // __PLAT_LINUX__
+89
View File
@@ -0,0 +1,89 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <chrono>
#include <thread>
class Clock {
public:
static uint64_t ticks(uint32_t frequency = Clock::frequency) {
return (Clock::nanos() - Clock::startup.count()) / (1000000000ULL / frequency);
}
static uint64_t nanosToTicks(uint64_t ns, uint32_t frequency = Clock::frequency) {
return ns / (1000000000ULL / frequency);
}
// Time acceleration compensated
static uint64_t ticksToNanos(uint64_t tick, uint32_t frequency = Clock::frequency) {
return (tick * (1000000000ULL / frequency)) / Clock::time_multiplier;
}
static void setFrequency(uint32_t freq) {
Clock::frequency = freq;
}
// Time Acceleration compensated
static uint64_t nanos() {
auto now = std::chrono::high_resolution_clock::now().time_since_epoch();
return (now.count() - Clock::startup.count()) * Clock::time_multiplier;
}
static uint64_t micros() {
return Clock::nanos() / 1000;
}
static uint64_t millis() {
return Clock::micros() / 1000;
}
static double seconds() {
return Clock::nanos() / 1000000000.0;
}
static void delayCycles(uint64_t cycles) {
std::this_thread::sleep_for(std::chrono::nanoseconds( (1000000000L / frequency) * cycles) / Clock::time_multiplier );
}
static void delayMicros(uint64_t micros) {
std::this_thread::sleep_for(std::chrono::microseconds( micros ) / Clock::time_multiplier);
}
static void delayMillis(uint64_t millis) {
std::this_thread::sleep_for(std::chrono::milliseconds( millis ) / Clock::time_multiplier);
}
static void delaySeconds(double secs) {
std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(secs * 1000) / Clock::time_multiplier);
}
// Will reduce timer resolution increasing likelihood of overflows
static void setTimeMultiplier(double tm) {
Clock::time_multiplier = tm;
}
private:
static std::chrono::nanoseconds startup;
static uint32_t frequency;
static double time_multiplier;
};
@@ -0,0 +1,30 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "Gpio.h"
pin_data Gpio::pin_map[Gpio::pin_count+1] = {};
IOLogger* Gpio::logger = nullptr;
#endif // __PLAT_LINUX__
+141
View File
@@ -0,0 +1,141 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "Clock.h"
#include "../../../inc/MarlinConfigPre.h"
#include <stdint.h>
typedef int16_t pin_type;
struct GpioEvent {
enum Type {
NOP,
FALL,
RISE,
SET_VALUE,
SETM,
SETD
};
uint64_t timestamp;
pin_type pin_id;
GpioEvent::Type event;
GpioEvent(uint64_t timestamp, pin_type pin_id, GpioEvent::Type event){
this->timestamp = timestamp;
this->pin_id = pin_id;
this->event = event;
}
};
class IOLogger {
public:
virtual ~IOLogger(){};
virtual void log(GpioEvent ev) = 0;
};
class Peripheral {
public:
virtual ~Peripheral(){};
virtual void interrupt(GpioEvent ev) = 0;
virtual void update() = 0;
};
struct pin_data {
uint8_t dir;
uint8_t mode;
uint16_t value;
Peripheral* cb;
};
class Gpio {
public:
static const pin_type pin_count = 255;
static pin_data pin_map[pin_count+1];
static bool valid_pin(pin_type pin) {
return pin >= 0 && pin <= pin_count;
}
static void set(pin_type pin) {
set(pin, 1);
}
static void set(pin_type pin, uint16_t value) {
if (!valid_pin(pin)) return;
GpioEvent::Type evt_type = value > 1 ? GpioEvent::SET_VALUE : value > pin_map[pin].value ? GpioEvent::RISE : value < pin_map[pin].value ? GpioEvent::FALL : GpioEvent::NOP;
pin_map[pin].value = value;
GpioEvent evt(Clock::nanos(), pin, evt_type);
if (pin_map[pin].cb != nullptr) {
pin_map[pin].cb->interrupt(evt);
}
if (Gpio::logger != nullptr) Gpio::logger->log(evt);
}
static uint16_t get(pin_type pin) {
if (!valid_pin(pin)) return 0;
return pin_map[pin].value;
}
static void clear(pin_type pin) {
set(pin, 0);
}
static void setMode(pin_type pin, uint8_t value) {
if (!valid_pin(pin)) return;
pin_map[pin].mode = value;
GpioEvent evt(Clock::nanos(), pin, GpioEvent::Type::SETM);
if (pin_map[pin].cb != nullptr) pin_map[pin].cb->interrupt(evt);
if (Gpio::logger != nullptr) Gpio::logger->log(evt);
}
static uint8_t getMode(pin_type pin) {
if (!valid_pin(pin)) return 0;
return pin_map[pin].mode;
}
static void setDir(pin_type pin, uint8_t value) {
if (!valid_pin(pin)) return;
pin_map[pin].dir = value;
GpioEvent evt(Clock::nanos(), pin, GpioEvent::Type::SETD);
if (pin_map[pin].cb != nullptr) pin_map[pin].cb->interrupt(evt);
if (Gpio::logger != nullptr) Gpio::logger->log(evt);
}
static uint8_t getDir(pin_type pin) {
if (!valid_pin(pin)) return 0;
return pin_map[pin].dir;
}
static void attachPeripheral(pin_type pin, Peripheral* per) {
if (!valid_pin(pin)) return;
pin_map[pin].cb = per;
}
static void attachLogger(IOLogger* logger) {
Gpio::logger = logger;
}
private:
static IOLogger* logger;
};
@@ -0,0 +1,61 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "Clock.h"
#include <stdio.h>
#include "../../../inc/MarlinConfig.h"
#include "Heater.h"
Heater::Heater(pin_t heater, pin_t adc) {
heater_state = 0;
room_temp_raw = 150;
last = Clock::micros();
heater_pin = heater;
adc_pin = adc;
heat = 0.0;
}
Heater::~Heater() {
}
void Heater::update() {
// crude pwm read and cruder heat simulation
auto now = Clock::micros();
double delta = (now - last);
if (delta > 1000 ) {
heater_state = pwmcap.update(0xFFFF * Gpio::pin_map[heater_pin].value);
last = now;
heat += (heater_state - heat) * (delta / 1000000000.0);
if (heat < room_temp_raw) heat = room_temp_raw;
Gpio::pin_map[analogInputToDigitalPin(adc_pin)].value = 0xFFFF - (uint16_t)heat;
}
}
void Heater::interrupt(GpioEvent ev) {
// ununsed
}
#endif // __PLAT_LINUX__
@@ -0,0 +1,47 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "Gpio.h"
struct LowpassFilter {
uint64_t data_delay = 0;
uint16_t update(uint16_t value) {
data_delay = data_delay - (data_delay >> 6) + value;
return (uint16_t)(data_delay >> 6);
}
};
class Heater: public Peripheral {
public:
Heater(pin_t heater, pin_t adc);
virtual ~Heater();
void interrupt(GpioEvent ev);
void update();
pin_t heater_pin, adc_pin;
uint16_t room_temp_raw;
uint16_t heater_state;
LowpassFilter pwmcap;
double heat;
uint64_t last;
};
@@ -0,0 +1,50 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "IOLoggerCSV.h"
IOLoggerCSV::IOLoggerCSV(std::string filename) {
file.open(filename);
}
IOLoggerCSV::~IOLoggerCSV() {
file.close();
}
void IOLoggerCSV::log(GpioEvent ev) {
std::lock_guard<std::mutex> lock(vector_lock);
events.push_back(ev); //minimal impact to signal handler
}
void IOLoggerCSV::flush() {
{ std::lock_guard<std::mutex> lock(vector_lock);
while (!events.empty()) {
file << events.front().timestamp << ", "<< events.front().pin_id << ", " << events.front().event << std::endl;
events.pop_front();
}
}
file.flush();
}
#endif // __PLAT_LINUX__
@@ -0,0 +1,40 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <mutex>
#include <list>
#include <fstream>
#include "Gpio.h"
class IOLoggerCSV: public IOLogger {
public:
IOLoggerCSV(std::string filename);
virtual ~IOLoggerCSV();
void flush();
void log(GpioEvent ev);
private:
std::ofstream file;
std::list<GpioEvent> events;
std::mutex vector_lock;
};
@@ -0,0 +1,66 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include <random>
#include <stdio.h>
#include "Clock.h"
#include "LinearAxis.h"
LinearAxis::LinearAxis(pin_type enable, pin_type dir, pin_type step, pin_type end_min, pin_type end_max) {
enable_pin = enable;
dir_pin = dir;
step_pin = step;
min_pin = end_min;
max_pin = end_max;
min_position = 50;
max_position = (200*80) + min_position;
position = rand() % ((max_position - 40) - min_position) + (min_position + 20);
last_update = Clock::nanos();
Gpio::attachPeripheral(step_pin, this);
}
LinearAxis::~LinearAxis() {
}
void LinearAxis::update() {
}
void LinearAxis::interrupt(GpioEvent ev) {
if (ev.pin_id == step_pin && !Gpio::pin_map[enable_pin].value){
if (ev.event == GpioEvent::RISE) {
last_update = ev.timestamp;
position += -1 + 2 * Gpio::pin_map[dir_pin].value;
Gpio::pin_map[min_pin].value = (position < min_position);
//Gpio::pin_map[max_pin].value = (position > max_position);
//if (position < min_position) printf("axis(%d) endstop : pos: %d, mm: %f, min: %d\n", step_pin, position, position / 80.0, Gpio::pin_map[min_pin].value);
}
}
}
#endif // __PLAT_LINUX__
@@ -0,0 +1,45 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <chrono>
#include "Gpio.h"
class LinearAxis: public Peripheral {
public:
LinearAxis(pin_type enable, pin_type dir, pin_type step, pin_type end_min, pin_type end_max);
virtual ~LinearAxis();
void update();
void interrupt(GpioEvent ev);
pin_type enable_pin;
pin_type dir_pin;
pin_type step_pin;
pin_type min_pin;
pin_type max_pin;
int32_t position;
int32_t min_position;
int32_t max_position;
uint64_t last_update;
};
+118
View File
@@ -0,0 +1,118 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "Timer.h"
#include <stdio.h>
Timer::Timer() {
active = false;
compare = 0;
frequency = 0;
overruns = 0;
timerid = 0;
cbfn = nullptr;
period = 0;
start_time = 0;
avg_error = 0;
}
Timer::~Timer() {
timer_delete(timerid);
}
void Timer::init(uint32_t sig_id, uint32_t sim_freq, callback_fn* fn) {
struct sigaction sa;
struct sigevent sev;
frequency = sim_freq;
cbfn = fn;
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = Timer::handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGRTMIN, &sa, NULL) == -1) {
return; // todo: handle error
}
sigemptyset(&mask);
sigaddset(&mask, SIGRTMIN);
disable();
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN;
sev.sigev_value.sival_ptr = (void*)this;
if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) {
return; // todo: handle error
}
}
void Timer::start(uint32_t frequency) {
setCompare(this->frequency / frequency);
//printf("timer(%ld) started\n", getID());
}
void Timer::enable() {
if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) {
return; // todo: handle error
}
active = true;
//printf("timer(%ld) enabled\n", getID());
}
void Timer::disable() {
if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1) {
return; // todo: handle error
}
active = false;
}
void Timer::setCompare(uint32_t compare) {
uint32_t nsec_offset = 0;
if (active) {
nsec_offset = Clock::nanos() - this->start_time; // calculate how long the timer would have been running for
nsec_offset = nsec_offset < 1000 ? nsec_offset : 0; // constrain, this shouldn't be needed but apparently Marlin enables interrupts on the stepper timer before initialising it, todo: investigate ?bug?
}
this->compare = compare;
uint64_t ns = Clock::ticksToNanos(compare, frequency) - nsec_offset;
struct itimerspec its;
its.it_value.tv_sec = ns / 1000000000;
its.it_value.tv_nsec = ns % 1000000000;
its.it_interval.tv_sec = its.it_value.tv_sec;
its.it_interval.tv_nsec = its.it_value.tv_nsec;
if (timer_settime(timerid, 0, &its, NULL) == -1) {
printf("timer(%ld) failed, compare: %d(%ld)\n", getID(), compare, its.it_value.tv_nsec);
return; // todo: handle error
}
//printf("timer(%ld) started, compare: %d(%d)\n", getID(), compare, its.it_value.tv_nsec);
this->period = its.it_value.tv_nsec;
this->start_time = Clock::nanos();
}
uint32_t Timer::getCount() {
return Clock::nanosToTicks(Clock::nanos() - this->start_time, frequency);
}
#endif // __PLAT_LINUX__
+76
View File
@@ -0,0 +1,76 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <stdio.h>
#include "Clock.h"
class Timer {
public:
Timer();
virtual ~Timer();
typedef void (callback_fn)();
void init(uint32_t sig_id, uint32_t sim_freq, callback_fn* fn);
void start(uint32_t frequency);
void enable();
bool enabled() {return active;}
void disable();
void setCompare(uint32_t compare);
uint32_t getCount();
uint32_t getCompare() {return compare;}
uint32_t getOverruns() {return overruns;}
uint32_t getAvgError() {return avg_error;}
intptr_t getID() {
return (*(intptr_t*)timerid);
}
static void handler(int sig, siginfo_t *si, void *uc){
Timer* _this = (Timer*)si->si_value.sival_ptr;
_this->avg_error += (Clock::nanos() - _this->start_time) - _this->period; //high_resolution_clock is also limited in precision, but best we have
_this->avg_error /= 2; //very crude precision analysis (actually within +-500ns usually)
_this->start_time = Clock::nanos(); // wrap
_this->cbfn();
_this->overruns += timer_getoverrun(_this->timerid); // even at 50Khz this doesn't stay zero, again demonstrating the limitations
// using a realtime linux kernel would help somewhat
}
private:
bool active;
uint32_t compare;
uint32_t frequency;
uint32_t overruns;
timer_t timerid;
sigset_t mask;
callback_fn* cbfn;
uint64_t period;
uint64_t avg_error;
uint64_t start_time;
};
+125
View File
@@ -0,0 +1,125 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <math.h>
#include <cstring>
#include <pinmapping.h>
#define HIGH 0x01
#define LOW 0x00
#define INPUT 0x00
#define OUTPUT 0x01
#define INPUT_PULLUP 0x02
#define INPUT_PULLDOWN 0x03
#define LSBFIRST 0
#define MSBFIRST 1
#define CHANGE 0x02
#define FALLING 0x03
#define RISING 0x04
#define E2END 0xFFF // EEPROM end address
typedef uint8_t byte;
#define PROGMEM
#define PSTR(v) (v)
#define PGM_P const char *
// Used for libraries, preprocessor, and constants
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#ifndef isnan
#define isnan std::isnan
#endif
#ifndef isinf
#define isinf std::isinf
#endif
#define sq(v) ((v) * (v))
#define square(v) sq(v)
#define constrain(value, arg_min, arg_max) ((value) < (arg_min) ? (arg_min) :((value) > (arg_max) ? (arg_max) : (value)))
//Interrupts
void cli(void); // Disable
void sei(void); // Enable
void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode);
void detachInterrupt(uint32_t pin);
extern "C" void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
extern "C" void GpioDisableInt(uint32_t port, uint32_t pin);
// Program Memory
#define pgm_read_ptr(addr) (*((void**)(addr)))
#define pgm_read_byte_near(addr) (*((uint8_t*)(addr)))
#define pgm_read_float_near(addr) (*((float*)(addr)))
#define pgm_read_word_near(addr) (*((uint16_t*)(addr)))
#define pgm_read_dword_near(addr) (*((uint32_t*)(addr)))
#define pgm_read_byte(addr) pgm_read_byte_near(addr)
#define pgm_read_float(addr) pgm_read_float_near(addr)
#define pgm_read_word(addr) pgm_read_word_near(addr)
#define pgm_read_dword(addr) pgm_read_dword_near(addr)
using std::memcpy;
#define memcpy_P memcpy
#define sprintf_P sprintf
#define strstr_P strstr
#define strncpy_P strncpy
#define vsnprintf_P vsnprintf
#define strcpy_P strcpy
#define snprintf_P snprintf
#define strlen_P strlen
// Time functions
extern "C" {
void delay(const int milis);
}
void _delay_ms(const int delay);
void delayMicroseconds(unsigned long);
uint32_t millis();
//IO functions
void pinMode(const pin_t, const uint8_t);
void digitalWrite(pin_t, uint8_t);
bool digitalRead(pin_t);
void analogWrite(pin_t, int);
uint16_t analogRead(pin_t);
// EEPROM
void eeprom_write_byte(unsigned char *pos, unsigned char value);
unsigned char eeprom_read_byte(unsigned char *pos);
void eeprom_read_block (void *__dst, const void *__src, size_t __n);
void eeprom_update_block (const void *__src, void *__dst, size_t __n);
int32_t random(int32_t);
int32_t random(int32_t, int32_t);
void randomSeed(uint32_t);
char *dtostrf (double __val, signed char __width, unsigned char __prec, char *__s);
int map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max);
@@ -0,0 +1,70 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include <pinmapping.h>
#include "../../../gcode/parser.h"
uint8_t analog_offset = NUM_DIGITAL_PINS - NUM_ANALOG_INPUTS;
// Get the digital pin for an analog index
pin_t analogInputToDigitalPin(const int8_t p) {
return (WITHIN(p, 0, NUM_ANALOG_INPUTS) ? analog_offset + p : P_NC);
}
// Return the index of a pin number
int16_t GET_PIN_MAP_INDEX(const pin_t pin) {
return pin;
}
// Test whether the pin is valid
bool VALID_PIN(const pin_t p) {
return WITHIN(p, 0, NUM_DIGITAL_PINS);
}
// Get the analog index for a digital pin
int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p) {
return (WITHIN(p, analog_offset, NUM_DIGITAL_PINS) ? p - analog_offset : P_NC);
}
// Test whether the pin is PWM
bool PWM_PIN(const pin_t p) {
return false;
}
// Test whether the pin is interruptable
bool INTERRUPT_PIN(const pin_t p) {
return false;
}
// Get the pin number at the given index
pin_t GET_PIN_MAP_PIN(const int16_t ind) {
return ind;
}
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
return parser.intval(code, dval);
}
#endif // __PLAT_LINUX__
@@ -0,0 +1,59 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../../inc/MarlinConfigPre.h"
#include <stdint.h>
#include "../hardware/Gpio.h"
typedef pin_type pin_t;
#define P_NC -1
constexpr uint16_t NUM_DIGITAL_PINS = Gpio::pin_count;
constexpr uint8_t NUM_ANALOG_INPUTS = 16;
#define HAL_SENSITIVE_PINS
// Get the digital pin for an analog index
pin_t analogInputToDigitalPin(const int8_t p);
// Return the index of a pin number
int16_t GET_PIN_MAP_INDEX(const pin_t pin);
// Test whether the pin is valid
bool VALID_PIN(const pin_t p);
// Get the analog index for a digital pin
int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p);
// Test whether the pin is PWM
bool PWM_PIN(const pin_t p);
// Test whether the pin is interruptable
bool INTERRUPT_PIN(const pin_t p);
// Get the pin number at the given index
pin_t GET_PIN_MAP_PIN(const int16_t ind);
// Parse a G-code word into a pin index
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
+207
View File
@@ -0,0 +1,207 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(EMERGENCY_PARSER)
#include "../../../feature/emergency_parser.h"
#endif
#include <stdarg.h>
#include <stdio.h>
/**
* Generic RingBuffer
* T type of the buffer array
* S size of the buffer (must be power of 2)
*
*/
template <typename T, uint32_t S> class RingBuffer {
public:
RingBuffer() { index_read = index_write = 0; }
uint32_t available() volatile { return index_write - index_read; }
uint32_t free() volatile { return buffer_size - available(); }
bool empty() volatile { return index_read == index_write; }
bool full() volatile { return available() == buffer_size; }
void clear() volatile { index_read = index_write = 0; }
bool peek(T *value) volatile {
if (value == 0 || available() == 0)
return false;
*value = buffer[mask(index_read)];
return true;
}
int read() volatile {
if (empty()) return -1;
return buffer[mask(index_read++)];
}
bool write(T value) volatile {
if (full()) return false;
buffer[mask(index_write++)] = value;
return true;
}
private:
uint32_t mask(uint32_t val) volatile {
return buffer_mask & val;
}
static const uint32_t buffer_size = S;
static const uint32_t buffer_mask = buffer_size - 1;
volatile T buffer[buffer_size];
volatile uint32_t index_write;
volatile uint32_t index_read;
};
class HalSerial {
public:
#if ENABLED(EMERGENCY_PARSER)
EmergencyParser::State emergency_state;
#endif
HalSerial() { host_connected = true; }
void begin(int32_t baud) {
}
int peek() {
uint8_t value;
return receive_buffer.peek(&value) ? value : -1;
}
int read() { return receive_buffer.read(); }
size_t write(char c) {
if (!host_connected) return 0;
while (!transmit_buffer.free());
return transmit_buffer.write(c);
}
operator bool() { return host_connected; }
uint16_t available() {
return (uint16_t)receive_buffer.available();
}
void flush() { receive_buffer.clear(); }
uint8_t availableForWrite(void){
return transmit_buffer.free() > 255 ? 255 : (uint8_t)transmit_buffer.free();
}
void flushTX(void){
if (host_connected)
while (transmit_buffer.available()) { /* nada */ }
}
void printf(const char *format, ...) {
static char buffer[256];
va_list vArgs;
va_start(vArgs, format);
int length = vsnprintf((char *) buffer, 256, (char const *) format, vArgs);
va_end(vArgs);
if (length > 0 && length < 256) {
if (host_connected) {
for (int i = 0; i < length;) {
if (transmit_buffer.write(buffer[i])) {
++i;
}
}
}
}
}
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
void print_bin(uint32_t value, uint8_t num_digits) {
uint32_t mask = 1 << (num_digits -1);
for (uint8_t i = 0; i < num_digits; i++) {
if (!(i % 4) && i) write(' ');
if (!(i % 16) && i) write(' ');
if (value & mask) write('1');
else write('0');
value <<= 1;
}
}
void print(const char value[]) { printf("%s" , value); }
void print(char value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 8);
else if (nbase == OCT) printf("%3o", value);
else if (nbase == HEX) printf("%2X", value);
else if (nbase == DEC ) printf("%d", value);
else printf("%c" , value);
}
void print(unsigned char value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 8);
else if (nbase == OCT) printf("%3o", value);
else if (nbase == HEX) printf("%2X", value);
else printf("%u" , value);
}
void print(int value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 16);
else if (nbase == OCT) printf("%6o", value);
else if (nbase == HEX) printf("%4X", value);
else printf("%d", value);
}
void print(unsigned int value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 16);
else if (nbase == OCT) printf("%6o", value);
else if (nbase == HEX) printf("%4X", value);
else printf("%u" , value);
}
void print(long value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 32);
else if (nbase == OCT) printf("%11o", value);
else if (nbase == HEX) printf("%8X", value);
else printf("%ld" , value);
}
void print(unsigned long value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 32);
else if (nbase == OCT) printf("%11o", value);
else if (nbase == HEX) printf("%8X", value);
else printf("%lu" , value);
}
void print(float value, int round = 6) { printf("%f" , value); }
void print(double value, int round = 6) { printf("%f" , value); }
void println(const char value[]) { printf("%s\n" , value); }
void println(char value, int nbase = 0) { print(value, nbase); println(); }
void println(unsigned char value, int nbase = 0) { print(value, nbase); println(); }
void println(int value, int nbase = 0) { print(value, nbase); println(); }
void println(unsigned int value, int nbase = 0) { print(value, nbase); println(); }
void println(long value, int nbase = 0) { print(value, nbase); println(); }
void println(unsigned long value, int nbase = 0) { print(value, nbase); println(); }
void println(float value, int round = 6) { printf("%f\n" , value); }
void println(double value, int round = 6) { printf("%f\n" , value); }
void println(void) { print('\n'); }
volatile RingBuffer<uint8_t, 128> receive_buffer;
volatile RingBuffer<uint8_t, 128> transmit_buffer;
volatile bool host_connected;
};
+137
View File
@@ -0,0 +1,137 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
extern void setup();
extern void loop();
#include <thread>
#include <iostream>
#include <fstream>
#include "../../inc/MarlinConfig.h"
#include <stdio.h>
#include <stdarg.h>
#include "../shared/Delay.h"
#include "hardware/IOLoggerCSV.h"
#include "hardware/Heater.h"
#include "hardware/LinearAxis.h"
// simple stdout / stdin implementation for fake serial port
void write_serial_thread() {
for (;;) {
for (std::size_t i = usb_serial.transmit_buffer.available(); i > 0; i--) {
fputc(usb_serial.transmit_buffer.read(), stdout);
}
std::this_thread::yield();
}
}
void read_serial_thread() {
char buffer[255] = {};
for (;;) {
std::size_t len = MIN(usb_serial.receive_buffer.free(), 254U);
if (fgets(buffer, len, stdin))
for (std::size_t i = 0; i < strlen(buffer); i++)
usb_serial.receive_buffer.write(buffer[i]);
std::this_thread::yield();
}
}
void simulation_loop() {
Heater hotend(HEATER_0_PIN, TEMP_0_PIN);
Heater bed(HEATER_BED_PIN, TEMP_BED_PIN);
LinearAxis x_axis(X_ENABLE_PIN, X_DIR_PIN, X_STEP_PIN, X_MIN_PIN, X_MAX_PIN);
LinearAxis y_axis(Y_ENABLE_PIN, Y_DIR_PIN, Y_STEP_PIN, Y_MIN_PIN, Y_MAX_PIN);
LinearAxis z_axis(Z_ENABLE_PIN, Z_DIR_PIN, Z_STEP_PIN, Z_MIN_PIN, Z_MAX_PIN);
LinearAxis extruder0(E0_ENABLE_PIN, E0_DIR_PIN, E0_STEP_PIN, P_NC, P_NC);
//#define GPIO_LOGGING // Full GPIO and Positional Logging
#ifdef GPIO_LOGGING
IOLoggerCSV logger("all_gpio_log.csv");
Gpio::attachLogger(&logger);
std::ofstream position_log;
position_log.open("axis_position_log.csv");
int32_t x,y,z;
#endif
for (;;) {
hotend.update();
bed.update();
x_axis.update();
y_axis.update();
z_axis.update();
extruder0.update();
#ifdef GPIO_LOGGING
if (x_axis.position != x || y_axis.position != y || z_axis.position != z) {
uint64_t update = MAX3(x_axis.last_update, y_axis.last_update, z_axis.last_update);
position_log << update << ", " << x_axis.position << ", " << y_axis.position << ", " << z_axis.position << std::endl;
position_log.flush();
x = x_axis.position;
y = y_axis.position;
z = z_axis.position;
}
// flush the logger
logger.flush();
#endif
std::this_thread::yield();
}
}
int main(void) {
std::thread write_serial (write_serial_thread);
std::thread read_serial (read_serial_thread);
#if NUM_SERIAL > 0
MYSERIAL0.begin(BAUDRATE);
SERIAL_PRINTF("x86_64 Initialised\n");
SERIAL_FLUSHTX();
#endif
Clock::setFrequency(F_CPU);
Clock::setTimeMultiplier(1.0); // some testing at 10x
HAL_timer_init();
std::thread simulation (simulation_loop);
DELAY_US(10000);
setup();
for (;;) {
loop();
std::this_thread::yield();
}
simulation.join();
write_serial.join();
read_serial.join();
}
#endif // __PLAT_LINUX__
@@ -0,0 +1,101 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "../../inc/MarlinConfig.h"
#if ENABLED(EEPROM_SETTINGS)
#include "../shared/persistent_store_api.h"
#include <stdio.h>
uint8_t buffer[E2END];
char filename[] = "eeprom.dat";
bool PersistentStore::access_start() {
const char eeprom_erase_value = 0xFF;
FILE * eeprom_file = fopen(filename, "rb");
if (eeprom_file == NULL) return false;
fseek(eeprom_file, 0L, SEEK_END);
std::size_t file_size = ftell(eeprom_file);
if (file_size < E2END) {
memset(buffer + file_size, eeprom_erase_value, E2END - file_size);
}
else {
fseek(eeprom_file, 0L, SEEK_SET);
fread(buffer, sizeof(uint8_t), sizeof(buffer), eeprom_file);
}
fclose(eeprom_file);
return true;
}
bool PersistentStore::access_finish() {
FILE * eeprom_file = fopen(filename, "wb");
if (eeprom_file == NULL) return false;
fwrite(buffer, sizeof(uint8_t), sizeof(buffer), eeprom_file);
fclose(eeprom_file);
return true;
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, const size_t size, uint16_t *crc) {
std::size_t bytes_written = 0;
for (std::size_t i = 0; i < size; i++) {
buffer[pos+i] = value[i];
bytes_written ++;
}
crc16(crc, value, size);
pos = pos + size;
return (bytes_written != size); // return true for any error
}
bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
std::size_t bytes_read = 0;
if (writing) {
for (std::size_t i = 0; i < size; i++) {
value[i] = buffer[pos+i];
bytes_read ++;
}
crc16(crc, value, size);
}
else {
uint8_t temp[size];
for (std::size_t i = 0; i < size; i++) {
temp[i] = buffer[pos+i];
bytes_read ++;
}
crc16(crc, temp, size);
}
pos = pos + size;
return bytes_read != size; // return true for any error
}
size_t PersistentStore::capacity() { return 4096; } // 4KiB of Emulated EEPROM
#endif // EEPROM_SETTINGS
#endif // __PLAT_LINUX__
+63
View File
@@ -0,0 +1,63 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Support routines for X86_64
*/
/**
* Translation of routines & variables used by pinsDebug.h
*/
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
#define pwm_details(pin) pin = pin // do nothing // print PWM details
#define pwm_status(pin) false //Print a pin's PWM status. Return true if it's currently a PWM pin.
#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
#define digitalRead_mod(p) digitalRead(p)
#define PRINT_PORT(p)
#define GET_ARRAY_PIN(p) pin_array[p].pin
#define NAME_FORMAT(p) PSTR("%-##p##s")
#define PRINT_ARRAY_NAME(x) do {sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer);} while (0)
#define PRINT_PIN(p) do {sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer);} while (0)
#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin
// active ADC function/mode/code values for PINSEL registers
constexpr int8_t ADC_pin_mode(pin_t pin) {
return (-1);
}
int8_t get_pin_mode(pin_t pin) {
if (!VALID_PIN(pin)) return -1;
return 0;
}
bool GET_PINMODE(pin_t pin) {
int8_t pin_mode = get_pin_mode(pin);
if (pin_mode == -1 || pin_mode == ADC_pin_mode(pin)) // found an invalid pin or active analog pin
return false;
return (Gpio::getMode(pin) != 0); //input/output state
}
bool GET_ARRAY_IS_DIGITAL(pin_t pin) {
return (!IS_ANALOG(pin) || get_pin_mode(pin) != ADC_pin_mode(pin));
}
+80
View File
@@ -0,0 +1,80 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
* Copyright (c) 2009 Michael Margolis. All right reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* Based on "servo.h - Interrupt driven Servo library for Arduino using 16 bit timers -
* Version 2 Copyright (c) 2009 Michael Margolis. All right reserved.
*
* The only modification was to update/delete macros to match the LPC176x.
*
*/
#include <stdint.h>
// Macros
//values in microseconds
#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
#define REFRESH_INTERVAL 20000 // minimum time to refresh servos in microseconds
#define MAX_SERVOS 4
#define INVALID_SERVO 255 // flag indicating an invalid servo index
// Types
typedef struct {
uint8_t nbr : 8 ; // a pin number from 0 to 254 (255 signals invalid pin)
uint8_t isActive : 1 ; // true if this channel is enabled, pin not pulsed if false
} ServoPin_t;
typedef struct {
ServoPin_t Pin;
unsigned int pulse_width; // pulse width in microseconds
} ServoInfo_t;
// Global variables
extern uint8_t ServoCount;
extern ServoInfo_t servo_info[MAX_SERVOS];
+53
View File
@@ -0,0 +1,53 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "src/core/macros.h"
#if BOTH(SDSUPPORT, DOGLCD) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN)
#define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently
// needed due to the speed and mode requred for communicating with each device being different.
// This requirement can be removed if the SPI access to these devices is updated to use
// spiBeginTransaction.
#endif
/** onboard SD card */
//#define SCK_PIN P0_07
//#define MISO_PIN P0_08
//#define MOSI_PIN P0_09
//#define SS_PIN P0_06
/** external */
#ifndef SCK_PIN
#define SCK_PIN 50
#endif
#ifndef MISO_PIN
#define MISO_PIN 51
#endif
#ifndef MOSI_PIN
#define MOSI_PIN 52
#endif
#ifndef SS_PIN
#define SS_PIN 53
#endif
#ifndef SDSS
#define SDSS SS_PIN
#endif
+46
View File
@@ -0,0 +1,46 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "../../inc/MarlinConfig.h"
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
void watchdog_init(void) {}
void HAL_clear_reset_source(void) {}
uint8_t HAL_get_reset_source(void) {
return RST_POWER_ON;
}
void watchdog_reset() {}
#else
void HAL_clear_reset_source(void) {}
uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
#endif // USE_WATCHDOG
#endif // __PLAT_LINUX__
+34
View File
@@ -0,0 +1,34 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#define RST_POWER_ON 1
#define RST_EXTERNAL 2
#define RST_BROWN_OUT 4
#define RST_WATCHDOG 8
#define WDT_TIMEOUT 4000000 // 4 second timeout
void watchdog_init(void);
void watchdog_reset(void);
void HAL_clear_reset_source(void);
uint8_t HAL_get_reset_source(void);
+4
View File
@@ -59,4 +59,8 @@ int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
return ind > -2 ? ind : dval;
}
void flashFirmware(int16_t value) {
NVIC_SystemReset();
}
#endif // TARGET_LPC1768
+19
View File
@@ -154,3 +154,22 @@ int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
#define HAL_IDLETASK 1
void HAL_idletask(void);
#define PLATFORM_M997_SUPPORT
void flashFirmware(int16_t value);
/**
* set_pwm_frequency
* Set the frequency of the timer corresponding to the provided pin
* All Hardware PWM pins run at the same frequency and all
* Software PWM pins run at the same frequency
*/
void set_pwm_frequency(const pin_t pin, int f_desired);
/**
* set_pwm_duty
* Set the PWM duty cycle of the provided pin to the provided value
* Optionally allows inverting the duty cycle [default = false]
* Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
*/
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
+10 -14
View File
@@ -81,17 +81,15 @@
uint8_t spiRec() { return spiTransfer(0xFF); }
void spiRead(uint8_t*buf, uint16_t nbyte) {
if (nbyte)
for (int i = 0; i < nbyte; i++)
buf[i] = spiTransfer(0xFF);
for (int i = 0; i < nbyte; i++)
buf[i] = spiTransfer(0xFF);
}
void spiSend(uint8_t b) { (void)spiTransfer(b); }
void spiSend(const uint8_t* buf, size_t n) {
if (n)
for (uint16_t i = 0; i < n; i++)
(void)spiTransfer(buf[i]);
void spiSend(const uint8_t* buf, size_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++)
(void)spiTransfer(buf[i]);
}
void spiSendBlock(uint8_t token, const uint8_t* buf) {
@@ -178,15 +176,14 @@
void spiSend(uint8_t b) { doio(b); }
void spiSend(const uint8_t* buf, size_t n) {
if (n)
for (uint16_t i = 0; i < n; i++) doio(buf[i]);
void spiSend(const uint8_t* buf, size_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]);
}
void spiSend(uint32_t chan, byte b) {
}
void spiSend(uint32_t chan, const uint8_t* buf, size_t n) {
void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {
}
// Read single byte from SPI
@@ -195,9 +192,8 @@
uint8_t spiRec(uint32_t chan) { return 0; }
// Read from SPI into buffer
void spiRead(uint8_t*buf, uint16_t nbyte) {
if (nbyte)
for (int i = 0; i < nbyte; i++) buf[i] = doio(0xff);
void spiRead(uint8_t *buf, uint16_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF);
}
static uint8_t spiTransfer(uint8_t b) {
+2 -2
View File
@@ -88,8 +88,8 @@ typedef uint32_t hal_timer_t;
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define HAL_STEP_TIMER_ISR _HAL_TIMER_ISR(STEP_TIMER_NUM)
#define HAL_TEMP_TIMER_ISR _HAL_TIMER_ISR(TEMP_TIMER_NUM)
#define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(STEP_TIMER_NUM)
#define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(TEMP_TIMER_NUM)
// Timer references by index
#define STEP_TIMER _HAL_TIMER(STEP_TIMER_NUM)
+40
View File
@@ -0,0 +1,40 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(FAST_PWM_FAN)
#include <pwm.h>
void set_pwm_frequency(const pin_t pin, int f_desired) {
pwm_set_frequency(pin, f_desired);
}
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);
}
#endif // FAST_PWM_FAN
#endif // TARGET_LPC1768
+40 -33
View File
@@ -35,21 +35,22 @@
#include <Arduino.h>
#define USEABLE_HARDWARE_PWM(pin) TRUE // all pins are PWM capable
#define PWM_PIN(P) true // all pins are PWM capable
#define USEABLE_HARDWARE_PWM(P) PWM_PIN(P)
#define LPC_PIN(pin) gpio_pin(pin)
#define LPC_GPIO(port) gpio_port(port)
#define LPC_PIN(pin) gpio_pin(pin)
#define LPC_GPIO(port) gpio_port(port)
#define SET_DIR_INPUT(IO) gpio_set_input(IO)
#define SET_DIR_OUTPUT(IO) gpio_set_output(IO)
#define SET_DIR_INPUT(IO) gpio_set_input(IO)
#define SET_DIR_OUTPUT(IO) gpio_set_output(IO)
#define SET_MODE(IO, mode) pinMode(IO, mode)
#define SET_MODE(IO, mode) pinMode(IO, mode)
#define WRITE_PIN_SET(IO) gpio_set(IO)
#define WRITE_PIN_CLR(IO) gpio_clear(IO)
#define WRITE_PIN_SET(IO) gpio_set(IO)
#define WRITE_PIN_CLR(IO) gpio_clear(IO)
#define READ_PIN(IO) gpio_get(IO)
#define WRITE_PIN(IO,V) gpio_set(IO, V)
#define READ_PIN(IO) gpio_get(IO)
#define WRITE_PIN(IO,V) gpio_set(IO, V)
/**
* Magic I/O routines
@@ -60,64 +61,70 @@
*/
/// Read a pin
#define _READ(IO) READ_PIN(IO)
#define _READ(IO) READ_PIN(IO)
/// Write to a pin
#define _WRITE_VAR(IO,V) digitalWrite(IO,V)
#define _WRITE_VAR(IO,V) digitalWrite(IO,V)
#define _WRITE(IO,V) WRITE_PIN(IO,V)
#define _WRITE(IO,V) WRITE_PIN(IO,V)
/// toggle a pin
#define _TOGGLE(IO) _WRITE(IO, !READ(IO))
#define _TOGGLE(IO) _WRITE(IO, !READ(IO))
/// set pin as input
#define _SET_INPUT(IO) SET_DIR_INPUT(IO)
#define _SET_INPUT(IO) SET_DIR_INPUT(IO)
/// set pin as output
#define _SET_OUTPUT(IO) SET_DIR_OUTPUT(IO)
#define _SET_OUTPUT(IO) SET_DIR_OUTPUT(IO)
/// set pin as input with pullup mode
#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT)
#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT)
/// set pin as input with pulldown mode
#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT)
#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT)
/// check if pin is an input
#define _GET_INPUT(IO) (!gpio_get_dir(IO))
#define _IS_INPUT(IO) (!gpio_get_dir(IO))
/// check if pin is an output
#define _GET_OUTPUT(IO) (gpio_get_dir(IO))
#define _IS_OUTPUT(IO) (gpio_get_dir(IO))
/// check if pin is a timer
/// all gpio pins are pwm capable, either interrupt or hardware pwm controlled
#define _GET_TIMER(IO) TRUE
#define _HAS_TIMER(IO) true
/// Read a pin wrapper
#define READ(IO) _READ(IO)
#define READ(IO) _READ(IO)
/// Write to a pin wrapper
#define WRITE_VAR(IO,V) _WRITE_VAR(IO,V)
#define WRITE(IO,V) _WRITE(IO,V)
#define WRITE_VAR(IO,V) _WRITE_VAR(IO,V)
#define WRITE(IO,V) _WRITE(IO,V)
/// toggle a pin wrapper
#define TOGGLE(IO) _TOGGLE(IO)
#define TOGGLE(IO) _TOGGLE(IO)
/// set pin as input wrapper
#define SET_INPUT(IO) _SET_INPUT(IO)
#define SET_INPUT(IO) _SET_INPUT(IO)
/// set pin as input with pullup wrapper
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
/// set pin as input with pulldown wrapper
#define SET_INPUT_PULLDOWN(IO) do{ _SET_INPUT(IO); _PULLDOWN(IO, HIGH); }while(0)
#define SET_INPUT_PULLDOWN(IO) do{ _SET_INPUT(IO); _PULLDOWN(IO, HIGH); }while(0)
/// set pin as output wrapper - reads the pin and sets the output to that value
#define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0)
#define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0)
// set pin as PWM
#define SET_PWM(IO) SET_OUTPUT(IO)
/// check if pin is an input wrapper
#define GET_INPUT(IO) _GET_INPUT(IO)
#define IS_INPUT(IO) _IS_INPUT(IO)
/// check if pin is an output wrapper
#define GET_OUTPUT(IO) _GET_OUTPUT(IO)
#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
/// check if pin is a timer (wrapper)
#define GET_TIMER(IO) _GET_TIMER(IO)
#define HAS_TIMER(IO) _HAS_TIMER(IO)
// Shorthand
#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
// digitalRead/Write wrappers
#define extDigitalRead(IO) digitalRead(IO)
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
+1 -1
View File
@@ -98,7 +98,7 @@ void HAL_init() {
// HAL idle task
void HAL_idletask(void) {
#if ENABLED(SDSUPPORT) && ENABLED(SHARED_SD_CARD)
#if BOTH(SDSUPPORT, SHARED_SD_CARD)
// If Marlin is using the SD card we need to lock it to prevent access from
// a PC via USB.
// Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but
@@ -21,4 +21,4 @@
*/
#include "../shared/persistent_store_api.h"
#define FLASH_EEPROM
#define FLASH_EEPROM_EMULATION
@@ -43,7 +43,7 @@
#include "persistent_store_api.h"
#include "../../inc/MarlinConfig.h"
#if ENABLED(FLASH_EEPROM)
#if ENABLED(FLASH_EEPROM_EMULATION)
extern "C" {
#include "lpc17xx_iap.h"
@@ -54,7 +54,7 @@ extern "C" {
#define EEPROM_SIZE (4096)
#define SECTOR_SIZE (32768)
#define EEPROM_SLOTS (SECTOR_SIZE/EEPROM_SIZE)
#define EEPROM_ERASE (0xff)
#define EEPROM_ERASE (0xFF)
#define SLOT_ADDRESS(sector, slot) (((uint8_t *)SECTOR_START(sector)) + slot * EEPROM_SIZE)
static uint8_t ram_eeprom[EEPROM_SIZE] __attribute__((aligned(4))) = {0};
@@ -74,7 +74,8 @@ bool PersistentStore::access_start() {
// sector is blank so nothing stored yet
for (int i = 0; i < EEPROM_SIZE; i++) ram_eeprom[i] = EEPROM_ERASE;
current_slot = EEPROM_SLOTS;
} else {
}
else {
// current slot is the first non blank one
current_slot = first_nblank_loc / EEPROM_SIZE;
uint8_t *eeprom_data = SLOT_ADDRESS(EEPROM_SECTOR, current_slot);
@@ -126,6 +127,6 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t
size_t PersistentStore::capacity() { return EEPROM_SIZE; }
#endif // FLASH_EEPROM
#endif // FLASH_EEPROM_EMULATION
#endif // EEPROM_SETTINGS
#endif // TARGET_LPC1768
@@ -29,7 +29,7 @@
#include "../../inc/MarlinConfig.h"
#include "persistent_store_api.h"
#if DISABLED(FLASH_EEPROM)
#if DISABLED(FLASH_EEPROM_EMULATION)
#include <chanfs/diskio.h>
#include <chanfs/ff.h>
@@ -178,6 +178,6 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uin
size_t PersistentStore::capacity() { return 4096; } // 4KiB of Emulated EEPROM
#endif // !FLASH_EEPROM
#endif // !FLASH_EEPROM_EMULATION
#endif // EEPROM_SETTINGS
#endif // TARGET_LPC1768
+1 -1
View File
@@ -32,7 +32,7 @@
#define pwm_details(pin) pin = pin // do nothing // print PWM details
#define pwm_status(pin) false //Print a pin's PWM status. Return true if it's currently a PWM pin.
#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
#define digitalRead_mod(p) digitalRead(p)
#define digitalRead_mod(p) extDigitalRead(p)
#define PRINT_PORT(p)
#define GET_ARRAY_PIN(p) pin_array[p].pin
#define NAME_FORMAT(p) PSTR("%-##p##s")
@@ -26,8 +26,6 @@
* COM interface for Arduino (AND ATmega) and the SSDxxxx chip (SOLOMON) variant
* I2C protocol
*
* ToDo: Rename this to u8g_com_avr_ssd_i2c.c
*
* Universal 8bit Graphics Library
*
* Copyright (c) 2011, olikraus@gmail.com
@@ -68,23 +68,15 @@
static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL;
static uint8_t SPI_speed = 0;
static uint8_t rs_last_state = 255;
static void u8g_com_LPC1768_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val) {
if (rs != rs_last_state) { // time to send a command/data byte
static uint8_t rs_last_state = 255;
if (rs != rs_last_state) {
// Transfer Data (FA) or Command (F8)
swSpiTransfer(rs ? 0x0FA : 0x0F8, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
rs_last_state = rs;
if (rs == 0)
/* command */
swSpiTransfer(0x0F8, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
else
/* data */
swSpiTransfer(0x0FA, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
DELAY_US(40); // give the controller some time to process the data: 20 is bad, 30 is OK, 40 is safe
DELAY_US(40); // Give the controller time to process the data: 20 is bad, 30 is OK, 40 is safe
}
swSpiTransfer(val & 0x0F0, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
swSpiTransfer(val << 4, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
}
+10 -6
View File
@@ -42,8 +42,6 @@
#include "fastio_STM32.h"
#include "watchdog_STM32.h"
#include "HAL_timers_STM32.h"
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
@@ -101,6 +99,8 @@
#define NUM_SERIAL 1
#endif
#include "HAL_timers_STM32.h"
/**
* TODO: review this to return 1 for pins that are not analog input
*/
@@ -176,7 +176,10 @@ static inline int freeMemory() {
return &top - reinterpret_cast<char*>(_sbrk(0));
}
//
// SPI: Extended functions which take a channel number (hardware SPI only)
//
/** Write single byte to specified SPI channel */
void spiSend(uint32_t chan, byte b);
/** Write buffer to specified SPI channel */
@@ -184,18 +187,19 @@ void spiSend(uint32_t chan, const uint8_t* buf, size_t n);
/** Read single byte from specified SPI channel */
uint8_t spiRec(uint32_t chan);
//
// EEPROM
//
/**
* Wire library should work for i2c eeproms.
*/
// Wire library should work for i2c EEPROMs
void eeprom_write_byte(uint8_t *pos, unsigned char value);
uint8_t eeprom_read_byte(uint8_t *pos);
void eeprom_read_block (void *__dst, const void *__src, size_t __n);
void eeprom_update_block (const void *__src, void *__dst, size_t __n);
//
// ADC
//
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)
+2 -2
View File
@@ -137,8 +137,8 @@
extern void Step_Handler(stimer_t *htim);
extern void Temp_Handler(stimer_t *htim);
#define HAL_STEP_TIMER_ISR void Step_Handler(stimer_t *htim)
#define HAL_TEMP_TIMER_ISR void Temp_Handler(stimer_t *htim)
#define HAL_STEP_TIMER_ISR() void Step_Handler(stimer_t *htim)
#define HAL_TEMP_TIMER_ISR() void Temp_Handler(stimer_t *htim)
// --------------------------------------------------------------------------
// Types
+4
View File
@@ -69,3 +69,7 @@
#if ENABLED(EMERGENCY_PARSER)
#error "EMERGENCY_PARSER is not yet implemented for STM32. Disable EMERGENCY_PARSER to continue."
#endif
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
+14 -5
View File
@@ -45,6 +45,10 @@ void FastIO_init(); // Must be called before using fast io macros
#define _BV32(b) (1UL << (b))
#if !defined(PWM)
#define PWM OUTPUT
#endif
#if defined(STM32F0xx) || defined(STM32F1xx) || defined(STM32F3xx) || defined(STM32L0xx) || defined(STM32L4xx)
#define _WRITE(IO, V) do { \
if (V) FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO])) ; \
@@ -72,10 +76,15 @@ void FastIO_init(); // Must be called before using fast io macros
#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, INPUT_PULLUP) /*!< Input with Pull-up activation */
#define SET_INPUT_PULLDOWN(IO) _SET_MODE(IO, INPUT_PULLDOWN) /*!< Input with Pull-down activation */
#define SET_OUTPUT(IO) OUT_WRITE(IO, LOW)
#define SET_PWM(IO) _SET_MODE(IO, PWM)
#define GET_INPUT(IO)
#define GET_OUTPUT(IO)
#define GET_TIMER(IO)
#define IS_INPUT(IO)
#define IS_OUTPUT(IO)
#define HAS_TIMER(IO)
#define PWM_PIN(p) digitalPinHasPWM(p)
#define USEABLE_HARDWARE_PWM(p) PWM_PIN(p)
#define PWM_PIN(P) HAS_TIMER(P)
#define USEABLE_HARDWARE_PWM(P) PWM_PIN(P)
// digitalRead/Write wrappers
#define extDigitalRead(IO) digitalRead(IO)
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
@@ -28,20 +28,20 @@
#include "../shared/persistent_store_api.h"
#if DISABLED(EEPROM_EMULATED_WITH_SRAM) && DISABLED(SPI_EEPROM) && DISABLED(I2C_EEPROM)
#if DISABLED(EEPROM_EMULATED_WITH_SRAM, SPI_EEPROM, I2C_EEPROM)
#include <EEPROM.h>
static bool eeprom_data_written = false;
#endif
bool PersistentStore::access_start() {
#if DISABLED(EEPROM_EMULATED_WITH_SRAM) && DISABLED(SPI_EEPROM) && DISABLED(I2C_EEPROM)
#if DISABLED(EEPROM_EMULATED_WITH_SRAM, SPI_EEPROM, I2C_EEPROM)
eeprom_buffer_fill();
#endif
return true;
}
bool PersistentStore::access_finish() {
#if DISABLED(EEPROM_EMULATED_WITH_SRAM) && DISABLED(SPI_EEPROM) && DISABLED(I2C_EEPROM)
#if DISABLED(EEPROM_EMULATED_WITH_SRAM, SPI_EEPROM, I2C_EEPROM)
if (eeprom_data_written) {
eeprom_buffer_flush();
eeprom_data_written = false;
@@ -55,7 +55,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
uint8_t v = *value;
// Save to either external EEPROM, program flash or Backup SRAM
#if ENABLED(SPI_EEPROM) || ENABLED(I2C_EEPROM)
#if EITHER(SPI_EEPROM, I2C_EEPROM)
// EEPROM has only ~100,000 write cycles,
// so only write bytes that have changed!
uint8_t * const p = (uint8_t * const)pos;
@@ -76,7 +76,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
pos++;
value++;
};
#if DISABLED(EEPROM_EMULATED_WITH_SRAM) && DISABLED(SPI_EEPROM) && DISABLED(I2C_EEPROM)
#if DISABLED(EEPROM_EMULATED_WITH_SRAM, SPI_EEPROM, I2C_EEPROM)
eeprom_data_written = true;
#endif
@@ -87,7 +87,7 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t
do {
// Read from either external EEPROM, program flash or Backup SRAM
const uint8_t c = (
#if ENABLED(SPI_EEPROM) || ENABLED(I2C_EEPROM)
#if EITHER(SPI_EEPROM, I2C_EEPROM)
eeprom_read_byte((uint8_t*)pos)
#elif DISABLED(EEPROM_EMULATED_WITH_SRAM)
eeprom_buffered_read_byte(pos)
@@ -105,7 +105,7 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t
}
size_t PersistentStore::capacity() {
#if ENABLED(SPI_EEPROM) || ENABLED(I2C_EEPROM)
#if EITHER(SPI_EEPROM, I2C_EEPROM)
return E2END + 1;
#elif DISABLED(EEPROM_EMULATED_WITH_SRAM)
return E2END + 1;
+28 -8
View File
@@ -33,6 +33,7 @@
#include "HAL.h"
#include <STM32ADC.h>
#include "../../inc/MarlinConfig.h"
// --------------------------------------------------------------------------
// Externals
@@ -91,7 +92,9 @@
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
USBSerial SerialUSB;
#ifdef SERIAL_USB
USBSerial SerialUSB;
#endif
uint16_t HAL_adc_result;
@@ -104,6 +107,12 @@ uint8_t adc_pins[] = {
#if HAS_TEMP_ADC_0
TEMP_0_PIN,
#endif
#if HAS_HEATED_BED
TEMP_BED_PIN,
#endif
#if HAS_HEATED_CHAMBER
TEMP_CHAMBER_PIN,
#endif
#if HAS_TEMP_ADC_1
TEMP_1_PIN,
#endif
@@ -116,8 +125,8 @@ uint8_t adc_pins[] = {
#if HAS_TEMP_ADC_4
TEMP_4_PIN,
#endif
#if HAS_HEATED_BED
TEMP_BED_PIN,
#if HAS_TEMP_ADC_5
TEMP_5_PIN,
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
FILWIDTH_PIN,
@@ -128,6 +137,12 @@ enum TEMP_PINS : char {
#if HAS_TEMP_ADC_0
TEMP_0,
#endif
#if HAS_HEATED_BED
TEMP_BED,
#endif
#if HAS_HEATED_CHAMBER
TEMP_CHAMBER,
#endif
#if HAS_TEMP_ADC_1
TEMP_1,
#endif
@@ -140,8 +155,8 @@ enum TEMP_PINS : char {
#if HAS_TEMP_ADC_4
TEMP_4,
#endif
#if HAS_HEATED_BED
TEMP_BED,
#if HAS_TEMP_ADC_5
TEMP_5,
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
FILWIDTH,
@@ -192,7 +207,6 @@ static void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) {
} }
#endif
void HAL_init(void) {
NVIC_SetPriorityGrouping(0x3);
}
@@ -268,6 +282,12 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
#if HAS_TEMP_ADC_0
case TEMP_0_PIN: pin_index = TEMP_0; break;
#endif
#if HAS_HEATED_BED
case TEMP_BED_PIN: pin_index = TEMP_BED; break;
#endif
#if HAS_HEATED_CHAMBER
case TEMP_CHAMBER_PIN: pin_index = TEMP_CHAMBER; break;
#endif
#if HAS_TEMP_ADC_1
case TEMP_1_PIN: pin_index = TEMP_1; break;
#endif
@@ -280,8 +300,8 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
#if HAS_TEMP_ADC_4
case TEMP_4_PIN: pin_index = TEMP_4; break;
#endif
#if HAS_HEATED_BED
case TEMP_BED_PIN: pin_index = TEMP_BED; break;
#if HAS_TEMP_ADC_5
case TEMP_5_PIN: pin_index = TEMP_5; break;
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
case FILWIDTH_PIN: pin_index = FILWIDTH; break;
+63 -24
View File
@@ -51,46 +51,69 @@
#include "watchdog_STM32F1.h"
#include "HAL_timers_STM32F1.h"
#include "../../inc/MarlinConfigPre.h"
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3"
#ifdef SERIAL_USB
#define UsbSerial Serial
#define MSerial1 Serial1
#define MSerial2 Serial2
#define MSerial3 Serial3
#define MSerial4 Serial4
#define MSerial5 Serial5
#else
extern USBSerial SerialUSB;
#define UsbSerial SerialUSB
#define MSerial1 Serial
#define MSerial2 Serial1
#define MSerial3 Serial2
#define MSerial4 Serial3
#define MSerial5 Serial4
#endif
#if !WITHIN(SERIAL_PORT, -1, 5)
#error "SERIAL_PORT must be from -1 to 5"
#endif
#if SERIAL_PORT == -1
extern USBSerial SerialUSB;
#define MYSERIAL0 SerialUSB
#define MYSERIAL0 UsbSerial
#elif SERIAL_PORT == 0
#define MYSERIAL0 Serial
#error "Serial port 0 does not exist"
#elif SERIAL_PORT == 1
#define MYSERIAL0 Serial1
#define MYSERIAL0 MSerial1
#elif SERIAL_PORT == 2
#define MYSERIAL0 Serial2
#define MYSERIAL0 MSerial2
#elif SERIAL_PORT == 3
#define MYSERIAL0 Serial3
#define MYSERIAL0 MSerial3
#elif SERIAL_PORT == 4
#define MYSERIAL0 MSerial4
#elif SERIAL_PORT == 5
#define MYSERIAL0 MSerial5
#endif
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
#error "SERIAL_PORT_2 must be from -1 to 3"
#if !WITHIN(SERIAL_PORT_2, -1, 5)
#error "SERIAL_PORT_2 must be from -1 to 5"
#elif SERIAL_PORT_2 == SERIAL_PORT
#error "SERIAL_PORT_2 must be different than SERIAL_PORT"
#endif
#define NUM_SERIAL 2
#if SERIAL_PORT_2 == -1
extern USBSerial SerialUSB;
#define MYSERIAL1 SerialUSB
#define MYSERIAL1 UsbSerial
#elif SERIAL_PORT_2 == 0
#define MYSERIAL1 Serial
#error "Serial port 0 does not exist"
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 Serial1
#define MYSERIAL1 MSerial1
#elif SERIAL_PORT_2 == 2
#define MYSERIAL1 Serial2
#define MYSERIAL1 MSerial2
#elif SERIAL_PORT_2 == 3
#define MYSERIAL1 Serial3
#define MYSERIAL1 MSerial3
#elif SERIAL_PORT_2 == 4
#define MYSERIAL1 MSerial4
#elif SERIAL_PORT_2 == 5
#define MYSERIAL1 MSerial5
#endif
#else
#define NUM_SERIAL 1
@@ -107,6 +130,10 @@ void HAL_init();
#define analogInputToDigitalPin(p) (p)
#endif
#ifndef digitalPinHasPWM
#define digitalPinHasPWM(P) (PIN_MAP[P].timer_device != NULL)
#endif
#define CRITICAL_SECTION_START uint32_t primask = __get_primask(); (void)__iCliRetVal()
#define CRITICAL_SECTION_END if (!primask) (void)__iSeiRetVal()
#define ISRS_ENABLED() (!__get_primask())
@@ -159,10 +186,10 @@ extern uint16_t HAL_adc_result;
#define __bss_end __bss_end__
/** clear reset reason */
void HAL_clear_reset_source (void);
void HAL_clear_reset_source(void);
/** reset reason */
uint8_t HAL_get_reset_source (void);
uint8_t HAL_get_reset_source(void);
void _delay_ms(const int delay);
@@ -180,12 +207,21 @@ static int freeMemory() {
return top;
}
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static int freeMemory() {
volatile char top;
return &top - reinterpret_cast<char*>(_sbrk(0));
}
#pragma GCC diagnostic pop
//
// SPI: Extended functions which take a channel number (hardware SPI only)
//
/** Write single byte to specified SPI channel */
void spiSend(uint32_t chan, byte b);
/** Write buffer to specified SPI channel */
@@ -193,19 +229,22 @@ void spiSend(uint32_t chan, const uint8_t* buf, size_t n);
/** Read single byte from specified SPI channel */
uint8_t spiRec(uint32_t chan);
//
// EEPROM
//
/**
* TODO: Write all this eeprom stuff. Can emulate eeprom in flash as last resort.
* Wire library should work for i2c eeproms.
* TODO: Write all this EEPROM stuff. Can emulate EEPROM in flash as last resort.
* Wire library should work for i2c EEPROMs.
*/
void eeprom_write_byte(uint8_t *pos, unsigned char value);
uint8_t eeprom_read_byte(uint8_t *pos);
void eeprom_read_block (void *__dst, const void *__src, size_t __n);
void eeprom_update_block (const void *__src, void *__dst, size_t __n);
void eeprom_read_block(void *__dst, const void *__src, size_t __n);
void eeprom_update_block(const void *__src, void *__dst, size_t __n);
//
// ADC
//
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT_ANALOG);
@@ -21,7 +21,7 @@
*
*/
#ifdef __STM32F1__
#if defined(ARDUINO_ARCH_STM32F1) && (defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY))
#include "HAL_sdio_STM32F1.h"
@@ -76,7 +76,7 @@ bool SDIO_Init(void) {
return true;
}
bool SDIO_ReadBlock(uint32_t blockAddress, uint8_t *data) {
bool SDIO_ReadBlock_DMA(uint32_t blockAddress, uint8_t *data) {
if (SDIO_GetCardState() != SDIO_CARD_TRANSFER) return false;
if (blockAddress >= SdCard.LogBlockNbr) return false;
if ((0x03 & (uint32_t)data)) return false; // misaligned data
@@ -100,6 +100,12 @@ bool SDIO_ReadBlock(uint32_t blockAddress, uint8_t *data) {
dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL);
if (SDIO->STA & SDIO_STA_RXDAVL) {
while (SDIO->STA & SDIO_STA_RXDAVL) (void) SDIO->FIFO;
SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS);
return false;
}
if (SDIO_GET_FLAG(SDIO_STA_TRX_ERROR_FLAGS)) {
SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS);
return false;
@@ -108,6 +114,12 @@ bool SDIO_ReadBlock(uint32_t blockAddress, uint8_t *data) {
return true;
}
bool SDIO_ReadBlock(uint32_t blockAddress, uint8_t *data) {
uint32_t retries = 3;
while (retries--) if (SDIO_ReadBlock_DMA(blockAddress, data)) return true;
return false;
}
bool SDIO_WriteBlock(uint32_t blockAddress, const uint8_t *data) {
if (SDIO_GetCardState() != SDIO_CARD_TRANSFER) return false;
if (blockAddress >= SdCard.LogBlockNbr) return false;
@@ -264,4 +276,4 @@ bool SDIO_GetCmdResp7(void) {
return true;
}
#endif // __STM32F1__
#endif // ARDUINO_ARCH_STM32F1 && (STM32_HIGH_DENSITY || STM32_XL_DENSITY)
@@ -85,9 +85,8 @@ timer_dev* get_timer_dev(int number);
// TODO change this
#define HAL_TEMP_TIMER_ISR extern "C" void tempTC_Handler(void)
#define HAL_STEP_TIMER_ISR extern "C" void stepTC_Handler(void)
#define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler(void)
#define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler(void)
extern "C" void tempTC_Handler(void);
extern "C" void stepTC_Handler(void);
+4
View File
@@ -74,3 +74,7 @@
#if ENABLED(SDIO_SUPPORT) && DISABLED(SDSUPPORT)
#error "SDIO_SUPPORT requires SDSUPPORT. Enable SDSUPPORT to continue."
#endif
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
-1
View File
@@ -1 +0,0 @@
#include "bit_constants.h"
+13 -7
View File
@@ -30,7 +30,7 @@
#include <libmaple/gpio.h>
#define READ(IO) (PIN_MAP[IO].gpio_device->regs->IDR & (1U << PIN_MAP[IO].gpio_bit) ? HIGH : LOW)
#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << (16 * !(bool)V))
#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << (16 * !((bool)V)))
#define TOGGLE(IO) (PIN_MAP[IO].gpio_device->regs->ODR = PIN_MAP[IO].gpio_device->regs->ODR ^ (1U << PIN_MAP[IO].gpio_bit))
#define WRITE_VAR(IO,V) WRITE(IO,V)
@@ -42,11 +42,17 @@
#define SET_INPUT(IO) _SET_MODE(IO, GPIO_INPUT_FLOATING)
#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, GPIO_INPUT_PU)
#define SET_OUTPUT(IO) OUT_WRITE(IO,LOW)
#define SET_OUTPUT(IO) OUT_WRITE(IO, LOW)
#define SET_PWM(IO) pinMode(IO, PWM) // do{ gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_AF_OUTPUT_PP); timer_set_mode(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, TIMER_PWM); }while(0)
#define GET_INPUT(IO) (_GET_MODE(IO) == GPIO_INPUT_FLOATING || _GET_MODE(IO) == GPIO_INPUT_ANALOG || _GET_MODE(IO) == GPIO_INPUT_PU || _GET_MODE(IO) == GPIO_INPUT_PD)
#define GET_OUTPUT(IO) (_GET_MODE(IO) == GPIO_OUTPUT_PP)
#define GET_TIMER(IO) (PIN_MAP[IO].timer_device != NULL)
#define IS_INPUT(IO) (_GET_MODE(IO) == GPIO_INPUT_FLOATING || _GET_MODE(IO) == GPIO_INPUT_ANALOG || _GET_MODE(IO) == GPIO_INPUT_PU || _GET_MODE(IO) == GPIO_INPUT_PD)
#define IS_OUTPUT(IO) (_GET_MODE(IO) == GPIO_OUTPUT_PP)
#define HAS_TIMER(IO) (PIN_MAP[IO].timer_device != NULL)
#define PWM_PIN(P) HAS_TIMER(P)
#define USEABLE_HARDWARE_PWM(P) PWM_PIN(P)
// digitalRead/Write wrappers
#define extDigitalRead(IO) digitalRead(IO)
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
#define PWM_PIN(p) true
#define USEABLE_HARDWARE_PWM(p) PWM_PIN(p)
@@ -32,7 +32,7 @@
#include "../../inc/MarlinConfig.h"
// This is for EEPROM emulation in flash
#if ENABLED(EEPROM_SETTINGS) && ENABLED(FLASH_EEPROM_EMULATION)
#if BOTH(EEPROM_SETTINGS, FLASH_EEPROM_EMULATION)
#include "../shared/persistent_store_api.h"
@@ -79,14 +79,15 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, const size_t si
}
// Now, write any remaining single byte
if (size & 1) {
const uint16_t odd = size & 1;
if (odd) {
uint16_t temp = value[size - 1];
status = FLASH_ProgramHalfWord(pageBase + pos + i, temp);
if (status != FLASH_COMPLETE) return true;
}
crc16(crc, value, size);
pos += ((size + 1) & ~1);
pos += size + odd;
return false;
}
@@ -97,7 +98,7 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uin
if (writing) value[i] = c;
crc16(crc, &c, 1);
}
pos += ((size + 1) & ~1);
pos += ((size + 1) & ~1); // i.e., size+(size&1), round up odd values
return false;
}
@@ -55,14 +55,14 @@ bool PersistentStore::access_start() {
bool PersistentStore::access_finish() {
if (!card.isDetected()) return false;
card.openFile(eeprom_filename, true);
card.openFile(eeprom_filename, false);
int16_t bytes_written = card.write(HAL_STM32F1_eeprom_content, HAL_STM32F1_EEPROM_SIZE);
card.closefile();
return (bytes_written == HAL_STM32F1_EEPROM_SIZE);
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, const size_t size, uint16_t *crc) {
for (int i = 0; i < size; i++)
for (size_t i = 0; i < size; i++)
HAL_STM32F1_eeprom_content[pos + i] = value[i];
crc16(crc, value, size);
pos += size;
@@ -70,7 +70,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, const size_t si
}
bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
for (int i = 0; i < size; i++) {
for (size_t i = 0; i < size; i++) {
uint8_t c = HAL_STM32F1_eeprom_content[pos + i];
if (writing) value[i] = c;
crc16(crc, &c, 1);
@@ -26,7 +26,7 @@
* Communication interface for FSMC
*/
#if defined(STM32F1) || defined(STM32F1xx)
#if defined(ARDUINO_ARCH_STM32F1) && (defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY))
#include "../../inc/MarlinConfig.h"
@@ -108,36 +108,43 @@ __attribute__((always_inline)) __STATIC_INLINE void __DSB(void) {
}
#define FSMC_CS_NE1 PD7
#define FSMC_CS_NE2 PG9
#define FSMC_CS_NE3 PG10
#define FSMC_CS_NE4 PG12
#define FSMC_RS_A0 PF0
#define FSMC_RS_A1 PF1
#define FSMC_RS_A2 PF2
#define FSMC_RS_A3 PF3
#define FSMC_RS_A4 PF4
#define FSMC_RS_A5 PF5
#define FSMC_RS_A6 PF12
#define FSMC_RS_A7 PF13
#define FSMC_RS_A8 PF14
#define FSMC_RS_A9 PF15
#define FSMC_RS_A10 PG0
#define FSMC_RS_A11 PG1
#define FSMC_RS_A12 PG2
#define FSMC_RS_A13 PG3
#define FSMC_RS_A14 PG4
#define FSMC_RS_A15 PG5
#define FSMC_RS_A16 PD11
#define FSMC_RS_A17 PD12
#define FSMC_RS_A18 PD13
#define FSMC_RS_A19 PE3
#define FSMC_RS_A20 PE4
#define FSMC_RS_A21 PE5
#define FSMC_RS_A22 PE6
#define FSMC_RS_A23 PE2
#define FSMC_RS_A24 PG13
#define FSMC_RS_A25 PG14
#ifdef STM32_XL_DENSITY
#define FSMC_CS_NE2 PG9
#define FSMC_CS_NE3 PG10
#define FSMC_CS_NE4 PG12
#define FSMC_RS_A0 PF0
#define FSMC_RS_A1 PF1
#define FSMC_RS_A2 PF2
#define FSMC_RS_A3 PF3
#define FSMC_RS_A4 PF4
#define FSMC_RS_A5 PF5
#define FSMC_RS_A6 PF12
#define FSMC_RS_A7 PF13
#define FSMC_RS_A8 PF14
#define FSMC_RS_A9 PF15
#define FSMC_RS_A10 PG0
#define FSMC_RS_A11 PG1
#define FSMC_RS_A12 PG2
#define FSMC_RS_A13 PG3
#define FSMC_RS_A14 PG4
#define FSMC_RS_A15 PG5
#endif
#define FSMC_RS_A16 PD11
#define FSMC_RS_A17 PD12
#define FSMC_RS_A18 PD13
#define FSMC_RS_A19 PE3
#define FSMC_RS_A20 PE4
#define FSMC_RS_A21 PE5
#define FSMC_RS_A22 PE6
#define FSMC_RS_A23 PE2
#ifdef STM32_XL_DENSITY
#define FSMC_RS_A24 PG13
#define FSMC_RS_A25 PG14
#endif
static uint8_t fsmcInit = 0;
@@ -156,31 +163,35 @@ void LCD_IO_Init(uint8_t cs, uint8_t rs) {
switch (cs) {
case FSMC_CS_NE1: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION1; break;
case FSMC_CS_NE2: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION2; break;
case FSMC_CS_NE3: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION3; break;
case FSMC_CS_NE4: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION4; break;
#ifdef STM32_XL_DENSITY
case FSMC_CS_NE2: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION2; break;
case FSMC_CS_NE3: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION3; break;
case FSMC_CS_NE4: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION4; break;
#endif
default: return;
}
#define _ORADDR(N) controllerAddress |= (_BV32(N) - 2)
switch (rs) {
case FSMC_RS_A0: _ORADDR( 1); break;
case FSMC_RS_A1: _ORADDR( 2); break;
case FSMC_RS_A2: _ORADDR( 3); break;
case FSMC_RS_A3: _ORADDR( 4); break;
case FSMC_RS_A4: _ORADDR( 5); break;
case FSMC_RS_A5: _ORADDR( 6); break;
case FSMC_RS_A6: _ORADDR( 7); break;
case FSMC_RS_A7: _ORADDR( 8); break;
case FSMC_RS_A8: _ORADDR( 9); break;
case FSMC_RS_A9: _ORADDR(10); break;
case FSMC_RS_A10: _ORADDR(11); break;
case FSMC_RS_A11: _ORADDR(12); break;
case FSMC_RS_A12: _ORADDR(13); break;
case FSMC_RS_A13: _ORADDR(14); break;
case FSMC_RS_A14: _ORADDR(15); break;
case FSMC_RS_A15: _ORADDR(16); break;
#ifdef STM32_XL_DENSITY
case FSMC_RS_A0: _ORADDR( 1); break;
case FSMC_RS_A1: _ORADDR( 2); break;
case FSMC_RS_A2: _ORADDR( 3); break;
case FSMC_RS_A3: _ORADDR( 4); break;
case FSMC_RS_A4: _ORADDR( 5); break;
case FSMC_RS_A5: _ORADDR( 6); break;
case FSMC_RS_A6: _ORADDR( 7); break;
case FSMC_RS_A7: _ORADDR( 8); break;
case FSMC_RS_A8: _ORADDR( 9); break;
case FSMC_RS_A9: _ORADDR(10); break;
case FSMC_RS_A10: _ORADDR(11); break;
case FSMC_RS_A11: _ORADDR(12); break;
case FSMC_RS_A12: _ORADDR(13); break;
case FSMC_RS_A13: _ORADDR(14); break;
case FSMC_RS_A14: _ORADDR(15); break;
case FSMC_RS_A15: _ORADDR(16); break;
#endif
case FSMC_RS_A16: _ORADDR(17); break;
case FSMC_RS_A17: _ORADDR(18); break;
case FSMC_RS_A18: _ORADDR(19); break;
@@ -189,8 +200,10 @@ void LCD_IO_Init(uint8_t cs, uint8_t rs) {
case FSMC_RS_A21: _ORADDR(22); break;
case FSMC_RS_A22: _ORADDR(23); break;
case FSMC_RS_A23: _ORADDR(24); break;
case FSMC_RS_A24: _ORADDR(25); break;
case FSMC_RS_A25: _ORADDR(26); break;
#ifdef STM32_XL_DENSITY
case FSMC_RS_A24: _ORADDR(25); break;
case FSMC_RS_A25: _ORADDR(26); break;
#endif
default: return;
}
@@ -254,4 +267,4 @@ uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize) {
#endif // HAS_GRAPHICAL_LCD
#endif // STM32F1 || STM32F1xx
#endif // ARDUINO_ARCH_STM32F1 && (STM32_HIGH_DENSITY || STM32_XL_DENSITY)
@@ -26,7 +26,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(EEPROM_SETTINGS) && DISABLED(I2C_EEPROM) && DISABLED(SPI_EEPROM)
#if ENABLED(EEPROM_SETTINGS) && DISABLED(I2C_EEPROM, SPI_EEPROM)
// --------------------------------------------------------------------------
// Includes
@@ -138,5 +138,5 @@ void eeprom_update_block(const void *__src, void *__dst, size_t __n) {
}
#endif // ENABLED(EEPROM_SETTINGS) && DISABLED(I2C_EEPROM) && DISABLED(SPI_EEPROM)
#endif // EEPROM_SETTINGS && (!I2C_EEPROM && !SPI_EEPROM)
#endif // STM32GENERIC && STM32F4
+9 -2
View File
@@ -195,7 +195,10 @@ static int freeMemory() {
return &top - reinterpret_cast<char*>(_sbrk(0));
}
//
// SPI: Extended functions which take a channel number (hardware SPI only)
//
/** Write single byte to specified SPI channel */
void spiSend(uint32_t chan, byte b);
/** Write buffer to specified SPI channel */
@@ -203,18 +206,22 @@ void spiSend(uint32_t chan, const uint8_t* buf, size_t n);
/** Read single byte from specified SPI channel */
uint8_t spiRec(uint32_t chan);
//
// EEPROM
//
/**
* TODO: Write all this eeprom stuff. Can emulate eeprom in flash as last resort.
* Wire library should work for i2c eeproms.
* TODO: Write all this EEPROM stuff. Can emulate EEPROM in flash as last resort.
* Wire library should work for i2c EEPROMs.
*/
void eeprom_write_byte(uint8_t *pos, unsigned char value);
uint8_t eeprom_read_byte(uint8_t *pos);
void eeprom_read_block (void *__dst, const void *__src, size_t __n);
void eeprom_update_block (const void *__src, void *__dst, size_t __n);
//
// ADC
//
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)

Some files were not shown because too many files have changed in this diff Show More