Wednesday, 30 April 2014

Using Usb Bar-code Reader with beagle bone and 2x16 LCD Display

As you know, bar-code reader is a special input device for computers to read bar-codes Bar-code reader first scan the bar-code using a light beam( usually a laser beam ) and analyze the width and distance between the bars. After successful scanning it convert the data into ASCII code which can be decoded by our computer. Simply we can say, a bar-code reader are same as that of a keyboard. Both generates the same ASCII code for representing an alphanumeric character.

For more about ascii, read this article.

Here i am using the beagle bone black to read the bar-code and putting it on the 2x16 lcd deiplay.
wen we plug in the bar-code reader it will generates an event under the directory /dev/input/eventX
here X is the number such as 0,1,2,3 etc.



on beagle bone i have found the device event as event 0.
*********************************************************************************
read_barcode.cpp
*********************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include "LCD_2x16.h"

char buffer[256];
char bar_value;

int scan_keyascii()
{
int fd;
struct input_event remote_event;
unsigned char i,k=0;

memset(buffer,' ',sizeof(buffer));

unsigned char kbdus[128] =
{
0,  27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
 '9', '0', '-', '=', '\b', /* Backspace */
 '\t', /* Tab */
 'Q', 'W', 'E', 'R', /* 19 */
 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', '\n', /* Enter key */
0, /* 29   - Control */
 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', /* 39 */
'\'', '`',   0, /* Left shift */
'\\', 'Z', 'X', 'C', 'V', 'B', 'N', /* 49 */
 'M', ',', '.', '/',   0, /* Right shift */
 '*',
0, /* Alt */
 ' ', /* Space bar */
0, /* Caps lock */
0, /* 59 - F1 key ... > */
0,   0,   0,   0,   0,   0,   0,   0,
0, /* < ... F10 */
0, /* 69 - Num lock*/
0, /* Scroll Lock */
0, /* Home key */
0, /* Up Arrow */
0, /* Page Up */
 '-',
0, /* Left Arrow */
0,
0, /* Right Arrow */
 '+',
0, /* 79 - End key*/
0, /* Down Arrow */
0, /* Page Down */
0, /* Insert Key */
0, /* Delete Key */
0,   0,   0,
0, /* F11 Key */
0, /* F12 Key */
0, /* All other keys are undefined */
};
fd = open("/dev/input/event1", O_RDONLY); /* Open the event file */

if(fd == -1) 
{
printf("Can not open the input device!\n");
return 1;
}
else
{
   memset((char *)Buffer_Line1,' ',sizeof(Buffer_Line1));
sprintf((char *)Buffer_Line1,"  Read barcode  ");
LCD_Update_Line(Buffer_Line1,1);
while (1) 
{
read(fd, &remote_event, sizeof(struct input_event)); /* read the last event */
if(remote_event.type == EV_KEY && remote_event.value == 1)
{ /* Check if a key was pressed */

if(remote_event.code==103) 
{ /* Compare with key up code */
printf("Key up was pressed\n");
}
else if(remote_event.code==108) 
{ /* Compare with key down code */
printf("Key down was pressed\n");
}
/* ... */
else
{
if((remote_event.code <= 128) && (remote_event.code != 42))
{
i = kbdus[remote_event.code];

if((i == '\n')||(i == '\r'))
{
buffer[k] = 0;
bar_value = k;
break;
}
else
{

putchar(i);
buffer[k] = i;
k++;
}
}
  }
 
}
}
}

return 0;
}

int main()
{  
    char *buf;
    char buf1[2],LCD_print[16],LCD_print1[16];
    
    int loc = 0;
    int bytesread = 0;
    int lcd_print;    
    bzero(buffer,256);
    printf("reading barcode:");
    scan_keyascii();
    len=(strlen(buffer)-1);
    
    lcd_print = (16-bar_value)/2;
    
    for(n=0;n < lcd_print; n++)
    {
   LCD_print[n]=' ';
}
    
    sprintf((char *)LCD_print1,"%s%s",LCD_print,buffer);
    memset((char *)Buffer_Line1,' ',sizeof(Buffer_Line1));
memcpy(Buffer_Line1,LCD_print1,bar_value+lcd_print);
LCD_Update_Line(Buffer_Line1,2);
    return 0;
}

