diff --git a/chip/chip.h b/chip/chip.h index 347df94..e7d2b2b 100644 --- a/chip/chip.h +++ b/chip/chip.h @@ -121,7 +121,8 @@ extern "C" { #endif typedef enum { - PA0 = 0x10, + PinNull = 0, + PA0 = 0x10, PA1, PA2, PA3, diff --git a/components/tmc/ic/TMC5160/TMC5160.c b/components/tmc/ic/TMC5160/TMC5160.c deleted file mode 100644 index 5e1102d..0000000 --- a/components/tmc/ic/TMC5160/TMC5160.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * TMC5160.c - * - * Created on: 03.07.2017 - * Author: LK - */ -#if 0 -#include "TMC5160.h" - -// => SPI wrapper -// Send [length] bytes stored in the [data] array over SPI and overwrite [data] -// with the reply. The first byte sent/received is data[0]. -extern void tmc5160_readWriteArray(TMC5160TypeDef *tmc5160, uint8_t *data, size_t length); -// <= SPI wrapper -static void writeConfiguration(TMC5160TypeDef *tmc5160); - -// Writes (x1 << 24) | (x2 << 16) | (x3 << 8) | x4 to the given address -void tmc5160_writeDatagram(TMC5160TypeDef *tmc5160, uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) -{ - uint8_t data[5] = { address | TMC5160_WRITE_BIT, x1, x2, x3, x4 }; - tmc5160_readWriteArray(tmc5160, &data[0], 5); - - int32_t value = ((uint32_t)x1 << 24) | ((uint32_t)x2 << 16) | (x3 << 8) | x4; - - // Write to the shadow register and mark the register dirty - address = TMC_ADDRESS(address); - tmc5160->config->shadowRegister[address] = value; - tmc5160->registerAccess[address] |= TMC_ACCESS_DIRTY; -} - -// Write an integer to the given address -void tmc5160_writeInt(TMC5160TypeDef *tmc5160, uint8_t address, int32_t value) -{ - tmc5160_writeDatagram(tmc5160, address, BYTE(value, 3), BYTE(value, 2), BYTE(value, 1), BYTE(value, 0)); -} - -// Read an integer from the given address -int32_t tmc5160_readInt(TMC5160TypeDef *tmc5160, uint8_t address) -{ - address = TMC_ADDRESS(address); - - // register not readable -> shadow register copy - if(!TMC_IS_READABLE(tmc5160->registerAccess[address])) - return tmc5160->config->shadowRegister[address]; - - uint8_t data[5] = { 0, 0, 0, 0, 0 }; - - data[0] = address; - tmc5160_readWriteArray(tmc5160, &data[0], 5); - - data[0] = address; - tmc5160_readWriteArray(tmc5160, &data[0], 5); - - return ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | (data[3] << 8) | data[4]; -} - -// Initialize a TMC5160 IC. -// This function requires: -// - tmc5160: The pointer to a TMC5160TypeDef struct, which represents one IC -// - channel: The channel index, which will be sent back in the SPI callback -// - config: A ConfigurationTypeDef struct, which will be used by the IC -// - registerResetState: An int32_t array with 128 elements. This holds the values to be used for a reset. -void tmc5160_init(TMC5160TypeDef *tmc5160, uint8_t channel, ConfigurationTypeDef *config, const int32_t *registerResetState) -{ - tmc5160->velocity = 0; - tmc5160->oldTick = 0; - tmc5160->oldX = 0; - - tmc5160->config = config; - tmc5160->config->callback = NULL; - tmc5160->config->channel = channel; - tmc5160->config->configIndex = 0; - tmc5160->config->state = CONFIG_READY; - - size_t i; - for(i = 0; i < TMC5160_REGISTER_COUNT; i++) - { - tmc5160->registerAccess[i] = tmc5160_defaultRegisterAccess[i]; - tmc5160->registerResetState[i] = registerResetState[i]; - } -} - -// Fill the shadow registers of hardware preset non-readable registers -// Only needed if you want to 'read' those registers e.g to display the value -// in the TMCL IDE register browser -void tmc5160_fillShadowRegisters(TMC5160TypeDef *tmc5160) -{ - // Check if we have constants defined - if(ARRAY_SIZE(tmc5160_RegisterConstants) == 0) - return; - - size_t i, j; - for(i = 0, j = 0; i < TMC5160_REGISTER_COUNT; i++) - { - // We only need to worry about hardware preset, write-only registers - // that have not yet been written (no dirty bit) here. - if(tmc5160->registerAccess[i] != TMC_ACCESS_W_PRESET) - continue; - - // Search the constant list for the current address. With the constant - // list being sorted in ascended order, we can walk through the list - // until the entry with an address equal or greater than i - while(j < ARRAY_SIZE(tmc5160_RegisterConstants) && (tmc5160_RegisterConstants[j].address < i)) - j++; - - // Abort when we reach the end of the constant list - if (j == ARRAY_SIZE(tmc5160_RegisterConstants)) - break; - - // If we have an entry for our current address, write the constant - if(tmc5160_RegisterConstants[j].address == i) - { - tmc5160->config->shadowRegister[i] = tmc5160_RegisterConstants[j].value; - } - } -} - -// Reset the TMC5160. -uint8_t tmc5160_reset(TMC5160TypeDef *tmc5160) -{ - if(tmc5160->config->state != CONFIG_READY) - return false; - - // Reset the dirty bits and wipe the shadow registers - size_t i; - for(i = 0; i < TMC5160_REGISTER_COUNT; i++) - { - tmc5160->registerAccess[i] &= ~TMC_ACCESS_DIRTY; - tmc5160->config->shadowRegister[i] = 0; - } - - tmc5160->config->state = CONFIG_RESET; - tmc5160->config->configIndex = 0; - - if(tmc5160->config->state != CONFIG_READY){ - writeConfiguration(tmc5160); - } - return true; -} - -// Restore the TMC5160 to the state stored in the shadow registers. -// This can be used to recover the IC configuration after a VM power loss. -uint8_t tmc5160_restore(TMC5160TypeDef *tmc5160) -{ - if(tmc5160->config->state != CONFIG_READY) - return false; - - tmc5160->config->state = CONFIG_RESTORE; - tmc5160->config->configIndex = 0; - - if(tmc5160->config->state != CONFIG_READY){ - writeConfiguration(tmc5160); - } - return true; -} - -// Change the values the IC will be configured with when performing a reset. -void tmc5160_setRegisterResetState(TMC5160TypeDef *tmc5160, const int32_t *resetState) -{ - size_t i; - for(i = 0; i < TMC5160_REGISTER_COUNT; i++) - { - tmc5160->registerResetState[i] = resetState[i]; - } -} - -// Register a function to be called after completion of the configuration mechanism -void tmc5160_setCallback(TMC5160TypeDef *tmc5160, tmc5160_callback callback) -{ - tmc5160->config->callback = (tmc_callback_config) callback; -} - -// Helper function: Configure the next register. -static void writeConfiguration(TMC5160TypeDef *tmc5160) -{ - uint8_t *ptr = &tmc5160->config->configIndex; - const int32_t *settings; - - if(tmc5160->config->state == CONFIG_RESTORE) - { - settings = tmc5160->config->shadowRegister; - // Find the next restorable register - while((*ptr < TMC5160_REGISTER_COUNT) && !TMC_IS_RESTORABLE(tmc5160->registerAccess[*ptr])) - { - (*ptr)++; - } - } - else - { - settings = tmc5160->registerResetState; - // Find the next resettable register - while((*ptr < TMC5160_REGISTER_COUNT) && !TMC_IS_RESETTABLE(tmc5160->registerAccess[*ptr])) - { - (*ptr)++; - } - } - - if(*ptr < TMC5160_REGISTER_COUNT) - { - tmc5160_writeInt(tmc5160, *ptr, settings[*ptr]); - (*ptr)++; - } - else // Finished configuration - { - if(tmc5160->config->callback) - { - ((tmc5160_callback)tmc5160->config->callback)(tmc5160, tmc5160->config->state); - } - - tmc5160->config->state = CONFIG_READY; - } -} - -// Call this periodically -void tmc5160_periodicJob(TMC5160TypeDef *tmc5160, uint32_t tick) -{ -#if 0 - if(tmc5160->config->state != CONFIG_READY) - { - writeConfiguration(tmc5160); - return; - } -#endif - - int32_t XActual; - uint32_t tickDiff; - - // Calculate velocity v = dx/dt - if((tickDiff = tick - tmc5160->oldTick) >= 5) - { - XActual = tmc5160_readInt(tmc5160, TMC5160_XACTUAL); - // ToDo CHECK 2: API Compatibility - write alternative algorithm w/o floating point? (LH) - tmc5160->velocity = (uint32_t) ((float32_t) ((XActual - tmc5160->oldX) / (float32_t) tickDiff) * (float32_t) 1048.576); - - tmc5160->oldX = XActual; - tmc5160->oldTick = tick; - } -} - -// Rotate with a given velocity (to the right) -void tmc5160_rotate(TMC5160TypeDef *tmc5160, int32_t velocity) -{ - // Set absolute velocity - tmc5160_writeInt(tmc5160, TMC5160_VMAX, abs(velocity)); - // Set direction - tmc5160_writeInt(tmc5160, TMC5160_RAMPMODE, (velocity >= 0) ? TMC5160_MODE_VELPOS : TMC5160_MODE_VELNEG); -} - -// Rotate to the right -void tmc5160_right(TMC5160TypeDef *tmc5160, uint32_t velocity) -{ - tmc5160_rotate(tmc5160, velocity); -} - -// Rotate to the left -void tmc5160_left(TMC5160TypeDef *tmc5160, uint32_t velocity) -{ - tmc5160_rotate(tmc5160, -velocity); -} - -// Stop moving -void tmc5160_stop(TMC5160TypeDef *tmc5160) -{ - tmc5160_rotate(tmc5160, 0); -} - -// Move to a specified position with a given velocity -void tmc5160_moveTo(TMC5160TypeDef *tmc5160, int32_t position, uint32_t velocityMax) -{ - tmc5160_writeInt(tmc5160, TMC5160_RAMPMODE, TMC5160_MODE_POSITION); - - // VMAX also holds the target velocity in velocity mode. - // Re-write the position mode maximum velocity here. - tmc5160_writeInt(tmc5160, TMC5160_VMAX, velocityMax); - - tmc5160_writeInt(tmc5160, TMC5160_XTARGET, position); -} - -// Move by a given amount with a given velocity -// This function will write the absolute target position to *ticks -void tmc5160_moveBy(TMC5160TypeDef *tmc5160, int32_t *ticks, uint32_t velocityMax) -{ - // determine actual position and add numbers of ticks to move - *ticks += tmc5160_readInt(tmc5160, TMC5160_XACTUAL); - - tmc5160_moveTo(tmc5160, *ticks, velocityMax); -} - -uint8_t tmc5160_consistencyCheck(TMC5160TypeDef *tmc5160) -{ - // Config has not yet been written -> it cant be consistent - if(tmc5160->config->state != CONFIG_READY) - return 0; - - // Check constant shadow registers consistent with actual registers - for(size_t i = 0; i < TMC5160_REGISTER_COUNT; i++) - if(tmc5160->config->shadowRegister[i] != tmc5160_readInt(tmc5160, i)) - return 1; - - // No inconsistency detected - return 0; -} -#endif \ No newline at end of file diff --git a/components/tmc/ic/ztmc5130.cpp b/components/tmc/ic/ztmc5130.cpp index 0224cd2..885932d 100644 --- a/components/tmc/ic/ztmc5130.cpp +++ b/components/tmc/ic/ztmc5130.cpp @@ -12,18 +12,30 @@ using namespace iflytop; #define PRV_FIELD_WRITE(address, mask, shift, value) (writeInt(address, FIELD_SET(readInt(address), mask, shift, value))) #define PRV_FIELD_READ(address, mask, shift) FIELD_GET(readInt(address), mask, shift) +#define SET_PIN(pin, val) \ + if (pin) { \ + pin->setState(val); \ + } TMC5130::TMC5130(/* args */) {} -void TMC5130::createDeafultTMC5130Config(TMC5130Config_t *config, TMC5130Port *m_port) { - config->m_port = m_port; - config->autoReadEventRegisterInterval = 10; - config->autoReadEventRegister = true; -} -void TMC5130::initialize(uint8_t channel, TMC5130Config_t *config) { - m_channel = channel; - m_config = config; - m_port = config->m_port; +void TMC5130::initialize(cfg_t *cfg) { + m_cfg = *cfg; + + // m_channel = channel; + // m_config = config; + // m_port = config->m_port; m_registerAccessTable = &tmc5130_defaultRegisterAccess[0]; m_defaultRegisterResetState = &tmc5130_defaultRegisterResetState[0]; + if (cfg->csn_pin != PinNull) { + m_csnpin = new ZGPIO(); + m_csnpin->initAsOutput(cfg->csn_pin, ZGPIO::kMode_nopull, false, true); + } + if (cfg->enn_pin != PinNull) { + m_ennpin = new ZGPIO(); + m_ennpin->initAsOutput(cfg->enn_pin, ZGPIO::kMode_nopull, false, true); + } + + ZGPIO *m_csnpin; + ZGPIO *m_ennpin; enableIC(false); // tmc5130_init(&m_TMC5130, channel, &m_tmc_api_config, &tmc5130_defaultRegisterResetState[0]); @@ -55,12 +67,18 @@ void TMC5130::initialize(uint8_t channel, TMC5130Config_t *config) { enableIC(true); } -void TMC5130::enableIC(bool enable) { m_port->TMC5130Port_setENNPinState(m_channel, !enable); } +void TMC5130::enableIC(bool enable) { + // m_port->TMC5130Port_setENNPinState(m_channel, !enable); + SET_PIN(m_ennpin, !enable); +} uint8_t TMC5130::reset() { stop(); - m_port->TMC5130Port_setResetNPinState(m_channel, false); - m_port->TMC5130Port_sleepus(1000); - m_port->TMC5130Port_setResetNPinState(m_channel, true); + // m_port->TMC5130Port_setResetNPinState(m_channel, false); + SET_PIN(m_csnpin, false); + // m_port->TMC5130Port_sleepus(1000); + chip_delay_us(1000); + // m_port->TMC5130Port_setResetNPinState(m_channel, true); + SET_PIN(m_csnpin, true); for (uint32_t add = 0; add < TMC5130_REGISTER_COUNT; add++) { if (!TMC_IS_RESETTABLE(m_registerAccessTable[add])) { @@ -120,7 +138,6 @@ bool TMC5130::isReachTarget() { } return false; } -void TMC5130::periodicJob(uint32_t now) {} /******************************************************************************* * basic * *******************************************************************************/ @@ -130,7 +147,8 @@ void TMC5130::writeSubRegister(uint8_t address, uint32_t mask, uint32_t shift, u } void TMC5130::readWriteArray(uint8_t *data, size_t length) { CriticalContext cc; - m_port->TMC5130Port_readWriteArray(m_channel, data, length); + // m_port->TMC5130Port_readWriteArray(m_channel, data, length); + HAL_SPI_TransmitReceive(m_hspi, data, data, length, 100); } void TMC5130::writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) { CriticalContext cc; diff --git a/components/tmc/ic/ztmc5130.hpp b/components/tmc/ic/ztmc5130.hpp index 5942ee6..592821b 100644 --- a/components/tmc/ic/ztmc5130.hpp +++ b/components/tmc/ic/ztmc5130.hpp @@ -57,50 +57,28 @@ class Tmc5130RampStat { bool isSetted(ramp_stat_bit_t bit) { return (m_state & bit) != 0; } }; -class TMC5130Port { - public: - /** - * @brief 使能引脚,低有效。 - * - * @param state - */ - virtual void TMC5130Port_setENNPinState(uint16_t channel, bool state) = 0; - /** - * @brief 复位引脚,低有效,TMC5130没有复位引脚,但可以通过切断电源等方式实现,如果硬件电路上没有,该方法不需要实现 - * - * @param channel - * @param state - */ - virtual void TMC5130Port_setResetNPinState(uint16_t channel, bool state) = 0; - /** - * @brief us级别延时函数。 - * - * @param us - */ - virtual void TMC5130Port_sleepus(int32_t us) = 0; - /** - * @brief SPI读写接口 - * - * @param data - * @param length - */ - virtual void TMC5130Port_readWriteArray(uint16_t channel, uint8_t *data, size_t length) = 0; -}; - class TMC5130 : public IStepperMotor { public: typedef struct { - bool autoReadEventRegister; // 是否自动读取事件寄存器 - uint32_t autoReadEventRegisterInterval; // 自动读取事件寄存器的时间间隔,单位为ms - TMC5130Port *m_port; - } TMC5130Config_t; + SPI_HandleTypeDef *hspi; + Pin_t enn_pin; + Pin_t csn_pin; + } cfg_t; + protected: - TMC5130Port *m_port; - TMC5130Config_t *m_config; - uint8_t m_channel; - uint32_t m_lastCallPeriodicJobTick; - int32_t m_shadowRegister[TMC_REGISTER_COUNT]; + // TMC5130Port *m_port; + // TMC5130Config_t *m_config; + + cfg_t m_cfg; + + ZGPIO *m_csnpin; + ZGPIO *m_ennpin; + SPI_HandleTypeDef *m_hspi; + + // uint8_t m_channel; + uint32_t m_lastCallPeriodicJobTick; + int32_t m_shadowRegister[TMC_REGISTER_COUNT]; const uint8_t *m_registerAccessTable; const int32_t *m_defaultRegisterResetState; @@ -108,9 +86,8 @@ class TMC5130 : public IStepperMotor { public: TMC5130(/* args */); - static void createDeafultTMC5130Config(TMC5130Config_t *config, TMC5130Port *m_port); - void initialize(uint8_t channel, TMC5130Config_t *config); - void periodicJob(uint32_t ticket); + // static void createDeafultTMC5130Config(TMC5130Config_t *config, TMC5130Port *m_port); + void initialize(cfg_t *cfg); void enableIC(bool enable); uint8_t reset(); diff --git a/hal/zhal_core.cpp b/hal/zhal_core.cpp index 162493e..52c19c6 100644 --- a/hal/zhal_core.cpp +++ b/hal/zhal_core.cpp @@ -31,3 +31,12 @@ void ZHALCORE::loop() { periodJob->schedule_times++; } } + +void ZHALCORE::initialize(cfg_t oscfg) { + iflytop_no_os_cfg_t cfg = { + .delayhtim = oscfg.delayhtim, + .debuguart = oscfg.debuguart, + }; + + iflytop_no_os_init(&cfg); +} diff --git a/hal/zhal_core.hpp b/hal/zhal_core.hpp index e7638d0..829f497 100644 --- a/hal/zhal_core.hpp +++ b/hal/zhal_core.hpp @@ -23,6 +23,11 @@ class ZHALCORE { public: }; + typedef struct { + TIM_HandleTypeDef* delayhtim; + UART_HandleTypeDef* debuguart; + } cfg_t; + class PeriodJob { public: PeriodJob(function job, uint32_t period_ms) { @@ -41,7 +46,7 @@ class ZHALCORE { ZHALCORE() {} static ZHALCORE* getInstance() { return &ZHALCORE_instance; } - void initialize(){}; + void initialize(cfg_t oscfg); void regPeriodJob(function job, uint32_t period_ms); void loop();