I want to use Manchester Coding for my DALI Master-slave project. I am using two boards for this project, one is STM32E407 and the other is STM32F3Discovery. As an initial step, I want to test for sending simple hex data(0xFE96)[FE-Preamble data, 96 is the command I want to send] from STM32F3Discovery to STM32E407 using Manchester coding following this App_Note, with time-based decoding approach. I have configured both boards for the same clock configuration.
Programming: Manch_Tx (Encoding) part was very easy and working quite as expected. The problem for me is with Manch_Rx(Decoding) part. I have configured TIMer4(CH3) of STM32E407, for a period of 0xFFFF and up-count mode.According to my clock configuration, timer peripheral clock frequency is 64MHz. I have configured one external interrupt pin triggered by user_button on STM32F3Discovery for hardware flow control.
Various aspects that I have considered:
- I have made sure the data transfer will start with external interrupt(push_button on STM32F3-Discovery) which triggers input capture on STM32E407.
- I have even experimented to include some delay(few msecs) for the data transfer to start.
- Tweaking with NVIC priority for timer (Not exactly know any standard method, was just giving less priority to Timer as Systick)
- Using pulse_frequency rather than pulse_width(time) to avoid float
I am using HAL_TIM_IC_CaptureCallback() function to measure the pulse frequency as follows.
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_3)
{
if(uhCaptureIndex == 0)
{
/* Get the 1st Input Capture value */
uwIC3Value1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);
uhCaptureIndex = 1;
}
else if(uhCaptureIndex == 1)
{
/* Get the 2nd Input Capture value */
uwIC3Value2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);
/* Capture comuputation */
if (uwIC3Value2 > uwIC3Value1)
{
uwDiffCapture = (uwIC3Value2 - uwIC3Value1);
}
else /* (uwIC3Value2 <= uwIC3Value1) */
{
uwDiffCapture = ((0xFFFF - uwIC3Value1) + uwIC3Value2);
}
/* Calculation of 'window_T' */
/* pulse_T = uwDiffCapture / (2*HAL_RCC_GetPCLK1Freq()); */
/* Calcualtion of pulse_Frequency */
pulse_Frequency = (2*HAL_RCC_GetPCLK1Freq()) / uwDiffCapture;
uhCaptureIndex = 0;
}
}
}
Main function
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM4_Init();
while(interrupt_detected == 0)
{
}
if(HAL_TIM_IC_Start_IT(&htim4, TIM_CHANNEL_3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/* Test in general the value of uwDiffCapture */
/* while(!(pulse_Frequency > (2*Freq_T-Freq_Delta_T) && (pulse_Frequency < (2*Freq_T+Freq_Delta_T)))) */
/* { */
/* HAL_TIM_IC_CaptureCallback(&htim4); */
/* HAL_GPIO_TogglePin(LED_Red_GPIO_Port, LED_Red_Pin); */
/* HAL_Delay(250); */
/* } */
while(!((pulse_Frequency > 4000) && (pulse_Frequency < 10000)))
{
HAL_TIM_IC_CaptureCallback(&htim4);
HAL_GPIO_TogglePin(LED_Red_GPIO_Port, LED_Red_Pin);
HAL_Delay(250);
}
HAL_GPIO_WritePin(LED_Red_GPIO_Port, LED_Red_Pin, GPIO_PIN_RESET);
/* When it is in sync turn on LED_Green */
HAL_GPIO_WritePin(LED_Green_GPIO_Port, LED_Green_Pin, GPIO_PIN_SET);
while (1)
{
}
}
My Understanding:
Min_pulse_frequency = 2*TIM4_Peripheral_Frequency/Period
I was using T(mid_bit_time) as 125usec[corresponding pulse_frequency 8kHz] for Manch_Tx func(). I want to make sure that on receiving side pulse_frequency lies between 2*T-Delta_T and 2*T+Delta_T as a first debugging step [before the complete implementation of Manch_Rx func()] and this is where I am having the problem. I am converting time data into frequency and comparing that the pulse_frequency lies within limits. The wrote 4000, 10000 values are calculated based on expected frequency and adding some heavy tolerance. I am not getting any reliable results.
My questions are:
- What am I missing or where is my understanding wrong?
- In general, my logic of calling HAL_TIM_IC_CaptureCallback[non-blocking mode] correct or should I have to use TIM4_IRQHandler()[blocking-mode] ??
- Is the entire process less painful if I use DMA for time capture?
PS: I am using HAL_Libraries as you can see and (openocd, linux, Emacs and jtag ) interface.
EDIT: The problem lies in using HAL_TIM_IC_CaptureCallback() function. In the HAL library, HAL_TIM_IC_CaptureCallback() is only used to report for update of events in Capture or Compare mode that is the reason why calling CaptureCallback does not work to measure the signal period. Instead, I have to use IRQHandler and this is what makes it more complicated!