Hey Guys!

I Have A Device With a Small LCD Module Like This (http://tiny.cc/gva5pw). And I Have to Write a Code in C To Display Text on The Module ! I Also Have To Run Program in a Minimal Modified Version of FreeBSD ! So Far I Havent Started to Code On My 'OWN' But Some Code That Came With The Manual ..

Code I : lcm.c (This file includes the hardware independent implementation of LCM APIs. All the APIs in this file invoke the hardware dependent functions ‘InitSerialPort( )’, ‘WriteSerial( )’, ‘ReadSerial( )’ and ‘CloseSerialPort( )’ for accessing the serial port)

#include <stdio.h>
#include <curses.h>
#include <unistd.h>
#include "lcm.h"
#include <pthread.h>


pthread_mutex_t mutex;
bool inited=false;
void init();

#define delay(val) usleep(1000*val)

int getKeyLcm()
{ 
  if(!inited) {
    init();
  }
  pthread_mutex_lock(&mutex);
  unsigned char data;
  data = 0xFE;
  writeSerial(&data, 1); //request
  data = 0x0B;
  writeSerial(&data, 1);
  delay(10);
  readSerial(&data, 1);
  pthread_mutex_unlock(&mutex);
  switch(data)
  {
    case 0x0E:
      return UP;
    case 0x0D:
      return RIGHT;
    case 0x0B:
      return LEFT;
    case 0x07:
      return DOWN;
    default:
      return NONE;
  }
}

int displayLcm(bool mode)
{
  if(!inited) {
    init();
  }
  pthread_mutex_lock(&mutex);
  unsigned char data;
  data = 0xFE;
  writeSerial(&data, 1); //request
  if(mode == true)
    data = 0x01;
  else
    data = 0x02;
  writeSerial(&data, 1);
  pthread_mutex_unlock(&mutex);
  return 0;
}

int setPositionLcm(int row, int column)
{
  if(!inited) {
    init();
  }
  if((row != 0) && (row!=1))
    return -1;
  if((column < 0) && (column>15))
    return -1;
  pthread_mutex_lock(&mutex);
  unsigned char data;
  data = 0xFE;
  writeSerial(&data, 1); //request
  data = 0x09;
  writeSerial(&data, 1);
  data = 0x40 * (unsigned char)row + (unsigned char)column;
  writeSerial(&data, 1);
  pthread_mutex_unlock(&mutex);
  return 0;
}

int getPositionLcm(int* row, int* column)
{
  if(!inited) {
    init();
  }
  pthread_mutex_lock(&mutex);
  unsigned char data;
  data = 0xFE;
  writeSerial(&data, 1); //request
  data = 0x0A;
  writeSerial(&data, 1);
  delay(10);
  readSerial(&data, 1);
  if(data >= 0x40)
    *row = 1;
  else
    *row = 0;
  *column = data & 0x0F;
  pthread_mutex_unlock(&mutex);
  return 0;
}

int cursorLcm(bool mode)
{
  if(!inited) {
    init();
  }
  pthread_mutex_lock(&mutex);
  unsigned char data;
  data = 0xFE;
  writeSerial(&data, 1); //request
  if( mode == true )
    data = 0x05;
  else
    data = 0x06;
  writeSerial(&data, 1);
  pthread_mutex_unlock(&mutex);
  return 0;
}

int cursorActionLcm(int type)
{
  if(!inited) {
    init();
  }
  unsigned char data;
  int row, column;
  getPositionLcm(&row, &column);
  switch(type)
  {
    case HOME:
      setPositionLcm(0, 0);
      break;
    case MOVERIGHT:
      if(column < 15)
        column ++;
      setPositionLcm(row, column);
      break;
    case MOVELEFT:
      if(column > 0)
        column --;
      setPositionLcm(row, column);
      break;
    case MOVEBACK:
      if(column > 0)
        column --; 
      printf("row = %d, column = %d\n",row,column);
      setPositionLcm(row, column);
      data = ' ';
      showLcm(1, &data );
      setPositionLcm(row, column);
  }
  return 0;
}

int clrscrLcm()
{
  if(!inited) {
    init();
  }
  pthread_mutex_lock(&mutex);
  unsigned char data;
  data = 0xFE;
  writeSerial(&data, 1); //request
  data = 0x03;
  writeSerial(&data, 1);
  pthread_mutex_unlock(&mutex);
  return 0;
}

int showLcm(int length, unsigned char* info)
{
  if(!inited) {
    init();
  }
  unsigned char data;
  int row, column;
  int i;
  getPositionLcm(&row, &column);
  if(length + column > 15)
    length = 16 - column;
  pthread_mutex_lock(&mutex);
  for(i = 0; i < length; i++) {
    data = *(info + i);
    writeSerial(&data, 1); 
  }
  pthread_mutex_unlock(&mutex);
  if(column + length >=16)
    setPositionLcm(row, 15);
  return 0;
}

void init()
{
  unsigned char start[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0xfe,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
  int i;
  unsigned char data;
  //init magic words
  initSerialPort(2);
  writeSerial(start, 16);
  pthread_mutex_init(&mutex, NULL);
  inited = true;

}

CODE II : lcm.h (This file includes the declarations and macro definitions needed by lcm.c.)

/* Type Definition */
typedef char           i8;
typedef unsigned char  u8;
typedef short          i16;
typedef unsigned short u16;
typedef unsigned long  u32;
typedef int            i32;


i32 displayLcm(bool mode);
i32 setPositionLcm(i32 row, i32 column);
i32 getPositionLcm(i32 *row, i32 *column);
i32 cursorLcm(bool mode);
i32 cursorActionLcm(i32 type);
i32 clrscrLcm(void);
i32 showLcm(i32 length, u8* info);
i32 getKeyLcm(void);


#define HOME 0x01
#define MOVERIGHT 0x02
#define MOVELEFT 0x03
#define MOVEBACK 0x04

#define UP 0x01
#define DOWN 0x02
#define RIGHT 0x03
#define LEFT  0x04

#define NONE

Code III : lcmdemo.c (This file is the source code of the demo program. This program displays the user interface, processes user’s input, and invokes LCM APIs to demonstrates the functions of LCM.)

#include "serialport.h"
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <term.h>
#include <curses.h>
#include <unistd.h>
#include "lcm.h"
#include <pthread.h>

extern struct termios oldtio, newtio;
extern int fd;

int gettingKey = 0;
void* buttonThread(void* arg);

void GP()
{
  int row, column;
  getPositionLcm(&row, &column);
  printf("Cursor is located on row %d, column %d now.\n", row, column);
}

void SP()
{
  int row, column;
  int ret;
  printf("Please input row:[0,1]");
  scanf("%d", &row);
  printf("Please input column:[0-15]");
  scanf("%d", &column);
  ret = setPositionLcm(row, column);
  if(ret < 0)
    printf("Input data incorrect!!\n");
}

void DON()
{
  printf("Turn display on now!\n");
  displayLcm(true);
}

void DOFF()
{
  printf("Turn display off now!\n");
  displayLcm(false);
}

void CON()
{
  printf("Show cursor now!\n");
  cursorLcm(true);
}

void COFF()
{
  printf("Don't show cursor now!\n");
  cursorLcm(false);
}

void CH()
{
  printf("Cursor is moved to home position now!\n");
  cursorActionLcm(HOME);
}

void CMR()
{
  printf("Cursor is moved to next column now!\n");
  cursorActionLcm(MOVERIGHT);
}

void CML()
{
  printf("Cursor is moved to previous column now!\n");
  cursorActionLcm(MOVELEFT);
}

void CMB()
{
  printf("Cursor is backspaced now!\n");
  cursorActionLcm(MOVEBACK);
}

void CLR()
{
  printf("LCM is cleared!\n");
  clrscrLcm();
}
struct _FuncTable {
  void (*func)();
  const char str[255];
};

static struct _FuncTable FuncTable[]=
{
  {GP,    "Get Cursor Position",},
  {SP,    "Set Cursor Position",},
  {DON,   "Turn On LCM Display",},
  {DOFF,  "Turn Off LCM Display",},
  {CON,   "Turn On LCM Cursor",},
  {COFF,  "Turn Off LCM Cursor",},
  {CH,    "Move Cursor Home",},
  {CMR,   "Move Cursor Right",},
  {CML,   "Move Cursor Left",},
  {CMB,   "Backspace",},
  {CLR,   "Clear LCM Screen",},
};

int main()
{
  unsigned char msg_demo[] ="Mohammed Sherif"; //screen is 16 char wide
  unsigned char msg_bye[] =" Bye Bye ^_^ ";
  unsigned char msg_clr[] ="                ";
  pthread_t th;
  int cmd,i;
  unsigned char input[255];
  clrscrLcm();
  cursorActionLcm(HOME);
  showLcm(16, msg_demo);
    gettingKey = 1;
  pthread_create(&th, NULL, buttonThread, NULL);
  printf("   Acrosser LCM Demo Program\n");
  while(1) {
    printf("\n");
    printf("   ========== MENU =========\n");
    printf("   (0) Exit\n");
    for(i = 0; i < (sizeof(FuncTable) / sizeof(FuncTable[0])); i++) {
      printf("   (%d) ",i+1);
      printf(FuncTable[i].str);
      printf("\n");
    }
    printf("   =========================\n");
CMD_RETRY:
    printf("  >> ");
    scanf("%s",input);
    cmd=atoi(input);
    if ((cmd < 0) || (cmd > ( sizeof(FuncTable) / sizeof(FuncTable[0]) )))
      goto CMD_RETRY;
    if (cmd == 0) {
            gettingKey = 0; 
      break;
        }
    (*(FuncTable[cmd-1].func))();
  }
  setPositionLcm(1, 0);
  showLcm(16, msg_clr);
  setPositionLcm(1, 0);
  showLcm(13, msg_bye);

    pthread_join( th, NULL);
    tcsetattr(fd, TCSANOW, &oldtio);              
  printf("Test finished\n");

    exit(0);
}

void* buttonThread(void* arg)
{
  unsigned char key;
  unsigned char msg_up[] =" Up pushed ";
  unsigned char msg_down[] =" Down pushed ";
  unsigned char msg_left[]=" Left pushed ";
  unsigned char msg_right[] =" Right pushed ";
  unsigned char msg_clr[] ="                ";

  while(gettingKey) {
    usleep(20);
    key = getKeyLcm();
    switch(key) {
      case UP:
        printf("Up button\n");
        setPositionLcm(1, 0);
        showLcm(16, msg_clr);
        setPositionLcm(1, 0);
        showLcm(11, msg_up);
        break;
      case DOWN:
        printf("Down button\n");
        setPositionLcm(1, 0);
        showLcm(16, msg_clr);
        setPositionLcm(1, 0);
        showLcm(13, msg_down);
        break;
      case LEFT:
        printf("Left button\n");
        setPositionLcm(1, 0);
        showLcm(16, msg_clr);
        setPositionLcm(1, 0);
        showLcm(13, msg_left);
        break;
      case RIGHT:
        printf("Right button\n");
        setPositionLcm(1, 0);
        showLcm(16, msg_clr);
        setPositionLcm(1, 0);
        showLcm(14, msg_right);
        break;
      default:
        break;
    }
  }

    pthread_exit(NULL);

}

Code IV : Makefile (This is the instruction script for GNU make system.)

AP_NAME = lcmdemo
LIB_NAME = serialport lcm
CC = gcc
INCLUDEDIR = $(KERNELDIR)/include
CFLAGS = -O2 -fomit-frame-pointer -I$(INCLUDEDIR) -L/usr/lib -lpthread 
LFLAGNELDIR ?= /lib/modules/$(shell uname -r)/build

PRJ_OBJS = ${AP_NAME}.o $(LIBSOURCES:.c=.o)

APSOURCES = ${AP_NAME}.c
LIBSOURCES = $(LIB_NAME:=.c)

LIB_OBJS = $(LIB_NAME:=.o)
all: clean ap

ap: ${PRJ_OBJS}
    $(CC) $(CFLAGS) ${LFLAGS} -o ${AP_NAME} ${AP_NAME}.o ${LIB_OBJS}

clean:

rm -f ${AP_NAME} .o *.so *.a *.so. *~ core

Code V : serialport.c(This file includes the hardware dependent implementation of ‘InitSerialPort( )’, ‘WriteSerial( )’, ‘ReadSerial( )’ and ‘CloseSerialPort( )’ for accessing the serial port.)

//#include "tools.h"
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>

#define BAUDRATE B19200
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1                 //POSIX compliant source

#define DWORD unsigned long
#define FALSE 0
#define TRUE 1

#define SLEEP(x) usleep(x*10)
#define READ_TIMEOUT_UNIT  2            // units:READ_TIMEOUT_UNIT(ms)
#define READ_TIMEOUT_CNT   5 

char message[256];
volatile int STOP = FALSE;
void signal_handler_IO (int status);    //definition of signal handler
int wait_flag=TRUE;                     //TRUE while no signal received
char devicename[80];
long Baud_Rate = 19200;                 // default Baud Rate (110 through 38400)
long BAUD;                              // derived baud rate from command line
long DATABITS;
long STOPBITS;
long PARITYON;
long PARITY;
int Data_Bits = 8;              // Number of data bits
int Stop_Bits = 1;              // Number of stop bits
int Parity = 0;                 // Parity as follows: 
                // 00 = NONE, 01 = Odd, 02 = Even, 03 = Mark, 04 = Space
int Format = 4;
int status;
int fd;

struct termios oldtio, newtio;

int initSerialPort(unsigned short usCOM_Num)
{
    int c, i, error;
    char In1, Key;
//  struct termios oldtio, newtio;
    struct sigaction saio;               //definition of signal action
    char buf[255];                       //buffer for where data is put
    sprintf(devicename, "/dev/ttyS%01d", usCOM_Num - 1);
    BAUD =  B9600;
    DATABITS = CS8;
    PARITYON = 0;
    STOPBITS = 0;
        fd = open(devicename, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd < 0)
        {
                perror(devicename);
                sprintf(message,"Open %s fail!!\r\n",devicename);
                fd = 0;
                return 0;
        }

    //install the serial handler before making the device asynchronous
    tcgetattr(fd, &oldtio);     // save current port settings 
//debug 
//  cfsetispeed(&newtio, B9600);
//  cfsetospeed(&newtio, B9600); 
    newtio = oldtio; 
    newtio.c_cflag = (BAUD | CS8 | CREAD | CLOCAL | HUPCL);// | DATABITS | STOPBITS);
    newtio.c_iflag = IGNPAR;
    newtio.c_oflag = 0;
    newtio.c_lflag = 0;        //ICANON;
    newtio.c_cc[VMIN]=1;
    newtio.c_cc[VTIME]=0;
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &newtio);              
    int n;
    for(n=0; n < 3; n++)
    {
        tcflush(fd, TCIOFLUSH);
        usleep(100000);
    }
    return fd;
} //end of initSerialPort

/*int writeSerial(unsigned char *buf, int bufsize)
{
    int  bytes_sent = 0;
    int  attempts = 0;
    int  max_send_attempts = 100;
    while( 1 )
    {
        int actualy_bytes_sent = write(fd, buf+bytes_sent, bufsize-bytes_sent);
        if(actualy_bytes_sent == -1 )
        {
            if( errno == EAGAIN )
            {
                if( attempts < max_send_attempts)
                {
                    usleep(10000); // 100 ms
                    attempts++;
                }
                else
                {
                    return bytes_sent;
                }
                continue;
            }
            else
            {
                return -1;
            }
        } else {
            attempts = 0;
        }

        bytes_sent += actualy_bytes_sent;
        if( bytes_sent == bufsize )
            break;
        if( bytes_sent > bufsize )
            return -1;
        usleep(1);
    }
    return bytes_sent;
}
*/

int readSerial(unsigned char *buf, int bufsize)
{
    int bytes_available;
    int attempt = 0;
    int max_read_attempt = 1000;
    while( 1 )
    {
        ioctl(fd, FIONREAD, &bytes_available );
        if(bytes_available < bufsize)
        {
            if( attempt < max_read_attempt )
            {
                usleep(1000);
                attempt++;
            }
            else
            {
                break;
            }
        }
        else
        {
            bytes_available = bufsize;
            break;
        }       
    }

    if( bytes_available > 0 )
    {
        bufsize=read(fd, buf, bytes_available);
        return bufsize;
    }
    return bytes_available;
}

void CloseSerialPort()
{
    close(fd);        //close the com port
}

void signal_handler_IO (int status)
{
    wait_flag = FALSE;

}

Code VI : serialport.h (This file includes the declarations and macro definitions needed by serialport.c.)

#ifndef __SERIALPORT_H_
#define __SERIALPORT_H_
#define readByte(buff)  readSerial((unsigned char *)buff, 1)
#define writeByte(buff) writeSerial((unsigned char *)buff, 1)
int initSerialPort(unsigned short usCOM_Num);
int writeSerial(unsigned char *buf,int bufsize);
int readSerial(unsigned char *buf,int bufsize);
void CloseSerialPort();
#endif

These are all the Codes! :/ , I dont think these are going to work but I Just Gave them to you guys , If Anyone Can Come up with any good solutions it would be really Nice of you

Thank you! :)

You are probably going to have to pay someone to write the program for you. And you will have to give him/her one of those modules to work with so that the program can be tested. Therre are many freelance web sites where you can hire a programmer.

So Far I Havent Started to Code On My 'OWN'

What are you waiting for? Get started! Cheapest way, and you learn something too ;-)

You are probably going to have to pay someone to write the program for you. And you will have to give him/her one of those modules to work with so that the program can be tested. Therre are many freelance web sites where you can hire a programmer.

Ancient Dragon ! Sorry Man I Cant Do that Because I Dont Have Any money ! :P I'm Broke!

I know this was two years ago, but I'm trying to do the same thing, with probably the same exact LCM you were working with, and on FreeBSD. Any chance you could share with you came up with, or point me in the right direction?

Thanks!

This question has already been answered. Start a new discussion instead.