My Cortex-M4 project uses a bank of WS2812 LEDs that require precise delays
in the nanosecond range when modulating a data pin. The typical approach
when using this part is to suspend all interrupts, pull the pin high, issue
a certain number of NOP instructions depending on the value to display,
then pull the pin low and issue another set of NOP instructions, repeating
the process until all values are displayed and finally re-enabling
interrupts.
There are several options available in FreeRTOS for exclusive access:
vTaskSuspendScheduler, taskDISABLE_INTERRUPTS and taskENTER_CRITICAL.
Considering my requirement is to have exclusive use of the chip for timing
(not access to a shared resource), which is the preferred approach? If I
use critical sections, will I need to set the priority of all interrupts to
be at least BASEPRI so they are masked? Will the PendSV and SysTick
interrupts still run, possibly throwing the timing out of whack?
If you inisist on your bit-banging approach, then you need to make sure that your bit banging is not interrupted at all during the data transfer. If doing this from a task, you need to turn off all interrupts. You need to check your port how it deals with the interrupts:
taskENTER_CRITICAL on Cortex-M3/4/7 only masks interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY, so other interrupts with higher urgency still run.
dito for taskDISABLE_INTERRUPTS: it uses BASEPRI for interrupt masking.
What you need to use is to disable all interrupts which usually is provided in the FreeRTOS port like this:
Thanks Erich, yes I’m an avid reader of your blog and have been following your interrupts series. I did not know you had already covered the particular requirements of the WS2812, and I’ll give the FTM/DMA approach a shot.
Simon.