Author Topic: CTS & RTS  (Read 13202 times)

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
CTS & RTS
« on: April 03, 2009, 11:17:02 AM »
Hi Mark,
  I wish to use the CTS and RTS (using the 52259) on UART 2 and UART 1. Do I simply do the following:

config.h
  #define SUPPORT_HW_FLOW

when setting up the port:
if ((SerialPortID = fnOpen( TYPE_TTY, ucDriverMode, &tInterfaceParameters )) != 0) { // open or change the channel with defined configurations (initially inactive)

      .....
         if ((SerialPortID = fnOpen( TYPE_TTY, ucDriverMode, &tInterfaceParameters )) != 0) {
        fnDriver( SerialPortID, ( TX_ON | RX_ON ), 0 );                 
        if (tInterfaceParameters.usConfig & RTS_CTS) {                   
            fnDriver( SerialPortID, (MODIFY_INTERRUPT | ENABLE_CTS_CHANGE), 0 );
            fnDriver( SerialPortID, (MODIFY_CONTROL | SET_RTS), 0 );     

        }

     }

Is that all I have to do?  What about DMA does this work too with the setup?

Many Thanks
Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: CTS & RTS
« Reply #1 on: April 03, 2009, 12:08:14 PM »
Hi Neil

Yes, this is the correct method. RTS_CTS will then be used for flow control.

You should generally not use DMA when working in this mode since it will not stop transmission during a block of data due to negated CTS.

I notice that this is still an open point because it should be possible to interrupt the DMA transmission when the CTS interrupt arrives. Also, when I read through the RTS/CTS note at the following thread: http://www.utasker.com/forum/index.php?topic=105.msg424#msg424
I wonder whether this can not be automated by setting the TXCTS bit in UMR2?
Quote
This allows the transmitter to automatically stop sending when the CTS line has been negated by the other side. It doesn't disturb the character which may have been in the process of transmission at the time the negation was detected but will freeze the transmitter afterwards until the CTS line has been asserted again.

This does sound as though it is automated at the HW level and so should also work when the transmitter is DMA driven.

If you are doing tests which involve flow control could you give this a quick try? I suggest the following change in M5223X.c - in fnConfigSCI();

Originally:
    if (pars->usConfig & TWO_STOPS) {                                    // the mode register 2 has been selected by previous write
        *ucReg = UART_TWO_STOP;
    }
    else if (pars->usConfig & ONE_HALF_STOPS) {
        *ucReg = UART_ONE_HALF_STOP;
    }
    else {
        *ucReg = UART_ONE_STOP;
    }



Modification:

    if (pars->usConfig & TWO_STOPS) {                                    // the mode register 2 has been selected by previous write
        ucBits = UART_TWO_STOP;
    }
    else if (pars->usConfig & ONE_HALF_STOPS) {
        ucBits = UART_ONE_HALF_STOP;
    }
    else {
        ucBits = UART_ONE_STOP;
    }

    #if defined SUPPORT_HW_FLOW && defined SERIAL_SUPPORT_DMA            // {97}
    if ((pars->usConfig & RTS_CTS) && (ucUseDMA & UART_TX_DMA)) {        // RTS/CTS flow control used with DMA transmission
        ucBits |= TXCTS;                                                 // enable automatic negation of RTS when the input FIFO is full
    }
    #endif
    *ucReg = ucBits;


If it works it will be a good solution. Unfortunately the description in the user manual seems to state that this bit should be used together with TXRTS (strange). But, TXRTS and RXRTS should not be used together otherwise RTS control will be disabled. This sounds as though there may be restrictions and, either the RXRTS operation is lost or else the RTS line will also be disabled after every character, which is not suitable for RTS/CTS flow control.

Should the test be unsuccessful, disable DMA operation so that basic RTS/CTS flow control operates as normal. I will then look into how the CTS interrupt can be used to "freeze" the DMA transmission.

Regards

Mark

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: CTS & RTS
« Reply #2 on: April 03, 2009, 04:15:51 PM »
Hi Mark,
  Before checking the above, I have to drive the RTS high, then about a second later bring back low again.  What the best way to control the RTS after the serial port has been setup

Neil
 

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: CTS & RTS
« Reply #3 on: April 03, 2009, 05:44:33 PM »
Hi Mark,
  I have been trying to set up the serial port with CTS/RTS, I done the below ( I set the RTS_CTS in the usconfig):
I have another serial port sending out data to hyperterminal which works fine (on uart 0), but as soon as the below is called, then nothing gets sent on that uart. The same happens when I tried the above code , as well as previous.

Neil


    TTYTABLE tInterfaceParameters;                                       // table for passing information to driver
    tInterfaceParameters.Channel = 2;                            // set UART channel for serial use
    tInterfaceParameters.ucSpeed = SERIAL_BAUD_9600; // baud rate
    tInterfaceParameters.Rx_tx_sizes.RxQueueSize = 200;       // input buffer size
    tInterfaceParameters.Rx_tx_sizes.TxQueueSize = 500;       // output buffer size
    tInterfaceParameters.Task_to_wake = TASK_USBCOMMAND;                        // wake self when messages have been received
    tInterfaceParameters.usConfig =(CHAR_8 | NO_PARITY | ONE_STOP | CHAR_MODE | RTS_CTS);
   tInterfaceParameters.ucDMAConfig = 1; //  DMA for UART2
    if ((USBPortID = fnOpen( TYPE_TTY, ucDriverMode, &tInterfaceParameters )) != 0)
     { // open or change the channel with defined configurations (initially inactive)
       fnDriver( USBPortID, ( TX_ON | RX_ON ), 0 );
      if (tInterfaceParameters.usConfig & RTS_CTS) {                   // {8}

            fnDriver( SerialPortID, (MODIFY_INTERRUPT | ENABLE_CTS_CHANGE), 0 ); // activate CTS interrupt when working with HW flow control (this returns also the present control line states)
            fnDriver( SerialPortID, (MODIFY_CONTROL | SET_RTS), 0 );     // activate RTS line when working with HW flow control

        }
}


Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: CTS & RTS
« Reply #4 on: April 03, 2009, 07:48:24 PM »
Hi Neil

Generally the RTS line belowing to the UART is controlled by calling
    fnDriver( SerialPortID, (MODIFY_CONTROL | SET_RTS), 0 );
or
    fnDriver( SerialPortID, (MODIFY_CONTROL | CLEAR_RTS), 0 );

Check how UART2 is configured since the M52259 allows it to be on one of 3 ports:

UART2_ON_AS // TX/RX on AS
UART2_ON_UB // TX/RX on UB
or the default on UC

Check in app_hw_m5223x.h to see which is presently selected and check that it matches your hardware connection. It may be working but the signals appear at a different port to the one you are expecting.

Regards

Mark


Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: CTS & RTS
« Reply #5 on: April 03, 2009, 09:25:22 PM »
Hi Mark,
   If I remove the ' | RTS_CTS' from tInterfaceParameters.usConfig above, then the information is displayed on uart 0 as expected. If I leave the rtc_cts in, then  nothing is sent out on uart 0 (even when the rts_cts os on channel 3).  Here is my serial setup. I assume UART2_ON_UB is serial port 3?


#ifdef SERIAL_INTERFACE
    #if defined _M52210 || defined _M52212 || defined _M52213            // {35}
        #define NUMBER_SERIAL   (2)                                      // the number of physical queue needed for serial interface(s)
    #else
        #define NUMBER_SERIAL   (3)                                      // the number of physical queue needed for serial interface(s)
    #endif
    #define SERIAL_PORT_0   '0'                                          // if we open UART channel 0 we simulate using comx on the PC
    #define SERIAL_PORT_1   '4'                                          // if we open UART channel 1 we simulate using comx on the PC
    #define SERIAL_PORT_2   '3'                                          // if we open UART channel 2 we simulate using comx on the PC
    #if defined M52210DEMO || defined M52211EVB
        #define DEMO_UART     1                                          // use UART 1 (the UART connector on the board)
        #define PPP_UART      0                                          // use UART 0 for PPP
        #define MODBUS_UART_0 0                                          // {44}
    #else
        #define DEMO_UART     0                                          // use UART 0
        #define PPP_UART      1                                          // use UART 1 for PPP
        #define MODBUS_UART_0 2                                          // {44}
        #define MODBUS_UART_1 1                                          // {44}
    #endif
    #define SERIAL_SUPPORT_DMA                                           // enable UART DMA support (available on this processor)

    #define TX_BUFFER_SIZE   (256)                                       // the size of demo RS232 input and output buffers
    #define RX_BUFFER_SIZE   (64)

  //#define UART1_ON_QS                                                  // alternative UART pin mapping {7}
  //#define UART2_ON_AS                                                  // alternative UART pin mapping (set automatically with 64 and 80 pin package)
 // #define UART2_ON_UB                                                  // alternative UART pin mapping
#else
    #define TX_BUFFER_SIZE   (64)
    #define RX_BUFFER_SIZE   (64)
#endif

Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: CTS & RTS
« Reply #6 on: April 03, 2009, 10:57:43 PM »
Hi Neil

I noticed that you are opening UART2 and saving its handle as USBPortID.

Then you are enabling CTS and setting RTS using the handle SerialPortID (presumably UART0).

Could this be the source of the problem? Once opening UART2 you should use its handle to control the lines (although I am not sure why this should stop UART0 from operating correctly...)

Regards

Mark


Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: CTS & RTS
« Reply #7 on: April 04, 2009, 12:01:09 AM »
Hi Mark,
  Thats what it was, its been a long day  ::)

