FeatherM4CAN VS TOOL1RR

생성일 비교 결과 만료 없음
195 삭제
182
298 추가
309
/*
/*
* Pins_FeatherM4CAN.h
* TOOL1RR.h

*
* Created on: 6 Oct 2023
* Author: David
*/
*/



#ifndef SRC_CONFIG_TOOL1RR_H_
#ifndef SRC_CONFIG_PINS_FEATHERM4CAN_H_
#define SRC_CONFIG_TOOL1RR_H_
#define SRC_CONFIG_PINS_FEATHERM4CAN_H_


#include <Hardware/PinDescription.h>
#include <Hardware/PinDescription.h>



#define BOARD_TYPE_NAME "TOOL1RR"
#define BOARD_TYPE_NAME "FeatherM4CAN"
#define BOOTLOADER_NAME "SAME5x"
#define BOOTLOADER_NAME "SAME5x"


// General features
// General features
#define HAS_VREF_MONITOR 0
#define HAS_VREF_MONITOR 1
#define HAS_VOLTAGE_MONITOR 0
#define HAS_VOLTAGE_MONITOR 1
#define HAS_12V_MONITOR 0
#define HAS_12V_MONITOR 0
#define HAS_CPU_TEMP_SENSOR 1
#define HAS_CPU_TEMP_SENSOR 1
#define HAS_ADDRESS_SWITCHES 0
#define HAS_ADDRESS_SWITCHES 0
#define HAS_BUTTONS 0
#define HAS_BUTTONS 0


// Drivers configuration
// Drivers configuration
#define SUPPORT_DRIVERS 1
#define SUPPORT_DRIVERS 1
#define HAS_SMART_DRIVERS 0
#define HAS_SMART_DRIVERS 1
#define HAS_STALL_DETECT 0
#define HAS_STALL_DETECT 1
#define SINGLE_DRIVER 1
#define SINGLE_DRIVER 1
#define SUPPORT_SLOW_DRIVERS 1
#define SUPPORT_SLOW_DRIVERS 0
#define DEDICATED_STEP_TIMER 1
#define DEDICATED_STEP_TIMER 1
#define SUPPORT_INPUT_SHAPING 0
#define SUPPORT_INPUT_SHAPING 1


#define ACTIVE_HIGH_STEP 1
#define ACTIVE_HIGH_STEP 1 // 1 = active high, 0 = active low
#define ACTIVE_HIGH_DIR 1
#define ACTIVE_HIGH_DIR 1 // 1 = active high, 0 = active low
#define ACTIVE_HIGH_ENABLE 0


#define SUPPORT_TMC51xx 0
#define SUPPORT_TMC51xx 0
#define SUPPORT_TMC2660 0
#define SUPPORT_TMC2660 0
#define SUPPORT_TMC22xx 0
#define SUPPORT_TMC22xx 1
#define SUPPORT_TMC2208 0
#define SUPPORT_TMC2208 0
#define SUPPORT_TMC2209 0
#define SUPPORT_TMC2209 0
#define SUPPORT_TMC2240 0
#define SUPPORT_TMC2240 1


constexpr size_t NumDrivers = 1;
constexpr size_t NumDrivers = 1;
constexpr size_t MaxSmartDrivers = 1;


PortGroup * const StepPio = &(PORT->Group[0]);
#define TMC22xx_USES_SERCOM 1
constexpr Pin StepPins[NumDrivers] = { PortAPin(16) };
#define TMC22xx_HAS_MUX 0
constexpr Pin DirectionPins[NumDrivers] = { PortAPin(17) };
#define TMC22xx_SINGLE_DRIVER 1
constexpr Pin EnablePins[NumDrivers] = { PortAPin(18) };
#define TMC22xx_HAS_ENABLE_PINS 0
#define TMC22xx_VARIABLE_NUM_DRIVERS 0
#define TMC22xx_USE_SLAVEADDR 0


constexpr Pin GlobalTmc22xxEnablePin = PortAPin(0);


#define SUPPORT_THERMISTORS 0
constexpr uint8_t TMC22xxSercomNumber = 0;
Sercom * const SERCOM_TMC22xx = SERCOM0;

constexpr Pin TMC22xxSercomTxPin = PortAPin(8);
constexpr GpioPinFunction TMC22xxSercomTxPinPeriphMode = GpioPinFunction::C;
constexpr Pin TMC22xxSercomRxPin = PortAPin(9);
constexpr GpioPinFunction TMC22xxSercomRxPinPeriphMode = GpioPinFunction::C;
constexpr uint8_t TMC22xxSercomRxPad = 1;

