Compare commits
8 Commits
main
...
dev/copy_dds
| Author | SHA1 | Date | |
|---|---|---|---|
| 34a8093c34 | |||
| e6fdabcd3a | |||
| bb5621a3fd | |||
| 552b3ab5b4 | |||
| 3f10ca6e02 | |||
| 17b60b9452 | |||
| c17830ee1c | |||
| d980b5196a |
Vendored
+15
-1
@@ -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
@@ -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}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
@@ -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"
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user