Author Topic: How to use the UART to get data and send data!  (Read 90017 times)

Offline Fausto_F

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: How to use the UART to get data and send data!
« Reply #15 on: March 18, 2008, 02:00:22 PM »
Hi Mark,

A debounce timer after the event seems to be the best solution.

Thanks again for all your support.

Fausto

Offline Arun Bhargav

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: How to use the UART to get data and send data!
« Reply #16 on: August 07, 2008, 11:43:13 AM »
Hello,

A better solution to UART problems is Cypress. They are an expert in UART, Data acquisition and control system.  Cypress provides a wide selection of Documentation, Design Kits, Training, Technical Articles, Example Projects and more to help design engineers use our products effectively.
Check this at http://www.cypress.com/

Offline kyork

  • Newbie
  • *
  • Posts: 6
    • View Profile
Recieving Data via Simulator
« Reply #17 on: August 21, 2008, 09:53:12 PM »
I have a USB->Serial device connected to my PC and I would like to use the Simulator to talk to it.  I have the following simple task setup:

Code: [Select]
void fnApplication(TTASKTABLE *pTable)
{
//initialize
if( state == 0 )
{
TTYTABLE tInterfaceParameters;       //table for passing information to driver

tInterfaceParameters.Channel = DEMO_UART;  // serial 0, 1, 2, 3, 4, etc.
  tInterfaceParameters.ucSpeed =  SERIAL_BAUD_115200; // baud rate
  tInterfaceParameters.Rx_tx_sizes.RxQueueSize = RX_BUFFER_SIZE;       // input buffer size
tInterfaceParameters.Rx_tx_sizes.TxQueueSize = TX_BUFFER_SIZE; // outpu buffer size
    tInterfaceParameters.Task_to_wake = 0;
tInterfaceParameters.usConfig = (CHAR_8 | NO_PARITY | ONE_STOP | RTS_CTS | NO_HANDSHAKE | CHAR_MODE);    

if ( (SerialPortID = fnOpen(TYPE_TTY, FOR_I_O, &tInterfaceParameters)) != 0 )  // open or change the channel with defined configurations (initially inactive)
{
fnDriver( SerialPortID, (RX_ON | TX_ON), 0 );        // enable RX & TX
DebugHandle = SerialPortID;
state = 1;
}
}
else
{
int count = fnMsgs(SerialPortID);
if( count > 0 )
{
unsigned char buffer[MEDIUM_MESSAGE];
int read;

read = fnRead(SerialPortID,buffer,MEDIUM_MESSAGE);
}
}
}

Also, I have #define SERIAL_PORT_0   '8' set in app_hw_m5223x.h

If I reset the device connected to the USB->Serial connection, it sends some data on bootup.  If I connect to COM8 with Hyperterminal, I can see this data come in.  However, the above task never gets a value from fnMsgs() greater than zero.

Am I missing some step to get the Simulators serial emulation to work?

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3243
    • View Profile
    • uTasker
Re: How to use the UART to get data and send data!
« Reply #18 on: August 22, 2008, 01:20:50 PM »
Hi

By setting the define #define SERIAL_PORT_0   '8' all communication with the UART 0 should be mapped to COM 8 - in both directions. There should be nothing more necessary.

I would suggest the following checks.
1. Check that DEMO_UART is also 0

2. Check that you don't have SERIAL_SUPPORT_DMA active. This would require tInterfaceParameters.ucDMAConfig = x; to also be configured when setting it up. Undefined configuration parameters could cause problems.

3. Connect your COM 8 via a cross-over cable (null-modem cable) to a terminal emulator set up to 115200 baud. Add a test transmission to your code after it has opened the UART interface (eg. fnWrite(SerialPortID, ""HELLO", 5);, or fnDebugMsg("HELLO"); since you have set the debug output to the UART) This should arrive at the terminal emulator so that you can verify that transmission is operating correctly.

4. I would set tInterfaceParameters.Task_to_wake to TASK_APPLICATION so that each received character will wake the task (is it polling in your test case?). When entering something at the terminal emulator the task should be woken (set a break point in it to verify) and then fnMsgs() should also return the character count and the read return the entered character(s).

I just verified your code, with modifications for 3 and 4. It was using COM 3 (also a USB-RS232 converter) and it ran successfully.

Regards

Mark

Offline kyork

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: How to use the UART to get data and send data!
« Reply #19 on: August 22, 2008, 05:22:28 PM »
Mark,

Thanks for the follow up. 

The problem seems to be some kind of buffering, maybe on the USB/Serial converter.  Here's what I'm seeing happen.

1) Start the Simulator
2) Power up the serial device
3) <no incoming message>
4) Stop Simulator
5) Start Simulator
6) <message expected from #3 reads in immediately>
7) Write command to serial to cause a reset
8) Serial device resets (so obviously writing works)
9) <no incoming message>

