Ultimaker Interim commit

This commit is contained in:
Rob Giseburt
2017-03-30 18:55:31 -05:00
parent fc674c6d3a
commit 806aa81e68
14 changed files with 540 additions and 69 deletions
+1 -1
Submodule Motate updated: 508cd27ec3...3d0d332dc5
+2 -2
View File
@@ -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.
}
+12 -21
View File
@@ -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(); }
}
+10 -12
View File
@@ -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];
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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); //
+11 -10
View File
@@ -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;
+416
View File
@@ -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
+3 -3
View File
@@ -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
)}
{};
+41 -1
View File
@@ -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 = (
+8 -4
View File
@@ -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
+4 -2
View File
@@ -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
View File
@@ -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();
};
};