Solved
Can I combine Encoder with Input Capture at DMA?
Hi!
I have a STM32F373 processor and I have 2 Encoders and 3 Input Captures.
I have enabled DMA for input capture.
Timer 4:

Timer 19:

And I have this code.
My questions are:
- Can I use Encoder together with Input Capture if Input Capture has DMA?
- What will DMA store inside the arrays input_capture[2]? Is it the counter value? I'm assuming it will be some kind of a counted value, right?
- Will this work?
static TIM_HandleTypeDef* tim4_handle;
static TIM_HandleTypeDef* tim19_handle;
volatile static uint32_t input_capture0[2] = {0};
volatile static uint32_t input_capture1[2] = {0};
volatile static uint32_t input_capture2[2] = {0};
static uint32_t pulse_count[4] = {0};
void STM32_PLC_Start_Counters(TIM_HandleTypeDef* htim4, TIM_HandleTypeDef* htim19) {
/* Encoder - Prescaler does not effect encoder */
if(HAL_TIM_Encoder_Start(htim4, TIM_CHANNEL_ALL) != HAL_OK)
Error_Handler();
if(HAL_TIM_Encoder_Start(htim19, TIM_CHANNEL_ALL) != HAL_OK)
Error_Handler();
/*
* Input capture for measuring frequency
* For TIM4 and TIM19
* Timer clock: 48 Mhz
* Prescaler: 4799
* Counter: 65535 (0xffff)
* Update frequency: 6.5535 Hz
* Example: For every second, it will count 10000
* Lowest frequency measurement: 1/(0xFFFF*0.0001) = 0.1526 Hz
* Highest frequency measurement: 1/(1*0.0001) = 10000 Hz
*/
if(HAL_TIM_IC_Start_DMA(htim4, TIM_CHANNEL_3, (uint32_t*)input_capture1, 2) != HAL_OK)
Error_Handler();
if(HAL_TIM_IC_Start_DMA(htim4, TIM_CHANNEL_4, (uint32_t*)input_capture0, 2) != HAL_OK)
Error_Handler();
if(HAL_TIM_IC_Start_DMA(htim19, TIM_CHANNEL_3, (uint32_t*)input_capture2, 2) != HAL_OK)
Error_Handler();
/* Save */
tim4_handle = htim4;
tim19_handle = htim19;
}
int16_t STM32_PLC_Encoder_Get(uint8_t i) {
if(i == 0)
return tim4_handle->Instance->CNT;
else
return tim19_handle->Instance->CNT;
}
static float compute_frequency(uint16_t input_capture[]) {
/*
* Typical worst case scenarios:
* T1: 0xFFFF - T0: 0x0
* T1: 0x0 - T0: 0xFFFF
* T1: 0x7FFF - T0: 0x7FFF
* T1: 0x0 - T0: 0x0
*/
if(input_capture[1] > input_capture[0]) {
return (float) 1/((input_capture[1] - input_capture[0])*0.0001f);
} else if(input_capture[1] < input_capture[0]) {
return (float) 1/((input_capture[1] + 0xFFFF - input_capture[0])*0.0001f);
} else if(input_capture[1] == 0x7FFF && input_capture[0] == 0x7FFF){
return (float) 1/(0xFFFF*0.0001f);
} else {
return 0;
}
}
float STM32_PLC_Input_Capture_Get(uint8_t i) {
if(i == 0)
return compute_frequency((uint16_t*)input_capture0);
else if(i == 1)
return compute_frequency((uint16_t*)input_capture1);
else
return compute_frequency((uint16_t*)input_capture2);
}
void STM32_PLC_Input_Capture_Reset() {
for(uint8_t i = 0; i < 2; i++){
input_capture0[i] = 0;
input_capture1[i] = 0;
input_capture2[i] = 0;
}
}
void STM32_PLC_Pulse_Count_Set(uint8_t i){
pulse_count[i]++;
}
uint32_t STM32_PLC_Pulse_Count_Get(uint8_t i){
return pulse_count[i];
}
void STM32_PLC_Pulse_Count_Reset(){
memset(pulse_count, 0, sizeof(pulse_count));
}