Category: Software
Product Number: TMC4361A, TMC2160, ATMega328p(MCU)
Software Version: C++17
I've been working on setting up a smart stepper motor using an ATMega328p microcontroller, TMC4361A motion controller, and TMC2160 driver.
I am using the TMCAPI available on GitHub and primarily use the register macro definitions, tmc4361a_writeInt() and tmc4361a_readInt() functions. . I've created my own readWriteArray() function to transfer SPI packets. SPI is configured at 1MHz, MSB Order, and SPIMODE3. Using a logic analyzer, I can see that my SPI frames are sending as expected and the Trinamic ICs are replying on the next sent frame. This appears to be correct communication behavior, except here is my issue...
Although it appears that I am writing to the TMC4361A registers, when I read the register the response is the dummy packet sent on the read call rather than the value I wrote. I'm seeing the same behavior when writing to the cover registers and reading from the cover_drv registers. It appears that adding the Write bit to data is taken care of in the TMCAPI and I've checked that manually adding it before calling tmc4361a_writeInt() has no effect. Is there something I'm missing here?
Here are some source code snippets below to help. The registers set here are set on initialization and suggested from the TMC4361A datasheet v1.26, section 22.1.
/* Activate SPI data transfer mode (p.225)*/
tmc4361A_writeInt(motorToIC(motor), TMC4361A_SPIOUT_CONF, 0x4440128D);
tmc4361A_writeInt(motorToIC(motor), TMC4361A_COVER_HIGH_WR, 0x80);
tmc4361A_writeInt(motorToIC(motor), TMC4361A_COVER_LOW_WR, 0x00010000);
tmc4361A_writeInt(motorToIC(motor), TMC4361A_COVER_HIGH_WR, 0xEC);
tmc4361A_writeInt(motorToIC(motor), TMC4361A_COVER_LOW_WR, 0x000100C3);
tmc4361A_writeInt(motorToIC(motor), TMC4361A_COVER_HIGH_WR, 0x90);
tmc4361A_writeInt(motorToIC(motor), TMC4361A_COVER_LOW_WR, 0x82029805);
/* open loop mode (p.120) */
tmc4361A_writeInt(motorToIC(motor), TMC4361A_STDBY_DELAY, 80); //num clk cycles (80 cycles = 5 us)
TMC4361A_FIELD_WRITE(motorToIC(motor), TMC4361A_SCALE_VALUES, TMC4361A_HOLD_SCALE_VAL_MASK, TMC4361A_HOLD_SCALE_VAL_SHIFT, 128);
TMC4361A_FIELD_WRITE(motorToIC(motor), TMC4361A_CURRENT_CONF, TMC4361A_HOLD_CURRENT_SCALE_EN_MASK, TMC4361A_HOLD_CURRENT_SCALE_EN_SHIFT, 1);
TMC4361A_FIELD_WRITE(motorToIC(motor), TMC4361A_CURRENT_CONF, TMC4361A_CLOSED_LOOP_SCALE_EN_MASK, TMC4361A_CLOSED_LOOP_SCALE_EN_SHIFT, 0);
// => SPI Wrapper
void tmc4361A_readWriteArray(uint8_t channel, uint8_t *data, size_t length)
{
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
SPI.transfer(data, length);
SPI.endTransaction();
}
// <= SPI Wrapper
Sorry for the long message. I hope I've added sufficient details but please ask if there's anything else I can add to help describe my issue.