Skip to content

Commit

Permalink
feat(esp_simplefoc): esp_simplefoc component version update. fix #392
Browse files Browse the repository at this point in the history
  • Loading branch information
YanKE01 committed Oct 8, 2024
1 parent e1ee3d1 commit 8f2f077
Show file tree
Hide file tree
Showing 12 changed files with 422 additions and 73 deletions.
6 changes: 6 additions & 0 deletions components/motor/esp_simplefoc/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# ChangeLog

## v1.0.0 - 2024-9-20
### Enhancements:
* FOC:
* MT6701 encoder supports I2C mode.
* Modify the ledc source clock of ESP32C6 and ESP32H2 to auto.
* Version maintenance.

## v0.2.0 - 2024-7-5
### Enhancements:
Expand Down
17 changes: 17 additions & 0 deletions components/motor/esp_simplefoc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,25 @@ Features:
5. Use IQMath to greatly accelerate Foc operations.


### Add component to your project

Please use the component manager command `add-dependency` to add the `esp_simplefoc` to your project's dependency, during the `CMake` step the component will be downloaded automatically

```
idf.py add-dependency "espressif/esp_simplefoc=*"
```

Alternatively, you can create `idf_component.yml`. More is in [Espressif's documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html).

### User guide

Please refer to:https://docs.espressif.com/projects/esp-iot-solution/zh_CN/latest/motor/foc/esp_simplefoc.html


### Usage Considerations

1. The configTICK_RATE_HZ of Freertos must be set to 1000. If it is not set, a motor exception may occur.

### License

esp_simplefoc is licensed under the Apache License, see license.txt for more information.
2 changes: 1 addition & 1 deletion components/motor/esp_simplefoc/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 0.2.0
version: 1.0.0
targets:
- esp32
- esp32s2
Expand Down
170 changes: 110 additions & 60 deletions components/motor/esp_simplefoc/port/angle_sensor/mt6701.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -52,6 +52,14 @@ MT6701::MT6701(spi_host_device_t spi_host, gpio_num_t sclk_io, gpio_num_t miso_i
is_installed = false;
}

MT6701::MT6701(i2c_port_t i2c_port, gpio_num_t sclk_io, gpio_num_t miso_io)
{
_i2c_port = i2c_port;
_sclk_io = sclk_io;
_miso_io = miso_io;
is_installed = false;
}

MT6701::~MT6701()
{
if (is_installed) {
Expand All @@ -63,46 +71,76 @@ void MT6701::init()
{
esp_err_t ret;

/*!< Configuration for the spi bus */
spi_bus_config_t buscfg = {
.mosi_io_num = _mosi_io,
.miso_io_num = _miso_io,
.sclk_io_num = _sclk_io,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 1000,
};

ret = spi_bus_initialize(_spi_host, &buscfg, SPI_DMA_CH_AUTO);
ESP_RETURN_ON_FALSE(ret == ESP_OK,, TAG, "SPI bus init fail");

spi_device_interface_config_t dev_cfg = {
.command_bits = 0,
.address_bits = 0,
.dummy_bits = 0,
.mode = 3,
.clock_speed_hz = 4000000,
.spics_io_num = _cs_io,
.flags = 0,
.queue_size = 1,
.pre_cb = NULL,
.post_cb = NULL,
};

ret = spi_bus_add_device(_spi_host, &dev_cfg, &spi_device);
ESP_RETURN_ON_FALSE(ret == ESP_OK,, TAG, "SPI bus add device fail");

is_installed = true;
if (_spi_host != SPI_HOST_MAX) {
// Configuration for the spi bus
spi_bus_config_t buscfg = {
.mosi_io_num = _mosi_io,
.miso_io_num = _miso_io,
.sclk_io_num = _sclk_io,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 1000,
};

ret = spi_bus_initialize(_spi_host, &buscfg, SPI_DMA_CH_AUTO);
ESP_RETURN_ON_FALSE(ret == ESP_OK,, TAG, "SPI bus init fail");

spi_device_interface_config_t dev_cfg = {
.command_bits = 0,
.address_bits = 0,
.dummy_bits = 0,
.mode = 3,
.clock_speed_hz = 4000000,
.spics_io_num = _cs_io,
.flags = 0,
.queue_size = 1,
.pre_cb = NULL,
.post_cb = NULL,
};

ret = spi_bus_add_device(_spi_host, &dev_cfg, &spi_device);
ESP_RETURN_ON_FALSE(ret == ESP_OK,, TAG, "SPI bus add device fail");

is_installed = true;
} else if (_i2c_port != I2C_NUM_MAX) {
// Configuration for the i2c bus
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = _miso_io,
.scl_io_num = _sclk_io,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
};
i2c_config.master.clk_speed = 400 * 1000;

ret = i2c_param_config(_i2c_port, &i2c_config);
ESP_RETURN_ON_FALSE(ret == ESP_OK,, TAG, "I2C config fail");

ret = i2c_driver_install(_i2c_port, i2c_config.mode, 0, 0, 0);
ESP_RETURN_ON_FALSE(ret == ESP_OK,, TAG, "I2C install fail");

is_installed = true;
} else {
is_installed = false;
}

}

void MT6701::deinit()
{
esp_err_t ret;
ret = spi_bus_remove_device(spi_device);
ESP_RETURN_ON_FALSE(ret == ESP_OK,, TAG, "SPI remove device fail");
ret = spi_bus_free(_spi_host);
ESP_RETURN_ON_FALSE(ret == ESP_OK,, TAG, "SPI free fail");
is_installed = false;

if (_spi_host != SPI_HOST_MAX) {
ret = spi_bus_remove_device(spi_device);
ESP_RETURN_ON_FALSE(ret == ESP_OK,, TAG, "SPI remove device fail");
ret = spi_bus_free(_spi_host);
ESP_RETURN_ON_FALSE(ret == ESP_OK,, TAG, "SPI free fail");
is_installed = false;
} else if (_i2c_port != I2C_NUM_MAX) {
ret = i2c_driver_delete(_i2c_port);
ESP_RETURN_ON_FALSE(ret == ESP_OK,, TAG, "I2C del fail");
is_installed = false;
}
}

float MT6701::getSensorAngle()
Expand All @@ -111,29 +149,41 @@ float MT6701::getSensorAngle()
static float angle = 0.0;
static float previous_angle = 0.0;

spi_transaction_t spi_transaction = {
.flags = SPI_TRANS_USE_RXDATA,
.length = 24,
.rxlength = 24,
.tx_buffer = NULL,
.rx_buffer = NULL,
};

ret = spi_device_polling_transmit(spi_device, &spi_transaction);
ESP_RETURN_ON_FALSE(ret == ESP_OK, 0.0, TAG, "SPI transaction failed: %s", esp_err_to_name(ret));

uint32_t spi_32 = ((int32_t)spi_transaction.rx_data[0] << 16) | ((int32_t)spi_transaction.rx_data[1] << 8) | spi_transaction.rx_data[2];
uint32_t angle_spi = spi_32 >> 10;

uint8_t received_crc = spi_32 & 0x3F;
uint8_t calculated_crc = CRC6_43_18bit(spi_32 >> 6);

if (received_crc == calculated_crc) {
angle = (float)angle_spi * 2 * M_PI / 16384;
previous_angle = angle;
ESP_LOGD(TAG, "Angle: %f", angle);
} else {
return previous_angle;
if (_spi_host != SPI_HOST_MAX) {
spi_transaction_t spi_transaction = {
.flags = SPI_TRANS_USE_RXDATA,
.length = 24,
.rxlength = 24,
.tx_buffer = NULL,
.rx_buffer = NULL,
};

ret = spi_device_polling_transmit(spi_device, &spi_transaction);
ESP_RETURN_ON_FALSE(ret == ESP_OK, 0.0, TAG, "SPI transaction failed: %s", esp_err_to_name(ret));

uint32_t spi_32 = ((int32_t)spi_transaction.rx_data[0] << 16) | ((int32_t)spi_transaction.rx_data[1] << 8) | spi_transaction.rx_data[2];
uint32_t angle_spi = spi_32 >> 10;

uint8_t received_crc = spi_32 & 0x3F;
uint8_t calculated_crc = CRC6_43_18bit(spi_32 >> 6);

if (received_crc == calculated_crc) {
angle = (float)angle_spi * 2 * M_PI / 16384;
previous_angle = angle;
ESP_LOGD(TAG, "Angle: %f", angle);
} else {
return previous_angle;
}
return angle;
} else if (_i2c_port != I2C_NUM_MAX) {
uint8_t raw_angle_addr = 0x03;
uint8_t raw_angle_buffer[2] = {0};
if (i2c_master_write_read_device(_i2c_port, 0x06, &raw_angle_addr, 1, raw_angle_buffer, 2, 1000 / portTICK_PERIOD_MS) != ESP_OK) {
return -1;
}
angle = ((int)((raw_angle_buffer[0] << 6) | (raw_angle_buffer[1] >> 2))) * 0.00038349519f; /*!< Converts raw data into angle information in radians. */
return angle;
}
return angle;

return -1;
}
17 changes: 14 additions & 3 deletions components/motor/esp_simplefoc/port/angle_sensor/mt6701.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -8,6 +8,7 @@

#include "common/base_classes/Sensor.h"
#include "driver/spi_master.h"
#include "driver/i2c.h"
#include "driver/gpio.h"

class MT6701 : public Sensor {
Expand All @@ -23,6 +24,15 @@ class MT6701 : public Sensor {
*/
MT6701(spi_host_device_t spi_host, gpio_num_t sclk_io, gpio_num_t miso_io, gpio_num_t mosi_io, gpio_num_t cs_io);

/**
* @brief Construct a new MT6701 object
*
* @param i2c_port
* @param sclk_io
* @param miso_io
*/
MT6701(i2c_port_t i2c_port, gpio_num_t sclk_io, gpio_num_t miso_io);

/**
* @brief Destroy the mt6701 object
*
Expand All @@ -49,11 +59,12 @@ class MT6701 : public Sensor {
float getSensorAngle();

private:
spi_host_device_t _spi_host;
spi_host_device_t _spi_host = SPI_HOST_MAX;
spi_device_handle_t spi_device;
i2c_port_t _i2c_port = I2C_NUM_MAX;
gpio_num_t _sclk_io;
gpio_num_t _miso_io;
gpio_num_t _mosi_io;
gpio_num_t _cs_io;
spi_device_handle_t spi_device;
bool is_installed;
};
10 changes: 9 additions & 1 deletion components/motor/esp_simplefoc/port/esp/esp_hal_bldc_3pwm.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -355,7 +355,11 @@ int BLDCDriver3PWM::init()
.duty_resolution = _LEDC_DUTY_RES,
.timer_num = LEDC_TIMER_0,
.freq_hz = _LEDC_FREQUENCY, // Set output frequency at 20 kHz
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
.clk_cfg = LEDC_AUTO_CLK
#else
.clk_cfg = LEDC_USE_APB_CLK
#endif
};
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

Expand Down Expand Up @@ -510,7 +514,11 @@ int BLDCDriver3PWM::init(std::vector<int> _ledc_channels)
.duty_resolution = _LEDC_DUTY_RES,
.timer_num = LEDC_TIMER_0,
.freq_hz = _LEDC_FREQUENCY, // Set output frequency at 20 kHz
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
.clk_cfg = LEDC_AUTO_CLK
#else
.clk_cfg = LEDC_USE_APB_CLK
#endif
};
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -16,9 +16,13 @@

const char *TAG = "TEST";

TEST_CASE("test as5600", "[sensor][as5600]")
TEST_CASE("test as5600", "[sensor][as5600][i2c]")
{
AS5600 as5600 = AS5600(I2C_NUM_0, GPIO_NUM_8, GPIO_NUM_2);
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
AS5600 as5600 = AS5600(I2C_NUM_0, GPIO_NUM_2, GPIO_NUM_1);
#else
AS5600 as5600 = AS5600(I2C_NUM_0, GPIO_NUM_12, GPIO_NUM_13);
#endif
as5600.init();
for (int i = 0; i < 10; ++i) {
ESP_LOGI(TAG, "angle:%.2f", as5600.getSensorAngle());
Expand All @@ -27,9 +31,9 @@ TEST_CASE("test as5600", "[sensor][as5600]")
as5600.deinit();
}

TEST_CASE("test mt6701", "[sensor][mt6701]")
TEST_CASE("test mt6701", "[sensor][mt6701][spi]")
{
#if CONFIG_IDF_TARGET_ESP32C3
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
MT6701 mt6701 = MT6701(SPI2_HOST, GPIO_NUM_2, GPIO_NUM_1, (gpio_num_t) -1, GPIO_NUM_3);
#else
MT6701 mt6701 = MT6701(SPI2_HOST, GPIO_NUM_2, GPIO_NUM_1, (gpio_num_t) -1, GPIO_NUM_42);
Expand All @@ -42,9 +46,26 @@ TEST_CASE("test mt6701", "[sensor][mt6701]")
mt6701.deinit();
}

TEST_CASE("test as5048a", "[sensor][as5048a]")
TEST_CASE("test mt6701", "[sensor][mt6701][i2c]")
{
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
MT6701 mt6701 = MT6701(I2C_NUM_0, GPIO_NUM_2, GPIO_NUM_1);
#else
MT6701 mt6701 = MT6701(I2C_NUM_0, GPIO_NUM_12, GPIO_NUM_13);
#endif
mt6701.init();

for (int i = 0; i < 10; ++i) {
ESP_LOGI(TAG, "angle:%.2f", mt6701.getSensorAngle());
vTaskDelay(1000 / portTICK_PERIOD_MS);
}

mt6701.deinit();
}

TEST_CASE("test as5048a", "[sensor][as5048a][spi]")
{
#if CONFIG_IDF_TARGET_ESP32C3
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
AS5048a as5048a = AS5048a(SPI2_HOST, GPIO_NUM_2, GPIO_NUM_1, (gpio_num_t) -1, GPIO_NUM_3);
#else
AS5048a as5048a = AS5048a(SPI2_HOST, GPIO_NUM_2, GPIO_NUM_1, (gpio_num_t) -1, GPIO_NUM_42);
Expand Down
Loading

0 comments on commit 8f2f077

Please sign in to comment.