problem with timer interrupt, works in first place but not later on in program
Hello community,
I have a strange behaviour with my timer. Well probably it is not strange but the problem sits between keyboard and mouse, but hopefully you can help me find the cause.
following the setup of my program:
I use STM32F4 on a self-created board (well, develeped by a collegue), atollic truestudio, the HAL libraries and systick option. (firmware was created by that colleague as well who has left our company).
My goal is the following:
send a command via usb (working) to init my sensor system (working), then start the actual program/routine which includes:
starting timer with approx 256hz, with every hit of the timer interrupt (ISR) sample data until I have 256 samples (all working), calculating fft (working), sending results out over usb (working), set a counter which decrements in systick function (working), when counter reaches "0" restart the timer (probably not working) and get next samples (NOT working).
Precisely: the ISR, where I sample my data, is not hit anymore.
I try to post the relevant code:
void init_machsens(int CI_INTERFACE)
{
//init-routine
}
void start_machsens(int CI_INTERFACE)
{
if (MEAS_MODE < 1)
{
for (PCounter1 = 0; PCounter1 < CI_PART_LENGTH; PCounter1++)
{
EXEC_PARAM2[PCounter1] = '\0';
}
strncpy((char*)EXEC_PARAM2, "FFT", 3);
MX_TIM11_DeInit();
MX_TIM11_Init();
adc_measurement();
menu_update(); //updates an epaper-display
CONT_MEAS_COUNTER = 200; //each 2s new measurement
}
switch(CI_INTERFACE)
{
case 0: break;
case 1: USB1_TRANSFER = TRUE;break;
case 2: USB2_TRANSFER = TRUE;break;
case 3: ETH1_TRANSFER = TRUE;break;
case 4: USART1_TRANSFER = TRUE;break;
case 5: USART3_TRANSFER = TRUE;break;
case 6: USART6_TRANSFER = TRUE;break;
default: break;
}
}
void adc_measurement(void)
{
//get 256 FFT_Samples:
HAL_TIM_Base_Start_IT(&htim11);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET); //testpin for oszi
TIM11_COUNTER = 0;
while(TIM11_COUNTER < 256);
HAL_TIM_Base_Stop_IT(&htim11);
//prepare raw data for fft calculation
calc_rfft_values(1);
calc_rfft_values(2);
calc_rfft_values(3);
//prepare USB_OUT_DATA
CDC_Transmit_HS((uint8_t *)USB_OUT_DATA, (USB_COUNTER));
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == htim11.Instance)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);
//start ad conversion:
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET); //SPI2
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_RESET); //SPI2
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_11, GPIO_PIN_SET); //SPI4
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_11, GPIO_PIN_RESET); //SPI4
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_5, GPIO_PIN_SET); //SPI5
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_5, GPIO_PIN_RESET); //SPI5
// ADC_X ready?
while(HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_3))
{
}
// ADC_Y ready?
while(HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_2))
{
}
// ADC_Z ready?
while(HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_1))
{
}
transfer_SPI2(2, 3, SPI_NO_CS);
transfer_SPI4(2, 3, SPI_NO_CS);
transfer_SPI5(2, 3, SPI_NO_CS);
FFT_SampleX[TIM11_COUNTER][0] = SPI2_TRANSFER_RX[0];
FFT_SampleX[TIM11_COUNTER][1] = SPI2_TRANSFER_RX[1];
FFT_SampleX[TIM11_COUNTER][2] = SPI2_TRANSFER_RX[2];
FFT_SampleY[TIM11_COUNTER][0] = SPI4_TRANSFER_RX[0];
FFT_SampleY[TIM11_COUNTER][1] = SPI4_TRANSFER_RX[1];
FFT_SampleY[TIM11_COUNTER][2] = SPI4_TRANSFER_RX[2];
FFT_SampleZ[TIM11_COUNTER][0] = SPI5_TRANSFER_RX[0];
FFT_SampleZ[TIM11_COUNTER][1] = SPI5_TRANSFER_RX[1];
FFT_SampleZ[TIM11_COUNTER][2] = SPI5_TRANSFER_RX[2];
TIM11_COUNTER++;
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET);
}
}
void Systick_Command(void)
{
// IWDG Reload (IWDG is set to 8 seconds)
HAL_IWDG_Refresh(&hiwdg);
// ADC Measurement Continuous
if (CONT_MEAS_COUNTER > 1)
{
CONT_MEAS_COUNTER--;
}
if ((CONT_MEAS_COUNTER > 0) && (CONT_MEAS_COUNTER < 2))
{
if (strstr((char*)EXEC_PARAM2, "FFT") > 0)
{
adc_measurement(); //dauert langsam 1,065s
display_update(); //dauert 485ms
CONT_MEAS_COUNTER = 200; // Each Shot any 2s
}
}
}
/* TIM11 init function */
void MX_TIM11_Init(void)
{
htim11.Instance = TIM11;
htim11.Init.Prescaler = 3360; // htim11.Init.Prescaler = 3360; //168MHz * 20
htim11.Init.CounterMode = TIM_COUNTERMODE_UP;
// Set the Init Parameter
//TIM11_INIT_PERIOD = 40000 / FH5401_FREQ;
htim11.Init.Period = TIM11_INIT_PERIOD;
htim11.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim11) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/*
if (HAL_TIM_OnePulse_Init(&htim11, TIM_OPMODE_SINGLE) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
} */
//HAL_TIM_Base_Start_IT(&htim11);
}with the help of the E5-pin watching on an oscilloscope I figured out that the program hangs on the while(TIM11_COUNTER<256) routine. The program is then cancelled by watchdog.
Another approch whicht I tried, was, to start the timer in the init function and control the execution of the data sampling with a special setting of the TIM11_COUNTER variable. But still, the ISR is not hit when starting the adc_measurement() out of the systick routine.
So far, the information I could provide at this point. If you need more, please let me know!
Is there some problem, that systick oder usb confuses the timer11? Actually I searched through the firmware for any other existance of timer11 and found none.
I would be very happy if you'd share any idea where I could dig for the problem. Thank you in advance for your time and help.
Greetings,
Annika
