How to read DMX with FreeRTOS?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to read DMX with FreeRTOS?

1,389 Views
shu-nongwu
Contributor I

Hi everyone, I'm working on a DMX decoder using the FreeRTOS drivers and K21 micro controller. To give some background information about DMX, There is a BREAK(low, 88 us minimum) and then MARK AFTER BREAK(high, 8 us minimum) followed by 8N2 UART frames. My implementation of a DMX decoder involves timing the BREAK to check if it's valid. If the timing is valid then a Semaphore is passed to a task that reads UART using UART_RTOS_Receive. However there are issues that arise.

- First of all, if the packet is smaller than the buffer size then the event bit that is responsible for telling the RTOS, "OK we are done reading UART bytes" isn't triggering even if the UART line is IDLE.

- Another problem is that when the function UART_RTOS_Receive is first called, there is a framing error. What is strange is that the function gets called during the MARK AFTER BREAK when the line is IDLE so the IDLE is being interpreted as a framing error for some reason.

If anyone can shed some light on this issue then that would be greatly appreciated.

Edit: Spelling

Labels (1)
Tags (4)
0 Kudos
6 Replies

1,061 Views
shu-nongwu
Contributor I

Hi just to give everyone an update. I'm running into some really weird issues with this program. After the mark after break, I'm enabling the UART IRQ and setting the interrupt to activate on the "read data register full" flag, RDRF. The UART peripheral should start shifting bytes into the register as soon as the start byte occurs which means that 44 us (11 bits) after the MAB ends/start byte begins there should a UART_TX_RX_IRQ triggered. However in my program this IRQ is triggering 20-22 us after the MAB ends/start byte. Subsequently the IRQ get triggered ~20-24 us after the previous one gets triggered. The time it takes for the IRQ to trigger after the MAB should be 44 us because that's how long it takes to shift 11 bits in. My baud rate is 250k.

I attached images of the suspicious errors. I'm debugging this program by generating a pulse on one of the pins (gpio on off) within the UART_TX_RX_IRQ handler every time it gets called and using an oscilloscope to read the pulse.

After_MAB_timing.png

Between_2_IRQ_timing.png

0 Kudos

1,061 Views
mjbcswitzerland
Specialist V

Hi Shu-Nong

This is the DMX512 Rx timing and interrupts on a K21 using the uTasker DMX512 driver (in interrupt driven mode):

pastedImage_2.png

1. The break is detected by a framing error interrupt 11 bits (44us) after the start of the break.
2. Subsequent interrupt occur just after the start of the start bit (or after the end of the second stop bit)
3. Following interrupt occur at each character (44us rate)

The first data byte on a DMX512 frame (with DMX content) is 0x00 - the measured delay from the end of the MAB (start bit of this byte) to the interrupt is practically about 46us.

I conclude that your possible problems could be that you
- have the wrong baud rate programmed at the receiver.
- or you have pending interrupts when you enable the rx interrupt when starting

Generally the Rx interrupt can be left enabled all the time in this mode - enabling it after MAB is risky since it is potentially time critical.

Regards

Mark

uTasker - for more performance and faster, cheaper product development

0 Kudos

1,061 Views
danielchen
NXP TechSupport
NXP TechSupport

Hi Shu-nong:

RTOS Uart driver is blocking the current task until whole required data are received.

It works like this,  in the UART ISR, when the predefined number of data has been received already, the callback functioin is called, the in the callback function, a semaphore is posted.

You can refer to the implementation of UART_RTOS_Receive function

int UART_RTOS_Receive(...)

{

...

   ev = xEventGroupWaitBits(handle->rxEvent,
                             RTOS_UART_COMPLETE | RTOS_UART_RING_BUFFER_OVERRUN | RTOS_UART_HARDWARE_BUFFER_OVERRUN,
                             pdTRUE, pdFALSE, portMAX_DELAY);

...

}

If you needs to receive function to return immediately, I would suggest you try the following.   modify the last parameter of xEventGroupWaitBits from portMAX_DELAY to a short value. for exampel 32 or other.

Regards

Daniel

0 Kudos

1,061 Views
shu-nongwu
Contributor I

I understand that the RTOS_UART_COMPLETE event flag is suppose to be set when the idle line is high. 

if (status == kStatus_UART_RxIdle)
{
xResult = xEventGroupSetBitsFromISR(handle->rxEvent, RTOS_UART_COMPLETE, &xHigherPriorityTaskWoken);
}

when the DMX frame is finished, shouldn't it send the line high signaling the UART peripheral that it is in IDLE mode.

0 Kudos

1,061 Views
mjbcswitzerland
Specialist V

Shu-Nong

I don't think that idle line detection is valid for DMX512 decoding since the specification allows gaps (idle line) between the slots to be sent (not just after the complete frame). Also, in some frames (also short ones) that repeat as soon as the last data slot has been sent there is no IDLE line state that occurs!

Therefore I think that you need to use break detection instead because that is what is guaranteed to be present. Maximum sized 513 slot frames can of course also be terminated when the maximum number of bytes has been received.

Regards

Mark

0 Kudos

1,060 Views
mjbcswitzerland
Specialist V

Hi

I have attached the uTasker DMX512 (including RDM) document that is being prepared - it can be used on any Kinetis part (also using DMA for lowest overhead) and works together with FreeRTOS (as option).
Contact me directly if there is interest.

Regards

Mark

0 Kudos