10#if defined(ARDUINO_ARCH_RP2040) && defined(RP2040_SINGLE_WIRE_UART_PIN)
11 #include <hardware/gpio.h>
31#if TMCSTEPPER_SW_SERIAL
37 RXTX_pin(SW_RX_pin == SW_TX_pin ? SW_RX_pin : 0),
41 SoftwareSerial *SWSerialObj =
new SoftwareSerial(SW_RX_pin, SW_TX_pin);
42 SWSerial = SWSerialObj;
47 if (SWSerial !=
nullptr)
49 SWSerial->begin(baudrate);
52 #if HAS_HALF_DUPLEX_MODE
62 #if TMCSTEPPER_SW_SERIAL
63 #ifndef TMC2208_BAUDRATE
64 #define TMC2208_BAUDRATE 115200
73 GCONF_register.i_scale_analog = 1;
74 GCONF_register.internal_rsense = 0;
75 GCONF_register.en_spreadcycle = 0;
76 GCONF_register.multistep_filt = 1;
78 IHOLD_IRUN_register.iholddelay = 1;
80 TPOWERDOWN_register.sr = 20;
83 CHOPCONF_register.toff = 3;
84 CHOPCONF_register.hstrt = 5;
85 CHOPCONF_register.hend = 0;
86 CHOPCONF_register.tbl = 0;
87 CHOPCONF_register.vsense =
false;
88 CHOPCONF_register.mres = 0;
89 CHOPCONF_register.intpol =
true;
90 CHOPCONF_register.dedge =
false;
91 CHOPCONF_register.diss2g =
false;
92 CHOPCONF_register.diss2vs =
false;
95 PWMCONF_register.pwm_ofs = 36;
96 PWMCONF_register.pwm_grad = 0;
97 PWMCONF_register.pwm_freq = 1;
98 PWMCONF_register.pwm_autoscale =
true;
99 PWMCONF_register.pwm_autograd =
true;
100 PWMCONF_register.freewheel = 0;
101 PWMCONF_register.pwm_reg = 1;
102 PWMCONF_register.pwm_lim = 12;
116 GCONF(GCONF_register.sr);
130 for (uint8_t i = 0; i < len; i++) {
131 uint8_t currentByte = datagram[i];
132 for (uint8_t j = 0; j < 8; j++) {
133 if ((crc >> 7) ^ (currentByte & 0x01)) {
134 crc = (crc << 1) ^ 0x07;
139 currentByte = currentByte >> 1;
148 #if TMCSTEPPER_SW_SERIAL
149 if (SWSerial !=
nullptr) {
150 out = SWSerial->available();
170 #if TMCSTEPPER_SW_SERIAL
171 if (SWSerial !=
nullptr) {
184 #if TMCSTEPPER_SW_SERIAL
185 if (SWSerial !=
nullptr) {
186 out = SWSerial->read();
199 #if TMCSTEPPER_SW_SERIAL
200 if (SWSerial !=
nullptr) {
201 return SWSerial->write(data);
216 #if TMCSTEPPER_SW_SERIAL
217 if (SWSerial !=
nullptr) {
226 uint8_t datagram[] = {
TMC2208_SYNC,
slave_address, addr, (uint8_t)(regVal>>24), (uint8_t)(regVal>>16), (uint8_t)(regVal>>8), (uint8_t)(regVal>>0), 0x00};
228 datagram[len] =
calcCRC(datagram, len);
232 for (uint8_t i = 0; i<= len; i++) {
240#if defined(ARDUINO_ARCH_RP2040) && defined(RP2040_SINGLE_WIRE_UART_PIN)
242 #include <hardware/gpio.h>
247 static void _rp2040_sw_uart_write_byte(uint8_t
byte) {
248 constexpr uint32_t T = 9;
249 gpio_set_function(RP2040_SINGLE_WIRE_UART_PIN, GPIO_FUNC_SIO);
250 gpio_set_dir(RP2040_SINGLE_WIRE_UART_PIN, GPIO_OUT);
251 gpio_put(RP2040_SINGLE_WIRE_UART_PIN, 1);
253 gpio_put(RP2040_SINGLE_WIRE_UART_PIN, 0);
254 delayMicroseconds(T);
256 for (
int i = 0; i < 8; i++) {
257 gpio_put(RP2040_SINGLE_WIRE_UART_PIN, (
byte >> i) & 1);
258 delayMicroseconds(T);
261 gpio_put(RP2040_SINGLE_WIRE_UART_PIN, 1);
262 delayMicroseconds(T);
264 gpio_set_function(RP2040_SINGLE_WIRE_UART_PIN, GPIO_FUNC_UART);
271 const uint32_t _flush_t0 = micros();
274 if ((micros() - _flush_t0) > (uint32_t)timeout * 1000UL)
break;
277 #if HAS_HALF_DUPLEX_MODE
285 #if defined(ARDUINO_ARCH_RP2040) && defined(RP2040_SINGLE_WIRE_UART_PIN)
287 for (
int i = 0; i <= len; i++) _rp2040_sw_uart_write_byte(datagram[i]);
290 for (
int i = 0; i <= len; i++)
serial_write(datagram[i]);
293 #if HAS_HALF_DUPLEX_MODE
303 uint32_t _sync_t0 = micros();
304 uint32_t sync_target = (
static_cast<uint32_t
>(datagram[0])<<16) | 0xFF00 | datagram[2];
308 if ((micros() - _sync_t0) > (uint32_t)timeout * 1000UL) {
313 if (res < 0)
continue;
319 }
while (sync != sync_target);
323 uint32_t _body_t0 = micros();
326 for (uint8_t i = 0; i < 5; i++) {
327 if ((micros() - _body_t0) > (uint32_t)timeout * 1000UL) {
332 if (res < 0)
continue;
338 #if HAS_HALF_DUPLEX_MODE
351 constexpr uint8_t len = 3;
354 datagram[len] =
calcCRC(datagram, len);
355 uint64_t out = 0x00000000UL;
366 uint8_t out_datagram[] = {
367 static_cast<uint8_t
>(out>>56),
368 static_cast<uint8_t
>(out>>48),
369 static_cast<uint8_t
>(out>>40),
370 static_cast<uint8_t
>(out>>32),
371 static_cast<uint8_t
>(out>>24),
372 static_cast<uint8_t
>(out>>16),
373 static_cast<uint8_t
>(out>> 8),
374 static_cast<uint8_t
>(out>> 0)
376 uint8_t crc =
calcCRC(out_datagram, 7);
377 if ((crc !=
static_cast<uint8_t
>(out)) || crc == 0 ) {
398 FACTORY_CONF_register.sr = input;
399 write(FACTORY_CONF_register.address, FACTORY_CONF_register.sr);
407 VACTUAL_register.sr = input;
408 write(VACTUAL_register.address, VACTUAL_register.sr);
411 return VACTUAL_register.sr;
444 int16_t value = r.
cur_a;
445 if (value > 255) value -= 512;
451 int16_t value = r.
cur_b;
452 if (value > 255) value -= 512;
__attribute__((weak)) int TMC2208Stepper
#define HAS_HALF_DUPLEX_MODE
static constexpr uint8_t TMC2208_SYNC
void write(uint8_t, uint32_t)
static constexpr uint8_t replyDelay
static constexpr uint8_t abort_window
uint64_t _sendDatagram(uint8_t[], const uint8_t, uint16_t)
uint8_t calcCRC(uint8_t datagram[], uint8_t len)
void postWriteCommunication()
TMC2208Stepper(Stream *SerialPort, float RS, uint8_t addr, uint16_t mul_pin1, uint16_t mul_pin2)
void beginSerial(uint32_t)=delete
void preWriteCommunication()
void OTP_PROG(uint16_t input)
void preReadCommunication()
void postReadCommunication()
const uint8_t slave_address
static constexpr uint8_t max_retries
uint8_t serial_write(const uint8_t data)
static constexpr uint8_t TMC_READ
static constexpr uint8_t TMC_WRITE
#define pinMode(PIN, MODE)
#define digitalWrite(PIN, MODE)
static constexpr uint8_t address
static constexpr uint8_t address
uint8_t int16_t pwm_scale_auto
static constexpr uint8_t address
static constexpr uint8_t address
static constexpr uint8_t address
static constexpr uint8_t address