Author Topic: Simulator for serial port data  (Read 13087 times)

Offline lthyagar

  • Newbie
  • *
  • Posts: 21
    • View Profile
Simulator for serial port data
« on: September 09, 2009, 06:08:42 PM »
Hello,
This is what I am planning to do:
1) interface a Garmin GPS unit to my workstation serial port using a usb-serial converter.
2) I would like to use interrupts on the serial port, and it should interrupt on the line ending. The ISR will send a message to the GPS task to start processing.
3)  GPS task to process ( parse)  the GPS sentence.
4) Send LAT, LON and Speed over ground to LCD task.
I know how to go about steps 1, 3 and 4.
Is step 2 possible using  the simulator? At present I do not have any target hardware.

Thanks!!
Lav

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Simulator for serial port data
« Reply #1 on: September 09, 2009, 10:07:36 PM »
Hi Lav

If you map a UART to a COM port you will receive an interrupt for each received character (that is, the RX interrupt handler will be called for each character).
Depending on the interface mode you will get a wake-up of the UART's own task on each character or only on a defined terminator (message mode).
If your line ending is a particular character you can configure this to perform the wake-up: see the following - http://www.utasker.com/forum/index.php?topic=54.0

Other possible conditions are a break condition (the Coldfire project and its simulator should be able to handle this too but I don't think that all packages support it), or an idle line for a certain amount of time (supported by most processors in V1.4 because this is used in MODBUS RTU mode - see MODBUS document http://www.utasker.com/docs/MODBUS/uTasker_MODBUS.PDF).

Regards

Mark

Offline lthyagar

  • Newbie
  • *
  • Posts: 21
    • View Profile
exception when simulating
« Reply #2 on: September 10, 2009, 01:42:19 AM »
#include "config.h"
#define OWN_TASK                 TASK_MY_FIRST_TASK
//Prototypes
void setUart(unsigned char mode);
// Global variables
static QUEUE_HANDLE SerialPortID;      // quehandler for serialport 3


extern void fnMyFirstTask(TTASKTABLE *ptrTaskTable)
{
   QUEUE_TRANSFER length;
    unsigned char ucInputBuffer[100];
  static int iState = 0;
  static unsigned char ucCounter = 0;
  static const char LCDdsp[] = " From Lav's task";      // display message from present cursor position
  if (iState== 0)
   {   
      setUart(FOR_READ ); //Rx only
      iState = 1;
        }
while ((length = fnMsgs(SerialPortID)) != 0) {    // get number of waiting bytes
        if (length > sizeof(ucInputBuffer)) {     // ensure buffer can’t be overrun
            length = sizeof(ucInputBuffer);
        }
        fnRead(SerialPortID, ucInputBuffer, length);     // read to a local buffer
    }
  //  fnDebugMsg("Hello, World! Test number ");
   /* fnDebugDec(ucCounter++, sizeof(ucCounter));
    fnDebugMsg("\r\n");*/
   TOGGLE_LAV_OUT() ;
   fnDoLCD_com_text(E_LCD_TEXT, (unsigned char *)LCDdsp, (sizeof(LCDdsp) - 1));
   //uTaskerStateChange(OWN_TASK, UTASKER_GO);                // switch to polling mode of operation
}

void setUart(unsigned char mode)
{
   TTYTABLE tInterfaceParameters;       //table for passing information to driver
   
   tInterfaceParameters.Channel = SERIAL_PORT_3;  // serial 0, 1, 2, 3, 4, etc.
    tInterfaceParameters.ucSpeed =  SERIAL_BAUD_4800; // 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 = TASK_MY_FIRST_TASK;
   tInterfaceParameters.Config = (CHAR_8 | NO_PARITY | ONE_STOP | NO_HANDSHAKE | CHAR_MODE );               
   
   if ( (SerialPortID = fnOpen(TYPE_TTY, mode, &tInterfaceParameters)) != 0 )  // open or change the channel with defined configurations (initially inactive)
      fnDriver( SerialPortID, (RX_ON | TX_ON), 0 );        // enable RX & TX
   
}


I get this error;
Unhandled exception at 0x0046339f in uTaskerV1-4.exe: 0xC0000005: Access violation writing location 0x0000004b.
Will appreciate any help. thanx.

Offline lthyagar

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Simulator for serial port data
« Reply #3 on: September 10, 2009, 03:27:20 AM »
Fixed the exception.
I had to change #define NUMBER_SERIAL to  (4) from 3.
The USB--> serial converter  creates COM3 as the virtual COM port in my
64 bit vista system.
Hence I had to define  #define SERIAL_PORT_3        3  .
I have verified that the virtual COM port is functional, using moni.
Running the simulation with the GPS sentences coming in on the COM port:
while ((length = fnMsgs(SerialPortID)) != 0)
SerialPortID= 19
length=52428-----> and the buffer contains garbage.
Any ideas why the characters are not making into the buffer?

Thanks!!

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Simulator for serial port data
« Reply #4 on: September 10, 2009, 11:55:14 AM »
Hi Lav

I believe that you are working with the SAM7X.
Assuming that this is true, the chip doesn't have UART 3; it has UARTs 0 and 1 (actually called USARTs on the chip) and UART2 (actually the debug unit with restricted UART capabilities).

This will probably explain the crash on first attempt since the driver would ignore the open request if UART 3 and then the serial handler is invalid.

It is not possible to increase NUMBER_SERIAL since this is chip dependent.

The fact that the COM port on the PC is 3 has nothing to do with the SAM7X UART. Assuming that you want to use UART0 on the SAM7X and your virtual COM port is 8 (for example) this is fine. You open the UART in code using tInterfaceParameters.Channel = SERIAL_PORT_0; and you map this to the PC COM port in app_hw_sam7x.h using #define SERIAL_PORT_0        8 // map UART0 to PC COM port 8

I don't actually known what happens when NUMBER_SERIAL is increased. It will possibly allow it to be sort of opened (although it doesn't really exist) but there is no simulation support behind this for such a UART and the rest is probably random what it does.

