Problems with /dev/ttySAC0 or max3232?

mathez
Hi,

I'm trying to use the first uart at ttl levels. I have connected an GPS
receiver to the RX and TX pin of the serial port. My code works fine on any
of the other two serial ports but on the first one, I don't get any data.
I've already disabled the console on this serial port and I can read and
write data when connecting with my pc through the max3232 chip using
hyperterminal and the comport testprogram at the mini2440. 

Do I have to disable the max3232 chip somehow in order to use the serial
port at ttl level?

many thanks in advance
mathez

Andreas
I think the max3232 has to be disabled in order to use RX and TX from CON1.
But when I look in the schematics, there seems to be no possibilty for
this. Maybe disassembling?

Edje11
Did you connected your gps to the D-9 connector or the white plastic
connector?
On the white connector there's com1 available at TTL level, but keep in
mind that TTL level is 3.3V.

mathez
Well,

I connect to the small white one on the board. The strange thing that the
other two ports (ttySAC1 and ttySAC2) are working fine, just using the RX
and TX pin. The GPS Receiver uses 3.3V TTL level...

When I connect to D9 connector using my pc and a terminal I can receive and
transmit data. I hope there is still an easy way to use ttl level at
ttysac0. Disassembling would took me too long...

stuck
hi methez please help me ..i have a question how did you open the
/dev/ttySAC1 file when i use the command open("/dev/ttySAC1",..);
it gives me error saying -> /dev/ttySAC1 : No such file or directory

what may be the problem..i'm using ubuntu
the error is same on both desktop and mini

waiting for generous reply
stuck

mathez
hi stuck,

are you sure you have an device named "/dev/ttysac1" on your desktop
computer?

try "cd /dev/" and then "ls". You should then see if you have such an
device on your desktop computer. On my desktop comupter the serial devices
are naemd "/dev/ttySx"!

On the mini device the serial devices are named "/dev/ttySAC0" ...
"/dev/ttySAC2" and it works fine opening those ports, except the TTL level
connector on ttySAC0.

Take a look in the source examples. The "comtest" example does exactly what
you are looking for (at least when you are running qtopia)

bergenm
Mathez,

  Could you post your code and kernel version for accessing the serial
ports. Maybe a mini tutorial for doing this. (ie changing permissions on
ports.....)

  A lot of new programmers up here. 

Thanks
Mike

mathez
Hi there,

I will post some code later because I'm very busy at the moment...

But it would be very generous if someone could solve, or at least give me a
hint, to my problem in my initial posting! 

Many thanks in advance
mathez

MikeB
I will put a serial level changer on my SAC0 white header tonight and see
what I get.

mathez
Hi,

first of all thanks to MikeB for looking into my problem.

Now, as promised, I will give you a small excerpt of my threaded programm
that I'm running under qtopia.
First I will give you a small overview of the hardware that I'm using on
the serial ports.

On ttySAC1 and ttySAC2 I have connected two GPS receivers and I have a
wireless module that 
I wanted to connect to ttySAC0, but (as seen above) I did not manage to get
it working on that port.
Instead I use an USB adapter for this device, so ttyUSB0 is currently that
file...

In my application I have some buttons and I just start the thread calling
the enable() function 
when clicking on one of the buttons.

For the sake of clarity I will only post the function where I read (using
interupts) from ttySAC1
and ttySAC2 and store the results in a file. It is just a straight forward
modification of the comtest
example that comes with the mini. I inserted lots of comments, so I think
this code is very easy to understand.

First of all the header file of my GPSThread class:

#ifndef GPSTHREAD_H
#define GPSTHREAD_H

#include "pthread.h"

class GPSThread
{

public:
    GPSThread();
    virtual ~GPSThread();
    virtual void enable(); // start the thread
    virtual void disable(); // stop the thread
    bool should_run; // for stopping the thread
    bool is_running; // status of the thread
    pthread_t thread; // the thread itself
    int commA_fd, commB_fd; // the file descriptors of the two serial ports
    int deviceSpeed; // the baud rate of the two devices
    int byteBits; // the number of bits
    // the name of the first port, i.e. "/dev/ttySAC1"
    const char *deviceNameA;
    // see also the implementation of the constructor 
    const char *deviceNameB; 
    pthread_mutex_t mutex; // a mutex, not really needed in this excerpt
};

