This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Receiving DMX512 data stream

Parts of this discussion started on this thread: i-am-trying-to-do-dmx512-protocol

I am using SDK 15.2.0 on an nRF52810.  My test board is based off of a Laird BL651 which contains a real (not simulated) nRF52810.  I'm using the Segger IDE.  My code is based off of the ble_app_uart_pca10040e_s112 example.  I made a copy of app_uart_fifo.c and modified to use the nrfx_uarte drivers directly.

I am trying to receive a DMX512 data stream. The DMX controller sends a packet of up to 513 bytes of data at 250KBaud and precedes each packet with a UART BREAK (holds the line low for 90us).  In my test case the controller is only sending 65 bytes of data.

I initiate the read using: nrfx_uarte_rx(&app_uart_inst, dmx_rx_buffer, BUF_READ_SIZE );  where BUF_READ_SIZE  is 513.  Here is my event handler:

static void uart_event_handler(const nrfx_uarte_event_t * p_event, void* p_context) 
{
    app_uart_evt_t app_uart_event; 
    uint32_t err_code;
 
    switch (p_event->type)
    {
        case NRFX_UARTE_EVT_RX_DONE:
            {
                //never reached??
                NRF_LOG_DEBUG("DMX data in:");
                NRF_LOG_HEXDUMP_DEBUG(dmx_rx_buffer, p_event->data.rxtx.bytes);
                (void)nrfx_uarte_rx(&app_uart_inst, dmx_rx_buffer, BUF_READ_SIZE);
            }
            break;

        case NRFX_UARTE_EVT_ERROR:
            app_uart_event.evt_type                 = APP_UART_COMMUNICATION_ERROR;
            app_uart_event.data.error_communication = p_event->data.error.error_mask;

            if (app_uart_event.data.error_communication & UARTE_ERRORSRC_BREAK_Msk)
            {
                size_t amount = nrf_uarte_rx_amount_get(app_uart_inst.p_reg);
                NRF_LOG_DEBUG("DMX err: %d %d %d %d", amount, p_event->data.rxtx.bytes,  dmx_rx_buffer[1],  dmx_rx_buffer[57]);
                (void)nrfx_uarte_rx(&app_uart_inst, dmx_rx_buffer, BUF_READ_SIZE);
            }
            break;
            
        default:
            break;
    }
}

The good news is I'm capturing the data reliably.  The bad news is I can't tell how much data was received.  The EVT_RX_DONE handler never gets called unless I reduce BUF_READ_SIZE from 513 to 65 or less.  The EVT_ERROR handler is correctly detecting BREAK.  I checked it with a scope and the handler gets called consistently 60us after the start of the BREAK which is good.  The handler is also seeing a FRAMING error which is expected.  It doesn't appear to be missing any of the BREAK events.

Once in the EVT_ERROR handler I can't find the amount of data received before the error occurred. 

Also,  if I stop the code and check the 513 byte buffer contents, I can see the correct 65 bytes of DMX data,  but the 65 bytes of data gets replicated throughout the 513 byte buffer, so I see my data at locations 0-64, but also at 65-129, 130-195, ... .

is there a way to find the number of bytes received before the BREAK and can I stop the data from filling the rest of the buffer after the BREAK is received?

Parents
  • I was wrong about the data replicating throughout the buffer.  I was checking this by pausing the code and examining the memory with the debugger.  I'm guessing that stopping the code doesn't stop ongoing UART-DMA operations so the buffer continues to fill after the break, which is good for me.

    I still need a way to find the number of bytes received before the BREAK.

Reply
  • I was wrong about the data replicating throughout the buffer.  I was checking this by pausing the code and examining the memory with the debugger.  I'm guessing that stopping the code doesn't stop ongoing UART-DMA operations so the buffer continues to fill after the break, which is good for me.

    I still need a way to find the number of bytes received before the BREAK.

Children
No Data
Related