Shorter paths to HAL, ExtUI (#17156)
This commit is contained in:
32
Marlin/src/HAL/LINUX/hardware/Clock.cpp
Normal file
32
Marlin/src/HAL/LINUX/hardware/Clock.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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
Marlin/src/HAL/LINUX/hardware/Clock.h
Normal file
89
Marlin/src/HAL/LINUX/hardware/Clock.h
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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;
|
||||
};
|
30
Marlin/src/HAL/LINUX/hardware/Gpio.cpp
Normal file
30
Marlin/src/HAL/LINUX/hardware/Gpio.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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
Marlin/src/HAL/LINUX/hardware/Gpio.h
Normal file
141
Marlin/src/HAL/LINUX/hardware/Gpio.h
Normal file
@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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;
|
||||
};
|
61
Marlin/src/HAL/LINUX/hardware/Heater.cpp
Normal file
61
Marlin/src/HAL/LINUX/hardware/Heater.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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);
|
||||
|
||||
NOLESS(heat, room_temp_raw);
|
||||
Gpio::pin_map[analogInputToDigitalPin(adc_pin)].value = 0xFFFF - (uint16_t)heat;
|
||||
}
|
||||
}
|
||||
|
||||
void Heater::interrupt(GpioEvent ev) {
|
||||
// ununsed
|
||||
}
|
||||
|
||||
#endif // __PLAT_LINUX__
|
47
Marlin/src/HAL/LINUX/hardware/Heater.h
Normal file
47
Marlin/src/HAL/LINUX/hardware/Heater.h
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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;
|
||||
};
|
50
Marlin/src/HAL/LINUX/hardware/IOLoggerCSV.cpp
Normal file
50
Marlin/src/HAL/LINUX/hardware/IOLoggerCSV.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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__
|
40
Marlin/src/HAL/LINUX/hardware/IOLoggerCSV.h
Normal file
40
Marlin/src/HAL/LINUX/hardware/IOLoggerCSV.h
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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;
|
||||
};
|
66
Marlin/src/HAL/LINUX/hardware/LinearAxis.cpp
Normal file
66
Marlin/src/HAL/LINUX/hardware/LinearAxis.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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__
|
45
Marlin/src/HAL/LINUX/hardware/LinearAxis.h
Normal file
45
Marlin/src/HAL/LINUX/hardware/LinearAxis.h
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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
Marlin/src/HAL/LINUX/hardware/Timer.cpp
Normal file
118
Marlin/src/HAL/LINUX/hardware/Timer.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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, nullptr) == -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, nullptr) == -1) {
|
||||
return; // todo: handle error
|
||||
}
|
||||
active = true;
|
||||
//printf("timer(%ld) enabled\n", getID());
|
||||
}
|
||||
|
||||
void Timer::disable() {
|
||||
if (sigprocmask(SIG_SETMASK, &mask, nullptr) == -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, nullptr) == -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
Marlin/src/HAL/LINUX/hardware/Timer.h
Normal file
76
Marlin/src/HAL/LINUX/hardware/Timer.h
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 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;
|
||||
};
|
Reference in New Issue
Block a user