This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

UART1 on AM1808 EVM

Other Parts Discussed in Thread: AM1808, OMAP-L138

Hello,

 

I try to work with UART1 on AM1808 EVM.

I have seen the article about it:

http://processors.wiki.ti.com/index.php/Enabling_UART1_on_AM18X/DA850/OMAP-L138_running_Linux

When I transmit data from the EVM I receive only zeros on another side, when I send data from terminal I receive on the EVM also only zeros instead of data - the signal is OK on RS-232/TTL convertor, so it must be some ARM UART internal issue.

It looks like UART 1 is not working.

I use PSP release 03.21.00.04 - it does not look like I need to rebuild the kernel.

Is this correct?

Also I do not use flow control of the serial port, so I do not need to do any additional actions.

Why the port is not working?

What else can I try?

 

Regards,

Slavik

  • I resolved the issue:

    1) I diffed kernel source code and list of patches - all changes are already there.

    No need to rebuild the kernel if you already have latest version.

    2) I did not write termios structure back, this is why serial port did not work.

    It did not affect UART2 because it was already initialized by Linux terminal and I used the same settings.

     

  • Hey, I am having a similar problem on the OMAP L138, I updated my PSP to release 03.21.00.04 then rebuilt the kernel, and tested the UART1 TXD line. I am still just getting a bunch of what seem like random ~4 V spikes when viewed on an o-scope. How did you solve this? Can you explain what you mean by "I did not write termios structure back, this is why serial port did not work."? 

    Thanks,

    Matt

  • Hi Matt,

    There are 2 types of Linux UART examples:

    1) In first case you read settings from port, update important parameters for you and open the port. So effectively you are relying on the existing default values. This is more popular way;

    2) In second case you use empty termios structure and setup all parameters manually, it is more difficult to do.

    In my case, when I was reading from the port - after initialization there were junk values. It is probably related to the way how TI BSP is initialized and I suspect it is different on other Linux distributions.

    Here is my code for reference:

    /* Open serial port */
    void CSerialDrv::init()
    {
        struct termios config;

        m_fd = open(m_strPortName.c_str(), O_RDWR | O_NOCTTY );

        if (m_fd == -1)
        {
            cout << "CSerialDrv failed to open: " << m_strPortName << " port" << endl;
        }
        else
        {
            memset(&config, 0, sizeof(config));                        // Clear serial port configuration
            config.c_cflag |= (CS8 | CREAD | CLOCAL);                // 8N1, see termios.h for more information
            config.c_cflag &= ~CRTSCTS;                                // Disable hardware flow control
            config.c_iflag = IGNPAR;                                  // Ignore parity errors
            config.c_oflag = 0;                                       // Set output flag noncanonical, no processing
            config.c_cc[VTIME] = 0;                                 // Inter-character timer unused
            config.c_cc[VMIN]  = 1;                                 // Blocking read until 1 character arrives
            cfsetospeed(&config, m_speed);                            // 115200 baud
            cfsetispeed(&config, m_speed);                            // 115200 baud
            tcflush(m_fd, TCIFLUSH);                                // Flush serial port buffers
            tcsetattr(m_fd, TCSANOW, &config);                        // Write serial port configuration
        }
    }

    I hope it will help you.

    Cheers,

    Slavik

  • Hi Slavik,

                           We have ported android Froyo on AM1808 processor successfully from sdcard. But my problem is i cant access serial port (read, write) using com port.

    I have downloaded android serial port API (.apk file) from link  http://code.google.com/p/android-serialport-api/downloads/list  . After i installed this .apk file on my android device iam getting force close error.

     i have set permissions too.

    Can you please help me out in this issue. Thanks in advance.

    As per ur code which file i need to change, can you please tell me path and file name.

    Regards

    Pooja.

  • Hi Pooja,

    Thanks a lot for your message.

    I have written serial port driver (it is more like a high-level handler) for Embedded Linux RTOS based on AM1808, not for Android OS.

    I am not sure if this will be the same between Android and Embedded Linux.

    But if you want, I can share source code of my UART driver with you.

    If you need to find out name of the serial port, it is very easy - this is the port as the one that you connect terminal on AM1808.

    I also used UART2, but it is identical to UART1 - all default stdin/stdout is redirected to UART1.

    This is the only difference.

    I did not have problem with permissions on Embedded Linux.

    Regards,

    Slavik

  • Hi Slavik,

                    Thanks alot for your quick response.Do please send me source code so that i will check with mine if any modifications i wil alter according to my hardware and requirement.

    I have buld android kernel on linux platform. I could read data from serial port using command (cat /dev/ttyS1) in linux. but when i am accessing through my android application iam unable to get data as expected. My task is to read continuous GPS data from serial port in android.

    If you have any source code do help me out please. Thanks in advance.

    Regards

    Pooja.

  • Hi Slavik,

                       Is there any command to check or to set property of baudrate, permisssions etc during runtime so that i can read /dev/ttyS1 data.

    Regards

    Pooja.

  • Hi Pooja,

    Here is the source code as I promised.

    Header file:

    #ifndef CSERIALDRV_H_
    #define CSERIALDRV_H_

    // Include files
    #include <stdio.h>
    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include <string.h>
    #include <termios.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include "common.h"


    class CSerialDrv
    {

    private:

        int m_fd;

        std::string m_strPortName;

        unsigned int m_speed;

    public:

        CSerialDrv(std::string strPortName, unsigned int speed = B115200);

        void init();

        ZigBeeMsg_S receive();

        int received();

        int recv(char* buf, int len);

        int send(ZigBeeMsg_S msg);

        int flush();

        int release() {return close(m_fd);}

        ~CSerialDrv() {release();}

    };// END CLASS DEFINITION CSerialDrv


    #endif /* CSERIALDRV_H_ */

    Source file:

    // Include files
    #include "CSerialDrv.h"

    // Name spaces
    using namespace std;

    const char kStartByte        = 0x55;

    /* Default constructor */
    CSerialDrv::CSerialDrv(string strPortName, unsigned int speed)
    {
        m_strPortName     = strPortName;
        m_speed         = speed;

        init();
    }

    /* Open serial port */
    void CSerialDrv::init()
    {
        struct termios config;

        m_fd = open(m_strPortName.c_str(), O_RDWR | O_NOCTTY );

        if (m_fd == -1)
        {
            cout << "CSerialDrv failed to open: " << m_strPortName << " port" << endl;
        }
        else
        {
            memset(&config, 0, sizeof(config));                        // Clear serial port configuration
            config.c_cflag |= (CS8 | CREAD | CLOCAL);                // 8N1, see termios.h for more information
            config.c_cflag &= ~CRTSCTS;                                // Disable hardware flow control
            config.c_iflag = IGNPAR;                                  // Ignore parity errors
            config.c_oflag = 0;                                       // Set output flag noncanonical, no processing
            config.c_cc[VTIME] = 0;                                 // Inter-character timer unused
            config.c_cc[VMIN]  = 1;                                 // Blocking read until 1 character arrives
            cfsetospeed(&config, m_speed);                            // 115200 baud
            cfsetispeed(&config, m_speed);                            // 115200 baud
            tcflush(m_fd, TCIFLUSH);                                // Flush serial port buffers
            tcsetattr(m_fd, TCSANOW, &config);                        // Write serial port configuration
        }
    }

    /* Write data to serial port */
    int CSerialDrv::send(ZigBeeMsg_S msg)
    {
        int ret = 0;
        if (msg.len < MAX_MSG_SIZE)
        {
            ret = write(m_fd, msg.data, msg.len);
            usleep(5*MS);            // Wait at least 5 ms inter-frame delay
        }
        return ret;
    }

    /* Flusg input/output data of the serial port */
    int CSerialDrv::flush()
    {
        int status = 0;
        ioctl(m_fd, TCFLSH, &status);

        return status;
    }

    /* Get number of bytes in the input buffer */
    int CSerialDrv::received()
    {
        int bytes = 0;
        ioctl(m_fd, FIONREAD, &bytes);

        return bytes;
    }

    /* Read data from serial port */
    int CSerialDrv::recv(char* buf, int len)
    {
        return read(m_fd, buf, len);
    }

    /* Read data from serial port */
    ZigBeeMsg_S CSerialDrv::receive(void)
    {
        ZigBeeMsg_S ret;
        char* ptr = ret.data;
        memset(&ret, 0, sizeof(ret));

        ret.data[0] = kStartByte;
        ptr++;
        unsigned int length = 0;
        /* Read message ID and payload length */
        if ((read(m_fd, ptr, 2) == 2))
        {
            length = ret.data[2];
            length = length + 2;    // Read checksum field as well
            ptr = ptr + 2;
        }
        else
        {
            return ret;
        }
        /* Read message payload and checksum */
        if (length < MAX_MSG_SIZE)
        {
            if ((read(m_fd, ptr, length) != (int)length))
            {
                return ret;
            }
        }
        else
        {
            return ret;
        }

        ret.len = ret.data[2] + 5;

        /* No input data */
        return ret;
    }

    I hope it will help.

    Regards,

    Slavik

  • Hi Pooja,

    You can check/change baudrate by reading/writing to termios structure, the same way as it has been done in my source code.

    About permissions - I don't know, there must be some Linux command.

    But I cannot check it, because I do not have AM-1808 board anymore.

    Regards,

    Slavik