5 Commits

Author SHA1 Message Date
roy01 34a8093c34 暫存 2026-06-02 11:47:48 +08:00
roy01 e6fdabcd3a uart 可以使用 debug_epwm_en等等指令 2026-04-23 17:34:52 +08:00
roy01 bb5621a3fd uart tx rx ok 2026-04-23 16:17:40 +08:00
roy01 552b3ab5b4 合併 main app 2026-04-23 14:37:26 +08:00
roy01 3f10ca6e02 feat: copy dds 2026-04-23 14:08:58 +08:00
16 changed files with 1138 additions and 384 deletions
+111
View File
@@ -0,0 +1,111 @@
#ifndef __APP_CFG_H__
#define __APP_CFG_H__
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define FW_VERSION "0.0.1"
enum phase_e
{
PHASE_U = 0,
PHASE_V = 1,
PHASE_W = 2,
PHASE_CH = 3,
};
enum motor_task_mode_e
{
MOTOR_TASK_IDLE = 0,
MOTOR_TASK_RUNNING = 1,
};
enum notify_type_e
{
NOTIFY_TYPE_NODATA = 0,
NOTIFY_TYPE_BASIC = 1,
NOTIFY_TYPE_RESERVED = 2,
NOTIFY_TYPE_PERIOD = 3,
};
struct old_cmd_param_t
{
int32_t dds_ftw;
uint32_t dds_amp;
uint32_t notify_time_ms;
uint16_t notify_type;
bool vf_ctrl_fb_enabled;
bool soft_start_enabled;
struct soft_start_param_t
{
uint32_t dds_amp_first;
int32_t dds_ftw_first;
int32_t dds_ftw_goal;
uint32_t soft_start_time_ms;
int32_t curve_offset;
} soft_start;
};
struct dds_output_t
{
uint32_t phase_acc;
uint8_t lut_idx;
uint8_t nquadrant;
uint8_t last_quadrant;
int16_t lut_sin_val;
int16_t lut_cos_val;
uint16_t duty;
};
struct dds_feedback_t
{
int16_t current_corrected;
int32_t sum_sine;
int32_t sum_cos;
int16_t m_point;
int32_t in_phase;
int32_t q_over_i;
int32_t err_sig;
int32_t magnitude;
};
struct motor_ctx_t
{
enum motor_task_mode_e mode;
uint32_t phase_acc_base;
int32_t begin_dds_ftw; // max: 2^22
int32_t begin_dds_amp; // max: 2^7*1250
int32_t goal_dds_ftw;
int32_t goal_dds_amp;
int32_t current_dds_ftw;
int32_t current_dds_amp;
struct dds_output_t phase_out[PHASE_CH];
struct dds_feedback_t phase_fb[PHASE_CH];
};
extern struct motor_ctx_t g_motor_ctx;
extern bool g_motor_running;
extern int32_t g_dds_ftw_setting;
extern int32_t g_dds_amp_setting;
extern uint32_t g_notify_time_ms;
extern uint16_t g_notify_type;
extern bool g_notify_en;
#ifdef __cplusplus
}
#endif
#endif
+8 -4
View File
@@ -6,11 +6,15 @@ extern "C"
{
#endif
#include "main.h"
#include "app_cfg.h"
void epwm_init(void);
void epwm_en(bool en);
void epwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val);
#define HIRC_Freq 60000000U
#define CurrentLoopIsrFreq 24000U
#define EPWM_PWM_PERIOD 2500U
void epwm_drv_init(void);
void epwm_drv_output_en(bool en);
void epwm_drv_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val);
bool epwm_is_24khz_tick_and_clear(void);
#ifdef __cplusplus
+1 -1
View File
@@ -26,7 +26,7 @@ extern "C"
//=============================================================================
// Macro Definition
//=============================================================================
#define FW_VERSION "0.0.1"
//=============================================================================
// Structure Definition
//=============================================================================
+119
View File
@@ -0,0 +1,119 @@
#ifndef __MOTOR_CONTROL_H__
#define __MOTOR_CONTROL_H__
#include <stdint.h>
#include "app_cfg.h"
#include "epwm_drv.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define B_MOTOR_60V
enum motor_mode_e
{
MOTOR_MODE_RUN = 1,
MOTOR_MODE_SOFT_START = 2,
};
enum amp_ftw_control_mode_e
{
AMP_FTW_FIXED_FIXED = 0,
AMP_FTW_FIXED_VARIABLE = 1,
AMP_FTW_VARIABLE_FIXED = 2,
AMP_FTW_VARIABLE_VARIABLE = 3,
};
enum vf_control_use_type_e
{
VF_CTRL_FORMULA_STABLE = 0,
VF_CTRL_FORMULA_MIN = 1,
};
struct vf_control_formula_t
{
int32_t slope;
int32_t offset;
};
#ifdef B_MOTOR_100V
#define VF_SLOPE_X10000 35997
#define VF_OFFSET_STABLE_PCT 0.02f
#define VF_OFFSET_MIN (-1073)
#elif defined(B_MOTOR_60V)
#define VF_SLOPE_X10000 54487
#define VF_OFFSET_STABLE_PCT 0.02f
#define VF_OFFSET_MIN 296
#else
#error "Motor type not defined"
#endif
void handle_motor_task(void);
void motor_ctrl_apply_default_settings(struct old_cmd_param_t *cmd_param);
void motor_ctrl_set_amp_ftw_mode(enum amp_ftw_control_mode_e mode);
void motor_ctrl_set_mode(enum motor_mode_e mode);
enum motor_mode_e motor_ctrl_get_mode(void);
void motor_ctrl_start(void);
void motor_ctrl_stop(void);
void update_phase_accumulator(void);
#define DDS_FTW_1HZ ((int32_t)(((uint64_t)1U * 4194304U + 12000U) / 24000U))
#define DDS_FTW_10HZ (DDS_FTW_1HZ * 10)
#define DDS_FTW_100HZ (DDS_FTW_1HZ * 100)
#define DDS_FTW_1000HZ (DDS_FTW_1HZ * 1000)
#define DDS_FTW_1300HZ (DDS_FTW_1HZ * 1300)
#define DDS_AMP_MIN 0U
#define DDS_AMP_1 1U
#define DDS_AMP_10 10U
#define DDS_AMP_100 100U
#define DDS_AMP_1000 1000U
#define DDS_AMP_10000 10000U
#define DDS_DUTY_MID (EPWM_PWM_PERIOD / 2U)
#define DDS_AMP_MAX ((((uint32_t)DDS_DUTY_MID - 1U) << 18) / 2047U)
struct dds_cal_param
{
uint32_t phase_acc;
uint8_t lut_idx;
uint8_t nquadrant;
uint8_t last_quadrant;
int16_t lut_sin_val;
int16_t lut_cos_val;
uint16_t duty;
};
struct dds_phase_error_cal_param
{
int16_t current_corrected;
int32_t sum_sine;
int32_t sum_cos;
int16_t m_point;
int32_t in_phase;
int32_t q_over_i;
int32_t err_sig;
int32_t magnitude;
};
void dds_pwm_stop(void);
void dds_pwm_start(void);
void dds_set_phase_acc_ftw(uint32_t ftw);
void dds_set_phase_acc_amp(uint32_t amp);
int32_t dds_freq_hz_to_ftw(uint32_t freq_hz);
struct dds_cal_param *dds_get_cal_param(uint16_t phase_idx);
struct dds_phase_error_cal_param *dds_get_phase_error_cal_param(void);
void dds_get_ftw_amp_setting(int32_t *ftw, uint32_t *amp);
void dds_pwm_duty_cycle_update(void);
uint8_t dds_is_change_duty_flags(void);
void dds_tim_period_elapsed(void);
#ifdef __cplusplus
}
#endif
#endif
-66
View File
@@ -1,66 +0,0 @@
#ifndef __MOTOR_CTRL_H__
#define __MOTOR_CTRL_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "main.h"
#include "epwm_drv.h"
#define PWM_LUT_SIZE (64U)
#define PHASE_CH 3
// 1Hz = pwm_lut_size * sub_step / pwm_clk
// 1Hz = 64 * 65536 / 24000 FTW approximately 174.762666
#define DDS_FTW_1HZ (PWM_LUT_SIZE * 65536 / 24000)
enum motor_ctrl_mode
{
MOTOR_TASK_IDLE = 0,
MOTOR_TASK_RUN = 1
};
struct dds_phase_output_t
{
uint32_t phase_acc;
uint8_t lut_idx;
uint8_t nquadrant;
uint8_t last_quadrant;
int16_t lut_sin_val;
int16_t lut_cos_val;
uint16_t duty;
};
struct motor_ctrl_ctx_t
{
uint16_t mode;
uint32_t phase_acc_base;
int32_t current_dds_ftw; // max: 2^22
int32_t current_dds_amp; // max: 2^7*1250
int32_t goal_dds_ftw;
int32_t goal_dds_amp;
int32_t begin_dds_ftw;
int32_t begin_dds_amp;
struct dds_phase_output_t dds_phase_out[PHASE_CH];
};
extern struct motor_ctrl_ctx_t g_motor_ctrl_t;
void motor_ctrl_init(void);
void motor_task(void);
void motor_ctrl_phase_accumulator(void);
void motor_ctrl_stop(void);
void motor_ctrl_start(void);
void dds_pwm_duty_cycle_update(void);
#ifdef __cplusplus
}
#endif
#endif
-19
View File
@@ -1,19 +0,0 @@
#ifndef __UART_CMD_SRV_H__
#define __UART_CMD_SRV_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "uart_drv.h"
#include "main.h"
void uart_cmd_process(void);
#ifdef __cplusplus
}
#endif
#endif
+8 -6
View File
@@ -1,14 +1,15 @@
#ifndef __DRV_UART_H__
#define __DRV_UART_H__
#ifndef __UART_DRV_H__
#define __UART_DRV_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "main.h"
#include "app_cfg.h"
#define UART_RX_BUF_SIZE 128
#define UART_RX_BUF_SIZE 64
#define UART_TX_BUF_SIZE 256
extern volatile char g_uart_rx_buf[UART_RX_BUF_SIZE];
extern volatile uint16_t g_uart_rx_idx;
@@ -16,8 +17,9 @@ extern "C"
#define uart_send_msg(str, ...) printf(str, ##__VA_ARGS__);
void uart_init(void);
void uart_clear_rx_frame(void);
int uart_drv_init(void);
int uart_drv_write(void *p_src, int src_size);
void uart_drv_clr_rx_frame(void);
bool uart_is_frame_ready(void);
#ifdef __cplusplus
+33
View File
@@ -0,0 +1,33 @@
#ifndef __UVW_ADC_H__
#define __UVW_ADC_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
#define ADC_BUF_LEN 8
#define IDX_IU_LF 0
#define IDX_IV_LF 1
#define IDX_IW_LF 2
#define IDX_IALL_LF 3
#define IDX_BEMF_U 4
#define IDX_BEMF_V 5
#define IDX_BEMF_W 6
#define IDX_VBUS 7
void adc_drv_init(void);
void adc_duty_cycle_set(float percentage);
void adc_timer_start(void);
void adc_timer_stop(void);
void get_adc_values_raw(uint16_t *buf, uint16_t len);
void get_adc_values_raw_one_channel(uint16_t channel, uint16_t *value);
#ifdef __cplusplus
}
#endif
#endif
+18 -23
View File
@@ -1,13 +1,5 @@
#include "epwm_drv.h"
#include "motor_ctrl.h"
#define HIRC_Freq 60000000 // Hz
#define CurrentLoopIsrFreq 24000 // Hz
#define PWM_PERIOD HIRC_Freq / CurrentLoopIsrFreq
#define DEAD_TIME 200 // ns
#define DEAD_TIME_VALUE DEAD_TIME * 0.06
static volatile bool g_epwm_24khz_tick = false;
__INTERRUPT void epwm_irq_handler(void)
@@ -17,15 +9,16 @@ __INTERRUPT void epwm_irq_handler(void)
/* Overflow happens once per PWM period -> 24kHz tick */
if ((EPWM->SR & 0x10000U) == 0x10000U)
{
extern void update_phase_accumulator(void);
update_phase_accumulator();
g_epwm_24khz_tick = true;
motor_ctrl_phase_accumulator();
TIM_ClearITPendingBit(EPWM, 0x10000U); // clear OVIF
}
RESTORE_IRQ_CSR_CONTEXT();
}
void epwm_en(bool en)
void epwm_drv_output_en(bool en)
{
if (en)
{
@@ -39,24 +32,14 @@ void epwm_en(bool en)
}
}
void epwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val)
void epwm_drv_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val)
{
TIM_SetCompare1(EPWM, ch1_val);
TIM_SetCompare2(EPWM, ch2_val);
TIM_SetCompare3(EPWM, ch3_val);
}
bool epwm_is_24khz_tick_and_clear(void)
{
bool ready = g_epwm_24khz_tick;
if (ready)
{
g_epwm_24khz_tick = false;
}
return ready;
}
void epwm_init(void)
void epwm_drv_init(void)
{
GPIO_InitTypeDef epwm_gpio_cfg = { 0 };
TIM_TimeBaseInitTypeDef tim_base_cfg = { 0 };
@@ -78,7 +61,7 @@ void epwm_init(void)
TIM_TimeBaseStructInit(&tim_base_cfg);
tim_base_cfg.TIM_Prescaler = 0;
tim_base_cfg.TIM_CounterMode = TIM_CounterMode_Up;
tim_base_cfg.TIM_Period = PWM_PERIOD - 1;
tim_base_cfg.TIM_Period = EPWM_PWM_PERIOD - 1;
tim_base_cfg.TIM_ClockDivision = TIM_CKD_Div1;
tim_base_cfg.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(EPWM, &tim_base_cfg);
@@ -105,6 +88,18 @@ void epwm_init(void)
// timer counter enable
TIM_Cmd(EPWM, ENABLE);
TIM_CtrlPWMOutputs(EPWM, DISABLE);
sys_enable_girq();
}
bool epwm_is_24khz_tick_and_clear(void)
{
if (g_epwm_24khz_tick)
{
g_epwm_24khz_tick = false;
return true;
}
return false;
}
+269 -8
View File
@@ -11,8 +11,12 @@
#include "main.h"
#include "epwm_drv.h"
#include "motor_ctrl.h"
#include "uart_cmd_srv.h"
#include "app_cfg.h"
#include "motor_control.h"
#include "uart_drv.h"
#include "uvw_adc.h"
//=============================================================================
// Constant Definition
//=============================================================================
@@ -32,6 +36,14 @@
//=============================================================================
// Private Function Definition
//=============================================================================
struct motor_ctx_t g_motor_ctx;
bool g_motor_running = false;
int32_t g_dds_ftw_setting = 0;
int32_t g_dds_amp_setting = 0;
uint32_t g_notify_time_ms = 0;
uint16_t g_notify_type = 0;
bool g_notify_en = false;
static void sysclk_init(void)
{
SYSCFG_ClkInitTypeDef SysClkInit = { 0 };
@@ -52,6 +64,242 @@ static void test_pin_init(void)
GPIO_WriteBit(GPIOA, GPIO_Pin_14, GPIO_PIN_LOW);
GPIO_Init(GPIOA, &gpio_init);
}
static void app_start_motor(void)
{
g_motor_running = true;
motor_ctrl_start();
}
static void app_stop_motor(void)
{
g_motor_running = false;
motor_ctrl_stop();
}
static void motor_ctrl_print_basic_data(void)
{
struct motor_ctx_t *motor = &g_motor_ctx;
uint8_t buffer[64] = { 0 };
uint8_t *ptr = buffer;
uint32_t mcu_timestamp = sys_get_tick();
uint16_t adc_values[ADC_BUF_LEN] = { 0 };
get_adc_values_raw(adc_values, ADC_BUF_LEN);
*ptr++ = 0x55;
*ptr++ = 0xAA;
*(uint16_t *)ptr = g_notify_type;
ptr += 2;
*(uint32_t *)ptr = mcu_timestamp;
ptr += 4;
*(int32_t *)ptr = ((int32_t)adc_values[IDX_IU_LF] - 2048) * (-1);
ptr += 4;
*(int32_t *)ptr = ((int32_t)adc_values[IDX_IV_LF] - 2048) * (-1);
ptr += 4;
*(int32_t *)ptr = ((int32_t)adc_values[IDX_IW_LF] - 2048) * (-1);
ptr += 4;
*(int32_t *)ptr = ((int32_t)adc_values[IDX_IALL_LF] - 2048);
ptr += 4;
*(int32_t *)ptr = adc_values[IDX_BEMF_U];
ptr += 4;
*(int32_t *)ptr = adc_values[IDX_BEMF_V];
ptr += 4;
*(int32_t *)ptr = adc_values[IDX_BEMF_W];
ptr += 4;
*(int32_t *)ptr = adc_values[IDX_VBUS];
ptr += 4;
*(uint32_t *)ptr = motor->current_dds_ftw;
ptr += 4;
*(int32_t *)ptr = motor->current_dds_amp;
ptr += 4;
*ptr++ = 0x0D;
*ptr++ = 0x0A;
uart_drv_write(buffer, (uint16_t)(ptr - buffer));
}
static void handle_notify_task(void)
{
if (!g_notify_en)
{
return;
}
if (g_notify_type == NOTIFY_TYPE_PERIOD)
{
return;
}
if (g_notify_type == NOTIFY_TYPE_BASIC) // every g_notify_time_ms ms print basic data once
{
static uint32_t notify_time = 0;
uint32_t now = sys_get_tick();
if (now - notify_time >= g_notify_time_ms)
{
notify_time = now;
motor_ctrl_print_basic_data();
}
}
}
void tool(uint32_t val)
{
switch (val)
{
case 1:
epwm_drv_output_en(1);
break;
case 2:
epwm_drv_output_en(0);
break;
}
}
static bool cmd_match_with_arg(const volatile char *buf, const char *prefix, const char **arg_out)
{
size_t len = strlen(prefix);
for (size_t i = 0; i < len; i++)
{
if (buf[i] != prefix[i])
return false;
}
if (buf[len] == ' ')
{
*arg_out = (const char *)&buf[len + 1];
return true;
}
return false;
}
static int32_t cmd_parse_int_list(const char *arg, int32_t *out, int32_t max_count)
{
int32_t count = 0;
char *end = NULL;
const char *p = arg;
while (*p != '\0' && count < max_count)
{
while (*p == ' ')
p++;
if (*p == '\0')
break;
out[count] = strtol(p, &end, 10);
if (end == p)
return -1;
count++;
p = end;
}
while (*p == ' ')
p++;
if (*p != '\0')
return -1;
return count;
}
static void handle_cmd_task(void)
{
char *data = (char *)g_uart_rx_buf;
const char *arg = NULL;
if (!uart_is_frame_ready())
{
return;
}
if (strncmp(data, "help", 4) == 0)
{
uart_send_msg("Available commands:\r\n");
uart_send_msg(" start - Start motor\r\n");
uart_send_msg(" stop - Stop motor\r\n");
uart_send_msg(" dds_ftw:<val> - Set dds_ftw\r\n");
uart_send_msg(" dds_amp:<val> - Set dds_amp\r\n");
uart_send_msg(" notify_ms:<val> - Set notify rate in ms\r\n");
uart_send_msg(" notify_type:<val> - Set notify type (0-3)\r\n");
uart_send_msg(" fw_ver - Show firmware version\r\n");
uart_send_msg(" help - Show this help\r\n");
}
else if (strncmp(data, "start", 5) == 0)
{
uart_send_msg("start motor\r\n");
}
else if (strncmp(data, "stop", 4) == 0)
{
uart_send_msg("stop motor\r\n");
}
else if (strncmp(data, "dds_ftw:", 8) == 0)
{
g_dds_ftw_setting = atoi(data + 8);
uart_send_msg("Set dds_ftw to %ld\r\n", g_dds_ftw_setting);
// dds_set_phase_acc_ftw((uint32_t)g_dds_ftw_setting);
}
else if (strncmp(data, "dds_amp:", 8) == 0)
{
g_dds_amp_setting = (uint32_t)atoi(data + 8);
g_dds_amp_setting = g_dds_amp_setting > DDS_AMP_MAX ? DDS_AMP_MAX : g_dds_amp_setting;
uart_send_msg("Set dds_amp to %lu\r\n", g_dds_amp_setting);
// dds_set_phase_acc_amp((uint32_t)g_dds_amp_setting);
}
else if (strncmp(data, "notify_ms:", 10) == 0)
{
g_notify_time_ms = (uint32_t)atoi(data + 10);
uart_send_msg("Set notify rate to %lu ms\r\n", g_notify_time_ms);
}
else if (strncmp(data, "notify_type:", 12) == 0)
{
g_notify_type = (uint16_t)atoi(data + 12);
uart_send_msg("Set notify type to %u\r\n", g_notify_type);
}
else if (strncmp(data, "fw_ver", 6) == 0)
{
uart_send_msg("FW_VER_PEC930_%s\r\n", FW_VERSION);
}
else if (cmd_match_with_arg(data, "debug_epwm_set_duty", &arg))
{
int32_t values[3] = { 0 };
int32_t parsed = cmd_parse_int_list(arg, values, 3);
if (parsed <= 0)
{
uart_send_msg("ERR usage: epwm_set_duty duty1 duty2 duty3\r\n");
}
else
{
epwm_drv_set_duty(values[0], values[1], values[2]);
uart_send_msg("OK epwm_set_duty: %ld %ld %ld\r\n", values[0], values[1], values[2]);
}
}
else if (cmd_match_with_arg(data, "debug_epwm_en", &arg))
{
if (arg[0] == '1')
{
epwm_drv_output_en(1);
uart_send_msg("OK epwm on\r\n");
}
else if (arg[0] == '0')
{
epwm_drv_output_en(0);
uart_send_msg("OK epwm off\r\n");
}
else
{
uart_send_msg("ERR usage: epwm_en 1/0\r\n");
}
}
else
{
uart_send_msg("ERR unknown cmd\r\n");
}
uart_drv_clr_rx_frame();
}
//=============================================================================
// Public Function Definition
//=============================================================================
@@ -59,17 +307,30 @@ int main(void)
{
sysclk_init();
test_pin_init();
epwm_init();
uart_init();
uart_send_msg("%s\r\n", "uart ok");
uart_drv_init();
epwm_drv_init();
motor_ctrl_init();
// adc_drv_init();
// motor_ctrl_apply_default_settings();
// app_stop_motor();
uart_send_msg("pec930 motor app ready\r\n");
while (1)
{
uart_cmd_process();
motor_task();
// while (pending_ticks-- > 0U)
// {
// dds_tim_period_elapsed();
// }
handle_cmd_task();
handle_motor_task();
handle_notify_task();
}
return 0;
}
+479
View File
@@ -0,0 +1,479 @@
#include "motor_control.h"
#include "uvw_adc.h"
#include "uart_drv.h"
struct vf_control_formula_t g_vf_control_formulas[2] = {
[VF_CTRL_FORMULA_STABLE] = {
.slope = VF_SLOPE_X10000,
.offset = (int32_t)(DDS_AMP_MAX * VF_OFFSET_STABLE_PCT),
},
[VF_CTRL_FORMULA_MIN] = {
.slope = VF_SLOPE_X10000,
.offset = VF_OFFSET_MIN,
},
};
static enum amp_ftw_control_mode_e g_amp_ftw_control_mode = AMP_FTW_FIXED_FIXED;
static enum motor_mode_e g_motor_mode = MOTOR_MODE_RUN;
static int32_t div_round_closest(int32_t numerator, uint32_t denominator)
{
if (denominator == 0U)
{
return 0;
}
if (numerator >= 0)
{
return (numerator + (int32_t)(denominator / 2U)) / (int32_t)denominator;
}
return (numerator - (int32_t)(denominator / 2U)) / (int32_t)denominator;
}
enum motor_mode_e motor_ctrl_get_mode(void)
{
return g_motor_mode;
}
void motor_ctrl_set_amp_ftw_mode(enum amp_ftw_control_mode_e mode)
{
g_amp_ftw_control_mode = mode;
}
void motor_ctrl_set_mode(enum motor_mode_e mode)
{
g_motor_mode = mode;
}
void motor_ctrl_start(void)
{
dds_pwm_start();
adc_timer_start();
}
void motor_ctrl_stop(void)
{
dds_pwm_stop();
adc_timer_stop();
dds_set_phase_acc_ftw(0);
dds_set_phase_acc_amp(0);
g_motor_mode = MOTOR_MODE_RUN;
g_amp_ftw_control_mode = AMP_FTW_FIXED_FIXED;
}
static uint32_t motor_ctrl_vf_formula_cal(enum vf_control_use_type_e vf_control_use_type, int32_t dftw)
{
struct vf_control_formula_t *formula = &g_vf_control_formulas[vf_control_use_type];
int32_t damp = (dftw * formula->slope) / 10000 + formula->offset;
if (damp < 0)
{
return 0;
}
return (uint32_t)damp > DDS_AMP_MAX ? DDS_AMP_MAX : (uint32_t)damp;
}
static void motor_ctrl_soft_start_mode(struct old_cmd_param_t *cmd_param)
{
static int32_t dftw_step = 0;
static int32_t dftw_goal = 0;
static int32_t damp_first = 0;
int32_t dftw = 0;
uint32_t damp = 0;
if (cmd_param->soft_start.dds_ftw_first == cmd_param->soft_start.dds_ftw_goal)
{
g_motor_mode = MOTOR_MODE_RUN;
return;
}
if (g_amp_ftw_control_mode == AMP_FTW_FIXED_FIXED)
{
damp_first = (int32_t)cmd_param->soft_start.dds_amp_first;
dftw_goal = cmd_param->soft_start.dds_ftw_goal;
dftw_step = div_round_closest(cmd_param->soft_start.dds_ftw_goal - cmd_param->soft_start.dds_ftw_first,
cmd_param->soft_start.soft_start_time_ms);
if (dftw_step == 0 && cmd_param->soft_start.dds_ftw_goal != cmd_param->soft_start.dds_ftw_first)
{
dftw_step = (cmd_param->soft_start.dds_ftw_goal > cmd_param->soft_start.dds_ftw_first) ? 1 : -1;
}
g_vf_control_formulas[VF_CTRL_FORMULA_STABLE].offset = cmd_param->soft_start.curve_offset;
dds_set_phase_acc_ftw((uint32_t)cmd_param->soft_start.dds_ftw_first);
dds_set_phase_acc_amp(cmd_param->soft_start.dds_amp_first);
g_amp_ftw_control_mode = AMP_FTW_FIXED_VARIABLE;
}
else if (g_amp_ftw_control_mode == AMP_FTW_FIXED_VARIABLE)
{
dds_get_ftw_amp_setting(&dftw, &damp);
dftw += dftw_step;
dds_set_phase_acc_ftw((uint32_t)dftw);
if (motor_ctrl_vf_formula_cal(VF_CTRL_FORMULA_STABLE, dftw) >= (uint32_t)damp_first)
{
g_amp_ftw_control_mode = AMP_FTW_VARIABLE_VARIABLE;
}
}
else if (g_amp_ftw_control_mode == AMP_FTW_VARIABLE_VARIABLE)
{
dds_get_ftw_amp_setting(&dftw, &damp);
dftw += dftw_step;
damp = motor_ctrl_vf_formula_cal(VF_CTRL_FORMULA_STABLE, dftw);
dds_set_phase_acc_ftw((uint32_t)dftw);
dds_set_phase_acc_amp(damp);
if ((dftw_step >= 0 && dftw >= dftw_goal) || (dftw_step < 0 && dftw <= dftw_goal) || damp >= DDS_AMP_MAX)
{
g_motor_mode = MOTOR_MODE_RUN;
}
}
}
void motor_ctrl_apply_default_settings(struct old_cmd_param_t *cmd_param)
{
adc_duty_cycle_set(0.18f);
dds_set_phase_acc_ftw((uint32_t)cmd_param->dds_ftw);
dds_set_phase_acc_amp(cmd_param->dds_amp);
}
void update_phase_accumulator(void)
{
struct motor_ctx_t *motor = &g_motor_ctx;
motor->phase_acc_base += motor->current_dds_ftw;
}
void handle_motor_task(void)
{
struct motor_ctx_t *motor = &g_motor_ctx;
if (motor->mode == MOTOR_TASK_IDLE || g_motor_running == false)
{
return;
}
if (epwm_is_24khz_tick_and_clear())
{
dds_pwm_duty_cycle_update();
}
// static uint32_t update_damp_dftw_time = 0;
// uint32_t now = sys_get_tick();
// if ((now - update_damp_dftw_time) >= 1U)
// {
// update_damp_dftw_time = now;
// if (g_motor_mode == MOTOR_MODE_SOFT_START)
// {
// motor_ctrl_soft_start_mode(cmd_param);
// }
// }
// if (dds_is_change_duty_flags())
// {
// dds_pwm_duty_cycle_update();
// }
}
static uint8_t g_change_duty_flags = 0;
static int32_t g_set_dds_ftw = 0;
static uint32_t g_set_dds_amp = 0;
static uint32_t g_dds_phase_acc = 0;
static struct dds_cal_param g_phase[3] = { 0 };
static struct dds_phase_error_cal_param g_phase_cal = { 0 };
static bool g_vf_ctrl_fb_enabled = false;
const uint32_t phase_offset[PHASE_CH] = { 0, 1398101, 2796203 };
// clang-format off
static const int16_t g_lut_sin[64] = {
0, 200, 399, 594, 783, 965, 1137, 1298,
1447, 1582, 1702, 1805, 1891, 1959, 2008, 2037,
2047, 2037, 2008, 1959, 1891, 1805, 1702, 1582,
1447, 1298, 1137, 965, 783, 594, 399, 200,
0, -200, -399, -594, -783, -965, -1137, -1298,
-1447, -1582, -1702, -1805, -1891, -1959, -2008, -2037,
-2047, -2037, -2008, -1959, -1891, -1805, -1702, -1582,
-1447, -1298, -1137, -965, -783, -594, -399, -200,
};
// clang-format on
// clang-format off
static const int16_t g_lut_cos[64] = {
2047, 2037, 2008, 1959, 1891, 1805, 1702, 1582,
1447, 1298, 1137, 965, 783, 594, 399, 200,
0, -200, -399, -594, -783, -965, -1137, -1298,
-1447, -1582, -1702, -1805, -1891, -1959, -2008, -2037,
-2047, -2037, -2008, -1959, -1891, -1805, -1702, -1582,
-1447, -1298, -1137, -965, -783, -594, -399, -200,
0, 200, 399, 594, 783, 965, 1137, 1298,
1447, 1582, 1702, 1805, 1891, 1959, 2008, 2037,
};
// clang-format on
static uint32_t isqrt_u64(uint64_t value)
{
uint64_t op = value;
uint64_t res = 0;
uint64_t one = 1ULL << 62;
while (one > op)
{
one >>= 2;
}
while (one != 0)
{
if (op >= res + one)
{
op -= res + one;
res = (res >> 1) + one;
}
else
{
res >>= 1;
}
one >>= 2;
}
return (uint32_t)res;
}
static void print_period_data(uint16_t print_type, struct dds_cal_param *phase, struct dds_phase_error_cal_param *phase_error_cal)
{
uint8_t buffer[64] = { 0 };
uint8_t *ptr = buffer;
uint32_t mcu_timestamp = sys_get_tick();
*ptr++ = 0x55;
*ptr++ = 0xAA;
*(uint16_t *)ptr = print_type;
ptr += 2;
*(uint32_t *)ptr = mcu_timestamp;
ptr += 4;
*(uint32_t *)ptr = phase[PHASE_U].phase_acc;
ptr += 4;
*(uint32_t *)ptr = phase[PHASE_V].phase_acc;
ptr += 4;
*(uint32_t *)ptr = phase[PHASE_W].phase_acc;
ptr += 4;
*(uint32_t *)ptr = g_set_dds_amp;
ptr += 4;
*(int32_t *)ptr = g_set_dds_ftw;
ptr += 4;
*(int16_t *)ptr = phase_error_cal->current_corrected;
ptr += 2;
*(int16_t *)ptr = phase_error_cal->m_point;
ptr += 2;
*(int32_t *)ptr = phase_error_cal->sum_sine;
ptr += 4;
*(int32_t *)ptr = phase_error_cal->sum_cos;
ptr += 4;
*(int32_t *)ptr = phase_error_cal->err_sig;
ptr += 4;
*(int32_t *)ptr = phase_error_cal->magnitude;
ptr += 4;
*ptr++ = 0x0D;
*ptr++ = 0x0A;
uart_drv_write(buffer, (uint16_t)(ptr - buffer));
}
static void fix_amp_fb(int32_t err_sig)
{
int32_t dftw = 0;
uint32_t damp = 0;
int32_t next_damp = 0;
dds_get_ftw_amp_setting(&dftw, &damp);
next_damp = (int32_t)damp;
if (err_sig <= -300 && err_sig >= -700)
{
next_damp += (err_sig >= -500) ? 1 : -1;
}
else if (err_sig > -300)
{
next_damp += 10;
}
else if (err_sig < -700)
{
next_damp -= 10;
}
if (next_damp < 0)
{
next_damp = 0;
}
else if ((uint32_t)next_damp > DDS_AMP_MAX)
{
next_damp = (int32_t)DDS_AMP_MAX;
}
dds_set_phase_acc_ftw((uint32_t)dftw);
dds_set_phase_acc_amp((uint32_t)next_damp);
}
void dds_pwm_start(void)
{
g_dds_phase_acc = 0;
g_phase_cal.sum_sine = 0;
g_phase_cal.sum_cos = 0;
g_phase_cal.m_point = 0;
g_phase_cal.err_sig = 0;
g_phase_cal.magnitude = 0;
for (uint32_t i = 0; i < 3U; i++)
{
g_phase[i].nquadrant = 0;
g_phase[i].last_quadrant = 0;
}
epwm_drv_output_en(true);
}
void dds_pwm_stop(void)
{
epwm_drv_output_en(false);
}
void dds_set_phase_acc_ftw(uint32_t ftw)
{
g_set_dds_ftw = (int32_t)ftw;
}
void dds_set_phase_acc_amp(uint32_t amp)
{
g_set_dds_amp = amp > DDS_AMP_MAX ? DDS_AMP_MAX : amp;
}
int32_t dds_freq_hz_to_ftw(uint32_t freq_hz)
{
return (int32_t)(((uint64_t)freq_hz * 4194304U + 12000U) / 24000U);
}
uint8_t dds_is_change_duty_flags(void)
{
return g_change_duty_flags;
}
struct dds_cal_param *dds_get_cal_param(uint16_t phase_idx)
{
return &g_phase[phase_idx];
}
struct dds_phase_error_cal_param *dds_get_phase_error_cal_param(void)
{
return &g_phase_cal;
}
void dds_get_ftw_amp_setting(int32_t *ftw, uint32_t *amp)
{
if (ftw != NULL)
{
*ftw = g_set_dds_ftw;
}
if (amp != NULL)
{
*amp = g_set_dds_amp;
}
}
// void dds_pwm_duty_cycle_update(void)
// {
// struct motor_ctrl_ctx_t *motor = &g_motor_ctrl_t;
// struct dds_phase_output_t *u = &motor->dds_phase_out[0];
// struct dds_phase_output_t *v = &motor->dds_phase_out[1];
// struct dds_phase_output_t *w = &motor->dds_phase_out[2];
// for (int i = 0; i < PHASE_CH; i++)
// {
// struct dds_phase_output_t *p = &motor->dds_phase_out[i];
// p->phase_acc = (motor->phase_acc_base + phase_offset[i]) % 0x003FFFFF;
// p->last_quadrant = p->nquadrant;
// p->lut_idx = p->phase_acc >> 16;
// p->nquadrant = p->lut_idx >> 4;
// p->lut_sin_val = LUT_sin[p->lut_idx];
// p->lut_cos_val = LUT_cos[p->lut_idx];
// p->duty = (((int32_t)p->lut_sin_val * motor->current_dds_amp) >> 18) + 1250; // 0~2500 duty cycle range
// }
// epwm_set_duty(u->duty, v->duty, w->duty);
// }
void dds_pwm_duty_cycle_update(void)
{
struct motor_ctx_t *motor = &g_motor_ctx;
struct dds_output_t *u = &motor->phase_out[0];
struct dds_output_t *v = &motor->phase_out[1];
struct dds_output_t *w = &motor->phase_out[2];
// uint16_t adc_iu_lf = 0;
for (int i = 0; i < PHASE_CH; i++)
{
struct dds_output_t *p = &motor->phase_out[i];
p->phase_acc = (motor->phase_acc_base + phase_offset[i]) % 0x003FFFFF;
p->last_quadrant = p->nquadrant;
p->lut_idx = p->phase_acc >> 16;
p->nquadrant = p->lut_idx >> 4;
p->lut_sin_val = g_lut_sin[p->lut_idx];
p->lut_cos_val = g_lut_cos[p->lut_idx];
p->duty = (((int32_t)p->lut_sin_val * motor->current_dds_amp) >> 18) + 1250; // 0~2500 duty cycle range
// if (p->last_quadrant == 1U && p->nquadrant == 2U)
// {
// adc_duty_cycle_set(0.60f);
// }
// else if (p->last_quadrant == 3U && p->nquadrant == 0U)
// {
// adc_duty_cycle_set(0.18f);
// }
}
// get_adc_values_raw_one_channel(IDX_IU_LF, &adc_iu_lf);
// g_phase_cal.m_point += 1;
// g_phase_cal.current_corrected = ((int16_t)adc_iu_lf - 2048) * (-1);
// g_phase_cal.sum_sine += ((int32_t)g_phase[PHASE_U].lut_sin_val) * g_phase_cal.current_corrected;
// g_phase_cal.sum_cos += ((int32_t)g_phase[PHASE_U].lut_cos_val) * g_phase_cal.current_corrected;
// if (g_phase[PHASE_U].last_quadrant == 3U && g_phase[PHASE_U].nquadrant == 0U)
// {
// if (g_phase_cal.sum_sine != 0)
// {
// int32_t avg_sine = g_phase_cal.sum_sine / g_phase_cal.m_point;
// int32_t avg_cos = g_phase_cal.sum_cos / g_phase_cal.m_point;
// g_phase_cal.err_sig = (avg_cos * 1024) / avg_sine;
// g_phase_cal.magnitude = (int32_t)isqrt_u64((uint64_t)((int64_t)avg_sine * avg_sine) + (uint64_t)((int64_t)avg_cos * avg_cos)) * g_phase_cal.m_point;
// g_vf_ctrl_fb_enabled = cmd->vf_ctrl_fb_enabled;
// if (g_vf_ctrl_fb_enabled && motor_mode == MOTOR_MODE_RUN)
// {
// fix_amp_fb(g_phase_cal.err_sig);
// }
// }
// if (cmd->notify_type == NOTIFY_TYPE_PERIOD)
// {
// print_period_data(cmd->notify_type, g_phase, &g_phase_cal);
// }
// g_phase_cal.sum_sine = 0;
// g_phase_cal.sum_cos = 0;
// g_phase_cal.m_point = 0;
// }
epwm_drv_set_duty(u->duty, v->duty, w->duty);
// g_change_duty_flags &= (uint8_t)~1U;
}
void dds_tim_period_elapsed(void)
{
g_dds_phase_acc += (uint32_t)g_set_dds_ftw;
g_change_duty_flags |= 1U;
}
-50
View File
@@ -1,50 +0,0 @@
#include "motor_ctrl.h"
struct motor_ctrl_ctx_t g_motor_ctrl_t;
void motor_ctrl_phase_accumulator(void)
{
if (g_motor_ctrl_t.mode == MOTOR_TASK_RUN)
{
g_motor_ctrl_t.phase_acc_base += g_motor_ctrl_t.current_dds_ftw;
}
}
void motor_ctrl_init(void)
{
struct motor_ctrl_ctx_t *m = &g_motor_ctrl_t;
m->mode = MOTOR_TASK_IDLE;
m->phase_acc_base = 0;
m->current_dds_ftw = 0;
}
void motor_ctrl_start(void)
{
struct motor_ctrl_ctx_t *m = &g_motor_ctrl_t;
motor_ctrl_init();
m->current_dds_ftw = DDS_FTW_1HZ * 80;
m->current_dds_amp = 160000;
m->mode = MOTOR_TASK_RUN;
epwm_en(1);
}
void motor_ctrl_stop(void)
{
epwm_en(0);
motor_ctrl_init();
}
void motor_task(void)
{
if (g_motor_ctrl_t.mode == MOTOR_TASK_IDLE)
return;
if (epwm_is_24khz_tick_and_clear())
{
dds_pwm_duty_cycle_update();
}
}
-33
View File
@@ -1,33 +0,0 @@
#include "motor_ctrl.h"
const uint32_t phase_offset[PHASE_CH] = { 0, 1398101, 2796203 };
// 64-point sine wave lookup table (-2048-2047 range)
// Sine_table[i] = sin(i*2*pi/64)*(4095/2) where i = 0 to 63
// Use sine_amplitude parameter to scale to desired duty cycle range later
const int16_t LUT_sin[PWM_LUT_SIZE] = { 0, 200, 399, 594, 783, 965, 1137, 1298, 1447, 1582, 1702, 1805, 1891, 1959, 2008, 2037, 2047, 2037, 2008, 1959, 1891, 1805, 1702, 1582, 1447, 1298, 1137, 965, 783, 594, 399, 200, 0, -200, -399, -594, -783, -965, -1137, -1298, -1447, -1582, -1702, -1805, -1891, -1959, -2008, -2037, -2047, -2037, -2008, -1959, -1891, -1805, -1702, -1582, -1447, -1298, -1137, -965, -783, -594, -399, -200 };
const int16_t LUT_cos[PWM_LUT_SIZE] = { 2047, 2037, 2008, 1959, 1891, 1805, 1702, 1582, 1447, 1298, 1137, 965, 783, 594, 399, 200, 0, -200, -399, -594, -783, -965, -1137, -1298, -1447, -1582, -1702, -1805, -1891, -1959, -2008, -2037, -2047, -2037, -2008, -1959, -1891, -1805, -1702, -1582, -1447, -1298, -1137, -965, -783, -594, -399, -200, 0, 200, 399, 594, 783, 965, 1137, 1298, 1447, 1582, 1702, 1805, 1891, 1959, 2008, 2037 };
void dds_pwm_duty_cycle_update(void)
{
struct motor_ctrl_ctx_t *motor = &g_motor_ctrl_t;
struct dds_phase_output_t *u = &motor->dds_phase_out[0];
struct dds_phase_output_t *v = &motor->dds_phase_out[1];
struct dds_phase_output_t *w = &motor->dds_phase_out[2];
for (int i = 0; i < PHASE_CH; i++)
{
struct dds_phase_output_t *p = &motor->dds_phase_out[i];
p->phase_acc = (motor->phase_acc_base + phase_offset[i]) % 0x003FFFFF;
p->last_quadrant = p->nquadrant;
p->lut_idx = p->phase_acc >> 16;
p->nquadrant = p->lut_idx >> 4;
p->lut_sin_val = LUT_sin[p->lut_idx];
p->lut_cos_val = LUT_cos[p->lut_idx];
p->duty = (((int32_t)p->lut_sin_val * motor->current_dds_amp) >> 18) + 1250; // 0~2500 duty cycle range
}
epwm_set_duty(u->duty, v->duty, w->duty);
}
-152
View File
@@ -1,152 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "uart_cmd_srv.h"
#include "motor_ctrl.h"
static bool cmd_match_with_arg(const volatile char *buf, const char *prefix, const char **arg_out)
{
size_t len = strlen(prefix);
for (size_t i = 0; i < len; i++)
{
if (buf[i] != prefix[i])
return false;
}
if (buf[len] == ' ')
{
*arg_out = (const char *)&buf[len + 1];
return true;
}
return false;
}
static int32_t cmd_parse_int_list(const char *arg, int32_t *out, int32_t max_count)
{
int32_t count = 0;
char *end = NULL;
const char *p = arg;
while (*p != '\0' && count < max_count)
{
while (*p == ' ')
p++;
if (*p == '\0')
break;
out[count] = strtol(p, &end, 10);
if (end == p)
return -1;
count++;
p = end;
}
while (*p == ' ')
p++;
if (*p != '\0')
return -1;
return count;
}
void uart_cmd_process(void)
{
if (!uart_is_frame_ready())
return;
const char *arg = NULL;
char *cmd = (char *)g_uart_rx_buf;
if (strcmp(cmd, "help") == 0)
{
uart_send_msg("Commands:\r\n");
uart_send_msg(" help - show this help\r\n");
uart_send_msg(" fw_ver - show firmware version\r\n");
uart_send_msg(" epwm_en 1/0 - enable/disable EPWM output\r\n");
uart_send_msg(" epwm_set_duty d1 d2 d3 - set duty for 3 channels\r\n");
uart_send_msg(" mode_run 1/0 - start/stop motor control task\r\n");
uart_send_msg(" val n1 n2 ... - parse integer values\r\n");
}
else if (strcmp(cmd, "fw_ver") == 0)
{
uart_send_msg("FW: " FW_VERSION "\r\n");
}
else if (cmd_match_with_arg(cmd, "epwm_en", &arg))
{
if (arg[0] == '1')
{
epwm_en(1);
uart_send_msg("OK epwm on\r\n");
}
else if (arg[0] == '0')
{
epwm_en(0);
uart_send_msg("OK epwm off\r\n");
}
else
{
uart_send_msg("ERR usage: epwm_en 1/0\r\n");
}
}
else if (cmd_match_with_arg(cmd, "epwm_set_duty", &arg))
{
int32_t values[3] = { 0 };
int32_t parsed = cmd_parse_int_list(arg, values, 3);
if (parsed <= 0)
{
uart_send_msg("ERR usage: epwm_set_duty duty1 duty2 duty3\r\n");
}
else
{
epwm_set_duty(values[0], values[1], values[2]);
uart_send_msg("OK epwm_set_duty: %d %d %d\r\n", values[0], values[1], values[2]);
}
}
else if (cmd_match_with_arg(cmd, "mode_run", &arg))
{
if (arg[0] == '1')
{
motor_ctrl_start();
uart_send_msg("OK mode_run on\r\n");
}
else if (arg[0] == '0')
{
motor_ctrl_stop();
uart_send_msg("OK mode_run off\r\n");
}
else
{
uart_send_msg("ERR usage: mode_run 1/0\r\n");
}
}
else if (cmd_match_with_arg(cmd, "val", &arg))
{
int32_t values[8] = { 0 };
int32_t parsed = cmd_parse_int_list(arg, values, 8);
if (parsed <= 0)
{
uart_send_msg("ERR usage: val n1 n2 ...\r\n");
}
else
{
for (int32_t i = 0; i < parsed; i++)
{
char buf[32];
snprintf(buf, sizeof(buf), "%d\r\n", values[i]);
uart_send_msg(buf);
}
}
}
else
{
uart_send_msg("ERR unknown cmd\r\n");
}
// reset for next command
uart_clear_rx_frame();
}
+35 -22
View File
@@ -12,6 +12,8 @@
#define UART_RX_PIN GPIO_Pin_05
#define UART_RX_AF GPIO_AF_1
char g_uart_tx_buf[UART_TX_BUF_SIZE];
volatile char g_uart_rx_buf[UART_RX_BUF_SIZE];
volatile uint16_t g_uart_rx_idx = 0;
volatile bool g_uart_rx_complete = false;
@@ -41,29 +43,11 @@ __INTERRUPT void uart_rx_handler(void)
RESTORE_IRQ_CSR_CONTEXT();
}
// void uart_cmd_send_str(const char *str)
// {
// while (*str)
// {
// UART_SendData(UART_DEVICE, *str++);
// UART_WaitTxFifoEmpty(UART_DEVICE);
// }
// }
void uart_clear_rx_frame(void)
{
g_uart_rx_idx = 0;
g_uart_rx_complete = false;
}
bool uart_is_frame_ready(void)
{
return g_uart_rx_complete;
}
/* Configure PB3 as UART0 TX, PB5 as UART0 RX */
void uart_init(void)
int uart_drv_init(void)
{
__disable_irq();
GPIO_InitTypeDef gpio_init_cfg = { 0 };
UART_InitTypeDef uart_init_cfg = { 0 };
@@ -98,5 +82,34 @@ void uart_init(void)
/* Start UART */
UART_Start(UART_DEVICE);
sys_enable_girq();
__enable_irq();
return 0;
}
int uart_drv_write(void *p_src, int src_size)
{
if (p_src == NULL)
return 0;
memcpy(g_uart_tx_buf, p_src, src_size);
for (uint16_t i = 0; i < src_size; i++)
{
UART_SendData(UART_DEVICE, g_uart_tx_buf[i]);
UART_WaitTxFifoEmpty(UART_DEVICE);
}
return src_size;
}
void uart_drv_clr_rx_frame(void)
{
g_uart_rx_idx = 0;
g_uart_rx_complete = false;
}
bool uart_is_frame_ready(void)
{
return g_uart_rx_complete;
}
+57
View File
@@ -0,0 +1,57 @@
#include "uvw_adc.h"
static uint16_t g_adc_stub_values[ADC_BUF_LEN] = {
2048,
2048,
2048,
2048,
0,
0,
0,
0,
};
void adc_drv_init(void)
{
}
void adc_duty_cycle_set(float percentage)
{
(void)percentage;
}
void adc_timer_start(void)
{
}
void adc_timer_stop(void)
{
}
void get_adc_values_raw(uint16_t *buf, uint16_t len)
{
if (buf == 0)
{
return;
}
if (len > ADC_BUF_LEN)
{
len = ADC_BUF_LEN;
}
for (uint16_t i = 0; i < len; i++)
{
buf[i] = g_adc_stub_values[i];
}
}
void get_adc_values_raw_one_channel(uint16_t channel, uint16_t *value)
{
if (value == 0 || channel >= ADC_BUF_LEN)
{
return;
}
*value = g_adc_stub_values[channel];
}