]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/duck/lightsaver/indicator_leds.c
5d2e1ad9f638d38f53323b9ab2a5ef4fb8516c9d
[qmk_firmware.git] / keyboards / duck / lightsaver / indicator_leds.c
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 }