This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

detecting both edges of interrupt

Other Parts Discussed in Thread: CC2500

I've found a case where a peripheral (the RF1A module, if it matters) has an interrupt where I need to detect both the positive transition and the negative transition.  The signal will generally be low, and it's safe for my state machine if the initial configuration is to detect low-to-high transitions.  The duration when the signal is high may be extremely short, though it should be at least 8 MCLK ticks.

The digital IO module documentation suggests that inverting the IES bit within the interrupt call "may" do the right thing.  I.e., if I entered on a low-to-high transition and at the instant I update IES the IN value is already  low, the documentation says IFG "may be set".  I'd be more comfortable if it said "will be set".

In practice and absent chip errata, is it safe to assume that it will be set?

If not, is there an alternative recommended pattern for robust detection of both edges of an interrupt?

  • I realize this recommendation consumes 2 pins, but if you truly want a robust detection of both edges of the interrupt and you don't have enough time to make the change to the IES bit to change the direction, I would suggest connecting this external signal to 2 pins.  One configured for low-to-high edge detection and the other configured for high-to-low edge detection.

  • Thanks; that's probably the right approach when a hardware change is practical.  In this case, the RF1A is a peripheral module within the CC430, and I don't believe it's possible to replicate the signal.

  • Exactly which RF1A signal are you talking about? Is it listed in Table 22-4 or Table 22-5 of slau259b?

    If it is normally low, occasionally go high, and go back to low within a short period of time, you may set it up to generate interrupt a rising edge only and use polling to wait for it to go low.

  • RFIFG9.  Goes high on the sync word, and low when packet processing is finished.  For long messages and low baud rates, the duration could be a couple hundred milliseconds.  For short messages and high baud rates, packet processing could complete within a couple dozen microseconds, perhaps before the sync word interrupt finishes processing if a higher priority interrupt also stole some CPU cycles for another activity.  At the point of receiving the sync word, I can't anticipate the duration.  This is, I believe, the only signal that provides end-of-packet for both transmissions and receptions.

    If I can reliably detect both events, things are good.  If I might miss the packet finish event, I have to lay in an alarm to detect the situation.  I can check RF1AIN before toggling the bit in RFA1IES to reduce the chance of getting it wrong, but there's still a race condition since I can't do that atomically.

    Though this case is specific to RFIFG9 in the RF1A module, the same code should eventually work with GDOxCFG=6 on a CC2500/CC110x, where the signal will be present on a digital IO pin.  Hence my original attempt to make the question generic about the behavior of IES settings at specific IN states.

    Should I take these suggestions to find a different approach as indicating that I can't expect an already-enabled interrupt to be generated  when setting its IES register to generate an interrupt on transition to the state it is already in?  It works in the long-pulse; having to validate it experimentally in the high-speed case is not going to leave me feeling comfortable about the robustness of the system.

  • First of all, please read whatever I say with a grain of salt. I have no experience with CC430 at all. I am a hobbyist with no training in software or hardware engineering. English is my second language, and the only source of information I have about this subject is from reading slau259b.pdf and slas554e.pdf. Worse yet, I am an atheist -- I do not believe whatever I consider unreasonable.

    You want to have a reliable way to detect when a sync word is sent or received. You also want to have a reliable way to detect when that packet processing is finished. Thus you need to detect both positive and negative edges of RFIN9 (in the RF1AIN register), not the edges of RFIFG9 (in the RF1AIFG register). The last sentence above may contradict to part of slau259b.pdf

    Initially, like you said, it is safe to set up a configuration so that a positive edge of RFIN9 sets RFIFG9 and generates an RF1A interrupt. Later on, as described below, the condition to set RFIFG9 may be changed to negative edge of RFIN9 or vice versa.

    There are many other causes that may trigger an RF1A interrupt. Inside the RF1A ISR, you can read (but read it only once) RF1AIV to determined the cause of the current interrupt. If this identifies that the interrupt is caused by RFIFG9, you may want to do the following.

    #1. Flip RFIES9 (in RF1AIES register) to generate another RF1A interrupt later. That is, change it from low-to-high to high-to-low or vice versa.

    #2. Check the state of RFIN9. Set RFIFG9 if either: (a) new setting of RFIES9 is for low-to-high and RFIN9 is already high, or (b) new setting of RFIES9 is for high-to-low and RFIN9 is already low.

    #3 Proceed to handle this current interrupt caused by the previous RFIFG9 and return from interrupt.

    Now some notes to clarify the above procedure.

    At step #1, RFIFG9 is already cleared by the act of reading RF1AIV (the one that identified FRIFG9 as the cause of the current interrupt).

    At step #2, we read RFIN9. If it has not changed since the last edge that caused the current interrupt, then RFIFG9 remains cleared. Let us call this situation x. You were correctly not worried about this situation.

    On the other hand, if RFIN9 has changed, there are two situations. One is, the new RFIES9 setting was in time to detect that edge of RFIN9 and RFIFG9 is set. Let us call this situation y. The other situation is, the change happened earlier and the new RFIES9 setting was too late to catch that edge of RFIN9 and RFIFG9 remains cleared. Let us call this situation z. You were correctly worried about the difference between y and z.

    For situation x, the logic of the rest of step #2 will not try to set RFIFG9. But the new setting of RFIES9 enables the hardware to detect its next change as intended and set FRIFG9 at that time.

    For both situations y and z, the logic of the rest of step #2 will set RFIFG9 by software. In the x case, RFIFG9 is already set, setting it again is unnecessary but does no harm. In the z case, setting RFIFG9 by software is necessary and sufficient to remedy the deficiency in hardware detection cased by latency. In either cases, after the current ISR returns from interrupt, another interrupt cause by the FRIFG9 will be pending.

  • Thank you.  Reading more closely the Digital I/O section I see:

    Software can also set each PxIFG flag, providing a way to generate a software-initiated interrupt.  ... If any PxIFG flag becomes set during a Px interrupt service routine, or is set after the RETI instruction of a Px interrupt service routine is executed, the set PxIFG flag generates another interrupt.

    It's probably safe to assume the RF1A registers behave the same.  Given that, I can do what I need to do, following steps just as you describe.

    I suspect that my approach was misdirected by some hardware platform I worked on twenty years ago that had an IFG equivalent that reflected internal state, and the only thing you were allowed to do was clear---not set---bits.  The MSP430 solution is much cleaner.

  • Peter Bigot said:
    I need to detect both the positive transition and the negative transition. 

    While you seem to have found a solution, let me suggest another possible aproach.

    The Capture/compare registers can capture the current value of the associated timer register on falling, rising or both transitions of its input pin. In case of the CCR0, it has its own interrupt vector, so the IFG bit for one transition is cleared once the ISR is entered. The other CCRs require the IFG bit to be cleared manually or by reading the tiemr interrupt vector register.
    If another transition occurs during the latency (because of another ISR is currently running or GIE bit is clear), an overflow bit is set in addition to the IFG bit, so you know that since handling the last itnerrupt, two transitions have happened. Of course the current state can be read too.

**Attention** This is a public forum