// Define the baud rate used to send/receive data to/from the drivers.
// If we assume a worst case clock frequency of 8MHz then the maximum baud rate is 8MHz/16 = 500kbaud.
// We send data via a 1K series resistor. Even if we assume a 200pF load on the shared UART line, this gives a 200ns time constant, which is much less than the 2us bit time @ 500kbaud.
// To write a register we need to send 8 bytes. To read a register we send 4 bytes and receive 8 bytes after a programmable delay.
// So at 500kbaud it takes about 128us to write a register, and 192us+ to read a register.
// In testing I found that 500kbaud was not reliable on the Duet Maestro, so now using 200kbaud.
constexpr uint32_t DriversBaudRate = 200000;
constexpr uint32_t TransferTimeout = 10; // any transfer should complete within 10 ticks @ 1ms/tick

constexpr uint32_t Tmc2240CurrentRange = 0x01; // which current range we set the TMC2240 to (2A)
constexpr uint32_t Tmc2240SlopeControl = 0x01; // which slope control we set the TMC2240 to (200V/us)
constexpr float Tmc2240Rref = 15.0; // TMC2240 reference resistor in Kohms
constexpr float DriverFullScaleCurrent = 24000/Tmc2240Rref; // in mA, assuming we set the range bits in the DRV_CONF register to 0x01
constexpr float DriverCsMultiplier = 32.0/DriverFullScaleCurrent; // with RRef = 15K this works out as 1.6A so this is the maximum current we can ask for

#if 1
// New current limits (RRF 3.6 and later)
constexpr float MaximumMotorCurrent = 1600.0;
constexpr float MaximumStandstillCurrent = 1130.0;
#else
// Original current limits for normal use (RRF 3.5.x and earlier)
constexpr float MaximumMotorCurrent = 1000.0; // peak current per phase, only one phase gets this at a time
constexpr float MaximumStandstillCurrent = 800.0; // peak current in a single phase at standstill
#endif

constexpr uint32_t DefaultStandstillCurrentPercent = 75;

PortGroup * const StepPio = &(PORT->Group[1]); // the PIO that all the step pins are on
constexpr Pin StepPins[NumDrivers] = { PortBPin(23) };
constexpr Pin DirectionPins[NumDrivers] = { PortAPin(10) };
constexpr Pin DriverDiagPins[NumDrivers] = { PortAPin(21) };

#define SUPPORT_THERMISTORS 1
#define SUPPORT_SPI_SENSORS 0
#define SUPPORT_SPI_SENSORS 0
#define SUPPORT_DMA_NEOPIXEL 0
#define SUPPORT_LDC1612 1
#define SUPPORT_I2C_SENSORS 0
#define SUPPORT_AS5601 1 // support direct-connected magnetic filament monitor encoder chip
#define SUPPORT_LIS3DH 0
#define SUPPORT_TCA6408A 1 // support button and LEDs on filament monitor via TCA6408A chip
#define SUPPORT_LDC1612 0
#define SUPPORT_DMA_NEOPIXEL 0 // can't get SERCOM SPI working due to output state when not transmitting - case opened with Microchip

#ifdef DEBUG
# define SUPPORT_I2C_SENSORS 0 // in debug mode the SERCOM is used for debugging
# define SUPPORT_LIS3DH 0
#else
# define SUPPORT_I2C_SENSORS 1
# define SUPPORT_LIS3DH 1
#endif

#define SUPPORT_DHT_SENSOR 0
#define SUPPORT_DHT_SENSOR 0
#define NUM_SERIAL_PORTS 0


#define USE_MPU 0
#define USE_MPU 0
#define USE_CACHE 1
#define USE_CACHE 1


constexpr bool UseAlternateCanPins = true;
constexpr bool UseAlternateCanPins = true;
constexpr Pin CanTxPin = PortBPin(14);
constexpr Pin CanRxPin = PortBPin(15);
constexpr Pin CanStandbyPin = PortBPin(12); // PB12
constexpr Pin CanBoostEnablePin = PortBPin(13); // PB13
constexpr GpioPinFunction CanPinsMode = GpioPinFunction::H;


constexpr size_t MaxPortsPerHeater = 1;
constexpr size_t MaxPortsPerHeater = 1;


