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.

EK-TM4C1294XL: UART Rx FIFO hold off

Guru 55913 points
Part Number: EK-TM4C1294XL

How do I make a single UART not accept characters into the holding register? 

IntDisable() RX does not hold off data entering the holding register or 16x8 FIFO. RXD holding register hold off should be an internal FIFO control function, but how? RAW or Masked Boolean switch via IntStatus() flags does not affect holding register. There are times when a host desires to shut port to client from the application perspective. Surely there must be a way to shut the RX data port without using modem control signals or external GPIO trickery.

The client does not provide modem control signals so it must be some kind of HWREG control to achieve RX stealth mode.

  • BP101 said:
    How do I make a single UART not accept characters into the holding register? 

    and

    BP101 said:
    there must be a way to shut the RX data port without using modem control signals or external GPIO trickery.

    Would not "Switching (either)  'GPIOPinConfigure() and/or GPIOPinType()away from 'UART' -  quickly/easily achieve your, 'Non Modem/GPIO Trickery' objectives?     

    While we do not have (nor find the '129 MCU compelling') - it is believed that, 'Just like on our '123 MCU' - your, 'Clearing of UARTCTL's  'RXE' bit - will 'Prevent UART Reception!'

    BP101 said:
    it must be some kind of HWREG control to achieve RX stealth mode.

    Or not!    How about, "UARTDisable()" - that's a listed API function - which should (very) well - meet your needs and 'avoid' HWREG  Control.    And that registers as, 'BP's  Solution #2' - thus meeting the requirement for 'Two for One' pricing!    (i.e. TWO Splashes of Green - s'il vous plaît.)

    Yet - w/that stated -  is 'Blinding your MCU' to, 'All subsequent arriving Serial Data' wise?'    (i.e. are all of your 'clients' unable to, 'Call for Service and/or Help - or (any) other needs and/or refreshing?)    By 'Blinding your MCU - any/all clients are condemned to 'sink and/or swim' - on their own!    (Has that fact been fully/properly recognized, weighed & realistically considered?)

    Tag: Reconfiguring the pin (surely) enables/disables select  pin-functionality!

  • Hi BP101,

      Please bear in mind the UART is full-duplex. If your host doesn't initiate the transmit on the TX then there is no receive on the RX. Therefore, I think your application should have full control when to stop. In any case, have you tried to disable the RXE (UART receive enable) bit in the UARTCTL register?

  • Hello Charles,

    Charles Tsai said:
    Please bear in mind the UART is full-duplex.

    Can that (really) be true?     Staff/I have 'searched the net' - to our surprise - this statement appears correct!    (NO disbelief in you - but in opposition to our experience.)

    • RS-485 - most of the line drivers supporting this mode provide (both) 'RX & TX' enable pins - which do not accommodate 'Full Duplex!'   (the 2 wire differential bus could not support such 'full-duplex.')
    • Your MCU's  UART support, '9 bit mode.'    As such - how could the 'receiving side' start 'transmitting' prior to the appropriate address being decoded?
    • Our firm (for at minimum the past 20+ years) has employed 'Command/Control' - in which a 'Command' is transmitted - and the receive side - only after reception & evaluation - is (only then) able to respond.

    It is apparent that when the UART is operated w/in RS485 mode - (usually) the full duplex reduces to half duplex.     Note our import from 'Wikipedia':  "Full-duplex Ethernet connections work by making simultaneous use of two physical twisted pairs inside the same jacket, which are directly connected to each networked device: one pair is for receiving packets, while the other pair is for sending packets. This effectively makes the cable itself a collision-free environment and doubles the maximum total transmission capacity supported by each Ethernet connection.

    Charles Tsai said:
    If your host doesn't initiate the transmit on the TX then there is no receive on the RX.

    That said, we have (and have had) NO/ZERO RECOGNITION THAT 'UART-RX' CANNOT OCCUR W/OUT UART-TX!     Staff/I  stand in solid 'disbelief'  to this statement!     While 'full duplex UART operation is likely' (due to the presence of separate TX & RX buffers) ... yet that  does not enforce a mandatory, 'TX Operation for each/every desired RX Reception!'   

    For years (and beyond) there have been numerous, 'Send & Pray' UART Implementations - in which transmission is (only & always) ONE WAY!    (the remote MCU's UART  ONLY  Receives (never/ever sends!) - thus the sender can only 'hope' (or pray) for transmission success!)

    And key (to the 'full duplex') introduction - w/in UARTCTL there appear (UART Directional Control Bits: RXE & TXE!)    These are UNIQUELY CONTROLLED - thus indeed -  either RXE or TXE may be disabled - and in such case - NO full duplex operation can occur... 

  • Hi cb1,

      Thank you for your clarification. Perhaps my misunderstanding of the full-duplex. II was thinking along the line that TX and RX happens at the same time and wonder how can the host MCU receive data without first initiating the data to transmit (i.e. the command). If someone (i.e. external host) sends command to the MCU then how can you just disable the reception of the commands. I suppose you can receive the commands and evaluate to take no action instead of just close the door on the reception. 

  • Hi Charles,

    Even though our LM3S, LX4F & TM4C123 MCU manuals make 'NO/ZERO mention of 'full-duplex' UART' - your notng that fact appears correct!     We had become 'locked in' to our 'half-duplex belief' via our experience w/'2 Wire, Differential RS485 Transceivers.'     

    And - as previously noted - we (and others) have 'Long determined' the 'Command/Control's' style of 'Directive Transmission' vastly superior!      (When & as followed by the 'Remote UART's (post receiving & processing its response) Return Transmission.')    Indeed - many have found this (Command/Control) communication method (vastly easier & more intuitive) than 'SPI's method of providing 'OLD/Dummy Data' w/each Fresh Master Transmission!  ...  It is believed that the SPI 'method' works well for long, repetitive data transfers - yet proves a 'horror' - for critical, Command & Control Data Transactions!    (i.e. Can you say, 'Missile AWAY' - but only upon the 'following dummy transmission!')     No thanks!

    We both identified the 'UARTCTL Bits 'RXE' (clearance) as the (most likely) suspect to achieve poster BP's 'trickery-lite' objective...    Good that!

    (this remains a 'feeb tag free' zone...)

  • Hi Charles,

    Charles Tsai said:
    ... how can the host MCU receive data without first initiating the data to transmit (i.e. the command). If someone (i.e. external host) sends command to the MCU then how can you just disable the reception of the commands?

    Both are good points - staff preferred to answer separately - to enhance clarity.

    W/in 'Command Control' (via our understanding) most always a  'Proper Command is Sent.'    That 'command' may be deemed a 'Broadcast' - which impacts multiple devices - all sharing the RS485 bus.   (in fact the 'broadcast' may impact several, most - even ALL other devices.)

    This initial 'Command/Control Transmission' initiates the response process - yet, 'No Response Data' is invited (nor sought) at this point in time.    (this is so as all impacted devices must process the command - and then determine their 'Que in the Response Sequence' - should multiple devices have been selected.)    Note too that certain commands may require 'serious processing' - thus an 'instant and/or 'premeditated response' is not possible.    This should answer your issue as to, 'How this 'Command/Control' Process launches.'

    Now the 'Issuing MCU' (they all may be 'equals' - there is no necessity for a 'host') knows:

    • which MCUs on the RS485 bus should respond
    • and approximately what their 'turn around time' should be
    • while preparing to receive 'sequential responses' from each remote MCU previously addressed

    There is 'No disabling of the commands' - each/every transmission is evaluated by 'ALL' MCUs on the bus - only those addressed (via the broadcast) must respond.    Each MCU 'Listens intently prior to transmitting' - seeking 'collision avoidance.'   When an MCU is 'not specifically addressed' - it continues w/its 'normal operations' - yet w/high priority directed to the arrival of 'Activity" - upon (only) its RX Pin.   (there is ZERO 'matching' TX activity - the TX is only enabled upon:

    • that specific MCU's Command Generation
    • that specific MCU's Response to another's directive

    In the case raised by 'BP101' - we do not disable 'RXE' - yet regular 'MCU Housekeeping' is charged w/properly managing the MCU's internal buffers.    On and at regular (known) intervals - each MCU on the bus will 'sign-in' - assuring bus & system integrity...

  • Hi cb1,

      LIKE! Thank you again. 

      I'm interested to know if BP101 is using the UART with the RS232 or RS485 line driver or just TTL. 

  • Hi Charles,

    Certainement mon ami.     From his past postings - he's 'graduated' to an Arduino-based Display System - which feeds data via UART to his MCU.   (strongly suspect  'CMOS/TTL Levels' - or doubtfully RS232 - and (inconceivably) RS485...)

    Crack staff (this time a 'gifted high-schooler') submitted "UARTDisable()" - as a 'quick/dirty means' of  'quieting BP's FIFO overload...'    She's very, very smart - note that she's deployed an 'API function' - saving BP101 from his  (suspected)  HWREG (only) encounter...

  • cb1_mobile said:
    Crack staff (this time a 'gifted high-schooler') submitted "UARTDisable()" - as a 'quick/dirty means' of  'quieting BP's FIFO overload...

    Well it still needs to TX at that time and that would stop all data transfers. Oddly the RXE bit is set via Tivaware UartEnable() so the HWREG might be the way to stealth/shut the RX input. An even bigger problem is with RX NonBlocking and for loop fall through always occurs exactly at 16 bytes no mater the input buffers size passed in. If we goose the handlers input rate it sometimes can push 24 bytes into said 32 bytes buffer. It don't care if the RX handler is called from RX interrupt or 5ms timer the same NonBlocking fall though occurs as forum posted array issue. The clue to (for/else if) fall through is the higher array values never get touched in debug single steps.

    Thanks for the great ideas above!

    void
    UARTEnable(uint32_t ui32Base)
    {
        //
        // Check the arguments.
        //
        ASSERT(_UARTBaseValid(ui32Base));
    
        //
        // Enable the FIFO.
        //
        HWREG(ui32Base + UART_O_LCRH) |= UART_LCRH_FEN;
    
        //
        // Enable RX, TX, and the UART.
        //
        HWREG(ui32Base + UART_O_CTL) |= (UART_CTL_UARTEN | UART_CTL_TXE |
                                         UART_CTL_RXE);
    }

  • The RX interrupt seems to go crazy, single character 'U' (0x55) keeps printing when RXE bit was disabled and later enabled. Flushing the TX FIFO has no effect.

        /* Enable the TXD interrupt for FIFO transfers  */
        MAP_UARTIntEnable(UART2_BASE, UART_INT_TX); //| UART_INT_CTS)
    /* For now disengage the RX interrupt */ MAP_UARTIntDisable(UART2_BASE, (UART_INT_RX | UART_INT_RT));
    /* Disable the FIFO */ MAP_UARTFIFODisable(UART2_BASE);
    /* Enable UART2 with TX-FIFO, disable RX-FIFO */ HWREG(UART2_BASE + UART_O_CTL) |= (UART_CTL_UARTEN | UART_CTL_TXE | ~(UART_CTL_RXE));
    /* FIFO is reconfigured */ MAP_UARTFIFOEnable(UART2_BASE);
    MAP_IntEnable(INT_UART2); TX some things: /* Now enable the RX FIFO */ MAP_UARTEnable(UART2_BASE); /* Now Nextion is reset engage the RX interrupt */ MAP_UARTIntEnable(UART2_BASE, (UART_INT_RX | UART_INT_RT));

      

  • BP101 said:
    MAP_UARTIntDisable(UART2_BASE, (UART_INT_RX | UART_INT_RT));

    My Arduino obsessed ami -  your  usage  (above) is NOT what  my crack staff had (properly) suggested!    You have  'repeated'  the failed usage noted in your initial post  "IntDisable() RX" - have you not?

    She proposed,  "UARTDisable()" -  which prevented the arrival of data upon our '123's RX Pin - from entering the MCU's Receive Buffer!     And that - is precisely what your initial post sought!

    Your 'NEW' specification:

    BP101 said:
    Well it still needs to TX at that time and that would stop all data transfers.

    That's (completely) brand new information - yet cannot that NEW DEMAND be handled by issuing "UARTEnable()" prior to the need to TX - and then restoring "UARTDisable()" after your TX completes.   (i.e. the UART is no longer  registered as 'busy.')

    Tag: Poster has 'Moved the Cheese!'

  • cb1_mobile said:
    She proposed,  "UARTDisable()" -  which prevented the arrival of data upon our '123's RX Pin - from entering the MCU's Receive Buffer!     And that - is precisely what your initial post sought!

    Yet post did not seek to stop the transmitter which must be left functional when the receiver is shut, disable UART disables both TX/RX. That said; first post (green) clearing the RXE bit should have shut the receiver off. However the handler function was still being invoked (looping) by the RX interrupt for what ever reason. Disabling RX interrupt did not stop the crazy looping, RAW or local. Again there is some issue/s with the receiver silicon that RXE bit should control the receiver.

    16.3.3

    When the receiver is idle (the UnRx signal is continuously 1), and the data input goes Low (a start

    bit has been received), the receive counter begins running and data is sampled on the eighth cycle

    of Baud16 or fourth cycle of Baud8 depending on the setting of the HSE bit (bit 5) in UARTCTL

    (described in “Transmit/Receive Logic” on page 1162).

  • Thank you - our 'Shamrock Shake' inventory has been (near) exhausted...   (thus your splash of green  (properly) raises crack staff's spirits.)

    Note that the (earlier) 'Verified Post' had provided 2 mechanisms to, 'Block UART Reception.'    (i.e. Clear the RXE bit or deploy 'UARTDisable()' ... both were tested by 2 staffers - and proven to succeed.)

    Staff is highly curious - Do describe (via your code, please) just how you, 'Disabled the RX Interrupt.'    Had you cleared RXE prior to that disabling?    You may experiment by 'clearing RXE' (both) prior to and post - 'Properly disabling the RX Interrupt.'    (Staff tested on one of our '123s - no such 'Unwanted/Illegal RX Interrupt' was (ever) evident!)

    Staff notes - yet questions your 'Import of 16.3.3.'     They state that your 'Manipulation of the RXE Bit' (clearing it) in 'No way' impacts the 'External Signal Input to the UART's RX pin!     With that (clearly) agreed - can your intent have been that (somehow) the 'normal/customary' operation of the UART's Receive Section - continues unabated?    (We don't believe that to be the case...)

    Again - do post your method of 'Disabling the RX Interrupt.'     The (unsubstantiated) claim of its 'Going Rogue' - proves beyond our comprehension...

  • cb1_mobile said:
    Again - do post your method of 'Disabling the RX Interrupt.'     The (unsubstantiated) claim of its 'Going Rogue' - proves beyond our comprehension...

    It's in the posted code snip back one page. What your staff is not aware of Target sent 'rest' to device, default mode sends completion codes, unless immediately sent command to stop doing that insane practice. Directly after telling it to stop doing that, target starts 5ms loop of 6k-8k CPS transmit upload to device.

    So if device ignored/missed said command it starts sending completinon codes (8k-11k CPS) for every transmitted command it flagged as error or ok.  

    Remedy - stop sending command 'rest' to device after target resets from firmware updates.

  • Twas requested,  'Post your method of Disabling the RX Interrupt.'

    BP101 said:
    It's in the posted code snip back one page.

    And so the young ladies looked  and found:    (but at the cost of 'their' further time & effort - even deeper, 'brainwork'  -  in your behalf) ...  and already their (young staff's effort) 'outnumbers that of the ENTIRE FORUM!'    Thus 'unwise' to deflect them  from your Aid  (via an unwanted Search) - you (as posts' author) 'know' where your code resides!      You really should consider, 'Speeding/Easing your helper's task...'     (they have 'plenty of Paid Work holding!')

    /* For now disengage the RX interrupt */

    MAP_UARTIntDisable(UART2_BASE, (UART_INT_RX | UART_INT_RT));

    Is it possible that (another)  Interrupt Parameter (not w/in your 2 item listing) generates the interrupt?     Such seems a possibility - does it not?

    And ... are there not means for determining (which) particular interrupt triggered?    (even illegally!)     That would prove beyond useful - would it not?     (Sorry - Staff/I have no use for 'so slow' an MCU ... hate it when a 'Herd of Turtles' hi-beam us while on the Autobahn headed to Frankfurt...)

    [edit]: 17:54 CST  Just prior to their 'escape' from our famed 'back-room'  (Saturday/over-time) - one noted:   (pardon - likely BP Code Error!)

    /* Enable UART2 with TX-FIFO, disable RX-FIFO */     'BP Code'
        HWREG(UART2_BASE + UART_O_CTL) |=
                (UART_CTL_UARTEN | UART_CTL_TXE | ~(UART_CTL_RXE));  //  *** Do you really WANT that? ***  

    Further - there are multiple levels of 'Interrupt Enabling & Disabling.'     Perhaps several such 'Disablings' must be deployed - to free you from the 'unwanted/illegal...'

    TAG:  'KISS' - Easing the helper's role, subduing unwanted UART Interrupts, Attention to Detail ...

  • Interesting catch from the gang of young scholars.

    Bitwise NOT of set enable bit OR'd with other control bits in the same register, compiler (C-code) should OR (either OR) a bitwise inverse of a single binary value. Oddly the Tivaware INT enable call uses &=. One has to wonder does & ~(bit) toggle the bit where |~ would not.  Seemingly both methods should produce the same bit logic but again this is tool chain vendor code not C++. My view is the tool chain compiler 18.12.3.LTS should warn if it can not produce |~ bit logic, yet it does not either way.

    The hold off issue was not that serious but disable of UART for short time may have been one way to stop it, or not. Several times testing delay value used between 'rest' and commanding device to disable return codes. Delay time up to execution of sending command tended to wonder every few resets so it was a futile request it seems.

    Frustrated I removed the 'rest' command being sent to the device.

        //
        // Disable the specified interrupts.
        //
        HWREG(ui32Base + UART_O_IM) &= ~(ui32IntFlags);
    
        //
        // Enable the specified interrupts.
        //
        HWREG(ui32Base + UART_O_IM) |= ui32IntFlags;

  • BP101 said:
     compiler (C-code) should OR (either OR) a bitwise inverse of a single binary value.

    You may note that the 'OR'  operator  can only (ever) potentially 'Set a Bit' - NOT clear one!     Thus your attempted clear of RXE must fail.

    Young staff 'sensed' that your 'Clear of bit RXE' was (likely) suspect - they were indeed correct - as your code clearly reveals.   

    Such bits are cleared via the 'AND' operator - which you surely knew.    One man show often faces the struggle to maintain 'Attention to Detail'

  • cb1_mobile said:
    Young staff 'sensed' that your 'Clear of bit RXE' was (likely) suspect - they were indeed correct - as your code clearly reveals

    Again as reported the RXE bit fails no matter how it was configured with TXE or by itself. CCS compilers fail to use Boolean logic derived from 2 input OR logic that requires silicon physical control of two inputs and not compiler incorrect logical deduction there is only one input one conclusion. Therefore the OR operation should be even more safe as AND to control bits from the registers safety perspective, not the compilers unsafe incorrect logic. We don't want to even Touch other control bits when clearing a single bit making the OR operation far superior to AND's unsafe bit changing practice. The directive (|=) in the HWREG sets the register control mode =WRITE and seems to be incorrectly interpreted when confronted by a C+ Bitwise NOT. That is an ANSI C standard operation being ignored by the tool chain compiler.   

     That said a Set control bit OR'd with Bitwise NOT (inverse) tool chain compiler should produce Thumb instructions that clear only a single Bit and (not touch) any of the others via HWREG |= directive. That can not be said of the unsafe AND operation (HWREG &=) that must touch all other register bits when clearing a single bit position when other control bits are being set in the same line statement. TI compiler approach to register bit changes is highly hypocritical to the safer (HWREG |=) multiple bit Sets and a procedure that confuses much safer OR'd bit changes with UNSAFE illogical bit manipulation. Will they ever grow up and recognize the hypocrisy of HWREG (|= versus &=) where tool chain register bit safety is concerned, the world may never know.

    Seemingly the UART receiver has several silicon issues that have never been skirted or not reported to this forum. The last snide remark was unwarranted, UNTRUE and not taken as being prudent to the conversation.

  • Your 'understanding & reporting' of the 'Operation of the 'OR' Operator' - as well as the definition of 'snide' are (both) unique & incorrect.     Plain statement of fact hardly qualifies as, 'snide.'   

    Basic programming mistake - almost surely - lead to your coming to, 'False Conclusions'  which  'over-exercised' your 'helpers.'

    Tag:  Should 'reality' be masked & denied?