Line data Source code
1 : /* 2 : This program is free software: you can redistribute it and/or modify 3 : it under the terms of the GNU General Public License as published by 4 : the Free Software Foundation, either version 3 of the License, or 5 : (at your option) any later version. 6 : 7 : This program is distributed in the hope that it will be useful, 8 : but WITHOUT ANY WARRANTY; without even the implied warranty of 9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 : GNU General Public License for more details. 11 : 12 : You should have received a copy of the GNU General Public License 13 : along with this program. If not, see <http://www.gnu.org/licenses/>. 14 : */ 15 : 16 : #include "NeoPixel.h" 17 : 18 : #if AP_NOTIFY_NEOPIXEL_ENABLED 19 : 20 : #include "AP_Notify/AP_Notify.h" 21 : #include "SRV_Channel/SRV_Channel.h" 22 : 23 : // This limit is from the dshot driver rcout groups limit 24 : #define AP_NOTIFY_NEOPIXEL_MAX_INSTANCES 4 25 : 26 : // Datasheet: https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf 27 : // 24bit msg as 3 byte GRB (not RGB) where first bit is G7, and last bit is B0 28 : // (first) G7|G6|G5|G4|G3|G2|G1|G0|R7|R6|R5|R4|R3|R2|R1|R0|B7|B6|B5|B4|B3|B2|B1|B0 (last) 29 : 30 : #define NEOPIXEL_LED_LOW 0x33 31 : #define NEOPIXEL_LED_MEDIUM 0x7F 32 : #define NEOPIXEL_LED_HIGH 0xFF 33 : #define NEOPIXEL_LED_OFF 0x00 34 : 35 : extern const AP_HAL::HAL& hal; 36 : 37 0 : NeoPixel::NeoPixel() : 38 0 : SerialLED(NEOPIXEL_LED_OFF, NEOPIXEL_LED_HIGH, NEOPIXEL_LED_MEDIUM, NEOPIXEL_LED_LOW) 39 : { 40 0 : } 41 : 42 0 : uint16_t NeoPixel::init_ports() 43 : { 44 0 : uint16_t mask = 0; 45 0 : for (uint16_t i=0; i<AP_NOTIFY_NEOPIXEL_MAX_INSTANCES; i++) { 46 0 : const SRV_Channel::Function fn = (SRV_Channel::Function)((uint8_t)SRV_Channel::k_LED_neopixel1 + i); 47 0 : if (!SRV_Channels::function_assigned(fn)) { 48 0 : continue; 49 : } 50 0 : mask |= SRV_Channels::get_output_channel_mask(fn); 51 : } 52 : 53 : #if AP_NOTIFY_NEOPIXEL_MASK 54 : // Use board-defined default mask if no servo functions assigned 55 : if (mask == 0) { 56 : mask = AP_NOTIFY_NEOPIXEL_MASK; 57 : } 58 : #endif 59 : 60 0 : if (mask == 0) { 61 0 : return 0; 62 : } 63 : 64 0 : AP_SerialLED *led = AP_SerialLED::get_singleton(); 65 0 : if (led == nullptr) { 66 0 : return 0; 67 : } 68 : 69 0 : for (uint16_t chan=0; chan<16; chan++) { 70 0 : if ((1U<<chan) & mask) { 71 0 : if (pNotify->get_led_type() & AP_Notify::Notify_LED_NeoPixel) { 72 0 : led->set_num_neopixel(chan+1, pNotify->get_led_len()); 73 0 : } else if (pNotify->get_led_type() & AP_Notify::Notify_LED_NeoPixelRGB) { 74 0 : led->set_num_neopixel_rgb(chan+1, pNotify->get_led_len()); 75 : } 76 : } 77 : } 78 : 79 0 : return mask; 80 : } 81 : 82 : #endif // AP_NOTIFY_NEOPIXEL_ENABLED