243 lines
6.5 KiB
C
243 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 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
|
|
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
|
|
|