I'm going to play with it some more, see if I can narrow down exactly what's going on.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3243
    • View Profile
    • uTasker
Re: How to use the UART to get data and send data!
« Reply #20 on: August 22, 2008, 07:57:58 PM »
Hi

Make sure that the default setup of the USB-RS232 interface (or the terminal emulator) is not HW handshake since it may refuse to sent in this case. This is also valid for all COM ports.

I sometimes have my USB-RS232 adapter block in XOFF mode and have to disconnect and reconnect to get it working again (not a big issue since it only happens when unexpected random data is receivd by it in XON/XOFF handshake mode).

Recently there was an article in a well known electronics magazine where they wrote about setting up a board via an RS232 interface. Their recommendation was not to use a USB-RS232 converter but rather a PC with COM ports. They even wrote that "if you don't have a PC with COM port then try to borrow one from someone for the setup which does"! This is very extreme - the USB-RS232 adapters can certainly give a few more problems that the real COM ports but they are not that bad....

Regards

Mark

Offline kyork

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: How to use the UART to get data and send data!
« Reply #21 on: August 25, 2008, 10:56:09 PM »
Mark,

I have some legacy code that writes data to the UART and then polls until it gets a response.  Is it possible to write directly to the serial driver?

Thanks

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3243
    • View Profile
    • uTasker
Re: How to use the UART to get data and send data!
« Reply #22 on: August 25, 2008, 11:01:24 PM »
Hi

I am not exactly sure what you mean by writing directly to the serial driver. It is of course possible to use a different driver interface by removing SERIAL_INTERFACE and adding other code to do it.

Have you an example of the legacy code?

Regards

Mark

Offline kyork

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: How to use the UART to get data and send data!
« Reply #23 on: August 25, 2008, 11:25:46 PM »
The legacy code is a transport layer driver, the psuedocode is:

driverInit();   //open serial

while( !connected )
{
  fnWrite(RESET); //this sends a RESET frame to the UART device
  fnRead(buffer);
  if( buffer == RSTACK )
     connected = true;
}

The RESET frame is never sent out in this case (I assume because the data is buffered, and sent later by the scheduler).  Is there any way to force the UART driver to write the buffered data?

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3243
    • View Profile
    • uTasker
Re: How to use the UART to get data and send data!
« Reply #24 on: August 26, 2008, 04:09:06 AM »
Hi

OK - I understand now.

First of all - check out the following thread which will explain why the reset is not sent out when using the simulator:
http://www.utasker.com/forum/index.php?topic=330.0

Try putting your original code in a task similar to the folliwing and you should find that - with a small(ish) change - it will work:

void fnMyTask(TTASKTABLE *ptrTaskTable)
{
    static int iState = 0;
    if (!iState) {
        driverInit();   //open serial on initialisation
        iState = 1;
    }
    switch (iState) {
    case 1:             // need to connect
        fnWrite(RESET); //this sends a RESET frame to the UART device
        iState = 2;
        uTaskerStateChange(OWN_TASK, UTASKER_GO);  // switch to polling mode
        break;
    case 2:
        if (fnRead(buffer) != 0) { // read the input (do nothing if nothing arrived)
            if( buffer == RSTACK ) {
                iState = 3;
                uTaskerStateChange(OWN_TASK, UTASKER_STOP); // switch to event mode of operation
                break;
            }
        }
        fnWrite(RESET); // sends the RESET frame again until a correct answer is received
        break;
    case 3:            // synchronised - continue with normal operation
        break;
    }
}



This will send the RESET frame and then quit. Since the task is set to polling mode it will then return (after allowing other stuff to run in the meantime) and see whether there is an answer. If not it will repeat until there is.

