indicator_leds.c (2505B)
1 /* 2 Copyright 2016-2017 Ralf Schmitt <ralf@bunkertor.net> Rasmus Schults <rasmusx@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 "duck_led/duck_led.h" 22 23 #define LED_T1H 900 24 #define LED_T1L 600 25 #define LED_T0H 400 26 #define LED_T0L 900 27 28 void send_bit_d4(bool bitVal) { 29 if(bitVal) { 30 asm volatile ( 31 "sbi %[port], %[bit] \n\t" 32 ".rept %[onCycles] \n\t" 33 "nop \n\t" 34 ".endr \n\t" 35 "cbi %[port], %[bit] \n\t" 36 ".rept %[offCycles] \n\t" 37 "nop \n\t" 38 ".endr \n\t" 39 :: 40 [port] "I" (_SFR_IO_ADDR(PORTD)), 41 [bit] "I" (4), 42 [onCycles] "I" (NS_TO_CYCLES(LED_T1H) - 2), 43 [offCycles] "I" (NS_TO_CYCLES(LED_T1L) - 2)); 44 } else { 45 asm volatile ( 46 "sbi %[port], %[bit] \n\t" 47 ".rept %[onCycles] \n\t" 48 "nop \n\t" 49 ".endr \n\t" 50 "cbi %[port], %[bit] \n\t" 51 ".rept %[offCycles] \n\t" 52 "nop \n\t" 53 ".endr \n\t" 54 :: 55 [port] "I" (_SFR_IO_ADDR(PORTD)), 56 [bit] "I" (4), 57 [onCycles] "I" (NS_TO_CYCLES(LED_T0H) - 2), 58 [offCycles] "I" (NS_TO_CYCLES(LED_T0L) - 2)); 59 } 60 } 61 62 void send_value(uint8_t byte, enum Device device) { 63 for(uint8_t b = 0; b < 8; b++) { 64 if(device == Device_STATUSLED) { 65 send_bit_d4(byte & 0b10000000); 66 byte <<= 1; 67 } 68 } 69 } 70 71 void send_color(uint8_t r, uint8_t g, uint8_t b, enum Device device) { 72 send_value(r, device); 73 send_value(g, device); 74 send_value(b, device); 75 } 76 77 void indicator_leds_set(bool leds[8]) { 78 cli(); 79 send_color(leds[1] ? 255 : 0, leds[2] ? 255 : 0, leds[0] ? 255 : 0, Device_STATUSLED); 80 send_color(leds[4] ? 255 : 0, leds[5] ? 255 : 0, leds[3] ? 255 : 0, Device_STATUSLED); 81 send_color(leds[6] ? 255 : 0, leds[7] ? 255 : 0, 0, Device_STATUSLED); 82 sei(); 83 show(); 84 }