diff options
author | David Crocker <dcrocker@eschertech.com> | 2021-10-18 13:10:50 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2021-10-18 13:10:50 +0300 |
commit | 6d6d3b8b62a20d842539afb2e319dd335a785af5 (patch) | |
tree | f42f72e15c793fe921306601afe87d619b68132f /src/Movement | |
parent | e1b1cd1960f6da4fba50a01b1b6de31c10187ed1 (diff) |
Implemented GetStandarDriverStatus in TMC2660 driver
Diffstat (limited to 'src/Movement')
-rw-r--r-- | src/Movement/StepperDrivers/TMC22xx.cpp | 102 | ||||
-rw-r--r-- | src/Movement/StepperDrivers/TMC22xx.h | 4 | ||||
-rw-r--r-- | src/Movement/StepperDrivers/TMC2660.cpp | 518 | ||||
-rw-r--r-- | src/Movement/StepperDrivers/TMC2660.h | 20 | ||||
-rw-r--r-- | src/Movement/StepperDrivers/TMC51xx.cpp | 6 | ||||
-rw-r--r-- | src/Movement/StepperDrivers/TMC51xx.h | 2 |
6 files changed, 293 insertions, 359 deletions
diff --git a/src/Movement/StepperDrivers/TMC22xx.cpp b/src/Movement/StepperDrivers/TMC22xx.cpp index 15720077..b3ed6cc0 100644 --- a/src/Movement/StepperDrivers/TMC22xx.cpp +++ b/src/Movement/StepperDrivers/TMC22xx.cpp @@ -907,9 +907,7 @@ pre(!driversPowered) #if HAS_STALL_DETECT diagPin = p_diagPin; -# if !defined(DUET3MINI_V04) // on Duet 3 Mini we have already done this and switched the pin to be a CCL input IoPort::SetPinMode(p_diagPin, INPUT_PULLDOWN); // pull down not up so that missing drivers don't signal stalls -# endif #endif #if !(TMC22xx_HAS_MUX || TMC22xx_SINGLE_DRIVER) @@ -2140,80 +2138,24 @@ GCodeResult SmartDrivers::SetAnyRegister(size_t driver, const StringRef& reply, return GCodeResult::error; } -#ifdef DUET3MINI_V04 - -// Stall detection for Duet 3 Mini v0.4 and later -// Each TMC2209 DIAG output is routed to its own MCU pin, however we don't have enough EXINTs on the SAME54 to give each one its own interrupt. -// So we route them all to CCL input pins instead, which lets us selectively OR them together in 3 groups and generate an interrupt from the resulting events - -// Set up to generate interrupts on the specified drivers stalling -void EnableStallInterrupt(DriversBitmap drivers) noexcept -{ - // Disable all the Diag event interrupts - for (unsigned int i = 1; i < 3; ++i) - { - CCL->LUTCTRL[i].reg &= ~CCL_LUTCTRL_ENABLE; - EVSYS->Channel[CclLut0Event + i].CHINTENCLR.reg = EVSYS_CHINTENCLR_EVD | EVSYS_CHINTENCLR_OVR; - EVSYS->Channel[CclLut0Event + i].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTENCLR_OVR; - } - - if (!drivers.IsEmpty()) - { - // Calculate the new LUT control values - constexpr uint32_t lutDefault = CCL_LUTCTRL_TRUTH(0xFE) | CCL_LUTCTRL_LUTEO; // OR function, disabled, event output enabled - uint32_t lutInputControls[4] = { lutDefault, lutDefault, lutDefault, lutDefault }; - drivers.IterateWhile([&lutInputControls](unsigned int driver, unsigned int count) -> bool - { if (driver < GetNumTmcDrivers()) - { - const uint32_t cclInput = CclDiagInputs[driver]; - lutInputControls[cclInput & 3] |= cclInput & 0x000000FFFFFF0000; - return true; - } - else - { - return false; - } - } ); - - // Now set up the CCL with those inputs. We only use CCL 1-3 so leave 0 alone for possible other applications. - for (unsigned int i = 1; i < 4; ++i) - { - if (lutInputControls[i] & 0x000000FFFFFF0000) // if any inputs are enabled - { - CCL->LUTCTRL[i].reg = lutInputControls[i]; - CCL->LUTCTRL[i].reg = lutInputControls[i] | CCL_LUTCTRL_ENABLE; - EVSYS->Channel[CclLut0Event + i].CHINTENSET.reg = EVSYS_CHINTENCLR_EVD; - } - } - } -} - -// Initialise the stall detection logic that is external to the drivers. Only needs to be called once. -static void InitStallDetectionLogic() noexcept +StandardDriverStatus SmartDrivers::GetStandardDriverStatus(size_t driver) noexcept { - // Set up the DIAG inputs as CCL inputs - for (Pin p : DriverDiagPins) + StandardDriverStatus rslt; + if (driver < GetNumTmcDrivers()) { - pinMode(p, INPUT_PULLDOWN); // enable pulldown in case of missing drivers - SetPinFunction(p, GpioPinFunction::N); + const uint32_t status = driverStates[driver].ReadLiveStatus(); + // The lowest 8 bits of StandardDriverStatus have the same meanings as for the TMC2209 status + rslt.all = status & 0x000000FF; + rslt.all |= ExtractBit(status, TMC_RR_STST_BIT_POS, StandardDriverStatus::StandstillBitPos); // put the standstill bit in the right place + rslt.all |= ExtractBit(status, TMC_RR_SG_BIT_POS, StandardDriverStatus::StallBitPos); // put the stall bit in the right place } - - // Set up the event channels for CCL LUTs 1 to 3. We only use CCL 1-3 so leave 0 alone for possible other applications. - for (unsigned int i = 1; i < 4; ++i) + else { - GCLK->PCHCTRL[EVSYS_GCLK_ID_0 + i].reg = GCLK_PCHCTRL_GEN(GclkNum60MHz) | GCLK_PCHCTRL_CHEN; // enable the GCLK, needed to use the resynchronised path - EVSYS->Channel[CclLut0Event + i].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(0x74 + i) | EVSYS_CHANNEL_PATH_RESYNCHRONIZED; - // LUT output events on the SAME5x are event generator numbers 0x74 to 0x77. Resynchronised path allows interrupts. - EVSYS->Channel[CclLut0Event + i].CHINTENCLR.reg = EVSYS_CHINTENCLR_EVD | EVSYS_CHINTENCLR_OVR; // disable interrupts for now - NVIC_SetPriority((IRQn)(EVSYS_0_IRQn + i), NvicPriorityDriverDiag); - NVIC_EnableIRQ((IRQn)(EVSYS_0_IRQn + i)); // enable the interrupt for this event channel in the NVIC + rslt.all = 0; } - - CCL->CTRL.reg = CCL_CTRL_ENABLE; // enable the CCL + return rslt; } -#endif - #if HAS_STALL_DETECT DriversBitmap SmartDrivers::GetStalledDrivers(DriversBitmap driversOfInterest) noexcept @@ -2232,28 +2174,6 @@ DriversBitmap SmartDrivers::GetStalledDrivers(DriversBitmap driversOfInterest) n #endif -#if SUPPORT_REMOTE_COMMANDS - -StandardDriverStatus SmartDrivers::GetStandardDriverStatus(size_t driver) noexcept -{ - StandardDriverStatus rslt; - if (driver < GetNumTmcDrivers()) - { - const uint32_t status = driverStates[driver].ReadLiveStatus(); - // The lowest 8 bits of StandardDriverStatus have the same meanings as for the TMC2209 status - rslt.all = status & 0x000000FF; - rslt.all |= ExtractBit(status, TMC_RR_STST_BIT_POS, StandardDriverStatus::StandstillBitPos); // put the standstill bit in the right place - rslt.all |= ExtractBit(status, TMC_RR_SG_BIT_POS, StandardDriverStatus::StallBitPos); // put the stall bit in the right place - } - else - { - rslt.all = 0; - } - return rslt; -} - -#endif - #endif // End diff --git a/src/Movement/StepperDrivers/TMC22xx.h b/src/Movement/StepperDrivers/TMC22xx.h index b41e2976..02898616 100644 --- a/src/Movement/StepperDrivers/TMC22xx.h +++ b/src/Movement/StepperDrivers/TMC22xx.h @@ -67,12 +67,10 @@ namespace SmartDrivers uint32_t GetRegister(size_t driver, SmartDriverRegister reg) noexcept; GCodeResult GetAnyRegister(size_t driver, const StringRef& reply, uint8_t regNum) noexcept; GCodeResult SetAnyRegister(size_t driver, const StringRef& reply, uint8_t regNum, uint32_t regVal) noexcept; + StandardDriverStatus GetStandardDriverStatus(size_t driver) noexcept; #if HAS_STALL_DETECT DriversBitmap GetStalledDrivers(DriversBitmap driversOfInterest) noexcept; #endif -#if SUPPORT_REMOTE_COMMANDS - StandardDriverStatus GetStandardDriverStatus(size_t driver) noexcept; -#endif }; #endif diff --git a/src/Movement/StepperDrivers/TMC2660.cpp b/src/Movement/StepperDrivers/TMC2660.cpp index 5f042865..de545401 100644 --- a/src/Movement/StepperDrivers/TMC2660.cpp +++ b/src/Movement/StepperDrivers/TMC2660.cpp @@ -898,353 +898,369 @@ void TMC2660_SPI_Handler(void) noexcept //--------------------------- Public interface --------------------------------- -namespace SmartDrivers +// Initialise the driver interface and the drivers, leaving each drive disabled. +// It is assumed that the drivers are not powered, so driversPowered(true) must be called after calling this before the motors can be moved. +void SmartDrivers::Init(const Pin driverSelectPins[NumDirectDrivers], size_t numTmcDrivers) noexcept { - // Initialise the driver interface and the drivers, leaving each drive disabled. - // It is assumed that the drivers are not powered, so driversPowered(true) must be called after calling this before the motors can be moved. - void Init(const Pin driverSelectPins[NumDirectDrivers], size_t numTmcDrivers) noexcept - { - numTmc2660Drivers = min<size_t>(numTmcDrivers, MaxSmartDrivers); + numTmc2660Drivers = min<size_t>(numTmcDrivers, MaxSmartDrivers); - // Make sure the ENN pins are high - pinMode(GlobalTmc2660EnablePin, OUTPUT_HIGH); + // Make sure the ENN pins are high + pinMode(GlobalTmc2660EnablePin, OUTPUT_HIGH); - // The pins are already set up for SPI in the pins table - SetPinFunction(TMC2660MosiPin, TMC2660PeriphMode); - SetPinFunction(TMC2660MisoPin, TMC2660PeriphMode); - SetPinFunction(TMC2660SclkPin, TMC2660PeriphMode); + // The pins are already set up for SPI in the pins table + SetPinFunction(TMC2660MosiPin, TMC2660PeriphMode); + SetPinFunction(TMC2660MisoPin, TMC2660PeriphMode); + SetPinFunction(TMC2660SclkPin, TMC2660PeriphMode); - // Enable the clock to the USART or SPI - pmc_enable_periph_clk(ID_TMC2660_SPI); + // Enable the clock to the USART or SPI + pmc_enable_periph_clk(ID_TMC2660_SPI); #if TMC2660_USES_USART - // Set USART_EXT_DRV in SPI mode, with data changing on the falling edge of the clock and captured on the rising edge - USART_TMC2660->US_IDR = ~0u; - USART_TMC2660->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS; - USART_TMC2660->US_MR = US_MR_USART_MODE_SPI_MASTER - | US_MR_USCLKS_MCK - | US_MR_CHRL_8_BIT - | US_MR_CHMODE_NORMAL - | US_MR_CPOL - | US_MR_CLKO; - USART_TMC2660->US_BRGR = SystemCoreClockFreq/DriversSpiClockFrequency; // set SPI clock frequency - USART_TMC2660->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS | US_CR_RSTSTA; - - // We need a few microseconds of delay here for the USART to sort itself out before we send any data, - // otherwise the processor generates two short reset pulses on its own NRST pin, and resets itself. - // 2016-07-07: removed this delay, because we no longer send commands to the TMC2660 drivers immediately. - //delay(10); + // Set USART_EXT_DRV in SPI mode, with data changing on the falling edge of the clock and captured on the rising edge + USART_TMC2660->US_IDR = ~0u; + USART_TMC2660->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS; + USART_TMC2660->US_MR = US_MR_USART_MODE_SPI_MASTER + | US_MR_USCLKS_MCK + | US_MR_CHRL_8_BIT + | US_MR_CHMODE_NORMAL + | US_MR_CPOL + | US_MR_CLKO; + USART_TMC2660->US_BRGR = SystemCoreClockFreq/DriversSpiClockFrequency; // set SPI clock frequency + USART_TMC2660->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS | US_CR_RSTSTA; + + // We need a few microseconds of delay here for the USART to sort itself out before we send any data, + // otherwise the processor generates two short reset pulses on its own NRST pin, and resets itself. + // 2016-07-07: removed this delay, because we no longer send commands to the TMC2660 drivers immediately. + //delay(10); #else - // Set up the SPI interface with data changing on the falling edge of the clock and captured on the rising edge - spi_reset(SPI_TMC2660); // this clears the transmit and receive registers and puts the SPI into slave mode - SPI_TMC2660->SPI_MR = SPI_MR_MSTR // master mode - | SPI_MR_MODFDIS // disable fault detection - | SPI_MR_PCS(0); // fixed peripheral select - - // Set SPI mode, clock frequency, CS active after transfer, delay between transfers - const uint16_t baud_div = (uint16_t)spi_calc_baudrate_div(DriversSpiClockFrequency, SystemCoreClock); - const uint32_t csr = SPI_CSR_SCBR(baud_div) // Baud rate - | SPI_CSR_BITS_8_BIT // Transfer bit width - | SPI_CSR_DLYBCT(0) // Transfer delay - | SPI_CSR_CSAAT // Keep CS low after transfer in case we are slow in writing the next byte - | SPI_CSR_CPOL; // clock high between transfers - SPI_TMC2660->SPI_CSR[0] = csr; + // Set up the SPI interface with data changing on the falling edge of the clock and captured on the rising edge + spi_reset(SPI_TMC2660); // this clears the transmit and receive registers and puts the SPI into slave mode + SPI_TMC2660->SPI_MR = SPI_MR_MSTR // master mode + | SPI_MR_MODFDIS // disable fault detection + | SPI_MR_PCS(0); // fixed peripheral select + + // Set SPI mode, clock frequency, CS active after transfer, delay between transfers + const uint16_t baud_div = (uint16_t)spi_calc_baudrate_div(DriversSpiClockFrequency, SystemCoreClock); + const uint32_t csr = SPI_CSR_SCBR(baud_div) // Baud rate + | SPI_CSR_BITS_8_BIT // Transfer bit width + | SPI_CSR_DLYBCT(0) // Transfer delay + | SPI_CSR_CSAAT // Keep CS low after transfer in case we are slow in writing the next byte + | SPI_CSR_CPOL; // clock high between transfers + SPI_TMC2660->SPI_CSR[0] = csr; #endif - driversState = DriversState::noPower; - EndstopOrZProbe::SetDriversNotStalled(DriversBitmap::MakeLowestNBits(MaxSmartDrivers)); - for (size_t driver = 0; driver < numTmc2660Drivers; ++driver) - { - driverStates[driver].Init(driver, driverSelectPins[driver]); // axes are mapped straight through to drivers initially - } + driversState = DriversState::noPower; + EndstopOrZProbe::SetDriversNotStalled(DriversBitmap::MakeLowestNBits(MaxSmartDrivers)); + for (size_t driver = 0; driver < numTmc2660Drivers; ++driver) + { + driverStates[driver].Init(driver, driverSelectPins[driver]); // axes are mapped straight through to drivers initially + } #if SAME70 - pmc_enable_periph_clk(ID_XDMAC); - xdmac_channel_disable_interrupt(XDMAC, DmacChanTmcTx, 0xFFFFFFFF); - xdmac_channel_disable_interrupt(XDMAC, DmacChanTmcRx, 0xFFFFFFFF); - xdmac_enable_interrupt(XDMAC, DmacChanTmcRx); + pmc_enable_periph_clk(ID_XDMAC); + xdmac_channel_disable_interrupt(XDMAC, DmacChanTmcTx, 0xFFFFFFFF); + xdmac_channel_disable_interrupt(XDMAC, DmacChanTmcRx, 0xFFFFFFFF); + xdmac_enable_interrupt(XDMAC, DmacChanTmcRx); #endif - } +} - // Shut down the drivers and stop any related interrupts. Don't call Spin() again after calling this as it may re-enable them. - void Exit() noexcept - { - digitalWrite(GlobalTmc2660EnablePin, HIGH); - NVIC_DisableIRQ(TMC2660_SPI_IRQn); - driversState = DriversState::noPower; - } +// Shut down the drivers and stop any related interrupts. Don't call Spin() again after calling this as it may re-enable them. +void SmartDrivers::Exit() noexcept +{ + digitalWrite(GlobalTmc2660EnablePin, HIGH); + NVIC_DisableIRQ(TMC2660_SPI_IRQn); + driversState = DriversState::noPower; +} - void SetAxisNumber(size_t driver, uint32_t axisNumber) noexcept +void SmartDrivers::SetAxisNumber(size_t driver, uint32_t axisNumber) noexcept +{ + if (driver < numTmc2660Drivers) { - if (driver < numTmc2660Drivers) - { - driverStates[driver].SetAxisNumber(axisNumber); - } + driverStates[driver].SetAxisNumber(axisNumber); } +} - void SetCurrent(size_t driver, float current) noexcept +void SmartDrivers::SetCurrent(size_t driver, float current) noexcept +{ + if (driver < numTmc2660Drivers) { - if (driver < numTmc2660Drivers) - { - driverStates[driver].SetCurrent(current); - } + driverStates[driver].SetCurrent(current); } +} - void EnableDrive(size_t driver, bool en) noexcept +void SmartDrivers::EnableDrive(size_t driver, bool en) noexcept +{ + if (driver < numTmc2660Drivers) { - if (driver < numTmc2660Drivers) - { - driverStates[driver].Enable(en); - } + driverStates[driver].Enable(en); } +} - uint32_t GetLiveStatus(size_t driver) noexcept - { - return (driver < numTmc2660Drivers) ? driverStates[driver].ReadLiveStatus() : 0; - } +uint32_t SmartDrivers::GetLiveStatus(size_t driver) noexcept +{ + return (driver < numTmc2660Drivers) ? driverStates[driver].ReadLiveStatus() : 0; +} - uint32_t GetAccumulatedStatus(size_t driver, uint32_t bitsToKeep) noexcept - { - return (driver < numTmc2660Drivers) ? driverStates[driver].ReadAccumulatedStatus(bitsToKeep) : 0; - } +uint32_t SmartDrivers::GetAccumulatedStatus(size_t driver, uint32_t bitsToKeep) noexcept +{ + return (driver < numTmc2660Drivers) ? driverStates[driver].ReadAccumulatedStatus(bitsToKeep) : 0; +} - // Set microstepping and microstep interpolation - bool SetMicrostepping(size_t driver, unsigned int microsteps, bool interpolate) noexcept +// Set microstepping and microstep interpolation +bool SmartDrivers::SetMicrostepping(size_t driver, unsigned int microsteps, bool interpolate) noexcept +{ + if (driver < numTmc2660Drivers && microsteps > 0) { - if (driver < numTmc2660Drivers && microsteps > 0) + // Set the microstepping. We need to determine how many bits right to shift the desired microstepping to reach 1. + unsigned int shift = 0; + unsigned int uSteps = (unsigned int)microsteps; + while ((uSteps & 1) == 0) { - // Set the microstepping. We need to determine how many bits right to shift the desired microstepping to reach 1. - unsigned int shift = 0; - unsigned int uSteps = (unsigned int)microsteps; - while ((uSteps & 1) == 0) - { - uSteps >>= 1; - ++shift; - } - if (uSteps == 1 && shift <= 8) - { - driverStates[driver].SetMicrostepping(shift, interpolate); - return true; - } + uSteps >>= 1; + ++shift; } - return false; - } - - // Get microstepping and interpolation - unsigned int GetMicrostepping(size_t driver, bool& interpolation) noexcept - { - if (driver < numTmc2660Drivers) + if (uSteps == 1 && shift <= 8) { - return driverStates[driver].GetMicrostepping(interpolation); + driverStates[driver].SetMicrostepping(shift, interpolate); + return true; } - interpolation = false; - return 1; } + return false; +} - bool SetDriverMode(size_t driver, unsigned int mode) noexcept +// Get microstepping and interpolation +unsigned int SmartDrivers::GetMicrostepping(size_t driver, bool& interpolation) noexcept +{ + if (driver < numTmc2660Drivers) { - return driver < numTmc2660Drivers && driverStates[driver].SetDriverMode(mode); + return driverStates[driver].GetMicrostepping(interpolation); } + interpolation = false; + return 1; +} - DriverMode GetDriverMode(size_t driver) noexcept - { - return (driver < numTmc2660Drivers) ? driverStates[driver].GetDriverMode() : DriverMode::unknown; - } +bool SmartDrivers::SetDriverMode(size_t driver, unsigned int mode) noexcept +{ + return driver < numTmc2660Drivers && driverStates[driver].SetDriverMode(mode); +} + +DriverMode SmartDrivers::GetDriverMode(size_t driver) noexcept +{ + return (driver < numTmc2660Drivers) ? driverStates[driver].GetDriverMode() : DriverMode::unknown; +} - // Flag the the drivers have been powered up. - // Before the first call to this function with powered true, you must call Init(). - void Spin(bool powered) noexcept +// Flag the the drivers have been powered up. +// Before the first call to this function with powered true, you must call Init(). +void SmartDrivers::Spin(bool powered) noexcept +{ + if (powered) { - if (powered) + switch (driversState) { - switch (driversState) + case DriversState::noPower: + // Power to the drivers has been provided or restored, so we need to enable and re-initialise them + EndstopOrZProbe::SetDriversNotStalled(DriversBitmap::MakeLowestNBits(MaxSmartDrivers)); + for (size_t driver = 0; driver < numTmc2660Drivers; ++driver) { - case DriversState::noPower: - // Power to the drivers has been provided or restored, so we need to enable and re-initialise them - EndstopOrZProbe::SetDriversNotStalled(DriversBitmap::MakeLowestNBits(MaxSmartDrivers)); - for (size_t driver = 0; driver < numTmc2660Drivers; ++driver) - { - driverStates[driver].WriteAll(); - } - driversState = DriversState::initialising; - break; + driverStates[driver].WriteAll(); + } + driversState = DriversState::initialising; + break; - case DriversState::initialising: - // If all drivers have been initialised, move to checking the microstep counters + case DriversState::initialising: + // If all drivers have been initialised, move to checking the microstep counters + { + bool allInitialised = true; + for (size_t i = 0; i < numTmc2660Drivers; ++i) { - bool allInitialised = true; - for (size_t i = 0; i < numTmc2660Drivers; ++i) + if (driverStates[i].UpdatePending()) { - if (driverStates[i].UpdatePending()) - { - allInitialised = false; - break; - } - driverStates[i].ClearMicrostepPosition(); + allInitialised = false; + break; } + driverStates[i].ClearMicrostepPosition(); + } - if (allInitialised) - { - driversState = DriversState::stepping; - } + if (allInitialised) + { + driversState = DriversState::stepping; } - break; + } + break; - case DriversState::stepping: + case DriversState::stepping: + { + bool moreNeeded = false; + for (size_t i = 0; i < numTmc2660Drivers; ++i) { - bool moreNeeded = false; - for (size_t i = 0; i < numTmc2660Drivers; ++i) + // The following line assumes that driver numbers in RRF map directly to smart driver numbers in this module. They do on Duets. + if (reprap.GetPlatform().GetEnableValue(i) >= 0) // if the driver has not been disabled { - // The following line assumes that driver numbers in RRF map directly to smart driver numbers in this module. They do on Duets. - if (reprap.GetPlatform().GetEnableValue(i) >= 0) // if the driver has not been disabled + uint32_t count = driverStates[i].ReadMicrostepPosition(); + if (count != 0) { - uint32_t count = driverStates[i].ReadMicrostepPosition(); - if (count != 0) + moreNeeded = true; + if (count < 1024) { - moreNeeded = true; - if (count < 1024) + const bool backwards = (count > 512); + reprap.GetPlatform().SetDriverAbsoluteDirection(i, backwards); // a high on DIR decreases the microstep counter + if (backwards) { - const bool backwards = (count > 512); - reprap.GetPlatform().SetDriverAbsoluteDirection(i, backwards); // a high on DIR decreases the microstep counter - if (backwards) - { - count = 1024 - count; - } - do - { - delayMicroseconds(1); - const uint32_t driverBitmap = StepPins::CalcDriverBitmap(i); - StepPins::StepDriversHigh(driverBitmap); - delayMicroseconds(1); - StepPins::StepDriversLow(driverBitmap); - --count; - } while (count != 0); - driverStates[i].ClearMicrostepPosition(); + count = 1024 - count; } + do + { + delayMicroseconds(1); + const uint32_t driverBitmap = StepPins::CalcDriverBitmap(i); + StepPins::StepDriversHigh(driverBitmap); + delayMicroseconds(1); + StepPins::StepDriversLow(driverBitmap); + --count; + } while (count != 0); + driverStates[i].ClearMicrostepPosition(); } } } - if (!moreNeeded) - { - driversState = DriversState::reinitialising; - for (size_t driver = 0; driver < numTmc2660Drivers; ++driver) - { - driverStates[driver].WriteAll(); - } - } } - break; - - case DriversState::reinitialising: - // If all drivers have been initialised, set the global enable + if (!moreNeeded) { - bool allInitialised = true; - for (size_t i = 0; i < numTmc2660Drivers; ++i) + driversState = DriversState::reinitialising; + for (size_t driver = 0; driver < numTmc2660Drivers; ++driver) { - if (driverStates[i].UpdatePending()) - { - allInitialised = false; - break; - } + driverStates[driver].WriteAll(); } + } + } + break; - if (allInitialised) + case DriversState::reinitialising: + // If all drivers have been initialised, set the global enable + { + bool allInitialised = true; + for (size_t i = 0; i < numTmc2660Drivers; ++i) + { + if (driverStates[i].UpdatePending()) { - digitalWrite(GlobalTmc2660EnablePin, LOW); - driversState = DriversState::ready; + allInitialised = false; + break; } } - break; - case DriversState::ready: - break; + if (allInitialised) + { + digitalWrite(GlobalTmc2660EnablePin, LOW); + driversState = DriversState::ready; + } } + break; - if (currentDriver == nullptr && numTmc2660Drivers != 0) - { - // Kick off the first transfer - NVIC_EnableIRQ(TMC2660_SPI_IRQn); - driverStates[0].StartTransfer(); - } + case DriversState::ready: + break; } - else if (driversState != DriversState::noPower) + + if (currentDriver == nullptr && numTmc2660Drivers != 0) { - digitalWrite(GlobalTmc2660EnablePin, HIGH); // disable the drivers - driversState = DriversState::noPower; - EndstopOrZProbe::SetDriversNotStalled(DriversBitmap::MakeLowestNBits(MaxSmartDrivers)); + // Kick off the first transfer + NVIC_EnableIRQ(TMC2660_SPI_IRQn); + driverStates[0].StartTransfer(); } } - - // This is called from the tick ISR, possibly while Spin (with powered either true or false) is being executed - void TurnDriversOff() noexcept + else if (driversState != DriversState::noPower) { - digitalWrite(GlobalTmc2660EnablePin, HIGH); // disable the drivers + digitalWrite(GlobalTmc2660EnablePin, HIGH); // disable the drivers driversState = DriversState::noPower; EndstopOrZProbe::SetDriversNotStalled(DriversBitmap::MakeLowestNBits(MaxSmartDrivers)); } +} - void SetStallThreshold(size_t driver, int sgThreshold) noexcept - { - if (driver < numTmc2660Drivers) - { - driverStates[driver].SetStallDetectThreshold(sgThreshold); - } - } +// This is called from the tick ISR, possibly while Spin (with powered either true or false) is being executed +void SmartDrivers::TurnDriversOff() noexcept +{ + digitalWrite(GlobalTmc2660EnablePin, HIGH); // disable the drivers + driversState = DriversState::noPower; + EndstopOrZProbe::SetDriversNotStalled(DriversBitmap::MakeLowestNBits(MaxSmartDrivers)); +} - void SetStallFilter(size_t driver, bool sgFilter) noexcept +void SmartDrivers::SetStallThreshold(size_t driver, int sgThreshold) noexcept +{ + if (driver < numTmc2660Drivers) { - if (driver < numTmc2660Drivers) - { - driverStates[driver].SetStallDetectFilter(sgFilter); - } + driverStates[driver].SetStallDetectThreshold(sgThreshold); } +} - void SetStallMinimumStepsPerSecond(size_t driver, unsigned int stepsPerSecond) noexcept +void SmartDrivers::SetStallFilter(size_t driver, bool sgFilter) noexcept +{ + if (driver < numTmc2660Drivers) { - if (driver < numTmc2660Drivers) - { - driverStates[driver].SetStallMinimumStepsPerSecond(stepsPerSecond); - } + driverStates[driver].SetStallDetectFilter(sgFilter); } +} - void AppendStallConfig(size_t driver, const StringRef& reply) noexcept +void SmartDrivers::SetStallMinimumStepsPerSecond(size_t driver, unsigned int stepsPerSecond) noexcept +{ + if (driver < numTmc2660Drivers) { - if (driver < numTmc2660Drivers) - { - driverStates[driver].AppendStallConfig(reply); - } + driverStates[driver].SetStallMinimumStepsPerSecond(stepsPerSecond); } +} - void AppendDriverStatus(size_t driver, const StringRef& reply) noexcept +void SmartDrivers::AppendStallConfig(size_t driver, const StringRef& reply) noexcept +{ + if (driver < numTmc2660Drivers) { - if (driver < numTmc2660Drivers) - { - driverStates[driver].AppendDriverStatus(reply); - } + driverStates[driver].AppendStallConfig(reply); } +} - float GetStandstillCurrentPercent(size_t driver) noexcept +void SmartDrivers::AppendDriverStatus(size_t driver, const StringRef& reply) noexcept +{ + if (driver < numTmc2660Drivers) { - return 100.0; // not supported + driverStates[driver].AppendDriverStatus(reply); } +} - void SetStandstillCurrentPercent(size_t driver, float percent) noexcept - { - // not supported so nothing to see here - } +float SmartDrivers::GetStandstillCurrentPercent(size_t driver) noexcept +{ + return 100.0; // not supported +} + +void SmartDrivers::SetStandstillCurrentPercent(size_t driver, float percent) noexcept +{ + // not supported so nothing to see here +} + +bool SmartDrivers::SetRegister(size_t driver, SmartDriverRegister reg, uint32_t regVal) noexcept +{ + return (driver < numTmc2660Drivers) && driverStates[driver].SetRegister(reg, regVal); +} + +uint32_t SmartDrivers::GetRegister(size_t driver, SmartDriverRegister reg) noexcept +{ + return (driver < numTmc2660Drivers) ? driverStates[driver].GetRegister(reg) : 0; +} - bool SetRegister(size_t driver, SmartDriverRegister reg, uint32_t regVal) noexcept +StandardDriverStatus SmartDrivers::GetStandardDriverStatus(size_t driver) noexcept +{ + StandardDriverStatus rslt; + if (driver < numTmc2660Drivers) { - return (driver < numTmc2660Drivers) && driverStates[driver].SetRegister(reg, regVal); + const uint32_t status = driverStates[driver].ReadLiveStatus(); + // The lowest 8 bits of StandardDriverStatus have the same meanings as for the TMC2209 status, but the TMC2660 uses different bit assignments + rslt.all = ExtractBit(status, TMC_RR_OT_BIT_POS, StandardDriverStatus::OtBitPos); + rslt.all |= ExtractBit(status, TMC_RR_OTPW_BIT_POS, StandardDriverStatus::OtpwBitPos); + rslt.all |= (status & TMC_RR_S2G) >> 1; // put the S2G bits in the right place + rslt.all |= (status & (TMC_RR_OLA | TMC_RR_OLB)) << 1; // put the open load bits in the right place + rslt.all |= ExtractBit(status, TMC_RR_STST_BIT_POS, StandardDriverStatus::StandstillBitPos); // put the standstill bit in the right place + rslt.all |= ExtractBit(status, TMC_RR_SG_BIT_POS, StandardDriverStatus::StallBitPos); // put the stall bit in the right place } - - uint32_t GetRegister(size_t driver, SmartDriverRegister reg) noexcept + else { - return (driver < numTmc2660Drivers) ? driverStates[driver].GetRegister(reg) : 0; + rslt.all = 0; } - -}; // end namespace - + return rslt; +} #endif // End diff --git a/src/Movement/StepperDrivers/TMC2660.h b/src/Movement/StepperDrivers/TMC2660.h index e4145078..8bb8d97e 100644 --- a/src/Movement/StepperDrivers/TMC2660.h +++ b/src/Movement/StepperDrivers/TMC2660.h @@ -15,13 +15,18 @@ #include <Pins.h> // TMC2660 read response bits that are returned by the status calls -const uint32_t TMC_RR_SG = 1 << 0; // stall detected -const uint32_t TMC_RR_OT = 1 << 1; // over temperature shutdown -const uint32_t TMC_RR_OTPW = 1 << 2; // over temperature warning -const uint32_t TMC_RR_S2G = 3 << 3; // short to ground counter (2 bits) -const uint32_t TMC_RR_OLA = 1 << 5; // open load A -const uint32_t TMC_RR_OLB = 1 << 6; // open load B -const uint32_t TMC_RR_STST = 1 << 7; // standstill detected +constexpr uint32_t TMC_RR_SG = 1 << 0; // stall detected +constexpr uint32_t TMC_RR_OT = 1 << 1; // over temperature shutdown +constexpr uint32_t TMC_RR_OTPW = 1 << 2; // over temperature warning +constexpr uint32_t TMC_RR_S2G = 3 << 3; // short to ground counter (2 bits) +constexpr uint32_t TMC_RR_OLA = 1 << 5; // open load A +constexpr uint32_t TMC_RR_OLB = 1 << 6; // open load B +constexpr uint32_t TMC_RR_STST = 1 << 7; // standstill detected + +constexpr unsigned int TMC_RR_OT_BIT_POS = 1; +constexpr unsigned int TMC_RR_OTPW_BIT_POS = 2; +constexpr unsigned int TMC_RR_STST_BIT_POS = 7; +constexpr unsigned int TMC_RR_SG_BIT_POS = 0; namespace SmartDrivers { @@ -49,6 +54,7 @@ namespace SmartDrivers void SetStandstillCurrentPercent(size_t driver, float percent) noexcept; bool SetRegister(size_t driver, SmartDriverRegister reg, uint32_t regVal) noexcept; uint32_t GetRegister(size_t driver, SmartDriverRegister reg) noexcept; + StandardDriverStatus GetStandardDriverStatus(size_t driver) noexcept; }; #endif diff --git a/src/Movement/StepperDrivers/TMC51xx.cpp b/src/Movement/StepperDrivers/TMC51xx.cpp index 64976644..ca2201ec 100644 --- a/src/Movement/StepperDrivers/TMC51xx.cpp +++ b/src/Movement/StepperDrivers/TMC51xx.cpp @@ -1600,8 +1600,6 @@ GCodeResult SmartDrivers::SetAnyRegister(size_t driver, const StringRef& reply, return GCodeResult::error; } -#if SUPPORT_REMOTE_COMMANDS - StandardDriverStatus SmartDrivers::GetStandardDriverStatus(size_t driver) noexcept { StandardDriverStatus rslt; @@ -1609,7 +1607,7 @@ StandardDriverStatus SmartDrivers::GetStandardDriverStatus(size_t driver) noexce { const uint32_t status = driverStates[driver].ReadLiveStatus(); // The lowest 8 bits of StandardDriverStatus have the same meanings as for the TMC2209 status, but the TMC51xx uses different bit assignments - rslt.all = (status >> (25 - 0)) & (0x0F << 0); // this puts the it, otpw, s2ga and s2gb bits in the right place + rslt.all = (status >> (25 - 0)) & (0x0F << 0); // this puts the ot, otpw, s2ga and s2gb bits in the right place rslt.all |= (status >> (12 - 4)) & (3u << 4); // put s2vsa and s2vsb in the right place rslt.all |= (status >> (29 - 6)) & (3u << 6); // put ola and olb in the right place rslt.all |= ExtractBit(status, TMC_RR_STST_BIT_POS, StandardDriverStatus::StandstillBitPos); // put the standstill bit in the right place @@ -1624,6 +1622,4 @@ StandardDriverStatus SmartDrivers::GetStandardDriverStatus(size_t driver) noexce #endif -#endif - // End diff --git a/src/Movement/StepperDrivers/TMC51xx.h b/src/Movement/StepperDrivers/TMC51xx.h index 90fc0f76..aa77821e 100644 --- a/src/Movement/StepperDrivers/TMC51xx.h +++ b/src/Movement/StepperDrivers/TMC51xx.h @@ -56,9 +56,7 @@ namespace SmartDrivers uint32_t GetRegister(size_t driver, SmartDriverRegister reg) noexcept; GCodeResult GetAnyRegister(size_t driver, const StringRef& reply, uint8_t regNum) noexcept; GCodeResult SetAnyRegister(size_t driver, const StringRef& reply, uint8_t regNum, uint32_t regVal) noexcept; -#if SUPPORT_REMOTE_COMMANDS StandardDriverStatus GetStandardDriverStatus(size_t driver) noexcept; -#endif }; #endif |