#endif // GPSTHREAD_H

Pretty simple so far. Now here is the implemtation of this class.

# include "gps_thread.h"
# include "pthread.h"
# include <stdio.h>
# include <termio.h>
# include <unistd.h>
# include <fcntl.h>
# include <time.h>
# include <string.h>
# include <errno.h>

GPSThread *instance;

void *recorder_function(void*)
{

// those are my file descriptors for the output files, one for 
// each receiver
    FILE *fileA_fd, *fileB_fd;

  // the struct for the device attributes
    struct termios deviceAttr;
// a struct for defining the timeout when using interupt communication
    struct timeval timeout;

  // the timeout value for the select function, pass NULL for
        // no timeout
    timeout.tv_sec = 0;
    timeout.tv_usec = 50;

  // this is just for naming my files with date and time, not
       // really needed
    time_t rawtime;
    struct tm *timeinfo;
    char filenameA[80], filenameB[80];    

    time(&rawtime);
    timeinfo = localtime(&rawtime);

  // the file names
    strftime(filenameA, 80, "/home/GPS_A_%y%m%d_%H%M%S.bin", timeinfo);
    strftime(filenameB, 80, "/home/GPS_B_%y%m%d_%H%M%S.bin", timeinfo);

  // open the files for writing
    fileA_fd = fopen(filenameA, "w");
    fileB_fd = fopen(filenameB, "w");

  // now it gets interesting:
  // here the ttySAC1 is opened
    instance->commA_fd = open(instance->deviceNameA, O_RDWR, 0);
    if (instance->commA_fd < 0)
  printf("Unable to open device\n");
  // set the port to non blocking mode
    if (fcntl(instance->commA_fd, F_SETFL, O_NONBLOCK) < 0)
       printf("Unable set to NONBLOCK mode\n");
    
  // here the ttySAC2 is opened
    instance->commB_fd = open(instance->deviceNameB, O_RDWR, 0);
    if (instance->commB_fd < 0)
  printf("Unable to open device\n");
  // set the port to non blocking mode
    if (fcntl(instance->commB_fd, F_SETFL, O_NONBLOCK) < 0)
       printf("Unable set to NONBLOCK mode\n");
    
  // set all the device attributes to zero
    memset(&deviceAttr, 0, sizeof(struct termios));
  // set the parameters, see the constructor for the values
    deviceAttr.c_iflag = IGNPAR;
    deviceAttr.c_cflag = instance->deviceSpeed | HUPCL | instance->byteBits
| CREAD | CLOCAL;
    deviceAttr.c_cc[VMIN] = 1;

// apply the attributes to ttySAC1
    if (tcsetattr(instance->commA_fd, TCSANOW, &deviceAttr) < 0)
        printf("Unable to set comm port\n");

// apply the attributes to ttySAC2, they are the same except of the
// device name
    if (tcsetattr(instance->commB_fd, TCSANOW, &deviceAttr) < 0)
        printf("Unable to set comm port\n");

// my buffer for reading
// I read somewhere that the serial ports have an 64 byte buffer, so I 
// alway try to read 64 bytes
// because the port speed is nearly 1Mbps, reading single bytes would be
// quite slow, like in the comtest example
    unsigned char buffer[64];

    // this is the main loop of the thread, it runs till I stop it
    while(instance->should_run)
    {

  // this is needed for reading with interrupts
  fd_set readSetFD;

  // set it to zero
  FD_ZERO(&readSetFD);

  // add the first device
  FD_SET(instance->commA_fd, &readSetFD);
  // add the second device
  FD_SET(instance->commB_fd, &readSetFD);
  
  // the select function will cause the thread to wait, till data
        // is available on one of the ports
#  define max(x,y) ( ((x) >= (y)) ? (x) : (y) )
  if (select(max(instance->commA_fd, instance->commB_fd) + 1, &readSetFD,
NULL, NULL, &timeout) < 0) {
      //printf(strerror(errno));
  }
#  undef max
  
  // variable for the number of bytes read
        int length;

  // is data available on the first device?
  if (FD_ISSET(instance->commA_fd, &readSetFD)) {
      // if so, read as long as data is available
            // this loop will usually only run once
      while ( (length = read(instance->commA_fd, buffer, 64)) > 0 )
            { 
    // and write it to the file
    fwrite(buffer, sizeof(char), length, fileA_fd);
                fflush(fileA_fd);
      }
            
  }
    
  // the same as above, but for the second device
        if (FD_ISSET(instance->commB_fd, &readSetFD)) {
      while ( (length = read(instance->commB_fd, buffer, 64) ) > 0 )
            { 
    fwrite(buffer, sizeof(char), length, fileB_fd);
                fflush(fileA_fd);
      }
        
  }


    }

    // do some cleaning up if the thread was stopped
    close(instance->commA_fd);
    close(instance->commB_fd);

    fclose(fileA_fd);
    fclose(fileB_fd);

    return NULL;
}

