Re: UART Transmission TX inside ISR

"Onestone [email protected] [msp430]" <[email protected]> Fri, 30 Sep 2016 01:59:47 +0930
Newsgroups gmane.comp.hardware.texas-instruments.msp430.discuss
Message-ID <[email protected]>
--------------FF2F6439D23FE831500F0EB9
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit

Without seeing how that compiles it is hard to say. What I can say is 
that transmitting inside the interrupt, provided your interrupt is 
small, is generally the fastest and most efficient way to do it. The DMA 
on the MSP430 is not a true DMA in that it steals clocks from the CPU so 
isn't as efficient as a traditional DMA. If you have DMA and your 
messages are reasonably long then it's worthwhile usign DMA most of the 
time. You have to weigh the DMA set up overhead, and the loss of CPU 
cycles against the savings made, and make allowances for all scenarios

This is a typical UART handler that handles both Tx and RX although RX 
isn't used in this case.

Handling the RX may seem pedantic, but register RAM corruption does 
occur (I probably made a tidy living for many years off of that common 
omission) and unless you have other more complex safeguards in place 
this is a simple way of avoiding erroneous transmission. It should have 
another instruction prior to exit that clears the RXIFG so that the 
false int doesn't keep re-occurring, but it wasn't in my original code 
so I left it so I could point out my own error.

;****** THIS UART A0 IS USED FOR RF COMMS


USCABTX_ISR:                         ;UART1 TX VECTOR, TRAP IF UNUSED.
     BIT    #UCA0TXIFG,&IFG2           ;Test Tx int flag
     JNZ    TXHB0                      ;jump if set
     BIC    #LPM3,0(SP)                ;set low poer mode on exit
     RETI                              ;else exit
TXHB0:
     MOV    &TX_PTR,R12                ;set up to use indexed fetch
     INC    &TX_PTR
     MOV.B    TX_BUFFER(R12),&UCA0TXBUF    ;write next byte to Tx OUTPUT reg
     DEC    DIGITS                     ;DIGITS is a reserved register 
for tracking the Tx size
     JNZ    ENDTX                      ;if not last byte continue
     BIC.B    #UCA0TXIE,&IE2           ;else disable ISR
     BIS.B    #GREEN,&P2OUT            ;turn Green Tx LED off
     BIC    #LPM3,0(SP)                ;and exit in LPM3
ENDTX:
     RETI

Al


On 30/09/2016 12:57 AM, [email protected] [msp430] wrote:
>
>
> I'm curious if someone can explain to me the (negative?) effects of 
> trying to send UART bytes directly from my Interrupt Service Routine. 
>  Is this bad design practice because now my ISR will take longer to 
> execute?  Should I be using DMA to TX data here?  Thanks in advance.
>
>
> static void ParseRxData(const uint8_t rx_byte)
>
> {
>
>     // Only Allow ASCII Characters to be loaded into buffer
>
>     // This will drop CR/LF etc, won't go in gRxBuffer
>
>     if (rx_byte >= 0x20)
>
>         gRxBuffer[gWrIndex++] = tolower(rx_byte); // stuff lowercase 
> only into buffer
>
>
>     UartSendChar(rx_byte);
>
>
>     if (rx_byte == 0x0A) // End of Command
>
>     {
>
>         gRxBuffer[gWrIndex] = 0;  // Add null pointer to end
>
>         gFlagCmdReady = true;  // Set Global Flag Ready Command
>
>         gWrIndex = 0;
>
>     }
>
> }
>
>
>
> //******************************************************************************
>
> //
>
> //This is the USCI_A1 interrupt vector service routine.
>
> //
>
> //******************************************************************************
>
> #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
>
> #pragma vector=USCI_A1_VECTOR
>
> __interrupt
>
> #elif defined(__GNUC__)
>
> __attribute__((interrupt(USCI_A1_VECTOR)))
>
> #endif
>
> void EUSCI_A1_ISR(void)
>
> {
>
>     uint8_t RXData;
>
>     switch(__even_in_range(UCA1IV,USCI_UART_UCTXCPTIFG))
>
>     {
>
>     case USCI_NONE: break;
>
>     case USCI_UART_UCRXIFG:
>
>         RXData = EUSCI_A_UART_receiveData(EUSCI_A1_BASE);
>
>         ParseRxData(RXData);
>
>         break;
>
>     case USCI_UART_UCTXIFG: break;
>
>     case USCI_UART_UCSTTIFG: break;
>
>     case USCI_UART_UCTXCPTIFG: break;
>
>     }
>
> }
>
>
>
>
> 


--------------FF2F6439D23FE831500F0EB9
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit





<head>

<style type="text/css">
<!--

