This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

F28335 SCI-A Interrupts RXRDY/BRKDT not working

Other Parts Discussed in Thread: TMS320F28335, CONTROLSUITE

Hello TI Community!

I am working with the TMS320F28335's SCI-A serial communication. When RXRDY/BRKDT interrupt is enabled by setting the RX/BKINTENA bit and desabling SCIFFENA the RXRDY/BRKDT interrupts (as well as the flags itselves have been tested) does not work. I assumed that the Pie configuration is ok, once that when enabled the FIFO Interrupt works fine.

Configuration that FIFO interrupt works:

PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block

PieCtrlRegs.PIEIER9.bit.INTx1=1; // PIE Group 9, int1
IER = 0x100; // Enable CPU INT
EINT;

SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
SciaRegs.SCICTL2.bit.TXINTENA =1;
SciaRegs.SCICTL2.bit.RXBKINTENA =1;
//SciaRegs.SCIHBAUD = 0x0000;
//SciaRegs.SCILBAUD = SCI_PRD;

SciaRegs.SCIHBAUD = 0x01;
SciaRegs.SCILBAUD = 0xE7;


//SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop back
SciaRegs.SCIFFTX.all=0xC028;
SciaRegs.SCIFFRX.all=0x0028;
SciaRegs.SCIFFRX.bit.RXFFIL = 0x0010;

SciaRegs.SCIFFTX.bit.SCIFFENA = 0;
SciaRegs.SCIFFCT.all=0x00;

SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;
SciaRegs.SCIFFRX.bit.RXFIFORESET=1;

When I want to use RXRDY/BRKDT interrupt I desable FIFO registers as well as FIFO interrupt, but RXRDY/BRKDT does not work yet. I followed the "scia_loopback_interrupts" example to do the configurations. It's funny how in this example both interrupts are set, both RXRDY/BRKDT and FIFO interrupt (TXFFINT), when it's clear for me in the SCI manual that only one of them can work at a time, once that the RXRDY/BRKDT interrupt only works with the FIFO desabled, as shown in "Figure 1-10. SCI FIFO Interrupt Flags and Enable Logic" of SPRUFZ5A.

