This program is supposed to read acceleration values from a Wii remote and light up LEDs based on those values. The only error I'm getting that prevents compilation is that pBase isn't defined in main.cpp. main.cpp includes ZedBoard.h and ZedBoard.cpp where pBase is defined so I'm failing to see the issue here. I've been trying to solve this for a while and I can't figure it out.
ZedBoard.h
#ifndef ZEDBOARD_H
#define ZEDBOARD_H
const int gpio_led1_offset = 0x12C; // Offset for LED1
const int gpio_led2_offset = 0x130; // Offset for LED2
const int gpio_led3_offset = 0x134; // Offset for LED3
const int gpio_led4_offset = 0x138; // Offset for LED4
const int gpio_led5_offset = 0x13C; // Offset for LED5
const int gpio_led6_offset = 0x140; // Offset for LED6
const int gpio_led7_offset = 0x144; // Offset for LED7
const int gpio_led8_offset = 0x148; // Offset for LED8
const int gpio_sw1_offset = 0x14C; // Offset for Switch 1
const int gpio_sw2_offset = 0x150; // Offset for Switch 2
const int gpio_sw3_offset = 0x154; // Offset for Switch 3
const int gpio_sw4_offset = 0x158; // Offset for Switch 4
const int gpio_sw5_offset = 0x15C; // Offset for Switch 5
const int gpio_sw6_offset = 0x160; // Offset for Switch 6
const int gpio_sw7_offset = 0x164; // Offset for Switch 7
const int gpio_sw8_offset = 0x168; // Offset for Switch 8
const int gpio_pbtnl_offset = 0x16C; // Offset for left push button
const int gpio_pbtnr_offset = 0x170; // Offset for right push button
const int gpio_pbtnu_offset = 0x174; // Offset for up push button
const int gpio_pbtnd_offset = 0x178; // Offset for down push button
const int gpio_pbtnc_offset = 0x17C; // Offset for center push button
// Physical base address of GPIO
const unsigned gpio_address = 0x400d0000;
// Length of memory-mapped IO window
const unsigned gpio_size = 0xff;
// Class Definition
class ZedBoard {
private:
char *pBase; // virtual address where I/O was mapped
int fd; // file descriptor for dev memory
int dummyValue; // for testing without a Zedboard
public:
ZedBoard(); // Default Constructor
~ZedBoard(); // Destructor
void RegisterWrite(char *pBase, int offset, int value);
int RegisterRead(int offset);
void Write1Led(char *pBase, int ledNum, int state);
void WriteAllLeds(int value);
int Read1Switch(int switchNum);
int ReadAllSwitches();
};
#endif
ZedBoard.cpp
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <iostream>
#include "ZedBoard.h"
using namespace std;
/**
* Constructor Initialize general-purpose I/O
* - Opens access to physical memory /dev/mem
* - Maps memory at offset 'gpio_address' into virtual address space
*
* @param None Default constructor does not need arguments.
* @return None Default constructor does not return anything.
*/
ZedBoard::ZedBoard(){
cout << "\nStarting...." << endl;
// dummyValue = 99;
// Uncomment this block of code when connected to the Zedboard
fd = open( "/dev/mem", O_RDWR);
pBase = (char *) mmap(NULL,gpio_size,PROT_READ | PROT_WRITE,
MAP_SHARED,fd,gpio_address);
// Check error
if (pBase == MAP_FAILED)
{
cerr << "Mapping I/O memory failed - Did you run with 'sudo'? \n";
exit(1); // Returns 1 to the operating system;
}
}
/**
* Destructor to close general-purpose I/O.
* - Uses virtual address where I/O was mapped.
* - Uses file descriptor previously returned by 'open'.
*
* @param None Destructor does not need arguments.
* @return None Destructor does not return anything.
*/
ZedBoard::~ZedBoard(){
munmap(pBase, gpio_size);
}
/*
* Write a 4-byte value at the specified general-purpose I/O location.
*
* - Uses base address returned by 'mmap'.
* @parem offset Offset where device is mapped.
* @param value Value to be written.
*/
void ZedBoard::RegisterWrite(char *pBase, int offset, int value)
{
* (int *) (pBase + offset) = value;
// dummyValue = value;
}
/**
* Read a 4-byte value from the specified general-purpose I/O location.
- Uses base address returned by 'mmap'.
@param offset Offset where device is mapped.
@return Value read.
*/
int ZedBoard::RegisterRead(int offset)
{
return * (int *) (pBase + offset);
// return dummyValue;
}
/*
Changes the state of an LED (ON or OFF)
- Uses base address of I/O
@param ledNum LED number (0 to 7)
@param state State to change to (ON or OFF)
*/
/*
Show lower 8 bits of integer value on LEDs
- Calls Write1Led() to set all LEDs
@param value Value to show on LEDs
*/
void ZedBoard::WriteAllLeds(int value)
{
cout << "\nWriting to all LEDs...." << endl;
for(int i = 0; i < 8; i++) {// write to all LEDs
Write1Led(pBase, i, (value / (1<<i)) % 2);
}
}
void ZedBoard::Write1Led(char *pBase, int ledNum, int state)
{
cout << "\nWriting to LED " << ledNum << ": LED state = " << state << endl;
if (ledNum == 1)
{
RegisterWrite(pBase, gpio_led1_offset, state);
}
else
{
RegisterWrite(pBase, gpio_led1_offset + (ledNum * 4), state);
}
}
/*
Reads the value of a switch
- Uses base address of I/O
@param switchNum Switch number (0 to 7)
@return Switch value read
*/
int ZedBoard::Read1Switch(int switchNum)
{
cout << "\nReading Switch " << switchNum << endl;
//return RegisterRead(gpio_sw1_offset + (switchNum * 4));
return switchNum;
}
/*
Reads the switch values into a decimal integer
- Calls Read1Switch() to read all switches
@return Switches' value read
*/
int ZedBoard::ReadAllSwitches()
{
int switchValue = 0;
cout << "\nReading all switches...." << endl;
for(int i = 7; i >= 0; i--) {// read all switches
switchValue = (switchValue << 1) + Read1Switch(i);
}
return switchValue;
}
WiimoteAccel.h
#ifndef WIIMOTEACCEL_H
#define WIIMOTEACCEL_H
class WiimoteAccel{
public:
WiimoteAccel();
~WiimoteAccel();
void Wiimote();
void Listen();
virtual void AccelerationEvent(int code, int acceleration);
private:
int fd;
};
#endif
WiimoteAccel.cpp
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include "ZedBoard.h"
#include "WiimoteAccel.h"
WiimoteAccel::WiimoteAccel()
{
}
WiimoteAccel::~WiimoteAccel()
{
}
void WiimoteAccel::Wiimote()
{
fd = open("/dev/input/event0", O_RDONLY);
if (fd == -1)
{
std::cerr << "Error: Could not open event file - forgot sudo?\n";
exit(1);
}
}
void WiimoteAccel::Listen()
{
for (;;)
{
// Read a packet of 16 bytes from Wiimote
char buffer[16];
read(fd, buffer, 16);
// Extract code (byte 10) and value (byte 12) from packet
int code = buffer[10];
short acceleration = * (short *) (buffer + 12);
this->AccelerationEvent(code, acceleration);
}
}
void WiimoteAccel::AccelerationEvent(int code, int acceleration)
{
// Print them
std::cout << "Code = " << code << ", acceleration = " << acceleration << '\n';
}
main.cpp
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include "WiimoteAccel.h"
#include "ZedBoard.h"
#include "ZedBoard.cpp"
using namespace std;
class WiimoteToLed : public WiimoteAccel {
private:
ZedBoard* zed_board;
public:
WiimoteToLed(ZedBoard* zed_board);
~WiimoteToLed();
void AccelerationEvent(int code, int acceleration)
{
int x = 0;
for(;;)
{
if (code == 3)
{
cout << "ACCELERATION IS "<< acceleration <<"!\n";
if(acceleration == 0)
{
x = 0;
}
else if(acceleration > -100 && acceleration <= -75)
{
x = 1;
}
else if(acceleration > -75 && acceleration <= -50)
{
x = 2;
}
else if(acceleration > -50 && acceleration <= -25)
{
x = 3;
}
else if(acceleration > -25 && acceleration > 0)
{
x = 4;
}
else if(acceleration < 0 && acceleration >= 25)
{
x = 5;
}
else if(acceleration < 25 && acceleration >= 50)
{
x = 6;
}
else if(acceleration < 50 && acceleration >= 75)
{
x = 7;
}
else if(acceleration < 75 && acceleration >= 100)
{
x = 8;
}
switch(x)
{
case 0:
cout << "Wiimote isn't moving\n";
zed_board->Write1Led(pBase,1,0);
zed_board->Write1Led(pBase,2,0);
zed_board->Write1Led(pBase,3,0);
zed_board->Write1Led(pBase,4,0);
zed_board->Write1Led(pBase,5,0);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 1:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,0);
zed_board->Write1Led(pBase,3,0);
zed_board->Write1Led(pBase,4,0);
zed_board->Write1Led(pBase,5,0);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 2:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,0);
zed_board->Write1Led(pBase,4,0);
zed_board->Write1Led(pBase,5,0);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 3:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,0);
zed_board->Write1Led(pBase,5,0);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 4:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,1);
zed_board->Write1Led(pBase,5,0);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 5:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,1);
zed_board->Write1Led(pBase,5,1);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 6:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,1);
zed_board->Write1Led(pBase,5,1);
zed_board->Write1Led(pBase,6,1);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 7:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,1);
zed_board->Write1Led(pBase,5,1);
zed_board->Write1Led(pBase,6,1);
zed_board->Write1Led(pBase,7,1);
zed_board->Write1Led(pBase,8,0);
case 8:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,1);
zed_board->Write1Led(pBase,5,1);
zed_board->Write1Led(pBase,6,1);
zed_board->Write1Led(pBase,7,1);
zed_board->Write1Led(pBase,8,1);
default:
cout << "Code = " << code <<'\n';
}
}
else
{
continue;
}
}
}
};
WiimoteToLed::WiimoteToLed(ZedBoard* zed_board)
{
Wiimote();
}
WiimoteToLed::~WiimoteToLed()
{
}
int main()
{
// Instantiate ZedBoard object statically
ZedBoard zed_board;
// Instantiate WiimoteToLed object statically, passing a pointer to the
// recently created ZedBoard object.
WiimoteToLed wiimote_to_led(&zed_board);
// Enter infinite loop listening to events. The overridden function
// WiimoteToLed::AccelerationEvent() will be invoked when the user moves
// the Wiimote.
wiimote_to_led.Listen();
// Unreachable code, previous function has an infinite loop
return 0;
}
makefile
WiimoteAccel: main.o WiimoteAccel.o
g++ main.o WiimoteAccel.o -o WiimoteAccel
main.o: main.cpp WiimoteAccel.h
g++ -g -Wall -c main.cpp
WiimoteAccel.o: WiimoteAccel.cpp WiimoteAccel.h
g++ -g -Wall -c WiimoteAccel.cpp
clean:
rm main.o WiimoteAccel.o WiimoteAccel