Might it work in Wine? I tried but it's not recognizing the serial ports...
Edit: It's only happening if more than one interrupt is enabled.
Seems like some sort of stack corruption? One interrupt happens over other one, then the it restores a wrong or corrupted context?
If I disable systick it won't happen. But this will also happen if any other interrupt is running.
It can't get any simpler than this!
#include "main.h"
volatile uint8_t new_capture;
/*--------------------------------------------------*/
void system_init(void)
{
LL_RCC_HSI_SetCalibFreq(LL_RCC_HSICALIBRATION_24MHz);
while (LL_RCC_HSI_IsReady() != 1);
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA | LL_IOP_GRP1_PERIPH_GPIOB | LL_IOP_GRP1_PERIPH_GPIOF);
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM1);
WritePin(RED,1);
WritePin(BLUE,1);
LL_GPIO_Init(CCP_Port, &(LL_GPIO_InitTypeDef){ CCP_Pin, LL_GPIO_MODE_ALTERNATE, LL_GPIO_SPEED_FREQ_VERY_HIGH, LL_GPIO_OUTPUT_PUSHPULL, LL_GPIO_PULL_NO, CCP_AF });
LL_GPIO_Init(RED_Port, &(LL_GPIO_InitTypeDef){ RED_Pin, LL_GPIO_MODE_OUTPUT, LL_GPIO_SPEED_FREQ_VERY_HIGH, LL_GPIO_OUTPUT_PUSHPULL });
LL_GPIO_Init(BLUE_Port, &(LL_GPIO_InitTypeDef){ BLUE_Pin, LL_GPIO_MODE_OUTPUT, LL_GPIO_SPEED_FREQ_VERY_HIGH, LL_GPIO_OUTPUT_PUSHPULL });
LL_TIM_Init(CCP_TIM, &(LL_TIM_InitTypeDef){ 23, LL_TIM_COUNTERDIRECTION_UP, 65535, LL_TIM_CLOCKDIVISION_DIV1, 0}); // 1MHz clock, 65ms overflow
LL_TIM_IC_Init(CCP_TIM, CCP_CH, &(LL_TIM_IC_InitTypeDef){ LL_TIM_IC_POLARITY_FALLING, LL_TIM_ACTIVEINPUT_DIRECTTI, LL_TIM_ICPSC_DIV1, 4 }); // Falling edge
LL_TIM_EnableCounter(CCP_TIM);
NVIC_SetPriority(TIM1_CC_IRQn, 1);
NVIC_EnableIRQ(TIM1_CC_IRQn);
SysTick_Config(24000); // 24MHz cpu clock, 1ms period.
}
/*--------------------------------------------------*/
void capture_start(void)
{
LL_TIM_ClearFlag_CC4(CCP_TIM);
LL_TIM_EnableIT_CC4(CCP_TIM);
}
/*--------------------------------------------------*/
int main(void)
{
uint32_t red=0, blue=0;
system_init();
capture_start();
while(1)
{
/*-------------*/ // Handle red led
if(new_capture)
{ // Turn on the red LED for some time when a capture is received.
new_capture=0;
red=100; // Load led counter
capture_start(); // Start a new capture
}
else if(red && !--red) // Decrease led counter until 0
WritePin(RED,1); // Led expired, turn off
/*-------------*/ // Handle blue led
if (!blue || !--blue ) // Generate small pulses in the blue led as heartbeat signal
{
bool b = ReadPin(BLUE);
WritePin(BLUE,!b);
blue = b ? 1000 : 1100000;
}
/*-------------*/
}
}
/*--------------------------------------------------*/
void systick_isr(void)
{
asm("nop"); // Do nothing
}
/*--------------------------------------------------*/
void capture_isr(void)
{
LL_TIM_SetCounter(CCP_TIM, 0); // Reset timer counter
if(LL_TIM_IsActiveFlag_CC4(CCP_TIM)) // Capture flag active
{
LL_TIM_IC_GetCaptureCH4(CCP_TIM); // Capture CCP value
LL_TIM_DisableIT_CC4(CCP_TIM); // Disable CC interrupt
LL_TIM_ClearFlag_CC4(CCP_TIM); // Clear flag
WritePin(RED,0); // Turn led on
new_capture=1; // Set flag
}
}