It can then be made more efficient by allowing reception to wake the task and adding a timer to repeat if there is no answer after a certain time, rather than polling.

Once in state 3 the reset has received an answer and further code can be run.

You could possibly map the original read and write calls to uTasker ones by using macros.
eg.
#define fnWrite(x) buff = x; fnWrite(serialID, &buff, 1);  // buff is a byte declared somewhere as unsigned char buff;
#define fnRead(x) fnRead(serialID, &x, 1);


If there are not a lot of such calls they could also be simply replaced.


I have rebuilt a number of old projects, especially ones running in super-loops. You usually find that there are various ways to make them more efficient by adding some timer or event support instead of polling. The simulator helps because the changes can be quite easily tested immediately. The code tends to become more structured/modular which then helps when additional features then need to be added. Also the original code works alongside new Ethernet stuff - as long as the new code occupies new tasks they shouldn't disturb each other and so can be kept logically separate.


Regards

Mark


Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3243
    • View Profile
    • uTasker
Re: How to use the UART to get data and send data!
« Reply #25 on: May 10, 2009, 09:15:20 PM »
Hi All

Please note that there is a new UART document here: http://www.utasker.com/docs/uTasker/uTaskerSerialLoader.PDF

At the time of writing it is a preliminary (in work) document but it will be extended to include all present support as well as extensions.

Comments on extra modes or explanations which would be useful in the document are welcome here.

Regards

Mark


Offline Kevin

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: How to use the UART to get data and send data!
« Reply #26 on: June 16, 2010, 01:47:18 AM »
I cannot get the simulator uart to work on COM1 (only serial port) or COM13 (usb to serial dongle).

I've got COM1 connected through a null modem to COM13 and have tera term connected to COM13.

app_hw_lpc23xx.h is set up as follows:
Code: [Select]
#ifdef SERIAL_INTERFACE
    #define WELCOME_MESSAGE_UART   "\r\n\nHello, world... LPC2XXX\r\n"
    #define NUMBER_EXTERNAL_SERIAL 0                                     // {6}
    #define NUMBER_SERIAL   (UARTS_AVAILABLE)                            // the number of physical queues needed for serial interface(s)
    #define SIM_COM_EXTENDED                                             // COM ports defined from 1..255
    #define SERIAL_PORT_0   1                                            // if we open UART channel 0 we simulate using this COM port on the PC
    #define SERIAL_PORT_1   4                                            // if we open UART channel 1 we simulate using this COM port on the PC
    #define SERIAL_PORT_2   11                                           // if we open UART channel 2 we simulate using this COM port on the PC
    #define SERIAL_PORT_3   12                                           // if we open UART channel 3 we simulate using this COM port on the PC

    #ifdef OLIMEX_LPC_P2103
        #define DEMO_UART        0                                       // use UART 0
    #else
        #define DEMO_UART        0                                       // use UART 0
      //#define PPP_UART         1                                       // use UART 1 for PPP
    #endif
    #define MODBUS_UART_0        0
    #define MODBUS_UART_1        1
    #define MODBUS_UART_2        2
    #define MODBUS_UART_3        3
  //#define SUPPORT_HW_FLOW                                              // enable hardware flow control support
    #if defined LPC2103 || defined LPC2102 || defined LPC2101
        #define TX_BUFFER_SIZE   (512)                                   // the size of RS232 input and output buffers
        #define RX_BUFFER_SIZE   (32)
    #else
        #define TX_BUFFER_SIZE   (4*1024)                                // the size of RS232 input and output buffers
        #define RX_BUFFER_SIZE   (64)
    #endif

    #ifndef _LPC21XX
      //#define UART1_PORT2                                              // set for alternative pin uses - TXD1 and RXD1 on P2.0 and P2.1 rather than TXD1 on P0.15 and RXD1 on P0.16
      //#define UART2_PORT2                                              // TXD2 and RXD2 on P2.8 and P2.9 rather than TXD2 and RXD2 on P0.10 and P0.11
      //#define UART3_PORT0_HIGH                                         // TXD3 and RXD3 on P0.25 and P0.26 rather than TXD3 and RXD3 on P0.0 and P0.1
    #endif

    #ifdef SUPPORT_HW_FLOW                                               // define the ports for RTS/CTS use
        #define RTS_0_PORT_SET     FIO0SET
        #define RTS_0_PORT_CLR     FIO0CLR
        #define RTS_0_PIN          PORT0_BIT6
        #define RTS_0_PORT_DDR     FIO0DIR
        #define RTS_0_PORT         PORT_0

        #define RTS_1_PORT_SET     FIO0SET
        #define RTS_1_PORT_CLR     FIO0CLR
        #define RTS_1_PIN          PORT0_BIT7
        #define RTS_1_PORT_DDR     FIO0DIR
        #define RTS_1_PORT         PORT_0

        #define RTS_2_PORT_SET     FIO0SET
        #define RTS_2_PORT_CLR     FIO0CLR
        #define RTS_2_PIN          PORT0_BIT5
        #define RTS_2_PORT_DDR     FIO0DIR
        #define RTS_2_PORT         PORT_0

        #define RTS_3_PORT_SET     FIO0SET
        #define RTS_3_PORT_CLR     FIO0CLR
        #define RTS_3_PIN          PORT0_BIT4
        #define RTS_3_PORT_DDR     FIO0DIR
        #define RTS_3_PORT         PORT_0

        #define CTS_0_PIN          PORT2_BIT0                            // CTS can be defined on ports 0 and 2 due to their interrupt capabilitieds
        #define CTS_0_PORT_DDR     FIO2DIR
        #define CTS_0_PORT         PORT_2
        #define CTS_0_STATE        FIO2PIN
        #define CTS_0_INT_PRIORITY 5

        #define CTS_1_PIN          PORT2_BIT1
        #define CTS_1_PORT_DDR     FIO2DIR
        #define CTS_1_PORT         PORT_2
        #define CTS_1_STATE        FIO2PIN
        #define CTS_1_INT_PRIORITY 5

        #define CTS_2_PIN          PORT2_BIT2
        #define CTS_2_PORT_DDR     FIO2DIR
        #define CTS_2_PORT         PORT_2
        #define CTS_2_STATE        FIO2PIN
        #define CTS_2_INT_PRIORITY 5

        #define CTS_3_PIN          PORT2_BIT3
        #define CTS_3_PORT_DDR     FIO2DIR
        #define CTS_3_PORT         PORT_2
        #define CTS_3_STATE        FIO2PIN
        #define CTS_3_INT_PRIORITY 5
    #endif

