]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboard/atomic/atomic.c
3996497161cc2400c5ed5f5cce938a45cf47fb64
[qmk_firmware.git] / keyboard / atomic / atomic.c
1 #include "atomic.h"
2
3 __attribute__ ((weak))
4 void matrix_init_user(void) {
5         // leave this function blank - it can be defined in a keymap file
6 };
7
8 __attribute__ ((weak))
9 void matrix_scan_user(void) {
10         // leave this function blank - it can be defined in a keymap file
11 }
12
13 __attribute__ ((weak))
14 void process_action_user(keyrecord_t *record) {
15         // leave this function blank - it can be defined in a keymap file
16 }
17
18 __attribute__ ((weak))
19 void led_set_user(uint8_t usb_led) {
20         // leave this function blank - it can be defined in a keymap file
21 }
22
23 void matrix_init_kb(void) {
24         // put your keyboard start-up code here
25         // runs once when the firmware starts up
26
27     MCUCR |= (1<<JTD);
28     MCUCR |= (1<<JTD);
29
30 #ifdef BACKLIGHT_ENABLE
31     backlight_init_ports();
32 #endif
33
34     // Turn status LED on
35     DDRE |= (1<<6);
36     PORTE |= (1<<6);
37
38         matrix_init_user();
39 }
40
41 void matrix_scan_kb(void) {
42         // put your looping keyboard code here
43         // runs every cycle (a lot)
44
45         matrix_scan_user();
46 }
47
48 void process_action_kb(keyrecord_t *record) {
49         // put your per-action keyboard code here
50         // runs for every action, just before processing by the firmware
51
52         process_action_user(record);
53 }
54
55 void led_set_kb(uint8_t usb_led) {
56         // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
57
58         led_set_user(usb_led);
59 }
60
61 #ifdef BACKLIGHT_ENABLE
62 #define CHANNEL OCR1C
63
64 void backlight_init_ports()
65 {
66
67     // Setup PB7 as output and output low.
68     DDRB |= (1<<7);
69     PORTB &= ~(1<<7);
70     
71     // Use full 16-bit resolution. 
72     ICR1 = 0xFFFF;
73
74     // I could write a wall of text here to explain... but TL;DW
75     // Go read the ATmega32u4 datasheet.
76     // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
77     
78     // Pin PB7 = OCR1C (Timer 1, Channel C)
79     // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
80     // (i.e. start high, go low when counter matches.)
81     // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
82     // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
83     
84     TCCR1A = _BV(COM1C1) | _BV(WGM11); // = 0b00001010;
85     TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
86
87     backlight_init();
88 }
89
90 void backlight_set(uint8_t level)
91 {
92     if ( level == 0 )
93     {
94         // Turn off PWM control on PB7, revert to output low.
95         TCCR1A &= ~(_BV(COM1C1));
96         CHANNEL = 0x0;
97         // Prevent backlight blink on lowest level
98         PORTB &= ~(_BV(PORTB7));
99     }
100     else if ( level == BACKLIGHT_LEVELS )
101     {
102         // Prevent backlight blink on lowest level
103         PORTB &= ~(_BV(PORTB7));
104         // Turn on PWM control of PB7
105         TCCR1A |= _BV(COM1C1);
106         // Set the brightness
107         CHANNEL = 0xFFFF;
108     }
109     else        
110     {
111         // Prevent backlight blink on lowest level
112         PORTB &= ~(_BV(PORTB7));
113         // Turn on PWM control of PB7
114         TCCR1A |= _BV(COM1C1);
115         // Set the brightness
116         CHANNEL = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
117     }
118 }
119
120 #endif