mirror of
				https://github.com/eclipse/upm.git
				synced 2025-10-30 06:34:58 +03:00 
			
		
		
		
	rgbringcoder: Initial implementation.
Signed-off-by: Jon Trulson <jtrulson@ics.com> Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
		 Jon Trulson
					Jon Trulson
				
			
				
					committed by
					
						 Mihai Tudor Panu
						Mihai Tudor Panu
					
				
			
			
				
	
			
			
			 Mihai Tudor Panu
						Mihai Tudor Panu
					
				
			
						parent
						
							c313e3ae69
						
					
				
				
					commit
					231a1f1b43
				
			
							
								
								
									
										5
									
								
								src/rgbringcoder/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/rgbringcoder/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| set (libname "rgbringcoder") | ||||
| set (libdescription "upm Sparkfun RGB RingCoder") | ||||
| set (module_src ${libname}.cxx) | ||||
| set (module_h ${libname}.h) | ||||
| upm_module_init() | ||||
							
								
								
									
										9
									
								
								src/rgbringcoder/jsupm_rgbringcoder.i
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/rgbringcoder/jsupm_rgbringcoder.i
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| %module jsupm_rgbringcoder | ||||
| %include "../upm.i" | ||||
| %include "stdint.i" | ||||
|  | ||||
| %{ | ||||
|     #include "rgbringcoder.h" | ||||
| %} | ||||
|  | ||||
| %include "rgbringcoder.h" | ||||
							
								
								
									
										9
									
								
								src/rgbringcoder/pyupm_rgbringcoder.i
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/rgbringcoder/pyupm_rgbringcoder.i
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| %module pyupm_rgbringcoder | ||||
| %include "../upm.i" | ||||
|  | ||||
| %feature("autodoc", "3"); | ||||
|  | ||||
| %include "rgbringcoder.h" | ||||
| %{ | ||||
|     #include "rgbringcoder.h" | ||||
| %} | ||||
							
								
								
									
										187
									
								
								src/rgbringcoder/rgbringcoder.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								src/rgbringcoder/rgbringcoder.cxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | ||||
