indicator_leds.c (2261B)
1 /* 2 Copyright 2017 MechMerlin <mechmerlin@gmail.com> 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 #include <avr/interrupt.h> 18 #include <avr/io.h> 19 #include <stdbool.h> 20 #include <util/delay.h> 21 #include "indicator_leds.h" 22 #include "duck_led/duck_led.h" 23 24 #define LED_T1H 600 25 #define LED_T1L 650 26 #define LED_T0H 250 27 #define LED_T0L 1000 28 29 void send_bit_d4(bool bitVal) { 30 if(bitVal) { 31 asm volatile ( 32 "sbi %[port], %[bit] \n\t" 33 ".rept %[onCycles] \n\t" 34 "nop \n\t" 35 ".endr \n\t" 36 "cbi %[port], %[bit] \n\t" 37 ".rept %[offCycles] \n\t" 38 "nop \n\t" 39 ".endr \n\t" 40 :: 41 [port] "I" (_SFR_IO_ADDR(PORTD)), 42 [bit] "I" (4), 43 [onCycles] "I" (NS_TO_CYCLES(LED_T1H) - 2), 44 [offCycles] "I" (NS_TO_CYCLES(LED_T1L) - 2)); 45 } else { 46 asm volatile ( 47 "sbi %[port], %[bit] \n\t" 48 ".rept %[onCycles] \n\t" 49 "nop \n\t" 50 ".endr \n\t" 51 "cbi %[port], %[bit] \n\t" 52 ".rept %[offCycles] \n\t" 53 "nop \n\t" 54 ".endr \n\t" 55 :: 56 [port] "I" (_SFR_IO_ADDR(PORTD)), 57 [bit] "I" (4), 58 [onCycles] "I" (NS_TO_CYCLES(LED_T0H) - 2), 59 [offCycles] "I" (NS_TO_CYCLES(LED_T0L) - 2)); 60 } 61 } 62 63 void send_value(uint8_t byte, enum Device device) { 64 for(uint8_t b = 0; b < 8; b++) { 65 if(device == Device_STATUSLED) { 66 send_bit_d4(byte & 0b10000000); 67 byte <<= 1; 68 } 69 } 70 } 71 72 // Send the LED indicators to the WS2811S chips 73 void indicator_leds_set(bool leds[8]) { 74 uint8_t led_cnt; 75 76 cli(); 77 for(led_cnt = 0; led_cnt < 8; led_cnt++) 78 send_value(leds[led_cnt] ? 255 : 0, Device_STATUSLED); 79 sei(); 80 show(); 81 } 82