Make tests compile
Introduces a nasty hack to forcefully write into the constexpr SPI descriptor's registers (which is the correct way in ASM, but kind of cumbersome in C++ now)pull/76/head
parent
364f1bcb0d
commit
3d1880c006
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "axis.h"
|
#include "axis.h"
|
||||||
#include "hal/spi.h"
|
|
||||||
|
|
||||||
/// Wrangler for assorted compile-time configuration and constants.
|
/// Wrangler for assorted compile-time configuration and constants.
|
||||||
namespace config {
|
namespace config {
|
||||||
|
|
@ -51,22 +50,14 @@ static constexpr uint8_t stepTimerFrequencyDivider = 8;
|
||||||
/// 16 = 8us (25us is the max frequency interval per maxStepFrequency)
|
/// 16 = 8us (25us is the max frequency interval per maxStepFrequency)
|
||||||
static constexpr uint8_t stepTimerQuantum = 16;
|
static constexpr uint8_t stepTimerQuantum = 16;
|
||||||
|
|
||||||
//<<<<<<< HEAD
|
|
||||||
/// Pulley axis configuration
|
/// Pulley axis configuration
|
||||||
static constexpr AxisConfig pulley = {
|
static constexpr AxisConfig pulley = {
|
||||||
//=======
|
|
||||||
//static constexpr hal::spi::SPI_TypeDef *TmcSpiBus = SPI0;
|
|
||||||
|
|
||||||
///// Idler configuration
|
|
||||||
//static constexpr AxisConfig idler = {
|
|
||||||
//>>>>>>> tmc2130: Define the SPI bus for the tmc drivers
|
|
||||||
.dirOn = true,
|
.dirOn = true,
|
||||||
.uSteps = 4, //x16
|
.uSteps = 4, //x16
|
||||||
.vSense = false,
|
.vSense = false,
|
||||||
.iRun = 20,
|
.iRun = 20,
|
||||||
.iHold = 20,
|
.iHold = 20,
|
||||||
.stealth = false,
|
.stealth = false,
|
||||||
.uSteps = 16,
|
|
||||||
.stepsPerUnit = 100,
|
.stepsPerUnit = 100,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -85,7 +76,6 @@ static constexpr AxisConfig selector = {
|
||||||
.iRun = 20,
|
.iRun = 20,
|
||||||
.iHold = 20,
|
.iHold = 20,
|
||||||
.stealth = false,
|
.stealth = false,
|
||||||
.uSteps = 16,
|
|
||||||
.stepsPerUnit = 100,
|
.stepsPerUnit = 100,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -104,7 +94,6 @@ static constexpr AxisConfig idler = {
|
||||||
.iRun = 20,
|
.iRun = 20,
|
||||||
.iHold = 20,
|
.iHold = 20,
|
||||||
.stealth = false,
|
.stealth = false,
|
||||||
.uSteps = 16,
|
|
||||||
.stepsPerUnit = 100,
|
.stepsPerUnit = 100,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
target_sources(
|
target_sources(
|
||||||
firmware PRIVATE avr/cpu.cpp avr/usart.cpp avr/shr16.cpp avr/eeprom.cpp avr/tmc2130.cpp adc.cpp
|
firmware
|
||||||
|
PRIVATE avr/cpu.cpp
|
||||||
|
avr/usart.cpp
|
||||||
|
avr/shr16.cpp
|
||||||
|
avr/eeprom.cpp
|
||||||
|
avr/tmc2130.cpp
|
||||||
|
adc.cpp
|
||||||
|
avr/spi.cpp
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "../spi.h"
|
||||||
|
|
||||||
|
namespace hal {
|
||||||
|
namespace spi {
|
||||||
|
|
||||||
|
#ifdef __AVR__
|
||||||
|
void Init(SPI_TypeDef *const hspi, SPI_InitTypeDef *const conf) {
|
||||||
|
gpio::Init(conf->miso_pin, gpio::GPIO_InitTypeDef(gpio::Mode::input, gpio::Pull::none));
|
||||||
|
gpio::Init(conf->mosi_pin, gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::low));
|
||||||
|
gpio::Init(conf->sck_pin, gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::low));
|
||||||
|
gpio::Init(conf->ss_pin, gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::high)); //the AVR requires this pin to be an output for SPI master mode to work properly.
|
||||||
|
|
||||||
|
const uint8_t spi2x = (conf->prescaler == 7) ? 0 : (conf->prescaler & 0x01);
|
||||||
|
const uint8_t spr = ((conf->prescaler - 1) >> 1) & 0x03;
|
||||||
|
|
||||||
|
hspi->SPCRx = (0 << SPIE) | (1 << SPE) | (0 << DORD) | (1 << MSTR) | ((conf->cpol & 0x01) << CPOL) | ((conf->cpha & 0x01) << CPHA) | (spr << SPR0);
|
||||||
|
hspi->SPSRx = (spi2x << SPI2X);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t TxRx(SPI_TypeDef *hspi, uint8_t val) {
|
||||||
|
hspi->SPDRx = val;
|
||||||
|
while (!(hspi->SPSRx & (1 << SPIF)))
|
||||||
|
;
|
||||||
|
return hspi->SPDRx;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace spi
|
||||||
|
} // namespace hal
|
||||||
|
|
@ -104,8 +104,11 @@ void TMC2130::WriteRegister(const MotorParams ¶ms, Registers reg, uint32_t d
|
||||||
|
|
||||||
void TMC2130::_spi_tx_rx(const MotorParams ¶ms, uint8_t (&pData)[5]) {
|
void TMC2130::_spi_tx_rx(const MotorParams ¶ms, uint8_t (&pData)[5]) {
|
||||||
hal::gpio::WritePin(params.csPin, hal::gpio::Level::low);
|
hal::gpio::WritePin(params.csPin, hal::gpio::Level::low);
|
||||||
for (uint8_t i = 0; i < sizeof(pData); i++)
|
for (uint8_t i = 0; i < sizeof(pData); i++) {
|
||||||
pData[i] = hal::spi::TxRx(params.spi, pData[i]);
|
// @@TODO horrible hack to persuate the compiler, that the expression is const in terms of memory layout and meaning,
|
||||||
|
// but we need to write into those registers
|
||||||
|
pData[i] = hal::spi::TxRx(const_cast<hal::spi::SPI_TypeDef *>(params.spi), pData[i]);
|
||||||
|
}
|
||||||
hal::gpio::WritePin(params.csPin, hal::gpio::Level::high);
|
hal::gpio::WritePin(params.csPin, hal::gpio::Level::high);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
|
||||||
|
#define SPI0 ((hal::spi::SPI_TypeDef *)&SPCR)
|
||||||
namespace hal {
|
namespace hal {
|
||||||
|
|
||||||
/// SPI interface
|
/// SPI interface
|
||||||
|
|
@ -23,27 +24,15 @@ struct SPI_InitTypeDef {
|
||||||
uint8_t cpol;
|
uint8_t cpol;
|
||||||
};
|
};
|
||||||
|
|
||||||
__attribute__((always_inline)) inline void Init(SPI_TypeDef *const hspi, SPI_InitTypeDef *const conf) {
|
void Init(SPI_TypeDef *const hspi, SPI_InitTypeDef *const conf);
|
||||||
using namespace hal;
|
|
||||||
gpio::Init(conf->miso_pin, gpio::GPIO_InitTypeDef(gpio::Mode::input, gpio::Pull::none));
|
|
||||||
gpio::Init(conf->mosi_pin, gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::low));
|
|
||||||
gpio::Init(conf->sck_pin, gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::low));
|
|
||||||
gpio::Init(conf->ss_pin, gpio::GPIO_InitTypeDef(gpio::Mode::output, gpio::Level::high)); //the AVR requires this pin to be an output for SPI master mode to work properly.
|
|
||||||
|
|
||||||
const uint8_t spi2x = (conf->prescaler == 7) ? 0 : (conf->prescaler & 0x01);
|
uint8_t TxRx(SPI_TypeDef *hspi, uint8_t val);
|
||||||
const uint8_t spr = ((conf->prescaler - 1) >> 1) & 0x03;
|
|
||||||
|
|
||||||
hspi->SPCRx = (0 << SPIE) | (1 << SPE) | (0 << DORD) | (1 << MSTR) | ((conf->cpol & 0x01) << CPOL) | ((conf->cpha & 0x01) << CPHA) | (spr << SPR0);
|
#ifdef __AVR__
|
||||||
hspi->SPSRx = (spi2x << SPI2X);
|
constexpr SPI_TypeDef *TmcSpiBus = SPI0;
|
||||||
}
|
#else
|
||||||
|
constexpr SPI_TypeDef *TmcSpiBus = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
__attribute__((always_inline)) inline uint8_t TxRx(SPI_TypeDef *const hspi, uint8_t val) {
|
|
||||||
hspi->SPDRx = val;
|
|
||||||
while (!(hspi->SPSRx & (1 << SPIF)))
|
|
||||||
;
|
|
||||||
return hspi->SPDRx;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#define SPI0 ((hal::spi::SPI_TypeDef *)&SPCR)
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ enum MotorMode : uint8_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MotorParams {
|
struct MotorParams {
|
||||||
hal::spi::SPI_TypeDef *spi;
|
const hal::spi::SPI_TypeDef *spi;
|
||||||
uint8_t idx; ///< SHR16 index
|
uint8_t idx; ///< SHR16 index
|
||||||
bool dirOn; ///< forward direction
|
bool dirOn; ///< forward direction
|
||||||
gpio::GPIO_pin csPin; ///< CS pin
|
gpio::GPIO_pin csPin; ///< CS pin
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ static constexpr AxisParams axisParams[NUM_AXIS] = {
|
||||||
// Pulley
|
// Pulley
|
||||||
{
|
{
|
||||||
.name = 'P',
|
.name = 'P',
|
||||||
.params = { .spi = config::TmcSpiBus, .idx = Pulley, .dirOn = config::pulley.dirOn, .csPin = PULLEY_CS_PIN, .stepPin = PULLEY_STEP_PIN, .sgPin = PULLEY_SG_PIN, .uSteps = config::pulley.uSteps },
|
.params = { .spi = hal::spi::TmcSpiBus, .idx = Pulley, .dirOn = config::pulley.dirOn, .csPin = PULLEY_CS_PIN, .stepPin = PULLEY_STEP_PIN, .sgPin = PULLEY_SG_PIN, .uSteps = config::pulley.uSteps },
|
||||||
.currents = { .vSense = config::pulley.vSense, .iRun = config::pulley.iRun, .iHold = config::pulley.iHold },
|
.currents = { .vSense = config::pulley.vSense, .iRun = config::pulley.iRun, .iHold = config::pulley.iHold },
|
||||||
.mode = DefaultMotorMode(config::pulley),
|
.mode = DefaultMotorMode(config::pulley),
|
||||||
.jerk = unitToSteps<P_speed_t>(config::pulleyLimits.jerk),
|
.jerk = unitToSteps<P_speed_t>(config::pulleyLimits.jerk),
|
||||||
|
|
@ -51,7 +51,7 @@ static constexpr AxisParams axisParams[NUM_AXIS] = {
|
||||||
// Selector
|
// Selector
|
||||||
{
|
{
|
||||||
.name = 'S',
|
.name = 'S',
|
||||||
.params = { .spi = config::TmcSpiBus, .idx = Selector, .dirOn = config::selector.dirOn, .csPin = SELECTOR_CS_PIN, .stepPin = SELECTOR_STEP_PIN, .sgPin = SELECTOR_SG_PIN, .uSteps = config::selector.uSteps },
|
.params = { .spi = hal::spi::TmcSpiBus, .idx = Selector, .dirOn = config::selector.dirOn, .csPin = SELECTOR_CS_PIN, .stepPin = SELECTOR_STEP_PIN, .sgPin = SELECTOR_SG_PIN, .uSteps = config::selector.uSteps },
|
||||||
.currents = { .vSense = config::selector.vSense, .iRun = config::selector.iRun, .iHold = config::selector.iHold },
|
.currents = { .vSense = config::selector.vSense, .iRun = config::selector.iRun, .iHold = config::selector.iHold },
|
||||||
.mode = DefaultMotorMode(config::selector),
|
.mode = DefaultMotorMode(config::selector),
|
||||||
.jerk = unitToSteps<S_speed_t>(config::selectorLimits.jerk),
|
.jerk = unitToSteps<S_speed_t>(config::selectorLimits.jerk),
|
||||||
|
|
@ -60,7 +60,7 @@ static constexpr AxisParams axisParams[NUM_AXIS] = {
|
||||||
// Idler
|
// Idler
|
||||||
{
|
{
|
||||||
.name = 'I',
|
.name = 'I',
|
||||||
.params = { .spi = config::TmcSpiBus, .idx = Idler, .dirOn = config::idler.dirOn, .csPin = IDLER_CS_PIN, .stepPin = IDLER_STEP_PIN, .sgPin = IDLER_SG_PIN, .uSteps = config::idler.uSteps },
|
.params = { .spi = hal::spi::TmcSpiBus, .idx = Idler, .dirOn = config::idler.dirOn, .csPin = IDLER_CS_PIN, .stepPin = IDLER_STEP_PIN, .sgPin = IDLER_SG_PIN, .uSteps = config::idler.uSteps },
|
||||||
.currents = { .vSense = config::idler.vSense, .iRun = config::idler.iRun, .iHold = config::idler.iHold },
|
.currents = { .vSense = config::idler.vSense, .iRun = config::idler.iRun, .iHold = config::idler.iHold },
|
||||||
.mode = DefaultMotorMode(config::idler),
|
.mode = DefaultMotorMode(config::idler),
|
||||||
.jerk = unitToSteps<I_speed_t>(config::idlerLimits.jerk),
|
.jerk = unitToSteps<I_speed_t>(config::idlerLimits.jerk),
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,17 @@ TMC2130::TMC2130(const MotorParams ¶ms,
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMC2130::SetMode(MotorMode mode) {
|
void TMC2130::SetMode(const MotorParams ¶ms, MotorMode mode) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMC2130::Init(const MotorParams & /*params*/) {
|
bool TMC2130::Init(const MotorParams & /*params*/) {
|
||||||
// TODO
|
// TODO
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TMC2130::SetEnabled(const MotorParams ¶ms, bool enabled) {
|
||||||
|
this->enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tmc2130
|
} // namespace tmc2130
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue