Skip to content

Commit

Permalink
Merge pull request #83 from pvginkel/esp-idf
Browse files Browse the repository at this point in the history
Added support for ESP-IDF projects.
  • Loading branch information
peterpolidoro authored Dec 27, 2024
2 parents cdd729a + cdff6e9 commit b31fe7a
Show file tree
Hide file tree
Showing 12 changed files with 275 additions and 21 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/build_examples_esp_idf_project.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Build ESP-IDF example project

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4
- name: esp-idf build
uses: espressif/esp-idf-ci-action@v1
with:
esp_idf_version: v5.3.2
target: esp32
path: examples/ESPIDFExample
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
idf_component_register(
SRC_DIRS "src/TMC2209"
INCLUDE_DIRS "src"
REQUIRES arduino-esp32
)
5 changes: 5 additions & 0 deletions examples/ESPIDFExample/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/build
/.vscode
/managed_components
/sdkconfig
/dependencies.lock
10 changes: 10 additions & 0 deletions examples/ESPIDFExample/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly

cmake_minimum_required(VERSION 3.16)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)

project(idf_project_example)
8 changes: 8 additions & 0 deletions examples/ESPIDFExample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
This folder contains a bare bones functional ESP-IDF project.

You can create one using the **ESP-IDF: New Project** command in
Visual Studio code, or use this one as a basis. If you do use this one
as a basis for your own project, review the `.gitignore` file as it
excludes files you would not want to exclude in a normal project.
Normally only the `managed_components` and `build` folders would be
excluded from version control.
6 changes: 6 additions & 0 deletions examples/ESPIDFExample/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FILE(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)

idf_component_register(
SRCS ${SOURCES}
INCLUDE_DIRS "."
)
5 changes: 5 additions & 0 deletions examples/ESPIDFExample/main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dependencies:
TMC2209:
path: ../../..
# Alternatively you can point this directly at the GitHub repository:
# git: https://github.com/janelia-arduino/TMC2209.git
129 changes: 129 additions & 0 deletions examples/ESPIDFExample/main/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#include <TMC2209.h>

// This example will not work on Arduino boards without HardwareSerial ports,
// such as the Uno, Nano, and Mini.
//
// See this reference for more details:
// https://www.arduino.cc/reference/en/language/functions/communication/serial/

HardwareSerial & serial_stream = Serial1;

const long SERIAL_BAUD_RATE = 115200;
const int DELAY = 2000;

// Instantiate TMC2209
TMC2209 stepper_driver;