| /* | ||||
|  * Author: Jon Trulson <jtrulson@ics.com> | ||||
|  * Copyright (c) 2015 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 "rgbringcoder.h" | ||||
|  | ||||
| using namespace std; | ||||
| using namespace upm; | ||||
|  | ||||
| RGBRingCoder::RGBRingCoder(int en, int latch, int clear, int clk, int dat,  | ||||
|                            int sw, int encA, int encB, int red,  | ||||
|                            int green, int blue) : | ||||
|   m_gpioEn(en), m_gpioLatch(latch), m_gpioClear(clear), m_gpioClock(clk),  | ||||
|   m_gpioData(dat), m_gpioSwitch(sw), m_gpioEncA(encA), m_gpioEncB(encB), | ||||
|   m_pwmRed(red), m_pwmGreen(green), m_pwmBlue(blue) | ||||
| { | ||||
|   m_counter = 0; | ||||
|  | ||||
|   // enable, set LOW | ||||
|   m_gpioEn.dir(mraa::DIR_OUT); | ||||
|   m_gpioEn.write(0); | ||||
|  | ||||
|   // latch | ||||
|   m_gpioLatch.dir(mraa::DIR_OUT); | ||||
|   m_gpioLatch.write(0); | ||||
|    | ||||
|   // clear, HIGH | ||||
|   m_gpioClear.dir(mraa::DIR_OUT); | ||||
|   m_gpioLatch.write(1); | ||||
|    | ||||
|   // clock | ||||
|   m_gpioClock.dir(mraa::DIR_OUT); | ||||
|   m_gpioClock.write(0); | ||||
|    | ||||
|   // data | ||||
|   m_gpioData.dir(mraa::DIR_OUT); | ||||
|   m_gpioData.write(0); | ||||
|  | ||||
|   // switch | ||||
|   m_gpioSwitch.dir(mraa::DIR_IN); | ||||
|   m_gpioSwitch.mode(mraa::MODE_HIZ);  // no pullup | ||||
|   m_gpioSwitch.write(0); | ||||
|    | ||||
|   // ecoder A interrupt | ||||
|   m_gpioEncA.dir(mraa::DIR_IN); | ||||
|   m_gpioEncA.mode(mraa::MODE_PULLUP); | ||||
|   // EDGE_BOTH would be nice... | ||||
|   m_gpioEncA.isr(mraa::EDGE_RISING, &interruptHandler, this); | ||||
|  | ||||
|   // ecoder B interrupt | ||||
|   m_gpioEncB.dir(mraa::DIR_IN); | ||||
|   m_gpioEncB.mode(mraa::MODE_PULLUP); | ||||
|   // EDGE_BOTH would be nice... | ||||
|   m_gpioEncB.isr(mraa::EDGE_RISING, &interruptHandler, this); | ||||
|  | ||||
|   // RGB LED pwms, set to off | ||||
|  | ||||
|   // Red led | ||||
|   m_pwmRed.period_ms(1); | ||||
|   m_pwmRed.write(0.99); | ||||
|   m_pwmRed.enable(true); | ||||
|  | ||||
|   // Green led | ||||
|   m_pwmGreen.period_ms(1); | ||||
|   m_pwmGreen.write(0.99); | ||||
|   m_pwmGreen.enable(true); | ||||
|  | ||||
|   // Blue led | ||||
|   m_pwmBlue.period_ms(1); | ||||
|   m_pwmBlue.write(0.99); | ||||
|   m_pwmBlue.enable(true); | ||||
|  | ||||
|   // whew. | ||||
| } | ||||
|  | ||||
| RGBRingCoder::~RGBRingCoder() | ||||
| { | ||||
|   m_gpioEncA.isrExit(); | ||||
|   m_gpioEncB.isrExit(); | ||||
|  | ||||
|   // turn off the ring | ||||
|   setRingLEDS(0x0000); | ||||
|  | ||||
|   // Turn of RGB LEDS | ||||
|   setRGBLED(0.99, 0.99, 0.99); | ||||
|   usleep(100000); | ||||
|  | ||||
|   // turn off PWM's | ||||
|   m_pwmRed.enable(false); | ||||
|   m_pwmGreen.enable(false); | ||||
|   m_pwmBlue.enable(false); | ||||
| } | ||||
|  | ||||
| void RGBRingCoder::interruptHandler(void *ctx) | ||||
| { | ||||
|    upm::RGBRingCoder *This = (upm::RGBRingCoder *)ctx; | ||||
|  | ||||
|    // From the Sparkfun guys: | ||||
|  | ||||
|    // enc_states[] is a fancy way to keep track of which direction | ||||
|    // the encoder is turning. 2-bits of oldEncoderState are paired | ||||
|    // with 2-bits of newEncoderState to create 16 possible values. | ||||
|    // Each of the 16 values will produce either a CW turn (1), | ||||
|    // CCW turn (-1) or no movement (0). | ||||
|  | ||||
|    static int8_t enc_states[] = {0, -1, 1, 0, 1, 0, 0, -1, | ||||
|                                  -1, 0, 0, 1, 0, 1, -1, 0}; | ||||
|    static uint8_t oldEncoderState = 0; | ||||
|    static uint8_t newEncoderState = 0; | ||||
|  | ||||
|    // First, find the newEncoderState. This'll be a 2-bit value | ||||
|    // the msb is the state of the B pin. The lsb is the state | ||||
|    // of the A pin on the encoder. | ||||
|    newEncoderState = (This->m_gpioEncB.read()<<1) |  | ||||
|      (This->m_gpioEncA.read()); | ||||
|  | ||||
|    // Now we pair oldEncoderState with new encoder state | ||||
|    // First we need to shift oldEncoder state left two bits. | ||||
|    // This'll put the last state in bits 2 and 3. | ||||
|  | ||||
|    oldEncoderState <<= 2; | ||||
|  | ||||
|    // Mask out everything in oldEncoderState except for the previous state | ||||
|    oldEncoderState &= 0x0c; | ||||
|  | ||||
|    // Now add the newEncoderState. oldEncoderState will now be of | ||||
|    // the form: 0b0000(old B)(old A)(new B)(new A) | ||||
|    oldEncoderState |= newEncoderState; | ||||
|  | ||||
|    // update our counter | ||||
|    This->m_counter += enc_states[oldEncoderState & 0x0f]; | ||||
| } | ||||
|  | ||||
| void RGBRingCoder::setRingLEDS(uint16_t bits) | ||||
| { | ||||
|   // First we need to set latch LOW | ||||
|   m_gpioLatch.write(0); | ||||
|  | ||||
|   // Now shift out the bits, msb first | ||||
|   for (int i=0; i<16; i++) | ||||
|     { | ||||
|       m_gpioData.write( ((bits & 0x8000) ? 1 : 0) ); | ||||
|  | ||||
|       // pulse the clock pin | ||||
|       m_gpioClock.write(1); | ||||
|       m_gpioClock.write(0); | ||||
|  | ||||
|       bits <<= 1; | ||||
|     } | ||||
|  | ||||
|   // latch it | ||||
|   m_gpioLatch.write(1); | ||||
| } | ||||
|  | ||||
| bool RGBRingCoder::getButtonState() | ||||
| { | ||||
|   return (m_gpioSwitch.read() ? true : false); | ||||
| } | ||||
|  | ||||
| void RGBRingCoder::setRGBLED(float r, float g, float b) | ||||
| { | ||||
|   m_pwmRed.write(r); | ||||
|   m_pwmGreen.write(g); | ||||
|   m_pwmBlue.write(b); | ||||
| } | ||||
							
								
								
									
										151
									
								
								src/rgbringcoder/rgbringcoder.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								src/rgbringcoder/rgbringcoder.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | ||||
| /* | ||||
|  * Author: Jon Trulson <jtrulson@ics.com> | ||||
|  * Copyright (c) 2015 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 <iostream> | ||||
| #include <string> | ||||
| #include <stdint.h> | ||||
| #include <unistd.h> | ||||
| #include <mraa/gpio.hpp> | ||||
| #include <mraa/pwm.hpp> | ||||
|  | ||||
|  | ||||
| namespace upm { | ||||
|   /** | ||||
|    * @brief Sparkfun RGB RingCoder | ||||
|    * @defgroup rgbringcoder libupm-rgbringcoder | ||||
|    * @ingroup seeed gpio led | ||||
|    */ | ||||
|  | ||||
|   /** | ||||
|    * @library rgbringcoder | ||||
|    * @sensor rgbringcoder | ||||
|    * @comname Sparkfun RGB Ringcoder | ||||
|    * @type led | ||||
|    * @web https://www.sparkfun.com/products/11040 | ||||
|    * @man sparkfun | ||||
|    * @con pwm gpio | ||||
|    * | ||||
|    * @brief API for the Sparkfun RGB Ringcoder | ||||
|    * | ||||
|    * The RGB RingCoder is a breakout board, a circular LED containing | ||||
|    * 16 LEDs arranged in a ring, and a rotary encoder.  The encoder | ||||
|    * contains an RGB LED as well as a push button function. | ||||
|    * | ||||
|    * The device will require 11 pins, 3 of which must be PWM capable | ||||
|    * (for the RGB LEDs). | ||||
|    * | ||||
|    * @snippet rgbringcoder.cxx Interesting | ||||
|    */ | ||||
|  | ||||
|   class RGBRingCoder { | ||||
|   public: | ||||
|  | ||||
|     /** | ||||
|      * RGBRingCoder constructor | ||||
|      * | ||||
|      * @param en enable gpio | ||||
|      * @param latch latch gpio | ||||
|      * @param clear clear gpio | ||||
|      * @param clk clock gpio | ||||
|      * @param dat data out gpio | ||||
|      * @param sw push button switch gpio | ||||
|      * @param encA encoder A gpio | ||||
|      * @param encB encoder B gpio | ||||
|      * @param red RGB red led pwm | ||||
|      * @param green RGB green led pwm | ||||
|      * @param blue RGB blue led pwm | ||||
|      */ | ||||
|     RGBRingCoder(int en, int latch, int clear, int clk, int dat, int sw,  | ||||
|                  int encA, int encB, int red, int green, int blue); | ||||
|  | ||||
|     /** | ||||
|      * RGBRingCoder Destructor | ||||
|      */ | ||||
|     ~RGBRingCoder(); | ||||
|  | ||||
|     /* | ||||
|      * set the state of the ring LEDs.  This is a 16 bit value, where | ||||
|      * each bit corresponds to one of the ring LEDs.  A 1 bit means | ||||
|      * that specific LED is on, and 0 bit means that specific LED is | ||||
|      * off. | ||||
|      * | ||||
|      * @param bits the bits representing the state of each LED | ||||
|      */ | ||||
|     void setRingLEDS(uint16_t bits); | ||||
|  | ||||
|     /*  | ||||
|      * return the state of the button | ||||
|      * | ||||
|      * @return true if the button is pressed, false otherwise | ||||
|      */ | ||||
|     bool getButtonState(); | ||||
|  | ||||
|     /*  | ||||
|      * get the current rotary encoder counter value | ||||
|      * | ||||
|      * @return the current counter value | ||||
|      */ | ||||
|     int getEncoderPosition() { return m_counter; }; | ||||
|  | ||||
|     /*  | ||||
|      * set the encoder counter to 0 | ||||
|      */ | ||||
|     void clearEncoderPosition() { m_counter = 0; }; | ||||
|  | ||||
|     /*  | ||||
|      * set the intensity of the red, grenn, and blue LEDs.  Values can | ||||
|      * be between 0.0 and 1.0.  Lower is brighter, higher is dimmer. | ||||
|      * | ||||
|      * @param r the red value, valid values are between 0.0 and 1.0 | ||||
|      * @param g the green value, valid values are between 0.0 and 1.0 | ||||
|      * @param b the blue value, valid values are between 0.0 and 1.0 | ||||
|      */ | ||||
|     void setRGBLED(float r, float g, float b); | ||||
|  | ||||
|   private: | ||||
|      | ||||
|     mraa::Gpio m_gpioEn; | ||||
|  | ||||
|     mraa::Gpio m_gpioLatch; | ||||
|     mraa::Gpio m_gpioClear; | ||||
|     mraa::Gpio m_gpioClock; | ||||
|     mraa::Gpio m_gpioData; | ||||
|  | ||||
|     mraa::Gpio m_gpioSwitch; | ||||
|  | ||||
|     mraa::Pwm m_pwmRed; | ||||
|     mraa::Pwm m_pwmGreen; | ||||
|     mraa::Pwm m_pwmBlue; | ||||
|  | ||||
|     mraa::Gpio m_gpioEncA; | ||||
|     mraa::Gpio m_gpioEncB; | ||||
|  | ||||
|     static void interruptHandler(void *ctx); | ||||
|     volatile int m_counter; | ||||
|  | ||||
|   }; | ||||
| } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user