AnsweredAssumed Answered

Different triggers on the same clock

Question asked by piovanelli.matteo on Mar 28, 2014
Latest reply on Mar 29, 2014 by Clive One

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:

//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);
    //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_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

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?