GPSThread::GPSThread()
{
// a global variable for accessing the object from the thread function
// this is bad code. it would be better to pass the object as an argument
// to the function
// lazy me :-)
    instance = this;
    pthread_mutex_init(&mutex,NULL);
    is_running = false;
    should_run = false;
  // sell explaining
    deviceSpeed = B921600;
    byteBits = CS8;
    deviceNameA = "/dev/ttySAC1";
    deviceNameB = "/dev/ttySAC2";
}

GPSThread::~GPSThread()
{
}

void GPSThread::enable()
{
    pthread_mutex_lock(&mutex);
    
    should_run = true;
    // start the thread
    pthread_create(&thread,NULL,recorder_function,NULL);
    is_running = true;
    pthread_mutex_unlock(&mutex);
}

void GPSThread::disable()
{
    pthread_mutex_lock(&mutex);
    
    should_run = false;
    // wait for the thread to die
    pthread_join(thread,NULL);
    is_running = false;
    pthread_mutex_unlock(&mutex);
}

I hope this helped. Threaded programms won't compile that easy, you will
have to make some adjustments to the
configuration files. If you need some help on that, just ask. 

kind regards
mathez

mathez
Just an addition:

I was able to run that programm on my desktop computer, but starting the
thread will ever cause the error "No such file or directory" because I
don't have two serial ports on my desktop computer and they are named
differently to the mini. But on the mini it runs very fine and the threaded
approach won't cause the UI to freeze...

MikeB
Same outcome. I have a ttl rs232 level shifter from sparkfun. i set voltage
to 3.3v from gpio and gnd from serial ports then rx/tx null modem and
straight nothing. I just wanted to see the same output I see when I plug
the cable into the rs232 port from pc. got some odd chars once. but i think
it was just noise. i will try this experiment again when my cable kit comes
in.

MikeB
Attachment: 0426102223a_393339.jpg (42.5 KB)
ok!! I spoke too soon. I had the vcc wire on the wrong part of gpio. works
now!!!  I used 3.3v off outside pin closest to sd card. and gnd from serial
ports. now i'm getting the normal console stuff... hope that helps.  The
ttl serial is 3.3v so my level shifter needed true 3.3v 
http://www.sparkfun.com/commerce/product_info.php?products_id=133

MikeB
Have you disabled the linux console from your ttySAC0?

MikeB
your first post nevermind.

dec
I think Tx (transmit) from the board is no problem, but Rx because the pin
is connected to the max3232 ROUT1 output.

MikeB
I can interact with the console through rx/tx both seem to work.

mathez
Thanks MikeB,

my connection to CON1 was very similar to yours. I also needed 3.3V for my
devices but did not get any response. Maybe it is like dec says that the
problems are only with the RX pin. I will also try it with a level shifter.

