Add initial board, HAL, and executor modules
This commit is contained in:
1 parent
3b9e129c88
commit
0b2eebe76d
82 files changed
+20611
No files matched your search
@@ -0,0 +1,213 @@
|
||||
#include "aw8646.h"
|
||||
#include "config.h"
|
||||
#include "esp_log.h"
|
||||
#include "io_expansion_board.h"
|
||||
|
||||
// Define AW8646 specific pins for Board v1.1.16
|
||||
// P0_0 -> DRV_T0
|
||||
// P0_6 -> DRV_T1
|
||||
// Only if NFC_RST_PIN is defined (implying it's moved to GPIO, freeing up P0_0)
|
||||
#ifdef NFC_RST_PIN
|
||||
#define AW8646_USE_CURRENT_CONTROL
|
||||
#define AW8646_T0_PIN 0
|
||||
#define AW8646_T0_PORT OUTPUT_PORT0
|
||||
#define AW8646_T1_PIN 6
|
||||
#define AW8646_T1_PORT OUTPUT_PORT0
|
||||
#endif
|
||||
|
||||
Aw8646Driver::Aw8646Driver(IOExpansionBoard &ioExp) : io_expansion_(ioExp)
|
||||
{
|
||||
}
|
||||
|
||||
esp_err_t Aw8646Driver::Init()
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
// 1. 默认处于休眠和禁用状态,防止发热!
|
||||
err = io_expansion_.SetMotorSleepMode(
|
||||
STEPPER_MOTOR_SLEEP,
|
||||
STEPPER_MOTOR_SLEEP_PORT,
|
||||
STEPPER_MOTOR_SLEEP_PIN
|
||||
);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set sleep mode: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
// 2. Disable Enable Pin (High = Disable for AW8646)
|
||||
err = io_expansion_.SetMotorEnableMode(
|
||||
true, // High -> Disable
|
||||
STEPPER_MOTOR_ENABLE_PORT,
|
||||
STEPPER_MOTOR_ENABLE_PIN
|
||||
);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set enable mode: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef AW8646_USE_CURRENT_CONTROL
|
||||
// 3. Initialize T0 and T1 pins for Current Control
|
||||
// Default to Low (0, 0) for now.
|
||||
uint8_t output0_val = 0;
|
||||
err = io_expansion_.IoexpandReadReg(OUTPUT_PORT0, &output0_val);
|
||||
if (err == ESP_OK) {
|
||||
output0_val &= ~(1 << AW8646_T0_PIN); // Set T0 Low
|
||||
output0_val &= ~(1 << AW8646_T1_PIN); // Set T1 Low
|
||||
err = io_expansion_.IoexpandWriteReg(OUTPUT_PORT0, output0_val);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set T0/T1: 0x%x", err);
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to read port 0: 0x%x", err);
|
||||
}
|
||||
#endif
|
||||
|
||||
// 4. Set Microsteps (Default to 1/8 step)
|
||||
err = SetMicrosteps(8);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set microsteps: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
// 5. Set Default Direction
|
||||
err = SetDirection(true);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set direction: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "AW8646 Driver Initialized (EN Logic Inverted, T0/T1 Configured)");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t Aw8646Driver::Enable(bool enable)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
if (enable)
|
||||
{
|
||||
ESP_LOGD(TAG, "Enabling AW8646 (sleep + enable=Low)");
|
||||
|
||||
// Ensure Sleep is High (Work)
|
||||
err = io_expansion_.SetMotorSleepMode(
|
||||
STEPPER_MOTOR_WORK,
|
||||
STEPPER_MOTOR_SLEEP_PORT,
|
||||
STEPPER_MOTOR_SLEEP_PIN
|
||||
);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// Enable Pin: Low to Enable
|
||||
err = io_expansion_.SetMotorEnableMode(
|
||||
false, // Low -> Enable
|
||||
STEPPER_MOTOR_ENABLE_PORT,
|
||||
STEPPER_MOTOR_ENABLE_PIN
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGD(TAG, "Disabling AW8646 (disable=High + sleep)");
|
||||
|
||||
// Enable Pin: High to Disable
|
||||
err = io_expansion_.SetMotorEnableMode(
|
||||
true, // High -> Disable
|
||||
STEPPER_MOTOR_ENABLE_PORT,
|
||||
STEPPER_MOTOR_ENABLE_PIN
|
||||
);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// Sleep Pin: Low to Sleep
|
||||
err = io_expansion_.SetMotorSleepMode(
|
||||
STEPPER_MOTOR_SLEEP,
|
||||
STEPPER_MOTOR_SLEEP_PORT,
|
||||
STEPPER_MOTOR_SLEEP_PIN
|
||||
);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t Aw8646Driver::SetDirection(bool dir)
|
||||
{
|
||||
uint8_t mode = dir ? STEPPER_MOTOR_RIGHT : STEPPER_MOTOR_LEFT;
|
||||
|
||||
return io_expansion_.StepperMotorSetDir(
|
||||
mode,
|
||||
STEPPER_MOTOR_DIR_PORT,
|
||||
STEPPER_MOTOR_DIR_PIN
|
||||
);
|
||||
}
|
||||
|
||||
esp_err_t Aw8646Driver::Sleep(bool sleep)
|
||||
{
|
||||
uint8_t mode = sleep ? STEPPER_MOTOR_SLEEP : STEPPER_MOTOR_WORK;
|
||||
return io_expansion_.SetMotorSleepMode(
|
||||
mode,
|
||||
STEPPER_MOTOR_SLEEP_PORT,
|
||||
STEPPER_MOTOR_SLEEP_PIN
|
||||
);
|
||||
}
|
||||
|
||||
esp_err_t Aw8646Driver::SetTriLevelPin(uint8_t port_reg, uint8_t config_reg, uint8_t pin, int state)
|
||||
{
|
||||
uint8_t val;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
if (state == 2) { // Hi-Z -> Input
|
||||
// Set as Input
|
||||
err = io_expansion_.IoexpandReadReg(config_reg, &val);
|
||||
if (err != ESP_OK) return err;
|
||||
val |= (1 << pin); // Set Input
|
||||
err = io_expansion_.IoexpandWriteReg(config_reg, val);
|
||||
} else { // 0 or 1 -> Output
|
||||
// Set as Output
|
||||
err = io_expansion_.IoexpandReadReg(config_reg, &val);
|
||||
if (err != ESP_OK) return err;
|
||||
val &= ~(1 << pin); // Set Output
|
||||
err = io_expansion_.IoexpandWriteReg(config_reg, val);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// Set Level
|
||||
err = io_expansion_.IoexpandReadReg(port_reg, &val);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
if (state == 1) val |= (1 << pin);
|
||||
else val &= ~(1 << pin);
|
||||
|
||||
err = io_expansion_.IoexpandWriteReg(port_reg, val);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t Aw8646Driver::SetMicrosteps(int microsteps)
|
||||
{
|
||||
// AW8646 Microstep Table (Rising Edge Only)
|
||||
// 1 (Full): MODE1=0, MODE0=0
|
||||
// 2 (1/2): MODE1=0, MODE0=Z (Hi-Z)
|
||||
// 4 (1/4): MODE1=0, MODE0=1
|
||||
// 8 (1/8): MODE1=Z, MODE0=0
|
||||
// 16 (1/16): MODE1=Z, MODE0=1
|
||||
// 32 (1/32): MODE1=1, MODE0=Z
|
||||
|
||||
int m1 = 0;
|
||||
int m0 = 0;
|
||||
|
||||
switch(microsteps) {
|
||||
case 1: m1 = 0; m0 = 0; break;
|
||||
case 2: m1 = 0; m0 = 2; break; // Z
|
||||
case 4: m1 = 0; m0 = 1; break;
|
||||
case 8: m1 = 2; m0 = 0; break; // Z
|
||||
case 16: m1 = 2; m0 = 1; break; // Z
|
||||
case 32: m1 = 1; m0 = 2; break; // Z
|
||||
default:
|
||||
ESP_LOGW(TAG, "Unsupported microsteps: %d, defaulting to 1/8", microsteps);
|
||||
m1 = 2; m0 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Setting Microsteps to 1/%d (M1=%d, M0=%d)", microsteps, m1, m0);
|
||||
|
||||
esp_err_t err;
|
||||
err = SetTriLevelPin(STEPPER_MOTOR_M1_MADE_PORT, STEPPER_MOTOR_M1_CONFIG, STEPPER_MOTOR_M1_PIN, m1);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
err = SetTriLevelPin(STEPPER_MOTOR_M0_MADE_PORT, STEPPER_MOTOR_M0_CONFIG, STEPPER_MOTOR_M0_PIN, m0);
|
||||
return err;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef AW8646_DRIVER_H
|
||||
#define AW8646_DRIVER_H
|
||||
|
||||
#include "stepper_driver.h"
|
||||
#include "io_expansion_board.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
class Aw8646Driver : public StepperDriver
|
||||
{
|
||||
public:
|
||||
explicit Aw8646Driver(IOExpansionBoard &ioExp);
|
||||
virtual ~Aw8646Driver() = default;
|
||||
|
||||
esp_err_t Init() override;
|
||||
esp_err_t Enable(bool enable) override;
|
||||
esp_err_t SetDirection(bool dir) override;
|
||||
esp_err_t Sleep(bool sleep) override;
|
||||
esp_err_t SetMicrosteps(int microsteps) override;
|
||||
|
||||
private:
|
||||
esp_err_t SetTriLevelPin(uint8_t port_reg, uint8_t config_reg, uint8_t pin, int state);
|
||||
|
||||
IOExpansionBoard &io_expansion_;
|
||||
const char* TAG = "Aw8646Driver";
|
||||
};
|
||||
|
||||
#endif // AW8646_DRIVER_H
|
||||
Binary file not shown.
@@ -0,0 +1,147 @@
|
||||
#include "drv8428.h"
|
||||
#include "config.h"
|
||||
|
||||
Drv8428Driver::Drv8428Driver(IOExpansionBoard &ioExp) : io_expansion_(ioExp)
|
||||
{
|
||||
}
|
||||
|
||||
esp_err_t Drv8428Driver::Init()
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
// 1. Set Sleep Mode to WORK (wake up initially to configure?)
|
||||
// Actually BoardSweekar::StepperMotorInit sets it to WORK then ENABLE_DISABLE.
|
||||
// Let's follow that.
|
||||
err = io_expansion_.SetMotorSleepMode(
|
||||
STEPPER_MOTOR_WORK,
|
||||
STEPPER_MOTOR_SLEEP_PORT,
|
||||
STEPPER_MOTOR_SLEEP_PIN
|
||||
);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set sleep mode: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
// 2. Disable Enable Pin
|
||||
err = io_expansion_.SetMotorEnableMode(
|
||||
STEPPER_MOTOR_ENABLE_DISABLE,
|
||||
STEPPER_MOTOR_ENABLE_PORT,
|
||||
STEPPER_MOTOR_ENABLE_PIN
|
||||
);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set enable mode: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
// 3. Set Microsteps (Defaulting to 1/8 as per original code which passed 4? need to verify)
|
||||
// BoardSweekar passed 4.
|
||||
// "io_expansion_.SetStepperMicrostepMode(4, ...)"
|
||||
// Let's assume 4 maps to 1/8 or whatever.
|
||||
err = SetMicrosteps(4);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set microsteps: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
// 4. Set Default Direction
|
||||
err = SetDirection(true); // Default to "UP" or whatever true means
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set direction: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "DRV8428 Driver Initialized");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t Drv8428Driver::Enable(bool enable)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
if (enable)
|
||||
{
|
||||
ESP_LOGD(TAG, "Enabling stepper motor (sleep + enable)");
|
||||
|
||||
// 1. Set sleep mode to WORK
|
||||
err = io_expansion_.SetMotorSleepMode(
|
||||
STEPPER_MOTOR_WORK,
|
||||
STEPPER_MOTOR_SLEEP_PORT,
|
||||
STEPPER_MOTOR_SLEEP_PIN
|
||||
);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// 2. Set enable mode to ENABLE
|
||||
err = io_expansion_.SetMotorEnableMode(
|
||||
STEPPER_MOTOR_ENABLE_ENABLE,
|
||||
STEPPER_MOTOR_ENABLE_PORT,
|
||||
STEPPER_MOTOR_ENABLE_PIN
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGD(TAG, "Disabling stepper motor (disable + sleep)");
|
||||
|
||||
// 1. Disable enable pin
|
||||
err = io_expansion_.SetMotorEnableMode(
|
||||
STEPPER_MOTOR_ENABLE_DISABLE,
|
||||
STEPPER_MOTOR_ENABLE_PORT,
|
||||
STEPPER_MOTOR_ENABLE_PIN
|
||||
);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// 2. Set sleep mode to SLEEP
|
||||
err = io_expansion_.SetMotorSleepMode(
|
||||
STEPPER_MOTOR_SLEEP,
|
||||
STEPPER_MOTOR_SLEEP_PORT,
|
||||
STEPPER_MOTOR_SLEEP_PIN
|
||||
);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t Drv8428Driver::SetDirection(bool dir)
|
||||
{
|
||||
// dir: true=UP, false=DOWN (based on original StepperMotor::SetDir logic)
|
||||
// Original: dir ? STEPPER_MOTOR_RIGHT : STEPPER_MOTOR_LEFT
|
||||
// Wait, StepperMotor::SetDir used STEPPER_MOTOR_RIGHT for true.
|
||||
// STEPPER_MOTOR_RIGHT is a macro, likely 1 or 0.
|
||||
|
||||
uint8_t mode = dir ? STEPPER_MOTOR_RIGHT : STEPPER_MOTOR_LEFT;
|
||||
|
||||
return io_expansion_.StepperMotorSetDir(
|
||||
mode,
|
||||
STEPPER_MOTOR_DIR_PORT,
|
||||
STEPPER_MOTOR_DIR_PIN
|
||||
);
|
||||
}
|
||||
|
||||
esp_err_t Drv8428Driver::Sleep(bool sleep)
|
||||
{
|
||||
// This is explicitly setting sleep mode, might be redundant with Enable(false)
|
||||
// but useful if we want to sleep without disabling or vice versa if supported.
|
||||
// For DRV8428, Enable(false) sets Sleep to SLEEP.
|
||||
|
||||
uint8_t mode = sleep ? STEPPER_MOTOR_SLEEP : STEPPER_MOTOR_WORK;
|
||||
return io_expansion_.SetMotorSleepMode(
|
||||
mode,
|
||||
STEPPER_MOTOR_SLEEP_PORT,
|
||||
STEPPER_MOTOR_SLEEP_PIN
|
||||
);
|
||||
}
|
||||
|
||||
esp_err_t Drv8428Driver::SetMicrosteps(int microsteps)
|
||||
{
|
||||
// Original code used hardcoded ports for microsteps.
|
||||
// io_expansion_.SetStepperMicrostepMode(4, STEPPER_MOTOR_M0_MADE_PORT, STEPPER_MOTOR_M0_PIN,
|
||||
// STEPPER_MOTOR_M1_MADE_PORT, STEPPER_MOTOR_M1_PIN);
|
||||
|
||||
// We can just pass the value 'microsteps' if it corresponds to the index expected by SetStepperMicrostepMode.
|
||||
// Or we might need a mapping.
|
||||
// Assuming 'microsteps' passed here is the raw value/index for now.
|
||||
|
||||
io_expansion_.SetStepperMicrostepMode(
|
||||
(uint8_t)microsteps,
|
||||
STEPPER_MOTOR_M0_MADE_PORT, STEPPER_MOTOR_M0_PIN,
|
||||
STEPPER_MOTOR_M1_MADE_PORT, STEPPER_MOTOR_M1_PIN
|
||||
);
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef DRV8428_DRIVER_H
|
||||
#define DRV8428_DRIVER_H
|
||||
|
||||
#include "stepper_driver.h"
|
||||
#include "io_expansion_board.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
class Drv8428Driver : public StepperDriver
|
||||
{
|
||||
public:
|
||||
explicit Drv8428Driver(IOExpansionBoard &ioExp);
|
||||
virtual ~Drv8428Driver() = default;
|
||||
|
||||
esp_err_t Init() override;
|
||||
esp_err_t Enable(bool enable) override;
|
||||
esp_err_t SetDirection(bool dir) override;
|
||||
esp_err_t Sleep(bool sleep) override;
|
||||
esp_err_t SetMicrosteps(int microsteps) override;
|
||||
|
||||
private:
|
||||
IOExpansionBoard &io_expansion_;
|
||||
const char* TAG = "Drv8428Driver";
|
||||
};
|
||||
|
||||
#endif // DRV8428_DRIVER_H
|
||||
@@ -0,0 +1,17 @@
|
||||
# main/04_hal/stepper_driver/module.cmake
|
||||
|
||||
|
||||
# 判断 menuconfig 中的开关
|
||||
if(NOT CONFIG_ENABLE_HAL_STEPPER_DRIVER AND NOT EARLY_EXPANSION)
|
||||
message(STATUS " [Skip] stepper_driver module disabled by menuconfig.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
list(APPEND MODULE_SRCS
|
||||
"04_hal/stepper_driver/drv8428.cc"
|
||||
"04_hal/stepper_driver/aw8646.cc"
|
||||
)
|
||||
|
||||
list(APPEND MODULE_INCLUDE_DIRS
|
||||
"04_hal/stepper_driver"
|
||||
)
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef STEPPER_DRIVER_H
|
||||
#define STEPPER_DRIVER_H
|
||||
|
||||
#include <cstdint>
|
||||
#include "esp_err.h"
|
||||
|
||||
/**
|
||||
* @brief Abstract base class for stepper motor driver chips.
|
||||
*
|
||||
* This interface abstracts the low-level control of the stepper motor driver,
|
||||
* such as enabling/disabling, setting direction, sleep mode, and microstepping configuration.
|
||||
* It does NOT handle step generation (that is handled by the StepperMotor class using GPTimer).
|
||||
*/
|
||||
class StepperDriver
|
||||
{
|
||||
public:
|
||||
virtual ~StepperDriver() = default;
|
||||
|
||||
/**
|
||||
* @brief Initialize the driver hardware (GPIOs, IO Expander, etc.)
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
virtual esp_err_t Init() = 0;
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the motor driver output.
|
||||
* @param enable true to enable, false to disable
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
virtual esp_err_t Enable(bool enable) = 0;
|
||||
|
||||
/**
|
||||
* @brief Set the motor direction.
|
||||
* @param dir true for one direction (e.g. UP/CW), false for the other (e.g. DOWN/CCW)
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
virtual esp_err_t SetDirection(bool dir) = 0;
|
||||
|
||||
/**
|
||||
* @brief Set the motor driver to sleep mode to save power.
|
||||
* @param sleep true to sleep, false to wake up
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
virtual esp_err_t Sleep(bool sleep) = 0;
|
||||
|
||||
/**
|
||||
* @brief Set microstepping mode.
|
||||
* @param microsteps Microstepping value (e.g., 1, 2, 4, 8, 16, 32, etc.)
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
virtual esp_err_t SetMicrosteps(int microsteps) = 0;
|
||||
};
|
||||
|
||||
#endif // STEPPER_DRIVER_H
|
||||
Reference in new issue
Block a user