1
\$\begingroup\$

I am currently trying to write code for a 48 channel DMX controlled dimmer using a PIC24FJ32GA002. Using a scope I have confirmed that there is a DMX signal reaching the Rx pin of the UART which has been configured correctly using the PPS function of the pic. Also nested interrupts are disabled.

Below is the contents of my ISR for the UART Rx interrupt. What happens when I debug it with a breakpoint set inside the ISR is that the ISR triggers once or twice with null data reaching U1RXREG, it then fails to trigger again and the program runs with no further interrupts.

The main loop for the program has a loop that processes the incoming DMX packets and outputs to the PWM controller. dmxRecieveByte() takes the contents of rxbyte and places it into a buffer that's the right size to store a DMX packet (512 bytes) to then be copied to a separate buffer when the packet is received.

UPDATE: I have changed the ISRs so that there are seperate handlers for errors and incoming bytes, the uartRecieve() function now handles sorting the incoming bytes and the ISRs take care of clearing flags and such. The Tx ISR is there as a placeholder untill I get the DMX functionality working correctly.

UPDATE 2: Added the UART init code and the updated Rx ISR code, still getting the ISR firing once at the programs first run then not happening again. I've got the production hardware now so any variables that were in that have been removed. Poked around with a scope probe and everything seems to be in order signal wise.

UART Init function

void dmxInit(void)
{

    DMX_UART_MODE    = 0b0000000000001001;
    DMX_UART_BAUD    = (FCY/(4*250000))-1;
    DMX_INT_PRIORITY = 0x07;

    PORTBbits.DMX_RX_MUX = 0;

    spareBufValid = 0;

    DMX_UART_ENABLE_BIT = 1;
    DMX_INT_ENABLE_BIT  = 1;
}

UART Rx ISR

void __attribute__ ((interrupt,no_auto_psv)) DMX_INTERRUPT_FUNC(void)
{
    uint8_t dmxData;

    if(DMX_OVERRUN_BIT)
    {   // Overrun error
        DMX_OVERRUN_BIT = 0;
        dmxReset();
    }
    else
    {   // empty any data in the UART fifo
        while(DMX_DATA_AVAIL_BIT)
        {
            if(DMX_FRAME_ERR_BIT)
            {   // frame error
                if(DMX_DATA_REG)
                {   // data is not 0 - not a break
                    dmxReset();
                }
                else
                {   // its a break!
                    breakDetected = 1;
                    startDetected = 0;

                    if(writeCount)
                    {
                        dmxWriteBufSwap();
                    }
                }
            }
            else
            {   // data in the fifo
                dmxData = DMX_DATA_REG;

                if(breakDetected)
                {
                    if(startDetected)
                    {   // some DMX data
                        if(rxCount == fixture.DMXStartAddress)
                        {
                            pByteWrite = pWriteBuf;
                        }

                        if(pByteWrite)
                        {
                            *pByteWrite++ = dmxData;
                            writeBufSize++;

                            if( (writeBufSize >= NumberOfChannels) || (rxCount >= NUM_DMX_CHANNELS-1) )
                            {   // finished receiving this packet
                                dmxWriteBufSwap();
                            }
                        }
                        rxCount++;
                    }
                    else
                    {   // This is the start code
                        if(dmxData == DMX_DATA_START_CODE)
                        {
                            startDetected  = 1;
                            writeBufSize   = 0;
                            rxCount        = 0;
                        }
                        else
                        {   // some other start code
                            dmxReset();
                        }
                    }
                }
            }
        }
    }
    DMX_INT_FLAG_BIT = 0;   // Clear interrupt flag
}
\$\endgroup\$
  • 3
    \$\begingroup\$ The ISR looks correct to me. Post your initialization. \$\endgroup\$ – Oleg Mazurov Jan 23 '15 at 17:09
  • \$\begingroup\$ Global interrupts enabled? \$\endgroup\$ – Justin Trzeciak Jan 24 '15 at 17:10
2
\$\begingroup\$

So turns out that that family of PICs has an ADC module that automatically takes priority over any other components and prevents pins from causing interrupts until it is disabled. Added some disable code to the main hardware initialization function to disable the ADC on all pins and it works a treat now.

\$\endgroup\$
0
\$\begingroup\$

That PIC has a separate interrupt vector for UART errors.
I think that you'll find that your UART is stuck in an unhandled error condition and is refusing to receive any more data.
I'd suggest you move your overrun and framing error checking & handling code to a new _U1ErrInterrupt handler.

\$\endgroup\$
  • \$\begingroup\$ There is a separate interrupt handler for errors, I'll see if re-structuring my code helps. \$\endgroup\$ – RobbG Jan 23 '15 at 16:32
  • \$\begingroup\$ Show us your UART init code too. There may be something there ... \$\endgroup\$ – brhans Jan 23 '15 at 21:49

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.