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


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





1 comment:

  1. Thanks for sharing,I learn a lot.I'm using a Beaglebone black + BBVIEW 4.3 LCD Display + Datalogic Magellan 110i usb scanner. The scanner is connected to the usb host port but when i read a bar code the scanner goes down and then up again. The scanner datasheet says that during reading the current goes to a 400ma maximum so it should not be a problem to the USB host port. If i remove the LCD cape i have no power problems. The board is connected to an industrial adjustable power source 2.5A power source used for testing. Is the maximum current available in the USB host related to current for the lcd cape?
    barcode reader for java

    ReplyDelete