Can anyone help me set the RXRDY/BRKDT interrupt? Or even make those flags work. I tested the flags using breakpoints but when data was sent none of them was detected.

  • Corrections: FIFO interrupt used is RXFFINT. Notice that even with SCIFFENA = 0 the FIFO interrupt is working.

  • Alexandre,

    I wrote below loopback code without using FIFO.  Try this.  It works.  RX/BK interrupt is used. 

    Please note that in non-FIFO mode, in order for the first transmit interrupt to occur, you need to first transmit a character.

    Did you check whether the SCIRX pin is receiving the data or not using a scope?

    In the SCI examples that TI provided, below configuration is not needed when FIFO is enabled.  But it does not hurt to keep it.  Initially there is no FIFO in C28x SCI.  Later it is added as an enhancement and at that time those examples are just appended with FIFO settings and hence you see the below statement.

    SciaRegs.SCICTL2.bit.RXBKINTENA =1;

    //-------------------------------------------------------------------------------------------------------------------------

    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

    #define CPU_FREQ   150E6
    #define LSPCLK_FREQ  CPU_FREQ/4
    #define SCI_FREQ   100E3
    #define SCI_PRD   (LSPCLK_FREQ/(SCI_FREQ*8))-1

    // Prototype statements for functions found within this file.
    interrupt void sciaTxIsr(void);
    interrupt void sciaRxIsr(void);
    void scia_init(void);
    void error(void);

    // Global variables
    Uint16 rdataA = 0;    // Received data for SCI-A
    Uint16 i = 1;

    void main(void)
    {
       Uint16 i;

    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2833x_SysCtrl.c file.
       InitSysCtrl();

    // Step 2. Initalize GPIO:
    // This example function is found in the DSP2833x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();
    // Setup only the GP I/O only for SCI-A and SCI-B functionality
    // This function is found in DSP2833x_Sci.c
       InitSciGpio();

    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;

    // Initialize PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP2833x_PieCtrl.c file.
       InitPieCtrl();

    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP2833x_DefaultIsr.c.
    // This function is found in DSP2833x_PieVect.c.
       InitPieVectTable();

    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
       EALLOW; // This is needed to write to EALLOW protected registers
       PieVectTable.SCIRXINTA = &sciaRxIsr;
       PieVectTable.SCITXINTA = &sciaTxIsr;
       EDIS;   // This is needed to disable write to EALLOW protected registers


    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP2833x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
       scia_init();  // Init SCI-A

    // Step 5. User specific code, enable interrupts:


    // Enable interrupts required for this example
       PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
       PieCtrlRegs.PIEIER9.bit.INTx1=1;     // PIE Group 9, int1
       PieCtrlRegs.PIEIER9.bit.INTx2=1;     // PIE Group 9, INT2
       IER = 0x100; // Enable CPU INT
       EINT;

    // Step 6. IDLE loop. Just sit and loop forever (optional):
        SciaRegs.SCITXBUF=i;
        i++;
     for(;;);

    }

    void error(void)
    {
        asm("     ESTOP0"); // Test failed!! Stop!
        for (;;);
    }


    interrupt void sciaTxIsr(void)
    {

        SciaRegs.SCITXBUF=i;     // Send data
        i++;
       
        if(i == 0xFFFF)
         i = 0;

        PieCtrlRegs.PIEACK.all|=0x100;      // Issue PIE ACK
    }

    interrupt void sciaRxIsr(void)
    {
     rdataA = SciaRegs.SCIRXBUF.all;  // Read data
     
     PieCtrlRegs.PIEACK.all|=0x100;       // Issue PIE ack
    }

    void scia_init()
    {
       SciaRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback
                                      // No parity,8 char bits,
                                      // async mode, idle-line protocol
       SciaRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,
                                      // Disable RX ERR, SLEEP, TXWAKE
       SciaRegs.SCICTL2.bit.TXINTENA =1;
       SciaRegs.SCICTL2.bit.RXBKINTENA =1;
       SciaRegs.SCIHBAUD = 0x0000;
       SciaRegs.SCILBAUD = SCI_PRD;
       SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop back

       SciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset

    }


    //===========================================================================
    // End of code

    //===========================================================================

    Thanks and regards,
    Vamsi

  • Thanks a lot for your quick answer, Vamsi. I realized my RX/BK interrupt was not being detected because I was writing "SciaRegs.SCIFFTX.all=0x0000;" wich was assigning 0 to bit SCIRST. When I tested with your rotine I realized that as you did not change SCIFFTX value, the default value was 0xA000, wich set SCIRST and TXFIFO Reset to 1, what made my RX/BK interrupt be detected.

    Now I face another problem. I want to implement Idle-Line Multiprocessor Mode. I am traying to follow the manual steps in my routine, wich are:

    Step 1. SCI wakes up after receipt of the block-start signal.

    Step 2. The processor recognizes the next SCI interrupt.

    Step 3. The interrupt service routine compares the received address (sent by a remote transmitter) to its own.

    Step 4. If the CPU is being addressed, the service routine clears the SLEEP bit and receives the rest of the data block.

    Step 5. If the CPU is not being addressed, the SLEEP bit remains set. This lets the CPU continue to execute its main program without being interrupted by the SCI port until the next detection of a block start.

    My comments:

    Step 1: Should I use RXWAKE for the SCI to wake up?

    Step 2: Assuming that SLEEP bit is set (as said in Step 5: SLEEP REMAINS set, ie, is is already set). Wich interrupt is detected? (with SLEEP set, RXRDY is not detected). Is it the BRK flag that sets this interrupt?

    I am getting confused on how to detect the start of the block and the end of it. Wich register should I use to detect the start of the block, so that I can read the address and compare it? Wich register indicates that the block is over, so I can go on with my rotine? The intention is that DSP will work as slave. It must wait for a block of bytes, read it if adreessed, and then reply.

  • This is the situation i'm in! I got the following questions:

    1. When SLEEP bit is set (=1), how to detect and receive the first byte to check the address? Shall i use RXRDY interrupt or just polling in the main loop?

    2. How to detect the end of the incoming message (the last byte of it)? Should i check the RXWAKE in the RXRDY interrupt? As mentioned in datasheet, RXWAKE would be reset to 0 when SCIRXBUF is read, so if I read the SCIRXBUF within the RXRDY interrupt (as for the last byte), where should i check the RXWAKE, before reading SCIRXBUF or after it?

    Thanks!!

  • Hi,

    I am using it in similar configuration, but I am not using loopback mode.. but it never generates the receiver interrupt.

    my source code is shown below.

    #include "DSP2833x_Device.h"

    // External Function prototypes
    extern void InitSysCtrl(void);
    extern void InitPieCtrl(void);
    extern void InitPieVectTable(void);

    // Prototype statements for functions found within this file.
    void Gpio_select(void);
    void SCIA_init(void);
    //interrupt void sci_tx_isr(void); // Prototype for Timer 0 Interrupt Service Routine
    interrupt void sci_rx_isr(void);
    char received_data =1;
    unsigned int index =0; // pointer into string
    //###########################################################################
    // main code
    //###########################################################################
    void main(void)
    {


    InitSysCtrl(); // Basic Core Initialization
    // SYSCLK=150MHz, HISPCLK= 75MHz, LSPCLK=37.5MHz
    EALLOW;
    SysCtrlRegs.WDCR= 0x00E8; // Re-enable the watchdog
    EDIS; // 0x00E8 to disable the Watchdog , Prescaler = 1
    // 0x00AF to NOT disable the Watchdog, Prescaler = 64

    Gpio_select(); // GPIO9, GPIO11, GPIO34 and GPIO49 as output
    // to 4 LEDs at Peripheral Explorer

    SCIA_init(); // Initalize SCI

    InitPieCtrl(); // default status of PIE; in DSP2833x_PieCtrl.c

    InitPieVectTable(); // init PIE vector table; in DSP2833x_PieVect.c

    // re-map PIE - entry for Timer 0 Interrupt
    EALLOW;
    // PieVectTable.SCITXINTA = &sci_tx_isr;
    PieVectTable.SCIRXINTA = &sci_rx_isr;
    EDIS;


    // Enable TINT0 in the PIE: Group 1 interrupt 7
    PieCtrlRegs.PIEIER9.bit.INTx1 = 1;
    // PieCtrlRegs.PIEIER9.bit.INTx2 = 1;

    // Enable CPU INT1 which is connected to CPU-Timer 0:
    IER = 0x0100;

    // Enable global Interrupts and higher priority real-time debug events:
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM
    SciaRegs.SCITXBUF=0x00;
    while(1)
    {

    }
    }

    void Gpio_select(void)
    {
    EALLOW;
    GpioCtrlRegs.GPAMUX1.all = 0; // GPIO15 ... GPIO0 = General Puropse I/O
    GpioCtrlRegs.GPAMUX2.all = 0; // GPIO31 ... GPIO16 = General Purpose I/O

    GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // SCIRXDA
    GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1; // SCITXDA

    GpioCtrlRegs.GPBMUX1.all = 0; // GPIO47 ... GPIO32 = General Purpose I/O
    GpioCtrlRegs.GPBMUX2.all = 0; // GPIO63 ... GPIO48 = General Purpose I/O
    GpioCtrlRegs.GPCMUX1.all = 0; // GPIO79 ... GPIO64 = General Purpose I/O
    GpioCtrlRegs.GPCMUX2.all = 0; // GPIO87 ... GPIO80 = General Purpose I/O

    GpioCtrlRegs.GPADIR.all = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO9 = 1; // peripheral explorer: LED LD1 at GPIO9
    GpioCtrlRegs.GPADIR.bit.GPIO11 = 1; // peripheral explorer: LED LD2 at GPIO11

    GpioCtrlRegs.GPBDIR.all = 0; // GPIO63-32 as inputs
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // peripheral explorer: LED LD3 at GPIO34
    GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; // peripheral explorer: LED LD4 at GPIO49

    GpioCtrlRegs.GPCDIR.all = 0; // GPIO87-64 as inputs
    EDIS;
    }

    void SCIA_init()
    {
    SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
    // ODD parity,8 char bits,
    // async mode, idle-line protocol
    SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
    // Disable RX ERR, SLEEP, TXWAKE

    // SYSCLOCKOUT = 150MHz; LSPCLK = 1/4 = 37.5 MHz
    // BRR = (LSPCLK / (9600 x 8)) -1
    // BRR = 487 gives 9605 Baud
    SciaRegs.SCIHBAUD = 487 >> 8; // Highbyte
    SciaRegs.SCILBAUD = 487 & 0x00FF; // Lowbyte
    SciaRegs.SCICTL2.bit.TXINTENA=1;
    SciaRegs.SCICTL2.bit.RXBKINTENA=1;
    SciaRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset
    }

    //interrupt void sci_tx_isr(void)
    //{
    // switch(received_data)
    // {
    // case 1:
    // SciaRegs.SCITXBUF = 'U'; // send single character
    // PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    // break;
    // case 2:
    // SciaRegs.SCITXBUF = 'M'; // send single character
    // PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    // break;
    // case 3:
    // SciaRegs.SCITXBUF = 'E'; // send single character
    // PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    // break;
    // case 4:
    // SciaRegs.SCITXBUF = 'S'; // send single character
    // PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    // break;
    // case 5:
    // SciaRegs.SCITXBUF = 'H'; // send single character
    // PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    // break;
    // default:
    // //SciaRegs.SCITXBUF.all = "T"; // send single character
    // PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    // break;
    // }
    //}


    interrupt void sci_rx_isr(void)
    {
    received_data = SciaRegs.SCIRXBUF.bit.RXDT;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    }
    //===========================================================================
    // End of SourceCode.
    //===========================================================================

    Thanks & Regards,

    Umesh T

  • If you also set GPAPUD (enable pull up) for RX and TX and GPAQSEL for RX, does it work?

    Best regards,

    Maria

  • Hi,

    No, It doesn't make any difference.. For me transmission is working properly.. Receiver only not working both in interrupt and polling method i tried no response...

    RXRDY bit is not at all get set to 1..

    Thanks & Regards,

    Umesh T

  • How did you set the GPAPUD and GPAQSEL?

    It should be:
        GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0;    // Enable pull-up for GPIO28 (SCIRXDA)
        GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0;       // Enable pull-up for GPIO29 (SCITXDA)

    /* Set qualification for selected pins to asynch only */
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.

        GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3;  // Asynch input GPIO28 (SCIRXDA)


    Also, what is your kit? Is it custom kit? How do you connect RX and TX (to PC)?

    Best regards,

    Maria

  • Hi,

    I am using TI's Experimenters kit with 28335 control card only..

    Yes initially InitSciaGpio() fn provided by TI.. In that one pullup and qualification config done..but remains same.

    when I use the configuration for C2000 launchpad its generating an interrupt..

    From this I am sure there wont be problem with software. 

    In the 28335 controlcard(TMDSCNCD28335PCF R1.0) the SW1 sci rx switch i tried it in open and close conditions still not able to get it work.

    anything else do i have to change???

    Thanks & Regards,

    Umesh T

  • Hi Umesh,

    This controlCARD actually has two separate ways of connecting to SCIA (on GPIO28/29) of the MCU:

    1) Via the 4-pin header J3 on the Docking Station: 
    J9 on the Docking Station should be unpopulated and SW1 should be closed

    2) Via the USB connector JP1 on the Docking Station:
    J9 on the Docking Station should be populated and SW1 should be open

    The above description along with the cCARD and Docking Station schematics located in controlSUITE should help you get the hardware setup correct.

    Hopefully this helps!


    Thank you,
    Brett

  • Hi,

    I will try.. I am trying to connect through usb ly.. J9 is not populated and I ll try..

    Thanks & Regards,

    Umesh T