diff --git a/keyboards/anne_pro/anne_pro.c b/keyboards/anne_pro/anne_pro.c index b116a9dcd2..ea43a662c0 100644 --- a/keyboards/anne_pro/anne_pro.c +++ b/keyboards/anne_pro/anne_pro.c @@ -15,108 +15,38 @@ */ #include "anne_pro.h" -#include "uart_tx_ringbuf.h" +#include "anne_pro_lighting.h" #include "ch.h" #include "hal.h" -#define LED_UART (&UARTD3) -/* UART transmission ringbuffer for the LED UART */ -static uint8_t led_uart_tx_buffer[256] = {0}; -static uart_tx_ringbuf_t led_uart_ringbuf = { - .buf = led_uart_tx_buffer, - .uart = LED_UART, - .size = sizeof(led_uart_tx_buffer), - .sending_elements = 0, - .head = 0, - .tail = 0, -}; - -/* Should the main loop try a transmission, used when transmission finishes - to send any data that might have been added to the buffer while the - transmission was in progress. -*/ -static volatile bool led_uart_try_transmission = false; - -/* Handler for finsihed LED UART transmissions */ -static void led_uart_txend(UARTDriver *uart) { - uart_tx_ringbuf_finish_transmission(&led_uart_ringbuf); - led_uart_try_transmission = true; -} - -/* LED UART configuration */ -static UARTConfig led_uart_cfg = { - .txend1_cb = led_uart_txend, - .txend2_cb = NULL, - .rxend_cb = NULL, - .rxchar_cb = NULL, - .rxerr_cb = NULL, - .speed = 38400, - .cr1 = 0, - .cr2 = USART_CR2_LINEN, - .cr3 = 0 -}; - -/* State of the leds on the keyboard */ -static volatile bool leds_enabled = false; - -/* Buffer for the keystate packet */ -static uint8_t keystate[12] = {9, 10, 7, 0}; - -/* Update the dynamic lighting packet based on a keypress */ -void update_dynamic_lighting(keyrecord_t *record) { - /* Only update dynamic lighting modes when leds are enabled */ - if (leds_enabled) { - /* Calculate the position of the key that was pressed */ - uint8_t row = record->event.key.row; - uint8_t col = record->event.key.col; - int position = row * MATRIX_COLS + col; - int index = position / 8; - int bit = position % 8; - - /* Update the keystate based on the location */ - if (record->event.pressed) { - keystate[3 + index] |= (1 << bit); - } else { - keystate[3 + index] &= ~(1 << bit); - } - - /* Send the keystate to the LED controller */ - uart_tx_ringbuf_write(&led_uart_ringbuf, 12, keystate); - } -} - /* Process the Anne Pro custom keycodes */ bool process_record_kb(uint16_t keycode, keyrecord_t *record) { - update_dynamic_lighting(record); + /* Update the key status for the reactive effects */ + anne_pro_lighting_update_dynamic(record); switch (keycode) { case APL_RGB: /* Toggle the RGB enabled/disabled */ if (record->event.pressed) { - leds_enabled = !leds_enabled; - if (leds_enabled) { - uart_tx_ringbuf_write(&led_uart_ringbuf, 3, "\x09\x01\x01"); - } else { - uart_tx_ringbuf_write(&led_uart_ringbuf, 4, "\x09\x02\x01\x00"); - } + anne_pro_lighting_toggle(); } return false; case APL_RAT: /* Change the animation rate */ - if (leds_enabled && record->event.pressed) { - uart_tx_ringbuf_write(&led_uart_ringbuf, 6, "\x09\x04\x05\x00\x01\x00"); + if (record->event.pressed) { + anne_pro_lighting_rate_next(); } return false; case APL_BRT: /* Change the brightness */ - if (leds_enabled && record->event.pressed) { - uart_tx_ringbuf_write(&led_uart_ringbuf, 6, "\x09\x04\x05\x00\x00\x01"); + if (record->event.pressed) { + anne_pro_lighting_brightness_next(); } return false; case APL_MOD: /* Change the lighting mode */ - if (leds_enabled && record->event.pressed) { - uart_tx_ringbuf_write(&led_uart_ringbuf, 6, "\x09\x04\x05\x01\x00\x00"); + if (record->event.pressed) { + anne_pro_lighting_mode_next(); } return false; default: @@ -127,39 +57,28 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) { /* Initialize custom keyboard features */ void keyboard_pre_init_kb(void) { - /* Turn on lighting controller */ - setPinOutput(C15); - writePinLow(C15); - chThdSleepMilliseconds(10); - writePinHigh(C15); - chThdSleepMilliseconds(10); - - /* Initialize the lighting UART */ - uartStart(LED_UART, &led_uart_cfg); - palSetPadMode(GPIOB, 10, PAL_MODE_ALTERNATE(7)); - palSetPadMode(GPIOB, 11, PAL_MODE_ALTERNATE(7)); + /* Initialize the ligthing controller */ + anne_pro_lighting_init(); keyboard_pre_init_user(); } /* Turn on the lighting when init is finished */ void keyboard_post_init_kb(void) { - /* Send 'set theme' command to lighting controller */ - uart_tx_ringbuf_write(&led_uart_ringbuf, 4, "\x09\x02\x01\x0e"); - /* Send 'set speed and brightness' command to lighting controller */ - uart_tx_ringbuf_write(&led_uart_ringbuf, 6, "\x09\x04\x02\x80\x01\x00"); - /* Mark LEDs as enabled */ - leds_enabled = true; + /* Turn on the lighting */ + anne_pro_lighting_on(); + /* Set the theme to rainbow */ + anne_pro_lighting_mode(APL_MODE_RAINBOW); + /* Set the effect rate to average and the brightness to average */ + anne_pro_lighting_rate_brightness(128, 5); keyboard_post_init_user(); } /* Start transmissions when the flag is set */ void matrix_scan_kb(void) { - if (led_uart_try_transmission) { - uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); - led_uart_try_transmission = false; - } + /* Run some update code for the lighting */ + anne_pro_lighting_update(); /* Run matrix_scan_user code */ matrix_scan_user(); diff --git a/keyboards/anne_pro/anne_pro_lighting.c b/keyboards/anne_pro/anne_pro_lighting.c new file mode 100644 index 0000000000..3fffab12b7 --- /dev/null +++ b/keyboards/anne_pro/anne_pro_lighting.c @@ -0,0 +1,169 @@ +/* Copyright 2019 Michiel Visser + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "anne_pro_lighting.h" +#include "uart_tx_ringbuf.h" +#include "quantum.h" +#include "ch.h" +#include "hal.h" + +#define LED_UART (&UARTD3) +/* UART transmission ringbuffer for the LED UART */ +static uint8_t led_uart_tx_buffer[256] = {0}; +static uart_tx_ringbuf_t led_uart_ringbuf = { + .buf = led_uart_tx_buffer, + .uart = LED_UART, + .size = sizeof(led_uart_tx_buffer), + .sending_elements = 0, + .head = 0, + .tail = 0, +}; + +/* Should the main loop try a transmission, used when transmission finishes + to send any data that might have been added to the buffer while the + transmission was in progress. +*/ +static volatile bool led_uart_try_transmission = false; + +/* Handler for finsihed LED UART transmissions */ +static void led_uart_txend(UARTDriver *uart) { + uart_tx_ringbuf_finish_transmission(&led_uart_ringbuf); + led_uart_try_transmission = true; +} + +/* LED UART configuration */ +static UARTConfig led_uart_cfg = { + .txend1_cb = led_uart_txend, + .txend2_cb = NULL, + .rxend_cb = NULL, + .rxchar_cb = NULL, + .rxerr_cb = NULL, + .speed = 38400, + .cr1 = 0, + .cr2 = USART_CR2_LINEN, + .cr3 = 0 +}; + +/* State of the leds on the keyboard */ +static volatile bool leds_enabled = false; + +void anne_pro_lighting_init(void) { + /* Turn on lighting controller */ + setPinOutput(C15); + writePinLow(C15); + chThdSleepMilliseconds(10); + writePinHigh(C15); + chThdSleepMilliseconds(10); + + /* Initialize the lighting UART */ + uartStart(LED_UART, &led_uart_cfg); + palSetPadMode(GPIOB, 10, PAL_MODE_ALTERNATE(7)); + palSetPadMode(GPIOB, 11, PAL_MODE_ALTERNATE(7)); +} + +/* Buffer for the keystate packet */ +static uint8_t keystate[12] = {9, 10, 7, 0}; + +/* Update the dynamic lighting packet based on a keypress */ +void anne_pro_lighting_update_dynamic(keyrecord_t *record) { + /* Only update dynamic lighting modes when leds are enabled */ + if (leds_enabled) { + /* Calculate the position of the key that was pressed */ + uint8_t row = record->event.key.row; + uint8_t col = record->event.key.col; + int position = row * MATRIX_COLS + col; + int index = position / 8; + int bit = position % 8; + + /* Update the keystate based on the location */ + if (record->event.pressed) { + keystate[3 + index] |= (1 << bit); + } else { + keystate[3 + index] &= ~(1 << bit); + } + + /* Send the keystate to the LED controller */ + uart_tx_ringbuf_write(&led_uart_ringbuf, 12, keystate); + } +} + +/* Update lighting, should be called every matrix scan */ +void anne_pro_lighting_update(void) { + if (led_uart_try_transmission) { + uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); + led_uart_try_transmission = false; + } +} + +/* Toggle the lighting on/off */ +void anne_pro_lighting_toggle(void) { + if (!leds_enabled) { + anne_pro_lighting_on(); + } else { + anne_pro_lighting_off(); + } +} + +/* Turn the lighting on */ +void anne_pro_lighting_on(void) { + uart_tx_ringbuf_write(&led_uart_ringbuf, 3, "\x09\x01\x01"); + leds_enabled = true; +} + +/* Turn the lighting off */ +void anne_pro_lighting_off(void) { + uart_tx_ringbuf_write(&led_uart_ringbuf, 4, "\x09\x02\x01\x00"); + leds_enabled = false; +} + +/* Select the next effect rate */ +void anne_pro_lighting_rate_next(void) { + if (leds_enabled) { + uart_tx_ringbuf_write(&led_uart_ringbuf, 6, "\x09\x04\x05\x00\x01\x00"); + } +} + +/* Select the next brightness */ +void anne_pro_lighting_brightness_next(void) { + if (leds_enabled) { + uart_tx_ringbuf_write(&led_uart_ringbuf, 6, "\x09\x04\x05\x00\x00\x01"); + } +} + +/* Select the next lighting mode */ +void anne_pro_lighting_mode_next(void) { + if (leds_enabled) { + uart_tx_ringbuf_write(&led_uart_ringbuf, 6, "\x09\x04\x05\x01\x00\x00"); + } +} + +/* Set the lighting mode */ +void anne_pro_lighting_mode(uint8_t mode) { + if (leds_enabled) { + uint8_t buf[] = {9, 2, 1, mode}; + uart_tx_ringbuf_write(&led_uart_ringbuf, 4, buf); + } +} + +/* Set the rate and brightness */ +void anne_pro_lighting_rate_brightness(uint8_t rate, uint8_t brightness) { + if (leds_enabled) { + if (brightness > 10) brightness = 10; + + uint8_t buf[] = {9, 4, 2, rate, brightness, 0}; + uart_tx_ringbuf_write(&led_uart_ringbuf, 6, buf); + } +} diff --git a/keyboards/anne_pro/anne_pro_lighting.h b/keyboards/anne_pro/anne_pro_lighting.h new file mode 100644 index 0000000000..e2e6bcd171 --- /dev/null +++ b/keyboards/anne_pro/anne_pro_lighting.h @@ -0,0 +1,51 @@ +/* Copyright 2019 Michiel Visser + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include "quantum.h" + +#define APL_MODE_OFF 0 +#define APL_MODE_RED 1 +#define APL_MODE_YELLOW 2 +#define APL_MODE_GREEN 3 +#define APL_MODE_CYAN 4 +#define APL_MODE_BLUE 5 +#define APL_MODE_PURPLE 6 +#define APL_MODE_PINK 7 +#define APL_MODE_ORANGE 8 +#define APL_MODE_WHITE 9 +#define APL_MODE_FLAG_FANCE 10 +#define APL_MODE_FLAG_ITALY 11 +#define APL_MODE_FLAG_ARGENTINA 12 +#define APL_MODE_BREATHING 13 +#define APL_MODE_RAINBOW 14 +#define APL_MODE_REACTIVE_FADE 15 +#define APL_MODE_REACTIVE_HOLD 16 +#define APL_MODE_REACTIVE_LINE 17 +#define APL_MODE_RANDOM 18 +#define APL_MODE_CUSTOM 128 + +void anne_pro_lighting_init(void); +void anne_pro_lighting_update(void); +void anne_pro_lighting_update_dynamic(keyrecord_t *record); +void anne_pro_lighting_toggle(void); +void anne_pro_lighting_on(void); +void anne_pro_lighting_off(void); +void anne_pro_lighting_rate_next(void); +void anne_pro_lighting_brightness_next(void); +void anne_pro_lighting_mode_next(void); +void anne_pro_lighting_mode(uint8_t mode); +void anne_pro_lighting_rate_brightness(uint8_t speed, uint8_t brightness); diff --git a/keyboards/anne_pro/rules.mk b/keyboards/anne_pro/rules.mk index 2e09e348f0..6c537567e6 100644 --- a/keyboards/anne_pro/rules.mk +++ b/keyboards/anne_pro/rules.mk @@ -23,6 +23,9 @@ ARMV = 7 # Extra arguments for dfu-util to flash to the correct location DFU_ARGS = -d 0483:df11 -a 0 -s 0x08004000 +# Extra source files +SRC += anne_pro_lighting.c + # Build Options # comment out to disable the options. #