сряда, 28 юли 2010 г.

Demo application - serial port and GPIO control.

These days I've made a project for my FriendlyARM 7" board. 
It demonstrates RS232 data transmission/reception and access to the GPIO pins. To test the serial port I used a serial-to-usb cable. The project seems to work as intended so I decided to share it:
http://rapidshare.com/files/409529027/stivlib_serial_gpio_demo_25JUL2010.zip.html
It can be used as starting point for learning.  The code may be modified and used freely without any waranty.

The whole working folder is included in the archive. Here are the files:

stivlib.pro - the Project file. This is a text file. Source and header files are described in it. If new files have to be added to the project  they must be described in this file

stivlib.png - image file used for icone of the desktop launcher
stivlib.desktop - text file. This is the desktop launcher.
stivlib - binary file. Compiled execteable.
In the previous post was described how to upload these files to the board.

serialport.h serialport.cpp - SerialPort class. It allows sending and recieving serial data and also control of RTS,CTS,DSR,DTR,DCD and RI pins.
gpio.h gpio.cpp - GPIO class. Each instance of this class controls one pin of the GPIO header. Refer to the documentation for the pin functions.  For example pin 31 controls the buzzer.

MainWindow.ui - xml file generated by Qt Creator. May be modified with text editor.


MainWindow.h MainWindow.cpp - here is defined the class of the main form dialog frmMainWindow. Connection between the SIGNALS and SLOTS are implemented here. These files are automaticaly generated with formuic script.   Do not modify them.

MainWindowImp.h MainWindowImp.cpp - In these files frmMainWindowImplementation class inherits frmMainWindow. The functionalyty of the application is implemented in this class.

main.cpp - it contains macroses for generating the application.

formuic - this script runs uic - user interface compiler. This script should be run each time modifications to MainForm.ui are made. New MainWindow.h MainWindow.cpp will be generated

build - this script runs the compiler and bilds the application

Makefile - the Mkefile is automaticaly generated. Do not modify it.



To have access to the GPIO the driver must be included to the linux kernel.
This is a link to compiled image with included drivers for GPIO and SPI. I have not tested the SPI yet.  It's for 7" display!
http://rapidshare.com/files/409529369/zImage-2.6.32.2-mini2440_gpio_spi.html
Great thanks to Eric Brombaugh for his page which helped me to compile and upload the kernel.

http://members.cox.net/ebrombaugh1/embedded/mini2440/index.html

9 коментара:

  1. Hi,
    I have implemented your Serial class, but when i read data using the read function the return value is -1 which means error, how to trace this error. If i implement using dataRecieved funtion there are junk characters in the recieved str variable.

    ОтговорИзтриване
  2. Hello Arun,
    When you say read function probably you mean sp_read.
    SerialPort class reads the data using timer rxTimer. This timer is initialised in the class constructor :
    SerialPort::SerialPort()
    {
    hport=-1;
    //memset(&ttyAttrib,0,sizeof(struct termios));

    //setup the recieving timer. FriendlyARM doesn't support QThread
    rxTimer = new QTimer(this);
    connect(rxTimer, SIGNAL(timeout()), this, SLOT(rxTimerTick()));
    rxTimer->start(TIMER_RX_PERIOD,false); //false- trigger timer repeatedly
    }

    TIMER_RX_PERIOD is defined 50 in serialport.h which means that slot rxTimerTick() is called every 50 milliseconds.

    void SerialPort::rxTimerTick()
    {
    if(hport== -1) return;

    int recievedBytesCount = read(hport,buf,RX_BUFFER_SIZE);
    if(recievedBytesCount < 1) return;
    buf[recievedBytesCount]=0;
    emit dataRecieved(QString(buf));
    }

    If hport is -1 the driver of the file is not open. This function will emit signal only if there is at least one byte received. In the application this way of reading the incoming data is used. In file MainWindowImp.h in the constructor serial port is initialized;

    .....
    .....
    //init the serial port
    int openResult;
    char portName[] = "/dev/ttyUSB0";
    connect(&sp, SIGNAL(dataRecieved(QString)),this,SLOT(dataRecieved(QString)));
    openResult = sp.sp_open(portName);
    if(openResult<1) QMessageBox::information(this,"SERIAL PORT ERROR","Unable to open serial port.",QMessageBox::Ok);
    else
    {
    sp.sp_setPort(B9600,8,'N',1);
    char data[]="The serial port is open ";
    sp.sp_write(data,25);
    }
    ....
    ....

    As you can see if the port is successfuly open a string "The serial port is open " is transmitted.
    Be sure that your serial cable is recognized properly and it appears in /dev folder. I have 3 usb-to-serial cables and one of them is not recognized by the board. I don know why because it works ok on my PC. Be sure the baud rate match. I think that this may be the reason for junk characters.

    If you want to use the sp_read function you should stop the rxTimer because it reads the data each 50ms.
    If sp_read returns -1 I think the reason may be that the serial port driver file is not open. If there is no data received this function should return 0 otherwise it should return the number of bytes received.

    int SerialPort::sp_read(char * rxbuffer, int rxbuffer_size)
    {
    int n = read(hport,rxbuffer,rxbuffer_size);
    return n;
    }

    Did you try sending data?

    ОтговорИзтриване
  3. Hi s_stavrev
    Thanks for the info, will check why the file is not open....because i can transmit data from the board to PC using serial port, but the other direction has this problem(ie read operation).I don't know why.......
    Stopping the rxTimer means commenting the connection line right or shall i use a stop(QTimer::stop()) function to stop the timer.

    ОтговорИзтриване
  4. Yes, just comment tis line
    rxTimer->start(TIMER_RX_PERIOD,false); //false- trigger timer repeatedly

    or this
    vconnect(rxTimer, SIGNAL(timeout()), this, SLOT(rxTimerTick()));

    ОтговорИзтриване
  5. Hi s_stavrev,
    I got it working....the problem was the connection through SAC0 port which starts an emulator when ARM board is switched on....so connected thru SAC1 loop back works fine but there is a mismatch in baudrate.....so the recieved bits are not the same as sent ones.....how to deal with that???

    ОтговорИзтриване
  6. Hi s_stavrev,
    I got it working......there was a mistake on my side during write operation. Thanks for the code once again, i was longing for this type for a long time.

    ОтговорИзтриване
  7. Hi,
    anyone have tried send binary through ftp? On the oryginal Friendly arm image FTP working with no problems but with your kernel is following:

    root@girder-laptop:/home/girder/Demo/stivlib# ftp 192.168.1.230
    Connected to 192.168.1.230.
    220 FriendlyARM FTP server (Version 6.4/OpenBSD/Linux-ftpd-0.17) ready.
    Name (192.168.1.230:girder): root
    331 Password required for root.
    Password:
    530 Login incorrect.
    Login failed.
    ftp>

    ОтговорИзтриване
  8. Hi, i've just solved.
    I've changed new password on my Friendlyarm.

    ОтговорИзтриване
  9. hello, please check the link above.
    I clicked on it to download and receive the message "ERROR: RapidPro expired. (34fa3175) "

    Thank you so much.

    ОтговорИзтриване