constexpr Pin LedPins[] = { PortAPin(23) };
constexpr size_t NumThermistorInputs = 3;
constexpr bool LedActiveHigh = true;
constexpr float DefaultThermistorSeriesR = 2200.0;
constexpr float DefaultThermistorR25_TOOL1RR_temp2 = 10000;
constexpr float DefaultThermistorBeta_TOOL1RR_temp2 = 3425.0;
constexpr float DefaultThermistorC_TOOL1RR_temp2 = 1.68e-7;

constexpr float VrefTopResistor = 27.0;
constexpr float MinVrefLoadR = (DefaultThermistorSeriesR / NumThermistorInputs) * 4700.0/((DefaultThermistorSeriesR / NumThermistorInputs) + 4700.0);

constexpr Pin VrefPin = PortAPin(6);
constexpr Pin VssaPin = PortBPin(9);

constexpr Pin BoardTypePin = PortAPin(3);

// Diagnostic LEDs
constexpr Pin LedPins[] = { PortAPin(30), PortAPin(31) };
constexpr bool LedActiveHigh = false;

constexpr Pin VinMonitorPin = PortAPin(2);
constexpr float VinDividerRatio = (60.4 + 4.7)/4.7;
constexpr float VinMonitorVoltageRange = VinDividerRatio * 3.3;

constexpr Pin TempSensePins[NumThermistorInputs] = { PortBPin(8), PortAPin(7), PortAPin(11) };

#if SUPPORT_I2C_SENSORS

// I2C using pins PA12,13
constexpr uint8_t I2CSercomNumber = 2;
constexpr Pin I2CSDAPin = PortAPin(12);
constexpr GpioPinFunction I2CSDAPinPeriphMode = GpioPinFunction::C;
constexpr Pin I2CSCLPin = PortAPin(13);
constexpr GpioPinFunction I2CSCLPinPeriphMode = GpioPinFunction::C;
# define I2C_HANDLER0 SERCOM2_0_Handler
# define I2C_HANDLER1 SERCOM2_1_Handler
# define I2C_HANDLER2 SERCOM2_2_Handler
# define I2C_HANDLER3 SERCOM2_3_Handler

#endif

#if SUPPORT_LIS3DH
# define ACCELEROMETER_USES_SPI (0) // accelerometer is connected via I2C
constexpr Pin Lis3dhInt1Pin = PortAPin(27);
#endif

#if SUPPORT_LDC1612
constexpr uint16_t LDC1612_I2CAddress = 0x2A; // pin 4 is tied low
constexpr unsigned int Ldc1612GClkNumber = 5;
constexpr Pin LDC1612ClockGenPin = PortBPin(11);
constexpr Pin LDC1612InterruptPin = PortAPin(25);
#endif

#if SUPPORT_AS5601
constexpr uint16_t AS5601_I2CAddress = 0x36; // I2C address of the AS5601
#endif

#if SUPPORT_TCA6408A
constexpr uint16_t TCA6408A_I2CAddress = 0x20; // I2C address of the TCA6408A (ADDR pin is tied to ground)
#endif

const auto sercom1cPad3 = SercomIo::sercom1c + SercomIo::pad3;
const auto sercom5dpad0 = SercomIo::sercom5d + SercomIo::pad0;
const auto sercom5dpad1 = SercomIo::sercom5d + SercomIo::pad1;

