Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPI bus CS signal Time Bug between TMC and CPU #303

Open
fixus971 opened this issue Jul 10, 2024 · 1 comment
Open

SPI bus CS signal Time Bug between TMC and CPU #303

fixus971 opened this issue Jul 10, 2024 · 1 comment

Comments

@fixus971
Copy link

Good morning. I finally found the cause of the communication problems that randomly popped up every now and then.
It's a generic problem that occurs with faster CPUs and in my case:
TMC5160 and CPU Adafruit-Esp32-Feather-v2 SPI bus at 1MHz

The problem is that the TMC5160 requires an impulsive deactivation of the CS(ChipSel) signal between data request and response recovery but a pause is completely missing in the communication soft so with fast CPUs it can happen that this OnOff impulse is invisible to the driver.

__attribute__((weak))
uint32_t TMC2130Stepper::read(uint8_t addressByte) {
  uint32_t out = 0UL;
  int8_t i = 1;

  beginTransaction();
  switchCSpin(LOW);
  transfer(addressByte);
  // Clear SPI
  transferEmptyBytes(4);

  // Shift the written data to the correct driver in chain
  // Default link_index = -1 and no shifting happens
  while(i < link_index) {
    transferEmptyBytes(5);
    i++;
  }

  switchCSpin(HIGH);
  switchCSpin(LOW);

^^^^^^^^^^^^^ No Pause

My solution is
file: TMC2130Stepper.cpp

__attribute__((weak))
void IRAM_ATTR TMC2130Stepper::switchCSpin(bool state) {
 digitalWrite(_pinCS, state);
 esp_timer_get_time(); //900ns but very stable
}

In the forums there are many other solutions to count nano sec but all of them sooner or later fail due to some type of internal optimization of the CPU:

delayMicroseconds(1); //1500ns is too long
ESP.getCycleCount(); //400 40ns sometimes
cpu_hal_get_cycle_count();
cpu_ll_get_cycle_count();
xthal_get_ccount();
asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");.. //400 40ns sometimes
{ volatile int i; for(i=0; i<1; ++i) {} } //520ns 40ns sometimes

The tests were performed with a Logic Analyzer at 50MHz.
As a Trigger, to see the defect you need to continuously read the 4:IOIN address and activate an output when version is different from 30: in the event of an error it returns 4 because the registers do not rotate and the value sent remains.

I made my fix as indicated and it works for hours but I am writing to report the problem which I believe more and more people will run into given the increasingly faster CPUs.
Furthermore, I need a stable solution from Teemuatlut because I intend to develop other devices.

Thanks for everything, -Federico

@bluthen
Copy link

bluthen commented Oct 11, 2024

Thanks for posting this. I wonder if this is an issue I've been struggling with using the Teensy 4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants