Files
hpsg5-controller_v2-stm32g4/Core/Src/sync_pulse.c

245 lines
6.5 KiB
C

#include "sync_pulse.h"
#include "timeouts.h"
#include "id.h"
extern TIM_HandleTypeDef htim8;
volatile int watchdog_active = 0;
volatile int watchdog_started = 0;
volatile int request_syncout_activation = 0;
typedef enum {
SYNC_PULSE_MODE_WATCHDOG = 0,
SYNC_PULSE_MODE_SYNCOUT = 1,
} SyncPulseMode_t;
static volatile SyncPulseMode_t s_mode = SYNC_PULSE_MODE_WATCHDOG;
void SYNC_Pulse_RequestSyncout(uint8_t enable)
{
request_syncout_activation = enable ? 1 : 0;
}
static void SYNC_Pulse_SwitchToSyncout(void)
{
/* Stop timer + interrupts, remap pin to GPIO output */
SYNC_PULSE_TIM_STOP();
SYNC_Pulse_EnableGPIO();
/* Optional: reset flags/state for syncout mode */
watchdog_active = 0;
s_mode = SYNC_PULSE_MODE_SYNCOUT;
}
static void SYNC_Pulse_SwitchToWatchdog(void)
{
/* Remap pin back to TIM8_CH1 AF, start PWM interrupts */
SYNC_Pulse_EnableTIM8();
SYNC_PULSE_TIM_START();
/* Optional: reset flags/state for watchdog mode */
watchdog_active = 0;
s_mode = SYNC_PULSE_MODE_WATCHDOG;
}
/* Call this from main loop / fast task */
void SYNC_Pulse_Poll(void)
{
uint8_t req = (request_syncout_activation != 0);
if (req && (s_mode != SYNC_PULSE_MODE_SYNCOUT))
{
__disable_irq();
SYNC_Pulse_SwitchToSyncout();
__enable_irq();
}
else if (!req && (s_mode != SYNC_PULSE_MODE_WATCHDOG))
{
__disable_irq();
SYNC_Pulse_SwitchToWatchdog();
__enable_irq();
}
}
uint8_t SYNC_Pulse_IsSyncoutMode(void)
{
return (s_mode == SYNC_PULSE_MODE_SYNCOUT);
}
/* =========================================================
Optional user hook: called from HAL callback
(keep it simple: set this from your app code if you want)
========================================================= */
static void (*s_sync_pulse_cb)(void) = 0;
void SYNC_Pulse_SetCallback(void (*cb)(void))
{
s_sync_pulse_cb = cb;
}
/* =========================================================
IRQ enable/disable
========================================================= */
static void SYNC_Pulse_TIM8_EnableNVIC(void)
{
/* TIM8 has two common IRQ lines on STM32G4:
- TIM8_CC_IRQn : capture/compare interrupts (PWM CC)
- TIM8_UP_TIM13_IRQn : update interrupt (period elapsed)
*/
HAL_NVIC_SetPriority(TIM8_CC_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(TIM8_CC_IRQn);
HAL_NVIC_SetPriority(TIM8_UP_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(TIM8_UP_IRQn);
}
static void SYNC_Pulse_TIM8_DisableNVIC(void)
{
HAL_NVIC_DisableIRQ(TIM8_CC_IRQn);
HAL_NVIC_DisableIRQ(TIM8_UP_IRQn);
}
/* =========================================================
Public API
========================================================= */
/**
* @brief Configure PA15 as TIM8_CH1 PWM output (AF2).
* NOTE: This only sets the pin muxing. Timer configuration is assumed done elsewhere.
*/
void SYNC_Pulse_EnableTIM8(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Remove previous GPIO config on PA15 */
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_15);
/* Configure PA15 alternate function = TIM8_CH1 (AF2) */
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM8;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Enable TIM8 interrupts in NVIC */
SYNC_Pulse_TIM8_EnableNVIC();
}
/**
* @brief Start TIM8 PWM on CH1 with interrupt enabled.
*
* This enables CC interrupts for the channel and will call:
* HAL_TIM_PWM_PulseFinishedCallback()
* (and/or other HAL callbacks depending on HAL internals)
*/
void SYNC_PULSE_TIM_START(void)
{
/* Start PWM + interrupt */
HAL_TIM_PWM_Start_IT(&htim8, TIM_CHANNEL_1);
/* If you also want update (period elapsed) interrupts, uncomment:
HAL_TIM_Base_Start_IT(&htim8);
*/
}
void SYNC_PULSE_TIM_STOP(void)
{
/* Start PWM + interrupt */
HAL_TIM_PWM_Stop_IT(&htim8, TIM_CHANNEL_1);
/* If you also want update (period elapsed) interrupts, uncomment:
HAL_TIM_Base_Start_IT(&htim8);
*/
}
/**
* @brief Disable TIM8_CH1 PWM and return PA15 to GPIO output mode.
*/
void SYNC_Pulse_EnableGPIO(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Stop PWM output on TIM8 CH1 (IT-safe stop) */
HAL_TIM_PWM_Stop_IT(&htim8, TIM_CHANNEL_1);
/* If you started base update IT, stop it too:
HAL_TIM_Base_Stop_IT(&htim8);
*/
/* Disable NVIC lines */
SYNC_Pulse_TIM8_DisableNVIC();
/* Remove AF mapping */
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_15);
/* Reconfigure PA15 as standard push-pull output */
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Optional: set known state */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET);
}
void SYNC_Pulse_GPIO_set(uint8_t state)
{
HAL_GPIO_WritePin(SYNC_OUT_GPIO_Port, SYNC_OUT_Pin,
state ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
/* =========================================================
Actual IRQ handlers (DEFINED HERE, not in stm32xx_it.c)
========================================================= */
void TIM8_CC_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim8);
}
void TIM8_UP_TIM13_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim8);
}
/* =========================================================
HAL callbacks (choose whichever you want)
========================================================= */
/* Called for Update event if Base_Start_IT (or update IT) is enabled */
/*void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM8)
{
// Period elapsed (update)
if (s_sync_pulse_cb) s_sync_pulse_cb();
}
}*/
#include "can_port.h"
/* Often triggered when PWM channel finishes a pulse when using PWM_Start_IT */
#if defined(T06301)
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM8)
{
if (!watchdog_active){
watchdog_active = 1; // ✅ Pulse finished
watchdog_started = 1;
can_port_send_msg_def(&MSG_ID_EMPF4);
Timeout_StartIfStopped(20, TIM16->CNT); // deberia mejorarlo bastante esto, en vez de
FIEONA_advance();
}
/* PWM CC event */
if (s_sync_pulse_cb) s_sync_pulse_cb();
}
}
#elif defined(cfgejemplo)
#endif