1 /* 2 * Author: Jun Kato and Yevgeniy Kiveisha <yevgeniy.kiveisha (at) intel.com> 3 * Contributions: Jon Trulson <jtrulson (at) ics.com> 4 * Copyright (c) 2015 Intel Corporation. 5 * 6 * This module is based on the my9221 driver 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining 9 * a copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sublicense, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be 17 * included in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 23 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 */ 27 28 #include <iostream> 29 #include <string> 30 #include <stdexcept> 31 #include <unistd.h> 32 #include <stdlib.h> 33 34 #include "grovecircularled.h" 35 36 using namespace upm; 37 38 GroveCircularLED::GroveCircularLED (uint8_t di, uint8_t dcki) 39 : m_clkPinCtx(dcki), 40 m_dataPinCtx(di) { 41 mraa::Result error = mraa::SUCCESS; 42 43 m_clkPinCtx.useMmap(true); 44 m_dataPinCtx.useMmap(true); 45 46 // set direction (out) 47 error = m_clkPinCtx.dir(mraa::DIR_OUT); 48 if (error != mraa::SUCCESS) { 49 printError(error); 50 } 51 } 52 53 mraa::Result 54 GroveCircularLED::setSpinner (uint8_t position) { 55 if (position < 0 || position >= 24) { 56 return mraa::ERROR_INVALID_PARAMETER; 57 } 58 for(uint8_t block_idx = 0; block_idx < 24; block_idx++) { 59 if (block_idx % 12 == 0) { 60 send16bitBlock (CMDMODE); 61 } 62 uint32_t state = (block_idx == position) ? BIT_HIGH : BIT_LOW; 63 send16bitBlock (state); 64 } 65 return lockData (); 66 } 67 68 mraa::Result 69 GroveCircularLED::setLevel (uint8_t level, bool direction) { 70 if (level < 0 || level > 24) { 71 return mraa::ERROR_INVALID_PARAMETER; 72 } 73 if (direction) { 74 for(uint8_t block_idx = 24; block_idx > 0; block_idx--) { 75 if (block_idx % 12 == 0) { 76 send16bitBlock (CMDMODE); 77 } 78 uint32_t state = (block_idx <= level) ? BIT_HIGH : BIT_LOW; 79 send16bitBlock (state); 80 } 81 } else { 82 for(uint8_t block_idx = 0; block_idx < 24; block_idx++) { 83 if (block_idx % 12 == 0) { 84 send16bitBlock (CMDMODE); 85 } 86 uint32_t state = (block_idx <= level - 1) ? BIT_HIGH : BIT_LOW; 87 send16bitBlock (state); 88 } 89 } 90 return lockData (); 91 } 92 93 mraa::Result 94 GroveCircularLED::setStatus (bool status[24]) { 95 for(uint8_t block_idx = 0; block_idx < 24; block_idx++) { 96 if (block_idx % 12 == 0) { 97 send16bitBlock (CMDMODE); 98 } 99 send16bitBlock (status[block_idx] ? BIT_HIGH : BIT_LOW); 100 } 101 return lockData (); 102 } 103 104 mraa::Result 105 GroveCircularLED::lockData () { 106 mraa::Result error = mraa::SUCCESS; 107 error = m_dataPinCtx.write (LOW); 108 usleep(10); 109 110 for(int idx = 0; idx < 4; idx++) { 111 error = m_dataPinCtx.write(HIGH); 112 error = m_dataPinCtx.write(LOW); 113 } 114 return error; 115 } 116 117 mraa::Result 118 GroveCircularLED::send16bitBlock (short data) { 119 mraa::Result error = mraa::SUCCESS; 120 for (uint8_t bit_idx = 0; bit_idx < MAX_BIT_PER_BLOCK; bit_idx++) { 121 uint32_t state = (data & 0x8000) ? HIGH : LOW; 122 error = m_dataPinCtx.write (state); 123 state = m_clkPinCtx.read (); 124 125 if (state) { 126 state = LOW; 127 } else { 128 state = HIGH; 129 } 130 131 error = m_clkPinCtx.write (state); 132 133 data <<= 1; 134 } 135 return error; 136 } 137