Open FFBoard
Open source force feedback firmware
TMCDebugBridge.cpp
Go to the documentation of this file.
1/*
2 * TMCDebugBridge.cpp
3 *
4 * Created on: 23.01.2020
5 * Author: Yannick
6 */
7
8#include <TMCDebugBridge.h>
9#ifdef TMCDEBUG
10#include "ledEffects.h"
11#include "voltagesense.h"
12#include "cdc_device.h"
13
14// Change this
16 .name = "TMC Debug Bridge" ,
17 .id=CLSID_MAIN_TMCDBG, //11
18 .visibility = ClassVisibility::debug
19 };
20// Copy this to your class for identification
22 return info;
23}
24
25uint8_t TMCDebugBridge::checksum(std::vector<uint8_t> *buffer,uint8_t len){
26 uint16_t sum = 0;
27 for(uint8_t i = 0; i < len ;i++){
28 sum+= (*buffer)[i];
29 }
30 sum = sum % 256;
31 return sum;
32}
33
35 //CommandHandler::registerCommands();
36 registerCommand("reg", TMCDebugBridge_commands::reg, "Read or write a TMC register at adr",CMDFLAG_GETADR | CMDFLAG_SETADR);
37 registerCommand("torque", TMCDebugBridge_commands::torque, "Change torque and enter torque mode",CMDFLAG_GET | CMDFLAG_SET);
38 registerCommand("pos", TMCDebugBridge_commands::pos, "Change pos and enter pos mode",CMDFLAG_GET | CMDFLAG_SET);
39 registerCommand("openloopspeed", TMCDebugBridge_commands::openloopspeed, "Move openloop (current controlled). adr=strength;val=speed",CMDFLAG_SETADR | CMDFLAG_SET);
40 registerCommand("velocity", TMCDebugBridge_commands::velocity, "Change velocity and enter velocity mode",CMDFLAG_GET | CMDFLAG_SET);
41 registerCommand("mode", TMCDebugBridge_commands::mode, "Change motion mode",CMDFLAG_GET | CMDFLAG_SET);
42 registerCommand("openloopspeedpwm", TMCDebugBridge_commands::openloopspeedpwm, "Move openloop raw PWM. adr=strength;val=speed",CMDFLAG_SETADR | CMDFLAG_SET);
43}
44
45
46
47CommandStatus TMCDebugBridge::command(const ParsedCommand& cmd,std::vector<CommandReply>& replies){
48 switch(static_cast<TMCDebugBridge_commands>(cmd.cmdId)){
50 if(cmd.type == CMDtype::get){
51 replies.emplace_back(drv->getTorque());
52 }else if(cmd.type == CMDtype::set){
53 if(drv->getState() != TMC_ControlState::Running){
54 drv->startMotor();
55 }
56 drv->turn(cmd.val);
57 }else{
58 return CommandStatus::ERR;
59 }
60 break;
61
63 if(cmd.type == CMDtype::get){
64 replies.emplace_back(drv->getPos());
65 }else if(cmd.type == CMDtype::set){
66 drv->setTargetPos(cmd.val);
67 }else{
68 return CommandStatus::ERR;
69 }
70 break;
71
73 if(cmd.type == CMDtype::set){
74 drv->setOpenLoopSpeedAccel(cmd.val,100);
75 }else if(cmd.type == CMDtype::setat){
76 drv->runOpenLoop(cmd.adr,0,cmd.val,10,true);
77 }else{
78 return CommandStatus::ERR;
79 }
80 break;
81
83 if(cmd.type == CMDtype::set){
84 drv->setOpenLoopSpeedAccel(cmd.val,100);
85 }else if(cmd.type == CMDtype::setat){
86 drv->runOpenLoop(cmd.adr,0,cmd.val,10,false);
87 }else{
88 return CommandStatus::ERR;
89 }
90 break;
91
93 if(cmd.type == CMDtype::get){
94 replies.emplace_back(drv->getVelocity());
95 }else if(cmd.type == CMDtype::set){
96 drv->setTargetVelocity(cmd.val);
97 }else{
98 return CommandStatus::ERR;
99 }
100 break;
101
103 if(cmd.type == CMDtype::get){
104 replies.emplace_back((uint8_t)drv->getMotionMode());
105 }else if(cmd.type == CMDtype::set && cmd.val < (uint8_t)MotionMode::NONE){
106 drv->setMotionMode(MotionMode(cmd.val));
107 drv->startMotor();
108 }else{
109 replies.emplace_back("stop=0,torque=1,velocity=2,position=3,prbsflux=4,prbstorque=5,prbsvelocity=6,uqudext=8,encminimove=9");
110 }
111 break;
112
114 if(cmd.type == CMDtype::getat){
115 replies.emplace_back(drv->readReg(cmd.val));
116 }else if(cmd.type == CMDtype::setat){
117 drv->writeReg(cmd.adr,cmd.val);
118 }else{
119 return CommandStatus::ERR;
120 }
121 break;
122 default:
124 }
125 return CommandStatus::OK;
126}
127
128void TMCDebugBridge::sendCdc(char* dat, uint32_t len){
129 tud_cdc_n_write(0, dat, len);
131}
132
133void TMCDebugBridge::cdcRcv(char* Buf, uint32_t *Len){
134 std::vector<uint8_t> dat;
135 dat.assign(Buf,Buf+*Len);
136 if(*Len == 9 && *Buf == 1){
137 uint8_t crc = checksum(&dat,*Len-1);
138
139 //uint8_t id = dat[0];
140 uint8_t cmd = dat[1];
141 uint8_t addr = dat[2];
142
143 if(dat[dat.size()-1] != crc){
144 //fail
145 return;
146 }
147
148 if(cmd == 148){ // read reg
149 uint8_t buf[4];
150 uint8_t rpl[4] = {2,1,0x64,0x94};
151// tmcReadRegRaw(addr, buf);
152 uint32_t bufI = drv->readReg(addr);
153 bufI = __REV(bufI);
154 memcpy(buf,&bufI,4);
155 std::vector<uint8_t> rx_data;
156
157 rx_data.insert(rx_data.begin(), &rpl[0],&rpl[4]);
158 rx_data.insert(rx_data.end(),buf, buf+4);
159 rx_data.push_back(checksum(&rx_data,8));
160 sendCdc((char*)rx_data.data(), 9);
161
162 }else if(cmd == 146){ // write
163
164 uint32_t ndat;
165 memcpy(&ndat,Buf+4,4);
166 drv->writeReg(addr,__REV(ndat));
167 std::vector<uint8_t> repl({2,1,0x64,0x92,dat[3],dat[4],dat[5],dat[6]});
168 repl.push_back(checksum(&repl,8));
169 sendCdc((char*)repl.data(), 9);
170 }else if(cmd == 143){
171 std::vector<uint8_t> repl(8,0);
172 if(addr == 3){
173 repl.assign({2,1,40,0x8f,0,0,0,2});
174 }else if(addr == 4){
175 repl.assign({2,1,40,0x8f,2,6,2,2});
176 }
177 repl.push_back(checksum(&repl,8));
178 sendCdc((char*)repl.data(), 9);
179 }else if(cmd == 10){ // Get global parameter.
180 std::vector<uint8_t> repl({2,1,64,0x0A,0,0,0,0});
181 if(addr == 5){
182 repl[7] = 2; // hwid
183 }else if(addr == 2){
184 repl[7] = 1; // active
185 }
186 repl.push_back(checksum(&repl,8));
187 sendCdc((char*)repl.data(), 9);
188 }else if(cmd == 0x0F){ // Get input
189 std::vector<uint8_t> repl({2,1,64,0x0F,0,0,0,0});
190 if(addr == 5){ // Voltage
191 uint16_t v = getIntV()/100;
192 repl[7] = v & 0xff;
193 repl[6] = (v>>8) & 0xff;
194 }
195 repl.push_back(checksum(&repl,8));
196 sendCdc((char*)repl.data(), 9);
197 }else if(cmd == 0x88){
198 char version[9] = {2,'0','0','1','5','V','3','0','7'}; // Version string
199 if(addr == 0){
200 sendCdc(version, 9);
201 }else if(addr == 1){ // Version binary
202 // module version high
203 uint32_t tmpVal = (uint8_t) version[1] - '0';
204 std::vector<uint8_t> repl = {2,0x01,0x64,0x88,0x00,0,0,0};
205 tmpVal *= 10;
206 tmpVal += (uint8_t) version[2] - '0';
207 repl[4] = tmpVal;
208
209 // module version low
210 tmpVal = (uint8_t) version[3] - '0';
211 tmpVal *= 10;
212 tmpVal += (uint8_t) version[4] - '0';
213 repl[5] = tmpVal;
214
215 // fw version high
216 repl[6] = (uint8_t) version[6] - '0';
217
218 // fw version low
219 tmpVal = (uint8_t) version[7] - '0';
220 tmpVal *= 10;
221 tmpVal += (uint8_t) version[8] - '0';
222 repl[7] = tmpVal;
223 repl.push_back(checksum(&repl,8));
224 sendCdc((char*)repl.data(), 9);
225 }
226
227 }
228 }else{
229 FFBoardMain::cdcRcv(Buf, Len);
230 }
231}
232
233
234
235
237
238 TMC4671MainConfig tmcconf;
240
241 this->drv = std::make_unique<TMC_1>();
242 drv->conf = tmcconf;
243 drv->setAddress(1);
244 //drv->setPids(tmcpids); // load some basic pids
245 drv->restoreFlash(); // before initialize!
246 drv->setLimits(tmclimits);
247 drv->setEncoderType(EncoderType_TMC::NONE); // Set encoder to none to prevent alignment
248 //drv->initialize();
249 drv->Start();
250 drv->enablePin.set();
251 //drv->stop();
252}
253
255 HAL_GPIO_WritePin(DRV_ENABLE_GPIO_Port,DRV_ENABLE_Pin,GPIO_PIN_RESET);
256}
257
258#endif
CommandStatus
uint8_t crc
MotionMode
Definition: TMC4671.h:51
uint32_t tud_cdc_n_write(uint8_t itf, void const *buffer, uint32_t bufsize)
Definition: cdc_device.c:171
static TU_ATTR_ALWAYS_INLINE uint32_t tud_cdc_write_flush(void)
Definition: cdc_device.h:175
void registerCommand(const char *cmd, const ID cmdid, const char *help=nullptr, uint32_t flags=0)
virtual void cdcRcv(char *Buf, uint32_t *Len)
Definition: FFBoardMain.cpp:32
virtual ~TMCDebugBridge()
const ClassIdentifier getInfo()
uint8_t checksum(std::vector< uint8_t > *buffer, uint8_t len)
CommandStatus command(const ParsedCommand &cmd, std::vector< CommandReply > &replies)
static void sendCdc(char *dat, uint32_t len)
const TMC4671Limits tmclimits
void cdcRcv(char *Buf, uint32_t *Len)
std::unique_ptr< TMC4671 > drv
static ClassIdentifier info
uint8_t const * buffer
Definition: midi_device.h:100
static void * memcpy(void *dst, const void *src, size_t n)
Definition: ringbuffer.c:8
const char * name
uint32_t cmdId
int32_t getIntV()