Line data Source code
1 : /* 2 : NCP5623 I2C LED driver 3 : */ 4 : /* 5 : This program is free software: you can redistribute it and/or modify 6 : it under the terms of the GNU General Public License as published by 7 : the Free Software Foundation, either version 3 of the License, or 8 : (at your option) any later version. 9 : 10 : This program is distributed in the hope that it will be useful, 11 : but WITHOUT ANY WARRANTY; without even the implied warranty of 12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 : GNU General Public License for more details. 14 : 15 : You should have received a copy of the GNU General Public License 16 : along with this program. If not, see <http://www.gnu.org/licenses/>. 17 : */ 18 : 19 : #include "NCP5623.h" 20 : #include <utility> 21 : 22 : #include <AP_HAL/AP_HAL.h> 23 : 24 : extern const AP_HAL::HAL& hal; 25 : 26 : #define NCP5623_LED_BRIGHT 0x1f // full brightness 27 : #define NCP5623_LED_MEDIUM 0x18 // medium brightness 28 : #define NCP5623_LED_DIM 0x0f // dim 29 : #define NCP5623_LED_OFF 0x00 // off 30 : 31 : #define NCP5623_LED_I2C_ADDR 0x38 // default I2C bus address 32 : #define NCP5623_C_LED_I2C_ADDR 0x39 // default I2C bus address for the NCP5623C 33 : 34 : #define NCP5623_LED_PWM0 0x40 // pwm0 register 35 : #define NCP5623_LED_PWM1 0x60 // pwm1 register 36 : #define NCP5623_LED_PWM2 0x80 // pwm2 register 37 : #define NCP5623_LED_ENABLE 0x20 // enable register 38 : 39 10470 : NCP5623::NCP5623(uint8_t bus) 40 : : RGBLed(NCP5623_LED_OFF, NCP5623_LED_BRIGHT, NCP5623_LED_MEDIUM, NCP5623_LED_DIM) 41 10470 : , _bus(bus) 42 : { 43 10470 : } 44 : 45 20940 : bool NCP5623::write(uint8_t reg, uint8_t data) 46 : { 47 20940 : uint8_t msg[1] = { 0x00 }; 48 : // scale to 0 to 0x1F 49 20940 : data = (data * 255U) / 0x1FU; 50 20940 : msg[0] = ((reg & 0xe0) | (data & 0x1f)); 51 20940 : bool ret = _dev->transfer(msg, 1, nullptr, 0); 52 20940 : return ret; 53 : } 54 : 55 0 : bool NCP5623::write_pwm(uint8_t _rgb[3]) 56 : { 57 0 : uint8_t reg = NCP5623_LED_PWM0; 58 0 : for (uint8_t i=0; i<3; i++) { 59 0 : if (!write(reg+i*0x20, _rgb[i])) { 60 0 : return false; 61 : } 62 : } 63 0 : return true; 64 : } 65 : 66 10470 : bool NCP5623::init(void) 67 : { 68 10470 : uint8_t addrs[] = { NCP5623_LED_I2C_ADDR, NCP5623_C_LED_I2C_ADDR }; 69 31410 : for (uint8_t i=0; i<ARRAY_SIZE(addrs); i++) { 70 : // first look for led on external bus 71 20940 : _dev = std::move(hal.i2c_mgr->get_device(_bus, addrs[i])); 72 20940 : if (!_dev) { 73 20940 : continue; 74 : } 75 : 76 20940 : _dev->get_semaphore()->take_blocking(); 77 20940 : _dev->set_retries(10); 78 : 79 : // enable the led 80 20940 : bool ret = write(NCP5623_LED_ENABLE, 0x1f); 81 20940 : if (!ret) { 82 20940 : _dev->get_semaphore()->give(); 83 20940 : continue; 84 : } 85 : 86 : // update the red, green and blue values to zero 87 0 : uint8_t off[3] = { _led_off, _led_off, _led_off }; 88 0 : ret = write_pwm(off); 89 : 90 0 : _dev->set_retries(1); 91 : 92 : // give back i2c semaphore 93 0 : _dev->get_semaphore()->give(); 94 : 95 0 : if (ret) { 96 0 : _dev->register_periodic_callback(20000, FUNCTOR_BIND_MEMBER(&NCP5623::_timer, void)); 97 : } 98 0 : return true; 99 : } 100 : 101 10470 : return false; 102 : } 103 : 104 : // set_rgb - set color as a combination of red, green and blue values 105 0 : bool NCP5623::hw_set_rgb(uint8_t red, uint8_t green, uint8_t blue) 106 : { 107 0 : rgb[0] = red; 108 0 : rgb[1] = green; 109 0 : rgb[2] = blue; 110 0 : _need_update = true; 111 0 : return true; 112 : } 113 : 114 0 : void NCP5623::_timer(void) 115 : { 116 0 : if (!_need_update) { 117 0 : return; 118 : } 119 0 : _need_update = false; 120 : 121 0 : write_pwm(rgb); 122 : }