2
\$\begingroup\$

I am trying to send DMX512 and RDM protocol to an Atmel ATmega88PA with very little results as of late. The USART will receive the incoming data, but processing is not performed correctly.

The idea behind the below code was to check for data overrun, the break, and then the actual data in the ISR and some sub functions.

ISR(USART_RX_vect){
//hw_wdt_enable();  
long data;
int temp;
while ( ! ( UCSR0A & ( 1 << RXC0 ) ) )
    ;

if ( UCSR0A & (1 << DOR0 ) ) 
{   // check for data over run
    data = UDR0; 
    temp = UCSR0A;
}
else if( UCSR0A & ( 1 << FE0 ) ) 
{   //some form of break detection
    data = UDR0; 
    temp = UCSR0A;
    rs485_break_received( data );
}   
else if( g_break_received )
{   //if we have a break msg is next
    g_break_received = 0;
    data = UDR0; 
    temp = UCSR0A;
    g_checksum = rs485_data_received ( data );
}
if ( g_checksum != 0 )
{
    g_error_count++;
}  }

void rs485_break_received ( uint8_t data ){ 
if ( 0 != s_slotNext )
{   // 2nd break, it's a DMX message
    // the whole message was received   
    s_pBuffer[s_slotNext] = data;
    uint8_t* pLast = s_pBuffer + s_slotNext;
    processing_queue_message ( s_pBuffer, pLast );
}
g_break_received = 1;
rs485_prepare_next_buffer ();  }

rs485_data_received checks the checksum on the message and will either move to processing_queue_message or return an error.
processing_queue_message goes into looking at the start codes to determine if its a RDM or DMX message.

I am using a DMXter 4 RDM module to test this code, trying to transmit a level change to a single channel, but I am getting information that is way off base.

  1. If I actually send data the program just keeps running.
  2. If I do not click send the program is constantly jumping into the Framing Error part.
  3. If I go above 128/255 for the level to be transmitted the program will go into the g_break_received part

2 & 3 happen before I even click transmit.

I think there is a problem clearing the Framing Error bit in USCR0A, but I am unsure how to correct it as the data sheet just says read the register. Is there some part of the DMX standard that I am missing? or maybe another way to clear the Framing Error?

\$\endgroup\$
1
\$\begingroup\$

I don't think it is a good idea to call lots of functions from your interrupt handler. Try to change it so it only reads the data to a buffer, and clear any possible error. Then have on your main loop a function to check for received data and process accordingly. That would be a first step to debug your problem.

On a side note, have you tried sending other types of data, say, ascii chars through RS485 and see if the get to your board?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.