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.

SCI FIFO Interrupts

In Sprufk7a, page 34 ... RXFFIL4-0: "Receive FIFO generates interrupt when the FIFO status bits (RXFFST4–0) and FIFO level bits (RXFFIL4–0) match (i.e., are greater than or equal to)." Does this mean an interrupt does not occur until the FIFO has the number of bytes specified in RXFFST4-0?

Besides setting "SciaRegs.SCICTL2.bit.RXBKINTENA = 1;" What settings should be set so in interrupt occurs only when a break occurs, regardless of the number of bytes in the FIFO?

  • Clyde,

    In Sprufk7a, page 34 ... RXFFIL4-0: "Receive FIFO generates interrupt when the FIFO status bits (RXFFST4–0) and FIFO level bits (RXFFIL4–0) match (i.e., are greater than or equal to)." Does this mean an interrupt does not occur until the FIFO has the number of bytes specified in RXFFST4-0?

    Vamsi:  It means that an interrupt does not occur until RX FIFO has received the number of bytes specified by the user in RXFFIL4-0. 

    Besides setting "SciaRegs.SCICTL2.bit.RXBKINTENA = 1;" What settings should be set so in interrupt occurs only when a break occurs, regardless of the number of bytes in the FIFO?

    Vamsi:  When FIFO is enabled, RXERRINTENA (SCICTL1.6) has to be enabled and RXFFIENA (SCIFFRX.5) has to be disabled for your requirement. 

    Thanks and regards,

    Vamsi

  • Why should RXERRINTENA be enabled?  A break is not an error. 

    I tried it with RXERRINTENA disabled and enabled ... and I set RXFFIENA to be disabled ... no interrupts now.  I do have the FIFO receive enabled:  "SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;"

    To clarify, I want to have the incoming info put into a FIFO ... but don't want the interrupt to occur until the data stops coming. 

  • Clyde,

    A break detect condition occurs (the SCIRXD is low for ten bit periods following a missing stop bit).  This action sets the BRKDT flag bit (SCIRXST, bit 5) and initiates an interrupt.  It is considered as an error because a stop bit is missing.  To enable FIFOs, you need to set SCIFFENA bit in SCIFFTX.

    Please refer to Table 1-6. SCI Interrupt Flags in SCI reference guide for more details.

    You can also look at "scia_loopback_interrupts" example in headerfile examples.

    Thanks and regards,

    Vamsi

  • I have looked at all of the scia example files.  Here is what I have:

      SciaRegs.SCICCR.bit.SCICHAR = 7;
      SciaRegs.SCICCR.bit.ADDRIDLE_MODE = SCI_ADR_MODE_DISABLED;
      SciaRegs.SCICCR.bit.LOOPBKENA = 0;
      SciaRegs.SCICCR.bit.PARITYENA = SCI_PARITY_ENABLED;
      SciaRegs.SCICCR.bit.PARITY = SCI_PARITY_EVEN;
      SciaRegs.SCICCR.bit.STOPBITS = SCI_ONE_STOP_BIT;

      SciaRegs.SCICTL1.bit.RXENA = 1;
      SciaRegs.SCICTL1.bit.TXENA = 1;
      SciaRegs.SCICTL1.bit.SLEEP = 0;
      SciaRegs.SCICTL1.bit.TXWAKE = 0;
      SciaRegs.SCICTL1.bit.SWRESET = 0;
      SciaRegs.SCICTL1.bit.RXERRINTENA = 1;

      SciaRegs.SCICTL2.bit.TXINTENA = 0;
      SciaRegs.SCICTL2.bit.RXBKINTENA = 1;

      SciaRegs.SCIHBAUD = 0x0000;
      SciaRegs.SCILBAUD = (LSPCLK_FRQ / (BAUD_RATE * 8.)) - 1 + 0.5;

      SciaRegs.SCIFFTX.bit.TXFFIL = 0;
      SciaRegs.SCIFFTX.bit.TXFFIENA = 0;
      SciaRegs.SCIFFTX.bit.TXFFINTCLR = 0;
      SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 0;
      SciaRegs.SCIFFTX.bit.SCIFFENA = 1;
      SciaRegs.SCIFFTX.bit.SCIRST = 1;

      SciaRegs.SCIFFRX.bit.RXFFIL = 0x08;
      SciaRegs.SCIFFRX.bit.RXFFIENA = 0;
      SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;
      SciaRegs.SCIFFRX.bit.RXFIFORESET = 0;
      SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1;

      SciaRegs.SCIFFCT.bit.FFTXDLY = 0;
      SciaRegs.SCIFFCT.bit.CDC = 0;
      SciaRegs.SCIFFCT.bit.ABDCLR = 1;

      SciaRegs.SCICTL1.bit.SWRESET = 1;
      SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1;
      SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;

    Something appears to be wrong as the interrupts no longer occur.  They were occurring when RXFFIENA was set, although then they occurred only after enough bytes were received.  Exactly, what code needs to be changed or added?

  • Unfortunately the SCI does not do what I think you want it to do by itself.  Correct me if I am mistaken but you are wanting to create an interrupt when there is no SCI traffic for a certain period of time.  The SCI will generate an interrupt (in FIFO mode) on a break (10 or more periods after a missing stop bit), error or FIFO full condition.  Your code above is set up to just generate interrupts on errors or breaks which are rare occurences and its is not uncommon for that not to happen.

    In order to acheive what I think you need I suggest you do the following:

    1) Create a one-shot timer with the desired timeout.  Don't start it.

    2) Enable the RX FIFO full interrupt.  For ease of use I recommend you set the FIFO level to 1 so that it generates an interrupt on every RX.

    3) In the interrupt start and reset the timer.

    4) Make a timer interrupt.  When this interrupt occurs it will be a certain time (desired timeout) after your last successful receive. Stop the timer in this interrupt.

     

    This solution works by resetting the timer upon every new RX so that it does not interrupt  until the desired timeout is reached after the last successful interrupt.

     

    Hopefully I have got the jist of what you need and it helps.

     

    Tim

  • This makes no sense.  Typically, a burst of bytes are sent ... an unknown number of bytes.  All I want is to capture the half dozen plus bytes that were sent into the FIFO, and then extract them from the FIFO after they have been received.  Since this is typical, a timer should not be needed.

     

  • Clyde,

    If I understand your requirement correctly, you need to

    (1) extract the bytes received in FIFO when the FIFO has 6 characters in it with out using interrupt and

    (2) an interrupt should occur only whenever there is a break condition detected. 

    For this above purpose,

    (1) You can poll the status of RXFFST bits for the number of bytes that you want to be in FIFO before reading the FIFO. 

          while(SciaRegs.SCIFFRX.bit.RXFFST !=6) { }

    (2) For an interrupt to occur upon a break detect, you need to enable RXERRINTENA (SCICTL1.6). 

    Thanks and regards,

    Vamsi

  • Don't know how many bytes.  Just want to retrieve the info after the bytes have been sent.

    It seems that "SciaRegs.SCICTL2.bit.RXBKINTENA = 1" should be adequate to have an interrupt after the bytes have been received.

  • Sorry if i misunderstood your requirements.   My solution is for a unknown length group of bytes, but it needs to have an interrupt every incoming byte for it to work successfully.

     

    Clyde Eisenbeis said:

    Don't know how many bytes.  Just want to retrieve the info after the bytes have been sent.

    It seems that "SciaRegs.SCICTL2.bit.RXBKINTENA = 1" should be adequate to have an interrupt after the bytes have been received.

    The problem with this is that it does not work in FIFO mode. Also a break condition is an error with a missing stop bit, not a cue to a stream of bytes finishing.  It will not trigger unless there is a missing stop bit so unless you can control your last byte to have a missing stop bit it will do nothing for you.

    I think the major issue here is the fact that the bytestream length is unknown. The FIFO is designed to interrupt after a known amount of bytes.  You could poll it at an approximately known rate to see how many you have but other than that I can not see a simple way of doing this in a single interrupt in this SCI unit.

     

    There is one other way I just thought of which uses an interrupt twice but it relies on the data.  This may not be what is your bytestream but it could be.  If you have a length byte in your bytestream early on (say 2nd byte for example) you could:

    1) Set up the FIFO to interrupt after 2 bytes.  On the interrupt, store the data, read the length byte.

    2) Alter the FIFO to interrupt after ~length bytes.  It should interrupt on the last byte.  Reset it to interrupt after 2 bytes.

    Just a possible solution if it fits your requirements.

     

    Tim

     

     


  • I'll try a few things to see if I can find an adequate, temporary solution.

    I just noticed that "SCIRXST: BRKDT" is not being set after bytes have been received.  The "SCICTL1: SWRESET" is being set to 0 and then to 1 during initialization and "SCICTL2: RXBKINTENA" is set to 1.  What else needs to be done?

     

     

  • I realize this is an old thread, but I have the same issue.

    @Clyde, the BRKDT is not what is needed here.  as others have stated, this is an error condition (missing stop bits).

    So... I have use a few other UARTs and they have had an "Idle Line" interrupt.  This will generate an interrupt when no data is being transmitted.  Long byte streams are handled with two IRQ's set:

    1) RX FIFO Half Full: service by just reading the HW FIFO into a SW fifo.  the half full allows more bytes to be received while interrupt is being serviced.

    2) Idle Line: Read remaining bytes.  then do your message processing

     

    I seems that this SCI does not provide an Idle Line IRQ.  I have though about :

    1) set the FIFO interrupt to 8 bytes (half) and a timer interrupt set to the frame time (maybe two frames worth?) similar to what was described previously.

    2) set the FIFO to interrupt to 1 byte and use the HW FIFO only to allow for the IRQ Service time.  Each interrupt read the FIFO until empty into a SW FIFO (usually only one byte).  Then start process the SW FIFO when the needed number of bytes are available in the SW FIFO.

    3) set the FIFO to interrupt at 8 bytes (half) keep servising until the number of bytes needed is less than 8.  The set the FIFO interrupt count to the need number (<8).  This would generate the fewest interrupts and be good for large blocks.

    Anybody else have any thoughts or ideas????

  • The problem is that TI design folks have implemented params that make the break function unusable in the TMS and MSP micros.

    Many years ago, when the serial port protocol was started, a break was defined as the time between bursts of bytes.  Bursts of bytes (one or more) are transmitted ... then there is a pause before the next burst of bytes is transmitted.  That pause is a break.

    To help keep things simple, a byte of data begins with a start bit and ends with a stop bit.  This is followed by a second byte with a start bit and stop bit.  The start bit can occur immediately after the last stop bit ... or it can occur later.  

    The stop bit is the opposite polarity of the start bit.  If the start bit is a zero, then the stop bit is a one.  In this case, when the signal goes to zero after the stop bit, it is interpreted as another start bit.  

    TI design folks have decided that the signal must be zero to be a break.  This is an error in logic.  Multiple start bits (more than 10) is a framing error.  A break is when there are multiple stop bits ... which is standard RS232 communication.  

    It is unfortunate that TI design folks have changed this protocol.  The current TI micros require us to use a timer to determine when there is a break in the communication.  This consumes time and power.  If TI micros used multiple stop bits as a break, it would reduce time and power consumption.

  • Thanks Clyde, that does seem to clear things up.

    Your solution is to use an separate timer interrupt?  Very annoying :-(

  • A separate timer is used.  Whenever the receive ISR retrieves another byte, the timer is reset.  A loop in the main code checks to see if the timer timed out ... which indicates a break occurred.

    It would be good if TI modified their micros to handle this correctly.  I doubt it would impact anyone ... unlikely anyone uses the TI break system as it is unusable in its current form.