]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/planck/planck.c
Renames keyboard folder to keyboards, adds couple of tmk's fixes (#432)
[qmk_firmware.git] / keyboards / planck / planck.c
1 #include "planck.h"
2
3 __attribute__ ((weak))
4 void matrix_init_user(void) {}
5
6 __attribute__ ((weak))
7 void matrix_scan_user(void) {}
8
9 __attribute__ ((weak))
10 bool process_action_user(keyrecord_t *record) {
11     return true;
12 }
13
14 __attribute__ ((weak))
15 void led_set_user(uint8_t usb_led) {}
16
17 void matrix_init_kb(void) {
18 #ifdef BACKLIGHT_ENABLE
19         backlight_init_ports();
20 #endif
21
22         // Turn status LED on
23         DDRE |= (1<<6);
24         PORTE |= (1<<6);
25
26         matrix_init_user();
27 }
28
29 void matrix_scan_kb(void) {
30         matrix_scan_user();
31 }
32
33 bool process_action_kb(keyrecord_t *record) {
34         return process_action_user(record);
35 }
36
37 void led_set_kb(uint8_t usb_led) {
38     // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
39
40     led_set_user(usb_led);
41 }
42
43 #ifdef BACKLIGHT_ENABLE
44 #define CHANNEL OCR1C
45 #define BREATHING_NO_HALT  0
46 #define BREATHING_HALT_OFF 1
47 #define BREATHING_HALT_ON  2
48
49 static uint8_t breath_intensity;
50 static uint8_t breath_speed;
51 static uint16_t breathing_index;
52 static uint8_t breathing_halt;
53
54 void backlight_init_ports()
55 {
56
57     // Setup PB7 as output and output low.
58     DDRB |= (1<<7);
59     PORTB &= ~(1<<7);
60
61     // Use full 16-bit resolution.
62     ICR1 = 0xFFFF;
63
64     // I could write a wall of text here to explain... but TL;DW
65     // Go read the ATmega32u4 datasheet.
66     // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
67
68     // Pin PB7 = OCR1C (Timer 1, Channel C)
69     // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
70     // (i.e. start high, go low when counter matches.)
71     // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
72     // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
73
74     TCCR1A = _BV(COM1C1) | _BV(WGM11); // = 0b00001010;
75     TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
76
77     backlight_init();
78     breathing_defaults();
79 }
80
81 void backlight_set(uint8_t level)
82 {
83     // Prevent backlight blink on lowest level
84     PORTB &= ~(_BV(PORTB7));
85
86     if ( level == 0 )
87     {
88         // Turn off PWM control on PB7, revert to output low.
89         TCCR1A &= ~(_BV(COM1C1));
90         CHANNEL = 0x0;
91     }
92     else if ( level == BACKLIGHT_LEVELS )
93     {
94         // Turn on PWM control of PB7
95         TCCR1A |= _BV(COM1C1);
96         // Set the brightness
97         CHANNEL = 0xFFFF;
98     }
99     else
100     {
101         // Turn on PWM control of PB7
102         TCCR1A |= _BV(COM1C1);
103         // Set the brightness
104         CHANNEL = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
105     }
106     breathing_intensity_default();
107 }
108
109
110 void breathing_enable(void)
111 {
112     if (get_backlight_level() == 0)
113     {
114         breathing_index = 0;
115     }
116     else
117     {
118         // Set breathing_index to be at the midpoint (brightest point)
119         breathing_index = 0x20 << breath_speed;
120     }
121
122     breathing_halt = BREATHING_NO_HALT;
123
124     // Enable breathing interrupt
125     TIMSK1 |= _BV(OCIE1A);
126 }
127
128 void breathing_pulse(void)
129 {
130     if (get_backlight_level() == 0)
131     {
132         breathing_index = 0;
133     }
134     else
135     {
136         // Set breathing_index to be at the midpoint + 1 (brightest point)
137         breathing_index = 0x21 << breath_speed;
138     }
139
140     breathing_halt = BREATHING_HALT_ON;
141
142     // Enable breathing interrupt
143     TIMSK1 |= _BV(OCIE1A);
144 }
145
146 void breathing_disable(void)
147 {
148     // Disable breathing interrupt
149     TIMSK1 &= ~_BV(OCIE1A);
150     backlight_set(get_backlight_level());
151 }
152
153 void breathing_self_disable(void)
154 {
155     if (get_backlight_level() == 0)
156     {
157         breathing_halt = BREATHING_HALT_OFF;
158     }
159     else
160     {
161         breathing_halt = BREATHING_HALT_ON;
162     }
163
164     //backlight_set(get_backlight_level());
165 }
166
167 void breathing_toggle(void)
168 {
169     if (!is_breathing())
170     {
171         if (get_backlight_level() == 0)
172         {
173             breathing_index = 0;
174         }
175         else
176         {
177             // Set breathing_index to be at the midpoint + 1 (brightest point)
178             breathing_index = 0x21 << breath_speed;
179         }
180
181         breathing_halt = BREATHING_NO_HALT;
182     }
183
184     // Toggle breathing interrupt
185     TIMSK1 ^= _BV(OCIE1A);
186
187     // Restore backlight level
188     if (!is_breathing())
189     {
190         backlight_set(get_backlight_level());
191     }
192 }
193
194 bool is_breathing(void)
195 {
196     return (TIMSK1 && _BV(OCIE1A));
197 }
198
199 void breathing_intensity_default(void)
200 {
201     //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
202     breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
203 }
204
205 void breathing_intensity_set(uint8_t value)
206 {
207     breath_intensity = value;
208 }
209
210 void breathing_speed_default(void)
211 {
212     breath_speed = 4;
213 }
214
215 void breathing_speed_set(uint8_t value)
216 {
217     bool is_breathing_now = is_breathing();
218     uint8_t old_breath_speed = breath_speed;
219
220     if (is_breathing_now)
221     {
222         // Disable breathing interrupt
223         TIMSK1 &= ~_BV(OCIE1A);
224     }
225
226     breath_speed = value;
227
228     if (is_breathing_now)
229     {
230         // Adjust index to account for new speed
231         breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
232
233         // Enable breathing interrupt
234         TIMSK1 |= _BV(OCIE1A);
235     }
236
237 }
238
239 void breathing_speed_inc(uint8_t value)
240 {
241     if ((uint16_t)(breath_speed - value) > 10 )
242     {
243         breathing_speed_set(0);
244     }
245     else
246     {
247         breathing_speed_set(breath_speed - value);
248     }
249 }
250
251 void breathing_speed_dec(uint8_t value)
252 {
253     if ((uint16_t)(breath_speed + value) > 10 )
254     {
255         breathing_speed_set(10);
256     }
257     else
258     {
259         breathing_speed_set(breath_speed + value);
260     }
261 }
262
263 void breathing_defaults(void)
264 {
265     breathing_intensity_default();
266     breathing_speed_default();
267     breathing_halt = BREATHING_NO_HALT;
268 }
269
270 /* Breathing Sleep LED brighness(PWM On period) table
271  * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
272  *
273  * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
274  * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
275  */
276 static const uint8_t breathing_table[64] PROGMEM = {
277   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   2,   4,   6,  10,
278  15,  23,  32,  44,  58,  74,  93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
279 255, 252, 245, 233, 218, 199, 179, 157, 135, 113,  93,  74,  58,  44,  32,  23,
280  15,  10,   6,   4,   2,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
281 };
282
283 ISR(TIMER1_COMPA_vect)
284 {
285     // CHANNEL = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
286
287
288     uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
289
290     if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
291     {
292         // Disable breathing interrupt
293         TIMSK1 &= ~_BV(OCIE1A);
294     }
295
296     CHANNEL = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
297
298 }
299
300
301
302 #endif