// Table of pin functions that we are allowed to use
constexpr PinDescription PinTable[] =
constexpr PinDescription PinTable[] =
{
{
// TC TCC ADC SERCOM in SERCOM out Exint PinNames
// TC TCC ADC SERCOM in SERCOM out Exint PinName
// Port A
// Port A
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA00 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA00 driver ENN
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA01 NC
{ TcOutput::tc2_1, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, "out1" }, // PA01 OUT0
{ TcOutput::none, TccOutput::none, AdcInput::adc0_0, SercomIo::none, SercomIo::none, 2, "pa02" }, // PA02
{ TcOutput::none, TccOutput::none, AdcInput::adc0_0, SercomIo::none, SercomIo::none, Nx, "ate.vin" }, // PA02 VIN monitor
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA03 NC
{ TcOutput::none, TccOutput::none, AdcInput::adc0_1, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA03 board type
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA04
{ TcOutput::none, TccOutput::none, AdcInput::adc0_4, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA04 spare analog in (strain gauge?)
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA05
{ TcOutput::none, TccOutput::none, AdcInput::adc0_5, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA05 spare
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA06
{ TcOutput::none, TccOutput::none, AdcInput::adc0_6, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA06 VRefMon
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA07 NC
{ TcOutput::none, TccOutput::none, AdcInput::adc0_7, SercomIo::none, SercomIo::none, 7, "temp1" }, // PA07 TEMP1
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA08 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA08 driver UART Tx
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA09 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA09 driver UART Rx
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA10 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, "ate.d0.dir" }, // PA10 driver DIR and reset jumper
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA11 NC
{ TcOutput::none, TccOutput::none, AdcInput::adc0_11, SercomIo::none, SercomIo::none, Nx, "temp2,coiltemp" }, // PA11 TEMP2
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 12, "pa12" }, // PA12
{ TcOutput::none, TccOutput::tcc1_2F, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA12 I2C SDA
{ TcOutput::tc2_0, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, "pa13" }, // PA13
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA13 I2C SCL
{ TcOutput::none, TccOutput::tcc1_2G, AdcInput::none, SercomIo::none, SercomIo::none, Nx, "pa14" }, // PA14
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA14 crystal
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA15 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA15 crystal
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA16 STEP
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 0, "io3.in" }, // PA16 IO1 in
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA17 DIR
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 1, "io1.in" }, // PA17 IO2 in
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA18 ENA
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 2, "out1.tach" }, // PA18 OUT2 tacho
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA19
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, sercom1cPad3, Nx, "led" }, // PA19 Neopixel out
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA20
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, "out2" }, // PA20 OUT2
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA21
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 5, "ate.d0.diag" }, // PA21 driver DIAG
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA22
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA22 CAN0 Tx
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA23 LED
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA23 CAN0 Rx
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA24 USB D-
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 8, "io2.in" }, // PA24 IO3 in
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA25 USB D+
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 9, nullptr }, // PA25 LDC1612 interrupt
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA26 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA26 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA27 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 11, nullptr }, // PA27 accelerometer interrupt
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA28 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA28 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA29 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA29 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA30 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA30 swclk and LED0
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA31 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA31 swdio and LED1


// Port B
// Port B
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB00 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB00 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB01 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB01 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB02 NC
{ TcOutput::none, TccOutput::tcc2_2F, AdcInput::none, SercomIo::none, sercom5dpad0, Nx, "io0.out" }, // PB02 IO0 out, UART available
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB03 NC
{ TcOutput::none, TccOutput::none, AdcInput::adc0_15, sercom5dpad1, SercomIo::none, 3, "io0.in" }, // PB03 IO0 in, UART available
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB04 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB04 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB05 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB05 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB06 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB06 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB07 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB07 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB08
{ TcOutput::none, TccOutput::none, AdcInput::adc0_2, SercomIo::none, SercomIo::none, Nx, "temp0" }, // PB08 TEMP0
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB09
{ TcOutput::none, TccOutput::none, AdcInput::adc0_3, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB09 VSSA monitor
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB10 NC
{ TcOutput::none, TccOutput::tcc0_4F, AdcInput::none, SercomIo::none, SercomIo::none, Nx, "out0" }, // PB10 OUT1
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB11 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB11 GCLK for LDC1612
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB12 CAN STANDBY
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB12 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB13 CAN BOOST
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB13 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB14 CAN_TX CAN1TX
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB14 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB15 CAN_RX CAN1RX
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB15 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB16
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB16 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB17
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB17 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB18 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB18 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB19 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB19 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB20 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB20 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB21 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB21 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB22 CRYSTAL
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 6, "out2.tach" }, // PB22 OUT2 tacho
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB23 CRYSTAL
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, "ate.d0.step" }, // PB23 driver STEP
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB24 NC

{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB25 NC
// Virtual pins
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB26 NC
#if SUPPORT_LIS3DH
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB27 NC
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, "i2c.lis3dh,i2c.lis2dw" }, // LIS3DH sensor connected via I2C
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB28 NC
#endif
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB29 NC
#if SUPPORT_LDC1612
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB30 NC
{ TcOutput::none, TccOutput::none, AdcInput::ldc1612, SercomIo::none, SercomIo::none, Nx, "i2c.ldc1612" }, // LDC1612 sensor connected via I2C
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB31 NC
#endif
#if SUPPORT_AS5601
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, "i2c.mfm" }, // AS5601+TCA6408A filament monitor connected via I2C
#endif
#if SUPPORT_TCA6408A
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, "i2c.mfm.button" }, // AS5601+TCA6408A filament monitor connected via I2C
#endif
};
};


