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
D.R.racer 2021-07-26 12:50:13 +02:00 committed by DRracer
parent 364f1bcb0d
commit 3d1880c006
8 changed files with 61 additions and 39 deletions

View File

@ -1,7 +1,6 @@
#pragma once
#include <stdint.h>
#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,
};

View File

@ -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
)

29
src/hal/avr/spi.cpp Normal file
View File

@ -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

View File

@ -104,8 +104,11 @@ void TMC2130::WriteRegister(const MotorParams &params, Registers reg, uint32_t d
void TMC2130::_spi_tx_rx(const MotorParams &params, 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<hal::spi::SPI_TypeDef *>(params.spi), pData[i]);
}
hal::gpio::WritePin(params.csPin, hal::gpio::Level::high);
}

View File

@ -2,6 +2,7 @@
#include <inttypes.h>
#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)

View File

@ -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

View File

@ -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<P_speed_t>(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<S_speed_t>(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<I_speed_t>(config::idlerLimits.jerk),

View File

@ -9,12 +9,17 @@ TMC2130::TMC2130(const MotorParams &params,
// TODO
}
void TMC2130::SetMode(MotorMode mode) {
void TMC2130::SetMode(const MotorParams &params, MotorMode mode) {
// TODO
}
void TMC2130::Init(const MotorParams & /*params*/) {
bool TMC2130::Init(const MotorParams & /*params*/) {
// TODO
return true;
}
void TMC2130::SetEnabled(const MotorParams &params, bool enabled) {
this->enabled = enabled;
}
} // namespace tmc2130