forked from EmbeddedTeam/app_photomagnetic
refactor: use dc-motor driver as low level layer
This commit is contained in:
parent
9de7db11f6
commit
ab818974f3
@ -1,25 +1,21 @@
|
||||
/ {
|
||||
zephyr,user {
|
||||
in3-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
|
||||
in4-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
|
||||
enb-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
|
||||
dc_motor: dc-motor0 {
|
||||
status = "okay";
|
||||
compatible = "st,l298n";
|
||||
freq-hz = <1000>;
|
||||
in1-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
|
||||
in2-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
|
||||
en-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
aliases {
|
||||
modbus-server-pc = &modbus_pc;
|
||||
};
|
||||
};
|
||||
&uart0 {
|
||||
|
||||
&uart1 {
|
||||
status = "okay";
|
||||
protocal: uart-com-protocal {
|
||||
compatible = "uart-com-protocal";
|
||||
current-speed = <115200>;
|
||||
modbus_pc: modbus-server0 {
|
||||
status = "okay";
|
||||
header = <0x7e 0xe7>;
|
||||
crc16 = "none";
|
||||
freq{
|
||||
id = <0x00>;
|
||||
};
|
||||
switch{
|
||||
id = <0x01>;
|
||||
};
|
||||
status{
|
||||
id = <0x02>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
2
prj.conf
2
prj.conf
@ -7,4 +7,6 @@ CONFIG_CONSOLE=y
|
||||
CONFIG_SERIAL=y
|
||||
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||
|
||||
CONFIG_MODBUS=y
|
||||
CONFIG_MODBUS_ROLE_SERVER=y
|
||||
CONFIG_LOG=y
|
||||
140
src/main.cpp
140
src/main.cpp
@ -1,74 +1,96 @@
|
||||
#include <uart_com/protocal.hpp>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <dc_motor/motor.hpp>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/modbus/modbus.h>
|
||||
namespace {
|
||||
enum Cmd {
|
||||
kFreq = 0x00,
|
||||
kSwitch = 0x01,
|
||||
kStatus = 0x02,
|
||||
};
|
||||
#define ZEPHYR_USER_NODE DT_PATH(zephyr_user)
|
||||
const gpio_dt_spec in3 = GPIO_DT_SPEC_GET(ZEPHYR_USER_NODE, in3_gpios);
|
||||
const gpio_dt_spec in4 = GPIO_DT_SPEC_GET(ZEPHYR_USER_NODE, in4_gpios);
|
||||
const gpio_dt_spec enb = GPIO_DT_SPEC_GET(ZEPHYR_USER_NODE, enb_gpios);
|
||||
volatile uint8_t duty_cycle_event{50};
|
||||
volatile bool is_enable{false};
|
||||
class Motor {
|
||||
|
||||
class ModbusServer {
|
||||
public:
|
||||
Motor() {
|
||||
gpio_pin_configure_dt(&in3, GPIO_OUTPUT_INACTIVE);
|
||||
gpio_pin_configure_dt(&in4, GPIO_OUTPUT_INACTIVE);
|
||||
gpio_pin_configure_dt(&enb, GPIO_OUTPUT_INACTIVE);
|
||||
struct Addr {
|
||||
enum Coil : uint16_t { MOTOR_RUNNING = 0 };
|
||||
enum Reg : uint16_t {
|
||||
SPEED = 0,
|
||||
};
|
||||
};
|
||||
ModbusServer() {
|
||||
m_iface =
|
||||
modbus_iface_get_by_name(DEVICE_DT_NAME(DT_ALIAS(modbus_server_pc)));
|
||||
modbus_init_server(m_iface, m_param);
|
||||
}
|
||||
|
||||
auto Rotate() -> void {
|
||||
gpio_pin_set_dt(&in3, 1);
|
||||
gpio_pin_set_dt(&in4, 0);
|
||||
};
|
||||
auto Reverse() {
|
||||
gpio_pin_set_dt(&in3, 0);
|
||||
gpio_pin_set_dt(&in4, 1);
|
||||
};
|
||||
auto Stop() {
|
||||
gpio_pin_set_dt(&in3, 0);
|
||||
gpio_pin_set_dt(&in4, 0);
|
||||
private:
|
||||
static auto CoilWr(uint16_t addr, bool state) -> int {
|
||||
switch (addr) {
|
||||
case Addr::Coil::MOTOR_RUNNING: {
|
||||
if (0 == state) {
|
||||
m_motor.SetSpeed(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
static auto CoilRd(uint16_t addr, bool *state) -> int {
|
||||
switch (addr) {
|
||||
case Addr::Coil::MOTOR_RUNNING: {
|
||||
const auto s = m_motor.GetState();
|
||||
*state = (s == driver::DcMotorState::RUNNING);
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
static auto RegWr(uint16_t addr, uint16_t reg) -> int {
|
||||
switch (addr) {
|
||||
case Addr::Reg::SPEED: {
|
||||
m_current_speed = reg;
|
||||
return int(m_motor.SetSpeed(reg).code_id());
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
static auto RedRd(uint16_t addr, uint16_t *reg) -> int {
|
||||
switch (addr) {
|
||||
case Addr::Reg::SPEED:
|
||||
*reg = m_current_speed;
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
inline static modbus_user_callbacks m_cbs = {.coil_rd = CoilRd,
|
||||
.coil_wr = CoilWr,
|
||||
.holding_reg_rd = RedRd,
|
||||
.holding_reg_wr = RegWr};
|
||||
inline static modbus_iface_param m_param = {
|
||||
.mode = MODBUS_MODE_RTU,
|
||||
.server =
|
||||
{
|
||||
.user_cb = &m_cbs,
|
||||
.unit_id = 1,
|
||||
},
|
||||
.serial =
|
||||
{
|
||||
.baud =
|
||||
DT_PROP(DT_PARENT(DT_ALIAS(modbus_server_pc)), current_speed),
|
||||
|
||||
.parity = UART_CFG_PARITY_NONE,
|
||||
},
|
||||
};
|
||||
inline static int m_iface;
|
||||
inline static int m_current_speed{0};
|
||||
inline static auto &m_motor =
|
||||
ZPP_DRV_GET(driver::DcMotor, DT_NODELABEL(dc_motor));
|
||||
};
|
||||
|
||||
Motor motor{};
|
||||
} // namespace
|
||||
|
||||
auto main(void) -> int {
|
||||
auto &protocal = ZPP_DRV_GET(uart_com::Protocal, DT_NODELABEL(protocal));
|
||||
protocal.SetRxCallback(kSwitch, [](uart_com::DataType data) {
|
||||
if (data[0] == 0) {
|
||||
motor.Stop();
|
||||
} else {
|
||||
motor.Rotate();
|
||||
}
|
||||
|
||||
printk("set switch: %d\n", data[0]);
|
||||
is_enable = data[0];
|
||||
});
|
||||
protocal.SetRxCallback(kFreq, [](uart_com::DataType data) {
|
||||
printk("set freq: %d\n", data[0]);
|
||||
|
||||
uint8_t freq = 0;
|
||||
if (data[0] == 100) {
|
||||
freq = 100;
|
||||
}
|
||||
freq = data[0];
|
||||
duty_cycle_event = freq;
|
||||
});
|
||||
|
||||
ModbusServer server{};
|
||||
while (1) {
|
||||
if (is_enable) {
|
||||
printk("duty circle %d\n", duty_cycle_event);
|
||||
gpio_pin_set_dt(&enb, 1);
|
||||
k_sleep(K_MSEC(duty_cycle_event));
|
||||
gpio_pin_set_dt(&enb, 0);
|
||||
k_sleep(K_MSEC(100 - duty_cycle_event));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user