constexpr size_t NumPins = ARRAY_SIZE(PinTable);
static constexpr size_t NumPins = ARRAY_SIZE(PinTable);
constexpr size_t NumNamedPins = ARRAY_SIZE(PinTable);
static constexpr size_t NumRealPins = 32 + 24; // 32 pins on port A (some missing), 24 on port B (many missing)
constexpr size_t NumRealPins = 32 + 32;
constexpr size_t NumVirtualPins = SUPPORT_LIS3DH + SUPPORT_LDC1612 + SUPPORT_AS5601 + SUPPORT_TCA6408A;
constexpr size_t NumVirtualPins = 0;

static_assert(NumPins == NumRealPins + NumVirtualPins);

#if SUPPORT_AS5601
constexpr Pin MfmPin = NumRealPins + SUPPORT_LIS3DH + SUPPORT_LDC1612; // pin number when the user selects magnetic filament monitor on I2C bus
#endif

#if SUPPORT_TCA6408A
constexpr Pin MfmButtonPin = NumRealPins + SUPPORT_LIS3DH + SUPPORT_LDC1612 + 1; // pin number when the user selects magnetic filament monitor button on I2C bus
#endif


// Timer/counter used to generate step pulses and other sub-millisecond timings
// Timer/counter used to generate step pulses and other sub-millisecond timings
TcCount32 * const StepTc = &(TC0->COUNT32);
TcCount32 * const StepTc = &(TC0->COUNT32);
constexpr IRQn StepTcIRQn = TC0_IRQn;
constexpr IRQn StepTcIRQn = TC0_IRQn;
constexpr unsigned int StepTcNumber = 0;
constexpr unsigned int StepTcNumber = 0;
#define STEP_TC_HANDLER TC0_Handler
#define STEP_TC_HANDLER TC0_Handler


// Available UART ports
// Available UART ports
#define NUM_SERIAL_PORTS 0
#define NUM_SERIAL_PORTS 0


// DMA channel assignments
// DMA channel assignments
constexpr DmaChannel DmacChanTmcTx = 0;
constexpr DmaChannel DmacChanTmcTx = 0;
constexpr DmaChannel DmacChanTmcRx = 1;
constexpr DmaChannel DmacChanTmcRx = 1;
constexpr DmaChannel DmacChanAdc0Rx = 2;
constexpr DmaChannel DmacChanAdc0Rx = 2;
constexpr DmaChannel DmacChanLedTx = 3;
constexpr DmaChannel DmacChanLedTx = 3;


constexpr unsigned int NumDmaChannelsUsed = 4; // must be at least the number of channels used, may be larger. Max 12 on the SAME5x.
constexpr unsigned int NumDmaChannelsUsed = 4; // must be at least the number of channels used, may be larger. Max 12 on the SAME5x.


constexpr DmaPriority DmacPrioTmcTx = 0;
constexpr DmaPriority DmacPrioTmcTx = 0;
constexpr DmaPriority DmacPrioTmcRx = 3;
constexpr DmaPriority DmacPrioTmcRx = 3;
constexpr DmaPriority DmacPrioAdcRx = 2;
constexpr DmaPriority DmacPrioAdcRx = 2;
constexpr DmaPriority DmacPrioLed = 1;
constexpr DmaPriority DmacPrioLed = 1;


// Interrupt priorities, lower means higher priority. 0-2 can't make RTOS calls.
// Interrupt priorities, lower means higher priority. 0-2 can't make RTOS calls.
const NvicPriority NvicPriorityStep = 3; // step interrupt is next highest, it can preempt most other interrupts
const NvicPriority NvicPriorityStep = 3; // step interrupt is next highest, it can preempt most other interrupts
const NvicPriority NvicPriorityUart = 3; // serial driver makes RTOS calls
const NvicPriority NvicPriorityUart = 3; // serial driver makes RTOS calls
const NvicPriority NvicPriorityI2C = 3;
const NvicPriority NvicPriorityI2C = 3;
const NvicPriority NvicPriorityPins = 3; // priority for GPIO pin interrupts
const NvicPriority NvicPriorityPins = 3; // priority for GPIO pin interrupts
const NvicPriority NvicPriorityCan = 4;
const NvicPriority NvicPriorityCan = 4;
const NvicPriority NvicPriorityDmac = 5; // priority for DMA complete interrupts
const NvicPriority NvicPriorityDmac = 5; // priority for DMA complete interrupts
const NvicPriority NvicPriorityAdc = 5;
const NvicPriority NvicPriorityAdc = 5;


#endif /* SRC_CONFIG_PINS_FEATHERM4CAN_H_ */
#endif /* SRC_CONFIG_TOOL1RR_H_ */