Probably the following will solve it for you (assuming the GPS module is connected to UART0 and your PC COM port is on COM 3):
tInterfaceParameters.Channel = SERIAL_PORT_0;
#define SERIAL_PORT_0        3



Regards

Mark


Offline lthyagar

  • Newbie
  • *
  • Posts: 21
    • View Profile
still no data read on serial port
« Reply #5 on: September 10, 2009, 05:44:53 PM »
Yes, I am working with the SAM7X
Mapped COM3 on PC to SERIAL_PORT_0.
Running the simulation with the GPS sentences coming in on the COM port:
while ((length = fnMsgs(SerialPortID)) != 0)
SerialPortID= 19
length=52428-----> and the buffer contains garbage.
My code below.

The task is running at 1 second rate.

#include "config.h"
#define OWN_TASK                 TASK_MY_FIRST_TASK
//Prototypes
void setUart(unsigned char mode);
// Global variables
static QUEUE_HANDLE SerialPortID;      // quehandler for serialport 2


extern void fnMyFirstTask(TTASKTABLE *ptrTaskTable)
{
   QUEUE_TRANSFER length;
    unsigned char ucInputBuffer[100];
  static int iState = 0;
  static unsigned char ucCounter = 0;
  static const char LCDdsp[] = " From Lav's task";      // display message from present cursor position
  if (iState== 0)
   {   
      setUart(FOR_READ ); //Rx only
      iState = 1;
        }
while ((length = fnMsgs(SerialPortID)) != 0) {    // get number of waiting bytes
        if (length > sizeof(ucInputBuffer)) {     // ensure buffer can’t be overrun
            length = sizeof(ucInputBuffer);
        }
        fnRead(SerialPortID, ucInputBuffer, length);     // read to a local buffer
    }
  //  fnDebugMsg("Hello, World! Test number ");
   /* fnDebugDec(ucCounter++, sizeof(ucCounter));
    fnDebugMsg("\r\n");*/
   TOGGLE_LAV_OUT() ;
   fnDoLCD_com_text(E_LCD_TEXT, (unsigned char *)LCDdsp, (sizeof(LCDdsp) - 1));
   //uTaskerStateChange(OWN_TASK, UTASKER_GO);                // switch to polling mode of operation
}

