Skip to content

Commit

Permalink
Implemented sleep() in libposix using a busy-loop (temporarily).
Browse files Browse the repository at this point in the history
Added LCDBar device implementation for the GrovePi driver.
Modified BroadcomI2C to use DEBUG() for several lines instead of NOTICE().
Added missing <String.h> in Device.h.
  • Loading branch information
nieklinnenbank committed Nov 4, 2015
1 parent 0d99398 commit 639d8ce
Show file tree
Hide file tree
Showing 7 changed files with 263 additions and 69 deletions.
9 changes: 4 additions & 5 deletions lib/libi2c/BroadcomI2C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,15 @@ BroadcomI2C::Result BroadcomI2C::initialize()

// Detect I2C controller. In Qemu, the ClockDivider is always zero.
if (m_io.read(ClockDivider) == 0)
{

{
return NotFound;
}

// Set a slow clock to attempt workaround the I2C bug in Broadcom 2835
setClockDivider(0x5dc * 3);
NOTICE("I2C GPIO pins set");
NOTICE("ClockDivider is " << m_io.read(ClockDivider));
NOTICE("Status is " << m_io.read(Status));
DEBUG("I2C GPIO pins set");
DEBUG("ClockDivider is " << m_io.read(ClockDivider));
DEBUG("Status is " << m_io.read(Status));

// Done
return Success;
Expand Down
8 changes: 8 additions & 0 deletions lib/libposix/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,14 @@ extern C int chdir(const char *path);
*/
extern C int unlink(const char *path);

/**
* Sleep for the specified number of seconds.
*
* @param seconds Number of seconds to sleep
* @return Zero on success or number of seconds left when interrupted.
*/
extern C unsigned int sleep(unsigned int seconds);

/**
* @}
*/
Expand Down
25 changes: 25 additions & 0 deletions lib/libposix/unistd/sleep.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2009 Niek Linnenbank
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <unistd.h>

unsigned int sleep(unsigned int seconds)
{
// TODO: kernel does not support sleep/wait scheduling yet.
// Temporary busy-loop implementation, which is inaccurate.
for (int i = 0; i < seconds * 1000000; i++);
}
1 change: 1 addition & 0 deletions server/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <Types.h>
#include <errno.h>
#include <String.h>

/**
* Abstract device class interface.
Expand Down
112 changes: 112 additions & 0 deletions server/i2c/grovepi/LCDBar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Copyright (C) 2015 Niek Linnenbank
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <unistd.h>
#include "LCDBar.h"

LCDBar::LCDBar(I2C *i2c)
{
m_i2c = i2c;
m_identifier << "groveLCD";
}

Error LCDBar::initialize()
{
return ESUCCESS;
}

Error LCDBar::write(s8 *buffer, Size size, Size offset)
{
setRGB(0, 255, 0);
setText((const char *) buffer, size);
return size;
}

void LCDBar::textCommand(LCDBar::Command cmd)
{
u8 command[2];

command[0] = 0x80;
command[1] = cmd;

m_i2c->setAddress(TextAddr);
m_i2c->write(command, sizeof(command));
}

void LCDBar::setText(const char *text, Size max)
{
textCommand(ClearDisplay);
sleep(1);

textCommand(DisplayOn | NoCursor);
textCommand(DoubleLine);
sleep(1);

for (uint line = 0; line < 2; line++)
{
for (uint i = 0; i < 16; i++)
{
if (i + (line * 16) >= max)
return;

char v = text[i + (line * 16)];

if (!v)
return;
else if (v == '\n')
{
textCommand(Newline);
break;
}
else
{
u8 command[2];
command[0] = 0x40;
command[1] = v;
m_i2c->write(command, sizeof(command));
}
}
}
}

void LCDBar::setRGB(uint r, uint g, uint b)
{
u8 command[2];
command[0] = 0;
command[1] = 0;
m_i2c->setAddress(0x62);
m_i2c->write(command, sizeof(command)); // 0,0

command[0] = 1;
m_i2c->write(command, sizeof(command)); // 1,0

command[0] = 0x8;
command[1] = 0xaa;
m_i2c->write(command, sizeof(command)); // 0x08,0xaa

command[0] = 4;
command[1] = r;
m_i2c->write(command, sizeof(command)); // 4,r

command[0] = 3;
command[1] = g;
m_i2c->write(command, sizeof(command)); // 3,g

command[0] = 2;
command[1] = b;
m_i2c->write(command, sizeof(command)); // 2,b
}
105 changes: 105 additions & 0 deletions server/i2c/grovepi/LCDBar.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright (C) 2015 Niek Linnenbank
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __SERVER_I2C_GROVEPI_LCDBAR_H
#define __SERVER_I2C_GROVEPI_LCDBAR_H

/**
* @defgroup groveDigi GrovePi LCD Bar
* @{
*/

#include <Macros.h>
#include <Types.h>
#include <Device.h>
#include <I2C.h>

/**
* @brief GrovePi LCD Bar
*
* @see https://github.com/DexterInd/GrovePi/blob/master/Firmware/Source/v1.2/grove_pi_v1_2_5/README.md
*/
class LCDBar : public Device
{
private:

static const uint RGBAddr = 0x62;
static const uint TextAddr = 0x3e;

/**
* LCDBar commands.
*/
enum Command
{
ClearDisplay = 0x01,
NoCursor = 0x04,
DisplayOn = 0x08,
DoubleLine = 0x28,
Newline = 0xc0,
WriteChar = 0x40
};

public:

/**
* @brief Constructor function.
*/
LCDBar(I2C *i2c);

/**
* @brief Initializes the class.
*
* @return Error status code.
*/
virtual Error initialize();

/**
* @brief Set LCD Bar text.
*
* @param buffer Buffer to save the read bytes.
* @param size Number of bytes to read.
* @param offset Offset in the file to read.
* @return Number of bytes on success and ZERO on failure.
*/
virtual Error write(s8 *buffer, Size size, Size offset);

private:

/**
* Set LCD color.
*/
void setRGB(uint r, uint g, uint b);

/**
* Set LCD text.
*/
void setText(const char *text, Size max);

/**
* Send I2C text command.
*/
void textCommand(Command cmd);

/** I2C controller */
I2C *m_i2c;
};

/**
* @}
*/

#endif /* __TIME_TIME_H */
72 changes: 8 additions & 64 deletions server/i2c/grovepi/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,45 +23,15 @@
#include <KernelLog.h>
#include "DigitalPort.h"
#include "AnalogPort.h"

#warning add to libposix with this dummy implementation.
#define sleep(sec) for (int i = 0; i < 1000000; i++);

void setRGB(BroadcomI2C *i2c, uint r, uint g, uint b)
{
u8 command[2];
command[0] = 0;
command[1] = 0;
i2c->setAddress(0x62);
i2c->write(command, sizeof(command)); // 0,0

command[0] = 1;
i2c->write(command, sizeof(command)); // 1,0

command[0] = 0x8;
command[1] = 0xaa;
i2c->write(command, sizeof(command)); // 0x08,0xaa

command[0] = 4;
command[1] = r;
i2c->write(command, sizeof(command)); // 4,r

command[0] = 3;
command[1] = g;
i2c->write(command, sizeof(command)); // 3,g

command[0] = 2;
command[1] = b;
i2c->write(command, sizeof(command)); // 2,b
}
#include "LCDBar.h"

int main(int argc, char **argv)
{
DeviceServer server(CharacterDeviceFile);

// Setup logging
Log *log = new KernelLog();
log->setMinimumLogLevel(Log::Debug);
log->setMinimumLogLevel(Log::Notice);

// Initialize I2C controller
BroadcomI2C *i2c = new BroadcomI2C();
Expand All @@ -80,35 +50,13 @@ int main(int argc, char **argv)
ERROR("failed to initialize I2C controller");
return EXIT_FAILURE;
}
u8 command[4];

// Set RGB LED
setRGB(i2c, 0, 0, 255);
sleep(1);

#if 0
// Send a version command to the GrovePi
command[0] = 8;
command[1] = 0;
command[2] = 0;
command[3] = 0;
i2c->setAddress(0x4);
i2c->write(command, sizeof(command));

// TODO: implement sleep
sleep(1);

// i2c->setAddress(0x4);
// i2c->read(command, 1);
// TODO: Provide /dev/i2c{0,1,2} and let the app set modes directly (TEMP fastest)
// or implement ioctl() support
// or /dev/grove/digi0/{mode | value | ...} with libfs / libdev (BEST)

i2c->setAddress(0x4);
i2c->read(command, sizeof(command));

// Ask firmware version
NOTICE("GrovePi firmware: " << command[1] << "." << command[2] << "." << command[3]);
#endif
#if 1
// Set Digipin 3 to input mode
u8 command[4];
command[0] = 5;
command[1] = 3;
command[2] = 0;
Expand All @@ -124,12 +72,6 @@ int main(int argc, char **argv)
command[3] = 0;
i2c->setAddress(0x4);
i2c->write(command, sizeof(command));

//sleep(1);
//i2c->setAddress(0x4);
//i2c->read(command, 1);
//NOTICE("digi2: " << command[0]);
#endif
}

// Add devices
Expand All @@ -139,6 +81,8 @@ int main(int argc, char **argv)
for (int j = 0; j < 3; j++)
server.add(new AnalogPort(i2c, j));

server.add(new LCDBar(i2c));

// Start serving requests
return server.run(argc, argv);
}

0 comments on commit 639d8ce

Please sign in to comment.