*********************************************************************************
LCD_2x16.cpp
*********************************************************************************
#include "Beagle_GPIO.hh"
#include "LCD_2x16.h"
#include <iostream>
#include <unistd.h>

Beagle_GPIO        gpio;
unsigned char Buffer_Line1[17] = {"    WELCOME     "};
unsigned char Buffer_Line2[17] = {"   To my blog   "};
unsigned char Data = 0;
unsigned char Lcd_Init_Command[7] = { 0x33,0x32,0x28,0x08,0x01,0x06,0x0C };
unsigned char Temp_Data;

/*****************************************************************************************************/
void LCD_Init()
{
unsigned char i;
gpio.configurePin( Beagle_GPIO::P8_11, Beagle_GPIO::kOUTPUT );
gpio.enablePinInterrupts( Beagle_GPIO::P8_11, false );

gpio.configurePin( Beagle_GPIO::P8_12, Beagle_GPIO::kOUTPUT );
gpio.enablePinInterrupts( Beagle_GPIO::P8_12, false );

gpio.configurePin( Beagle_GPIO::P8_15, Beagle_GPIO::kOUTPUT );
gpio.enablePinInterrupts( Beagle_GPIO::P8_15, false );

gpio.configurePin( Beagle_GPIO::P8_16, Beagle_GPIO::kOUTPUT );
gpio.enablePinInterrupts( Beagle_GPIO::P8_16, false );

gpio.configurePin( Beagle_GPIO::P9_12, Beagle_GPIO::kOUTPUT );
gpio.enablePinInterrupts( Beagle_GPIO::P9_12, false );

gpio.configurePin( Beagle_GPIO::P9_15, Beagle_GPIO::kOUTPUT );
gpio.enablePinInterrupts( Beagle_GPIO::P9_15, false );

LCD_Cmd(0x1); //Clear display 
gpio.writePin( Beagle_GPIO::P9_12, 1 );
for(i=0;i<=6;i++)
{
LCD_Cmd(Lcd_Init_Command[i]);
usleep(5000);
}
}

/*****************************************************************************************************/
void LCD_Cmd(unsigned char cmd)
{
Data = cmd;

LCD178X_LCD_RS_LOW//gpio_set_pin_low(LCD_DI);

Temp_Data = (Data & 0xF0);

if (Temp_Data & 0x10) 
gpio.writePin( Beagle_GPIO::P8_11, 1 );//pin_high(8,11);//gpio_set_pin_high(LCD_DATA0);
else
gpio.writePin( Beagle_GPIO::P8_11, 0 );//pin_low(8,11);//gpio_set_pin_low(LCD_DATA0);

if (Temp_Data & 0x20)
gpio.writePin( Beagle_GPIO::P8_12, 1 );//pin_high(8,12);//gpio_set_pin_high(LCD_DATA1);
else
gpio.writePin( Beagle_GPIO::P8_12, 0 );//pin_low(8,12);//gpio_set_pin_low(LCD_DATA1);

if (Temp_Data & 0x40)
gpio.writePin( Beagle_GPIO::P8_15, 1 );//pin_high(8,15);//gpio_set_pin_high(LCD_DATA2);
else
gpio.writePin( Beagle_GPIO::P8_15, 0 );//pin_low(8,15);//gpio_set_pin_low(LCD_DATA2);

if (Temp_Data & 0x80)
gpio.writePin( Beagle_GPIO::P8_16, 1 );//pin_high(8,16);//gpio_set_pin_high(LCD_DATA3);
else
gpio.writePin( Beagle_GPIO::P8_16, 0 );//pin_low(8,16);//gpio_set_pin_low(LCD_DATA3);

Enable();

Temp_Data = ((Data<<4) & 0xF0);

if (Temp_Data & 0x10)
gpio.writePin( Beagle_GPIO::P8_11, 1 );//pin_high(8,11);//gpio_set_pin_high(LCD_DATA0);
else
gpio.writePin( Beagle_GPIO::P8_11, 0 );//pin_low(8,11);//gpio_set_pin_low(LCD_DATA0);

if (Temp_Data & 0x20)
gpio.writePin( Beagle_GPIO::P8_12, 1 );//pin_high(8,12);//gpio_set_pin_high(LCD_DATA1);
else
gpio.writePin( Beagle_GPIO::P8_12, 0 );//pin_low(8,12);//gpio_set_pin_low(LCD_DATA1);

if (Temp_Data & 0x40)
gpio.writePin( Beagle_GPIO::P8_15, 1 );//pin_high(8,15);//gpio_set_pin_high(LCD_DATA2);
else
gpio.writePin( Beagle_GPIO::P8_15, 0 );//pin_low(8,15);//gpio_set_pin_low(LCD_DATA2);

if (Temp_Data & 0x80)
gpio.writePin( Beagle_GPIO::P8_16, 1 );//pin_high(8,16);//gpio_set_pin_high(LCD_DATA3);
else
gpio.writePin( Beagle_GPIO::P8_16, 0 );//pin_low(8,16);//gpio_set_pin_low(LCD_DATA3);

Enable();
}

