From 3d1880c006176b4c883e20021e976bf5ebc067cb Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Mon, 26 Jul 2021 12:50:13 +0200 Subject: [PATCH] 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) --- src/config/config.h | 11 --------- src/hal/CMakeLists.txt | 9 ++++++- src/hal/avr/spi.cpp | 29 +++++++++++++++++++++++ src/hal/avr/tmc2130.cpp | 7 ++++-- src/hal/spi.h | 27 +++++++-------------- src/hal/tmc2130.h | 2 +- src/modules/motion.h | 6 ++--- tests/unit/modules/stubs/stub_tmc2130.cpp | 9 +++++-- 8 files changed, 61 insertions(+), 39 deletions(-) create mode 100644 src/hal/avr/spi.cpp diff --git a/src/config/config.h b/src/config/config.h index 41ced4f..2acfa27 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -1,7 +1,6 @@ #pragma once #include #include "axis.h" -#include "hal/spi.h" /// Wrangler for assorted compile-time configuration and constants. namespace config { @@ -51,22 +50,14 @@ static constexpr uint8_t stepTimerFrequencyDivider = 8; /// 16 = 8us (25us is the max frequency interval per maxStepFrequency) static constexpr uint8_t stepTimerQuantum = 16; -//<<<<<<< HEAD /// Pulley axis configuration 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, .uSteps = 4, //x16 .vSense = false, .iRun = 20, .iHold = 20, .stealth = false, - .uSteps = 16, .stepsPerUnit = 100, }; @@ -85,7 +76,6 @@ static constexpr AxisConfig selector = { .iRun = 20, .iHold = 20, .stealth = false, - .uSteps = 16, .stepsPerUnit = 100, }; @@ -104,7 +94,6 @@ static constexpr AxisConfig idler = { .iRun = 20, .iHold = 20, .stealth = false, - .uSteps = 16, .stepsPerUnit = 100, }; diff --git a/src/hal/CMakeLists.txt b/src/hal/CMakeLists.txt index 1776def..169c0a8 100644 --- a/src/hal/CMakeLists.txt +++ b/src/hal/CMakeLists.txt @@ -1,3 +1,10 @@ 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 ) diff --git a/src/hal/avr/spi.cpp b/src/hal/avr/spi.cpp new file mode 100644 index 0000000..53b91de --- /dev/null +++ b/src/hal/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 diff --git a/src/hal/avr/tmc2130.cpp b/src/hal/avr/tmc2130.cpp index 22a140a..75e6f61 100644 --- a/src/hal/avr/tmc2130.cpp +++ b/src/hal/avr/tmc2130.cpp @@ -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]) { hal::gpio::WritePin(params.csPin, hal::gpio::Level::low); - for (uint8_t i = 0; i < sizeof(pData); i++) - pData[i] = hal::spi::TxRx(params.spi, pData[i]); + for (uint8_t i = 0; i < sizeof(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(params.spi), pData[i]); + } hal::gpio::WritePin(params.csPin, hal::gpio::Level::high); } diff --git a/src/hal/spi.h b/src/hal/spi.h index 254ccd8..9797739 100644 --- a/src/hal/spi.h +++ b/src/hal/spi.h @@ -2,6 +2,7 @@ #include #include "gpio.h" +#define SPI0 ((hal::spi::SPI_TypeDef *)&SPCR) namespace hal { /// SPI interface @@ -23,27 +24,15 @@ struct SPI_InitTypeDef { uint8_t cpol; }; -__attribute__((always_inline)) inline 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. +void Init(SPI_TypeDef *const hspi, SPI_InitTypeDef *const conf); - const uint8_t spi2x = (conf->prescaler == 7) ? 0 : (conf->prescaler & 0x01); - const uint8_t spr = ((conf->prescaler - 1) >> 1) & 0x03; +uint8_t TxRx(SPI_TypeDef *hspi, uint8_t val); - hspi->SPCRx = (0 << SPIE) | (1 << SPE) | (0 << DORD) | (1 << MSTR) | ((conf->cpol & 0x01) << CPOL) | ((conf->cpha & 0x01) << CPHA) | (spr << SPR0); - hspi->SPSRx = (spi2x << SPI2X); -} +#ifdef __AVR__ +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) diff --git a/src/hal/tmc2130.h b/src/hal/tmc2130.h index 2e845c5..b92a5a3 100644 --- a/src/hal/tmc2130.h +++ b/src/hal/tmc2130.h @@ -17,7 +17,7 @@ enum MotorMode : uint8_t { }; struct MotorParams { - hal::spi::SPI_TypeDef *spi; + const hal::spi::SPI_TypeDef *spi; uint8_t idx; ///< SHR16 index bool dirOn; ///< forward direction gpio::GPIO_pin csPin; ///< CS pin diff --git a/src/modules/motion.h b/src/modules/motion.h index 30b7c8f..0fcae91 100644 --- a/src/modules/motion.h +++ b/src/modules/motion.h @@ -42,7 +42,7 @@ static constexpr AxisParams axisParams[NUM_AXIS] = { // Pulley { .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 }, .mode = DefaultMotorMode(config::pulley), .jerk = unitToSteps(config::pulleyLimits.jerk), @@ -51,7 +51,7 @@ static constexpr AxisParams axisParams[NUM_AXIS] = { // Selector { .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 }, .mode = DefaultMotorMode(config::selector), .jerk = unitToSteps(config::selectorLimits.jerk), @@ -60,7 +60,7 @@ static constexpr AxisParams axisParams[NUM_AXIS] = { // Idler { .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 }, .mode = DefaultMotorMode(config::idler), .jerk = unitToSteps(config::idlerLimits.jerk), diff --git a/tests/unit/modules/stubs/stub_tmc2130.cpp b/tests/unit/modules/stubs/stub_tmc2130.cpp index 50fa9a0..83110cf 100644 --- a/tests/unit/modules/stubs/stub_tmc2130.cpp +++ b/tests/unit/modules/stubs/stub_tmc2130.cpp @@ -9,12 +9,17 @@ TMC2130::TMC2130(const MotorParams ¶ms, // TODO } -void TMC2130::SetMode(MotorMode mode) { +void TMC2130::SetMode(const MotorParams ¶ms, MotorMode mode) { // TODO } -void TMC2130::Init(const MotorParams & /*params*/) { +bool TMC2130::Init(const MotorParams & /*params*/) { // TODO + return true; +} + +void TMC2130::SetEnabled(const MotorParams ¶ms, bool enabled) { + this->enabled = enabled; } } // namespace tmc2130