EXTI Driver

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: utzig, lbednarz, tfAteba, barthess, RoccoMarco

Tabulous
Posts: 462
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 1 time
Been thanked: 13 times

Re: EXTI Driver

Postby Tabulous » Mon Mar 17, 2014 1:48 pm

Giovanni wrote:This should mean that the front is detected after the call to extStart(), there is no interrupt pending at that point.

Giovanni


I dont understand what you mean ?

All i know is that if a pin is high when you call extStart and you have it set for both edges, you will get a callback, which to me is wrong, as there have never be any transisitions, the pin has only ever been high.


If a pin is configured to input and floating, and it is pulled high with an external resistor, thus before any code is running the pin is high. If you now go and call extStart and you have it set for both edges/Auto start, you will get a callback............ yet there has been no transisition

User avatar
Giovanni
Site Admin
Posts: 13074
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 758 times
Been thanked: 637 times
Contact:

Re: EXTI Driver

Postby Giovanni » Mon Mar 17, 2014 4:08 pm

I am out of ideas. Resetting the PR registers makes sure that transitions happened before that moment are discarded.

You may try to not autostart the channels.

Giovanni

Tabulous
Posts: 462
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 1 time
Been thanked: 13 times

Re: EXTI Driver

Postby Tabulous » Mon Mar 17, 2014 4:35 pm

Giovanni wrote:I am out of ideas. Resetting the PR registers makes sure that transitions happened before that moment are discarded.

You may try to not autostart the channels.

Giovanni



I've tried that too :( as soon as extChannelEnable is called, callback is triggered, the only why i can stop this is to configure the transition as EXT_CH_MODE_FALLING_EDGE's, but then i cant detect both edges...

Tabulous
Posts: 462
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 1 time
Been thanked: 13 times

Re: EXTI Driver

Postby Tabulous » Mon Mar 17, 2014 5:43 pm

ive got a work around but its dirty, and dont really like doing it...... but putting a flag around the callbacks to mask them out, and then clear the mask on a Virtual timer.

i.e. Whist triggermask is FALSE ignore the callback.

Code: Select all

static void extcb1(EXTDriver *extp, expchannel_t channel)
{
static VirtualTimer vt4;


    (void)extp;
    (void)channel;

    if(triggermask == FALSE)
    {
        palClearPad(GPIOG, GPIOG_LED_STATUS_GRN);

        chSysLockFromIsr();
        if (chVTIsArmedI(&vt4))
        {
            chVTResetI(&vt4);
        }

        /* LED4 set to OFF after 200mS.*/
        chVTSetI(&vt4, MS2ST(200), led1off, NULL);
        chSysUnlockFromIsr();
    }
}



Dont think one should have to do this but, its the only solution i got, and the only way i can think to mask out this issue.

Tabulous
Posts: 462
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 1 time
Been thanked: 13 times

Re: EXTI Driver

Postby Tabulous » Mon Mar 17, 2014 8:39 pm

Just to update gone back to basics and got a bare main.c program with STLibs and this exerts the same issue, so cant be anything to do with Chibios.

What i can say is the F103 did not have this problem as ive just tested it.......Next stop Errata

User avatar
Giovanni
Site Admin
Posts: 13074
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 758 times
Been thanked: 637 times
Contact:

Re: EXTI Driver

Postby Giovanni » Mon Mar 17, 2014 8:42 pm

I already verified the errata, nothing apparently. I still think you are getting some kind of glitch on those inputs, you should verify with a scope, also try a stronger pullup.

Giovanni

Tabulous
Posts: 462
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 1 time
Been thanked: 13 times

Re: EXTI Driver

Postby Tabulous » Mon Mar 17, 2014 9:09 pm

Giovanni wrote:I already verified the errata, nothing apparently. I still think you are getting some kind of glitch on those inputs, you should verify with a scope, also try a stronger pullup.

Giovanni


Same software on and same hardware input circuitry on an F103 works ok, so the only real difference is MCU, begin to this there is a silicon issue here.


If you have a discoveryF4 i would be interested to see what you get if you tie a pin to VCC, and set it up as EXTI, i think you'll see the same as me, i.e interrupt is triggered as soon as you setup the EXTI

User avatar
Giovanni
Site Admin
Posts: 13074
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 758 times
Been thanked: 637 times
Contact:

Re: EXTI Driver

Postby Giovanni » Mon Mar 17, 2014 9:15 pm

I have to wait for the weekend for a test.

Giovanni

theShed
Posts: 50
Joined: Tue Feb 26, 2013 3:43 pm
Location: The flatlands of East Anglia

Re: EXTI Driver

Postby theShed » Mon Mar 17, 2014 10:20 pm

Can you try disabling irqs at the NVIC during startup of the ExtIrq and re-enable after clearing the PR.
Something like this:

Code: Select all

    static msg_t ThreadIO(void *arg)
    {
    Thread *p;
    struct iom *m;


        (void)arg;

        chRegSetThreadName("IO");

        /*
         * Activates the EXT driver.
         */
        chThdSleepMilliseconds(1000); // wait for Hardware Driver to Settle

        extStart(&EXTD1, &extcfg);

        nvicDisableVector(EXTI0_IRQn);
        nvicDisableVector(EXTI2_IRQn);
        nvicDisableVector(EXTI3_IRQn);

        extChannelEnable(&EXTD1, 0);
        extChannelEnable(&EXTD1, 2);
        extChannelEnable(&EXTD1, 3);

        EXTI->PR = 0xFFFFFFFF;

        nvicEnableVector(EXTI0_IRQn,
                   CORTEX_PRIORITY_MASK(STM32_EXT_EXTI0_IRQ_PRIORITY));
        nvicEnableVector(EXTI2_IRQn,
                   CORTEX_PRIORITY_MASK(STM32_EXT_EXTI2_IRQ_PRIORITY));
        nvicEnableVector(EXTI3_IRQn,
                   CORTEX_PRIORITY_MASK(STM32_EXT_EXTI3_IRQ_PRIORITY));

        while(TRUE)
        {
        chThdSleepMilliseconds(1000);
        }
    }


--
mike

Tabulous
Posts: 462
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 1 time
Been thanked: 13 times

Re: EXTI Driver

Postby Tabulous » Tue Mar 18, 2014 9:22 am

I've found the issue :-)

In low level driver function

ext_lld_channel_enable

You setup in this order the
EXTI->RTSR
EXTI->FTSR
EXTI->IMR
EXTI->EMR
and finally
SYSCFG->EXTICR

I dont think this is the correct way, It should be
SYSCFG->EXTICR
EXTI->RTSR
EXTI->FTSR
EXTI->IMR
EXTI->EMR

i'm not 100% sure why this fixes the issue, but if you look at the STM Lib code this is how they do it, i that order.

Below is revised ext_lld_channel_enable call, that now works

Code: Select all

void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) {

  /* Setting the associated GPIO for external channels.*/
  if (channel < 16) {
    uint32_t n = channel >> 2;
    uint32_t mask = ~(0xF << ((channel & 3) * 4));
    uint32_t port = ((extp->config->channels[channel].mode &
                      EXT_MODE_GPIO_MASK) >>
                     EXT_MODE_GPIO_OFF) << ((channel & 3) * 4);

#if defined(STM32L1XX_MD) || defined(STM32F0XX) || defined(STM32F2XX) ||    \
    defined(STM32F30X) || defined(STM32F37X) || defined(STM32F4XX)
  SYSCFG->EXTICR[n] = (SYSCFG->EXTICR[n] & mask) | port;
#else /* STM32F1XX */
  AFIO->EXTICR[n] = (AFIO->EXTICR[n] & mask) | port;
#endif /* STM32F1XX */
  }

#if STM32_EXTI_NUM_CHANNELS > 32
  if (channel < 32) {
#endif
    /* Programming edge registers.*/
    if (extp->config->channels[channel].mode & EXT_CH_MODE_RISING_EDGE)
      EXTI->RTSR |= (1 << channel);
    else
      EXTI->RTSR &= ~(1 << channel);
    if (extp->config->channels[channel].mode & EXT_CH_MODE_FALLING_EDGE)
      EXTI->FTSR |= (1 << channel);
    else
      EXTI->FTSR &= ~(1 << channel);

    /* Programming interrupt and event registers.*/
    if (extp->config->channels[channel].cb != NULL) {
      EXTI->IMR |= (1 << channel);
      EXTI->EMR &= ~(1 << channel);
    }
    else {
      EXTI->EMR |= (1 << channel);
      EXTI->IMR &= ~(1 << channel);
    }
#if STM32_EXTI_NUM_CHANNELS > 32
  }
  else {
    /* Programming edge registers.*/
    if (extp->config->channels[channel].mode & EXT_CH_MODE_RISING_EDGE)
      EXTI->RTSR2 |= (1 << (32 - channel));
    else
      EXTI->RTSR2 &= ~(1 << (32 - channel));
    if (extp->config->channels[channel].mode & EXT_CH_MODE_FALLING_EDGE)
      EXTI->FTSR2 |= (1 << (32 - channel));
    else
      EXTI->FTSR2 &= ~(1 << (32 - channel));

    /* Programming interrupt and event registers.*/
    if (extp->config->channels[channel].cb != NULL) {
      EXTI->IMR2 |= (1 << (32 - channel));
      EXTI->EMR2 &= ~(1 << (32 - channel));
    }
    else {
      EXTI->EMR2 |= (1 << (32 - channel));
      EXTI->IMR2 &= ~(1 << (32 - channel));
    }
  }
#endif
}


Return to “General Support”

Who is online

Users browsing this forum: No registered users and 5 guests