/*****************************************************************************************************/
void LCD_Data(unsigned char data)
{
Data = data;

LCD178X_LCD_RS_HIGH //gpio_set_pin_high(LCD_DI);

  Temp_Data = (Data & 0xF0);

if (Temp_Data & 0x10)
gpio.writePin( Beagle_GPIO::P8_11, 1 );//pin_high(8,11);//gpio_set_pin_high(LCD_DATA0);
else
gpio.writePin( Beagle_GPIO::P8_11, 0 );//pin_low(8,11);//gpio_set_pin_low(LCD_DATA0);

if (Temp_Data & 0x20)
gpio.writePin( Beagle_GPIO::P8_12, 1 );//pin_high(8,12);//gpio_set_pin_high(LCD_DATA1);
else
gpio.writePin( Beagle_GPIO::P8_12, 0 );//pin_low(8,12);//gpio_set_pin_low(LCD_DATA1);

if (Temp_Data & 0x40)
gpio.writePin( Beagle_GPIO::P8_15, 1 );//pin_high(8,15);//gpio_set_pin_high(LCD_DATA2);
else
gpio.writePin( Beagle_GPIO::P8_15, 0 );//pin_low(8,15);//gpio_set_pin_low(LCD_DATA2);

if (Temp_Data & 0x80)
gpio.writePin( Beagle_GPIO::P8_16, 1 );//pin_high(8,16);//gpio_set_pin_high(LCD_DATA3);
else
gpio.writePin( Beagle_GPIO::P8_16, 0 );//pin_low(8,16);//gpio_set_pin_low(LCD_DATA3);

Enable();

Temp_Data = ((Data<<4) & 0xF0);

if (Temp_Data & 0x10)
gpio.writePin( Beagle_GPIO::P8_11, 1 );//pin_high(8,11);//gpio_set_pin_high(LCD_DATA0);
else
gpio.writePin( Beagle_GPIO::P8_11, 0 );//pin_low(8,11);//gpio_set_pin_low(LCD_DATA0);

if (Temp_Data & 0x20)
gpio.writePin( Beagle_GPIO::P8_12, 1 );//pin_high(8,12);//gpio_set_pin_high(LCD_DATA1);
else
gpio.writePin( Beagle_GPIO::P8_12, 0 );//pin_low(8,12);//gpio_set_pin_low(LCD_DATA1);

if (Temp_Data & 0x40)
gpio.writePin( Beagle_GPIO::P8_15, 1 );//pin_high(8,15);//gpio_set_pin_high(LCD_DATA2);
else
gpio.writePin( Beagle_GPIO::P8_15, 0 );//pin_low(8,15);//gpio_set_pin_low(LCD_DATA2);

if (Temp_Data & 0x80)
gpio.writePin( Beagle_GPIO::P8_16, 1 );//pin_high(8,16);//gpio_set_pin_high(LCD_DATA3);
else
gpio.writePin( Beagle_GPIO::P8_16, 0 );//pin_low(8,16);//gpio_set_pin_low(LCD_DATA3);

Enable();


/*****************************************************************************************************/
void LCD_Update_Line(unsigned char *Data,unsigned char Num)
{
unsigned char i;

switch(Num)
{
case 1:
LCD_Cmd(0x80);
break;

case 2:
LCD_Cmd(0xC0);
break;

default:
LCD_Cmd(0x80);
break;
}

for(i=0;i<=15;i++)
{
LCD_Data(Data[i]);
}

}

/*****************************************************************************************************/
void Enable()
{
LPC178X_LCD_ENABLE_HIGH
usleep(700);
LPC178X_LCD_ENABLE_LOW
usleep(700);


}

*********************************************************************************
LCD_2x16.h
*********************************************************************************
#include <stdio.h>
#include <stdlib.h>
/*
 * LPC178x/7x processor PORT definitions
 */

/*USED TO ENABLE/DISABLE LCD*/
#define LPC178X_LCD_ENABLE_HIGH gpio.writePin( Beagle_GPIO::P9_12, 1 );
#define LPC178X_LCD_ENABLE_LOW gpio.writePin( Beagle_GPIO::P9_12, 0 );

/*USED TO PUT LCD IN DATA MODE*/
#define LCD178X_LCD_RS_HIGH gpio.writePin( Beagle_GPIO::P9_15, 1 );

/*USED TO PUT LCD IN COMMAND MODE*/
#define LCD178X_LCD_RS_LOW gpio.writePin( Beagle_GPIO::P9_15, 0 );

extern unsigned char  Data_Buffer_Line1[17];
void LCD_Init();
void LCD_Cmd(unsigned char luc_Command);
void LCD_Data(unsigned char luc_Data);
void LCD_Update_Line(unsigned char *Data,unsigned char Num);
void Enable();

*********************************************************************************
Beagle_GPIO.cpp
*********************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

//=======================================================
//=======================================================
 #include "Beagle_GPIO.hh"
//=======================================================
//=======================================================

const int Beagle_GPIO::GPIO_Pin_Bank[] = 
{
-1, -1,  1,  1,  1, // P8_1  -> P8_5
1,  2,  2,  2,  2, // P8_6  -> P8_10
1,  1,  0,  0,  1, // P8_11 -> P8_15
1,  0,  2,  0,  1, // P8_16 -> P8_20
1,  1,  1,  1,  1, // P8_21 -> P8_25
1,  2,  2,  2,  2, // P8_26 -> P8_30
0,  0,  0,  2,  0, // P8_31 -> P9_35
2,  2,  2,  2,  2, // P8_36 -> P8_40
2,  2,  2,  2,  2, // P8_41 -> P8_45
2, // P8_46
-1, -1, -1, -1, -1, // P9_1  -> P9_5
-1, -1, -1, -1, -1, // P9_6  -> P9_10
0,  1,  0,  1,  1, // P9_11 -> P9_15
1,  0,  0,  0,  0, // P9_16 -> P9_20
0,  0,  1,  0,  3, // P9_21 -> P9_25
0,  3,  3,  3,  3, // P9_26 -> P9_30
3, -1, -1, -1, -1, // P9_31 -> P9_35
-1, -1, -1, -1, -1, // P9_36 -> P9_40
0,  0, -1, -1, -1, // P9_41 -> P9_45
-1 // P9_46
};

//=======================================================
//=======================================================

const int Beagle_GPIO::GPIO_Pin_Id[] = 
{
-1, -1,  6,  7,  2, // P8_1  -> P8_5
3,  2,  3,  5,  4, // P8_6  -> P8_10
13, 12, 23, 26, 15, // P8_11 -> P8_15
14, 27,  1, 22, 31, // P8_16 -> P8_20
30,  5,  4,  1,  0, // P8_21 -> P8_25
29, 22, 24, 23, 25, // P8_26 -> P8_30
10, 11,  9, 17,  8, // P8_31 -> P9_35
16, 14, 15, 12, 13, // P8_36 -> P8_40
10, 11,  8,  9,  6, // P8_41 -> P8_45
7, // P8_46
-1, -1, -1, -1, -1, // P9_1  -> P9_5
-1, -1, -1, -1, -1, // P9_6  -> P9_10
30, 28, 31, 18, 16, // P9_11 -> P9_15
19,  5,  4, 13, 12, // P9_16 -> P9_20
3,  2, 17, 15, 21, // P9_21 -> P9_25
14, 19, 17, 15, 16, // P9_26 -> P9_30
14, -1, -1, -1, -1, // P9_31 -> P9_35
-1, -1, -1, -1, -1, // P9_36 -> P9_40
20,  7, -1, -1, -1, // P9_41 -> P9_45
-1 // P9_46
};

//=======================================================
//=======================================================

// Pad Control Register
const unsigned long Beagle_GPIO::GPIO_Pad_Control[] =
{
0x0000, 0x0000, 0x0818, 0x081C, 0x0808, // P8_1  -> P8_5
0x080C, 0x0890, 0x0894, 0x089C, 0x0898, // P8_6  -> P8_10
0x0834, 0x0830, 0x0824, 0x0828, 0x083C, // P8_11 -> P8_15
0x0838, 0x082C, 0x088C, 0x0820, 0x0884, // P8_16 -> P8_20
0x0880, 0x0814, 0x0810, 0x0804, 0x0800, // P8_21 -> P8_25
0x087C, 0x08E0, 0x08E8, 0x08E4, 0x08EC, // P8_26 -> P8_30
0x08D8, 0x08DC, 0x08D4, 0x08CC, 0x08D0, // P8_31 -> P8_35
0x08C8, 0x08C0, 0x08C4, 0x08B8, 0x08BC, // P8_36 -> P8_40
0x08B0, 0x08B4, 0x08A8, 0x08AC, 0x08A0, // P8_41 -> P8_45
0x08A4, // P8_46
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // P9_1  -> P9_5
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // P9_6  -> P9_10
0x0870, 0x0878, 0x0874, 0x0848, 0x0840, // P9_11 -> P9_15
0x084C, 0x095C, 0x0958, 0x097C, 0x0978, // P9_16 -> P9_20
0x0954, 0x0950, 0x0844, 0x0984, 0x09AC, // P9_21 -> P9_25
0x0980, 0x09A4, 0x099C, 0x0994, 0x0998, // P9_26 -> P9_30
0x0990, 0x0000, 0x0000, 0x0000, 0x0000, // P9_31 -> P9_35
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // P9_36 -> P9_40
0x09B4, 0x0964, 0x0000, 0x0000, 0x0000, // P9_41 -> P9_45
0x0000 // P9_46
};

//=======================================================
//=======================================================

const unsigned long Beagle_GPIO::GPIO_Control_Module_Registers = 0x44E10000;

//=======================================================
//=======================================================

const unsigned long Beagle_GPIO::GPIO_Base[] = 
{
0x44E07000, // GPIO0
0x4804C000, // GPIO1
0x481AC000, // GPIO2
0x481AE000 // GPIO3
};

//=======================================================
//=======================================================

Beagle_GPIO::Beagle_GPIO()
{
GPIO_PRINT( "Beagle_GPIO::Beagle_GPIO()" );

// Not initialized by default
m_active = false;

// Opening /dev/mem first
GPIO_PRINT( "Opening /dev/mem" );
m_gpio_fd = open( "/dev/mem", O_RDWR | O_SYNC );
if ( m_gpio_fd < 0 )
{
GPIO_ERROR( "Cannot open /dev/mem" );
return;
}

// Map Control Module 
m_controlModule = (unsigned long *)mmap( NULL, 0x1FFF, PROT_READ | PROT_WRITE, MAP_SHARED, m_gpio_fd, GPIO_Control_Module_Registers );
if ( m_controlModule == MAP_FAILED )
{
GPIO_ERROR( "Control Module Mapping failed" );
return;
}

// Now mapping the GPIO registers
for ( int i=0; i<4; ++i)
{
// Map a GPIO bank
m_gpio[i] = (unsigned long *)mmap( NULL, 0xFFF, PROT_READ | PROT_WRITE, MAP_SHARED, m_gpio_fd, GPIO_Base[i] );
if ( m_gpio[i] == MAP_FAILED )
{
GPIO_ERROR( "GPIO Mapping failed for GPIO Module " << i );
return;
}
}

// Init complete and successfull
m_active = true;

GPIO_PRINT( "Beagle GPIO Initialized" );
}

//=======================================================
//=======================================================

Beagle_GPIO::~Beagle_GPIO()
{
//GPIO_PRINT( "BeAGLe_GPIO::~Beagle_GPIO()" );
if ( m_active && m_gpio_fd)
close( m_gpio_fd );
}

//=======================================================
//=======================================================

// Configure pin as input/output
Beagle_GPIO::Beagle_GPIO_Status Beagle_GPIO::configurePin( unsigned short _pin, Beagle_GPIO_Direction _direction )
{
if ( !m_active )
return kFail;

assert(GPIO_Pin_Bank[_pin]>=0);
assert(GPIO_Pin_Id[_pin]>=0);

// Set Pin as GPIO on the pad control
m_controlModule[GPIO_Pad_Control[_pin]/4] |= 0x07;

unsigned long v = 0x1 << GPIO_Pin_Id[_pin];

if ( _direction == kINPUT)
{
m_gpio[GPIO_Pin_Bank[_pin]][kOE/4] |= v;
}
else
{
m_gpio[GPIO_Pin_Bank[_pin]][kOE/4] &= ~v;
}

// Disable Interrupts by default
m_gpio[GPIO_Pin_Bank[_pin]][kIRQSTATUS_CLR_0/4] |= v;
m_gpio[GPIO_Pin_Bank[_pin]][kIRQSTATUS_CLR_1/4] |= v;

return kSuccess;
}

//=======================================================
//=======================================================

// Enable/Disable interrupts for the pin
Beagle_GPIO::Beagle_GPIO_Status Beagle_GPIO::enablePinInterrupts( unsigned short _pin, bool _enable )
{
if ( !m_active )
return kFail;

assert(GPIO_Pin_Bank[_pin]>=0);
assert(GPIO_Pin_Id[_pin]>=0);

// Set Pin as GPIO on the pad control
m_controlModule[GPIO_Pad_Control[_pin]/4] |= 0x07;

unsigned long v = 0x1 << GPIO_Pin_Id[_pin];

if ( _enable )
{
m_gpio[GPIO_Pin_Bank[_pin]][kIRQSTATUS_SET_0/4] |= v;
m_gpio[GPIO_Pin_Bank[_pin]][kIRQSTATUS_SET_1/4] |= v;
}
else
{
m_gpio[GPIO_Pin_Bank[_pin]][kIRQSTATUS_CLR_0/4] |= v;
m_gpio[GPIO_Pin_Bank[_pin]][kIRQSTATUS_CLR_1/4] |= v;
}

return kSuccess;

}

//=======================================================
//=======================================================

// Write a value to a pin
Beagle_GPIO::Beagle_GPIO_Status Beagle_GPIO::writePin( unsigned short _pin, unsigned char _value )
{
assert(GPIO_Pin_Bank[_pin]>=0);
assert(GPIO_Pin_Id[_pin]>=0);

unsigned long v = (_value & 0x01) << GPIO_Pin_Id[_pin];
unsigned long mask = 0x1 << GPIO_Pin_Id[_pin];

// Remove bit
m_gpio[GPIO_Pin_Bank[_pin]][kDATAOUT/4] &= ~mask;
// Assign new bit value
m_gpio[GPIO_Pin_Bank[_pin]][kDATAOUT/4] |= v;

return kSuccess;
}

//=======================================================
//=======================================================

// Read a value from a pin
unsigned char Beagle_GPIO::readPin( unsigned short _pin )
{
assert(GPIO_Pin_Bank[_pin]>=0);
assert(GPIO_Pin_Id[_pin]>=0);

unsigned long bit = GPIO_Pin_Id[_pin];
return (m_gpio[GPIO_Pin_Bank[_pin]][kDATAIN/4] & (0x1 << bit)) >> bit;
}

//=======================================================
//=======================================================

// Default SPI Device for the beaglebone
static const char *spi_device = "/dev/spidev2.0";

// Open SPI Channel
void Beagle_GPIO::openSPI( unsigned char _mode,
  unsigned char _bits,
  unsigned long _speed,
        unsigned short _delay )
{
GPIO_PRINT( "Opening SPI Device" );
m_spi_fd = open( spi_device, O_RDWR );
if ( m_spi_fd < 0 )
{
GPIO_ERROR( "Error opening SPI Device" );
return;
}

int ret = 0;

// Save settings
m_spi_mode = _mode;
m_spi_bits = _bits;
m_spi_speed = _speed;
m_spi_delay = _delay;

m_spi_buffer_rx = new unsigned char[65536];

// SPI Mode
ret = ioctl(m_spi_fd, SPI_IOC_WR_MODE, &m_spi_mode);
if (ret == -1)
{
GPIO_ERROR( "Error setting SPI Mode");
return;
}

ret = ioctl(m_spi_fd, SPI_IOC_RD_MODE, &m_spi_mode);
if (ret == -1)
{
GPIO_ERROR( "Error getting SPI Mode");
return;
}

// SPI Bits Per Word
ret = ioctl(m_spi_fd, SPI_IOC_WR_BITS_PER_WORD, &m_spi_bits);
if (ret == -1)
{
GPIO_ERROR( "Error setting SPI Bits Per Word");
return;
}

ret = ioctl(m_spi_fd, SPI_IOC_RD_BITS_PER_WORD, &m_spi_bits);
if (ret == -1)
{
GPIO_ERROR( "Error getting SPI Bits Per Word");
return;
}

// SPI Max Speed
ret = ioctl(m_spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &m_spi_speed);
if (ret == -1)
{
GPIO_ERROR( "Error setting SPI Max Speed");
return;
}

ret = ioctl(m_spi_fd, SPI_IOC_RD_MAX_SPEED_HZ, &m_spi_speed);
if (ret == -1)
{
GPIO_ERROR( "Error getting SPI Max Speed");
return;
}

GPIO_PRINT( "SPI Mode : " << std::hex << (int)(m_spi_mode) );
GPIO_PRINT( "SPI Bits Per Word : " << std::dec << (int)(m_spi_bits) );
GPIO_PRINT( "SPI Max Speed : " << std::dec << m_spi_speed );
GPIO_PRINT( "SPI Delay : " << std::dec << m_spi_delay );
GPIO_PRINT( "SPI Opened" );
}

//=======================================================
//=======================================================

// Close SPI Channel
void Beagle_GPIO::closeSPI()
{
if ( m_spi_fd >= 0)
{
GPIO_PRINT( "Closing SPI Device" );
close( m_spi_fd );
delete [] m_spi_buffer_rx;
}
}

//=======================================================
//=======================================================

// Send SPI Buffer
void Beagle_GPIO::sendSPIBuffer( unsigned long _buffer, int _size )
{
assert( m_spi_fd >= 0 );
assert( _buffer > 0 );
assert( _size > 0 );

m_spi_ioc_tr.tx_buf = _buffer;
        m_spi_ioc_tr.rx_buf = (unsigned long)(m_spi_buffer_rx);
  m_spi_ioc_tr.len = _size;
        m_spi_ioc_tr.delay_usecs = m_spi_delay;
        m_spi_ioc_tr.speed_hz = m_spi_speed;
        m_spi_ioc_tr.bits_per_word = m_spi_bits;

if ( ioctl( m_spi_fd, SPI_IOC_MESSAGE(1), &m_spi_ioc_tr ) < 1 )
{
GPIO_ERROR( "Cannot send SPI Buffer, size=" << std::dec << _size );
return;
}
}
*********************************************************************************

Beagle_GPIO.hh
*********************************************************************************
/******************************
** Beagle Bone GPIO Library **
** **
** Francois Sugny **
** 01/07/12 **
** **
** v1.0 **
******************************/

//=======================================================
//=======================================================

#ifndef beagle_gpio_hh
#define beagle_gpio_hh

//=======================================================
//=======================================================

#include <iostream>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

//=======================================================
//=======================================================

#define GPIO_ERROR(msg)        std::cout << "[GPIO] Error : " << msg << std::endl;

#define BEAGLE_GPIO_DEBUG
#ifdef BEAGLE_GPIO_DEBUG
        #define GPIO_PRINT(msg)        std::cout << "[GPIO] : " << msg << std::endl;
        #define assert( condition )         \
                if (!(condition))        \
                {                        \
                        GPIO_ERROR( "Assert Failed in file '" << __FILE__ << "' on line " << __LINE__ );        \
                        exit(0);        \
                }

#else
        #define GPIO_PRINT(msg)
        #define assert( condition )
#endif


//=======================================================
//=======================================================

class Beagle_GPIO
{
public:
        // Return status
        typedef enum
        {
                kFail                 = 0,
                kSuccess         = 1
        } Beagle_GPIO_Status;

        // Beagle Bone GPIO Register Offsets
        enum
        {
                kREVISION                = 0x0,
                kSYSCONFIG                = 0x10,
                kIRQSTATUS_RAW_0        = 0x24,
                kIRQSTATUS_RAW_1        = 0x28,
                kIRQSTATUS_0                = 0x2C,
                kIRQSTATUS_1                = 0x30,
                kIRQSTATUS_SET_0        = 0x34,
                kIRQSTATUS_SET_1        = 0x38,
                kIRQSTATUS_CLR_0        = 0x3C,
                kIRQSTATUS_CLR_1        = 0x40,
                kIRQWAKEN_0                = 0x44,
                kIRQWAKEN_1                = 0x48,
                kSYSSTATUS                = 0x114,
                kCTRL                        = 0x130,
                kOE                        = 0x134,
                kDATAIN                        = 0x138,
                kDATAOUT                = 0x13C,
                kLEVELDETECT0                = 0x140,
                kLEVELDETECT1                = 0x144,
                kRISINGDETECT                = 0x148,
                kFALLINGDETECT                = 0x14C,
                kDEBOUNCEENABLE                = 0x150,
                kDEBOUNCINGTIME                = 0x154,
                kCLEARDATAOUT                = 0x190,
                kSETDATAOUT                = 0x194        
        } Beagle_GPIO_Registers;
        
        // Input/Output pin mode
        typedef enum
        {
                kINPUT        = 0,
                kOUTPUT = 1
        } Beagle_GPIO_Direction;
        
        // GPIO Pins
        enum
        {
                P8_1, P8_2, P8_3, P8_4, P8_5,
                P8_6, P8_7, P8_8, P8_9, P8_10,
                P8_11, P8_12, P8_13, P8_14, P8_15,
                P8_16, P8_17, P8_18, P8_19, P8_20,
                P8_21, P8_22, P8_23, P8_24, P8_25,
                P8_26, P8_27, P8_28, P8_29, P8_30,
                P8_31, P8_32, P8_33, P8_34, P8_35,
                P8_36, P8_37, P8_38, P8_39, P8_40,
                P8_41, P8_42, P8_43, P8_44, P8_45,
                P8_46,
                P9_1, P9_2, P9_3, P9_4, P9_5,
                P9_6, P9_7, P9_8, P9_9, P9_10,
                P9_11, P9_12, P9_13, P9_14, P9_15,
                P9_16, P9_17, P9_18, P9_19, P9_20,
                P9_21, P9_22, P9_23, P9_24, P9_25,
                P9_26, P9_27, P9_28, P9_29, P9_30,
                P9_31, P9_32, P9_33, P9_34, P9_35,
                P9_36, P9_37, P9_38, P9_39, P9_40,
                P9_41, P9_42, P9_43, P9_44, P9_45,
                P9_46
        } GPIO_Pins;
        
        // IO Banks for GPIOs
        static const int GPIO_Pin_Bank[];
        
        // Pin Id for GPIOs
        static const int GPIO_Pin_Id[];

        // Pad Control Register
        static const unsigned long GPIO_Pad_Control[];

        // Base address of Control Module Registers
        static const unsigned long GPIO_Control_Module_Registers;

        // Base addresses of GPIO Modules        
        static const unsigned long GPIO_Base[];
        
public:
        Beagle_GPIO();
        ~Beagle_GPIO();
        
public:
        // Configure pin as input/output
        Beagle_GPIO_Status configurePin( unsigned short _pin, Beagle_GPIO_Direction _direction );

        // Enable/Disable interrupts for the pin
        Beagle_GPIO_Status enablePinInterrupts( unsigned short _pin, bool _enable );

        // Write a value to a pin
        Beagle_GPIO_Status writePin( unsigned short _pin, unsigned char _value );

        // Read a value from a pin
        unsigned char readPin( unsigned short _pin );

        // Open SPI Channel
        void openSPI( unsigned char _mode=0,
                 unsigned char _bits=8,
                 unsigned long _speed=4800000,
                 unsigned short _delay=0 );

        // Close SPI Channel
        void closeSPI();

        // Send SPI Buffer
        void sendSPIBuffer( unsigned long buffer, int size );

        // Is this Module active ?
        bool isActive() { return m_active; }

private:
        bool                        m_active;
        int                        m_gpio_fd;
        unsigned long *                m_controlModule;
        unsigned long *         m_gpio[4];

        int                        m_spi_fd;
        unsigned char *                m_spi_buffer_rx;
        unsigned char                m_spi_mode;
        unsigned char                 m_spi_bits;
        unsigned long                 m_spi_speed;
        unsigned short                 m_spi_delay;
        
        struct spi_ioc_transfer m_spi_ioc_tr;
};

//=======================================================
//=======================================================

#endif


//=======================================================
*********************************************************************************