extern "C" void app_main()
{
Serial.begin(SERIAL_BAUD_RATE);

stepper_driver.setup(serial_stream);

Serial.println("*************************");
Serial.println("getSettings()");
TMC2209::Settings settings = stepper_driver.getSettings();
Serial.print("settings.is_communicating = ");
Serial.println(settings.is_communicating);
Serial.print("settings.is_setup = ");
Serial.println(settings.is_setup);
Serial.print("settings.software_enabled = ");
Serial.println(settings.software_enabled);
Serial.print("settings.microsteps_per_step = ");
Serial.println(settings.microsteps_per_step);
Serial.print("settings.inverse_motor_direction_enabled = ");
Serial.println(settings.inverse_motor_direction_enabled);
Serial.print("settings.stealth_chop_enabled = ");
Serial.println(settings.stealth_chop_enabled);
Serial.print("settings.standstill_mode = ");
switch (settings.standstill_mode)
{
case TMC2209::NORMAL:
Serial.println("normal");
break;
case TMC2209::FREEWHEELING:
Serial.println("freewheeling");
break;
case TMC2209::STRONG_BRAKING:
Serial.println("strong_braking");
break;
case TMC2209::BRAKING:
Serial.println("braking");
break;
}
Serial.print("settings.irun_percent = ");
Serial.println(settings.irun_percent);
Serial.print("settings.irun_register_value = ");
Serial.println(settings.irun_register_value);
Serial.print("settings.ihold_percent = ");
Serial.println(settings.ihold_percent);
Serial.print("settings.ihold_register_value = ");
Serial.println(settings.ihold_register_value);
Serial.print("settings.iholddelay_percent = ");
Serial.println(settings.iholddelay_percent);
Serial.print("settings.iholddelay_register_value = ");
Serial.println(settings.iholddelay_register_value);
Serial.print("settings.automatic_current_scaling_enabled = ");
Serial.println(settings.automatic_current_scaling_enabled);
Serial.print("settings.automatic_gradient_adaptation_enabled = ");
Serial.println(settings.automatic_gradient_adaptation_enabled);
Serial.print("settings.pwm_offset = ");
Serial.println(settings.pwm_offset);
Serial.print("settings.pwm_gradient = ");
Serial.println(settings.pwm_gradient);
Serial.print("settings.cool_step_enabled = ");
Serial.println(settings.cool_step_enabled);
Serial.print("settings.analog_current_scaling_enabled = ");
Serial.println(settings.analog_current_scaling_enabled);
Serial.print("settings.internal_sense_resistors_enabled = ");
Serial.println(settings.internal_sense_resistors_enabled);
Serial.println("*************************");
Serial.println();

Serial.println("*************************");
Serial.println("hardwareDisabled()");
bool hardware_disabled = stepper_driver.hardwareDisabled();
Serial.print("hardware_disabled = ");
Serial.println(hardware_disabled);
Serial.println("*************************");
Serial.println();

Serial.println("*************************");
Serial.println("getStatus()");
TMC2209::Status status = stepper_driver.getStatus();
Serial.print("status.over_temperature_warning = ");
Serial.println(status.over_temperature_warning);
Serial.print("status.over_temperature_shutdown = ");
Serial.println(status.over_temperature_shutdown);
Serial.print("status.short_to_ground_a = ");
Serial.println(status.short_to_ground_a);
Serial.print("status.short_to_ground_b = ");
Serial.println(status.short_to_ground_b);
Serial.print("status.low_side_short_a = ");
Serial.println(status.low_side_short_a);
Serial.print("status.low_side_short_b = ");
Serial.println(status.low_side_short_b);
Serial.print("status.open_load_a = ");
Serial.println(status.open_load_a);
Serial.print("status.open_load_b = ");
Serial.println(status.open_load_b);
Serial.print("status.over_temperature_120c = ");
Serial.println(status.over_temperature_120c);
Serial.print("status.over_temperature_143c = ");
Serial.println(status.over_temperature_143c);
Serial.print("status.over_temperature_150c = ");
Serial.println(status.over_temperature_150c);
Serial.print("status.over_temperature_157c = ");
Serial.println(status.over_temperature_157c);
Serial.print("status.current_scaling = ");
Serial.println(status.current_scaling);
Serial.print("status.stealth_chop_mode = ");
Serial.println(status.stealth_chop_mode);
Serial.print("status.standstill = ");
Serial.println(status.standstill);
Serial.println("*************************");
Serial.println();

Serial.println();
delay(DELAY);
}
2 changes: 2 additions & 0 deletions examples/ESPIDFExample/sdkconfig.defaults
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Required by the android-esp32 component.
CONFIG_FREERTOS_HZ=1000
5 changes: 5 additions & 0 deletions idf_component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dependencies:
idf:
version: ">=5.3.0"
arduino-esp32:
version: "*"
11 changes: 11 additions & 0 deletions src/TMC2209.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,16 @@ class TMC2209
void setAllCurrentValues(uint8_t run_current_percent,
uint8_t hold_current_percent,
uint8_t hold_delay_percent);
void setRMSCurrent(uint16_t mA,
float rSense,
float holdMultiplier = 0.5f);

void enableDoubleEdge();
void disableDoubleEdge();

void enableVSense();
void disableVSense();

void enableInverseMotorDirection();
void disableInverseMotorDirection();

Expand Down Expand Up @@ -279,6 +285,9 @@ class TMC2209
const static uint8_t STEPPER_DRIVER_FEATURE_OFF = 0;
const static uint8_t STEPPER_DRIVER_FEATURE_ON = 1;

const static uint8_t MAX_READ_RETRIES = 5;
const static uint32_t READ_RETRY_DELAY_MS = 20;

// Datagrams
const static uint8_t WRITE_READ_REPLY_DATAGRAM_SIZE = 8;
const static uint8_t DATA_SIZE = 4;
Expand Down Expand Up @@ -504,6 +513,8 @@ class TMC2209
const static uint8_t MRES_001 = 0b1000;
const static uint8_t DOUBLE_EDGE_DISABLE = 0;
const static uint8_t DOUBLE_EDGE_ENABLE = 1;
const static uint8_t VSENSE_DISABLE = 0;
const static uint8_t VSENSE_ENABLE = 1;

const static size_t MICROSTEPS_PER_STEP_MIN = 1;
const static size_t MICROSTEPS_PER_STEP_MAX = 256;
Expand Down
89 changes: 68 additions & 21 deletions src/TMC2209/TMC2209.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,30 @@ void TMC2209::setAllCurrentValues(uint8_t run_current_percent,
writeStoredDriverCurrent();
}