But, perhabs, my board is broken... I will see.

Thank you all for your suggestions.

regards
mathez

mathez
So it must work! I will try another device on this port...

david
hi im trying to develop an application by reading the serial port.

i compiled the example on my deskotp machine (ubuntu 9.10) executing this
instrution:
 arm-linux-gcc -o comtest comtest.c

after that i send the file comtest to the mini2440, and im trying to
execute by this instrution:
./comtest

but it thows me this mistake:
Unable to open device
streeror() is no such file or directory

can you help me what do i doing wrong?

thanks!!

Janusz
Hallo,

I have one question. You have written that you have no problem with ttySAC1
an ttySAC2. I tried to connect my microprocessor(PIC) to both ports and see
if I get something on this ports "cat /dev/ttySAC1" but I see nothing. Can
you tell me where the problem ?

Regards

MikeB
Janusz: Two things...maybe.

 1) The serial ports on the headers expect 3.3v ttl. PIC may be 5v.

 2) What serial set up is the mini2440 set for 9600,8,N,1 or 115200,8,N,1.

david
who can help me!!

MikeB
david: in http://www.friendlyarm.net/forum/topic/963 Stuck apparently fixed
this problem i am waiting for his reply of how he did it.

david
i think that the solution could be changing the code to read the SAC1, i
have been reading and it seems to be that SAC0 has problems because its use
to configure the sistem

what do you think?

david
friend i have the solution!!!

you have to edit your code: the comtest

look for the line where you configure the port i change this line:

 const char *DeviceName = "/dev/ttyS0";

it has to be like this:

    const char *DeviceName = "/dev/ttySAC0";

i tested sending info to my ubuntu machine from my mini and it works fine!!

but when i send info from my ubuntu machine to my mini it doesnt work

what could it be?

i solve the half of the problem plese help me with the other part

thanks a lot!!

david
can any body helpme? i cant send info from my desktop machine to my
mini2440 (using the comtest example), but i can send info from my mini to
my desktop machine

can someone giveme some ideas?

mikeb
david what type of level shifting are you using. the pc may read down to
3.3 volts. but your mini isnt gonna read full voltage from rs232 from pc.

david
i have the j2 in 5volts if i change this to 3.3 volts my mini doesnt work,

i found other code that my mini can receive info from my desktop pc but now
i trying to join both codes, im having some troubles
 
these are both codes:


with this i can send info with my mini to my desktop machine

# include <stdio.h>
# include <stdlib.h>
# include <termio.h>
# include <unistd.h>
# include <fcntl.h>
# include <getopt.h>
# include <time.h>
# include <errno.h>
# include <string.h>

static void Error(const char *Msg)
{
    fprintf (stderr, "%s\n", Msg);
    fprintf (stderr, "strerror() is %s\n", strerror(errno));
    exit(1);
}
static void Warning(const char *Msg)
{
     fprintf (stderr, "Warning: %s\n", Msg);
}


static int SerialSpeed(const char *SpeedString)
{
    int SpeedNumber = atoi(SpeedString);
#   define TestSpeed(Speed) if (SpeedNumber == Speed) return B##Speed
    TestSpeed(1200);
    TestSpeed(2400);
    TestSpeed(4800);
    TestSpeed(9600);
    TestSpeed(19200);
    TestSpeed(38400);
    TestSpeed(57600);
    TestSpeed(115200);
    TestSpeed(230400);
    Error("Bad speed");
    return -1;
}

