mirror of
https://github.com/synthetos/g2.git
synced 2026-09-22 19:43:53 +08:00
Ultimaker Interim commit
This commit is contained in:
+1
-1
Submodule Motate updated: 508cd27ec3...3d0d332dc5
@@ -29,14 +29,14 @@ ifeq ("$(BASE_BOARD)","gquintic")
|
||||
|
||||
DEVICE_DEFINES += MOTATE_CONFIG_HAS_USBSERIAL=1 ENABLE_TCM=1
|
||||
|
||||
FIRST_LINK_SOURCES += $(sort $(wildcard ${MOTATE_PATH}/Atmel_sam_common/*.cpp)) $(sort $(wildcard ${MOTATE_PATH}/Atmel_sams70/*.cpp))
|
||||
FIRST_LINK_SOURCES += $(sort $(wildcard ${MOTATE_PATH}/Atmel_sam_common/*.cpp)) $(sort $(wildcard ${MOTATE_PATH}/Atmel_sams70/*.cpp) $(wildcard ${BOARD_PATH}/*.cpp))
|
||||
|
||||
CHIP = SAMS70N19
|
||||
export CHIP
|
||||
CHIP_LOWERCASE = sams70n19
|
||||
|
||||
BOARD_PATH = ./board/gquintic
|
||||
SOURCE_DIRS += ${BOARD_PATH} device/trinamic device/step_dir_hobbyservo
|
||||
SOURCE_DIRS += ${BOARD_PATH} device/trinamic device/step_dir_hobbyservo device/max31865
|
||||
|
||||
PLATFORM_BASE = ${MOTATE_PATH}/platform/atmel_sam
|
||||
include $(PLATFORM_BASE).mk
|
||||
|
||||
@@ -39,12 +39,16 @@
|
||||
//Motate::ClockOutputPin<Motate::kExternalClock1_PinNumber> external_clk_pin {16000000}; // 16MHz optimally
|
||||
Motate::OutputPin<Motate::kExternalClock1_PinNumber> external_clk_pin {Motate::kStartLow};
|
||||
|
||||
SPI_CS_PinMux_used_t spiCSPinMux;
|
||||
SPIBus_used_t spiBus;
|
||||
|
||||
/*
|
||||
* hardware_init() - lowest level hardware init
|
||||
*/
|
||||
|
||||
void hardware_init()
|
||||
{
|
||||
spiBus.init();
|
||||
board_hardware_init();
|
||||
external_clk_pin = 0; // Force external clock to 0 for now.
|
||||
}
|
||||
@@ -28,47 +28,38 @@
|
||||
|
||||
#include "board_stepper.h"
|
||||
|
||||
|
||||
Motate::SPIChipSelectPinMux<Motate::kSocket1_SPISlaveSelectPinNumber,
|
||||
Motate::kSocket2_SPISlaveSelectPinNumber,
|
||||
Motate::kSocket3_SPISlaveSelectPinNumber,
|
||||
-1>
|
||||
spiCSPinMux;
|
||||
SPIBus_used_t spiBus;
|
||||
|
||||
// These are identical to board_stepper.h, except for the word "extern" and the initialization
|
||||
Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
Motate::kSocket1_StepPinNumber,
|
||||
Motate::kSocket1_DirPinNumber,
|
||||
Motate::kSocket1_EnablePinNumber>
|
||||
motor_1{spiBus, spiCSPinMux.getCS(4)};
|
||||
//Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
// Motate::kSocket1_StepPinNumber,
|
||||
// Motate::kSocket1_DirPinNumber,
|
||||
// Motate::kSocket1_EnablePinNumber>
|
||||
// motor_1{spiBus, spiCSPinMux.getCS(4)};
|
||||
Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
Motate::kSocket2_StepPinNumber,
|
||||
Motate::kSocket2_DirPinNumber,
|
||||
Motate::kSocket2_EnablePinNumber>
|
||||
motor_2{spiBus, spiCSPinMux.getCS(3)};
|
||||
motor_1{spiBus, spiCSPinMux.getCS(3)};
|
||||
Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
Motate::kSocket3_StepPinNumber,
|
||||
Motate::kSocket3_DirPinNumber,
|
||||
Motate::kSocket3_EnablePinNumber>
|
||||
motor_3{spiBus, spiCSPinMux.getCS(2)};
|
||||
motor_2{spiBus, spiCSPinMux.getCS(2)};
|
||||
Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
Motate::kSocket4_StepPinNumber,
|
||||
Motate::kSocket4_DirPinNumber,
|
||||
Motate::kSocket4_EnablePinNumber>
|
||||
motor_4{spiBus, spiCSPinMux.getCS(1)};
|
||||
motor_3{spiBus, spiCSPinMux.getCS(1)};
|
||||
Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
Motate::kSocket5_StepPinNumber,
|
||||
Motate::kSocket5_DirPinNumber,
|
||||
Motate::kSocket5_EnablePinNumber>
|
||||
motor_5{spiBus, spiCSPinMux.getCS(0)};
|
||||
motor_4{spiBus, spiCSPinMux.getCS(0)};
|
||||
|
||||
StepDirHobbyServo<Motate::kServo1_PinNumber> motor_6;
|
||||
StepDirHobbyServo<Motate::kServo1_PinNumber> motor_5;
|
||||
|
||||
Stepper* Motors[MOTORS] = {&motor_1, &motor_2, &motor_3, &motor_4, &motor_5, &motor_6};
|
||||
Stepper* Motors[MOTORS] = {&motor_1, &motor_2, &motor_3, &motor_4, &motor_5};
|
||||
//Stepper* Motors[MOTORS] = {&motor_1, &motor_2, &motor_3, &motor_4, &motor_5, &motor_6};
|
||||
|
||||
void board_stepper_init() {
|
||||
spiBus.init();
|
||||
|
||||
for (uint8_t motor = 0; motor < MOTORS; motor++) { Motors[motor]->init(); }
|
||||
}
|
||||
|
||||
@@ -32,35 +32,33 @@
|
||||
#include "tmc2130.h"
|
||||
#include "step_dir_hobbyservo.h"
|
||||
|
||||
typedef Motate::SPIBus<Motate::kSPI_MISOPinNumber, Motate::kSPI_MOSIPinNumber, Motate::kSPI_SCKPinNumber, kSPI_ServiceCallNumber> SPIBus_used_t;
|
||||
|
||||
// These are identical to board_stepper.h, except for the word "extern" and the initialization
|
||||
extern Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
Motate::kSocket1_StepPinNumber,
|
||||
Motate::kSocket1_DirPinNumber,
|
||||
Motate::kSocket1_EnablePinNumber>
|
||||
motor_1;
|
||||
//extern Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
// Motate::kSocket1_StepPinNumber,
|
||||
// Motate::kSocket1_DirPinNumber,
|
||||
// Motate::kSocket1_EnablePinNumber>
|
||||
// motor_1;
|
||||
extern Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
Motate::kSocket2_StepPinNumber,
|
||||
Motate::kSocket2_DirPinNumber,
|
||||
Motate::kSocket2_EnablePinNumber>
|
||||
motor_2;
|
||||
motor_1;
|
||||
extern Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
Motate::kSocket3_StepPinNumber,
|
||||
Motate::kSocket3_DirPinNumber,
|
||||
Motate::kSocket3_EnablePinNumber>
|
||||
motor_3;
|
||||
motor_2;
|
||||
extern Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
Motate::kSocket4_StepPinNumber,
|
||||
Motate::kSocket4_DirPinNumber,
|
||||
Motate::kSocket4_EnablePinNumber>
|
||||
motor_4;
|
||||
motor_3;
|
||||
extern Trinamic2130<SPIBus_used_t::SPIBusDevice,
|
||||
Motate::kSocket5_StepPinNumber,
|
||||
Motate::kSocket5_DirPinNumber,
|
||||
Motate::kSocket5_EnablePinNumber>
|
||||
motor_5;
|
||||
extern StepDirHobbyServo<Motate::kServo1_PinNumber> motor_6;
|
||||
motor_4;
|
||||
extern StepDirHobbyServo<Motate::kServo1_PinNumber> motor_5;
|
||||
|
||||
extern Stepper* Motors[MOTORS];
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ void board_hardware_init(void) // called 1st
|
||||
}
|
||||
|
||||
|
||||
void board_xio_init(void) // called later than board_hardware_init (there are thing in between)
|
||||
void board_xio_init(void) // called later than board_hardware_init (there are things in between)
|
||||
{
|
||||
// Init SPI
|
||||
#if XIO_HAS_SPI
|
||||
|
||||
@@ -148,7 +148,7 @@ _MAKE_MOTATE_PIN(kSocket2_DirPinNumber, 'A', 25); //
|
||||
_MAKE_MOTATE_PIN(kOutput5_PinNumber, 'A', 26); // TC 2,0
|
||||
_MAKE_MOTATE_PIN(kSocket3_DirPinNumber, 'A', 27); // On Timer 2!
|
||||
_MAKE_MOTATE_PIN(kUnassigned1, 'A', 28); // DIAG1
|
||||
_MAKE_MOTATE_PIN(kUnassigned2, 'A', 29); //
|
||||
_MAKE_MOTATE_PIN(kUnassigned2, 'A', 29); // NO PHYSICAL PIN
|
||||
_MAKE_MOTATE_PIN(kInput1_PinNumber, 'A', 30); //
|
||||
_MAKE_MOTATE_PIN(kInput4_PinNumber, 'A', 31); //
|
||||
|
||||
@@ -192,13 +192,13 @@ _MAKE_MOTATE_PIN(kUnassigned6, 'D', 19); //
|
||||
_MAKE_MOTATE_PIN(kSPI0_MISOPinNumber, 'D', 20); //
|
||||
_MAKE_MOTATE_PIN(kSPI0_MOSIPinNumber, 'D', 21); //
|
||||
_MAKE_MOTATE_PIN(kSPI0_SCKPinNumber, 'D', 22); //
|
||||
_MAKE_MOTATE_PIN(kUnassigned7, 'D', 23); //
|
||||
_MAKE_MOTATE_PIN(kUnassigned7, 'D', 23); // NO PHYSICAL PIN
|
||||
_MAKE_MOTATE_PIN(kSocket2_StepPinNumber, 'D', 24); //
|
||||
_MAKE_MOTATE_PIN(kSocket2_SPISlaveSelectPinNumber, 'D', 25); //
|
||||
_MAKE_MOTATE_PIN(kOutput9_PinNumber, 'D', 26); // PWM 2
|
||||
_MAKE_MOTATE_PIN(kSocket1_DirPinNumber, 'D', 27); //
|
||||
_MAKE_MOTATE_PIN(kSocket4_EnablePinNumber, 'D', 28); //
|
||||
_MAKE_MOTATE_PIN(kUnassigned8, 'D', 29); //
|
||||
_MAKE_MOTATE_PIN(kUnassigned8, 'D', 29); // NO PHYSICAL PIN
|
||||
_MAKE_MOTATE_PIN(kUnassigned9, 'D', 30); // INTERRUPT_OUT
|
||||
_MAKE_MOTATE_PIN(kUnassigned10, 'D', 31); //
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ enum hwPlatform {
|
||||
|
||||
#define AXES 6 // number of axes supported in this version
|
||||
#define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence)
|
||||
#define MOTORS 6 // number of motors on the board - 5 Trinamics + 1 servo
|
||||
#define MOTORS 5 // number of motors on the board - 5 Trinamics + 1 servo
|
||||
#define COORDS 6 // number of supported coordinate systems (index starts at 1)
|
||||
#define PWMS 2 // number of supported PWM channels
|
||||
#define TOOLS 32 // number of entries in tool table (index starts at 1)
|
||||
@@ -69,6 +69,7 @@ enum hwPlatform {
|
||||
////////////////////////////
|
||||
|
||||
#include "MotatePins.h"
|
||||
#include "MotateSPI.h"
|
||||
#include "MotateTimers.h" // for TimerChanel<> and related...
|
||||
#include "MotateServiceCall.h" // for ServiceCall<>
|
||||
|
||||
@@ -134,19 +135,19 @@ typedef TimerChannel<11, 0> fwd_plan_timer_type; // request exec timer in step
|
||||
|
||||
Motate::service_call_number kSPI_ServiceCallNumber = 3;
|
||||
|
||||
// Pin assignments
|
||||
/**** SPI Setup ****/
|
||||
|
||||
typedef Motate::SPIBus<Motate::kSPI_MISOPinNumber, Motate::kSPI_MOSIPinNumber, Motate::kSPI_SCKPinNumber, kSPI_ServiceCallNumber> SPIBus_used_t;
|
||||
extern SPIBus_used_t spiBus;
|
||||
|
||||
typedef Motate::SPIChipSelectPinMux<Motate::kSocket1_SPISlaveSelectPinNumber, Motate::kSocket2_SPISlaveSelectPinNumber, Motate::kSocket3_SPISlaveSelectPinNumber, -1> SPI_CS_PinMux_used_t;
|
||||
extern SPI_CS_PinMux_used_t spiCSPinMux;
|
||||
|
||||
/**** Motate Global Pin Allocations ****/
|
||||
|
||||
pin_number indicator_led_pin_num = Motate::kLED_USBRXPinNumber;
|
||||
static OutputPin<indicator_led_pin_num> IndicatorLed;
|
||||
|
||||
/**** Motate Global Pin Allocations ****/
|
||||
|
||||
//static OutputPin<kSocket1_SPISlaveSelectPinNumber> spi_ss1_pin;
|
||||
//static OutputPin<kSocket2_SPISlaveSelectPinNumber> spi_ss2_pin;
|
||||
//static OutputPin<kSocket3_SPISlaveSelectPinNumber> spi_ss3_pin;
|
||||
//static OutputPin<kSocket4_SPISlaveSelectPinNumber> spi_ss4_pin;
|
||||
//static OutputPin<kSocket5_SPISlaveSelectPinNumber> spi_ss5_pin;
|
||||
//static OutputPin<kSocket6_SPISlaveSelectPinNumber> spi_ss6_pin;
|
||||
static OutputPin<Motate::kKinen_SyncPinNumber> kinen_sync_pin;
|
||||
|
||||
static OutputPin<Motate::kGRBL_ResetPinNumber> grbl_reset_pin;
|
||||
|
||||
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* max31865/max31865.h - suppport for talking to the MAX31865 RTD (PT100) sensor amp/ADC
|
||||
* This file is part of the G2 project
|
||||
*
|
||||
* Copyright (c) 2017 Alden S. Hart, Jr.
|
||||
* Copyright (c) 2017 Robert Giseburt
|
||||
*
|
||||
* This file ("the software") is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License, version 2 as published by the
|
||||
* Free Software Foundation. You should have received a copy of the GNU General Public
|
||||
* License, version 2 along with the software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, you may use this file as part of a software library without
|
||||
* restriction. Specifically, if other files instantiate templates or use macros or
|
||||
* inline functions from this file, or you compile this file and link it with other
|
||||
* files to produce an executable, this file does not by itself cause the resulting
|
||||
* executable to be covered by the GNU General Public License. This exception does not
|
||||
* however invalidate any other reasons why the executable file might be covered by the
|
||||
* GNU General Public License.
|
||||
*
|
||||
* THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
|
||||
* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// Many thanks to Adafruit!
|
||||
// More specifically, for their driver at
|
||||
// https://github.com/adafruit/Adafruit_MAX31865
|
||||
// and their breakout board at https://adafru.it/3328
|
||||
|
||||
#ifndef max31865_h
|
||||
#define max31865_h
|
||||
|
||||
#include "MotateSPI.h"
|
||||
#include "MotateBuffer.h"
|
||||
#include "MotateUtilities.h" // for to/fromLittle/BigEndian
|
||||
|
||||
using Motate::OutputPin;
|
||||
using Motate::kStartHigh;
|
||||
using Motate::SPIMessage;
|
||||
using Motate::SPIInterrupt;
|
||||
using Motate::SPIDeviceMode;
|
||||
using Motate::fromBigEndian;
|
||||
using Motate::toBigEndian;
|
||||
|
||||
// Complete class for MAX31865 drivers.
|
||||
template <typename device_t>
|
||||
struct MAX31865 final {
|
||||
// SPI and message handling properties
|
||||
device_t _device;
|
||||
SPIMessage _message;
|
||||
|
||||
// Record if we're transmitting to prevent altering the buffers while they
|
||||
// are being transmitted still.
|
||||
volatile bool _transmitting = false;
|
||||
|
||||
// We don't want to transmit until we're inited
|
||||
bool _inited = false;
|
||||
|
||||
// Record what register we just requested, so we know what register the
|
||||
// the response is for (and to read the response.)
|
||||
int16_t _active_register = -1;
|
||||
|
||||
// Timer to keep track of when we need to do another periodic update
|
||||
Motate::Timeout _check_timer;
|
||||
|
||||
// Constructor - this is the only time we directly use the SBIBus
|
||||
template <typename SPIBus_t, typename chipSelect_t>
|
||||
MAX31865(SPIBus_t &spi_bus, const chipSelect_t &_cs, bool is_three_pin = false, bool fifty_hz = true) :
|
||||
_device{spi_bus.getDevice(_cs,
|
||||
5000000,
|
||||
SPIDeviceMode::kSPIMode2 | SPIDeviceMode::kSPI8Bit,
|
||||
400, // min_between_cs_delay_ns
|
||||
400, // cs_to_sck_delay_ns
|
||||
80 // between_word_delay_ns
|
||||
)}
|
||||
{
|
||||
init(is_three_pin, fifty_hz);
|
||||
};
|
||||
|
||||
// Prevent copying, and prevent moving (so we know if it happens)
|
||||
MAX31865(const MAX31865 &) = delete;
|
||||
MAX31865(MAX31865 &&other) : _device{std::move(other._device)} {};
|
||||
|
||||
|
||||
// ###########
|
||||
// From here on we store actual values from the MAX31865, and marshall data
|
||||
// from the in_buffer buffer to them, or from the values to the out_buffer.
|
||||
|
||||
// Note that this includes _startNextReadWrite() and _doneReadingCallback(),
|
||||
// which are what calls the functions to put data into the out_buffer and
|
||||
// read data from the in_buffer, respectively.
|
||||
|
||||
// Also, _init() is last, so it can setup a newly created MAX31865 object.
|
||||
|
||||
enum {
|
||||
CONFIG_reg = 0x00,
|
||||
RTD_reg = 0x01,
|
||||
HFAULT_reg = 0x03,
|
||||
LFAULT_reg = 0x05,
|
||||
FAULTSTAT_reg = 0x07,
|
||||
};
|
||||
|
||||
// IMPORTANT NOTE: The endianness of the ARM is little endian, but other processors
|
||||
// may be different.
|
||||
|
||||
uint8_t _scribble_buffer[4];
|
||||
|
||||
struct {
|
||||
uint8_t address;
|
||||
union {
|
||||
uint8_t value;
|
||||
struct {
|
||||
uint8_t fifty_or_sixty : 1; // 0
|
||||
uint8_t clear_fault : 1; // 1
|
||||
uint8_t fault_detection : 2; // 3-2
|
||||
uint8_t three_wire : 1; // 4
|
||||
uint8_t one_shot : 1; // 5
|
||||
uint8_t auto_mode : 1; // 6
|
||||
uint8_t v_bias : 1; // 7
|
||||
} __attribute__ ((packed));
|
||||
};
|
||||
} _config;
|
||||
bool _config_needs_read = false;
|
||||
bool _config_needs_written = false;
|
||||
void _postReadConf() {};
|
||||
|
||||
struct {
|
||||
uint8_t address;
|
||||
uint8_t high;
|
||||
uint8_t low;
|
||||
} _rtd_value_raw;
|
||||
float _rtd_value = -1;
|
||||
bool _rtd_value_needs_read = false;
|
||||
void _postReadRTD() {
|
||||
bool fault_detected = _rtd_value_raw.low & 0x01;
|
||||
uint16_t rtd_value_int = (_rtd_value_raw.high << 7) | (_rtd_value_raw.low >> 1);
|
||||
_rtd_value = 32768.0/(float)rtd_value_int;
|
||||
if (fault_detected) {
|
||||
_fault_status_needs_read = true;
|
||||
}
|
||||
if (_interrupt_handler) {
|
||||
_interrupt_handler();
|
||||
}
|
||||
};
|
||||
|
||||
struct {
|
||||
uint8_t address;
|
||||
uint8_t high;
|
||||
uint8_t low;
|
||||
} _fault_high;
|
||||
bool _fault_high_needs_read = false;
|
||||
bool _fault_high_needs_written = false;
|
||||
void _postReadFaultHigh() {};
|
||||
|
||||
struct {
|
||||
uint8_t address;
|
||||
uint8_t high;
|
||||
uint8_t low;
|
||||
} _fault_low;
|
||||
bool _fault_low_needs_read = false;
|
||||
bool _fault_low_needs_written = false;
|
||||
void _postReadFaultLow() {};
|
||||
|
||||
struct {
|
||||
uint8_t address;
|
||||
union {
|
||||
volatile uint8_t value;
|
||||
struct {
|
||||
uint8_t _unused : 2; // 1-0
|
||||
uint8_t over_under_voltage : 1; // 2
|
||||
uint8_t open_detection : 1; // 3
|
||||
uint8_t ref_too_low : 1; // 4
|
||||
uint8_t ref_too_high : 1; // 5
|
||||
uint8_t under_threhold : 1; // 6
|
||||
uint8_t over_threshold : 1; // 7
|
||||
} __attribute__ ((packed));
|
||||
};
|
||||
} _fault_status;
|
||||
bool _fault_status_needs_read = false;
|
||||
void _postReadFaultStatus() {
|
||||
/* here is where we would call alarm or something!! */
|
||||
};
|
||||
|
||||
void _startNextReadWrite()
|
||||
{
|
||||
if (_transmitting || !_inited) { return; }
|
||||
_transmitting = true; // preemptively say we're transmitting .. as a mutex
|
||||
|
||||
// We request the next register, and keep track of how long it is.
|
||||
uint8_t next_reg = 0;
|
||||
uint8_t *data_buffer = nullptr;
|
||||
int8_t register_size;
|
||||
|
||||
// We write before we read -- so we don't lose what we set in the registers when writing
|
||||
|
||||
// check if we need to write registers
|
||||
if (_config_needs_written) { next_reg = 0x80 | CONFIG_reg; data_buffer = (uint8_t*)&_config; register_size = 1; _config_needs_written = false; } else
|
||||
if (_fault_high_needs_written) { next_reg = 0x80 | HFAULT_reg; data_buffer = (uint8_t*)&_fault_high; register_size = 2; _fault_high_needs_written = false; } else
|
||||
if (_fault_low_needs_written) { next_reg = 0x80 | LFAULT_reg; data_buffer = (uint8_t*)&_fault_low; register_size = 2; _fault_low_needs_written = false; } else
|
||||
|
||||
// check if we need to read reagisters
|
||||
if (_config_needs_read) { next_reg = CONFIG_reg; data_buffer = (uint8_t*)&_config; register_size = 1; _config_needs_read = false; } else
|
||||
if (_rtd_value_needs_read) { next_reg = RTD_reg; data_buffer = (uint8_t*)&_rtd_value_raw; register_size = 2; _rtd_value_needs_read = false; } else
|
||||
if (_fault_high_needs_read) { next_reg = HFAULT_reg; data_buffer = (uint8_t*)&_fault_high; register_size = 2; _fault_high_needs_read = false; } else
|
||||
if (_fault_low_needs_read) { next_reg = LFAULT_reg; data_buffer = (uint8_t*)&_fault_low; register_size = 2; _fault_low_needs_read = false; } else
|
||||
if (_fault_status_needs_read) { next_reg = FAULTSTAT_reg; data_buffer = (uint8_t*)&_fault_status; register_size = 1; _fault_status_needs_read = false; } else
|
||||
|
||||
// otherwise we're done here
|
||||
{
|
||||
_active_register = -1;
|
||||
_transmitting = false; // we're not really transmitting.
|
||||
return;
|
||||
}
|
||||
|
||||
_active_register = next_reg;
|
||||
*data_buffer = next_reg;
|
||||
|
||||
if (next_reg & 0x80) {
|
||||
// writing, copy what we're
|
||||
_scribble_buffer[0] = data_buffer[0];
|
||||
_scribble_buffer[1] = 0xFF;
|
||||
_scribble_buffer[2] = 0xFF;
|
||||
_scribble_buffer[3] = 0xFF;
|
||||
|
||||
_message.setup(data_buffer, _scribble_buffer, 1+register_size, SPIMessage::DeassertAfter, SPIMessage::EndTransaction);
|
||||
} else {
|
||||
_scribble_buffer[0] = data_buffer[0];
|
||||
_scribble_buffer[1] = 0xFF;
|
||||
_scribble_buffer[2] = 0xFF;
|
||||
_scribble_buffer[3] = 0xFF;
|
||||
|
||||
_message.setup(_scribble_buffer, data_buffer, 1+register_size, SPIMessage::DeassertAfter, SPIMessage::EndTransaction);
|
||||
}
|
||||
_device.queueMessage(&_message);
|
||||
};
|
||||
|
||||
void _doneReadingCallback()
|
||||
{
|
||||
_transmitting = false;
|
||||
|
||||
// Check to make sure it was a read, and handle it accordingly
|
||||
if (0 == (_active_register & 0x80)) {
|
||||
switch (_active_register) {
|
||||
case CONFIG_reg: _postReadConf(); break;
|
||||
case RTD_reg: _postReadRTD(); break;
|
||||
case HFAULT_reg: _postReadFaultHigh(); break;
|
||||
case LFAULT_reg: _postReadFaultLow(); break;
|
||||
case FAULTSTAT_reg: _postReadFaultStatus(); break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_active_register = -1;
|
||||
_startNextReadWrite();
|
||||
};
|
||||
|
||||
void init(bool is_three_pin = false, bool fifty_hz = false)
|
||||
{
|
||||
_message.message_done_callback = [&] { this->_doneReadingCallback(); };
|
||||
|
||||
// Establish default values, and then prepare to read the registers we can to establish starting values
|
||||
|
||||
_config.v_bias = false; // effectively enable the device
|
||||
_config.auto_mode = false; // automatically run conversions
|
||||
_config.one_shot = false; // this is a command
|
||||
_config.fault_detection = 0; // this is a command - run automatic fault detection
|
||||
_config.clear_fault = false; // this is a command, and we want to execture it
|
||||
_config.fifty_or_sixty = fifty_hz; // this is a command
|
||||
_config_needs_written = false;
|
||||
//_config_needs_read = true;
|
||||
|
||||
_fault_high = {HFAULT_reg, 0xff, 0xff}; //_fault_high_needs_read = true;
|
||||
_fault_low = {LFAULT_reg, 0x00, 0x00}; //_fault_low_needs_read = true;
|
||||
|
||||
_inited = true;
|
||||
//_startNextReadWrite();
|
||||
_check_timer.set(fifty_hz ? 1000/50 : 1000/60);
|
||||
};
|
||||
|
||||
// interface to make this a drop-in replacement (after init) for an ADCPin
|
||||
|
||||
float _vref = 3.3;
|
||||
std::function<void(void)> _interrupt_handler;
|
||||
|
||||
enum {
|
||||
INITING,
|
||||
SETUP_WIRES,
|
||||
CLEAR_FAULT,
|
||||
SETUP_BIAS,
|
||||
NEEDS_SAMPLED,
|
||||
WAITING_FOR_SAMPLE
|
||||
} _state;
|
||||
|
||||
void startSampling()
|
||||
{
|
||||
if (_check_timer.isPast()) {
|
||||
if (INITING == _state) {
|
||||
_config_needs_read = true;
|
||||
_fault_high_needs_read = true;
|
||||
_fault_low_needs_read = true;
|
||||
|
||||
_check_timer.set(10);
|
||||
_startNextReadWrite();
|
||||
_state = SETUP_WIRES;
|
||||
}
|
||||
else if (SETUP_WIRES == _state) {
|
||||
_config.three_wire = false;
|
||||
_config_needs_written = true;
|
||||
_config_needs_read = true;
|
||||
|
||||
_check_timer.set(10);
|
||||
_startNextReadWrite();
|
||||
_state = CLEAR_FAULT;
|
||||
}
|
||||
else if (CLEAR_FAULT == _state) {
|
||||
_config.clear_fault = true;
|
||||
_config_needs_written = true;
|
||||
_config_needs_read = true;
|
||||
|
||||
_check_timer.set(10);
|
||||
_startNextReadWrite();
|
||||
_state = SETUP_BIAS;
|
||||
}
|
||||
else if (SETUP_BIAS == _state) {
|
||||
_config.v_bias = true;
|
||||
_config_needs_written = true;
|
||||
_config_needs_read = true;
|
||||
|
||||
_check_timer.set(10);
|
||||
_startNextReadWrite();
|
||||
_state = NEEDS_SAMPLED;
|
||||
}
|
||||
else if (NEEDS_SAMPLED == _state) {
|
||||
_config.one_shot = true;
|
||||
_config_needs_written = true;
|
||||
_config_needs_read = true;
|
||||
|
||||
_check_timer.set(70);
|
||||
_startNextReadWrite();
|
||||
_state = WAITING_FOR_SAMPLE;
|
||||
}
|
||||
else if (WAITING_FOR_SAMPLE == _state) {
|
||||
_rtd_value_needs_read = true;
|
||||
|
||||
_check_timer.set(1);
|
||||
_startNextReadWrite();
|
||||
_state = SETUP_BIAS;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int32_t getRaw() {
|
||||
uint16_t rtd_value_int = (_rtd_value_raw.high << 7) | (_rtd_value_raw.low >> 1);
|
||||
return rtd_value_int;
|
||||
};
|
||||
int32_t getValue() {
|
||||
return _rtd_value;
|
||||
};
|
||||
int32_t getBottom() {
|
||||
return 0;
|
||||
};
|
||||
float getBottomVoltage() {
|
||||
return 0;
|
||||
};
|
||||
int32_t getTop() {
|
||||
return 32767;
|
||||
};
|
||||
float getTopVoltage() {
|
||||
return _vref;
|
||||
};
|
||||
|
||||
void setVoltageRange(const float vref, const float min_expected = 0, const float max_expected = -1, const bool differential = false, const float ideal_steps = 1)
|
||||
{
|
||||
_vref = vref;
|
||||
|
||||
// uint16_t min_expected_int = (uint16_t)((min_expected/vref) * 32767.0) << 1;
|
||||
// fault_low.high = (min_expected_int >> 8) & 0xff;
|
||||
// fault_low.low = min_expected_int & 0xff;
|
||||
// fault_low_needs_written = true;
|
||||
//
|
||||
// if (max_expected > 0) {
|
||||
// uint16_t max_expected_int = (uint16_t)((max_expected/vref) * 32767.0) << 1;
|
||||
// fault_high.high = (max_expected_int >> 8) & 0xff;
|
||||
// fault_high.low = max_expected_int & 0xff;
|
||||
// fault_high_needs_written = true;
|
||||
// }
|
||||
|
||||
// differential should always be false
|
||||
// we can't control the resolution, so ignore ideal_steps too
|
||||
};
|
||||
float getVoltage() {
|
||||
return _rtd_value * _vref;
|
||||
};
|
||||
operator float() { return getVoltage(); };
|
||||
|
||||
void setInterrupts(const uint32_t interrupts) {
|
||||
// ignore this -- it's too dangerous to accidentally change the SPI interrupts
|
||||
};
|
||||
|
||||
// We can only support interrupt inferface option 2: a function with a closure or function pointer
|
||||
void setInterruptHandler(std::function<void(void)> &&handler) {
|
||||
_interrupt_handler = std::move(handler);
|
||||
};
|
||||
void setInterruptHandler(const std::function<void(void)> &handler) {
|
||||
_interrupt_handler = handler;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // max31865_h
|
||||
@@ -91,11 +91,11 @@ struct Trinamic2130 final : Stepper {
|
||||
template <typename SPIBus_t, typename chipSelect_t>
|
||||
Trinamic2130(SPIBus_t &spi_bus, const chipSelect_t &_cs) :
|
||||
_device{spi_bus.getDevice(_cs,
|
||||
4000000, //1MHz
|
||||
SPIDeviceMode::kSPIMode2 | SPIDeviceMode::kSPI8Bit,
|
||||
4000000, //4MHz
|
||||
SPIDeviceMode::kSPIMode1 | SPIDeviceMode::kSPI8Bit,
|
||||
0, // min_between_cs_delay_ns
|
||||
10, // cs_to_sck_delay_ns
|
||||
0 // between_word_delay_ns
|
||||
1 // between_word_delay_ns
|
||||
)}
|
||||
{};
|
||||
|
||||
|
||||
@@ -232,6 +232,20 @@
|
||||
passBuildSettingsInEnvironment = 1;
|
||||
productName = g3_due;
|
||||
};
|
||||
D43DFE011E8C84B400A2030D /* G2 gQuadratic Ultimaker2+ */ = {
|
||||
isa = PBXLegacyTarget;
|
||||
buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=Ultimaker2Plus DEBUG=0";
|
||||
buildConfigurationList = D43DFE021E8C84B400A2030D /* Build configuration list for PBXLegacyTarget "G2 gQuadratic Ultimaker2+" */;
|
||||
buildPhases = (
|
||||
);
|
||||
buildToolPath = /usr/bin/make;
|
||||
buildWorkingDirectory = .;
|
||||
dependencies = (
|
||||
);
|
||||
name = "G2 gQuadratic Ultimaker2+";
|
||||
passBuildSettingsInEnvironment = 1;
|
||||
productName = g3_due;
|
||||
};
|
||||
D43FF7141D537A5C00FB5B53 /* G2 gQuadratic Test */ = {
|
||||
isa = PBXLegacyTarget;
|
||||
buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=TestQuadratic DEBUG=2";
|
||||
@@ -290,7 +304,7 @@
|
||||
};
|
||||
D492E5AE1E54C2B4005ED97D /* G2 gQuadratic AxiDraw v3 */ = {
|
||||
isa = PBXLegacyTarget;
|
||||
buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=AxiDrawv3 DEBUG=2";
|
||||
buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=AxiDrawv3 DEBUG=0";
|
||||
buildConfigurationList = D492E5AF1E54C2B4005ED97D /* Build configuration list for PBXLegacyTarget "G2 gQuadratic AxiDraw v3" */;
|
||||
buildPhases = (
|
||||
);
|
||||
@@ -426,6 +440,7 @@
|
||||
D457112317053BFB00EA19A8 /* index */,
|
||||
D4782AB61D9E39EC00B32136 /* G2 EggBot */,
|
||||
D492E5AE1E54C2B4005ED97D /* G2 gQuadratic AxiDraw v3 */,
|
||||
D43DFE011E8C84B400A2030D /* G2 gQuadratic Ultimaker2+ */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -505,6 +520,22 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
D43DFE031E8C84B400A2030D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PATH = "$PATH:/usr/local/gcc-arm-none-eabi/bin";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
D43DFE041E8C84B400A2030D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PATH = "$PATH:/usr/local/gcc-arm-none-eabi/bin";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
D43FF7161D537A5C00FB5B53 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@@ -817,6 +848,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
D43DFE021E8C84B400A2030D /* Build configuration list for PBXLegacyTarget "G2 gQuadratic Ultimaker2+" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
D43DFE031E8C84B400A2030D /* Debug */,
|
||||
D43DFE041E8C84B400A2030D /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
D43FF7151D537A5C00FB5B53 /* Build configuration list for PBXLegacyTarget "G2 gQuadratic Test" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
||||
@@ -259,6 +259,8 @@
|
||||
|
||||
//** Temperature Sensors **
|
||||
|
||||
#include "device/max31865/max31865.h"
|
||||
|
||||
#define HAS_TEMPERATURE_SENSOR_1 true
|
||||
#if HAS_TEMPERATURE_SENSOR_1
|
||||
// Must choose Thermistor or PT100
|
||||
@@ -269,8 +271,10 @@
|
||||
/*R1:*/ 144700.0, /*R2:*/ 5190.0, /*R3:*/ 4809.0, /*pullup_resistance:*/ 4700 \
|
||||
}
|
||||
#else
|
||||
#define TEMPERATURE_SENSOR_1_TYPE PT100<ADCPin<kADC1_PinNumber>>
|
||||
#define TEMPERATURE_SENSOR_1_INIT {/*pullup_resistance:*/ 100, /*inline_resistance*/0, /*wheatstone*/ true}
|
||||
//#define TEMPERATURE_SENSOR_1_TYPE PT100<ADCPin<kADC1_PinNumber>>
|
||||
//#define TEMPERATURE_SENSOR_1_INIT {/*pullup_resistance:*/ 2200, /*inline_resistance*/0.003, /*differential*/ true}
|
||||
#define TEMPERATURE_SENSOR_1_TYPE PT100<MAX31865<SPIBus_used_t::SPIBusDevice>>
|
||||
#define TEMPERATURE_SENSOR_1_INIT {/*pullup_resistance:*/ 2200, /*inline_resistance*/0.003, /*differential*/ false, spiBus, spiCSPinMux.getCS(6)}
|
||||
#endif // 0 or 1
|
||||
#endif // HAS_TEMPERATURE_SENSOR_1
|
||||
|
||||
@@ -287,7 +291,7 @@
|
||||
}
|
||||
#else
|
||||
#define TEMPERATURE_SENSOR_2_TYPE PT100<ADCPin<kADC3_PinNumber>>
|
||||
#define TEMPERATURE_SENSOR_2_INIT {/*pullup_resistance:*/ 100, /*inline_resistance*/0}
|
||||
#define TEMPERATURE_SENSOR_2_INIT {/*pullup_resistance:*/ 2200, /*inline_resistance*/0}
|
||||
#endif // 0 or 1
|
||||
#endif // HAS_TEMPERATURE_SENSOR_2
|
||||
|
||||
@@ -303,7 +307,7 @@
|
||||
}
|
||||
#else
|
||||
#define TEMPERATURE_SENSOR_3_TYPE PT100<ADCPin<kADC2_PinNumber>>
|
||||
#define TEMPERATURE_SENSOR_3_INIT {/*pullup_resistance:*/ 100, /*inline_resistance*/0, /*wheatstone*/ true}
|
||||
#define TEMPERATURE_SENSOR_3_INIT {/*pullup_resistance:*/ 2200, /*inline_resistance*/0.003, /*differential*/ true}
|
||||
#endif // 0 or 1
|
||||
#endif // HAS_TEMPERATURE_SENSOR_3
|
||||
|
||||
|
||||
@@ -27,11 +27,13 @@
|
||||
*/
|
||||
|
||||
/***********************************************************************/
|
||||
/**** TestV9 profile - naked board *************************************/
|
||||
/**** AxiDraw v3 Configuration *****************************************/
|
||||
/***********************************************************************/
|
||||
|
||||
#include "hardware.h"
|
||||
|
||||
// ***> NOTE: The init message must be a single line with no CRs or LFs
|
||||
#define INIT_MESSAGE "Initializing configs to WaterColorBot v2 settings"
|
||||
#define INIT_MESSAGE "Initializing configs to AxiDraw v3 settings"
|
||||
|
||||
#define JUNCTION_INTEGRATION_TIME 2.5 // cornering - usually between 0.5 and 2.0 (higher is faster)
|
||||
#define CHORDAL_TOLERANCE 0.01 // chordal accuracy for arc drawing (in mm)
|
||||
|
||||
+24
-9
@@ -250,7 +250,7 @@ template<typename ADC_t, uint16_t min_temp = 0, uint16_t max_temp = 400>
|
||||
struct PT100 {
|
||||
float pullup_resistance;
|
||||
float inline_resistance;
|
||||
bool wheatstone;
|
||||
bool differential;
|
||||
|
||||
ADC_t adc_pin {kNormal, [&]{this->adc_has_new_value();} };
|
||||
float raw_adc_voltage = 0.0;
|
||||
@@ -258,16 +258,31 @@ struct PT100 {
|
||||
|
||||
typedef PT100<ADC_t, min_temp, max_temp> type;
|
||||
|
||||
PT100(const float pullup_resistance_, const float inline_resistance_, const bool wheatstone_ = false)
|
||||
PT100(const float pullup_resistance_, const float inline_resistance_, const bool differential_ = false)
|
||||
: pullup_resistance{ pullup_resistance_ },
|
||||
inline_resistance{ inline_resistance_ },
|
||||
wheatstone{wheatstone_}
|
||||
differential{differential_}
|
||||
{
|
||||
adc_pin.setInterrupts(kPinInterruptOnChange|kInterruptPriorityLow);
|
||||
adc_pin.setVoltageRange(kSystemVoltage,
|
||||
get_voltage_of_temp(min_temp),
|
||||
get_voltage_of_temp(max_temp),
|
||||
wheatstone, // if wheatstone, then differential
|
||||
differential,
|
||||
6400.0);
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
PT100(const float pullup_resistance_, const float inline_resistance_, const bool differential_ = false, Ts&&... additional_values)
|
||||
: pullup_resistance{ pullup_resistance_ },
|
||||
inline_resistance{ inline_resistance_ },
|
||||
differential{differential_},
|
||||
adc_pin {additional_values...}
|
||||
{
|
||||
adc_pin.setInterrupts(kPinInterruptOnChange|kInterruptPriorityLow);
|
||||
adc_pin.setVoltageRange(kSystemVoltage,
|
||||
get_voltage_of_temp(min_temp),
|
||||
get_voltage_of_temp(max_temp),
|
||||
differential,
|
||||
6400.0);
|
||||
};
|
||||
|
||||
@@ -275,8 +290,8 @@ struct PT100 {
|
||||
// R = 100(1 + A*T + B*T^2); A = 3.9083*10^-3; B = -5.775*10^-7
|
||||
float r = 100 * (1 + 0.0039083*t + -0.0000005775*t*t) + inline_resistance;
|
||||
|
||||
if (wheatstone) {
|
||||
return (r - pullup_resistance)/(2.0*(pullup_resistance + r));
|
||||
if (differential) {
|
||||
return (kSystemVoltage * r)/(2.0 * pullup_resistance + r);
|
||||
}
|
||||
return r/(r+pullup_resistance)*kSystemVoltage;
|
||||
};
|
||||
@@ -293,9 +308,9 @@ struct PT100 {
|
||||
|
||||
float get_resistance() {
|
||||
float r;
|
||||
if (wheatstone) {
|
||||
if (differential) {
|
||||
float v = raw_adc_voltage / kSystemVoltage;
|
||||
r = pullup_resistance*(1-2.0*v)/(2.0*v+1.0) - inline_resistance;
|
||||
r = (v * 2.0 * pullup_resistance)/(1.0 - v) - inline_resistance;
|
||||
} else {
|
||||
float v = raw_adc_voltage;
|
||||
r = ((pullup_resistance * v) / (kSystemVoltage - v)) - inline_resistance;
|
||||
@@ -317,7 +332,7 @@ struct PT100 {
|
||||
|
||||
// Call back function from the ADC to tell it that the ADC has a new sample...
|
||||
void adc_has_new_value() {
|
||||
raw_adc_voltage = (raw_adc_voltage * 10.0 + adc_pin.getVoltage())/11.0;
|
||||
raw_adc_voltage = (raw_adc_voltage*10.0 + adc_pin.getVoltage())/11.0;
|
||||
raw_adc_value = adc_pin.getRaw();
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user