8 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
roy01 17b60b9452 fix: remove isr.c 2026-04-22 09:31:51 +08:00
roy01 c17830ee1c feat: add flash-only configurations for Ubuntu and Windows in launch.json 2026-04-17 15:56:25 +08:00
roy01 d980b5196a feat: comment out target_link_libraries for libSysDev_PEC930.a 2026-04-13 16:05:04 +08:00
15 changed files with 1409 additions and 143 deletions
+15 -1
View File
@@ -16,6 +16,13 @@
"postDebugTask": "Stop OpenOCD (Ubuntu)", "postDebugTask": "Stop OpenOCD (Ubuntu)",
"overrideGDBServerStartedRegex": "Listening on port", "overrideGDBServerStartedRegex": "Listening on port",
}, },
{
"name": "Ubuntu Flash Only (No GDB)",
"type": "node-terminal",
"request": "launch",
"cwd": "${workspaceFolder}",
"command": "${workspaceFolder}/openocd/linux/2025.10/bin/openocd -s openocd/linux/2025.10/scripts -f openocd/linux/2025.10/scripts/target/pec930.cfg -c \"program ./build/Debug/pec930_motor.elf verify reset exit\""
},
{ {
"name": "Windows RISC-V Debug (OpenOCD)", "name": "Windows RISC-V Debug (OpenOCD)",
"type": "cortex-debug", "type": "cortex-debug",
@@ -30,7 +37,14 @@
"preLaunchTask": "Start OpenOCD (Windows)", "preLaunchTask": "Start OpenOCD (Windows)",
"postDebugTask": "Stop OpenOCD (Windows)", "postDebugTask": "Stop OpenOCD (Windows)",
"overrideGDBServerStartedRegex": "Listening on port", "overrideGDBServerStartedRegex": "Listening on port",
} },
{
"name": "Windows Flash Only (No GDB)",
"type": "node-terminal",
"request": "launch",
"cwd": "${workspaceFolder}",
"command": "${workspaceFolder}\\openocd\\win\\2025.10\\bin\\openocd.exe -s openocd\\win\\2025.10\\scripts -f openocd\\win\\2025.10\\scripts\\target\\pec930.cfg -c \"program .\\build\\Debug\\pec930_motor.elf verify reset exit\""
},
] ]
} }
+4 -3
View File
@@ -50,6 +50,7 @@ set(HAL_SOURCES
${PEC930_SDK_DIR}/Drivers/PEC930/HAL_Lib/src/hal_syscfg.c ${PEC930_SDK_DIR}/Drivers/PEC930/HAL_Lib/src/hal_syscfg.c
${PEC930_SDK_DIR}/Drivers/PEC930/HAL_Lib/src/hal_uart.c ${PEC930_SDK_DIR}/Drivers/PEC930/HAL_Lib/src/hal_uart.c
${PEC930_SDK_DIR}/Drivers/PEC930/HAL_Lib/src/hal_gpio.c ${PEC930_SDK_DIR}/Drivers/PEC930/HAL_Lib/src/hal_gpio.c
${PEC930_SDK_DIR}/Drivers/PEC930/HAL_Lib/src/hal_tim.c
) )
set(COMMON_SOURCES set(COMMON_SOURCES
@@ -107,9 +108,9 @@ target_link_options(${EXECUTABLE} PRIVATE
-Wl,--no-warn-rwx-segments -Wl,--no-warn-rwx-segments
) )
target_link_libraries(${EXECUTABLE} PRIVATE # target_link_libraries(${EXECUTABLE} PRIVATE
"${PEC930_SDK_DIR}/Drivers/PEC930/libSysDev_PEC930.a" # "${PEC930_SDK_DIR}/Drivers/PEC930/libSysDev_PEC930.a"
) # )
# Optional: Print executable size as part of the post build process # Optional: Print executable size as part of the post build process
add_custom_command(TARGET ${EXECUTABLE} add_custom_command(TARGET ${EXECUTABLE}
+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
+24
View File
@@ -0,0 +1,24 @@
#ifndef __EPWM_DRV_H__
#define __EPWM_DRV_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "app_cfg.h"
#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
}
#endif
#endif
-50
View File
@@ -1,50 +0,0 @@
/**
* Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved.
*/
/** @file isr.h
*
* @author Wei-Lun Hsu
* @version 0.1
* @date 2024/09/16
* @license
* @description
*/
#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__
#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
//=============================================================================
// Constant Definition
//=============================================================================
//=============================================================================
// Macro Definition
//=============================================================================
//=============================================================================
// Structure Definition
//=============================================================================
//=============================================================================
// Global Data Definition
//=============================================================================
//=============================================================================
// Private Function Definition
//=============================================================================
//=============================================================================
// Public Function Definition
//=============================================================================
#ifdef __cplusplus
}
#endif
#endif
+6 -7
View File
@@ -1,11 +1,10 @@
/** /**
* Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. * Copyright (c) 2026 Wisetop. All Rights Reserved.
*/ */
/** @file main.h /** @file main.c
* *
* @author Wei-Lun Hsu * @version 0.0.1
* @version 0.1 * @date 2026/04/22
* @date 2024/08/29
* @license * @license
* @description * @description
*/ */
@@ -14,10 +13,10 @@
#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ #define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
#include "hal_device.h" #include "hal_device.h"
#include "syslog.h" #include "syslog.h"
//============================================================================= //=============================================================================
+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
+29
View File
@@ -0,0 +1,29 @@
#ifndef __UART_DRV_H__
#define __UART_DRV_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "app_cfg.h"
#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;
extern volatile bool g_uart_rx_complete;
#define uart_send_msg(str, ...) printf(str, ##__VA_ARGS__);
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
}
#endif
#endif
+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
+105
View File
@@ -0,0 +1,105 @@
#include "epwm_drv.h"
static volatile bool g_epwm_24khz_tick = false;
__INTERRUPT void epwm_irq_handler(void)
{
SAVE_IRQ_CSR_CONTEXT();
/* 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;
TIM_ClearITPendingBit(EPWM, 0x10000U); // clear OVIF
}
RESTORE_IRQ_CSR_CONTEXT();
}
void epwm_drv_output_en(bool en)
{
if (en)
{
// main output enable
TIM_CtrlPWMOutputs(EPWM, ENABLE);
}
else
{
// main output disable
TIM_CtrlPWMOutputs(EPWM, DISABLE);
}
}
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);
}
void epwm_drv_init(void)
{
GPIO_InitTypeDef epwm_gpio_cfg = { 0 };
TIM_TimeBaseInitTypeDef tim_base_cfg = { 0 };
TIM_OCInitTypeDef tim_oc_cfg = { 0 };
sys_irq_attr_t irq_attr = {
.trig_mode = SYS_IRQ_TRIGGER_LEVEL,
.level = SYS_IRQ_LEVEL_H,
.priority = SYS_IRQ_PRIORITY_MIDDEN,
};
// gpio config
epwm_gpio_cfg.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 |
GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05;
epwm_gpio_cfg.GPIO_Mode = GPIO_Mode_AF;
epwm_gpio_cfg.GPIO_AF_Mode = GPIO_AF_6;
GPIO_Init(GPIOA, &epwm_gpio_cfg);
// timer base config
TIM_TimeBaseStructInit(&tim_base_cfg);
tim_base_cfg.TIM_Prescaler = 0;
tim_base_cfg.TIM_CounterMode = TIM_CounterMode_Up;
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);
TIM_ARRPreloadConfig(EPWM, ENABLE);
// timer output compare config
TIM_OCStructInit(&tim_oc_cfg);
tim_oc_cfg.TIM_OCMode = TIM_OCMode_PWM1;
tim_oc_cfg.TIM_OutputState = TIM_OutputState_Enable;
tim_oc_cfg.TIM_OutputNState = TIM_OutputNState_Enable;
tim_oc_cfg.TIM_Pulse = 0;
tim_oc_cfg.TIM_OCPolarity = TIM_OCPolarity_High;
tim_oc_cfg.TIM_OCNPolarity = TIM_OCNPolarity_High;
tim_oc_cfg.TIM_OCIdleState = TIM_OCIdleState_Reset;
tim_oc_cfg.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
TIM_OC1Init(EPWM, &tim_oc_cfg);
TIM_OC2Init(EPWM, &tim_oc_cfg);
TIM_OC3Init(EPWM, &tim_oc_cfg);
// register EPWM IRQ and enable overflow interrupt source
sys_register_IRQ(EPWM_IRQn, epwm_irq_handler, &irq_attr);
EPWM->DIER |= 0x0800U; // over flow
TIM_ClearITPendingBit(EPWM, 0x10000U);
// 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;
}
-39
View File
@@ -1,39 +0,0 @@
/**
* Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved.
*/
/** @file isr.c
*
* @author Wei-Lun Hsu
* @version 0.1
* @date 2024/09/16
* @license
* @description
*/
#include "isr.h"
//=============================================================================
// Constant Definition
//=============================================================================
//=============================================================================
// Macro Definition
//=============================================================================
//=============================================================================
// Structure Definition
//=============================================================================
//=============================================================================
// Global Data Definition
//=============================================================================
//=============================================================================
// Private Function Definition
//=============================================================================
//=============================================================================
// Public Function Definition
//=============================================================================
+293 -24
View File
@@ -1,18 +1,22 @@
/** /**
* Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. * Copyright (c) 2026 Wisetop. All Rights Reserved.
*/ */
/** @file main.c /** @file main.c
* *
* @author Wei-Lun Hsu * @version 0.0.1
* @version 0.1 * @date 2026/04/22
* @date 2024/08/29
* @license * @license
* @description * @description
*/ */
#include "main.h" #include "main.h"
#include "isr.h"
#include "epwm_drv.h"
#include "app_cfg.h"
#include "motor_control.h"
#include "uart_drv.h"
#include "uvw_adc.h"
//============================================================================= //=============================================================================
// Constant Definition // Constant Definition
//============================================================================= //=============================================================================
@@ -32,10 +36,268 @@
//============================================================================= //=============================================================================
// Private Function Definition // Private Function Definition
//============================================================================= //=============================================================================
uint32_t __FASTCODE fastcode_proc(void) 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)
{ {
log_color(SLOG_CYAN, "run at fast area: $pc= x%08X\n", (uint32_t)&fastcode_proc); SYSCFG_ClkInitTypeDef SysClkInit = { 0 };
return 0; SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI;
SYSCFG_SysClkConfig(&SysClkInit);
sys_config_systick(SYS_TICK_1_MS);
}
static void test_pin_init(void)
{
GPIO_InitTypeDef gpio_init = { 0 };
gpio_init.GPIO_Pin = GPIO_Pin_14;
gpio_init.GPIO_Mode = GPIO_Mode_OUT;
gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpio_init.GPIO_OType = GPIO_OType_PP;
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();
} }
//============================================================================= //=============================================================================
@@ -43,25 +305,32 @@ uint32_t __FASTCODE fastcode_proc(void)
//============================================================================= //=============================================================================
int main(void) int main(void)
{ {
SYSCFG_ClkInitTypeDef SysClkInit = {0}; sysclk_init();
test_pin_init();
uart_drv_init();
epwm_drv_init();
SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; // adc_drv_init();
SYSCFG_SysClkConfig(&SysClkInit); // motor_ctrl_apply_default_settings();
// app_stop_motor();
sys_config_systick(SYS_TICK_1_MS); uart_send_msg("pec930 motor app ready\r\n");
syslog_init();
info("This is a app demo project\n");
msg("log debug message: $pc= x%08X\n", __get_pc());
log_color(SLOG_GREEN, "color green\n");
log_color(SLOG_YELLOW, "color yellow\n");
fastcode_proc();
while (1) while (1)
{ {
__NOP();
// while (pending_ticks-- > 0U)
// {
// dds_tim_period_elapsed();
// }
handle_cmd_task();
handle_motor_task();
handle_notify_task();
} }
return 0; 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;
}
+115
View File
@@ -0,0 +1,115 @@
#include "uart_drv.h"
/* UART config */
#define UART_DEVICE UART0
#define UART_DEVICE_BAUD_RATE 115200
#define UART_TX_PORT GPIOB
#define UART_TX_PIN GPIO_Pin_03
#define UART_TX_AF GPIO_AF_1
#define UART_RX_PORT GPIOB
#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;
__INTERRUPT void uart_rx_handler(void)
{
SAVE_IRQ_CSR_CONTEXT();
if (UART_GetITStatus(UART_DEVICE, UART_FLAG_RXNE))
{
char ch = (char)UART_ReceiveData(UART_DEVICE);
if (ch == '\r' || ch == '\n')
{
if (g_uart_rx_idx > 0)
{
g_uart_rx_buf[g_uart_rx_idx] = '\0';
g_uart_rx_complete = true;
}
}
else if (g_uart_rx_idx < UART_RX_BUF_SIZE - 1)
{
g_uart_rx_buf[g_uart_rx_idx++] = ch;
}
}
RESTORE_IRQ_CSR_CONTEXT();
}
/* Configure PB3 as UART0 TX, PB5 as UART0 RX */
int uart_drv_init(void)
{
__disable_irq();
GPIO_InitTypeDef gpio_init_cfg = { 0 };
UART_InitTypeDef uart_init_cfg = { 0 };
gpio_init_cfg.GPIO_Pin = UART_TX_PIN;
gpio_init_cfg.GPIO_Mode = GPIO_Mode_AF;
gpio_init_cfg.GPIO_AF_Mode = UART_TX_AF;
GPIO_Init(UART_TX_PORT, &gpio_init_cfg);
gpio_init_cfg.GPIO_Pin = UART_RX_PIN;
gpio_init_cfg.GPIO_Mode = GPIO_Mode_AF;
gpio_init_cfg.GPIO_AF_Mode = UART_RX_AF;
GPIO_Init(UART_RX_PORT, &gpio_init_cfg);
uart_init_cfg.BaudRate = UART_DEVICE_BAUD_RATE;
uart_init_cfg.WordLength = UART_WordLength_8b;
uart_init_cfg.StopBits = UART_StopBits_1;
uart_init_cfg.Parity = UART_Parity_No;
uart_init_cfg.Mode = UART_Mode_TxRx;
UART_Init(UART_DEVICE, &uart_init_cfg);
/* Enable RX not-empty interrupt */
UART_ITConfig(UART_DEVICE, UART_IT_RX_FIFO_NO_EMPTY, ENABLE);
/* Register UART0 IRQ */
sys_irq_attr_t irq_attr = {
.trig_mode = SYS_IRQ_TRIGGER_LEVEL,
.level = SYS_IRQ_LEVEL_H,
.priority = SYS_IRQ_PRIORITY_MIDDEN,
};
sys_register_IRQ(UART0_IRQn, uart_rx_handler, &irq_attr);
/* Start UART */
UART_Start(UART_DEVICE);
__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];
}