generated from hulk/gd32e23x_template_cmake_vscode
127 lines
7.4 KiB
C
127 lines
7.4 KiB
C
#include "actuator.h"
|
|
|
|
void actuator_init(void) {
|
|
// Initialize PWM pins for actuators
|
|
rcu_periph_clock_enable(ACTUATOR_CH1_PWM_RCU);
|
|
rcu_periph_clock_enable(ACTUATOR_CH2_PWM_RCU);
|
|
rcu_periph_clock_enable(ACTUATOR_CH1_GPIO_RCU);
|
|
rcu_periph_clock_enable(ACTUATOR_CH2_GPIO_RCU);
|
|
// rcu_periph_clock_enable(PWM3_RCU);
|
|
// rcu_periph_clock_enable(PWM4_RCU);
|
|
|
|
rcu_periph_clock_enable(ACTUATOR_PWM_TIMER_RCU); // Enable clock for TIMER0
|
|
|
|
gpio_mode_set(ACTUATOR_CH1_PWM_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, ACTUATOR_CH1_PWM_PIN);
|
|
gpio_output_options_set(ACTUATOR_CH1_PWM_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ACTUATOR_CH1_PWM_PIN);
|
|
gpio_af_set(ACTUATOR_CH1_PWM_PORT, GPIO_AF_2, ACTUATOR_CH1_PWM_PIN);
|
|
|
|
gpio_mode_set(ACTUATOR_CH2_PWM_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, ACTUATOR_CH2_PWM_PIN);
|
|
gpio_output_options_set(ACTUATOR_CH2_PWM_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ACTUATOR_CH2_PWM_PIN);
|
|
gpio_af_set(ACTUATOR_CH2_PWM_PORT, GPIO_AF_2, ACTUATOR_CH2_PWM_PIN);
|
|
|
|
gpio_mode_set(ACTUATOR_CH1_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ACTUATOR_CH1_GPIO_PIN);
|
|
gpio_output_options_set(ACTUATOR_CH1_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ACTUATOR_CH1_GPIO_PIN);
|
|
gpio_bit_reset(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set initial state to LOW
|
|
|
|
gpio_mode_set(ACTUATOR_CH2_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ACTUATOR_CH2_GPIO_PIN);
|
|
gpio_output_options_set(ACTUATOR_CH2_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ACTUATOR_CH2_GPIO_PIN);
|
|
gpio_bit_reset(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set initial state to LOW
|
|
|
|
// Additional actuator initialization code can be added here
|
|
|
|
// HSI = 72MHz , Freq Timer = 72MHz / (Prescaler + 1) / (Period + 1)
|
|
timer_deinit(ACTUATOR_PWM_TIMER);
|
|
timer_parameter_struct timer_initpara;
|
|
timer_initpara.prescaler = 2; // 72MHz / (2+1) = 24MHz
|
|
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
|
|
timer_initpara.counterdirection = TIMER_COUNTER_UP;
|
|
timer_initpara.period = 999; // 24MHz / (999 + 1) = 24kHz
|
|
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
|
|
timer_initpara.repetitioncounter = 0;
|
|
timer_init(ACTUATOR_PWM_TIMER, &timer_initpara);
|
|
|
|
timer_oc_parameter_struct timer_ocinitpara;
|
|
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
|
|
timer_ocinitpara.outputstate = TIMER_CCX_ENABLE;
|
|
timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;
|
|
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
|
|
timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
|
|
timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
|
|
timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
|
|
|
|
// CH0
|
|
timer_channel_output_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, &timer_ocinitpara);
|
|
timer_channel_output_mode_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, TIMER_OC_MODE_PWM0);
|
|
timer_channel_output_shadow_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, TIMER_OC_SHADOW_ENABLE);
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, 0);
|
|
|
|
// CH1
|
|
timer_channel_output_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, &timer_ocinitpara);
|
|
timer_channel_output_mode_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, TIMER_OC_MODE_PWM0);
|
|
timer_channel_output_shadow_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, TIMER_OC_SHADOW_ENABLE);
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, 0);
|
|
|
|
timer_auto_reload_shadow_enable(ACTUATOR_PWM_TIMER);
|
|
timer_primary_output_config(ACTUATOR_PWM_TIMER, ENABLE);
|
|
timer_enable(ACTUATOR_PWM_TIMER);
|
|
}
|
|
|
|
void actuator_output(actuator_channel_t channel, uint16_t duty, actuator_direction_t direction) {
|
|
|
|
if (duty > 999) duty = 999; // Limit duty cycle to max value
|
|
|
|
if (direction != DIRECTION_PUSH && direction != DIRECTION_PULL) {
|
|
// Invalid direction, handle error if necessary
|
|
return;
|
|
}
|
|
|
|
// Set PWM output for the specified actuator channel
|
|
// This is a placeholder; actual implementation will depend on the PWM configuration
|
|
// For example, setting the duty cycle to a specific value to activate the actuator
|
|
if (channel == ACTUATOR_CH1) {
|
|
if (direction == DIRECTION_PUSH) {
|
|
SEGGER_RTT_printf(0, "[ACTUATOR] Actuator CH1 PUSH with duty %d\n", duty);
|
|
gpio_bit_reset(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set direction LOW
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, duty);
|
|
} else if (direction == DIRECTION_PULL) {
|
|
SEGGER_RTT_printf(0, "[ACTUATOR] Actuator CH1 PULL with duty %d\n", duty);
|
|
gpio_bit_set(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set direction HIGH
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, (999 - duty));
|
|
}
|
|
} else if (channel == ACTUATOR_CH2) {
|
|
if (direction == DIRECTION_PUSH) {
|
|
SEGGER_RTT_printf(0, "[ACTUATOR] Actuator CH2 PUSH with duty %d\n", duty);
|
|
gpio_bit_reset(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set direction LOW
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, duty);
|
|
} else if (direction == DIRECTION_PULL) {
|
|
SEGGER_RTT_printf(0, "[ACTUATOR] Actuator CH2 PULL with duty %d\n", duty);
|
|
gpio_bit_set(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set direction HIGH
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, (999 - duty));
|
|
}
|
|
} else {
|
|
// Invalid channel, handle error if necessary
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, 0); // Ensure CH1 is off
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, 0); // Ensure CH2 is off
|
|
gpio_bit_reset(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set CH1 direction LOW
|
|
gpio_bit_reset(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set CH2 direction LOW
|
|
}
|
|
}
|
|
|
|
void actuator_stop(actuator_channel_t channel) {
|
|
if(channel == ACTUATOR_CH1) {
|
|
SEGGER_RTT_printf(0, "[ACTUATOR] Stopping Actuator CH1\n");
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, 999); // Ensure CH1 is off
|
|
gpio_bit_set(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set CH1 direction LOW
|
|
} else if(channel == ACTUATOR_CH2) {
|
|
SEGGER_RTT_printf(0, "[ACTUATOR] Stopping Actuator CH2\n");
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, 999); // Ensure CH2 is off
|
|
gpio_bit_set(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set CH2 direction LOW
|
|
} else {
|
|
// Invalid channel, handle error if necessary
|
|
SEGGER_RTT_printf(0, "[ACTUATOR] Invalid channel specified for stop: %d\n", channel);
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, 999); // Ensure CH1 is off
|
|
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, 999); // Ensure CH2 is off
|
|
gpio_bit_set(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set CH1 direction LOW
|
|
gpio_bit_set(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set CH2 direction LOW
|
|
}
|
|
} |