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.
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();
*********************************************************************************
#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
//=======================================================
*********************************************************************************
*********************************************************************************
#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
//=======================================================
*********************************************************************************