@dc42
Just to put a bow on this (Merry Xmas ). I got it all working. It took another board rev as I had a couple hw hiccups. This included to swapping the MAX3051 to the TJA1441A CAN xcvr per David's #2 note. Any rate, brand new mcu flashed the bootloader first go. I had to first set the fuses as I listed above. The default fuses had several differences, but I didn't note them.
Also, all gpio, motor drivers and accelerometer are working as intended. interested. The '1HCL' is config'd as;
x3 step/dir drives
x2 med current outputs
x4 inputs, 24v tol
x1 lis3dH. I have the W on hand but just wanted to get the original circuit working first
I attached the final config with all the extraneous comments deleted in case anyone is interested.
/*
* EXP1HCLv1_0.h
*
* Created on: 3 Dec 2021
* Author: David
*/
#ifndef SRC_CONFIG_EXP1HCLV1_0_H_
#define SRC_CONFIG_EXP1HCLV1_0_H_
#include <Hardware/PinDescription.h>
#define BOARD_TYPE_NAME "EXP1HCL"
#define BOOTLOADER_NAME "SAME5x"
// General features
#define HAS_VREF_MONITOR 0
#define HAS_VOLTAGE_MONITOR 0
#define HAS_12V_MONITOR 0
#define HAS_CPU_TEMP_SENSOR 1
#define HAS_ADDRESS_SWITCHES 0
#define HAS_BUTTONS 1
// Drivers configuration
#define SUPPORT_DRIVERS 1
#define HAS_SMART_DRIVERS 0
#define HAS_STALL_DETECT 0
#define SINGLE_DRIVER 0
#define SUPPORT_SLOW_DRIVERS 0
#define SUPPORT_DELTA_MOVEMENT 0
#define DEDICATED_STEP_TIMER 1
#define ACTIVE_HIGH_STEP 1 // 1 = active high, 0 = active low
#define ACTIVE_HIGH_DIR 1 // 1 = active high, 0 = active low
#define ACTIVE_HIGH_ENABLE 1
#define SUPPORT_TMC51xx 0
#define SUPPORT_TMC2160 0
#define SUPPORT_TMC2660 0
#define SUPPORT_TMC22xx 0
#define SUPPORT_CLOSED_LOOP 0
#define SUPPORT_BRAKE_PWM 0
constexpr size_t NumDrivers = 3;
constexpr size_t MaxSmartDrivers = 0;
PortGroup * const StepPio = &(PORT->Group[1]); // the PIO that all the step pins are on (port B)
constexpr Pin StepPins[NumDrivers] = { PortBPin(8), PortBPin(22), PortBPin(23) };
constexpr Pin DirectionPins[NumDrivers] = { PortBPin(9), PortAPin(24), PortAPin(27) };
constexpr Pin EnablePins[NumDrivers] = { PortBPin(2), PortAPin(20), PortAPin(25) };
#define SUPPORT_THERMISTORS 0
#define SUPPORT_SPI_SENSORS 1
#define SUPPORT_DMA_NEOPIXEL 0
#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 0
# define SUPPORT_LIS3DH 1
#endif
#define SUPPORT_DHT_SENSOR 0
#define NUM_SERIAL_PORTS 0
#define USE_MPU 0
#define USE_CACHE 1
constexpr bool UseAlternateCanPins = true;
constexpr size_t MaxPortsPerHeater = 0;
constexpr size_t NumThermistorInputs = 0;
constexpr Pin BoardTypePin = PortAPin(3);
// Diagnostic LEDs
constexpr Pin LedPins[] = { PortAPin(31), PortAPin(30) };
constexpr bool LedActiveHigh = false;
constexpr Pin VinMonitorPin = PortAPin(2);
//constexpr Pin V12MonitorPin = PortAPin(6);
//constexpr float VinDividerRatio = (100.0 + 5.1)/5.1;
//constexpr float V12DividerRatio = (60.4 + 4.7)/4.7;
//constexpr float VinMonitorVoltageRange = VinDividerRatio * 3.3;
//constexpr float V12MonitorVoltageRange = V12DividerRatio * 3.3;
constexpr Pin ButtonPins[] = { PortAPin(0) }; //Used for CAN ID reset
#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
# if SUPPORT_I2C_SENSORS
# define ACCELEROMETER_USES_SPI (0) // accelerometer is connected via I2C
constexpr Pin Lis3dhInt1Pin = PortAPin(20); // same as io1.in
# else
# define ACCELEROMETER_USES_SPI (1) // accelerometer is connected via SPI
constexpr Pin Lis3dhCsPin = PortAPin(18); // same as encoder CS pin
constexpr Pin Lis3dhInt1Pin = PortAPin(12); // same as io1.in
# endif
#endif
// Shared SPI (used for interface to encoders, not for temperature sensors)
constexpr uint8_t SspiSercomNumber = 1;
constexpr uint32_t SspiDataInPad = 3;
constexpr Pin SSPIMosiPin = PortAPin(16);
constexpr GpioPinFunction SSPIMosiPinPeriphMode = GpioPinFunction::C;
constexpr Pin SSPISclkPin = PortAPin(17);
constexpr GpioPinFunction SSPISclkPinPeriphMode = GpioPinFunction::C;
constexpr Pin SSPIMisoPin = PortAPin(19);
constexpr GpioPinFunction SSPIMisoPinPeriphMode = GpioPinFunction::C;
// Clock generator pin for TMC2160
constexpr uint8_t ClockGenGclkNumber = 5;
constexpr Pin ClockGenPin = PortBPin(11);
constexpr GpioPinFunction ClockGenPinPeriphMode = GpioPinFunction::M;
// Table of pin functions that we are allowed to use
constexpr PinDescription PinTable[] =
{
// TC TCC ADC SERCOM in SERCOM out Exint PinName
// Port A
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 0, nullptr }, // PA00 ButtonPins[0] PortAPin(0) CANRST
{ TcOutput::tc2_1, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA01
{ TcOutput::none, TccOutput::none, AdcInput::adc0_0, SercomIo::none, SercomIo::none, Nx, "ate.vin" }, // PA02 VinMonitorPin PortAPin(2)
{ TcOutput::none, TccOutput::none, AdcInput::adc0_1, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA03 BoardTypePin PortAPin(3)
{ TcOutput::none, TccOutput::none, AdcInput::adc0_4, SercomIo::none, SercomIo::none, Nx, "out1" }, // PA04
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, "out0" }, // PA05
{ TcOutput::none, TccOutput::none, AdcInput::adc0_6, SercomIo::none, SercomIo::none, 6, "io0.in" }, // PA06
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA07
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA08//nullptr
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 9, "io1.in" }, // PA09
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 10, "io2.in" }, // PA10
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 11, "io3.in" }, // PA11
{ TcOutput::none, TccOutput::tcc1_2F, AdcInput::none, SercomIo::none, SercomIo::none, 12, nullptr }, // PA12 Lis3dhInt1Pin = PortAPin(12);
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA13 No IO!!
{ 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 crystal
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA16 SSPIMosiPin = PortAPin(16);
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA17 SSPISclkPin = PortAPin(17);
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, 2, "spi.cs0" }, // PA18 Lis3dhCsPin = PortAPin(18);
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA19 SSPIMisoPin = PortAPin(19);
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA20
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA21
{ 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 CAN0 Rx
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA24
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA25
{ 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
{ 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 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA30 LedPins[1] PortAPin(30)
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PA31 LedPins[0] PortAPin(31)
// Port B
{ 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 not on chip
{ TcOutput::none, TccOutput::tcc2_2F, AdcInput::none, SercomIo::none, SercomIo::sercom5d, Nx, nullptr }, // PB02 EnablePins[2] PortBPin(2)
{ TcOutput::none, TccOutput::none, AdcInput::adc0_15, SercomIo::sercom5d, SercomIo::none, Nx, nullptr }, // PB03
{ 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 not on chip
{ 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 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::adc0_2, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB08 StepPins[2] PortBPin(8)
{ TcOutput::none, TccOutput::none, AdcInput::adc0_3, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB09 DirectionPins[2] PortBPin(9)
{ TcOutput::none, TccOutput::tcc0_4F, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB10
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB11 ClockGenPin PortBPin(11);
{ 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 not on chip
{ 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 not on chip
{ 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 not on chip
{ 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 not on chip
{ 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 not on chip
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB22 StepPins[1] PortBPin(22)
{ TcOutput::none, TccOutput::none, AdcInput::none, SercomIo::none, SercomIo::none, Nx, nullptr }, // PB23 StepPins[0] PortBPin(23)
};
static constexpr size_t NumPins = ARRAY_SIZE(PinTable);
static constexpr size_t NumRealPins = 32 + 24; // 32 pins on port A (some missing), 24 on port B
static_assert(NumPins == NumRealPins); // no virtual pins in this table
// Timer/counter used to generate step pulses and other sub-millisecond timings
TcCount32 * const StepTc = &(TC0->COUNT32);
constexpr IRQn StepTcIRQn = TC0_IRQn;
constexpr unsigned int StepTcNumber = 0;
#define STEP_TC_HANDLER TC0_Handler
// Available UART ports
#define NUM_SERIAL_PORTS 0
// DMA channel assignments
constexpr DmaChannel DmacChanTmcTx = 0;
constexpr DmaChannel DmacChanTmcRx = 1;
constexpr DmaChannel DmacChanAdc0Rx = 2;
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 DmaPriority DmacPrioTmcTx = 0;
constexpr DmaPriority DmacPrioTmcRx = 3;
constexpr DmaPriority DmacPrioAdcRx = 2;
constexpr DmaPriority DmacPrioLed = 1;
// 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 NvicPriorityUart = 3; // serial driver makes RTOS calls
const NvicPriority NvicPriorityI2C = 3;
const NvicPriority NvicPriorityPins = 3; // priority for GPIO pin interrupts
const NvicPriority NvicPriorityCan = 4;
const NvicPriority NvicPriorityDmac = 5; // priority for DMA complete interrupts
const NvicPriority NvicPriorityAdc = 5;
#endif /* SRC_CONFIG_EXP1HCLV1_0_H_ */