TMC5160 and Raspeberry PI
thalesfsp opened this issue · comments
Hi! I'm trying to follow this blog post, but applied to the TMC5160 BOB. I cloned the latest version of the API, and made a few adjustments in the code, but I'm having problems with the init
function.
The signature presented in the blog post, void TMC5130_init(unsigned char motor)
is different from the API void tmc5130_init(TMC5130TypeDef *tmc5130, uint8_t channel, ConfigurationTypeDef *config, const int32_t *registerResetState)
I've limited knowledge on C, and in electronics. I searched around the web for examples of this new signature, and how to use/call that, but unfortunately did not find.
Follow my current project.c
file:
#include "SPI.h"
#include "tmc/ic/TMC5160/TMC5160.h"
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
static void myStateDemoMachine(int steps, int velocity);
int main(int argc, char **argv)
{
// start SPI
printf("Initialize SPI..\n");
SPI_init();
printf("..done\n");
remove("demo.s"); // exit demo mode
int value;
switch(argv[1][0]) // process arguments, first argument is the command, others are values
{
case 'i': // initialize
printf("Initialize driver..\n");
tmc5160_init(0);
break;
case 'r': // rotate
printf("Rotate with %ipps..\n", atoi(argv[2]));
tmc5160_rotate(0, atoi(argv[2]));
break;
case '0': //stop
printf("Stop motor..\n");
tmc5160_rotate(0, 0);
break;
case 't': // move to position
printf("Move to absolute absolute %d with velocity %ipps..\n", atoi(argv[2]), atoi(argv[3]));
tmc5160_left(0,0); // stop motor
tmc5160_writeInt(0,TMC5160_VMAX, abs(atoi(argv[3]))); // set velocity
// tmc5160_moveTo(TMC5160TypeDef *tmc5160, int32_t position, uint32_t velocityMax)
tmc5160_moveTo(0, 0, atoi(argv[2])); // set target
break;
case 'b': // move by number of steps
printf("Move to by %d steps with velocity %ipps..\n", atoi(argv[2]), atoi(argv[3]));
tmc5160_left(0,0); // stop motor
tmc5160_writeInt(0,TMC5160_VMAX, abs(atoi(argv[3]))); // set velocity
tmc5160_moveBy(0, 0, atoi(argv[2])); // set target
break;
case 'g': // get register value
value = tmc5160_readInt(0,atoi(argv[2])); //read from address
printf("Read from address 0x%2x =%i[int] = %08x[hex] = %f[double])\n", atoi(argv[2]), (int) value, (int) value, (double) value);
break;
case 's': // set register value
tmc5160_writeInt(0,atoi(argv[2]), atoi(argv[3])); //write to address
printf("Write to address 0x%2x<=%i[int] = %08x[hex] = %f[double])\n", atoi(argv[2]), (int) atoi(argv[3]), (int) atoi(argv[3]), (double) atoi(argv[3]));
break;
case 'd': // start demo
printf("Demo: Move back and forth by %d steps with velocity %ipps..\n", atoi(argv[2]), atoi(argv[3]));
close(open("demo.s", O_RDWR | O_CREAT, 0777)); // generate semaphore-file
while(access("demo.s", F_OK ) != -1) // as long as demo semaphore-file exists
{
myStateDemoMachine(atoi(argv[2]),abs(atoi(argv[3]))); // call demo code
usleep(500);
}
break;
default:
printf("Unknown command\n");
break;
}
// end SPI
printf("De-initialize SPI..\n");
SPI_deinit();
printf("..done\n");
}
enum { DEMO_STATE_INIT, DEMO_STATE_MOVE_RIGHT, DEMO_STATE_WAIT_RIGHT, DEMO_STATE_MOVE_LEFT, DEMO_STATE_WAIT_LEFT};
static void myStateDemoMachine(int steps, int velocity)
{ // simple state for moving back and forth
static int state = DEMO_STATE_INIT;
static int nextState = DEMO_STATE_INIT;
switch(state)
{
case DEMO_STATE_INIT:
tmc5160_moveBy(0, 0, 0);
tmc5160_writeInt(0,TMC5160_VMAX, velocity);
nextState = DEMO_STATE_MOVE_RIGHT;
break;
case DEMO_STATE_MOVE_RIGHT:
printf("Move right by %d steps with velocity %ipps..\n", steps, velocity);
tmc5160_moveBy(0, 0,steps);
nextState = DEMO_STATE_WAIT_RIGHT;
break;
case DEMO_STATE_WAIT_RIGHT:
usleep(20000);
if(tmc5160_readInt(0,TMC5160_RAMPSTAT) & (1<<9)) // if bit 9 in RAMPSTAT is set (position_reached)
{
nextState = DEMO_STATE_MOVE_LEFT;
}
break;
case DEMO_STATE_MOVE_LEFT:
printf("Move left by %d steps with velocity %ipps..\n", -steps, velocity);
tmc5160_moveBy(0, 0,-steps);
nextState = DEMO_STATE_WAIT_LEFT;
break;
case DEMO_STATE_WAIT_LEFT:
usleep(20000);
if(tmc5160_readInt(0,TMC5160_RAMPSTAT) & (1<<9)) // if bit 9 in RAMPSTAT is set (position_reached)
{
nextState = DEMO_STATE_MOVE_RIGHT;
}
break;
}
state = nextState;
}
Thank you!
Hi,
the source code for the Raspberry 3B has, per default, nothing to do with the TMC-API. It has its own coherent project, hence the different functions and function signatures. So you have to decide if you want to use the functions presented there or if you want to switch to using the TMC-API, which is possible of course.
If you want to use the TMC-API:
The TMC5160TypeDef
is just a structure for storing all neccessary information needed by the API (for e.g. register shadowing). You can look at it like a logical instance of an IC. You can look inside this structure, but you dont need to. The API takes care of it. Same with ConfigurationTypeDef
instances.
So what you have to do is basically create instances of TMC5160TypeDef
and ConfigurationTypeDef
(one each for every individual IC) somewhere in your project.c file, pass both as pointers to the tmc5130_init
function and give it a channel number. You can assign these numbers arbitrarily, they are used to differentiate between communications channels later on. If you just have one channel, in this case one SPI channel, you can just use 0.
As registerResetState
you can just use tmc5160_defaultRegisterResetState
provided by the TMC-API.
After that, just implement the function tmc5160_readWriteArray(...)
, which is needed by the API to read / write using your SPI.
A reference implementation for the TMC5160-EVAL can be found here. This can be applied to the TMC5160-BOB similarly.
Hello, @Lionheart1810! Thank you for your help! Can you help one more time providing me example of instances for both TMC5160TypeDef
and ConfigurationTypeDef?
What is required to be defined in these both instances? Finally, I would like to learn more about it. Would you be available for 30mins to join a chat and review my case? Cheers!
Example instances are already in the linked reference implementation. They are created as simple as
ConfigurationTypeDef config;
TMC5160TypeDef TMC5160;
After creation, you don't actually have to fiddle with its contents at all. Generally speaking, ConfigurationTypeDef
offers state information and register shadowing to your IC instance.
Also, remember to take care of some registers you might need to set to certain values to get your specific setup running.
Yes I guess I can take some time to look over it. Which platform though?
@Lionheart1810 I have Keybase, Zoom and Google Meet. You choose. How can I DM you? Email? Cheers and really thank you for your time and help, I appreciate that! Cheers!
Send me an E-Mail to kugis@trinamic.com
Thank you! I will reach you! Cheers!
Hello @Lionheart1810! I did message you :)