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.

FIFO NonBlocking

Guru 55913 points
Part Number: EK-TM4C1294XL

Hello all,

Resolved: https://e2e.ti.com/support/microcontrollers/other/f/908/p/856068/3168820#3168820

Posted some time ago RX buffer array FIFO being truncated exactly at 16 bytes or sometimes slightly > 16x8 but never full size of array buffer. After some debug time it occurs that (for/else if) loop pointer is being reset via (for char[I] size) when the RX 7/8 interrupt occurs breaking the NonBlocking loop counter char[I]. Therefore the full extent of RX buffer or input string being sent most always gets truncated for strings (>16 hexbytes) breaking up the RX data string into two commands versus one command followed by specific data.

The new challenge further increases the RX string size 32 Hexbytes which under no conditions can be truncated, must remain seamless. That is mainly due to how host command interpreter must have all argument array data present prior to passing and converting 16 bytes as strings into application variables as decimal integers.  Secondly we can not have RX handler mode Blocking (while) loop holding up the entire application in the process. So the NonBlocking (for) loop must remain contiguous up to the size of char[I] set by buffer array size.

Now that the cat is out of the bag, what to do as WA to stop buffer truncation?

Note: Null termination of strings is typically an internal application method not so much for serial transmissions over wire. So the longer 32 bytes DATA string now has bang char '!' every two hex bytes since the vendors compiler gets bitchy about adding '\0' every two bytes. Secondly Rx commands begin with 'p' and end 255,255,255 without '!'. You may ask why '!', obviously converting hex values to decimal via two bytes is shorter, faster and easier to debug than sending very long string/s of ASCII decimals.   

  • Hi BP101,

      Why are you enabling the 7/8 level RX interrupt when you are directly reading the DR register? What if you disable the interrupt?

  • BP101 said:
    ... obviously converting hex values to decimal via two bytes is shorter, faster and easier to debug than sending very long string/s of ASCII decimals.

    Staff & I are 'over-challenged' by such claim.   (your quote, above)   May we note (instead):

    • 0xFF (hex) presents a single byte - yet likely would require 3 bytes if converted to '255' (decimal.)
    • Was there any clear purpose in converting a 'likely' single hex-byte (say 0xFF) into your proposed 'two bytes?'    Would not 3 bytes be (instead) required?    And again ... to what intent?
    • Was not 'Hexadecimal' developed as a means to increase decimal's base of 10 to hex's 16?    Resulting in reduced storage requirements (especially) for larger numeric values!

    Is it possible that, 'What you claim as obvious' proves (neither) 'obvious nor correct?'

  • HI Charles, CB1 & company

    Even disable Rx interrupt during FIFO reads does not stop 16 byte exit of function. The 7/8 interrupt was to call the function but is forced and auto cleared either way. I will try to disable RX FIFO level detection see if the array buffer can fill after the argument has been passed to the (typedef struct) returned command handler. Most this seems C++ related how the compiler creates Thumb instructions seems buggy with back to back reads of UARTDR register passing char into Buffer array cells as pointed to by typedef structure.

    After posting made another function to handle terminated data strings versus commands. Oddly several passes of the command argument buffer RX FIFO is required to transverse or fill the data FIFO from yet another buffer for the new function during reads. The biggest problem lies with C++ array and pointers are not being compiled correctly as to allow decimal number pointers of start data or indirectly via integers read back stored char hex data for conversion into integers prior to loading back into variables. That causes MCU reset cycles, boot loops.

    As to CB1's question the variables are sent in 2 byte hexadecimal are efficient for small parameter values than large decimal ASCII string values.  It's difficult enough just to keep it all working when C++ directives can not reverse char buffer array pointers via CCS compilers. All it seems capable to do (*char -= *char) is to change the value to 0x0 not rub it out, backspace the buffer cell contents. So the tail 255,255,255 remains in the command to save the data strings via yet another function call. Yet and most odd the first argument pointer 'p' 0x70 is not stored in the argument array of the (typedef command struct).

  • What I came up with to handle another inline char * buffer, after client commanded to save serial data.

  • HI BP101,

      The processor speed is much faster than the UART baud rate. I can image when you are in the for loop checking if the RX FIFO is not empty, there is a moment that it is empty for a short duration. Perhaps it is in the middle of receiving the next character. Since it is empty, your code will breakout of the loop. Perhaps you want to include the BUSY bit condition into your for loop checking. You don't want to break out of the for loop unless the RX FIFO is empty and the bus is not BUSY. 

  • Hello BP101,

    Young staff has made repeated efforts - thus far unsuccessful - to, 'Boost their understanding of what you're attempting.'    (I share their inability to fully/properly grasp that which you've presented.)

    Staff believes that your clear listing:

    • Data being presented to the UART's RX pin by your Nextion Unit.    Kindly show this data in the exact form in which it is being sent.
    • That Data clearly noted - at each stage - w/in your Program.    

    Your post interweaves many different (even external) operations & methods.    Some include:

    • UART's FIFOs
    • C++ feeding CCS
    • Data Strings and Commands
    • Thumb Instructions
    • Several 'passes of the 'Command Argument RX FIFO.'    (it is believed (actually guessed) that such buffer is your unique creation ... and undetailed & undescribed!)
    • MCU Reset Cycles & Boot Loops ... these cause as you note, "...to allow decimal number pointers of start data or indirectly via integers read back stored char hex data for conversion into integers prior to loading back into variables."

    Might you accept that 'KISS' has been, 'Kicked beyond FAR from your (unique) playing field' - and even an, 'Army of skilled/motivated tacticians' may be unable to  (fully/properly)  'Absorb your Meaning!'

    It must be asked, "Had you not earlier described your 'Choice of Nextion'  (your Serial Connected Device) due to its, Ease of Use?"     

    Somehow - that 'ease' appears to have (along w/'KISS') - 'Left (perhaps (even) been banned from) the Building...'

    [edit]:  Vendor's Charles has raised a great point re: (MCU Speed vs FIFO unpacking rate.)     His post arrived during staff's (here) composing effort - and was noted only after we hit 'Post.'   

    It is believed that, 'Even should that unpacking' yield benefit - the 'total avoidance of 'KISS' has led to 'multiple Snake-Bites' - suffered by all those (bleeding & swollen) who, 'Seek to Assist...'

  • Hi Charles,

    >>Why are you enabling the 7/8 level RX interrupt when you are directly reading the DR register?

    Must leave for RX errors interrupt events; framing, parity + others.

    Charles Tsai said:
    Perhaps you want to include the BUSY bit condition into your for loop checking.

    Had also tested TX-Busy with Blocking wait loop in snip above but this is full duplex serial. So TX is still sending frames during this RX buffer time frame using the same UARTDR, mind boggling how that works. Added SysCtrlDelay() 250ms into the RX for loop may slow B2B read of stores into array buffer.

    Are you aware of C++ syntax to backspace over previously written array cell buffer contents?

  • Hello CB1,

    The command shared serial data buffer is shown in the CCS debug shot 1st post, s2 is the command. Charles points out the (else if empty) may be suspect in 1st code snip posted. 

    Yet UART serial data rate 115200 BPS and the data string quickly follows the command to save said string. We have to tell the target it needs to handle the RX data and what to do with it. The array buffer handling method is giving fits conversion (char to int) of with CCS compiler gives no errors but pointer into array method can cause looping resets.

    Point was compiler 18.12.3.LTS C++ syntax is not fully proven with serial UART string conversions pulled from C array storage passing of data types, the competition MCU classes appear to have no such limitations. Scooby Doo there is work to do here!

  • BP101 said:
    The command shared serial data buffer is shown in the CCS debug shot 1st post, s2 is the command.

    As a fellow, 'Small Biz Owner' - you must realize that you must 'Compete for Eyes, Minds & Efforts' - to succeed under (especially) the 'Pro Bono' circumstances found here.

    Young staff is, 'Not enthused' at 'Only one' of their 'Multiple, organized, Bullet-Pointed Requests' being recognized!    Realize that our group, 'Arrives here' when a 'teaching moment' reveals - yet when such moment proves 'overly burdening' - interest (naturally) wains...    And as our order book is full & growing - you're not 'too effectively' making your case for support!    (i.e. Your 'ease' should never trump the 'ease' of those offering quick & in-depth support!)

    Might the Nextion forum (if one exists) or your upgrade to the '600MHz ARM Cortex M7' - found in the Arduino Teensy - offer another solution path for your consideration?    (even in departure - the gifted youth here offer an 'eased lifeline'...)

  • cb1_mobile said:
    Young staff is, 'Not enthused' at 'Only one' of their 'Multiple, organized, Bullet-Pointed Requests' being recognized! 

    Please ask young staff to keep focus on the issue and not try to divert from it by adding scenarios that do not exist. The easiest method KISS is a two byte transfer protocol as outlined in this follow up post derived from the original question post very top of this thread. Otherwise vendor and helpers are only mildly aware something ain't working right in HW.

    Again the issue is UART FIFO can only hold 16 bytes as Charles has tried to express the empty flag can occur mid serial data transport into the receive register.

    That in of itself appears to be a HW errata in my opinion thereby making static command processing of more than 16 byte data streams highly burdensome upon CPU time. The alternative while ! empty UART Blocking mode (project example) eats up far to much CPU time even when RX interrupt calls the serial input handler.

    Again Note: Serial RX handler GPTM Polled or Interrupt  produces the very same errata, exactly at 16 bytes but is not listed in HW errata PDF. 

    The FIFO empty flag should never assert in the middle of data streams as it appears to do exactly @16 bytes. One ideal WA requires branching application serial data to another BUFFER via command processor for the command processor pfn callback (argc, argv[]) handler. 

    Scooby Doo we have some work to do now.    

  • @ BP101:

    cb1_mobile said:

    Your post interweaves many different (even external) operations & methods.    Some include:

    • UART's FIFOs
    • C++ feeding CCS
    • Data Strings and Commands
    • Thumb Instructions
    • Several 'passes of the 'Command Argument RX FIFO.'    (it is believed (actually guessed) that such buffer is your unique creation ... and undetailed & undescribed!)
    • MCU Reset Cycles & Boot Loops ... these cause as you note, "...to allow decimal number pointers of start data or indirectly via integers read back stored char hex data for conversion into integers prior to loading back into variables."   

    The listing above was compiled from a 'single one' of your postings w/in this long thread.   

    Thus your directive:  "... Ask young staff to keep focus on the issue and not try to divert from it by adding scenarios that do not exist."   proves markedly INVALID - as you yourself - 'Raised each/every one of these elements!     Had you forgotten ... and/or 'Now try to deny their issue?'

    Your repeated:

    • Total Rejection of KISS
    • Near continuous issue of the 'Guess du jour'
    • Denial of the request for placing 'YOUR Ease' AFTER the 'EASE of Others'

    proves unlikely to, 'Ease your path to success.'

  • cb1_mobile said:
    Thus your directive:  "... Ask young staff to keep focus on the issue and not try to divert from it by adding scenarios that do not exist."   proves markedly INVALID - as you yourself

    I was referring to your several bullet points that never address why the RX receiver truncates frames as it does. My explanation of command pfn function + parts must be understood are all part of the serial mix. The WA of added data buffer was just a shot in the dark solution, worked once never again. After rewrite of RX handler the same thing occurs but the pfn command return occurs now in the upper RX posted code loop, if(I>32).  

    cb1_mobile said:
    Total Rejection of KISS

    My kiss is one that gets to the nitty gritty Fast & Furious. Where on earth have I heard that expression before.

    For nonbelievers my word sender string is truncated by TM4C and CCS debug confirms a correct analysis - what goes into the RX FIFO ain't what comes out even with no SysCtrlDelays() involved in output below.

    Client several times touches the save button:

    Target lauch pad:

  • Charles Tsai said:
    You don't want to break out of the for loop unless the RX FIFO is empty and the bus is not BUSY

    If only that was possible since the Busy flag indicates the transmitter is busy. So it seems frames are being lost or truncated even when inserting a wait while state after byte 16 has been buffered.

    Oddly goosing the save button in the middle of TX send would sometimes randomly get all 24 bytes seemingly in two 5ms polling timer loops. Now with 24 byte sends it never seems to occur via the RX interrupt calling the RX function. It acts as if the RXFE bit was tied to the interrupt or the 7/8 threshold is late to trigger RX interrupt so the sent frames are being lost at the receiver.

    My point being as long as frames are still being sent and UARTDR read by application the receiver should be empty for new frames after the 16th byte. I could see where polling the FIFO with GPTM might loose frames after 16th byte but not when RX interrupt is the caller.

    }
    	/* Timeout for getting RXD FIFO bytes */
    	for(Timeout = 0; Timeout < timeout; Timeout++)
    	{
    		/* Load RX data elements */
    		for(i = 0; i <= 32; i++)
    		{
    			/* Check if receiver is Not full, NonBlocking
    			 * characters are received into FIFO */
    			if(!(HWREG(UART2_BASE + UART_O_FR) & UART_FR_RXFE && ~UART_FR_RXFF))
    			{
    				// Cchar[i] = UARTCharGet(UART2_BASE) & 0xFF;//
    				Cchar[i] = (HWREG(UART2_BASE + UART_O_DR));
    				/* System clock 8.33ns time, 833us delay */
    				//SysCtlDelay(SYSTEM_CLOCK / 1200);				
    				/* FIFO not empty */
    				ret = 1;
    			}
    			/* The RX FIFO is 7/8 full pause for next frame */
    			if ((i >= 15) && (HWREG(UART2_BASE + UART_O_FR) & UART_FR_RXFE))
    			{
    				/* Pause here wait for receiver loading */
    				/* System clock 8.33ns time, 128us delay */
    				SysCtlDelay(SYSTEM_CLOCK / 7800);
    			}
    			/* The RX FIFO is full */
    			if (i >= 32)
    			{
    				/* Scan the input buffer for commands
    				 * and process only valid command/s */
    				ret = CheckCommands();
    
    				ret = 0;
    				return(ret);
    			}
    
    				/* System clock 8.33ns time, 208us delay */
    				SysCtlDelay(SYSTEM_CLOCK / 4800);
    
    				/* Print 0x70 return variable name */
    				UARTprintf("Rx:%c :%x\n", Cchar[i], Cchar[i]); //Cchar[i]Cchar[i]
    		}
          }
    return(ret);
    }

  • Staff reviewed your Screen Caps - believe they have 'extracted the essence' - and improved upon its presentation.      (Removed the need to scroll - thus comparison much enhanced!)

    It is believed that your transfer succeeds up to the 17th 'serial character's' arrival.    Then - the receipt has been lost.

    Staff asks, 'Can you not confine your 'Source Serial Device' to send, 'Just bursts of 16 chars?'    The thread has become so long - and filled w/extraneous - that they can not easily determine if you've made this recognition.

    If you cannot 'Control & Halt the Source' - then you must attempt to, 'Implement your own (large-scale) serial buffer' - and capture the serial data therein.   

    This technique appears to be (surprisingly) 'KISS' based - and is just what the Staff here has hoped...   (You  may note that the large-frame capture image you pesented simply 'overwhelms' (far too much data included - AND forces an 'ineffective, huge spacing between each image!      Female staff eliminated that (unnecessary) spacing - so as to present that key image data  in a 'far more effective & viewable' form...)

  • cb1_mobile said:
    Staff asks, 'Can you not confine your 'Source Serial Device' to send, 'Just bursts of 16 chars?' 


    That 16 bytes was first attempted but noticed very difficult to see where each variable data began or ended. So the char '!' added to every 2 bytes makes it useful for strlen() on the other end to test for decoding hex to integers.

    cb1_mobile said:
    If you cannot 'Control & Halt the Source' - then you must attempt to, 'Implement your own (large-scale) serial buffer' - and capture the serial data therein. 

    Serial Buffer is what the top post shows beginning of thread, Cchar[I] is BUFFER 32. Later idea to add another serial function with new buffer for input data only, proved no better.

    So the last SysCtrlDelay() between if's when wider reveals timing issue may exist in RXFE flag or FIFO 7/8 threshold interrupt.

  • Can you not order your, 'Serial Source Device' to output, '8 Bit Hex-Bytes?'    In this manner - serial data (up to 255 decimal) is received in a single byte!

    Does that 'Serial Source Device' ever send data 'beyond/higher value than 255?'    If so - then 'back to back' Hex Bytes will accommodate values up to 65K decimal & will include your '!' (only forced between those '2 back to back' hex bytes - when they represent value 256 decimal & up.)

    This method eliminates your having to impose the '!' every 2 chars - which is tedious & (needlessly - if you adopt this method) quickly over-fills your BP created Serial Buffer...

  • cb1_mobile said:
    Can you not order your, 'Serial Source Device' to output, '8 Bit Hex-Bytes?'    In this manner - serial data (up to 255 decimal) is received in a single byte!

    That's how it is working now.  Perhaps you mean nibble and that would be nice but it requires 8 bits for each character, not decimal number (integer). Typically one can set the index pointer to exact location of stored data byte and jump over '\0' null terminators of strings. That's how we transmit variable integers as stings to the client and they are exact since the terminator is subtracted from the loop counter. 

  • cb1_mobile said:
    Can you not order your, 'Serial Source Device' to output, '8 Bit Hex-Bytes?'

    Number boxes produce little endian 1, 2, 3, 4 bytes ordering. Data can be converted to ASCII but each digit is 1 byte, even larger receive strings. I'm impressed that sending 12 variables via 5ms GPTM loop is working well as 100MBPS Ethernet via LWIP without all the overhead.

  • Feel your pain - yet we've not (yet) mastered all of you terminology:

    • local function array[I]  ...  might you further describe & detail?
    • BUFFER bytes   ...   How do these differ - or do they?
    • global storage BUFFER   ...   (same as above)

    It is suspected that 'Buffer Bytes' are contained w/in your 'Global storage Buffer.'    Is this correct?

    You note,

    BP101 said:
    the function passing of data to the BUFFER lags behind the serial input stream.

    Clearly 'KISS' proves a 'most willing/able'  vehicle  to 'confirm or deny' that.     In all such 'speed based situations' - does not ,  'Slowing your Baud Rate' (9600 suggested)  resolve or at minimum lead to added insights?

    One technique we've employed (which hopefully may work for you), 'Tie the UART RX pin to an input GPIO.'    This GPIO then is tasked w/, 'Counting the Number of  'Serial Bytes Received' as we 'Synchronized it to the Enabling of your UART's RXE bit!    (Initially the sending of key chars:  0x55 or 0xAA  (alternating bits) will enable you (start you) to program this  'Serial Byte Detection mode.')   

    Upon the arrival of Byte 16's 'STOP Bit' - you can:

    • generate a high priority interrupt which:
      • Halts further UART reception via 'Clear of bit RXE'
      • Alerts & Causes your software to 'unpack the properly loaded (and now blocked) RX-FIFO'

    You (and your screen shots) have repeatedly noted that 'FIFO Over-Fill' causes issues.    Yet several of your Screen Caps prove that the first 16 entries to your UART-RX FIFO nicely succeed.     

    Described herein is 'one method' by which you may (better) extract that '16 Bytes of Valid RX-FIFO Data!'

  • cb1_mobile said:
    'Global storage Buffer.'    Is this correct?

    Several ways have tried to relate one Buffer is used, contents are passed between functions.

    cb1_mobile said:
    generate a high priority interrupt which:
    • Halts further UART reception via 'Clear of bit RXE'

    Clearing RXE bit did NOT produced great results being cleared via (HWREG |= ~(RXE)) and (HWREG &= ~(RXE)). That seemed to shut down the transmitter in both cases after first few bytes were sent 'rest' did occur but no other commands after. Tried it alone and with the TXE produced same odd result.

    It would seem the UART startup code sends a speed parameter command to it's self to set target speed.  One reason the Tx/Rx timing during startup was so touchy. LCD widgets know nothing and remain mostly dumb terminal buckets powered by an 48Mhz MCU.

    BUFFER corruption was self caused by reading array values via array[0]=n pointers end of s2 command. Oddly using "char" to "char *" conversion variables to allow array[n] argument cell pointers cause MCU reset, even with delay between cell reads. Did young scholars tip off atoi() call subtracts '0' 0x30 from each hexadecimal input? 

    Call made to HexToDec() conversion keeps base16 addition in check. It was first suspect of MCU resets due to compiler warning "char" not compatible with type "char * ". So the BUFFER is ok perhaps was being written in the end but odd values of s2 many times did not add up.

    cb1_mobile said:
    You (and your screen shots) have repeatedly noted that 'FIFO Over-Fill' causes issues.    Yet several of your Screen Caps prove that the first 16 entries to your UART-RX FIFO nicely succeed.   

    Actually No, it is FIFO under run after byte 16 that is causing issues. Added delay after byte 16 may often succeed the full 28 bytes load into BUFFER. Oddly even with delay patch it may take two iterations of save command to fill 28 bytes, sometimes 28 on the 1st try.   

  • I believe that we must, 'Agree to disagree.'

    BP101 said:
    cb1_mobile:
    You (and your screen shots) have repeatedly noted that 'FIFO Over-Fill' causes issues.    Yet several of your Screen Caps prove that the first 16 entries to your UART-RX FIFO nicely succeed.   

  • cb1_mobile said:
    It is believed that your timings and/or methods of 'FIFO to "the BP created Buffer" data transfer is/are flawed - and it is (that) which causes the bulk of your issues...

    Again there are 28 transfer bytes NOT 16 and assignment BUFFER = 32 bytes. UARTDR Iteration loop is <= 32 loop count so the FIFO or RXFE flag control is flawed. When the receiver has start bit data after byte 16 the RXFE flag is incorrectly being set, that is silicon errata. Otherwise the HW is not compatible with C+ software BUFFER handling of the 16 byte FIFO. Perhaps RXFE flag should only be set relative the baud rate clock and not the system clock as it appears to have been designed.

    Note the addition of delay >12 inside the receiver loop code more often fills the entire 28 bytes into BUFFER abating the incorrect RXFE flag bit timing.

  • Hi Charles,

    You have been silent most follow up posts. seems a hit & run though you were mostly correct about pause. So it seems the 16th stop bit is incorrectly setting the RXFE flag even when a start bit follows. Oddly that does not produce over run error flag set via error flag check during RX interrupts.

    The RX codes for/I loop rapidly reads UARTDR register (7KCPS) bursts. During holding register time the RX data stream is highly time contiguous from the senders perspective. The added SysCtrlDelay() test of RXFE pause requires 357us being tied to BUFFER unloading of the same 28 bytes via s2 command call upon escaping the for/I loop >32. Then s2 command handler unloads the 28 bytes just received. Even with added pause it may require two RX interrupt passes to fill then entire 28 bytes, not always. Sometimes depending on RXFE pause delay, UART fills entire 28 bytes very first time and every other time there after when commanded via s2 directive several times in a row. 

    The question remaining, should the RX interrupt handler clear the RTIC bit as it now does and could that be cause of random undetected byte over run on the holding register? The perception taken from serial captures is receiver holding register (under run) often occurs but that is not being tested by the UART.

  • BP101 said:
    The question remaining, should the RX interrupt handler clear the RT bit as it now does and could that be cause of random undetected byte over run on the holding register?

    What is the RT bit?

  • Hi Charles

    RTIC bit. 

    Confirmed the RT interrupt bit is not being auto cleared by UART if application does not force clear UART_INT_RT along with the UART_RX_INT in receive interrupt handler, receiver enters hung state. My application was always clearing the RTIC bit in RX interrupt handler that after called the RX input handler.

    The fix requires to check the RT bit status when FIFO input loops > 15 && RXFE || ~RT. Thus it seems to require longer than 32 bit times when the HSE bit is clear for the receive timeout since it must be force cleared in the next 16 bits receive interrupt cycle.

    /* Check RX FIFO is empty or timeout Interrupt.
     * The RX timeout interrupt is asserted when
     * the RX FIFO is not empty, and no further data
     * is received over a 32-bit period when the HSE bit is
     * clear or over a 64-bit period when the HSE bit is set.
     * Note: The receive timeout interrupt is cleared
     * either when the FIFO becomes empty through reading
     * all the data (or by reading the holding register) */
     if ((i > 15) && (HWREG(UART2_BASE + UART_O_FR) & UART_FR_RXFE) ||
    			(HWREG(UART2_BASE + UART_O_MIS) & ~UART_INT_RT))
     {
         /* Pause here to wait for FIFO loading */
         /* System clock 8.33ns time, 357us delay */
    	SysCtlDelay(SYSTEM_CLOCK / 2800);
     }

  • Even with the RTIC delay patch shown above post the interrupt is not being auto cleared as datasheet states should occur. Receiver timeout interrupt RAW or Controller did not seem to matter either way. The false narrative 16 bytes can only be buffered during 7/8 full interrupt is seemingly due to RTIC bit masked or unmasked random missing interrupt in UART2 tested so far.

    For that reason 32 byte indirect BUFFER loads can at times be truncated exactly 16 bytes rather than the full size of our buffer. Was TI aware the UART similar to 16C550 was not capable to load more than 16 bytes of 28 bytes of steady data stream without issues? Is there any plan TI part to investigate why the RX bottle neck randomly occurs exactly 16 bytes as not to replicate such design into future products?

    Logically we should be able to load any size BUFFER length from back to back reads of UARTDR via near seamless receiver input data. It might otherwise be possible a slight difference in Baudot clocks exist between the transmitter and receiver partners leads to RTIC issues 115200 BPS?  Was there any verdict or testing why RTIC bit randomly locks receiver when not being forced cleared? We have spent many hours just to eventually find certain errata exists in RTIC bit making UART2 unusable for transfer of data >16 byte frames at any given time. It would be nice to know why UART2 cokes as it does but meantime have morphed other SW structures to follow this odd FIFO behavior.

  • Did you enable RTIM bit in the UARTIM register? Th RTIM bit must be set to see either the RTRIS or RTMIS. Normally the raw interrupt status flags do not depend on the interrupt mask to set. But the RTRIS/RTMIS is an exception. The Receive Timeout flag will be automatically cleared if the not-empty Receive FIFO is read. 

    This bit is cleared by writing a 1 to the RTIC bit in the UARTICR register.
    For receive timeout, the RTIM bit in the UARTIM register must be set
    to see the RTRIS status.

  • Hi Charles.

     

    Charles Tsai said:
    Did you enable RTIM bit in the UARTIM register?

    Isn't that the point of my last post, timeout INT is not being auto cleared? Again if it is not force clear via UART interrupt handler the receiver halts, RAW or controller masked mode. After further reading datasheet the Baudot generator may be the cause if the clock is not being set correctly by Tivaware. Review of call below appears to stray from the formula described in datasheet. It seems if the receiver holding register if not overrun status, not empty, the 17th start bit was always being missed without a small delay being added.

    Seemingly the 17th byte start bit was received but not detected by the receiver so RTIM is not auto cleared. Perhaps if Baudot does not closely match the senders Baud rate? Might explain odd overrun flag occurring only 22 bytes, 100ms GPTM on sender side transmitting 16 bytes + 6 for command, 22 bytes. Formula states to Multiply by 64, not divide by 64.

    16.3.2:

    The 16-bit integer is loaded through the UART Integer Baud-Rate Divisor (UARTIBRD) register (see page 1182) and the 6-bit fractional part is loaded with the UART Fractional Baud-Rate Divisor (UARTFBRD) register (see page 1183). The baud-rate divisor (BRD) has the following relationship to the system clock (where BRDI is the integer part of the BRD and BRDF is the fractional part, separated by a decimal place.)

    BRD = BRDI + BRDF = UARTSysClk / (ClkDiv * Baud Rate)

    The 6-bit fractional number (that is to be loaded into the DIVFRAC bit field in the UARTFBRD register) can be calculated by taking the fractional part of the baud-rate divisor, multiplying it by 64, and adding 0.5 to account for rounding errors:

    UARTFBRD[DIVFRAC] = integer(BRDF * 64 + 0.5) = 54.9448 or 55 and not 54 as 16.4 configuration example shows.

    Tivaware UARConfigSetExpClock() appears to do some math that is not in the above formula.

    void
    UARTConfigSetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk,
                        uint32_t ui32Baud, uint32_t ui32Config)
    {
        //
        // Compute the fractional baud rate divider.
        //
        ui32Div = (((ui32UARTClk * 8) / ui32Baud) + 1) / 2;
    
        //
        // Set the baud rate.
        //
        HWREG(ui32Base + UART_O_IBRD) = ui32Div / 64;
        HWREG(ui32Base + UART_O_FBRD) = ui32Div % 64;
    
        //
        // Set parity, data length, and number of stop bits.
        //
        HWREG(ui32Base + UART_O_LCRH) = ui32Config;

  • Checking the math from formula examples and CCS debug UART configured for 115200 BPS.

     BRDI=65, BRDF=7 yet BRDF has remainder 0.166666 being discarded. 

    BRD = [120000000 / (7812500000 * 115200)] = 65.104166666666666666666666666667


    BRDF = (0.104166666666666666666666666667 * 64 + 0.5) = [integer] 7.166666666666666666666666666688

    With CPU floating point unit (FPU) enabled, why Tivaware does not load register BRDF = 7.2 as the correct fractional divisor?

    Perhaps the serial device has adjusted BRDF (float) and accounts for start TX bit being randomly missed by TM4C1294 Receiver? Otherwise the serial device does not provide modem control signals or SW handshake at 115200 BPS top speed. Obviously serial device was fully tested (115200 BPS) had no TX/RX issues thus they expected no issues connecting to other UARTS.