Files
RaDrone/Source/BSP/Src/motors.c
Radzhab Bisultanov eecf8f2cc2 Initial commit
2026-02-17 19:10:09 +03:00

231 lines
4.5 KiB
C

#include "motors.h"
#include "stm32g431xx.h"
void motors_init()
{
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
RCC->APB1ENR1 |= RCC_APB1ENR1_TIM2EN;
motor_gpio_tim1_ch3_init();
motor_gpio_tim1_ch4_init();
motors_tim1_ch3_4_init();
motor_gpio_tim2_ch1_init();
motor_gpio_tim2_ch2_init();
motors_tim2_ch1_2_init();
}
void motor_gpio_tim1_ch3_init()
{
// set alt function mode PA10
GPIOA->MODER &= ~(3 << (10 * 2));
GPIOA->MODER |= 2 << (10 * 2);
// AF6 for PA10
GPIOA->AFR[1] &= ~(0xF << 8);
GPIOA->AFR[1] |= 6 << 8;
// very high speed
GPIOA->OSPEEDR |= 3 << (10 * 2);
}
void motor_gpio_tim1_ch4_init()
{
// set alt function mode PA11
GPIOA->MODER &= ~(3 << (11 * 2));
GPIOA->MODER |= 2 << (11 * 2);
// AF11 for PA11
GPIOA->AFR[1] &= ~(0xF << 12);
GPIOA->AFR[1] |= 11 << 12;
// very high speed
GPIOA->OSPEEDR |= 3 << (11 * 2);
}
void motors_tim1_ch3_4_init()
{
// PWM mode 1
TIM1->CCMR2 &= ~TIM_CCMR2_OC3M;
TIM1->CCMR2 |= TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2;
TIM1->CCMR2 &= ~TIM_CCMR2_OC4M;
TIM1->CCMR2 |= TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2;
// preload enable
TIM1->CCMR2 |= TIM_CCMR2_OC3PE;
TIM1->CCMR2 |= TIM_CCMR2_OC4PE;
// enable capture/compare 3 output
TIM1->CCER |= TIM_CCER_CC3E;
TIM1->CCER |= TIM_CCER_CC4E;
TIM1->PSC = 16 - 1;
TIM1->ARR = 20000 - 1;
TIM1->CCR3 = 900;
TIM1->CCR4 = 900;
// TIM1_ARR is buffered
TIM1->CR1 |= TIM_CR1_ARPE;
// set main output enable
TIM1->BDTR |= TIM_BDTR_MOE;
// set update generation
TIM1->EGR |= TIM_EGR_UG;
// set counter enable
TIM1->CR1 |= TIM_CR1_CEN;
}
void motor_gpio_tim2_ch1_init()
{
// set alt function mode PA0
GPIOA->MODER &= ~(3 << (0 * 2));
GPIOA->MODER |= 2 << (0 * 2);
// AF1 for PA0
GPIOA->AFR[0] &= ~(0xF << 0);
GPIOA->AFR[0] |= 1 << 0;
// very high speed
GPIOA->OSPEEDR |= 3 << (0 * 2);
}
void motor_gpio_tim2_ch2_init()
{
// set alt function mode PA1
GPIOA->MODER &= ~(3 << (1 * 2));
GPIOA->MODER |= 2 << (1 * 2);
// AF1 for PA1
GPIOA->AFR[0] &= ~(0xF << 4);
GPIOA->AFR[0] |= 1 << 4;
// very high speed
GPIOA->OSPEEDR |= 3 << (1 * 2);
}
void motors_tim2_ch1_2_init()
{
// PWM mode 1
TIM2->CCMR1 &= ~TIM_CCMR1_OC1M;
TIM2->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
TIM2->CCMR1 &= ~TIM_CCMR1_OC2M;
TIM2->CCMR1 |= TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2;
// preload enable
TIM2->CCMR1 |= TIM_CCMR1_OC1PE;
TIM2->CCMR1 |= TIM_CCMR1_OC2PE;
// enable capture/compare 3 output
TIM2->CCER |= TIM_CCER_CC1E;
TIM2->CCER |= TIM_CCER_CC2E;
TIM2->PSC = 16 - 1;
TIM2->ARR = 20000 - 1;
TIM2->CCR1 = 900;
TIM2->CCR2 = 900;
// TIM2_ARR is buffered
TIM2->CR1 |= TIM_CR1_ARPE;
// set main output enable
TIM2->BDTR |= TIM_BDTR_MOE;
// set update generation
TIM2->EGR |= TIM_EGR_UG;
// set counter enable
TIM2->CR1 |= TIM_CR1_CEN;
}
int16_t T;
int16_t P;
int16_t R;
int16_t Y;
int16_t m1;
int16_t m2;
int16_t m3;
int16_t m4;
void motors_set_throttle_mix(const int16_t throttle, const control_channels_t* chs, const int8_t armed)
{
T = throttle;
P = (int16_t) chs->pitch;
R = (int16_t) chs->roll;
Y = (int16_t) chs->yaw;
m1 = T - P + R - Y;
m2 = T - P - R + Y;
m3 = T + P + R + Y;
m4 = T + P - R - Y;
motor_set_throttle(1, m1, armed);
motor_set_throttle(2, m2, armed);
motor_set_throttle(3, m3, armed);
motor_set_throttle(4, m4, armed);
}
void motor_set_throttle(int8_t motor_number, int16_t us, int8_t armed)
{
if (armed && us < 1050) us = 1050;
if (us > 2000) us = 2000;
switch (motor_number)
{
case 1:
TIM1->CCR3 = us;
break;
case 2:
TIM2->CCR2 = us;
break;
case 3:
TIM1->CCR4 = us;
break;
case 4:
TIM2->CCR1 = us;
break;
}
}
void motors_turn_off()
{
motor_set_throttle(1, 900, 0);
motor_set_throttle(2, 900, 0);
motor_set_throttle(3, 900, 0);
motor_set_throttle(4, 900, 0);
}
void motor1_set_throttle(int16_t throttle)
{
if (throttle < 1000) throttle = 1000;
if (throttle > 2000) throttle = 2000;
TIM1->CCR3 = throttle;
}
void motor2_set_throttle(int16_t throttle)
{
if (throttle < 1000) throttle = 1000;
if (throttle > 2000) throttle = 2000;
TIM1->CCR4 = throttle;
}
void motor3_set_throttle(int16_t throttle)
{
if (throttle < 1000) throttle = 1000;
if (throttle > 2000) throttle = 2000;
TIM2->CCR1 = throttle;
}
void motor4_set_throttle(int16_t throttle)
{
if (throttle < 1000) throttle = 1000;
if (throttle > 2000) throttle = 2000;
TIM2->CCR2 = throttle;
}