Search code examples
arduinoavrarduino-unofirmata

Arduino AVR interrupts mask clearing


I'm building some soft using firmata protocol (firmata protocol) to provide few functionalities on arduino and manage board over USB.

I connect to arduino dimmer with zero-cross and wrote custom protocol commands to change state of dimmer (Dimmer library). All working correctly but, lamp blinking sometimes.

I think problem is that firmata is using AVR cli() macro for clearing interrupt mask (code) and then lamp is blink.

Is there any method to block clearing interrupt mask (is it safe ?) ? Is any method to implement dimmer without interrupts?


Solution

  • You can not block execution of specific instructions.

    I do not know any of the mentioned libraries but can answer on a principle base:

    Usually the cli and sei instruction pairs are used to ensure atomic execution of code pieces that break if some interrupt disturbs the routine.

    Normally there are no interrupts lost because the interrupt flags are still set and the ISRs are executed after the sei instruction. But since there is no interrupt queue only one interrupt of each kind can be kept.

    Also some glitches can appear if your ISR logic expects to be called immediately - e.g. because checks the current PIN-states on an Pin-Change-Interrupt, or because it expects that some timer counter has not counted further than a few cycles and sets a new compare value (in case of bit angle modulation e.g.). In this case the timer maybe already counted further than the new compare value prior to the start of the ISR and produces glitches.

    If this is the case than in my opinion you only have few options:

    • have a look into the sources of the firmata driver and try to shrink the source between cli() and sei()` to reduce the time that the interupts are locked.
    • try to fix the dimmer library to handle the cases there the ISR was executed delayed. Maybe the visual perception of this events can be removed

    But maybe one of the following things maybe considered:

    • the design of the two libraries are incompatible
    • the AVR is to slow to handle both appropriately, so that it always lose some ISRs

    If you are stuck to AVRs - maybe left the external protocol decoding on one and build a little UART/SPI channel with very simple protocol to another and run the Dimming Light control logic on that.