I'm using STM32F4 with HAL. It is configured as a simple counter as it counts pulses via EXTI interrupt. I want to asynchronously ask for the current number of impulses via UART.
Highest frequency of EXTI pulses is 250kHz, uC clock frequency is 180MHz. I think the problem is, sometimes the frequency of pulses on EXTI input is so high that a single UART Rx callback is unable to complete before a new pulse arrives on EXTI input. EXTI has a higher priority, so it interrupts UART Rx interrupt and the UART's response is rubbish.
I'd like this setup to work in a way that EXTI indeed has a higher priority, because it cannot skip any impulse. But the UART should, on rx interrupt, grab the value of number of pulses (global variable) and send it's message 'Pulse counter = <pulseCounter>' without TX buffer being filled with rubbish values. Doesn't matter if another higher priority interrupt arrives or not.
Is there a flaw in my understanding of this problem, or is there a way to fix the code?
Here is an example of UART response:
Here is the code initializing interrupts
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
HAL_UART_Receive_IT(&huart1, &uartMessage, 1);
HAL_NVIC_SetPriority(USART1_IRQn, 1, 0);
Here is the code of interrupt callbacks:
EXTI:
void getCounterValue()
{
*pGatePulseCounter = __HAL_TIM_GET_COUNTER(&htim6);
pGatePulseCounter++;
if (pGatePulseCounter == &gatePulseCounter[SAMPLE_TABLE_SIZE]) {
pGatePulseCounter = gatePulseCounter;
__HAL_TIM_SET_COUNTER(&htim6, 0);
}
pulseCounter++;
}
UART:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
uint8_t data[50] = {0};
if (uartMessage == 'p') {
sprintf((char*)data, "Pulse counter = <%d>\n\r", pulseCounter);
HAL_UART_Transmit_IT(&huart1, data, sizeof(data));
pulseCounter = 0;
} else if (uartMessage == 'f') {
sprintf((char*)data, "Current frequency = <%d>\n\r", pulseFrequency_Hz);
for (int i=0; i<SAMPLE_TABLE_SIZE; i++) {
gatePulseCounter[i] = 0;
}
HAL_UART_Transmit_IT(&huart1, data, sizeof(data));
} else {
}
HAL_UART_Receive_IT(&huart1, &uartMessage, 1);
}
global variables:
int gatePulseCounter[SAMPLE_TABLE_SIZE];
int* pGatePulseCounter = gatePulseCounter;
int pulseFrequency_Hz;
unsigned long int pulseCounter = 0;
unsigned long int pulseCounterBuffer = 0;
uint8_t uartMessage;
TIMx_CNT
register you will have how much changes was counted on pin. Also do not recommending sending UART messages by blocking approach. \$\endgroup\$