I had to revert to the original code in fnConfigSCI(), above, and set the .ucDMAConfig=0 , off.  As the new code with dma didnt read anything from the serial port.

Thanks
Neil

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: CTS & RTS
« Reply #8 on: April 06, 2009, 03:56:11 PM »
Hi mark,
  I have another serial port connected to  a GPRS modem.  I have set it up for hardware handshaking witht he cts/rts, with DMA off. After appying power the modem pulls the pin low, which I have to monitor. As this pin on the processor is used as hardware handshake, I tried to read the pin by doing the following:

 #define GSM_CTS_PIN PORT_UB_BIT3      //cts pin

 if(PORTIN_SETUB & GSM_CTS_PIN)
 {
   ...
 }

I have placed a breakpoint at the above, and tested on the scope. When the pin is low, the if(..) gets called.
If the above cannot be done while it is setup as hardware handshake, is it possible to set the hardware handshake off during initialisation, then switch back on after this?

Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: CTS & RTS
« Reply #9 on: April 06, 2009, 04:57:17 PM »
Hi Neil

When the CTS line is programmed for CTS operation it can not be read as a GPIO input.

It can however be read using registers UIPCR_UACR_0, UIPCR_UACR_1or UIPCR_UACR_2(depending on the UART in question).

if (UIPCR_UACR_1 & UART_CTS_IN)
{
...
}


This may be the best solution to monitoring its state when in RTS/CTS mode.

Regards

Mark