static void PrintUsage(void)
{

   fprintf(stderr, "comtest - interactive program of comm port\n");
   fprintf(stderr, "press [ESC] 3 times to quit\n\n");

   fprintf(stderr, "Usage: comtest [-d device] [-t tty] [-s speed] [-7]
[-c] [-x] [-o] [-h]\n");
   fprintf(stderr, "         -7 7 bit\n");
   fprintf(stderr, "         -x hex mode\n");
   fprintf(stderr, "         -o output to stdout too\n");
   fprintf(stderr, "         -c stdout output use color\n");
   fprintf(stderr, "         -h print this help\n");
   exit(-1);
}

static inline void WaitFdWriteable(int Fd)
{
    fd_set WriteSetFD;
    FD_ZERO(&WriteSetFD);
    FD_SET(Fd, &WriteSetFD);
    if (select(Fd + 1, NULL, &WriteSetFD, NULL, NULL) < 0) {
    Error(strerror(errno));
    }
  
}

int main(int argc, char **argv)
{
    int CommFd, TtyFd;

    struct termios TtyAttr;
    struct termios BackupTtyAttr;

    int DeviceSpeed = B115200;
    int TtySpeed = B115200;
    int ByteBits = CS8;
    const char *DeviceName = "/dev/ttySAC0";
    const char *TtyName = "/dev/tty";
    int OutputHex = 0;
    int OutputToStdout = 0;
    int UseColor = 0;

    opterr = 0;
    for (;;) {
        int c = getopt(argc, argv, "d:s:t:7xoch");
        if (c == -1)
            break;
        switch(c) {
        case 'd':
            DeviceName = optarg;
            break;
        case 't':
            TtyName = optarg;
            break;
        case 's':
      if (optarg[0] == 'd') {
    DeviceSpeed = SerialSpeed(optarg + 1);
      } else if (optarg[0] == 't') {
    TtySpeed = SerialSpeed(optarg + 1);
      } else
              TtySpeed = DeviceSpeed = SerialSpeed(optarg);
            break;
  case 'o':
      OutputToStdout = 1;
      break;
  case '7':
      ByteBits = CS7;
      break;
        case 'x':
            OutputHex = 1;
            break;
  case 'c':
      UseColor = 1;
      break;
        case '?':
        case 'h':
        default:
      PrintUsage();
        }
    }
    if (optind != argc)
        PrintUsage();

    CommFd = open(DeviceName, O_RDWR, 0);
    if (CommFd < 0)
  Error("Unable to open device");
    if (fcntl(CommFd, F_SETFL, O_NONBLOCK) < 0)
       Error("Unable set to NONBLOCK mode");



    memset(&TtyAttr, 0, sizeof(struct termios));
    TtyAttr.c_iflag = IGNPAR;
    TtyAttr.c_cflag = DeviceSpeed | HUPCL | ByteBits | CREAD | CLOCAL;
    TtyAttr.c_cc[VMIN] = 1;

    if (tcsetattr(CommFd, TCSANOW, &TtyAttr) < 0)
        Warning("Unable to set comm port");

    TtyFd = open(TtyName, O_RDWR | O_NDELAY, 0);
    if (TtyFd < 0)
  Error("Unable to open tty");

    TtyAttr.c_cflag = TtySpeed | HUPCL | ByteBits | CREAD | CLOCAL;
    if (tcgetattr(TtyFd, &BackupTtyAttr) < 0)
  Error("Unable to get tty");

    if (tcsetattr(TtyFd, TCSANOW, &TtyAttr) < 0)
  Error("Unable to set tty");


    for (;;) {
  unsigned char Char = 0;
  fd_set ReadSetFD;

  void OutputStdChar(FILE *File) {
      char Buffer[10];
      int Len = sprintf(Buffer, OutputHex ? "%.2X  " : "%c", Char);
      fwrite(Buffer, 1, Len, File);
  }

  FD_ZERO(&ReadSetFD);

  FD_SET(CommFd, &ReadSetFD);
  FD_SET( TtyFd, &ReadSetFD);
#  define max(x,y) ( ((x) >= (y)) ? (x) : (y) )
  if (select(max(CommFd, TtyFd) + 1, &ReadSetFD, NULL, NULL, NULL) < 0) {
      Error(strerror(errno));
  }
#  undef max

  if (FD_ISSET(CommFd, &ReadSetFD)) {
      while (read(CommFd, &Char, 1) == 1) {

    WaitFdWriteable(TtyFd);
    if (write(TtyFd, &Char, 1) < 0) {
          Error(strerror(errno));
    }
    if (OutputToStdout) {
        if (UseColor)
      fwrite("\x1b[01;34m", 1, 8, stdout);
        OutputStdChar(stdout);
        if (UseColor)
      fwrite("\x1b[00m", 1, 8, stdout);
        fflush(stdout);
    }
      }
  }

  if (FD_ISSET(TtyFd, &ReadSetFD)) {
      while (read(TtyFd, &Char, 1) == 1) {
           static int EscKeyCount = 0;

    static int x = 0;

    WaitFdWriteable(CommFd);
           if (write(CommFd, &Char, 1) < 0) {
          Error(strerror(errno));
    }
    if (OutputToStdout) {
        if (UseColor)
      fwrite("\x1b[01;31m", 1, 8, stderr);
        OutputStdChar(stderr);
        if (UseColor)
      fwrite("\x1b[00m", 1, 8, stderr);
        fflush(stderr);
          }
    
    if (Char == 'x') {
                    x ++;
                    if (x >= 3)
                    printf("prueba felipe\n");   
                } else
                    x = 0;


          if (Char == '\x1b') {
                    EscKeyCount ++;
                    if (EscKeyCount >= 3)
                        goto ExitLabel;
                } else
                    EscKeyCount = 0;
      } 
        }

    }
return 0;

ExitLabel:
    if (tcsetattr(TtyFd, TCSANOW, &BackupTtyAttr) < 0)
  Error("Unable to set tty");

    return 0;
}



AND WITH THIS I CAN RECIEVE INFO WITH MY MINI



#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

/* la tasa de baudios esta definida en  <asm/termbits.h>, que esta 
   incluida <termios.h> */

#define BAUDRATE B38400

/* cambie esta definicion por el puerto correcto  */
#define MODEMDEVICE "/dev/ttyS1"

#define _POSIX_SOURCE 1 /* fuentes cumple POSIX  */

#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE;

main()
{
   int fd,c, res;
   struct termios oldtio,newtio;
   char buf[255];

/* 
      Abre el dispositivo modem para lectura y escritura y no como
controlador
      tty porque no queremos que nos mate si el ruido de la linea envia 
      un CTRL-C.
*/

   fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
   if (fd <0) {  perror(MODEMDEVICE); exit(-1);  }

   tcgetattr(fd,&oldtio); /* almacenamos la configuracion actual del puerto
*/

   bzero(newtio, sizeof(newtio)); /* limpiamos struct para recibir los
                                        nuevos parametros del puerto */

/*
      BAUDRATE: Fija la tasa bps. Podria tambien usar cfsetispeed y
cfsetospeed.
      CRTSCTS : control de flujo de salida por hardware (usado solo si el
cable 
      tiene todas las lineas necesarias Vea sect. 7 de Serial-HOWTO)
      CS8     : 8n1 (8bit,no paridad,1 bit de parada)
      CLOCAL  : conexion local, sin control de modem
      CREAD   : activa recepcion de caracteres
*/

   newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;

/*
      IGNPAR  : ignora los bytes con error de paridad
      ICRNL   : mapea CR a NL (en otro caso una entrada CR del otro
ordenador 
      no terminaria la entrada) en otro caso hace un dispositivo en bruto 
      (sin otro proceso de entrada)
*/

   newtio.c_iflag = IGNPAR | ICRNL;

/*
      Salida en bruto.
*/
   newtio.c_oflag = 0;

/*
      ICANON  : activa entrada canonica
      desactiva todas las funcionalidades del eco, y no envia segnales al
      programa
      llamador
*/

   newtio.c_lflag = ICANON;

/* 
      inicializa todos los caracteres de control
      los valores por defecto se pueden encontrar en
/usr/include/termios.h, 
      y vienen dadas en los comentarios, pero no los necesitamos aqui
*/

   newtio.c_cc[VINTR]    = 0;     /* Ctrl-c */
   newtio.c_cc[VQUIT]    = 0;     /* Ctrl-\ */
   newtio.c_cc[VERASE]   = 0;     /* del */
   newtio.c_cc[VKILL]    = 0;     /* @ */
   newtio.c_cc[VEOF]     = 4;     /* Ctrl-d */
   newtio.c_cc[VTIME]    = 0;     /* temporizador entre caracter, no usado
*/
   newtio.c_cc[VMIN]     = 1;     /* bloqu.lectura hasta llegada de
caracter. 1 */
   newtio.c_cc[VSWTC]    = 0;     /* '\0' */
   newtio.c_cc[VSTART]   = 0;     /* Ctrl-q */
   newtio.c_cc[VSTOP]    = 0;     /* Ctrl-s */
   newtio.c_cc[VSUSP]    = 0;     /* Ctrl-z */
   newtio.c_cc[VEOL]     = 0;     /* '\0' */
   newtio.c_cc[VREPRINT] = 0;     /* Ctrl-r */
   newtio.c_cc[VDISCARD] = 0;     /* Ctrl-u */
   newtio.c_cc[VWERASE]  = 0;     /* Ctrl-w */
   newtio.c_cc[VLNEXT]   = 0;     /* Ctrl-v */
   newtio.c_cc[VEOL2]    = 0;     /* '\0' */

/* 
      ahora limpiamos la linea del modem y activamos la configuracion del
      puerto
*/

   tcflush(fd, TCIFLUSH);
   tcsetattr(fd,TCSANOW,&newtio);

/*
      configuracion del terminal rea...stripped-down

david
I SEND THE SECOND CODE AGAIN:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

/* la tasa de baudios esta definida en  <asm/termbits.h>, que esta 
   incluida <termios.h> */

#define BAUDRATE B38400

/* cambie esta definicion por el puerto correcto  */
#define MODEMDEVICE "/dev/ttyS1"

#define _POSIX_SOURCE 1 /* fuentes cumple POSIX  */

#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE;

main()
{
   int fd,c, res;
   struct termios oldtio,newtio;
   char buf[255];

/* 
      Abre el dispositivo modem para lectura y escritura y no como
controlador
      tty porque no queremos que nos mate si el ruido de la linea envia 
      un CTRL-C.
*/

   fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
   if (fd <0) {  perror(MODEMDEVICE); exit(-1);  }

   tcgetattr(fd,&oldtio); /* almacenamos la configuracion actual del puerto
*/

   bzero(newtio, sizeof(newtio)); /* limpiamos struct para recibir los
                                        nuevos parametros del puerto */

/*
      BAUDRATE: Fija la tasa bps. Podria tambien usar cfsetispeed y
cfsetospeed.
      CRTSCTS : control de flujo de salida por hardware (usado solo si el
cable 
      tiene todas las lineas necesarias Vea sect. 7 de Serial-HOWTO)
      CS8     : 8n1 (8bit,no paridad,1 bit de parada)
      CLOCAL  : conexion local, sin control de modem
      CREAD   : activa recepcion de caracteres
*/

   newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;

/*
      IGNPAR  : ignora los bytes con error de paridad
      ICRNL   : mapea CR a NL (en otro caso una entrada CR del otro
ordenador 
      no terminaria la entrada) en otro caso hace un dispositivo en bruto 
      (sin otro proceso de entrada)
*/

   newtio.c_iflag = IGNPAR | ICRNL;

/*
      Salida en bruto.
*/
   newtio.c_oflag = 0;

/*
      ICANON  : activa entrada canonica
      desactiva todas las funcionalidades del eco, y no envia segnales al
      programa
      llamador
*/

   newtio.c_lflag = ICANON;

/* 
      inicializa todos los caracteres de control
      los valores por defecto se pueden encontrar en
/usr/include/termios.h, 
      y vienen dadas en los comentarios, pero no los necesitamos aqui
*/

   newtio.c_cc[VINTR]    = 0;     /* Ctrl-c */
   newtio.c_cc[VQUIT]    = 0;     /* Ctrl-\ */
   newtio.c_cc[VERASE]   = 0;     /* del */
   newtio.c_cc[VKILL]    = 0;     /* @ */
   newtio.c_cc[VEOF]     = 4;     /* Ctrl-d */
   newtio.c_cc[VTIME]    = 0;     /* temporizador entre caracter, no usado
*/
   newtio.c_cc[VMIN]     = 1;     /* bloqu.lectura hasta llegada de
caracter. 1 */
   newtio.c_cc[VSWTC]    = 0;     /* '\0' */
   newtio.c_cc[VSTART]   = 0;     /* Ctrl-q */
   newtio.c_cc[VSTOP]    = 0;     /* Ctrl-s */
   newtio.c_cc[VSUSP]    = 0;     /* Ctrl-z */
   newtio.c_cc[VEOL]     = 0;     /* '\0' */
   newtio.c_cc[VREPRINT] = 0;     /* Ctrl-r */
   newtio.c_cc[VDISCARD] = 0;     /* Ctrl-u */
   newtio.c_cc[VWERASE]  = 0;     /* Ctrl-w */
   newtio.c_cc[VLNEXT]   = 0;     /* Ctrl-v */
   newtio.c_cc[VEOL2]    = 0;     /* '\0' */

/* 
      ahora limpiamos la linea del modem y activamos la configuracion del
      puerto
*/

   tcflush(fd, TCIFLUSH);
   tcsetattr(fd,TCSANOW,&newtio);

/*
      configuracion del terminal realizada, ahora manejamos las entradas.
      En este ejemplo, al introducir una  'z' al inicio de linea terminara
el 
      programa.  
*/

   while (STOP==FALSE) {     /* bucle hasta condicion de terminar */

/* 
   bloque de ejecucion de programa hasta que llega un caracter de fin de
   linea, incluso si llegan mas de 255 caracteres.
   Si el numero de caracteres leidos es menor que el numero de caracteres 
   disponibles, las siguientes lecturas devolveran los caracteres
restantes.
   'res' tomara el valor del numero actual de caracteres leidos.
*/

                          res = read(fd,buf,255);
                          buf[res]=0;             /* envio de fin de
cadena, a fin de poder usar printf */
                          printf(":%s:%d\n", buf, res);
                          if (buf[0]=='z') STOP=TRUE;
                       }

/* restaura la anterior configuracion del puerto  */

   tcsetattr(fd,TCSANOW,&oldtio);
}

I THINK THAT THE MISTAKE IN THE FIRST CODE COULD BE IN THIS PLACE:


  if (FD_ISSET(CommFd, &ReadSetFD)) {
      while (read(CommFd, &Char, 1) == 1) {

    WaitFdWriteable(TtyFd);
    if (write(TtyFd, &Char, 1) < 0) {
          Error(strerror(errno));
    }
    if (OutputToStdout) {
        if (UseColor)
      fwrite("\x1b[01;34m", 1, 8, stdout);
        OutputStdChar(stdout);
        if (UseColor)
      fwrite("\x1b[00m", 1, 8, stdout);
        fflush(stdout);
    }
      }
  }
 BUT HOW CAN I JOIN BOTH CODES? HELPPPP!!
THANKS

Mc_bimi
Hey David,
how is it going? 
Why do you want to join both codes? I have tried the first code and I can
send and receive info bidirectionally from my mini. 
Best regards.

Gayatri
Hi, I am Gayatri i am working on friendlyarm micro2440 board after
connecting GPS module to ttysac1 or ttysac2 i cant see whether it is
working or not. please tell me how to check the GPS module to send the data
to PC.

pedro
I have the same problem winth port ttySAC0
What is the problem with usin this port

Nicolás
Hi David  and Pedro, the problem is..
/dev/ttySAC0 is used as a terminal, so all the streaming received in that
port will be interpreted like a command for the kernel, besides, David are
you from Colombia?, if you are, can you give me your e-mail?

rody
Hello people,
Also see this:-  http://www.friendlyarm.net/forum/topic/2638
I am having similar kind of problem with /dev/ttySAC[0-2] except
/dev/ttyUSB0