Is there something else I have to do to enable the menu through the serial port when using the Simulator?

-Kevin

Offline Kevin

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: How to use the UART to get data and send data!
« Reply #27 on: June 16, 2010, 03:30:47 AM »
I ran through the "myfirsttask" tutorial and now everything seems to work.

Offline mhoneywill

  • Full Member
  • ***
  • Posts: 173
    • View Profile
Re: How to use the UART to get data and send data!
« Reply #28 on: June 16, 2010, 08:31:59 AM »
Hi Kevin,

To remove the need for hardware serial ports take a look at com0com http://com0com.sourceforge.net/ which will create any number of virtual serial port pairs on your PC which are linked with a virtual null modem cable. For example I have the following pairs set-up on my computer

com100 <--> com110
com101 <--> com111
com102 <--> com112

All my utasker projects connect to Uart0 to Com100, Uart1 to Com101 ... etc I then connect my terminal applications or test programs, or other utasker projects (If I'm simulating to utasker boards talking to each other) to the other port i.e. com110, com111 ... etc.

Com0com is very easy to use and in my experience just works :-). Note when it installs it creates a serial port pair with the names CNCA1 and CNCB1 just use the configuration tool to rename these to Comxxx etc.

I use high com port numbers to ensure I don't clash with other bits of hardware / Usb adapters I use.

Note: if you use com ports creater than com9 you will need to define SIM_COM_EXTENDED in the hardware header file for the hardware I'm simulating this is app_hw_lm3sxxxx.h

You might want to look at these other posts
http://www.utasker.com/forum/index.php?topic=343.msg1447#msg1447
http://www.utasker.com/forum/index.php?topic=673.msg2922#msg2922
http://www.utasker.com/forum/index.php?topic=663.msg2856#msg2856

Cheers

Martin
« Last Edit: June 16, 2010, 08:38:59 AM by mhoneywill »

Offline Kevin

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: How to use the UART to get data and send data!
« Reply #29 on: August 19, 2010, 02:38:44 AM »
Thanks Martin!