Not seeing TI_0 interrupt flag when sending serial data mode 0

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

I'm attempting to get serial mode 0 communications working using the CY3684 demo board (CY7C68013A).

   

The TRM indicates (14.3.3 pg 203 table 14-11 for SCON0.1) that once a byte is successfully transmitted, the USART0 interrupt is triggered and the TI_0 bit (bit 1) in the SCON0 SFR is set.

   

My problem is that, while I do see the interrupt happing, the TI_0 bit doesn't appear to be set.

   

I'm using the Keil C51 c compiler and the framework provided by Cypress.  Below are the bits of code I think are relevant.

   

 

   

Setting up for serial communication:

   

    // Port E setup
    PORTECFG = 0x28; // Enable RXD0OUT and INT6 for serial coms, all other alternate functions disabled (TRM 13.4.4)
    OEE      = 0x08; // Set port RXD0OUT to output, all others inputs

    // Serial coms on serial port 0 setup (TRM 14.3.3)
    SCON0    = 0x00;   // Mode 0, baud CLKOUT/12
    EICON   &= 0xF7;
    g_is_tx  = FALSE;
    IE      |= bmBIT4; // Enable recieve and transmit interrupts
    EIE     |= bmBIT4; // Enable INT6 interrupt (used for FPGA to signal data to tx)
    EICON   &= 0xF7;

    EA = 1;

   

 

   

The byte to be sent is provided by a vendor request over EP0.

   

BOOL DR_VendorCmnd(void)
{
    switch (SETUPDAT[1])
    {
    case CMD_SEND_BYTE:
        SBUF0 = SETUPDAT[2];
        g_is_tx = TRUE;
        EP0CS |= bmHSNAK;
        break;
    }

    return(FALSE);
}

   

 

   

The USART0 ISR.  It turns on LED2 when called, and conditionally turns on LED3 and LED4 based on the TI_0 and RI_0 interrupt flags.  LED2 does turn on, but LED3 and LED4 don't.

   

void ISR_USART0(void) interrupt 4
{
    unsigned char temp;

    temp = LED2ON;

    if (SCON0 & 0x01 > 0)
        temp = LED3ON;

    if (SCON0 & 0x02 > 0)
        temp = LED4ON;
}

   

 

   

I feel like I'm missing something basic, but just haven't been able to figure it out.  Any help would be very appreciated.

0 Likes
7 Replies
Anonymous
Not applicable

Benote,

   

Please let us know the modification you've done to call ISR_USART0() when the interrupt occurs.

   

The only 2 interrupt sources of usart0 are TI_0 and RI_0 if both are not set then it most probably has to do with the way the isr is called. In codes that i've written i usually poll TI and RI, haven't really tried using in ISR. If possible please attach your code here so that we can figure what is going wrong.

   

Regards,

   

Anand

0 Likes
Anonymous
Not applicable

Hi Anand,

   

Thank you for your reply.  ISR_UART0() is in a seperate c file (isr.c) due to the #pragma NOIV directive in periph.c.  I was assuming the compiler would generate the appropriate code automatically so the function would be called on interrupt 4 (0x0023) based on the function's definition:

   

void ISR_USART0(void) interrupt 4

   

Within TD_Init() I then set bit 4 (ES0) in IE to enable the serial port 0 interrupts.

   

The interrupt does seem to be working in some fashion, given that LED2 turns on, however in further testing, I've discovered that the device stops responsing over USB once I try sending data serially.  If I disable the serial interrupt, the issue goes away and the device responds normally after sending serial data.

   

I've attached the project code.  The EZ-USB Interface in CyConsole can be used to send a Vendor Request 0x40 to trigger the sending of the byte over serial.

   

Thanks,

   

Ben

0 Likes
Anonymous
Not applicable

Hi Ben,

   

I don't see the attachment.
TI and RI are bit-addressable so one thing you might want to try is read them directly than using the & operator on SCON0 to get the values.

   

Regards,

   

Anand

0 Likes
Anonymous
Not applicable

Whoops, figures I would miss that.  It should be attached here.  I will try the bit addressable method and see what happens there.

   

 

   

-Ben

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hmm, file attachement didn't work a second time.  I'm this time with IE in case there's an odd issue using Firefox.

0 Likes
Anonymous
Not applicable

Crazy, the bit addressable method seems to have been the key.  Changing ISR_UART0() to the following produces the results I would expect, LED2 and LED4 turn on and the device continues to respond to USB commands.

   

 

   

void ISR_USART0(void) interrupt 4
{
    unsigned char temp;

   

    temp = LED2ON;

   

    if (RI != 0)
    {
        temp = LED3ON;
        RI = 0;
    }

   

    if (TI != 0)
    {
        temp = LED4ON;
        TI = 0;
    }
}

   

 

   

Is there any explanation for this kind of behaviour?  I was under the impression that the bit-addressable SFRs were there almost as a convience/save a few cycles kind of thing but not required.  In any case, it seems to be working now.  Thanks for your help Anand!

   

-Ben

0 Likes
Anonymous
Not applicable

Ben,

   

We'll have to look at what the compiler was trying to do to understand why the other approach didn't work.

   

Not sure if it reads the value from the sfr and ANDs 0x01 or it ANDs 0x01 to that register directly. The fact that USB does not respond threw all kind of red flags. Happy to know that your code works.

   

Regards,

   

Anand

0 Likes