2014-11-08 11:25:51 +00:00
|
|
|
/*
|
|
|
|
This file is part of Repetier-Firmware.
|
|
|
|
|
|
|
|
Repetier-Firmware 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.
|
|
|
|
|
|
|
|
Repetier-Firmware 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 Repetier-Firmware. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
This firmware is a nearly complete rewrite of the sprinter firmware
|
|
|
|
by kliment (https://github.com/kliment/Sprinter)
|
|
|
|
which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
|
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
|
|
|
|
|
2014-11-08 11:25:51 +00:00
|
|
|
Main author: repetier
|
2016-08-29 08:40:14 +00:00
|
|
|
|
2014-11-08 11:25:51 +00:00
|
|
|
Initial port of hardware abstraction layer to Arduino Due: John Silvia
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Repetier.h"
|
|
|
|
#include <malloc.h>
|
|
|
|
|
|
|
|
//extern "C" void __cxa_pure_virtual() { }
|
|
|
|
extern "C" char *sbrk(int i);
|
|
|
|
extern long bresenham_step();
|
|
|
|
|
2015-03-02 05:41:36 +00:00
|
|
|
#define NUM_ADC_SAMPLES 2 + (1 << ANALOG_INPUT_SAMPLE)
|
|
|
|
#if ANALOG_INPUTS > 0
|
|
|
|
int32_t osAnalogInputBuildup[ANALOG_INPUTS];
|
|
|
|
int32_t osAnalogSamples[ANALOG_INPUTS][ANALOG_INPUT_MEDIAN];
|
2016-08-29 08:40:14 +00:00
|
|
|
int32_t osAnalogSamplesSum[ANALOG_INPUTS];
|
2015-03-02 05:41:36 +00:00
|
|
|
static int32_t adcSamplesMin[ANALOG_INPUTS];
|
|
|
|
static int32_t adcSamplesMax[ANALOG_INPUTS];
|
2016-08-29 08:40:14 +00:00
|
|
|
static int adcCounter = 0, adcSamplePos = 0;
|
2015-03-02 05:41:36 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static uint32_t adcEnable = 0;
|
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
char HAL::virtualEeprom[EEPROM_BYTES] = {0,0,0,0,0,0,0};
|
|
|
|
bool HAL::wdPinged = true;
|
|
|
|
volatile uint8_t HAL::insideTimer1 = 0;
|
2014-11-08 11:25:51 +00:00
|
|
|
#ifndef DUE_SOFTWARE_SPI
|
2016-08-29 08:40:14 +00:00
|
|
|
int spiDueDividors[] = {10, 21, 42, 84, 168, 255, 255};
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
HAL::HAL()
|
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
//ctor
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
HAL::~HAL()
|
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
//dtor
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
2015-03-12 05:10:08 +00:00
|
|
|
//Davinci Specific
|
2015-08-10 11:03:29 +00:00
|
|
|
#if FEATURE_BEEPER
|
|
|
|
bool HAL::enablesound = true;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if ENABLE_WIFI
|
|
|
|
bool HAL::bwifion=false;
|
|
|
|
#endif //wifi feature
|
|
|
|
|
2014-11-24 16:02:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
// Set up all timer interrupts
|
|
|
|
void HAL::setupTimer() {
|
|
|
|
uint32_t tc_count, tc_clock;
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
pmc_set_writeprotect(false);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
// set 3 bits for interrupt group priority, 1 bits for sub-priority
|
|
|
|
//NVIC_SetPriorityGrouping(4);
|
|
|
|
|
|
|
|
#if USE_ADVANCE
|
|
|
|
// Timer for extruder control
|
|
|
|
pmc_enable_periph_clk(EXTRUDER_TIMER_IRQ); // enable power to timer
|
|
|
|
//NVIC_SetPriority((IRQn_Type)EXTRUDER_TIMER_IRQ, NVIC_EncodePriority(4, 4, 1));
|
|
|
|
NVIC_SetPriority((IRQn_Type)EXTRUDER_TIMER_IRQ, 6);
|
|
|
|
|
|
|
|
// count up to value in RC register using given clock
|
|
|
|
TC_Configure(EXTRUDER_TIMER, EXTRUDER_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC | TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK3);
|
|
|
|
|
|
|
|
TC_SetRC(EXTRUDER_TIMER, EXTRUDER_TIMER_CHANNEL, (F_CPU_TRUE / 32) / EXTRUDER_CLOCK_FREQ); // set frequency 43 for 60000Hz
|
|
|
|
TC_Start(EXTRUDER_TIMER, EXTRUDER_TIMER_CHANNEL); // start timer running
|
|
|
|
|
|
|
|
// enable RC compare interrupt
|
|
|
|
EXTRUDER_TIMER->TC_CHANNEL[EXTRUDER_TIMER_CHANNEL].TC_IER = TC_IER_CPCS;
|
|
|
|
// clear the "disable RC compare" interrupt
|
|
|
|
EXTRUDER_TIMER->TC_CHANNEL[EXTRUDER_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS;
|
|
|
|
|
|
|
|
// allow interrupts on timer
|
|
|
|
NVIC_EnableIRQ((IRQn_Type)EXTRUDER_TIMER_IRQ);
|
2014-11-24 16:02:56 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
// Regular interrupts for heater control etc
|
|
|
|
pmc_enable_periph_clk(PWM_TIMER_IRQ);
|
|
|
|
//NVIC_SetPriority((IRQn_Type)PWM_TIMER_IRQ, NVIC_EncodePriority(4, 6, 0));
|
|
|
|
NVIC_SetPriority((IRQn_Type)PWM_TIMER_IRQ, 15);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
TC_FindMckDivisor(PWM_CLOCK_FREQ, F_CPU_TRUE, &tc_count, &tc_clock, F_CPU_TRUE);
|
|
|
|
TC_Configure(PWM_TIMER, PWM_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC | TC_CMR_WAVE | tc_clock);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
TC_SetRC(PWM_TIMER, PWM_TIMER_CHANNEL, (F_CPU_TRUE / tc_count) / PWM_CLOCK_FREQ);
|
|
|
|
TC_Start(PWM_TIMER, PWM_TIMER_CHANNEL);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
PWM_TIMER->TC_CHANNEL[PWM_TIMER_CHANNEL].TC_IER = TC_IER_CPCS;
|
|
|
|
PWM_TIMER->TC_CHANNEL[PWM_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS;
|
|
|
|
NVIC_EnableIRQ((IRQn_Type)PWM_TIMER_IRQ);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
// Timer for stepper motor control
|
|
|
|
pmc_enable_periph_clk(TIMER1_TIMER_IRQ );
|
|
|
|
//NVIC_SetPriority((IRQn_Type)TIMER1_TIMER_IRQ, NVIC_EncodePriority(4, 7, 1)); // highest priority - no surprises here wanted
|
|
|
|
NVIC_SetPriority((IRQn_Type)TIMER1_TIMER_IRQ,2); // highest priority - no surprises here wanted
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
TC_Configure(TIMER1_TIMER, TIMER1_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC |
|
|
|
|
TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK1);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
TC_SetRC(TIMER1_TIMER, TIMER1_TIMER_CHANNEL, (F_CPU_TRUE / TIMER1_PRESCALE) / TIMER1_CLOCK_FREQ);
|
|
|
|
TC_Start(TIMER1_TIMER, TIMER1_TIMER_CHANNEL);
|
|
|
|
|
|
|
|
TIMER1_TIMER->TC_CHANNEL[TIMER1_TIMER_CHANNEL].TC_IER = TC_IER_CPCS;
|
|
|
|
TIMER1_TIMER->TC_CHANNEL[TIMER1_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS;
|
|
|
|
NVIC_EnableIRQ((IRQn_Type)TIMER1_TIMER_IRQ);
|
|
|
|
|
|
|
|
// Servo control
|
2014-11-08 11:25:51 +00:00
|
|
|
#if FEATURE_SERVO
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO0_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
SET_OUTPUT(SERVO0_PIN);
|
|
|
|
WRITE(SERVO0_PIN, LOW);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO1_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
SET_OUTPUT(SERVO1_PIN);
|
|
|
|
WRITE(SERVO1_PIN, LOW);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO2_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
SET_OUTPUT(SERVO2_PIN);
|
|
|
|
WRITE(SERVO2_PIN, LOW);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO3_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
SET_OUTPUT(SERVO3_PIN);
|
|
|
|
WRITE(SERVO3_PIN, LOW);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
pmc_enable_periph_clk(SERVO_TIMER_IRQ );
|
|
|
|
//NVIC_SetPriority((IRQn_Type)SERVO_TIMER_IRQ, NVIC_EncodePriority(4, 5, 0));
|
|
|
|
NVIC_SetPriority((IRQn_Type)SERVO_TIMER_IRQ,4);
|
|
|
|
|
|
|
|
TC_Configure(SERVO_TIMER, SERVO_TIMER_CHANNEL, TC_CMR_WAVSEL_UP_RC |
|
|
|
|
TC_CMR_WAVE | TC_CMR_TCCLKS_TIMER_CLOCK1);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
TC_SetRC(SERVO_TIMER, SERVO_TIMER_CHANNEL, (F_CPU_TRUE / SERVO_PRESCALE) / SERVO_CLOCK_FREQ);
|
|
|
|
TC_Start(SERVO_TIMER, SERVO_TIMER_CHANNEL);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
SERVO_TIMER->TC_CHANNEL[SERVO_TIMER_CHANNEL].TC_IER = TC_IER_CPCS;
|
|
|
|
SERVO_TIMER->TC_CHANNEL[SERVO_TIMER_CHANNEL].TC_IDR = ~TC_IER_CPCS;
|
|
|
|
NVIC_EnableIRQ((IRQn_Type)SERVO_TIMER_IRQ);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-02-27 09:24:25 +00:00
|
|
|
#if ANALOG_INPUTS > 0
|
2014-11-08 11:25:51 +00:00
|
|
|
// Initialize ADC channels
|
|
|
|
void HAL::analogStart(void)
|
|
|
|
{
|
2015-03-02 05:41:36 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
#if MOTHERBOARD == 500 || MOTHERBOARD == 501
|
|
|
|
PIO_Configure(
|
|
|
|
g_APinDescription[58].pPort,
|
|
|
|
g_APinDescription[58].ulPinType,
|
|
|
|
g_APinDescription[58].ulPin,
|
|
|
|
g_APinDescription[58].ulPinConfiguration);
|
|
|
|
PIO_Configure(
|
|
|
|
g_APinDescription[59].pPort,
|
|
|
|
g_APinDescription[59].ulPinType,
|
|
|
|
g_APinDescription[59].ulPin,
|
|
|
|
g_APinDescription[59].ulPinConfiguration);
|
|
|
|
#endif // (MOTHERBOARD==500) || (MOTHERBOARD==501)
|
2014-11-08 11:25:51 +00:00
|
|
|
|
|
|
|
// ensure we can write to ADC registers
|
2015-03-02 05:41:36 +00:00
|
|
|
ADC->ADC_WPMR = 0x41444300u; //ADC_WPMR_WPKEY(0);
|
2014-11-08 11:25:51 +00:00
|
|
|
pmc_enable_periph_clk(ID_ADC); // enable adc clock
|
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
for (int i = 0; i < ANALOG_INPUTS; i++)
|
2014-11-08 11:25:51 +00:00
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
osAnalogInputValues[i] = 0;
|
|
|
|
adcSamplesMin[i] = 100000;
|
|
|
|
adcSamplesMax[i] = 0;
|
|
|
|
adcEnable |= (0x1u << osAnalogInputChannels[i]);
|
|
|
|
osAnalogSamplesSum[i] = 2048 * ANALOG_INPUT_MEDIAN;
|
|
|
|
for (int j = 0; j < ANALOG_INPUT_MEDIAN; j++)
|
|
|
|
osAnalogSamples[i][j] = 2048; // we want to prevent early error from bad starting values
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
// enable channels
|
|
|
|
ADC->ADC_CHER = adcEnable;
|
|
|
|
ADC->ADC_CHDR = !adcEnable;
|
|
|
|
|
|
|
|
// Initialize ADC mode register (some of the following params are not used here)
|
|
|
|
// HW trigger disabled, use external Trigger, 12 bit resolution
|
|
|
|
// core and ref voltage stays on, normal sleep mode, normal not free-run mode
|
|
|
|
// startup time 16 clocks, settling time 17 clocks, no changes on channel switch
|
|
|
|
// convert channels in numeric order
|
|
|
|
// set prescaler rate MCK/((PRESCALE+1) * 2)
|
|
|
|
// set tracking time (TRACKTIM+1) * clock periods
|
2016-08-29 08:40:14 +00:00
|
|
|
// set transfer period (TRANSFER * 2 + 3)
|
2015-03-02 05:41:36 +00:00
|
|
|
ADC->ADC_MR = ADC_MR_TRGEN_DIS | ADC_MR_TRGSEL_ADC_TRIG0 | ADC_MR_LOWRES_BITS_12 |
|
2016-08-29 08:40:14 +00:00
|
|
|
ADC_MR_SLEEP_NORMAL | ADC_MR_FWUP_OFF | ADC_MR_FREERUN_OFF |
|
|
|
|
ADC_MR_STARTUP_SUT64 | ADC_MR_SETTLING_AST17 | ADC_MR_ANACH_NONE |
|
|
|
|
ADC_MR_USEQ_NUM_ORDER |
|
|
|
|
ADC_MR_PRESCAL(AD_PRESCALE_FACTOR) |
|
|
|
|
ADC_MR_TRACKTIM(AD_TRACKING_CYCLES) |
|
|
|
|
ADC_MR_TRANSFER(AD_TRANSFER_CYCLES);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
|
|
|
ADC->ADC_IER = 0; // no ADC interrupts
|
|
|
|
ADC->ADC_CGR = 0; // Gain = 1
|
|
|
|
ADC->ADC_COR = 0; // Single-ended, no offset
|
2016-08-29 08:40:14 +00:00
|
|
|
|
2014-11-08 11:25:51 +00:00
|
|
|
// start first conversion
|
|
|
|
ADC->ADC_CR = ADC_CR_START;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
#if EEPROM_AVAILABLE == EEPROM_SDCARD
|
|
|
|
|
|
|
|
#if !SDSUPPORT
|
|
|
|
#error EEPROM using sd card requires SDCARSUPPORT
|
|
|
|
#endif
|
|
|
|
|
|
|
|
millis_t eprSyncTime = 0; // in sync
|
|
|
|
SdFile eepromFile;
|
|
|
|
void HAL::syncEEPROM() { // store to disk if changed
|
|
|
|
millis_t time = millis();
|
|
|
|
|
|
|
|
if (eprSyncTime && (time - eprSyncTime > 15000)) // Buffer writes only every 15 seconds to pool writes
|
|
|
|
{
|
|
|
|
eprSyncTime = 0;
|
|
|
|
bool failed = false;
|
|
|
|
if (!sd.sdactive) // not mounted
|
|
|
|
{
|
|
|
|
if (eepromFile.isOpen())
|
|
|
|
eepromFile.close();
|
|
|
|
Com::printErrorF("Could not write eeprom to sd card - no sd card mounted");
|
|
|
|
Com::println();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!eepromFile.seekSet(0))
|
|
|
|
failed = true;
|
|
|
|
|
|
|
|
if(!failed && !eepromFile.write(virtualEeprom, EEPROM_BYTES) == EEPROM_BYTES)
|
|
|
|
failed = true;
|
|
|
|
|
|
|
|
if(failed) {
|
|
|
|
Com::printErrorF("Could not write eeprom to sd card");
|
|
|
|
Com::println();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void HAL::importEEPROM() {
|
|
|
|
if (eepromFile.isOpen())
|
|
|
|
eepromFile.close();
|
|
|
|
if (!eepromFile.open("eeprom.bin", O_RDWR | O_CREAT | O_SYNC) ||
|
|
|
|
eepromFile.read(virtualEeprom, EEPROM_BYTES) != EEPROM_BYTES)
|
|
|
|
{
|
|
|
|
Com::printFLN(Com::tOpenFailedFile, "eeprom.bin");
|
|
|
|
} else {
|
|
|
|
Com::printFLN("EEPROM read from sd card.");
|
|
|
|
}
|
|
|
|
EEPROM::readDataFromEEPROM(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2014-11-08 11:25:51 +00:00
|
|
|
// Print apparent cause of start/restart
|
|
|
|
void HAL::showStartReason() {
|
2016-08-29 08:40:14 +00:00
|
|
|
int mcu = (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos;
|
|
|
|
switch (mcu) {
|
2014-11-08 11:25:51 +00:00
|
|
|
case 0:
|
2016-08-29 08:40:14 +00:00
|
|
|
Com::printInfoFLN(Com::tPowerUp);
|
|
|
|
break;
|
2014-11-08 11:25:51 +00:00
|
|
|
case 1:
|
2016-08-29 08:40:14 +00:00
|
|
|
// this is return from backup mode on SAM
|
|
|
|
Com::printInfoFLN(Com::tBrownOut);
|
2014-11-08 11:25:51 +00:00
|
|
|
case 2:
|
2016-08-29 08:40:14 +00:00
|
|
|
Com::printInfoFLN(Com::tWatchdog);
|
|
|
|
break;
|
2014-11-08 11:25:51 +00:00
|
|
|
case 3:
|
2016-08-29 08:40:14 +00:00
|
|
|
Com::printInfoFLN(Com::tSoftwareReset);
|
|
|
|
break;
|
2014-11-08 11:25:51 +00:00
|
|
|
case 4:
|
2016-08-29 08:40:14 +00:00
|
|
|
Com::printInfoFLN(Com::tExternalReset);
|
|
|
|
}
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return available memory
|
|
|
|
int HAL::getFreeRam() {
|
2016-08-29 08:40:14 +00:00
|
|
|
struct mallinfo memstruct = mallinfo();
|
|
|
|
register char * stack_ptr asm ("sp");
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
// avail mem in heap + (bottom of stack addr - end of heap addr)
|
|
|
|
return (memstruct.fordblks + (int)stack_ptr - (int)sbrk(0));
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Reset peripherals and cpu
|
|
|
|
void HAL::resetHardware() {
|
2016-08-29 08:40:14 +00:00
|
|
|
//Davinci Specific, fancy effect
|
|
|
|
playsound (1000,400);
|
|
|
|
RSTC->RSTC_CR = RSTC_CR_KEY(0xA5) | RSTC_CR_PERRST | RSTC_CR_PROCRST;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// from http://medialab.freaknet.org/martin/src/sqrt/sqrt.c
|
|
|
|
uint32_t HAL::integer64Sqrt(uint64_t a_nInput) {
|
2016-08-29 08:40:14 +00:00
|
|
|
uint64_t op = a_nInput;
|
|
|
|
uint64_t res = 0;
|
|
|
|
uint64_t one = 1uLL << 62; // The second-to-top bit is set: use 1u << 14 for uint16_t type; use 1uL<<30 for uint32_t type
|
|
|
|
|
|
|
|
// "one" starts at the highest power of four <= than the argument.
|
|
|
|
while (one > op)
|
|
|
|
one >>= 2;
|
|
|
|
while (one != 0)
|
|
|
|
{
|
|
|
|
if (op >= res + one)
|
2014-11-08 11:25:51 +00:00
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
op = op - (res + one);
|
|
|
|
res = res + 2 * one;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
2016-08-29 08:40:14 +00:00
|
|
|
res >>= 1;
|
|
|
|
one >>= 2;
|
|
|
|
}
|
|
|
|
if (op > res) // Do arithmetic rounding to nearest integer
|
|
|
|
{
|
|
|
|
res++;
|
|
|
|
}
|
|
|
|
return res;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef DUE_SOFTWARE_SPI
|
2016-08-29 08:40:14 +00:00
|
|
|
// hardware SPI
|
|
|
|
#if MOTHERBOARD == 500 || MOTHERBOARD == 501
|
|
|
|
bool spiInitMaded = false;
|
|
|
|
#endif
|
|
|
|
void HAL::spiBegin()
|
|
|
|
{
|
|
|
|
#if MOTHERBOARD == 500 || MOTHERBOARD == 501
|
|
|
|
if (spiInitMaded == false)
|
|
|
|
{
|
|
|
|
#endif // Configre SPI pins
|
|
|
|
PIO_Configure(
|
|
|
|
g_APinDescription[SCK_PIN].pPort,
|
|
|
|
g_APinDescription[SCK_PIN].ulPinType,
|
|
|
|
g_APinDescription[SCK_PIN].ulPin,
|
|
|
|
g_APinDescription[SCK_PIN].ulPinConfiguration);
|
|
|
|
PIO_Configure(
|
|
|
|
g_APinDescription[MOSI_PIN].pPort,
|
|
|
|
g_APinDescription[MOSI_PIN].ulPinType,
|
|
|
|
g_APinDescription[MOSI_PIN].ulPin,
|
|
|
|
g_APinDescription[MOSI_PIN].ulPinConfiguration);
|
|
|
|
PIO_Configure(
|
|
|
|
g_APinDescription[MISO_PIN].pPort,
|
|
|
|
g_APinDescription[MISO_PIN].ulPinType,
|
|
|
|
g_APinDescription[MISO_PIN].ulPin,
|
|
|
|
g_APinDescription[MISO_PIN].ulPinConfiguration);
|
|
|
|
|
|
|
|
// set master mode, peripheral select, fault detection
|
|
|
|
SPI_Configure(SPI0, ID_SPI0, SPI_MR_MSTR |
|
|
|
|
SPI_MR_MODFDIS | SPI_MR_PS);
|
|
|
|
SPI_Enable(SPI0);
|
|
|
|
#if MOTHERBOARD == 500 || MOTHERBOARD == 501
|
|
|
|
SET_OUTPUT(DAC0_SYNC);
|
|
|
|
#if NUM_EXTRUDER > 1
|
|
|
|
SET_OUTPUT(DAC1_SYNC);
|
|
|
|
WRITE(DAC1_SYNC, HIGH);
|
|
|
|
#endif
|
|
|
|
SET_OUTPUT(SPI_EEPROM1_CS);
|
|
|
|
SET_OUTPUT(SPI_EEPROM2_CS);
|
|
|
|
SET_OUTPUT(SPI_FLASH_CS);
|
|
|
|
WRITE(DAC0_SYNC, HIGH);
|
|
|
|
WRITE(SPI_EEPROM1_CS, HIGH );
|
|
|
|
WRITE(SPI_EEPROM2_CS, HIGH );
|
|
|
|
WRITE(SPI_FLASH_CS, HIGH );
|
|
|
|
WRITE(SDSS , HIGH );
|
|
|
|
#endif// MOTHERBOARD == 500 || MOTHERBOARD == 501
|
|
|
|
PIO_Configure(
|
|
|
|
g_APinDescription[SPI_PIN].pPort,
|
|
|
|
g_APinDescription[SPI_PIN].ulPinType,
|
|
|
|
g_APinDescription[SPI_PIN].ulPin,
|
|
|
|
g_APinDescription[SPI_PIN].ulPinConfiguration);
|
|
|
|
spiInit(1);
|
|
|
|
#if (MOTHERBOARD==500) || (MOTHERBOARD==501)
|
|
|
|
spiInitMaded = true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
// spiClock is 0 to 6, relecting AVR clock dividers 2,4,8,16,32,64,128
|
|
|
|
// Due can only go as slow as AVR divider 32 -- slowest Due clock is 329,412 Hz
|
|
|
|
void HAL::spiInit(uint8_t spiClock)
|
|
|
|
{
|
|
|
|
#if MOTHERBOARD == 500 || MOTHERBOARD == 501
|
|
|
|
if (spiInitMaded == false)
|
|
|
|
{
|
|
|
|
#endif
|
|
|
|
if (spiClock > 4) spiClock = 1;
|
|
|
|
#if MOTHERBOARD == 500 || MOTHERBOARD == 501
|
|
|
|
// Set SPI mode 1, clock, select not active after transfer, with delay between transfers
|
|
|
|
SPI_ConfigureNPCS(SPI0, SPI_CHAN_DAC,
|
|
|
|
SPI_CSR_CSAAT | SPI_CSR_SCBR(spiDueDividors[spiClock]) |
|
|
|
|
SPI_CSR_DLYBCT(1));
|
|
|
|
// Set SPI mode 0, clock, select not active after transfer, with delay between transfers
|
|
|
|
SPI_ConfigureNPCS(SPI0, SPI_CHAN_EEPROM1, SPI_CSR_NCPHA |
|
|
|
|
SPI_CSR_CSAAT | SPI_CSR_SCBR(spiDueDividors[spiClock]) |
|
|
|
|
SPI_CSR_DLYBCT(1));
|
|
|
|
#endif// MOTHERBOARD==500 || MOTHERBOARD==501
|
|
|
|
// Set SPI mode 0, clock, select not active after transfer, with delay between transfers
|
|
|
|
SPI_ConfigureNPCS(SPI0, SPI_CHAN, SPI_CSR_NCPHA |
|
|
|
|
SPI_CSR_CSAAT | SPI_CSR_SCBR(spiDueDividors[spiClock]) |
|
|
|
|
SPI_CSR_DLYBCT(1));
|
|
|
|
SPI_Enable(SPI0);
|
|
|
|
#if MOTHERBOARD == 500 || MOTHERBOARD == 501
|
|
|
|
spiInitMaded = true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
// Write single byte to SPI
|
|
|
|
void HAL::spiSend(byte b) {
|
|
|
|
// write byte with address and end transmission flag
|
|
|
|
SPI0->SPI_TDR = (uint32_t)b | SPI_PCS(SPI_CHAN) | SPI_TDR_LASTXFER;
|
|
|
|
// wait for transmit register empty
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0);
|
|
|
|
// wait for receive register
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
|
|
|
|
// clear status
|
|
|
|
SPI0->SPI_RDR;
|
|
|
|
//delayMicroseconds(1);
|
|
|
|
}
|
|
|
|
void HAL::spiSend(const uint8_t* buf , size_t n)
|
|
|
|
{
|
|
|
|
if (n == 0) return;
|
|
|
|
for (size_t i = 0; i < n - 1; i++)
|
|
|
|
{
|
|
|
|
SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(SPI_CHAN);
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0);
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
|
|
|
|
SPI0->SPI_RDR;
|
|
|
|
// delayMicroseconds(1);
|
|
|
|
}
|
|
|
|
spiSend(buf[n - 1]);
|
|
|
|
}
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
// Read single byte from SPI
|
|
|
|
uint8_t HAL::spiReceive()
|
|
|
|
{
|
|
|
|
// write dummy byte with address and end transmission flag
|
|
|
|
SPI0->SPI_TDR = 0x000000FF | SPI_PCS(SPI_CHAN) | SPI_TDR_LASTXFER;
|
|
|
|
// wait for transmit register empty
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0);
|
|
|
|
|
|
|
|
// wait for receive register
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
|
|
|
|
// get byte from receive register
|
|
|
|
//delayMicroseconds(1);
|
|
|
|
return SPI0->SPI_RDR;
|
|
|
|
}
|
|
|
|
#if MOTHERBOARD == 500 || MOTHERBOARD == 501
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
void HAL::spiSend(uint32_t chan, byte b)
|
|
|
|
{
|
|
|
|
uint8_t dummy_read = 0;
|
|
|
|
// wait for transmit register empty
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0);
|
|
|
|
// write byte with address and end transmission flag
|
|
|
|
SPI0->SPI_TDR = (uint32_t)b | SPI_PCS(chan) | SPI_TDR_LASTXFER;
|
|
|
|
// wait for receive register
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
|
|
|
|
// clear status
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 1)
|
|
|
|
dummy_read = SPI0->SPI_RDR;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HAL::spiSend(uint32_t chan , const uint8_t* buf , size_t n)
|
|
|
|
{
|
|
|
|
uint8_t dummy_read = 0;
|
|
|
|
if (n == 0) return;
|
|
|
|
for (int i = 0; i < n - 1; i++)
|
|
|
|
{
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0);
|
|
|
|
SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(chan);
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 1)
|
|
|
|
dummy_read = SPI0->SPI_RDR;
|
|
|
|
}
|
|
|
|
spiSend(chan, buf[n - 1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t HAL::spiReceive(uint32_t chan)
|
|
|
|
{
|
|
|
|
uint8_t spirec_tmp;
|
|
|
|
// wait for transmit register empty
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0);
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 1)
|
|
|
|
spirec_tmp = SPI0->SPI_RDR;
|
|
|
|
|
|
|
|
// write dummy byte with address and end transmission flag
|
|
|
|
SPI0->SPI_TDR = 0x000000FF | SPI_PCS(chan) | SPI_TDR_LASTXFER;
|
|
|
|
|
|
|
|
// wait for receive register
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
|
|
|
|
// get byte from receive register
|
|
|
|
return SPI0->SPI_RDR;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
// Read from SPI into buffer
|
|
|
|
void HAL::spiReadBlock(uint8_t*buf, uint16_t nbyte)
|
|
|
|
{
|
|
|
|
if (nbyte-- == 0) return;
|
|
|
|
|
|
|
|
for (int i = 0; i < nbyte; i++)
|
|
|
|
{
|
|
|
|
//while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0);
|
|
|
|
SPI0->SPI_TDR = 0x000000FF | SPI_PCS(SPI_CHAN);
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
|
|
|
|
buf[i] = SPI0->SPI_RDR;
|
|
|
|
// delayMicroseconds(1);
|
|
|
|
}
|
|
|
|
buf[nbyte] = spiReceive();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write from buffer to SPI
|
|
|
|
|
|
|
|
void HAL::spiSendBlock(uint8_t token, const uint8_t* buf)
|
|
|
|
{
|
|
|
|
SPI0->SPI_TDR = (uint32_t)token | SPI_PCS(SPI_CHAN);
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0);
|
|
|
|
//while ((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
|
|
|
|
//SPI0->SPI_RDR;
|
|
|
|
for (int i = 0; i < 511; i++)
|
|
|
|
{
|
|
|
|
SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(SPI_CHAN);
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0);
|
|
|
|
while ((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
|
|
|
|
SPI0->SPI_RDR;
|
|
|
|
// delayMicroseconds(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
spiSend(buf[511]);
|
|
|
|
}
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
|
2015-03-12 05:10:08 +00:00
|
|
|
//Davinci Specific
|
2014-11-24 16:02:56 +00:00
|
|
|
#ifdef TWI_CLOCK_FREQ
|
2016-08-29 08:40:14 +00:00
|
|
|
/****************************************************************************************
|
|
|
|
Setting for I2C Clock speed. needed to change clock speed for different peripherals
|
|
|
|
****************************************************************************************/
|
|
|
|
|
|
|
|
void HAL::i2cSetClockspeed(uint32_t clockSpeedHz)
|
|
|
|
|
|
|
|
{
|
|
|
|
// Set i2c clock rate
|
|
|
|
uint32_t dwCkDiv = 0;
|
|
|
|
uint32_t dwClDiv;
|
|
|
|
while ( dwClDiv == 0 )
|
|
|
|
{
|
|
|
|
dwClDiv = ((F_CPU_TRUE / (2 * clockSpeedHz)) - 4) / (1 << dwCkDiv);
|
|
|
|
|
|
|
|
if ( dwClDiv > 255 )
|
|
|
|
{
|
|
|
|
dwCkDiv++;
|
|
|
|
dwClDiv = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TWI_INTERFACE->TWI_CWGR = 0;
|
|
|
|
TWI_INTERFACE->TWI_CWGR = (dwCkDiv << 16) | (dwClDiv << 8) | dwClDiv;
|
|
|
|
}
|
|
|
|
|
2014-11-08 11:25:51 +00:00
|
|
|
/*************************************************************************
|
|
|
|
Initialization of the I2C bus interface. Need to be called only once
|
|
|
|
*************************************************************************/
|
|
|
|
void HAL::i2cInit(unsigned long clockSpeedHz)
|
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
// enable TWI
|
|
|
|
pmc_enable_periph_clk(TWI_ID);
|
|
|
|
|
|
|
|
// Configure pins
|
|
|
|
#if SDA_PIN >= 0
|
|
|
|
PIO_Configure(g_APinDescription[SDA_PIN].pPort,
|
|
|
|
g_APinDescription[SDA_PIN].ulPinType,
|
|
|
|
g_APinDescription[SDA_PIN].ulPin,
|
|
|
|
g_APinDescription[SDA_PIN].ulPinConfiguration);
|
|
|
|
#endif
|
|
|
|
#if SCL_PIN >= 0
|
|
|
|
PIO_Configure(g_APinDescription[SCL_PIN].pPort,
|
|
|
|
g_APinDescription[SCL_PIN].ulPinType,
|
|
|
|
g_APinDescription[SCL_PIN].ulPin,
|
|
|
|
g_APinDescription[SCL_PIN].ulPinConfiguration);
|
|
|
|
#endif
|
|
|
|
/*
|
|
|
|
// Set to Master mode with known state
|
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_SVEN;
|
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_SWRST;
|
|
|
|
//TWI_INTERFACE->TWI_RHR; // no action???
|
|
|
|
TWI_INTERFACE->TWI_IMR = 0;
|
|
|
|
|
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_SVDIS;
|
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_MSDIS;
|
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_MSEN; */
|
|
|
|
// Set to Master mode with known state
|
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_SWRST;// Reset
|
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_SVDIS;// Slave disable
|
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_MSEN; //Master enable
|
|
|
|
|
|
|
|
i2cSetClockspeed(clockSpeedHz);
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Issues a start condition and sends address and transfer direction.
|
|
|
|
return 0 = device accessible, 1= failed to access device
|
|
|
|
*************************************************************************/
|
|
|
|
unsigned char HAL::i2cStart(unsigned char address_and_direction)
|
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
uint32_t twiDirection = address_and_direction & 1;
|
|
|
|
uint32_t address = address_and_direction >> 1;
|
|
|
|
|
|
|
|
// set master mode register with no internal address
|
|
|
|
TWI_INTERFACE->TWI_MMR = 0;
|
|
|
|
TWI_INTERFACE->TWI_MMR = (twiDirection << 12) | TWI_MMR_IADRSZ_NONE |
|
|
|
|
TWI_MMR_DADR(address);
|
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS; //set master mode disable slave mode
|
|
|
|
if (twiDirection) TWI_INTERFACE->TWI_CR = TWI_CR_START; //send Start Bit for receiving data
|
|
|
|
// returning readiness to send/recieve not device accessibility
|
|
|
|
// return value not used in code anyway
|
|
|
|
return !(TWI_INTERFACE->TWI_SR & TWI_SR_TXCOMP);
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Issues a start condition and sends address and transfer direction.
|
|
|
|
If device is busy, use ack polling to wait until device is ready
|
|
|
|
|
|
|
|
Input: address and transfer direction of I2C device
|
|
|
|
*************************************************************************/
|
|
|
|
void HAL::i2cStartWait(unsigned char address_and_direction)
|
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
uint32_t twiDirection = address_and_direction & 1;
|
|
|
|
uint32_t address = address_and_direction >> 1;
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
while (!(TWI_INTERFACE->TWI_SR & TWI_SR_TXCOMP));
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
// set master mode register with no internal address
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
TWI_INTERFACE->TWI_MMR = 0;
|
|
|
|
TWI_INTERFACE->TWI_MMR = (twiDirection << 12) | TWI_MMR_IADRSZ_NONE |
|
|
|
|
TWI_MMR_DADR(address);
|
|
|
|
|
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS; //set master mode disable slave mode
|
|
|
|
|
|
|
|
if (twiDirection) TWI_INTERFACE->TWI_CR = TWI_CR_START;//send Start Bit for receiving data
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Issues a start condition and sends address and transfer direction.
|
|
|
|
Also specifies internal address of device
|
|
|
|
|
|
|
|
Input: address and transfer direction of I2C device, internal address
|
|
|
|
*************************************************************************/
|
|
|
|
void HAL::i2cStartAddr(unsigned char address_and_direction, unsigned int pos)
|
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
#if EEPROM_AVAILABLE == EEPROM_I2C
|
|
|
|
uint32_t twiDirection = address_and_direction & 1;
|
|
|
|
uint32_t address = address_and_direction >> 1;
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
// if 1 byte address, eeprom uses lower address bits for pos > 255
|
|
|
|
if (EEPROM_ADDRSZ_BYTES == TWI_MMR_IADRSZ_1_BYTE)
|
|
|
|
{
|
|
|
|
address |= pos >> 8;
|
|
|
|
pos &= 0xFF;
|
|
|
|
}
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
// set master mode register with internal address
|
|
|
|
TWI_INTERFACE->TWI_MMR = 0;
|
|
|
|
TWI_INTERFACE->TWI_MMR = (twiDirection << 12) | EEPROM_ADDRSZ_BYTES |
|
|
|
|
TWI_MMR_DADR(address);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
// write internal address register
|
|
|
|
TWI_INTERFACE->TWI_IADR = 0;
|
|
|
|
TWI_INTERFACE->TWI_IADR = TWI_IADR_IADR(pos);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
if (twiDirection) TWI_INTERFACE->TWI_CR = TWI_CR_START;//send Start Bit for receiving data
|
|
|
|
#endif
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
2016-08-29 08:40:14 +00:00
|
|
|
Terminates the data transfer and releases the I2C bus
|
2014-11-08 11:25:51 +00:00
|
|
|
*************************************************************************/
|
2016-08-29 08:40:14 +00:00
|
|
|
void HAL::i2cStop(void)
|
2014-11-08 11:25:51 +00:00
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
while ( (TWI_INTERFACE->TWI_SR & TWI_SR_TXRDY) != TWI_SR_TXRDY);//wait for transmission finished
|
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_STOP;// send Stop
|
|
|
|
while (!((TWI_INTERFACE->TWI_SR & TWI_SR_TXCOMP) == TWI_SR_TXCOMP));//wait for i2cCompleted
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Send one byte to I2C device
|
|
|
|
|
|
|
|
Input: byte to be transfered
|
|
|
|
Return: 0 write successful
|
|
|
|
1 write failed
|
|
|
|
*************************************************************************/
|
2016-08-29 08:40:14 +00:00
|
|
|
void HAL::i2cWrite( uint8_t data )
|
|
|
|
{
|
|
|
|
TWI_INTERFACE->TWI_THR = data;
|
|
|
|
while ( (TWI_INTERFACE->TWI_SR & TWI_SR_TXRDY) != TWI_SR_TXRDY);// wait for transmission finished
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Read one byte from the I2C device, request more data from device
|
|
|
|
Return: byte read from I2C device
|
|
|
|
*************************************************************************/
|
2016-08-29 08:40:14 +00:00
|
|
|
uint8_t HAL::i2cReadAck(void)
|
2014-11-08 11:25:51 +00:00
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
while ( (TWI_INTERFACE->TWI_SR & TWI_SR_RXRDY) != TWI_SR_RXRDY );//wait for received byte
|
|
|
|
return TWI_INTERFACE->TWI_RHR;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Read one byte from the I2C device, read is followed by a stop condition
|
|
|
|
|
|
|
|
Return: byte read from I2C device
|
|
|
|
*************************************************************************/
|
2016-08-29 08:40:14 +00:00
|
|
|
uint8_t HAL::i2cReadNak(void)
|
2014-11-08 11:25:51 +00:00
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
TWI_INTERFACE->TWI_CR = TWI_CR_STOP;// send Stop
|
|
|
|
uint8_t data = i2cReadAck();//read last byte
|
|
|
|
while (!((TWI_INTERFACE->TWI_SR & TWI_SR_TXCOMP) == TWI_SR_TXCOMP));// wait for i2cCompleted ;
|
|
|
|
return data;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
2015-03-12 05:10:08 +00:00
|
|
|
#endif //TWI_CLOCK_FREQ
|
|
|
|
|
2014-11-08 11:25:51 +00:00
|
|
|
|
|
|
|
#if FEATURE_SERVO
|
|
|
|
// may need further restrictions here in the future
|
|
|
|
#if defined (__SAM3X8E__)
|
2016-08-29 08:40:14 +00:00
|
|
|
unsigned int HAL::servoTimings[4] = {0, 0, 0, 0};
|
2014-11-08 11:25:51 +00:00
|
|
|
static uint8_t servoIndex = 0;
|
2016-08-29 08:40:14 +00:00
|
|
|
unsigned int servoAutoOff[4] = {0, 0, 0, 0};
|
|
|
|
void HAL::servoMicroseconds(uint8_t servo, int microsec, uint16_t autoOff) {
|
|
|
|
if (microsec < 500) microsec = 0;
|
|
|
|
if (microsec > 2500) microsec = 2500;
|
|
|
|
servoTimings[servo] = (unsigned int)(((F_CPU_TRUE / SERVO_PRESCALE) /
|
|
|
|
1000000) * microsec);
|
|
|
|
servoAutoOff[servo] = (microsec) ? (autoOff / 20) : 0;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
2016-08-29 08:40:14 +00:00
|
|
|
|
2014-11-08 11:25:51 +00:00
|
|
|
|
|
|
|
// ================== Interrupt handling ======================
|
|
|
|
|
|
|
|
// Servo timer Interrupt handler
|
|
|
|
void SERVO_COMPA_VECTOR ()
|
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
InterruptProtectedBlock noInt;
|
|
|
|
static uint32_t interval;
|
2014-11-08 11:25:51 +00:00
|
|
|
|
|
|
|
// apparently have to read status register
|
|
|
|
TC_GetStatus(SERVO_TIMER, SERVO_TIMER_CHANNEL);
|
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
switch (servoIndex) {
|
|
|
|
case 0:
|
|
|
|
if (HAL::servoTimings[0]) {
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO0_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
WRITE(SERVO0_PIN, HIGH);
|
|
|
|
#endif
|
|
|
|
interval = HAL::servoTimings[0];
|
|
|
|
} else
|
|
|
|
interval = SERVO2500US;
|
2014-11-08 11:25:51 +00:00
|
|
|
TC_SetRC(SERVO_TIMER, SERVO_TIMER_CHANNEL, interval);
|
|
|
|
break;
|
2016-08-29 08:40:14 +00:00
|
|
|
case 1:
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO0_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
WRITE(SERVO0_PIN, LOW);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
TC_SetRC(SERVO_TIMER, SERVO_TIMER_CHANNEL,
|
2014-11-08 11:25:51 +00:00
|
|
|
SERVO5000US - interval);
|
2016-08-29 08:40:14 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (HAL::servoTimings[1]) {
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO1_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
WRITE(SERVO1_PIN, HIGH);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
interval = HAL::servoTimings[1];
|
2016-08-29 08:40:14 +00:00
|
|
|
} else
|
|
|
|
interval = SERVO2500US;
|
|
|
|
TC_SetRC(SERVO_TIMER, SERVO_TIMER_CHANNEL, interval);
|
|
|
|
break;
|
|
|
|
case 3:
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO1_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
WRITE(SERVO1_PIN, LOW);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
TC_SetRC(SERVO_TIMER, SERVO_TIMER_CHANNEL,
|
2014-11-08 11:25:51 +00:00
|
|
|
SERVO5000US - interval);
|
2016-08-29 08:40:14 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if (HAL::servoTimings[2]) {
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO2_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
WRITE(SERVO2_PIN, HIGH);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
interval = HAL::servoTimings[2];
|
2016-08-29 08:40:14 +00:00
|
|
|
} else
|
|
|
|
interval = SERVO2500US;
|
|
|
|
TC_SetRC(SERVO_TIMER, SERVO_TIMER_CHANNEL, interval);
|
|
|
|
break;
|
|
|
|
case 5:
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO2_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
WRITE(SERVO2_PIN, LOW);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
TC_SetRC(SERVO_TIMER, SERVO_TIMER_CHANNEL,
|
2014-11-08 11:25:51 +00:00
|
|
|
SERVO5000US - interval);
|
2016-08-29 08:40:14 +00:00
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
if (HAL::servoTimings[3]) {
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO3_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
WRITE(SERVO3_PIN, HIGH);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
interval = HAL::servoTimings[3];
|
2016-08-29 08:40:14 +00:00
|
|
|
} else
|
|
|
|
interval = SERVO2500US;
|
|
|
|
TC_SetRC(SERVO_TIMER, SERVO_TIMER_CHANNEL, interval);
|
|
|
|
break;
|
|
|
|
case 7:
|
2015-02-27 09:24:25 +00:00
|
|
|
#if SERVO3_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
WRITE(SERVO3_PIN, LOW);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
TC_SetRC(SERVO_TIMER, SERVO_TIMER_CHANNEL,
|
2014-11-08 11:25:51 +00:00
|
|
|
SERVO5000US - interval);
|
2016-08-29 08:40:14 +00:00
|
|
|
break;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
2016-08-29 08:40:14 +00:00
|
|
|
if (servoIndex & 1)
|
2015-03-19 02:47:10 +00:00
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
uint8_t nr = servoIndex >> 1;
|
|
|
|
if (servoAutoOff[nr])
|
|
|
|
{
|
|
|
|
servoAutoOff[nr]--;
|
|
|
|
if (servoAutoOff[nr] == 0) HAL::servoTimings[nr] = 0;
|
|
|
|
}
|
2015-03-19 02:47:10 +00:00
|
|
|
}
|
2014-11-08 11:25:51 +00:00
|
|
|
servoIndex++;
|
2016-08-29 08:40:14 +00:00
|
|
|
if (servoIndex > 7) servoIndex = 0;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
#error No servo support for your board, please diable FEATURE_SERVO
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
TcChannel *stepperChannel = (TIMER1_TIMER->TC_CHANNEL + TIMER1_TIMER_CHANNEL);
|
|
|
|
#ifndef STEPPERTIMER_EXIT_TICKS
|
|
|
|
#define STEPPERTIMER_EXIT_TICKS 105 // at least 2,5us pause between stepper calls
|
|
|
|
#endif
|
2014-11-08 11:25:51 +00:00
|
|
|
|
|
|
|
/** \brief Timer interrupt routine to drive the stepper motors.
|
|
|
|
*/
|
|
|
|
void TIMER1_COMPA_VECTOR ()
|
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
// apparently have to read status register
|
|
|
|
stepperChannel->TC_SR;
|
|
|
|
stepperChannel->TC_RC = 1000000;
|
|
|
|
uint32_t delay;
|
|
|
|
if (PrintLine::hasLines())
|
|
|
|
{
|
|
|
|
delay = PrintLine::bresenhamStep();
|
|
|
|
}
|
|
|
|
else if (Printer::zBabystepsMissing != 0) {
|
|
|
|
Printer::zBabystep();
|
|
|
|
delay = Printer::interval;
|
|
|
|
} else {
|
|
|
|
if (waitRelax == 0)
|
2014-11-08 11:25:51 +00:00
|
|
|
{
|
|
|
|
#if USE_ADVANCE
|
2016-08-29 08:40:14 +00:00
|
|
|
if (Printer::advanceStepsSet)
|
|
|
|
{
|
|
|
|
Printer::extruderStepsNeeded -= Printer::advanceStepsSet;
|
2014-11-08 11:25:51 +00:00
|
|
|
#if ENABLE_QUADRATIC_ADVANCE
|
2016-08-29 08:40:14 +00:00
|
|
|
Printer::advanceExecuted = 0;
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
Printer::advanceStepsSet = 0;
|
|
|
|
}
|
|
|
|
if ((!Printer::extruderStepsNeeded) && (DISABLE_E))
|
|
|
|
Extruder::disableCurrentExtruderMotor();
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (DISABLE_E) Extruder::disableCurrentExtruderMotor();
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
}
|
2016-08-29 08:40:14 +00:00
|
|
|
else waitRelax--;
|
|
|
|
|
|
|
|
delay = 10000;
|
|
|
|
}
|
|
|
|
// convert old AVR timer delay value for SAM timers
|
|
|
|
uint32_t timer_count = (delay * TIMER1_PRESCALE);
|
|
|
|
//if (timer_count < 210) // max. 200 khz timer frequency
|
|
|
|
// timer_count = 210;
|
|
|
|
InterruptProtectedBlock noInt; // prevent interruption or we might get 102s delay
|
|
|
|
if ( stepperChannel->TC_CV + STEPPERTIMER_EXIT_TICKS > timer_count) {
|
|
|
|
stepperChannel->TC_RC = stepperChannel->TC_CV + STEPPERTIMER_EXIT_TICKS; // should end after exiting timer interrupt
|
|
|
|
//stepperChannel->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG ;
|
|
|
|
} else {
|
|
|
|
stepperChannel->TC_RC = timer_count;
|
|
|
|
}
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if !defined(HEATER_PWM_SPEED)
|
|
|
|
#define HEATER_PWM_SPEED 0
|
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if HEATER_PWM_SPEED < 0
|
2014-11-08 11:25:51 +00:00
|
|
|
#define HEATER_PWM_SPEED 0
|
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if HEATER_PWM_SPEED > 2
|
|
|
|
#define HEATER_PWM_SPEED 2
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if HEATER_PWM_SPEED == 0
|
|
|
|
#define HEATER_PWM_STEP 1
|
|
|
|
#define HEATER_PWM_MASK 255
|
|
|
|
#elif HEATER_PWM_SPEED == 1
|
|
|
|
#define HEATER_PWM_STEP 2
|
|
|
|
#define HEATER_PWM_MASK 254
|
|
|
|
#else
|
|
|
|
#define HEATER_PWM_STEP 4
|
|
|
|
#define HEATER_PWM_MASK 252
|
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
|
|
|
|
#if !defined(COOLER_PWM_SPEED)
|
|
|
|
#define COOLER_PWM_SPEED 0
|
|
|
|
#endif
|
|
|
|
#if COOLER_PWM_SPEED < 0
|
|
|
|
#define COOLER_PWM_SPEED 0
|
|
|
|
#endif
|
|
|
|
#if COOLER_PWM_SPEED > 2
|
|
|
|
#define COOLER_PWM_SPEED 2
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if COOLER_PWM_SPEED == 0
|
|
|
|
#define COOLER_PWM_STEP 1
|
|
|
|
#define COOLER_PWM_MASK 255
|
|
|
|
#elif COOLER_PWM_SPEED == 1
|
|
|
|
#define COOLER_PWM_STEP 2
|
|
|
|
#define COOLER_PWM_MASK 254
|
|
|
|
#else
|
|
|
|
#define COOLER_PWM_STEP 4
|
|
|
|
#define COOLER_PWM_MASK 252
|
|
|
|
#endif
|
|
|
|
|
2014-11-08 11:25:51 +00:00
|
|
|
#define pulseDensityModulate( pin, density,error,invert) {uint8_t carry;carry = error + (invert ? 255 - density : density); WRITE(pin, (carry < error)); error = carry;}
|
|
|
|
|
|
|
|
/**
|
|
|
|
This timer is called 3906 times per second. It is used to update
|
2016-08-29 08:40:14 +00:00
|
|
|
pwm values for heater and some other frequent jobs.
|
2014-11-08 11:25:51 +00:00
|
|
|
*/
|
|
|
|
void PWM_TIMER_VECTOR ()
|
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
//InterruptProtectedBlock noInt;
|
|
|
|
// apparently have to read status register
|
|
|
|
TC_GetStatus(PWM_TIMER, PWM_TIMER_CHANNEL);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
static uint8_t pwm_count_cooler = 0;
|
|
|
|
static uint8_t pwm_count_heater = 0;
|
|
|
|
static uint8_t pwm_pos_set[NUM_PWM];
|
|
|
|
static uint8_t pwm_cooler_pos_set[NUM_EXTRUDER];
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_count_heater == 0 && !PDM_FOR_EXTRUDER)
|
|
|
|
{
|
2015-02-27 09:24:25 +00:00
|
|
|
#if defined(EXT0_HEATER_PIN) && EXT0_HEATER_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
if ((pwm_pos_set[0] = (pwm_pos[0] & HEATER_PWM_MASK)) > 0) WRITE(EXT0_HEATER_PIN, !HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if defined(EXT1_HEATER_PIN) && EXT1_HEATER_PIN > -1 && NUM_EXTRUDER > 1 && !MIXING_EXTRUDER
|
|
|
|
if ((pwm_pos_set[1] = (pwm_pos[1] & HEATER_PWM_MASK)) > 0) WRITE(EXT1_HEATER_PIN, !HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if defined(EXT2_HEATER_PIN) && EXT2_HEATER_PIN > -1 && NUM_EXTRUDER > 2 && !MIXING_EXTRUDER
|
|
|
|
if ((pwm_pos_set[2] = (pwm_pos[2] & HEATER_PWM_MASK)) > 0) WRITE(EXT2_HEATER_PIN, !HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if defined(EXT3_HEATER_PIN) && EXT3_HEATER_PIN > -1 && NUM_EXTRUDER > 3 && !MIXING_EXTRUDER
|
|
|
|
if ((pwm_pos_set[3] = (pwm_pos[3] & HEATER_PWM_MASK)) > 0) WRITE(EXT3_HEATER_PIN, !HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if defined(EXT4_HEATER_PIN) && EXT4_HEATER_PIN > -1 && NUM_EXTRUDER > 4 && !MIXING_EXTRUDER
|
|
|
|
if ((pwm_pos_set[4] = (pwm_pos[4] & HEATER_PWM_MASK)) > 0) WRITE(EXT4_HEATER_PIN, !HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if defined(EXT5_HEATER_PIN) && EXT5_HEATER_PIN > -1 && NUM_EXTRUDER > 5 && !MIXING_EXTRUDER
|
|
|
|
if ((pwm_pos_set[5] = (pwm_pos[5] & HEATER_PWM_MASK)) > 0) WRITE(EXT5_HEATER_PIN, !HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-02-27 09:24:25 +00:00
|
|
|
#if HEATED_BED_HEATER_PIN > -1 && HAVE_HEATED_BED
|
2016-08-29 08:40:14 +00:00
|
|
|
if ((pwm_pos_set[NUM_EXTRUDER] = pwm_pos[NUM_EXTRUDER]) > 0) WRITE(HEATED_BED_HEATER_PIN, !HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
}
|
|
|
|
if (pwm_count_cooler == 0 && !PDM_FOR_COOLER)
|
|
|
|
{
|
2015-02-27 09:24:25 +00:00
|
|
|
#if defined(EXT0_HEATER_PIN) && EXT0_HEATER_PIN > -1 && EXT0_EXTRUDER_COOLER_PIN > -1
|
2016-08-29 08:40:14 +00:00
|
|
|
if ((pwm_cooler_pos_set[0] = (extruder[0].coolerPWM & COOLER_PWM_MASK)) > 0) WRITE(EXT0_EXTRUDER_COOLER_PIN, 1);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-03-06 03:04:08 +00:00
|
|
|
#if !SHARED_COOLER && defined(EXT1_HEATER_PIN) && EXT1_HEATER_PIN > -1 && NUM_EXTRUDER > 1
|
2015-02-27 09:24:25 +00:00
|
|
|
#if EXT1_EXTRUDER_COOLER_PIN > -1 && EXT1_EXTRUDER_COOLER_PIN != EXT0_EXTRUDER_COOLER_PIN
|
2016-08-29 08:40:14 +00:00
|
|
|
if ((pwm_cooler_pos_set[1] = (extruder[1].coolerPWM & COOLER_PWM_MASK)) > 0) WRITE(EXT1_EXTRUDER_COOLER_PIN, 1);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
2015-03-06 03:04:08 +00:00
|
|
|
#if !SHARED_COOLER && defined(EXT2_HEATER_PIN) && EXT2_HEATER_PIN > -1 && NUM_EXTRUDER > 2
|
2014-11-08 11:25:51 +00:00
|
|
|
#if EXT2_EXTRUDER_COOLER_PIN>-1
|
2016-08-29 08:40:14 +00:00
|
|
|
if ((pwm_cooler_pos_set[2] = (extruder[2].coolerPWM & COOLER_PWM_MASK)) > 0) WRITE(EXT2_EXTRUDER_COOLER_PIN, 1);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
2015-03-06 03:04:08 +00:00
|
|
|
#if !SHARED_COOLER && defined(EXT3_HEATER_PIN) && EXT3_HEATER_PIN > -1 && NUM_EXTRUDER > 3
|
2014-11-08 11:25:51 +00:00
|
|
|
#if EXT3_EXTRUDER_COOLER_PIN>-1
|
2016-08-29 08:40:14 +00:00
|
|
|
if ((pwm_cooler_pos_set[3] = (extruder[3].coolerPWM & COOLER_PWM_MASK)) > 0) WRITE(EXT3_EXTRUDER_COOLER_PIN, 1);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
2015-03-06 03:04:08 +00:00
|
|
|
#if !SHARED_COOLER && defined(EXT4_HEATER_PIN) && EXT4_HEATER_PIN > -1 && NUM_EXTRUDER > 4
|
2014-11-08 11:25:51 +00:00
|
|
|
#if EXT4_EXTRUDER_COOLER_PIN>-1
|
2016-08-29 08:40:14 +00:00
|
|
|
if ((pwm_cooler_pos_set[4] = (extruder[4].coolerPWM & COOLER_PWM_MASK)) > 0) WRITE(EXT4_EXTRUDER_COOLER_PIN, 1);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
2015-03-06 03:04:08 +00:00
|
|
|
#if !SHARED_COOLER && defined(EXT5_HEATER_PIN) && EXT5_HEATER_PIN > -1 && NUM_EXTRUDER > 5
|
2014-11-08 11:25:51 +00:00
|
|
|
#if EXT5_EXTRUDER_COOLER_PIN>-1
|
2016-08-29 08:40:14 +00:00
|
|
|
if ((pwm_cooler_pos_set[5] = (extruder[5].coolerPWM & COOLER_PWM_MASK)) > 0) WRITE(EXT5_EXTRUDER_COOLER_PIN, 1);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
2015-03-12 05:10:08 +00:00
|
|
|
#if FAN_BOARD_PIN > -1 && SHARED_COOLER_BOARD_EXT == 0
|
2016-08-29 08:40:14 +00:00
|
|
|
if((pwm_pos_set[PWM_BOARD_FAN] = (pwm_pos[PWM_BOARD_FAN] & COOLER_PWM_MASK)) > 0) WRITE(FAN_BOARD_PIN,1);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if FAN_PIN > -1 && FEATURE_FAN_CONTROL
|
|
|
|
if((pwm_pos_set[PWM_FAN1] = (pwm_pos[PWM_FAN1] & COOLER_PWM_MASK)) > 0) WRITE(FAN_PIN,1);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if FAN2_PIN > -1 && FEATURE_FAN2_CONTROL
|
|
|
|
if((pwm_pos_set[PWM_FAN2] = (pwm_pos[PWM_FAN2] & COOLER_PWM_MASK)) > 0) WRITE(FAN2_PIN,1);
|
|
|
|
#endif
|
|
|
|
#if defined(FAN_THERMO_PIN) && FAN_THERMO_PIN > -1
|
|
|
|
if((pwm_pos_set[PWM_FAN_THERMO] = (pwm_pos[PWM_FAN_THERMO] & COOLER_PWM_MASK)) > 0) WRITE(FAN_THERMO_PIN,1);
|
|
|
|
#endif
|
|
|
|
}
|
2015-02-27 09:24:25 +00:00
|
|
|
#if defined(EXT0_HEATER_PIN) && EXT0_HEATER_PIN > -1
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_EXTRUDER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT0_HEATER_PIN, pwm_pos[0], pwm_pos_set[0], HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_pos_set[0] == pwm_count_heater && pwm_pos_set[0] != HEATER_PWM_MASK) WRITE(EXT0_HEATER_PIN, HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-02-27 09:24:25 +00:00
|
|
|
#if EXT0_EXTRUDER_COOLER_PIN > -1
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_COOLER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT0_EXTRUDER_COOLER_PIN, extruder[0].coolerPWM, pwm_cooler_pos_set[0], false);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_cooler_pos_set[0] == pwm_count_cooler && pwm_cooler_pos_set[0] != COOLER_PWM_MASK) WRITE(EXT0_EXTRUDER_COOLER_PIN, 0);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if defined(EXT1_HEATER_PIN) && EXT1_HEATER_PIN > -1 && NUM_EXTRUDER > 1 && !MIXING_EXTRUDER
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_EXTRUDER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT1_HEATER_PIN, pwm_pos[1], pwm_pos_set[1], HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_pos_set[1] == pwm_count_heater && pwm_pos_set[1] != HEATER_PWM_MASK) WRITE(EXT1_HEATER_PIN, HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-03-06 03:04:08 +00:00
|
|
|
#if !SHARED_COOLER && defined(EXT1_EXTRUDER_COOLER_PIN) && EXT1_EXTRUDER_COOLER_PIN > -1 && EXT1_EXTRUDER_COOLER_PIN != EXT0_EXTRUDER_COOLER_PIN
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_COOLER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT1_EXTRUDER_COOLER_PIN, extruder[1].coolerPWM, pwm_cooler_pos_set[1], false);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_cooler_pos_set[1] == pwm_count_cooler && pwm_cooler_pos_set[1] != COOLER_PWM_MASK) WRITE(EXT1_EXTRUDER_COOLER_PIN, 0);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if defined(EXT2_HEATER_PIN) && EXT2_HEATER_PIN > -1 && NUM_EXTRUDER > 2 && !MIXING_EXTRUDER
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_EXTRUDER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT2_HEATER_PIN, pwm_pos[2], pwm_pos_set[2], HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_pos_set[2] == pwm_count_heater && pwm_pos_set[2] != HEATER_PWM_MASK) WRITE(EXT2_HEATER_PIN, HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-03-06 03:04:08 +00:00
|
|
|
#if !SHARED_COOLER && EXT2_EXTRUDER_COOLER_PIN > -1
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_COOLER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT2_EXTRUDER_COOLER_PIN, extruder[2].coolerPWM, pwm_cooler_pos_set[2], false);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_cooler_pos_set[2] == pwm_count_cooler && pwm_cooler_pos_set[2] != COOLER_PWM_MASK) WRITE(EXT2_EXTRUDER_COOLER_PIN, 0);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if defined(EXT3_HEATER_PIN) && EXT3_HEATER_PIN > -1 && NUM_EXTRUDER > 3 && !MIXING_EXTRUDER
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_EXTRUDER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT3_HEATER_PIN, pwm_pos[3], pwm_pos_set[3], HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_pos_set[3] == pwm_count_heater && pwm_pos_set[3] != HEATER_PWM_MASK) WRITE(EXT3_HEATER_PIN, HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-03-06 03:04:08 +00:00
|
|
|
#if !SHARED_COOLER && EXT3_EXTRUDER_COOLER_PIN > -1
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_COOLER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT3_EXTRUDER_COOLER_PIN, extruder[3].coolerPWM, pwm_cooler_pos_set[3], false);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_cooler_pos_set[3] == pwm_count_cooler && pwm_cooler_pos_set[3] != COOLER_PWM_MASK) WRITE(EXT3_EXTRUDER_COOLER_PIN, 0);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if defined(EXT4_HEATER_PIN) && EXT4_HEATER_PIN > -1 && NUM_EXTRUDER > 4 && !MIXING_EXTRUDER
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_EXTRUDER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT4_HEATER_PIN, pwm_pos[4], pwm_pos_set[4], HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_pos_set[4] == pwm_count_heater && pwm_pos_set[4] != HEATER_PWM_MASK) WRITE(EXT4_HEATER_PIN, HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-03-06 03:04:08 +00:00
|
|
|
#if !SHARED_COOLER && EXT4_EXTRUDER_COOLER_PIN > -1
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_COOLER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT4_EXTRUDER_COOLER_PIN, extruder[4].coolerPWM, pwm_cooler_pos_set[4], false);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_cooler_pos_set[4] == pwm_count_cooler && pwm_cooler_pos_set[4] != COOLER_PWM_MASK) WRITE(EXT4_EXTRUDER_COOLER_PIN, 0);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if defined(EXT5_HEATER_PIN) && EXT5_HEATER_PIN > -1 && NUM_EXTRUDER > 5 && !MIXING_EXTRUDER
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_EXTRUDER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT5_HEATER_PIN, pwm_pos[5], pwm_pos_set[5], HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_pos_set[5] == pwm_count_heater && pwm_pos_set[5] != HEATER_PWM_MASK) WRITE(EXT5_HEATER_PIN, HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-03-06 03:04:08 +00:00
|
|
|
#if !SHARED_COOLER && EXT5_EXTRUDER_COOLER_PIN > -1
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_COOLER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(EXT5_EXTRUDER_COOLER_PIN, extruder[5].coolerPWM, pwm_cooler_pos_set[5], false);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_cooler_pos_set[5] == pwm_count_cooler && pwm_cooler_pos_set[5] != COOLER_PWM_MASK) WRITE(EXT5_EXTRUDER_COOLER_PIN, 0);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if FAN_BOARD_PIN > -1 && SHARED_COOLER_BOARD_EXT == 0
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_COOLER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(FAN_BOARD_PIN, pwm_pos[PWM_BOARD_FAN], pwm_pos_set[PWM_BOARD_FAN], false);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if(pwm_pos_set[PWM_BOARD_FAN] == pwm_count_cooler && pwm_pos_set[NUM_EXTRUDER + 1] != COOLER_PWM_MASK) WRITE(FAN_BOARD_PIN,0);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
2015-02-27 09:24:25 +00:00
|
|
|
#if FAN_PIN > -1 && FEATURE_FAN_CONTROL
|
2015-03-13 11:12:55 +00:00
|
|
|
if(fanKickstart == 0)
|
|
|
|
{
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_COOLER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(FAN_PIN, pwm_pos[PWM_FAN1], pwm_pos_set[PWM_FAN1], false);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if(pwm_pos_set[PWM_FAN1] == pwm_count_cooler && pwm_pos_set[PWM_FAN1] != COOLER_PWM_MASK) WRITE(FAN_PIN,0);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2015-03-13 11:12:55 +00:00
|
|
|
}
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
#if FAN2_PIN > -1 && FEATURE_FAN2_CONTROL
|
|
|
|
if(fan2Kickstart == 0)
|
|
|
|
{
|
|
|
|
#if PDM_FOR_COOLER
|
|
|
|
pulseDensityModulate(FAN2_PIN, pwm_pos[PWM_FAN2], pwm_pos_set[PWM_FAN2], false);
|
|
|
|
#else
|
|
|
|
if(pwm_pos_set[PWM_FAN2] == pwm_count_cooler && pwm_pos_set[PWM_FAN2] != COOLER_PWM_MASK) WRITE(FAN2_PIN,0);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#if defined(FAN_THERMO_PIN) && FAN_THERMO_PIN > -1
|
|
|
|
#if PDM_FOR_COOLER
|
|
|
|
pulseDensityModulate(FAN_THERMO_PIN, pwm_pos[PWM_FAN_THERMO], pwm_pos_set[PWM_FAN_THERMO], false);
|
|
|
|
#else
|
|
|
|
if(pwm_pos_set[PWM_FAN_THERMO] == pwm_count_cooler && pwm_pos_set[PWM_FAN_THERMO] != COOLER_PWM_MASK) WRITE(FAN_THERMO_PIN,0);
|
|
|
|
#endif
|
|
|
|
#endif
|
2015-02-27 09:24:25 +00:00
|
|
|
#if HEATED_BED_HEATER_PIN > -1 && HAVE_HEATED_BED
|
2014-11-08 11:25:51 +00:00
|
|
|
#if PDM_FOR_EXTRUDER
|
2016-08-29 08:40:14 +00:00
|
|
|
pulseDensityModulate(HEATED_BED_HEATER_PIN, pwm_pos[NUM_EXTRUDER], pwm_pos_set[NUM_EXTRUDER], HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#else
|
2016-08-29 08:40:14 +00:00
|
|
|
if (pwm_pos_set[NUM_EXTRUDER] == pwm_count_heater && pwm_pos_set[NUM_EXTRUDER] != HEATER_PWM_MASK) WRITE(HEATED_BED_HEATER_PIN, HEATER_PINS_INVERTED);
|
2014-11-08 11:25:51 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
2016-08-29 08:40:14 +00:00
|
|
|
//noInt.unprotect();
|
|
|
|
counterPeriodical++; // Appxoimate a 100ms timer
|
|
|
|
if (counterPeriodical >= 390) // (int)(F_CPU/40960))
|
|
|
|
{
|
|
|
|
counterPeriodical = 0;
|
|
|
|
executePeriodical = 1;
|
|
|
|
#if FEATURE_FAN_CONTROL
|
|
|
|
if (fanKickstart) fanKickstart--;
|
|
|
|
#endif
|
|
|
|
#if FEATURE_FAN2_CONTROL
|
|
|
|
if (fan2Kickstart) fan2Kickstart--;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
// read analog values -- only read one per interrupt
|
|
|
|
#if ANALOG_INPUTS > 0
|
|
|
|
// conversion finished?
|
|
|
|
if ((ADC->ADC_ISR & adcEnable) == adcEnable)
|
|
|
|
{
|
|
|
|
adcCounter++;
|
|
|
|
for (int i = 0; i < ANALOG_INPUTS; i++) {
|
|
|
|
int32_t cur = ADC->ADC_CDR[osAnalogInputChannels[i]];
|
|
|
|
osAnalogInputBuildup[i] += cur;
|
|
|
|
adcSamplesMin[i] = RMath::min(adcSamplesMin[i], cur);
|
|
|
|
adcSamplesMax[i] = RMath::max(adcSamplesMax[i], cur);
|
|
|
|
if (adcCounter >= NUM_ADC_SAMPLES) // store new conversion result
|
|
|
|
{
|
|
|
|
// Strip biggest and smallest value and round correctly
|
|
|
|
osAnalogInputBuildup[i] = osAnalogInputBuildup[i] + (1 << (ANALOG_INPUT_SAMPLE - 1)) - (adcSamplesMin[i] + adcSamplesMax[i]);
|
|
|
|
adcSamplesMin[i] = 100000;
|
|
|
|
adcSamplesMax[i] = 0;
|
|
|
|
osAnalogSamplesSum[i] -= osAnalogSamples[i][adcSamplePos];
|
|
|
|
osAnalogSamplesSum[i] += (osAnalogSamples[i][adcSamplePos] = osAnalogInputBuildup[i] >> ANALOG_INPUT_SAMPLE);
|
|
|
|
osAnalogInputValues[i] = osAnalogSamplesSum[i] / ANALOG_INPUT_MEDIAN;
|
|
|
|
osAnalogInputBuildup[i] = 0;
|
|
|
|
} // adcCounter >= NUM_ADC_SAMPLES
|
|
|
|
} // for i
|
|
|
|
if (adcCounter >= NUM_ADC_SAMPLES) {
|
|
|
|
adcCounter = 0;
|
|
|
|
adcSamplePos++;
|
|
|
|
if (adcSamplePos >= ANALOG_INPUT_MEDIAN)
|
|
|
|
adcSamplePos = 0;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
2016-08-29 08:40:14 +00:00
|
|
|
ADC->ADC_CR = ADC_CR_START; // reread values
|
|
|
|
}
|
2015-02-27 09:24:25 +00:00
|
|
|
#endif // ANALOG_INPUTS > 0
|
2016-08-29 08:40:14 +00:00
|
|
|
pwm_count_cooler += COOLER_PWM_STEP;
|
|
|
|
pwm_count_heater += HEATER_PWM_STEP;
|
|
|
|
UI_FAST; // Short timed user interface action
|
|
|
|
#if FEATURE_WATCHDOG
|
|
|
|
if(HAL::wdPinged) {
|
|
|
|
//Davinci Specific
|
|
|
|
//WDT->WDT_CR = 0xA5000001;
|
|
|
|
WDT_Restart (WDT);
|
|
|
|
HAL::wdPinged = false;
|
|
|
|
}
|
|
|
|
#endif
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** \brief Timer routine for extruder stepper.
|
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
Several methods need to move the extruder. To get a optimal
|
|
|
|
result, all methods update the printer_state.extruderStepsNeeded
|
|
|
|
with the number of additional steps needed. During this
|
|
|
|
interrupt, one step is executed. This will keep the extruder
|
|
|
|
moving, until the total wanted movement is achieved. This will
|
|
|
|
be done with the maximum allowable speed for the extruder.
|
2014-11-08 11:25:51 +00:00
|
|
|
*/
|
|
|
|
#if USE_ADVANCE
|
2016-08-29 08:40:14 +00:00
|
|
|
TcChannel *extruderChannel = (EXTRUDER_TIMER->TC_CHANNEL + EXTRUDER_TIMER_CHANNEL);
|
|
|
|
#define SLOW_EXTRUDER_TICKS (F_CPU_TRUE / 32 / 1000) // 250us on direction change
|
|
|
|
#define NORMAL_EXTRUDER_TICKS (F_CPU_TRUE / 32 / EXTRUDER_CLOCK_FREQ) // 500us on direction change
|
|
|
|
#ifndef ADVANCE_DIR_FILTER_STEPS
|
|
|
|
#define ADVANCE_DIR_FILTER_STEPS 2
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int extruderLastDirection = 0;
|
2014-11-08 11:25:51 +00:00
|
|
|
void HAL::resetExtruderDirection() {
|
2016-08-29 08:40:14 +00:00
|
|
|
extruderLastDirection = 0;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
// EXTRUDER_TIMER IRQ handler
|
|
|
|
void EXTRUDER_TIMER_VECTOR ()
|
|
|
|
{
|
2016-08-29 08:40:14 +00:00
|
|
|
InterruptProtectedBlock noInt;
|
|
|
|
// apparently have to read status register
|
|
|
|
//TC_GetStatus(EXTRUDER_TIMER, EXTRUDER_TIMER_CHANNEL);
|
|
|
|
extruderChannel->TC_SR; // faster replacement for above line!
|
|
|
|
|
|
|
|
if (!Printer::isAdvanceActivated()) {
|
|
|
|
return; // currently no need
|
|
|
|
}
|
|
|
|
if (!Printer::isAdvanceActivated()) return; // currently no need
|
|
|
|
if (Printer::extruderStepsNeeded > 0 && extruderLastDirection != 1)
|
|
|
|
{
|
|
|
|
if(Printer::extruderStepsNeeded >= ADVANCE_DIR_FILTER_STEPS) {
|
|
|
|
Extruder::setDirection(true);
|
|
|
|
extruderLastDirection = 1;
|
|
|
|
//extruderChannel->TC_RC = SLOW_EXTRUDER_TICKS;
|
|
|
|
extruderChannel->TC_RC = Printer::maxExtruderSpeed;
|
|
|
|
} else {
|
|
|
|
extruderChannel->TC_RC = Printer::maxExtruderSpeed;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
2016-08-29 08:40:14 +00:00
|
|
|
}
|
|
|
|
else if (Printer::extruderStepsNeeded < 0 && extruderLastDirection != -1)
|
|
|
|
{
|
|
|
|
if(-Printer::extruderStepsNeeded >= ADVANCE_DIR_FILTER_STEPS) {
|
|
|
|
Extruder::setDirection(false);
|
|
|
|
extruderLastDirection = -1;
|
|
|
|
//extruderChannel->TC_RC = SLOW_EXTRUDER_TICKS;
|
|
|
|
extruderChannel->TC_RC = Printer::maxExtruderSpeed;
|
|
|
|
} else {
|
|
|
|
extruderChannel->TC_RC = Printer::maxExtruderSpeed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (Printer::extruderStepsNeeded != 0)
|
|
|
|
{
|
|
|
|
Extruder::step();
|
|
|
|
Printer::extruderStepsNeeded -= extruderLastDirection;
|
|
|
|
extruderChannel->TC_RC = Printer::maxExtruderSpeed;
|
|
|
|
Printer::insertStepperHighDelay();
|
|
|
|
Extruder::unstep();
|
|
|
|
}
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// IRQ handler for tone generator
|
|
|
|
void BEEPER_TIMER_VECTOR () {
|
2016-08-29 08:40:14 +00:00
|
|
|
static bool toggle;
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
TC_GetStatus(BEEPER_TIMER, BEEPER_TIMER_CHANNEL);
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
//Davinci Specific
|
|
|
|
WRITE(BEEPER_PIN, toggle);
|
|
|
|
toggle = !toggle;
|
2014-11-08 11:25:51 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
#if defined(BLUETOOTH_SERIAL) && BLUETOOTH_SERIAL > 0
|
|
|
|
RFDoubleSerial::RFDoubleSerial() {
|
|
|
|
}
|
|
|
|
void RFDoubleSerial::begin(unsigned long baud) {
|
|
|
|
RFSERIAL.begin(baud);
|
|
|
|
BT_SERIAL.begin(BLUETOOTH_BAUD);
|
|
|
|
}
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
void RFDoubleSerial::end() {
|
|
|
|
RFSERIAL.end();
|
|
|
|
BT_SERIAL.end();
|
|
|
|
}
|
|
|
|
int RFDoubleSerial::available(void) {
|
|
|
|
int x = RFSERIAL.available();
|
|
|
|
if (x > 0) return x;
|
|
|
|
return BT_SERIAL.available();
|
|
|
|
}
|
|
|
|
int RFDoubleSerial::peek(void) {
|
|
|
|
if(RFSERIAL.available())
|
|
|
|
return RFSERIAL.peek();
|
|
|
|
return BT_SERIAL.peek();
|
|
|
|
}
|
|
|
|
int RFDoubleSerial::read(void) {
|
|
|
|
if(RFSERIAL.available())
|
|
|
|
return RFSERIAL.read();
|
|
|
|
return BT_SERIAL.read();
|
|
|
|
}
|
|
|
|
void RFDoubleSerial::flush(void) {
|
|
|
|
RFSERIAL.flush();
|
|
|
|
BT_SERIAL.flush();
|
|
|
|
}
|
|
|
|
size_t RFDoubleSerial::write(uint8_t c) {
|
|
|
|
size_t r = RFSERIAL.write(c);
|
|
|
|
BT_SERIAL.write(c);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
RFDoubleSerial BTAdapter;
|
|
|
|
#endif
|
2014-11-08 11:25:51 +00:00
|
|
|
|
2016-08-29 08:40:14 +00:00
|
|
|
// Dummy function to overload weak arduino function that always disables
|
|
|
|
// watchdog. We do not need that as we do this our self.
|
|
|
|
void watchdogSetup(void) {
|
|
|
|
}
|