/* start of attachment style */
       .ygrp-photo-title{
         clear: both;
         font-size: smaller;
         height: 15px;
         overflow: hidden;
         text-align: center;
         width: 75px;
       }
       div.ygrp-photo{
         background-position: center;
         background-repeat: no-repeat;
         background-color: white;
         border: 1px solid black;
         height: 62px;
         width: 62px;
       }

       div.photo-title 
         a,
         div.photo-title a:active,
         div.photo-title a:hover,
         div.photo-title a:visited {
           text-decoration: none; 
       }

       div.attach-table div.attach-row {
         clear: both;
       }

       div.attach-table div.attach-row div {
         float: left;
         /* margin: 2px;*/
       }

       p {
         clear: both;
         padding: 15px 0 3px 0;
	 overflow: hidden;
       }

       div.ygrp-file {
         width: 30px;
         valign: middle;
       }
       div.attach-table div.attach-row div div a {
         text-decoration: none;
       }

       div.attach-table div.attach-row div div span {
         font-weight: normal;
       }

       div.ygrp-file-title {
         font-weight: bold;
       }
 /* end of attachment style */
        -->
        </style>
        </head>
<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">


<!-- |**|begin egp html banner|**| -->

<br><br>

<!-- |**|end egp html banner|**| -->



    <p><font size="-1">Without seeing how that compiles it is hard to
        say. What I can say is that transmitting inside the interrupt,
        provided your interrupt is small, is generally the fastest and
        most efficient way to do it. The DMA on the MSP430 is not a true
        DMA in that it steals clocks from the CPU so isn't as efficient
        as a traditional DMA. If you have DMA and your messages are
        reasonably long then it's worthwhile usign DMA most of the time.
        You have to weigh the DMA set up overhead, and the loss of CPU
        cycles against the savings made, and make allowances for all
        scenarios<br>
      </font></p>
    <p><font size="-1">This is a typical UART handler that handles both
        Tx and RX although RX isn't used in this case.</font></p>
    <p><font size="-1">Handling the RX may seem pedantic, but register
        RAM corruption does occur (I probably made a tidy living for
        many years off of that common omission) and unless you have
        other more complex safeguards in place this is a simple way of
        avoiding erroneous transmission. It should have another
        instruction prior to exit that clears the RXIFG so that the
        false int doesn't keep re-occurring, but it wasn't in my
        original code so I left it so I could point out my own error.<br>
      </font></p>
    <tt>;****** THIS UART A0 IS USED FOR RF COMMS</tt><br>
    <p><tt><br>
        USCABTX_ISR:                         ;UART1 TX VECTOR, TRAP IF
        UNUSED.<br>
            BIT    #UCA0TXIFG,&amp;IFG2           ;Test Tx int flag<br>
            JNZ    TXHB0                      ;jump if set<br>
      </tt><tt>    BIC    #LPM3,0(SP)                ;set low poer mode
        on exit<br>
            RETI                              ;else exit<br>
        TXHB0:<br>
            MOV    &amp;TX_PTR,R12                ;set up to use indexed
        fetch<br>
            INC    &amp;TX_PTR<br>
            MOV.B    TX_BUFFER(R12),&amp;UCA0TXBUF    ;write next byte
        to Tx OUTPUT reg<br>
            DEC    DIGITS                     ;DIGITS is a reserved
        register for tracking the Tx size<br>
            JNZ    ENDTX                      ;if not last byte continue<br>
            BIC.B    #UCA0TXIE,&amp;IE2           ;else disable ISR<br>
            BIS.B    #GREEN,&amp;P2OUT            ;turn Green Tx LED off<br>
      </tt><tt>    BIC    #LPM3,0(SP)                ;and exit in LPM3<br>
        ENDTX:<br>
            RETI</tt></p>
    <p><tt>Al</tt><br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 30/09/2016 12:57 AM,
      <a class="moz-txt-link-abbreviated" href="mailto:[email protected]">[email protected]</a> [msp430] wrote:<br>
    </div>
    <blockquote cite="mid:[email protected]" type="cite">
      <meta http-equiv="Context-Type" content="text/html; charset=UTF-8">
      <br>
      <br>
      <p>I'm curious if someone can explain to me the (negative?)
        effects of trying to send UART bytes directly from my Interrupt
        Service Routine.  Is this bad design practice because now my ISR
        will take longer to execute?  Should I be using DMA to TX data
        here?  Thanks in advance.</p>
      <p><br>
      </p>
      <p>static void ParseRxData(const uint8_t rx_byte)</p>
      <p>{</p>
      <p>    // Only Allow ASCII Characters to be loaded into buffer</p>
      <p>    // This will drop CR/LF etc, won't go in gRxBuffer</p>
      <p>    if (rx_byte &gt;= 0x20)</p>
      <p>        gRxBuffer[gWrIndex++] = tolower(rx_byte); // stuff
        lowercase only into buffer</p>
      <p><br>
      </p>
      <p>    UartSendChar(rx_byte);</p>
      <p><br>
      </p>
      <p>    if (rx_byte == 0x0A) // End of Command</p>
      <p>    {</p>
      <p>        gRxBuffer[gWrIndex] = 0;  // Add null pointer to end</p>
      <p>        gFlagCmdReady = true;  // Set Global Flag Ready Command</p>
      <p>        gWrIndex = 0;</p>
      <p>    }</p>
      <p>}</p>
      <p><br>
      </p>
      <p><br>
      </p>
      <p>//******************************************************************************</p>
      <p>//</p>
      <p>//This is the USCI_A1 interrupt vector service routine.</p>
      <p>//</p>
      <p>//******************************************************************************</p>
      <p>#if defined(__TI_COMPILER_VERSION__) ||
        defined(__IAR_SYSTEMS_ICC__)</p>
      <p>#pragma vector=USCI_A1_VECTOR</p>
      <p>__interrupt</p>
      <p>#elif defined(__GNUC__)</p>
      <p>__attribute__((interrupt(USCI_A1_VECTOR)))</p>
      <p>#endif</p>
      <p>void EUSCI_A1_ISR(void)</p>
      <p>{</p>
      <p>    uint8_t RXData;</p>
      <p>    switch(__even_in_range(UCA1IV,USCI_UART_UCTXCPTIFG))</p>
      <p>    {</p>
      <p>    case USCI_NONE: break;</p>
      <p>    case USCI_UART_UCRXIFG:</p>
      <p>        RXData = EUSCI_A_UART_receiveData(EUSCI_A1_BASE);</p>
      <p>        ParseRxData(RXData);</p>
      <p>        break;</p>
      <p>    case USCI_UART_UCTXIFG: break;</p>
      <p>    case USCI_UART_UCSTTIFG: break;</p>
      <p>    case USCI_UART_UCTXCPTIFG: break;</p>
      <p>    }</p>
      <p>}</p>
      <p><br>
      </p>
      <br>
      <br>
      <div width="1"></div>
    </blockquote>
    <br>
  



