]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/duck/octagon/v2/indicator_leds.c
116306fb7126e54b8e86d80140f202759f816585
[qmk_firmware.git] / keyboards / duck / octagon / v2 / indicator_leds.c
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
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_bit_d6(bool bitVal)
63 {
64   if(bitVal) {
65     asm volatile (
66         "sbi %[port], %[bit] \n\t"
67         ".rept %[onCycles] \n\t"
68         "nop \n\t"
69         ".endr \n\t"
70         "cbi %[port], %[bit] \n\t"
71         ".rept %[offCycles] \n\t"
72         "nop \n\t"
73         ".endr \n\t"
74         ::
75         [port]      "I" (_SFR_IO_ADDR(PORTD)),
76         [bit]       "I" (6),
77         [onCycles]  "I" (NS_TO_CYCLES(LED_T1H) - 2),
78         [offCycles] "I" (NS_TO_CYCLES(LED_T1L) - 2));
79   } else {
80     asm volatile (
81         "sbi %[port], %[bit] \n\t"
82         ".rept %[onCycles] \n\t"
83         "nop \n\t"
84         ".endr \n\t"
85         "cbi %[port], %[bit] \n\t"
86         ".rept %[offCycles] \n\t"
87         "nop \n\t"
88         ".endr \n\t"
89         ::
90         [port]      "I" (_SFR_IO_ADDR(PORTD)),
91         [bit]       "I" (6),
92         [onCycles]  "I" (NS_TO_CYCLES(LED_T0H) - 2),
93         [offCycles] "I" (NS_TO_CYCLES(LED_T0L) - 2));
94   }
95 }
96
97 void send_value(uint8_t byte, enum Device device) {
98   for(uint8_t b = 0; b < 8; b++) {
99     if(device == Device_STATUSLED) {
100       send_bit_d4(byte & 0b10000000);
101     }
102     if(device == Device_PCBRGB) {
103       send_bit_d6(byte & 0b10000000);
104     }
105     byte <<= 1;
106   }
107 }
108
109 void send_color(uint8_t r, uint8_t g, uint8_t b, enum Device device) {
110   send_value(r, device);
111   send_value(g, device);
112   send_value(b, device);
113 }
114
115 // Port from backlight_set_state
116 void indicator_leds_set(bool leds[8]) {
117   cli();
118   send_color(leds[1] ? 255 : 0, leds[2] ? 255 : 0, leds[0] ? 255 : 0, Device_STATUSLED);
119   send_color(leds[4] ? 255 : 0, leds[3] ? 255 : 0, leds[5] ? 255 : 0, Device_STATUSLED);
120   leds[6] ? (PORTD &= ~0b10000000) : (PORTD |= 0b10000000);
121   sei();
122   show();
123 }