void TMC2209::setRMSCurrent(uint16_t mA,
float rSense,
float holdMultiplier)
{
// Taken from https://github.com/teemuatlut/TMCStepper/blob/74e8e6881adc9241c2e626071e7328d7652f361a/src/source/TMCStepper.cpp#L41.

uint8_t CS = 32.0*1.41421*mA/1000.0*(rSense+0.02)/0.325 - 1;
// If Current Scale is too low, turn on high sensitivity R_sense and calculate again
if (CS < 16) {
enableVSense();
CS = 32.0*1.41421*mA/1000.0*(rSense+0.02)/0.180 - 1;
} else { // If CS >= 16, turn off high_sense_r
disableVSense();
}

if (CS > 31) {
CS = 31;
}

driver_current_.irun = CS;
driver_current_.ihold = CS*holdMultiplier;
writeStoredDriverCurrent();
}

void TMC2209::enableDoubleEdge()
{
chopper_config_.double_edge = DOUBLE_EDGE_ENABLE;
Expand All @@ -235,6 +259,18 @@ void TMC2209::disableDoubleEdge()
writeStoredChopperConfig();
}

void TMC2209::enableVSense()
{
chopper_config_.vsense = VSENSE_ENABLE;
writeStoredChopperConfig();
}

void TMC2209::disableVSense()
{
chopper_config_.vsense = VSENSE_DISABLE;
writeStoredChopperConfig();
}

void TMC2209::enableInverseMotorDirection()
{
global_config_.shaft = 1;
Expand Down Expand Up @@ -880,32 +916,43 @@ uint32_t TMC2209::read(uint8_t register_address)
read_request_datagram.rw = RW_READ;
read_request_datagram.crc = calculateCrc(read_request_datagram, READ_REQUEST_DATAGRAM_SIZE);

sendDatagramBidirectional(read_request_datagram, READ_REQUEST_DATAGRAM_SIZE);

uint32_t reply_delay = 0;
while ((serialAvailable() < WRITE_READ_REPLY_DATAGRAM_SIZE) and
(reply_delay < REPLY_DELAY_MAX_MICROSECONDS))
for (uint8_t retry = 0; retry < MAX_READ_RETRIES; retry++)
{
delayMicroseconds(REPLY_DELAY_INC_MICROSECONDS);
reply_delay += REPLY_DELAY_INC_MICROSECONDS;
}
sendDatagramBidirectional(read_request_datagram, READ_REQUEST_DATAGRAM_SIZE);

if (reply_delay >= REPLY_DELAY_MAX_MICROSECONDS)
{
return 0;
}
uint32_t reply_delay = 0;
while ((serialAvailable() < WRITE_READ_REPLY_DATAGRAM_SIZE) and
(reply_delay < REPLY_DELAY_MAX_MICROSECONDS))
{
delayMicroseconds(REPLY_DELAY_INC_MICROSECONDS);
reply_delay += REPLY_DELAY_INC_MICROSECONDS;
}

uint64_t byte;
uint8_t byte_count = 0;
WriteReadReplyDatagram read_reply_datagram;
read_reply_datagram.bytes = 0;
for (uint8_t i=0; i<WRITE_READ_REPLY_DATAGRAM_SIZE; ++i)
{
byte = serialRead();
read_reply_datagram.bytes |= (byte << (byte_count++ * BITS_PER_BYTE));
if (reply_delay >= REPLY_DELAY_MAX_MICROSECONDS)
{
return 0;
}

uint64_t byte;
uint8_t byte_count = 0;
WriteReadReplyDatagram read_reply_datagram;
read_reply_datagram.bytes = 0;
for (uint8_t i=0; i<WRITE_READ_REPLY_DATAGRAM_SIZE; ++i)
{
byte = serialRead();
read_reply_datagram.bytes |= (byte << (byte_count++ * BITS_PER_BYTE));
}

auto crc = calculateCrc(read_reply_datagram, WRITE_READ_REPLY_DATAGRAM_SIZE);
if (crc == read_reply_datagram.crc)
{
return reverseData(read_reply_datagram.data);
}

delay(READ_RETRY_DELAY_MS);
}

return reverseData(read_reply_datagram.data);
return 0;
}

uint8_t TMC2209::percentToCurrentSetting(uint8_t percent)
Expand Down

0 comments on commit b31fe7a

Please sign in to comment.