<!-- |**|begin egp html banner|**| -->

<br>


<br>

<!-- |**|end egp html banner|**| -->


<div width="1" style="color: white; clear: both;"/>__._,_.___</div>

      
  

    
    <div id="fromDMARC" style="clear:both; margin-top: 10px;">
         <hr style="height:2px ; border-width:0; color:#E3E3E3; background-color:#E3E3E3;">
         Posted by: Onestone &lt;[email protected]&gt;         <hr style="height:2px ; border-width:0; color:#E3E3E3; background-color:#E3E3E3;">
    </div>
<!-- Start Recommendations -->
<!-- End Recommendations -->


<!-- |**|begin egp html banner|**| -->

<br><br>
<tt>
To unsubscribe from the msp430 group, send an email to:<BR>
[email protected]<BR>
<BR>
</tt>
<br><br>

<!-- |**|end egp html banner|**| -->



<!-- |**|begin egp html banner|**| -->

  <img src="http://geo.yahoo.com/serv?s=97476590/grpId=2342629/grpspId=1705005378/msgId=52528/stime=1475166607" width="1" height="1"> <br>

<!-- |**|end egp html banner|**| -->

    
<!-- |**|begin egp html banner|**| -->

<br>



   
     
 
        <!-- |**|begin egp html banner|**| -->
        <div id="ygrp-vital" style="background-color: #f2f2f2; font-family: Verdana; font-size: 10px; margin-bottom: 10px; padding: 10px;">

        <span id="vithd" style="font-weight: bold; color: #333; text-transform: uppercase; "><a href="https://groups.yahoo.com/neo/groups/msp430/info;_ylc=X3oDMTJlbm0wN25xBF9TAzk3MzU5NzE0BGdycElkAzIzNDI2MjkEZ3Jwc3BJZAMxNzA1MDA1Mzc4BHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTQ3NTE2NjYwNg--" style="text-decoration: none;">Visit Your Group</a></span>

     <ul style="list-style-type: none; margin: 0; padding: 0; display: inline;">
                                                    </ul>
  </div>


<div id="ft" style="font-family: Arial; font-size: 11px; margin-top: 5px; padding: 0 2px 0 0; clear: both;">
  <a href="https://groups.yahoo.com/neo;_ylc=X3oDMTJkazRpN3ZoBF9TAzk3NDc2NTkwBGdycElkAzIzNDI2MjkEZ3Jwc3BJZAMxNzA1MDA1Mzc4BHNlYwNmdHIEc2xrA2dmcARzdGltZQMxNDc1MTY2NjA3" style="float: left;"><img src="http://l.yimg.com/ru/static/images/yg/img/email/new_logo/logo-groups-137x15.png" height="15" width="137" alt="Yahoo! Groups" style="border: 0;"/></a>
  <div style="color: #747575; float: right;"> &bull; <a href="https://info.yahoo.com/privacy/us/yahoo/groups/details.html" style="text-decoration: none;">Privacy</a> &bull; <a href="mailto:[email protected]?subject=Unsubscribe" style="text-decoration: none;">Unsubscribe</a> &bull; <a href="https://info.yahoo.com/legal/us/yahoo/utos/terms/" style="text-decoration: none;">Terms of Use</a> </div>
</div>

<!-- |**|end egp html banner|**| -->

  </div> <!-- ygrp-msg -->

   


  <br>

<!-- |**|end egp html banner|**| -->


<div style="color: white; clear: both;"/>__,_._,___</div>
</body>
</html>

--------------FF2F6439D23FE831500F0EB9--