Commit | Line | Data |
---|---|---|
cbc5de67 M |
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" | |
cb2f2fd2 | 22 | #include "duck_led/duck_led.h" |
cbc5de67 M |
23 | |
24 | #define LED_T1H 600 | |
25 | #define LED_T1L 650 | |
26 | #define LED_T0H 250 | |
27 | #define LED_T0L 1000 | |
28 | ||
cbc5de67 M |
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 | ||
cb2f2fd2 | 63 | void send_value(uint8_t byte, enum Device device) { |
cbc5de67 | 64 | for(uint8_t b = 0; b < 8; b++) { |
cb2f2fd2 M |
65 | if(device == Device_STATUSLED) { |
66 | send_bit_d4(byte & 0b10000000); | |
67 | byte <<= 1; | |
68 | } | |
cbc5de67 M |
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++) | |
cb2f2fd2 | 78 | send_value(leds[led_cnt] ? 255 : 0, Device_STATUSLED); |
cbc5de67 M |
79 | sei(); |
80 | show(); | |
81 | } | |
cb2f2fd2 | 82 |