Compare commits
7 Commits
main
...
dev/cmd_service
| Author | SHA1 | Date | |
|---|---|---|---|
| a2e0288adc | |||
| f713afa69a | |||
| 4ab09cde9e | |||
| 19bdd31ece | |||
| 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,20 @@
|
|||||||
|
#ifndef __EPWM_DRV_H__
|
||||||
|
#define __EPWM_DRV_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
void epwm_init(void);
|
||||||
|
void epwm_en(bool en);
|
||||||
|
void epwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val);
|
||||||
|
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
|
|
||||||
+25
-26
@@ -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,35 +13,35 @@
|
|||||||
#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"
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Constant Definition
|
// Constant Definition
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Macro Definition
|
// Macro Definition
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
#define FW_VERSION "0.0.1"
|
||||||
|
//=============================================================================
|
||||||
|
// Structure Definition
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Structure Definition
|
// Global Data Definition
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Global Data Definition
|
// Private Function Definition
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Private Function Definition
|
// Public Function Definition
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
// Public Function Definition
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#ifndef __MOTOR_CTRL_H__
|
||||||
|
#define __MOTOR_CTRL_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#include "epwm_drv.h"
|
||||||
|
|
||||||
|
#define PWM_LUT_SIZE (64U)
|
||||||
|
#define PHASE_CH 3
|
||||||
|
|
||||||
|
// 1Hz = pwm_lut_size * sub_step / pwm_clk
|
||||||
|
// 1Hz = 64 * 65536 / 24000 FTW approximately 174.762666
|
||||||
|
#define DDS_FTW_1HZ (PWM_LUT_SIZE * 65536 / 24000)
|
||||||
|
|
||||||
|
enum motor_ctrl_mode
|
||||||
|
{
|
||||||
|
MOTOR_TASK_IDLE = 0,
|
||||||
|
MOTOR_TASK_RUN = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dds_phase_output_t
|
||||||
|
{
|
||||||
|
uint32_t phase_acc;
|
||||||
|
uint8_t lut_idx;
|
||||||
|
uint8_t nquadrant;
|
||||||
|
uint8_t last_quadrant;
|
||||||
|
int16_t lut_sin_val;
|
||||||
|
int16_t lut_cos_val;
|
||||||
|
uint16_t duty;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct motor_ctrl_ctx_t
|
||||||
|
{
|
||||||
|
uint16_t mode;
|
||||||
|
uint32_t phase_acc_base;
|
||||||
|
|
||||||
|
int32_t current_dds_ftw; // max: 2^22
|
||||||
|
int32_t current_dds_amp; // max: 2^7*1250
|
||||||
|
int32_t goal_dds_ftw;
|
||||||
|
int32_t goal_dds_amp;
|
||||||
|
int32_t begin_dds_ftw;
|
||||||
|
int32_t begin_dds_amp;
|
||||||
|
|
||||||
|
struct dds_phase_output_t dds_phase_out[PHASE_CH];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct motor_ctrl_ctx_t g_motor_ctrl_t;
|
||||||
|
|
||||||
|
void motor_ctrl_init(void);
|
||||||
|
void motor_task(void);
|
||||||
|
void motor_ctrl_phase_accumulator(void);
|
||||||
|
void motor_ctrl_stop(void);
|
||||||
|
void motor_ctrl_start(void);
|
||||||
|
|
||||||
|
void dds_pwm_duty_cycle_update(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef __UART_CMD_SRV_H__
|
||||||
|
#define __UART_CMD_SRV_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "uart_drv.h"
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
void uart_cmd_process(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef __DRV_UART_H__
|
||||||
|
#define __DRV_UART_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#define UART_RX_BUF_SIZE 128
|
||||||
|
|
||||||
|
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__);
|
||||||
|
|
||||||
|
void uart_init(void);
|
||||||
|
void uart_clear_rx_frame(void);
|
||||||
|
bool uart_is_frame_ready(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
#include "epwm_drv.h"
|
||||||
|
|
||||||
|
#include "motor_ctrl.h"
|
||||||
|
|
||||||
|
#define HIRC_Freq 60000000 // Hz
|
||||||
|
#define CurrentLoopIsrFreq 24000 // Hz
|
||||||
|
#define PWM_PERIOD HIRC_Freq / CurrentLoopIsrFreq
|
||||||
|
#define DEAD_TIME 200 // ns
|
||||||
|
#define DEAD_TIME_VALUE DEAD_TIME * 0.06
|
||||||
|
|
||||||
|
static volatile bool g_epwm_24khz_tick = false;
|
||||||
|
|
||||||
|
__INTERRUPT void epwm_irq_handler(void)
|
||||||
|
{
|
||||||
|
SAVE_IRQ_CSR_CONTEXT();
|
||||||
|
|
||||||
|
/* Overflow happens once per PWM period -> 24kHz tick */
|
||||||
|
if ((EPWM->SR & 0x10000U) == 0x10000U)
|
||||||
|
{
|
||||||
|
g_epwm_24khz_tick = true;
|
||||||
|
motor_ctrl_phase_accumulator();
|
||||||
|
TIM_ClearITPendingBit(EPWM, 0x10000U); // clear OVIF
|
||||||
|
}
|
||||||
|
|
||||||
|
RESTORE_IRQ_CSR_CONTEXT();
|
||||||
|
}
|
||||||
|
|
||||||
|
void epwm_en(bool en)
|
||||||
|
{
|
||||||
|
if (en)
|
||||||
|
{
|
||||||
|
// main output enable
|
||||||
|
TIM_CtrlPWMOutputs(EPWM, ENABLE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// main output disable
|
||||||
|
TIM_CtrlPWMOutputs(EPWM, DISABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void epwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val)
|
||||||
|
{
|
||||||
|
TIM_SetCompare1(EPWM, ch1_val);
|
||||||
|
TIM_SetCompare2(EPWM, ch2_val);
|
||||||
|
TIM_SetCompare3(EPWM, ch3_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool epwm_is_24khz_tick_and_clear(void)
|
||||||
|
{
|
||||||
|
bool ready = g_epwm_24khz_tick;
|
||||||
|
if (ready)
|
||||||
|
{
|
||||||
|
g_epwm_24khz_tick = false;
|
||||||
|
}
|
||||||
|
return ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
void epwm_init(void)
|
||||||
|
{
|
||||||
|
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 = 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);
|
||||||
|
|
||||||
|
sys_enable_girq();
|
||||||
|
}
|
||||||
@@ -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
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
+36
-28
@@ -1,18 +1,18 @@
|
|||||||
/**
|
/**
|
||||||
* 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 "motor_ctrl.h"
|
||||||
|
#include "uart_cmd_srv.h"
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Constant Definition
|
// Constant Definition
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@@ -32,36 +32,44 @@
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Private Function Definition
|
// Private Function Definition
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
uint32_t __FASTCODE fastcode_proc(void)
|
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);
|
||||||
|
}
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Public Function Definition
|
// Public Function Definition
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
SYSCFG_ClkInitTypeDef SysClkInit = {0};
|
sysclk_init();
|
||||||
|
test_pin_init();
|
||||||
|
epwm_init();
|
||||||
|
uart_init();
|
||||||
|
uart_send_msg("%s\r\n", "uart ok");
|
||||||
|
|
||||||
SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI;
|
motor_ctrl_init();
|
||||||
SYSCFG_SysClkConfig(&SysClkInit);
|
|
||||||
|
|
||||||
sys_config_systick(SYS_TICK_1_MS);
|
while (1)
|
||||||
|
{
|
||||||
|
uart_cmd_process();
|
||||||
|
|
||||||
syslog_init();
|
motor_task();
|
||||||
|
}
|
||||||
info("This is a app demo project\n");
|
return 0;
|
||||||
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)
|
|
||||||
{
|
|
||||||
__NOP();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#include "motor_ctrl.h"
|
||||||
|
|
||||||
|
struct motor_ctrl_ctx_t g_motor_ctrl_t;
|
||||||
|
|
||||||
|
void motor_ctrl_phase_accumulator(void)
|
||||||
|
{
|
||||||
|
if (g_motor_ctrl_t.mode == MOTOR_TASK_RUN)
|
||||||
|
{
|
||||||
|
g_motor_ctrl_t.phase_acc_base += g_motor_ctrl_t.current_dds_ftw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void motor_ctrl_init(void)
|
||||||
|
{
|
||||||
|
struct motor_ctrl_ctx_t *m = &g_motor_ctrl_t;
|
||||||
|
|
||||||
|
m->mode = MOTOR_TASK_IDLE;
|
||||||
|
m->phase_acc_base = 0;
|
||||||
|
m->current_dds_ftw = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void motor_ctrl_start(void)
|
||||||
|
{
|
||||||
|
struct motor_ctrl_ctx_t *m = &g_motor_ctrl_t;
|
||||||
|
|
||||||
|
motor_ctrl_init();
|
||||||
|
|
||||||
|
m->current_dds_ftw = DDS_FTW_1HZ * 80;
|
||||||
|
m->current_dds_amp = 160000;
|
||||||
|
m->mode = MOTOR_TASK_RUN;
|
||||||
|
|
||||||
|
epwm_en(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void motor_ctrl_stop(void)
|
||||||
|
{
|
||||||
|
epwm_en(0);
|
||||||
|
motor_ctrl_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void motor_task(void)
|
||||||
|
{
|
||||||
|
if (g_motor_ctrl_t.mode == MOTOR_TASK_IDLE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (epwm_is_24khz_tick_and_clear())
|
||||||
|
{
|
||||||
|
dds_pwm_duty_cycle_update();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#include "motor_ctrl.h"
|
||||||
|
|
||||||
|
const uint32_t phase_offset[PHASE_CH] = { 0, 1398101, 2796203 };
|
||||||
|
|
||||||
|
// 64-point sine wave lookup table (-2048-2047 range)
|
||||||
|
// Sine_table[i] = sin(i*2*pi/64)*(4095/2) where i = 0 to 63
|
||||||
|
// Use sine_amplitude parameter to scale to desired duty cycle range later
|
||||||
|
const int16_t LUT_sin[PWM_LUT_SIZE] = { 0, 200, 399, 594, 783, 965, 1137, 1298, 1447, 1582, 1702, 1805, 1891, 1959, 2008, 2037, 2047, 2037, 2008, 1959, 1891, 1805, 1702, 1582, 1447, 1298, 1137, 965, 783, 594, 399, 200, 0, -200, -399, -594, -783, -965, -1137, -1298, -1447, -1582, -1702, -1805, -1891, -1959, -2008, -2037, -2047, -2037, -2008, -1959, -1891, -1805, -1702, -1582, -1447, -1298, -1137, -965, -783, -594, -399, -200 };
|
||||||
|
|
||||||
|
const int16_t LUT_cos[PWM_LUT_SIZE] = { 2047, 2037, 2008, 1959, 1891, 1805, 1702, 1582, 1447, 1298, 1137, 965, 783, 594, 399, 200, 0, -200, -399, -594, -783, -965, -1137, -1298, -1447, -1582, -1702, -1805, -1891, -1959, -2008, -2037, -2047, -2037, -2008, -1959, -1891, -1805, -1702, -1582, -1447, -1298, -1137, -965, -783, -594, -399, -200, 0, 200, 399, 594, 783, 965, 1137, 1298, 1447, 1582, 1702, 1805, 1891, 1959, 2008, 2037 };
|
||||||
|
|
||||||
|
void dds_pwm_duty_cycle_update(void)
|
||||||
|
{
|
||||||
|
struct motor_ctrl_ctx_t *motor = &g_motor_ctrl_t;
|
||||||
|
struct dds_phase_output_t *u = &motor->dds_phase_out[0];
|
||||||
|
struct dds_phase_output_t *v = &motor->dds_phase_out[1];
|
||||||
|
struct dds_phase_output_t *w = &motor->dds_phase_out[2];
|
||||||
|
|
||||||
|
for (int i = 0; i < PHASE_CH; i++)
|
||||||
|
{
|
||||||
|
struct dds_phase_output_t *p = &motor->dds_phase_out[i];
|
||||||
|
|
||||||
|
p->phase_acc = (motor->phase_acc_base + phase_offset[i]) % 0x003FFFFF;
|
||||||
|
p->last_quadrant = p->nquadrant;
|
||||||
|
p->lut_idx = p->phase_acc >> 16;
|
||||||
|
p->nquadrant = p->lut_idx >> 4;
|
||||||
|
p->lut_sin_val = LUT_sin[p->lut_idx];
|
||||||
|
p->lut_cos_val = LUT_cos[p->lut_idx];
|
||||||
|
p->duty = (((int32_t)p->lut_sin_val * motor->current_dds_amp) >> 18) + 1250; // 0~2500 duty cycle range
|
||||||
|
}
|
||||||
|
|
||||||
|
epwm_set_duty(u->duty, v->duty, w->duty);
|
||||||
|
}
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "uart_cmd_srv.h"
|
||||||
|
|
||||||
|
#include "motor_ctrl.h"
|
||||||
|
|
||||||
|
static bool cmd_match_with_arg(const volatile char *buf, const char *prefix, const char **arg_out)
|
||||||
|
{
|
||||||
|
size_t len = strlen(prefix);
|
||||||
|
for (size_t i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
if (buf[i] != prefix[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (buf[len] == ' ')
|
||||||
|
{
|
||||||
|
*arg_out = (const char *)&buf[len + 1];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t cmd_parse_int_list(const char *arg, int32_t *out, int32_t max_count)
|
||||||
|
{
|
||||||
|
int32_t count = 0;
|
||||||
|
char *end = NULL;
|
||||||
|
const char *p = arg;
|
||||||
|
|
||||||
|
while (*p != '\0' && count < max_count)
|
||||||
|
{
|
||||||
|
while (*p == ' ')
|
||||||
|
p++;
|
||||||
|
|
||||||
|
if (*p == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
out[count] = strtol(p, &end, 10);
|
||||||
|
if (end == p)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
count++;
|
||||||
|
p = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*p == ' ')
|
||||||
|
p++;
|
||||||
|
|
||||||
|
if (*p != '\0')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_cmd_process(void)
|
||||||
|
{
|
||||||
|
if (!uart_is_frame_ready())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char *arg = NULL;
|
||||||
|
char *cmd = (char *)g_uart_rx_buf;
|
||||||
|
|
||||||
|
if (strcmp(cmd, "help") == 0)
|
||||||
|
{
|
||||||
|
uart_send_msg("Commands:\r\n");
|
||||||
|
uart_send_msg(" help - show this help\r\n");
|
||||||
|
uart_send_msg(" fw_ver - show firmware version\r\n");
|
||||||
|
uart_send_msg(" epwm_en 1/0 - enable/disable EPWM output\r\n");
|
||||||
|
uart_send_msg(" epwm_set_duty d1 d2 d3 - set duty for 3 channels\r\n");
|
||||||
|
uart_send_msg(" mode_run 1/0 - start/stop motor control task\r\n");
|
||||||
|
uart_send_msg(" val n1 n2 ... - parse integer values\r\n");
|
||||||
|
}
|
||||||
|
else if (strcmp(cmd, "fw_ver") == 0)
|
||||||
|
{
|
||||||
|
uart_send_msg("FW: " FW_VERSION "\r\n");
|
||||||
|
}
|
||||||
|
else if (cmd_match_with_arg(cmd, "epwm_en", &arg))
|
||||||
|
{
|
||||||
|
if (arg[0] == '1')
|
||||||
|
{
|
||||||
|
epwm_en(1);
|
||||||
|
uart_send_msg("OK epwm on\r\n");
|
||||||
|
}
|
||||||
|
else if (arg[0] == '0')
|
||||||
|
{
|
||||||
|
epwm_en(0);
|
||||||
|
uart_send_msg("OK epwm off\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uart_send_msg("ERR usage: epwm_en 1/0\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cmd_match_with_arg(cmd, "epwm_set_duty", &arg))
|
||||||
|
{
|
||||||
|
int32_t values[3] = { 0 };
|
||||||
|
int32_t parsed = cmd_parse_int_list(arg, values, 3);
|
||||||
|
|
||||||
|
if (parsed <= 0)
|
||||||
|
{
|
||||||
|
uart_send_msg("ERR usage: epwm_set_duty duty1 duty2 duty3\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
epwm_set_duty(values[0], values[1], values[2]);
|
||||||
|
uart_send_msg("OK epwm_set_duty: %d %d %d\r\n", values[0], values[1], values[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cmd_match_with_arg(cmd, "mode_run", &arg))
|
||||||
|
{
|
||||||
|
if (arg[0] == '1')
|
||||||
|
{
|
||||||
|
motor_ctrl_start();
|
||||||
|
uart_send_msg("OK mode_run on\r\n");
|
||||||
|
}
|
||||||
|
else if (arg[0] == '0')
|
||||||
|
{
|
||||||
|
motor_ctrl_stop();
|
||||||
|
uart_send_msg("OK mode_run off\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uart_send_msg("ERR usage: mode_run 1/0\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cmd_match_with_arg(cmd, "val", &arg))
|
||||||
|
{
|
||||||
|
int32_t values[8] = { 0 };
|
||||||
|
int32_t parsed = cmd_parse_int_list(arg, values, 8);
|
||||||
|
|
||||||
|
if (parsed <= 0)
|
||||||
|
{
|
||||||
|
uart_send_msg("ERR usage: val n1 n2 ...\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int32_t i = 0; i < parsed; i++)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
snprintf(buf, sizeof(buf), "%d\r\n", values[i]);
|
||||||
|
uart_send_msg(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uart_send_msg("ERR unknown cmd\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset for next command
|
||||||
|
uart_clear_rx_frame();
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
#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
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// void uart_cmd_send_str(const char *str)
|
||||||
|
// {
|
||||||
|
// while (*str)
|
||||||
|
// {
|
||||||
|
// UART_SendData(UART_DEVICE, *str++);
|
||||||
|
// UART_WaitTxFifoEmpty(UART_DEVICE);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
void uart_clear_rx_frame(void)
|
||||||
|
{
|
||||||
|
g_uart_rx_idx = 0;
|
||||||
|
g_uart_rx_complete = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool uart_is_frame_ready(void)
|
||||||
|
{
|
||||||
|
return g_uart_rx_complete;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure PB3 as UART0 TX, PB5 as UART0 RX */
|
||||||
|
void uart_init(void)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
sys_enable_girq();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user