mirror of
https://github.com/eclipse/upm.git
synced 2025-03-15 04:57:30 +03:00
my9221: rewrite to include new functionality and serve as a base class
This driver has been rewritten to support some new functionality, be more generic and fix up some old bugs. Multiple MY9221's can now be chained together and are supported by the MY9221 base class. In addition, the Grove LED Bar and Grove Circular LED drivers have been incoporated into the my9221 library, using the new MY9221 class as their base class. Examples have been fixed to work with the new library, and renamed where needed. The current grovecircularled driver has been removed as it is now a part of the my9221 library. Signed-off-by: Jon Trulson <jtrulson@ics.com> Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
parent
71b0791239
commit
cbb289438e
@ -43,9 +43,9 @@ int main()
|
||||
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate a Grove Circular LED on gpio pins 5 and 4
|
||||
// Instantiate a Grove Circular LED on D9 for data, D8 for clock
|
||||
|
||||
upm::GroveCircularLED *circle = new upm::GroveCircularLED(5, 4);
|
||||
upm::GroveCircularLED *circle = new upm::GroveCircularLED(9, 8);
|
||||
|
||||
int level = 0;
|
||||
while (shouldRun)
|
||||
@ -54,6 +54,7 @@ int main()
|
||||
level = (level + 1) % 24;
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
//! [Interesting]
|
||||
|
||||
cout << "Exiting" << endl;
|
||||
|
@ -27,37 +27,36 @@
|
||||
#include "my9221.h"
|
||||
#include <signal.h>
|
||||
|
||||
int running = 0;
|
||||
int shouldRun = true;
|
||||
|
||||
void
|
||||
sig_handler(int signo)
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
printf("got signal\n");
|
||||
if (signo == SIGINT) {
|
||||
printf("exiting application\n");
|
||||
running = 1;
|
||||
}
|
||||
if (signo == SIGINT)
|
||||
shouldRun = false;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
//! [Interesting]
|
||||
upm::MY9221 *bar = new upm::MY9221(8, 9);
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
signal(SIGINT, sig_handler);
|
||||
//! [Interesting]
|
||||
upm::MY9221 *bar = new upm::MY9221(8, 9);
|
||||
|
||||
while (!running) {
|
||||
for (int idx = 1; idx < 11; idx++) {
|
||||
bar->setBarLevel (idx);
|
||||
usleep(1000);
|
||||
// Green to Red
|
||||
bar->setBarDirection(true);
|
||||
while (shouldRun)
|
||||
{
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
bar->setBarLevel(i);
|
||||
usleep(250000);
|
||||
}
|
||||
}
|
||||
//! [Interesting]
|
||||
//! [Interesting]
|
||||
|
||||
std::cout << "exiting application" << std::endl;
|
||||
std::cout << "Existing..." << std::endl;
|
||||
|
||||
delete bar;
|
||||
delete bar;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include "my9221.h"
|
||||
#include "groveledbar.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -44,26 +44,25 @@ int main ()
|
||||
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate a MY9221, we use D2 for the data, and D3 for the
|
||||
// data clock. This was tested with a Grove LED bar.
|
||||
|
||||
upm::MY9221* bar = new upm::MY9221(2, 3);
|
||||
// Instantiate a GroveLEDBar, we use D8 for the data, and D9 for the
|
||||
// clock. This was tested with a Grove LED bar.
|
||||
upm::GroveLEDBar* bar = new upm::GroveLEDBar(8, 9);
|
||||
|
||||
while (shouldRun)
|
||||
{
|
||||
// count up from green to red
|
||||
for (int i=1; i<=10; i++)
|
||||
for (int i=0; i<=10; i++)
|
||||
{
|
||||
bar->setBarLevel(i, true);
|
||||
usleep(50000);
|
||||
usleep(100000);
|
||||
}
|
||||
sleep(1);
|
||||
|
||||
// count down from red to green
|
||||
for (int i=1; i<=10; i++)
|
||||
for (int i=0; i<=10; i++)
|
||||
{
|
||||
bar->setBarLevel(i, false);
|
||||
usleep(50000);
|
||||
usleep(100000);
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
@ -71,7 +70,7 @@ int main ()
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
// turn off the LED's
|
||||
bar->setBarLevel(0, true);
|
||||
bar->setBarLevel(0);
|
||||
|
||||
delete bar;
|
||||
return 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
set (libname "my9221")
|
||||
set (libdescription "upm ledbar")
|
||||
set (module_src ${libname}.cxx)
|
||||
set (module_h ${libname}.h)
|
||||
set (libdescription "upm my9221")
|
||||
set (module_src ${libname}.cxx groveledbar.cxx grovecircularled.cxx)
|
||||
set (module_h ${libname}.h groveledbar.h grovecircularled.h)
|
||||
upm_module_init()
|
||||
|
14
src/my9221/TODO
Normal file
14
src/my9221/TODO
Normal file
@ -0,0 +1,14 @@
|
||||
- split up bar and circular methods from my9221 into own libraries
|
||||
|
||||
- add a getLED to match setLED
|
||||
|
||||
- for bar, allow spec (via some method) to a specific bar
|
||||
|
||||
- examples for my9221, keep existing ones for bar and circular
|
||||
|
||||
- warning message if mmap gpio fails and more that 1 instance
|
||||
|
||||
- make sure ctor throws exceptions on gpio setup errors, as well as
|
||||
ensure at least one instance specified.
|
||||
|
||||
- reg map of commandWord bits and provide accessor methods (set/get)
|
94
src/my9221/grovecircularled.cxx
Normal file
94
src/my9221/grovecircularled.cxx
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* These modules were rewritten, based on original work by:
|
||||
*
|
||||
* (original my9221/groveledbar driver)
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* (grovecircularled driver)
|
||||
* Author: Jun Kato and Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Contributions: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "grovecircularled.h"
|
||||
|
||||
using namespace upm;
|
||||
using namespace std;
|
||||
|
||||
GroveCircularLED::GroveCircularLED (uint8_t dataPin, uint8_t clockPin)
|
||||
: MY9221(dataPin, clockPin, 2)
|
||||
{
|
||||
// auto refresh by default
|
||||
setAutoRefresh(true);
|
||||
clearAll();
|
||||
}
|
||||
|
||||
GroveCircularLED::~GroveCircularLED()
|
||||
{
|
||||
}
|
||||
|
||||
void GroveCircularLED::setSpinner(uint8_t position)
|
||||
{
|
||||
if (position > 23)
|
||||
position = 23;
|
||||
|
||||
for (uint8_t i=0; i<(LEDS_PER_INSTANCE * m_instances); i++)
|
||||
m_bitStates[i] = (i == position) ? m_highIntensity : m_lowIntensity;
|
||||
|
||||
if (m_autoRefresh)
|
||||
refresh();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GroveCircularLED::setLevel(uint8_t level, bool direction)
|
||||
{
|
||||
if (level > 23)
|
||||
level = 23;
|
||||
|
||||
if (!direction)
|
||||
{
|
||||
for (int i=0; i<(LEDS_PER_INSTANCE * m_instances); i++)
|
||||
m_bitStates[i] = (i < level) ? m_highIntensity : m_lowIntensity;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0; i<(LEDS_PER_INSTANCE * m_instances); i++)
|
||||
m_bitStates[i] = (((LEDS_PER_INSTANCE * m_instances) - i) <= level)
|
||||
? m_highIntensity : m_lowIntensity;
|
||||
}
|
||||
|
||||
if (m_autoRefresh)
|
||||
refresh();
|
||||
|
||||
return;
|
||||
}
|
96
src/my9221/grovecircularled.h
Normal file
96
src/my9221/grovecircularled.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* These modules were rewritten, based on original work by:
|
||||
*
|
||||
* (original my9221/groveledbar)
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* (grovecircularled)
|
||||
* Author: Jun Kato and Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Contributions: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mraa/common.hpp>
|
||||
#include <mraa/gpio.hpp>
|
||||
#include "my9221.h"
|
||||
|
||||
namespace upm {
|
||||
|
||||
/**
|
||||
* @library my9221
|
||||
* @sensor grovecircularled
|
||||
* @comname Grove Circular LED
|
||||
* @type display
|
||||
* @man seeed
|
||||
* @web http://www.seeedstudio.com/wiki/Grove_-_Circular_LED
|
||||
* @con gpio
|
||||
*
|
||||
* @brief API for the Grove Circular LED module
|
||||
*
|
||||
* This is a circular LED ring based on the MY9221 chip. It is often used
|
||||
* with a rotary encoder and has 24 controllable LEDs.
|
||||
*
|
||||
* @image html grovecircularled.jpg
|
||||
* @snippet grovecircularled.cxx Interesting
|
||||
*/
|
||||
|
||||
class GroveCircularLED : public MY9221 {
|
||||
public:
|
||||
/**
|
||||
* Instantiates an GroveCircularLED object
|
||||
*
|
||||
* @param dataPin Data pin
|
||||
* @param clockPin Clock pin
|
||||
*/
|
||||
GroveCircularLED(uint8_t dataPin, uint8_t clockPin);
|
||||
|
||||
/**
|
||||
* GroveCircularLED destructor
|
||||
*/
|
||||
~GroveCircularLED();
|
||||
|
||||
/**
|
||||
* Sets the spinner (turns off all LEDs but selected one)
|
||||
*
|
||||
* @param position Selected position for the spinner (0-23)
|
||||
*/
|
||||
void setSpinner(uint8_t position);
|
||||
|
||||
/**
|
||||
* Sets the lighting status
|
||||
*
|
||||
* @param level Selected level for the circular LED (0-23)
|
||||
* @param direction Up or down; up is true and default
|
||||
*/
|
||||
void setLevel(uint8_t level, bool direction=true);
|
||||
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
88
src/my9221/groveledbar.cxx
Normal file
88
src/my9221/groveledbar.cxx
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* These modules were rewritten, based on original work by:
|
||||
*
|
||||
* (original my9221/groveledbar driver)
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* (grovecircularled driver)
|
||||
* Author: Jun Kato and Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Contributions: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "groveledbar.h"
|
||||
|
||||
using namespace upm;
|
||||
using namespace std;
|
||||
|
||||
GroveLEDBar::GroveLEDBar (uint8_t dataPin, uint8_t clockPin, int instances)
|
||||
: MY9221(dataPin, clockPin, instances)
|
||||
{
|
||||
// auto refresh by default
|
||||
setAutoRefresh(true);
|
||||
clearAll();
|
||||
}
|
||||
|
||||
GroveLEDBar::~GroveLEDBar()
|
||||
{
|
||||
}
|
||||
|
||||
void GroveLEDBar::setBarLevel(uint8_t level, bool greenToRed, int barNumber)
|
||||
{
|
||||
if (level > 10)
|
||||
level = 10;
|
||||
|
||||
if (barNumber >= m_instances)
|
||||
barNumber = m_instances - 1;
|
||||
|
||||
int start = barNumber * LEDS_PER_INSTANCE;
|
||||
int end = start + LEDS_PER_INSTANCE;
|
||||
|
||||
if (!greenToRed)
|
||||
{
|
||||
for (int i=start; i<end; i++)
|
||||
m_bitStates[i] = (i < (level + start)) ?
|
||||
m_highIntensity : m_lowIntensity;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=start; i<end; i++)
|
||||
m_bitStates[i] = ( ((start + LEDS_PER_INSTANCE) - i) <=
|
||||
(level + 2 + start)) ?
|
||||
m_highIntensity : m_lowIntensity;
|
||||
}
|
||||
|
||||
if (m_autoRefresh)
|
||||
refresh();
|
||||
|
||||
return;
|
||||
}
|
99
src/my9221/groveledbar.h
Normal file
99
src/my9221/groveledbar.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* These modules were rewritten, based on original work by:
|
||||
*
|
||||
* (original my9221/groveledbar)
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* (grovecircularled)
|
||||
* Author: Jun Kato and Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Contributions: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mraa/common.hpp>
|
||||
#include <mraa/gpio.hpp>
|
||||
|
||||
#include "my9221.h"
|
||||
|
||||
namespace upm {
|
||||
|
||||
/**
|
||||
* @library my9221
|
||||
* @sensor groveledbar
|
||||
* @comname Grove LED Bar
|
||||
* @altname MY9221 LED Bar
|
||||
* @type display
|
||||
* @man seeed
|
||||
* @web http://www.seeedstudio.com/wiki/Grove_-_LED_Bar
|
||||
* @con gpio
|
||||
* @kit eak
|
||||
*
|
||||
* @brief API for Grove LED Bars base on the MY9221
|
||||
*
|
||||
* This is a 10-segment LED bar, with 8 green segments, 1 yellow
|
||||
* segment, and one red segment. They can be daisy chained together
|
||||
* so that this module can control multiple LED bars.
|
||||
*
|
||||
* @image html my9221.jpg
|
||||
* @snippet groveledbar.cxx Interesting
|
||||
*/
|
||||
|
||||
class GroveLEDBar : public MY9221 {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Instantiates an GroveLEDBar object
|
||||
*
|
||||
* @param dataPin Data pin
|
||||
* @param clockPin Clock pin
|
||||
* @param instances Number of daisy-chained Grove LED Bars, default 1
|
||||
*/
|
||||
GroveLEDBar(uint8_t dataPin, uint8_t clockPin, int instances=1);
|
||||
|
||||
/**
|
||||
* GroveLEDBar destructor
|
||||
*/
|
||||
~GroveLEDBar();
|
||||
|
||||
/**
|
||||
* Sets the bar level
|
||||
*
|
||||
* @param level Selected level for the bar (0 - 10). 0 is off
|
||||
* @param greenToRed true if you start the level on the first
|
||||
* green LED, false otherwise
|
||||
* @param barNumber If you have multiple LED bars chained
|
||||
* together, this argument selects a specific bar starting at 0.
|
||||
* The default is 0.
|
||||
*/
|
||||
void setBarLevel(uint8_t level, bool greenToRed=true, int barNumber=0);
|
||||
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
@ -1,7 +1,18 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* These modules were rewritten, based on original work by:
|
||||
*
|
||||
* (original my9221/groveledbar driver)
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* (grovecircularled driver)
|
||||
* Author: Jun Kato and Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Contributions: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@ -31,76 +42,150 @@
|
||||
#include "my9221.h"
|
||||
|
||||
using namespace upm;
|
||||
using namespace std;
|
||||
|
||||
MY9221::MY9221 (uint8_t di, uint8_t dcki)
|
||||
: m_clkPinCtx(dcki), m_dataPinCtx(di) {
|
||||
mraa::Result error = mraa::SUCCESS;
|
||||
|
||||
// set direction (out)
|
||||
error = m_clkPinCtx.dir(mraa::DIR_OUT);
|
||||
if (error != mraa::SUCCESS) {
|
||||
mraa::printError(error);
|
||||
MY9221::MY9221 (uint8_t dataPin, uint8_t clockPin, int instances)
|
||||
: m_gpioData(dataPin), m_gpioClk(clockPin), m_bitStates(0)
|
||||
{
|
||||
if (instances < 1)
|
||||
{
|
||||
throw std::out_of_range(std::string(__FUNCTION__) +
|
||||
": instances must be at least 1");
|
||||
}
|
||||
|
||||
// set direction (out)
|
||||
error = m_dataPinCtx.dir(mraa::DIR_OUT);
|
||||
if (error != mraa::SUCCESS) {
|
||||
mraa::printError(error);
|
||||
}
|
||||
// set directions
|
||||
m_gpioClk.dir(mraa::DIR_OUT);
|
||||
m_gpioData.dir(mraa::DIR_OUT);
|
||||
|
||||
// we warn if these fail, since it may not be possible to handle
|
||||
// more than one instance
|
||||
|
||||
if (m_gpioClk.useMmap(true) != mraa::SUCCESS)
|
||||
cerr << __FUNCTION__
|
||||
<< ": Warning: mmap of Clk pin failed, correct operation "
|
||||
<< "may be affected."
|
||||
<< endl;
|
||||
|
||||
if (m_gpioData.useMmap(true) != mraa::SUCCESS)
|
||||
cerr << __FUNCTION__
|
||||
<< ": Warning: mmap of Data pin failed, correct operation "
|
||||
<< "may be affected."
|
||||
<< endl;
|
||||
|
||||
setLowIntensityValue(0x00); // full off
|
||||
setHighIntensityValue(0xff); // full brightness
|
||||
|
||||
m_commandWord = 0x0000; // all defaults
|
||||
m_instances = instances;
|
||||
|
||||
m_bitStates = new uint16_t[instances * LEDS_PER_INSTANCE];
|
||||
|
||||
setAutoRefresh(true);
|
||||
clearAll();
|
||||
}
|
||||
|
||||
mraa::Result
|
||||
MY9221::setBarLevel (uint8_t level, bool direction) {
|
||||
if (level > 10) {
|
||||
return mraa::ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
MY9221::~MY9221()
|
||||
{
|
||||
clearAll();
|
||||
|
||||
send16bitBlock (CMDMODE);
|
||||
if (direction) {
|
||||
level += 3;
|
||||
for(uint8_t block_idx = 12; block_idx > 0; block_idx--) {
|
||||
uint32_t state = (block_idx < level) ? BIT_HIGH : BIT_LOW;
|
||||
send16bitBlock (state);
|
||||
}
|
||||
} else {
|
||||
for(uint8_t block_idx = 0; block_idx < 12; block_idx++) {
|
||||
uint32_t state = (block_idx < level) ? BIT_HIGH : BIT_LOW;
|
||||
send16bitBlock (state);
|
||||
if (!m_autoRefresh)
|
||||
refresh();
|
||||
|
||||
delete m_bitStates;
|
||||
}
|
||||
|
||||
void MY9221::setLED(int led, bool on)
|
||||
{
|
||||
int maxLed = (LEDS_PER_INSTANCE * m_instances) - 1;
|
||||
|
||||
if (led > maxLed)
|
||||
led = maxLed;
|
||||
if (led < 0)
|
||||
led = 0;
|
||||
|
||||
m_bitStates[led] = (on) ? m_highIntensity : m_lowIntensity;
|
||||
|
||||
if (m_autoRefresh)
|
||||
refresh();
|
||||
}
|
||||
|
||||
void MY9221::setLowIntensityValue(int intensity)
|
||||
{
|
||||
m_lowIntensity = (intensity & 0xff);
|
||||
}
|
||||
|
||||
void MY9221::setHighIntensityValue(int intensity)
|
||||
{
|
||||
m_highIntensity = (intensity & 0xff);
|
||||
}
|
||||
|
||||
void MY9221::setAll()
|
||||
{
|
||||
for (int i=0; i<(m_instances * LEDS_PER_INSTANCE); i++)
|
||||
m_bitStates[i] = m_highIntensity;
|
||||
|
||||
if (m_autoRefresh)
|
||||
refresh();
|
||||
}
|
||||
|
||||
void MY9221::clearAll()
|
||||
{
|
||||
for (int i=0; i<(m_instances * LEDS_PER_INSTANCE); i++)
|
||||
m_bitStates[i] = m_lowIntensity;
|
||||
|
||||
if (m_autoRefresh)
|
||||
refresh();
|
||||
}
|
||||
|
||||
void MY9221::refresh()
|
||||
{
|
||||
for (int i=0; i<(m_instances * LEDS_PER_INSTANCE); i++)
|
||||
{
|
||||
if (i % 12 == 0)
|
||||
{
|
||||
send16bitBlock(m_commandWord);
|
||||
}
|
||||
send16bitBlock(m_bitStates[i]);
|
||||
}
|
||||
return lockData ();
|
||||
|
||||
lockData();
|
||||
}
|
||||
|
||||
mraa::Result
|
||||
MY9221::lockData () {
|
||||
mraa::Result error = mraa::SUCCESS;
|
||||
error = m_dataPinCtx.write(LOW);
|
||||
usleep(100);
|
||||
void MY9221::lockData()
|
||||
{
|
||||
m_gpioData.write(0);
|
||||
usleep(220);
|
||||
|
||||
for(int idx = 0; idx < 4; idx++) {
|
||||
error = m_dataPinCtx.write(HIGH);
|
||||
error = m_dataPinCtx.write(LOW);
|
||||
for(int idx = 0; idx < 4; idx++)
|
||||
{
|
||||
m_gpioData.write(1);
|
||||
m_gpioData.write(0);
|
||||
}
|
||||
return error;
|
||||
|
||||
// in reality, we only need > 200ns + (m_instances * 10ns), so the
|
||||
// following should be good for up to m_instances < 80), if the
|
||||
// datasheet is to be believed :)
|
||||
usleep(1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
mraa::Result
|
||||
MY9221::send16bitBlock (short data) {
|
||||
mraa::Result error = mraa::SUCCESS;
|
||||
for (uint8_t bit_idx = 0; bit_idx < MAX_BIT_PER_BLOCK; bit_idx++) {
|
||||
uint32_t state = (data & 0x8000) ? HIGH : LOW;
|
||||
error = m_dataPinCtx.write(state);
|
||||
state = m_clkPinCtx.read();
|
||||
void MY9221::send16bitBlock(uint16_t data)
|
||||
{
|
||||
for (uint8_t bit_idx = 0; bit_idx < 16; bit_idx++)
|
||||
{
|
||||
uint32_t state = (data & 0x8000) ? 1 : 0;
|
||||
m_gpioData.write(state);
|
||||
state = m_gpioClk.read();
|
||||
|
||||
if (state) {
|
||||
state = LOW;
|
||||
} else {
|
||||
state = HIGH;
|
||||
}
|
||||
if (state)
|
||||
state = 0;
|
||||
else
|
||||
state = 1;
|
||||
|
||||
error = m_clkPinCtx.write(state);
|
||||
m_gpioClk.write(state);
|
||||
|
||||
data <<= 1;
|
||||
data <<= 1;
|
||||
}
|
||||
return error;
|
||||
return;
|
||||
}
|
||||
|
@ -1,7 +1,18 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* These modules were rewritten, based on original work by:
|
||||
*
|
||||
* (original my9221/groveledbar)
|
||||
* Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* (grovecircularled)
|
||||
* Author: Jun Kato and Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Contributions: Jon Trulson <jtrulson@ics.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@ -24,77 +35,118 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mraa/aio.hpp>
|
||||
#include <mraa/common.hpp>
|
||||
|
||||
#include <mraa/gpio.hpp>
|
||||
|
||||
#define MAX_BIT_PER_BLOCK 16
|
||||
#define CMDMODE 0x0000
|
||||
#define BIT_HIGH 0x00ff
|
||||
#define BIT_LOW 0x0000
|
||||
|
||||
#define HIGH 1
|
||||
#define LOW 0
|
||||
|
||||
namespace upm {
|
||||
|
||||
/**
|
||||
* @brief MY9221 LED Bar library
|
||||
* @defgroup my9221 libupm-my9221
|
||||
* @ingroup seeed display gpio eak
|
||||
*/
|
||||
/**
|
||||
* @library my9221
|
||||
* @sensor my9221
|
||||
* @comname Grove LED Bar
|
||||
* @altname MY9221 LED Bar
|
||||
* @type display
|
||||
* @man seeed
|
||||
* @web http://www.seeedstudio.com/wiki/Grove_-_LED_Bar
|
||||
* @con gpio
|
||||
* @kit eak
|
||||
*
|
||||
* @brief API for MY9221-based LED Bars
|
||||
*
|
||||
* This module defines the MY9221 interface for libmy9221
|
||||
*
|
||||
* @image html my9221.jpg
|
||||
* @snippet my9221-ledbar.cxx Interesting
|
||||
* @snippet my9221-updown.cxx Interesting
|
||||
*/
|
||||
class MY9221 {
|
||||
public:
|
||||
/**
|
||||
* Instantiates an MY9221 object
|
||||
*
|
||||
* @param di Data pin
|
||||
* @param dcki Clock pin
|
||||
*/
|
||||
MY9221 (uint8_t di, uint8_t dcki);
|
||||
/**
|
||||
* @brief MY9221 LED Controller library
|
||||
* @defgroup my9221 libupm-my9221
|
||||
* @ingroup seeed display gpio eak
|
||||
*/
|
||||
class MY9221 {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Sets the bar level
|
||||
*
|
||||
* @param level Selected level for the bar (1 - 10)
|
||||
* @param direction Up or down; up is true and default
|
||||
*/
|
||||
mraa::Result setBarLevel (uint8_t level, bool direction=true);
|
||||
// 12 LED channels per chip (instance)
|
||||
static const int LEDS_PER_INSTANCE = 12;
|
||||
|
||||
/**
|
||||
* Returns the name of the component
|
||||
*/
|
||||
std::string name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
private:
|
||||
mraa::Result lockData ();
|
||||
mraa::Result send16bitBlock (short data);
|
||||
/**
|
||||
* Instantiates an MY9221 object
|
||||
*
|
||||
* @param dataPin Data pin
|
||||
* @param clockPin Clock pin
|
||||
* @param instances Number of daisy-chained my9221s, default 1
|
||||
*/
|
||||
MY9221(uint8_t dataPin, uint8_t clockPin, int instances=1);
|
||||
|
||||
std::string m_name;
|
||||
mraa::Gpio m_clkPinCtx;
|
||||
mraa::Gpio m_dataPinCtx;
|
||||
};
|
||||
/**
|
||||
* MY9221 destructor
|
||||
*/
|
||||
~MY9221();
|
||||
|
||||
/**
|
||||
* Enable or disable auto refresh. When auto refresh is enabled,
|
||||
* update the LED display as soon as the internal state changes.
|
||||
* When false, the display(s) will not be updated until the
|
||||
* refresh() method is called.
|
||||
*
|
||||
* @param enable true to enable auto refresh, false otherwise
|
||||
*/
|
||||
void setAutoRefresh(bool enable)
|
||||
{
|
||||
m_autoRefresh = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an LED to a specific on (high intensity) or off (low
|
||||
* intensity) value.
|
||||
*
|
||||
* @param led The LED whose state you wish to change
|
||||
* @param on true to turn on the LED, false to turn the LED off
|
||||
*/
|
||||
void setLED(int led, bool on);
|
||||
|
||||
/**
|
||||
* Set the greyscale intensity of an LED in the OFF state. The
|
||||
* intensity is a value from 0 (fully off) to 255 (fully on).
|
||||
* This will take effect on any future LED set or clear
|
||||
* operations.
|
||||
*
|
||||
* @param intensity a value from 0 (fully off) to 255 (fully on)
|
||||
*/
|
||||
void setLowIntensityValue(int intensity);
|
||||
|
||||
/**
|
||||
* Set the greyscale intensity of an LED in the ON state. The
|
||||
* intensity is a value from 0 (fully off) to 255 (fully on).
|
||||
* This will take effect on any future LED set or clear
|
||||
* operations.
|
||||
*
|
||||
* @param intensity a value from 0 (fully off) to 255 (fully on)
|
||||
*/
|
||||
void setHighIntensityValue(int intensity);
|
||||
|
||||
/**
|
||||
* Set all of the LEDS to the ON (high intensity value) state.
|
||||
*/
|
||||
void setAll();
|
||||
|
||||
/**
|
||||
* Set all of the LEDS to the OFF (low intensity value) state.
|
||||
*/
|
||||
void clearAll();
|
||||
|
||||
/**
|
||||
* Set the LED states to match the internal stored states. This
|
||||
* is useful when auto refresh (setAutoRefresh()) is false to
|
||||
* update the display.
|
||||
*/
|
||||
void refresh();
|
||||
|
||||
protected:
|
||||
virtual void lockData();
|
||||
virtual void send16bitBlock(uint16_t data);
|
||||
|
||||
bool m_autoRefresh;
|
||||
// we're only doing 8-bit greyscale, so the high order bits are
|
||||
// always 0
|
||||
uint16_t m_lowIntensity;
|
||||
uint16_t m_highIntensity;
|
||||
|
||||
unsigned int m_instances;
|
||||
|
||||
// an array of uint16_t's representing our bit states (on/off)
|
||||
// intensities. Only the low 8 bits are used, but in the future
|
||||
// 16bit support can work here as well.
|
||||
uint16_t *m_bitStates;
|
||||
|
||||
uint16_t m_commandWord;
|
||||
|
||||
mraa::Gpio m_gpioClk;
|
||||
mraa::Gpio m_gpioData;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user