void setUart(unsigned char mode)
{
   TTYTABLE tInterfaceParameters;       //table for passing information to driver
   
   tInterfaceParameters.Channel = SERIAL_PORT_0;  // serial 0, 1, 2, 3, 4, etc.
    tInterfaceParameters.ucSpeed =  SERIAL_BAUD_4800; // 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 = TASK_MY_FIRST_TASK;
   tInterfaceParameters.Config = (CHAR_8 | NO_PARITY | ONE_STOP | NO_HANDSHAKE | CHAR_MODE );               
   
   if ( (SerialPortID = fnOpen(TYPE_TTY, mode, &tInterfaceParameters)) != 0 )  // open or change the channel with defined configurations (initially inactive)
      fnDriver( SerialPortID, (RX_ON | TX_ON), 0 );        // enable RX & TX
   
}

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Simulator for serial port data
« Reply #6 on: September 10, 2009, 10:27:13 PM »
Hi

Please check whether you have enabled DMA operation on the UARTs (SERIAL_SUPPORT_DMA in app_hw_sam7x.h).
If this happens to be the case ensure that the configuration parameter
tInterfaceParameters.ucDMAConfig = 0;
is present otherwise it may default to a strange DMA mode.

Then do the following tests without the GPS module connected to the COM port:
1) Set a break point in
        if (length > sizeof(ucInputBuffer)) {     // ensure buffer can’t be overrun
and let the simulator run.
The break-point should not be reached since nothing is being received.

2) In the simulator UARTs menu, execute the command "Simulate a receive message on UART0".
You should arrive at the break-point and the a test message "Hello, World!" should be read from the input buffer.
This will confirm that the project is correctly configured, without requiring a COM port to be mapped.

3) If the tests are correct until now move on to the mapped COM port and try to send a single character to it (either from a terminal emulator set to 4'800Baud via the physical COM port or a com0com virtual loop.
This will then show whether the character is correctly received or not.

4) If test 3 is also successful try with the GPS module again.

Regards

Mark


Offline lthyagar

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Simulator for serial port data
« Reply #7 on: September 10, 2009, 11:21:33 PM »
Hello Mark, Step 2 failed. I am not receiving anything using the simulated receive.
SERIAL_SUPPORT_DMA   is set.
so i had to set tInterfaceParameters.ucDMAConfig = 0;

Offline lthyagar

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Simulator for serial port data
« Reply #8 on: September 11, 2009, 12:15:44 AM »
Step 2 works. I had to set SERIAL_PORT_0 to 0. It was mapped to 3 to match the COM3 on the PC.

I was taking a look at the code below:

extern void fnConfigSCI(QUEUE_HANDLE Channel, TTYTABLE *pars)
{
    unsigned long *ulReg = fnSelectChannel(Channel);
    switch (Channel) {
    case 0:
        POWER_UP(USART0);                                                // {37} enable clocks to UART0
        break;
    case 1:
        POWER_UP(USART1);                                                // {37} enable clocks to UART1
        break;
    #ifdef DBGU_UART                                                     // {35}
    case 2:
        POWER_UP(SYSIRQ);                                                // {37} enable clocks to UART2 (DBGU)
        break;
    #endif
    default:
        return;
    }
If channel is 3, it goes into the default section!!!
So UART0 is not enabled on the target.

Offline lthyagar

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Simulator for serial port data
« Reply #9 on: September 11, 2009, 01:31:31 AM »
Finally got it working !!
Had to force the COM3 to COM1 in the USB driver on Windows, and used
SERIAL_PORT0 set to 1 instead of 3.