Question
Different triggers on the same clock
Posted on March 28, 2014 at 21:35
Hello,
For a project I am working on I would like to generate interrupts on both edges of the HSI clock, for synchronization purposes. The sysclk is based on the main PLL, sourced from HSE. I output HSI on the MCO1 (pin PA8), and I am able to generate interrupts on either or both edges on the EXTI line 8 from that pin. However, if I do it like that I have found no way to distinguish between rising and falling transitions. My workaround (that does not work) would be to wire the PA8 pin (on which I output the clock) to the PC9 pin (I use a jumper between them). I would then detect falling edge transitions on PA8 through EXTI line 8, and rising edge transitions on PC9 through EXTI line 9. However, with my configuration I only detect the falling edge transitions on PA8. Here is my code:/*Initialization*/
//MCO1 outputs the HSI clock
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_MCO);
//With a jumper, I also wire MCO1 to the PC9 pin.
//Using two pins I can discriminate between clock edges
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*Interrupt settings*/
NVIC_InitTypeDef NVIC_InitStructure;
/*Configure the mask bits for the interrupt on MCO1 */
EXTI->IMR |= 0x1 <<
8
;
/*Configure trigger selection bits for the interrupt on MCO1 */
EXTI->RTSR &= EXTI8_RISING_EDGE_NO; //Disable rising edge as trigger EXTI8_RISING_EDGE_NO == (uint32_t)0xFFFFFEFF
EXTI->FTSR |= EXTI8_FALLING_EDGE_YES; //Enable falling edge as trigger EXTI8_FALLING_EDGE_YES == (uint32_t)0x100
/*Configure the mask bits for the interrupt on PC9 (externally wired to MCO1)*/
EXTI->IMR |= 0x1 <<
9
;
//Configure trigger selection bits for interrupt on PC9
EXTI->RTSR |= EXTI9_RISING_EDGE_YES; //Enable rising edge as trigger EXTI9_RISING_EDGE_YES == (uint32_t)0x200
EXTI->FTSR &= EXTI9_FALLING_EDGE_NO; //Disable falling edge as trigger EXTI9_FALLING_EDGE_NO == (uint32_t)0xFFFFFDFF
/*Configure the enable and mask bits on the NVIC IRQ channel
* HSI on pin PA8, goes to EXTI line 8
* PC9 goes to EXTI line 9*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
And here is the handler:
void EXTI9_5_IRQHandler(void)
{
if(EXTI->PR & PR_EXTI8) //Interrupt on EXTI line 8, on which we registered the SCLK falling edge
{
if(debug_led_count++ == 5000000)
{
STM_EVAL_LEDToggle(LED3); //blinks correctly
debug_led_count = 0;
}
}
else if(EXTI->PR & PR_EXTI9) //Interrupt on EXTI line 9, on which we registered the SCLK rising edge
{
if(debug_led_count2++ == 5000000)
{
STM_EVAL_LEDToggle(LED4); //does not blink ever
debug_led_count2 = 0;
}
}
}
Could anyone point me in the direction of a solution? Is there some configuration I am missing? O perhaps my approach is entirely wrong?
Cheers,
Matteo