 6edbd845eb
			
		
	
	
		6edbd845eb
		
			
		
	
	
	
	
		
			
			* Add BIOI Keyboards Add keyboards from BIOI, including dual-mode G60, Morgan65, and S65 * Update keyboards/bioi/g60/config.h Co-authored-by: Ryan <fauxpark@gmail.com> * Update keyboards/bioi/g60/config.h Co-authored-by: Ryan <fauxpark@gmail.com> * Update keyboards/bioi/g60/g60.c Co-authored-by: Ryan <fauxpark@gmail.com> * Update keyboards/bioi/g60/config.h Co-authored-by: Ryan <fauxpark@gmail.com> * Apply suggestions from code review Co-authored-by: Ryan <fauxpark@gmail.com> * Rename rule.mk to rules.mk * Rename rule.mk to rules.mk * Rename rule.mk to rules.mk * Update readme.md * Apply suggestions from code review Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com> * Update ble.h * Update config.h Change VenderID to 8101 * Update config.h * Update config.h * Update ble.c * Update ble.h * Add license headers * Apply suggestions from code review Co-authored-by: Drashna Jaelre <drashna@live.com> * Add license header in keymap files * Fix year in license header * Update keyboards/bioi/s65/readme.md Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com> Co-authored-by: Ryan <fauxpark@gmail.com> Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com> Co-authored-by: Drashna Jaelre <drashna@live.com>
		
			
				
	
	
		
			389 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			389 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
| Copyright 2019 Basic I/O Instruments(Scott Wei) <scot.wei@gmail.com>
 | |
| 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 <http://www.gnu.org/licenses/>.
 | |
| */
 | |
| 
 | |
| #include <avr/pgmspace.h>
 | |
| #include <util/delay.h>
 | |
| 
 | |
| #include "report.h"
 | |
| #include "host.h"
 | |
| #include "host_driver.h"
 | |
| #include "keyboard.h"
 | |
| #include "action.h"
 | |
| #include "led.h"
 | |
| #include "sendchar.h"
 | |
| #include "debug.h"
 | |
| #include "print.h"
 | |
| #ifdef SLEEP_LED_ENABLE
 | |
| #include "sleep_led.h"
 | |
| #endif
 | |
| #include "suspend.h"
 | |
| 
 | |
| #include "usb_descriptor.h"
 | |
| #include "lufa.h"
 | |
| #include "quantum.h"
 | |
| #include <util/atomic.h>
 | |
| #include "outputselect.h"
 | |
| 
 | |
| #ifdef NKRO_ENABLE
 | |
| #include "keycode_config.h"
 | |
| 
 | |
| extern keymap_config_t keymap_config;
 | |
| #endif
 | |
| 
 | |
| #ifdef AUDIO_ENABLE
 | |
| #include <audio.h>
 | |
| #endif
 | |
| 
 | |
| #ifdef BLUETOOTH_ENABLE
 | |
| #ifdef MODULE_ADAFRUIT_BLE
 | |
| #include "adafruit_ble.h"
 | |
| #else
 | |
| #include "bluetooth.h"
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
| #ifdef VIRTSER_ENABLE
 | |
| #include "virtser.h"
 | |
| #endif
 | |
| 
 | |
| #if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE)
 | |
| #include "rgblight.h"
 | |
| #endif
 | |
| 
 | |
| #ifdef MIDI_ENABLE
 | |
| #include "qmk_midi.h"
 | |
| #endif
 | |
| 
 | |
| #ifdef RAW_ENABLE
 | |
| #include "raw_hid.h"
 | |
| #endif
 | |
| 
 | |
| #include "ble.h"
 | |
| #include "usart.h"
 | |
| 
 | |
| #include <avr/power.h>
 | |
| #include <avr/sleep.h>
 | |
| 
 | |
| bool force_usb = false; //Reserved for FORCE USB Mode function.
 | |
| bool force_ble = false; //Reserved for FORCE USB Mode function.
 | |
| 
 | |
| bool usb_connected = false;
 | |
| bool ble_enabled = false;
 | |
| 
 | |
| uint32_t kb_idle_timer = 0;
 | |
| 
 | |
| bool usb_state_sent = false;
 | |
| 
 | |
| uint8_t USB_DeviceLastState = 0;
 | |
| 
 | |
| #ifdef RAW_ENABLE
 | |
| /** \brief Raw HID Task
 | |
|  *
 | |
|  * FIXME: Needs doc
 | |
|  */
 | |
| static void raw_hid_task(void)
 | |
| {
 | |
|     // Create a temporary buffer to hold the read in data from the host
 | |
|     uint8_t data[RAW_EPSIZE];
 | |
|     bool data_read = false;
 | |
| 
 | |
|     // Device must be connected and configured for the task to run
 | |
|     if (USB_DeviceState != DEVICE_STATE_Configured)
 | |
|         return;
 | |
| 
 | |
|     Endpoint_SelectEndpoint(RAW_OUT_EPNUM);
 | |
| 
 | |
|     // Check to see if a packet has been sent from the host
 | |
|     if (Endpoint_IsOUTReceived())
 | |
|     {
 | |
|         // Check to see if the packet contains data
 | |
|         if (Endpoint_IsReadWriteAllowed())
 | |
|         {
 | |
|             /* Read data */
 | |
|             Endpoint_Read_Stream_LE(data, sizeof(data), NULL);
 | |
|             data_read = true;
 | |
|         }
 | |
| 
 | |
|         // Finalize the stream transfer to receive the last packet
 | |
|         Endpoint_ClearOUT();
 | |
| 
 | |
|         if (data_read)
 | |
|         {
 | |
|             raw_hid_receive(data, sizeof(data));
 | |
|         }
 | |
|     }
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static void setup_mcu(void)
 | |
| {
 | |
|     /* Disable watchdog if enabled by bootloader/fuses */
 | |
|     MCUSR &= ~(1 << WDRF);
 | |
|     wdt_disable();
 | |
| 
 | |
|     CLKPR = (1 << CLKPCE);
 | |
|     CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
 | |
| }
 | |
| 
 | |
| static void setup_usb(void)
 | |
| {
 | |
|     // Leonardo needs. Without this USB device is not recognized.
 | |
|     USB_Disable();
 | |
| 
 | |
|     USB_Init();
 | |
| 
 | |
|     // for Console_Task
 | |
|     USB_Device_EnableSOFEvents();
 | |
|     print_set_sendchar(sendchar);
 | |
| }
 | |
| 
 | |
| void power_saving(void)
 | |
| {
 | |
|     power_adc_disable();
 | |
|     power_usart0_disable();
 | |
|     power_spi_disable();
 | |
|     power_twi_disable();
 | |
| 
 | |
|     USBCON |= (1 << FRZCLK); // Freeze the USB Clock
 | |
|     PLLCSR &= ~(1 << PLLE);  // Disable the USB Clock (PPL)
 | |
|     USBCON &= ~(1 << USBE);
 | |
| }
 | |
| 
 | |
| void power_recover(void)
 | |
| {
 | |
| 
 | |
|     USBCON |= (1 << USBE);
 | |
|     PLLCSR |= (1 << PLLE);    // Resume the USB Clock (PPL)
 | |
|     USBCON &= ~(1 << FRZCLK); // Resume the USB Clock
 | |
| 
 | |
|     power_adc_enable();
 | |
|     power_usart0_enable();
 | |
|     power_spi_enable();
 | |
|     power_twi_enable();
 | |
| }
 | |
| 
 | |
| void ble_task_init(void)
 | |
| {
 | |
|     kb_idle_timer = timer_read32();  //Mark current time, reserved for further usage;
 | |
| }
 | |
| 
 | |
| void ble_task(void)
 | |
| {
 | |
| 
 | |
|     if (USB_DeviceLastState != USB_DeviceState)
 | |
|     {
 | |
|         usb_state_sent = false;
 | |
| #ifdef BLE_DEBUG
 | |
|         send_str(PSTR("USB State Changed\r\n"));
 | |
|         if (USB_DeviceState == DEVICE_STATE_Unattached)
 | |
|         {
 | |
|             send_str(PSTR("USB State Unattached\r\n"));
 | |
|         }
 | |
| #endif
 | |
|         if (USB_DeviceState == DEVICE_STATE_Powered)
 | |
|         {
 | |
| #ifdef BLE_DEBUG
 | |
|             send_str(PSTR("USB State Powered\r\n"));
 | |
| #endif
 | |
|             power_recover();
 | |
|             host_set_driver(&null_driver);
 | |
|         }
 | |
| #ifdef BLE_DEBUG
 | |
|         if ((USB_DeviceState == DEVICE_STATE_Default))
 | |
|         {
 | |
|             send_str(PSTR("USB State Default\r\n"));
 | |
|         }
 | |
|         if ((USB_DeviceState == DEVICE_STATE_Addressed))
 | |
|         {
 | |
|             send_str(PSTR("USB State Addressed\r\n"));
 | |
|         }
 | |
|         if (USB_DeviceState == DEVICE_STATE_Configured)
 | |
|         {
 | |
|             send_str(PSTR("USB State Configured\r\n"));
 | |
|         }
 | |
|         if (USB_DeviceState > DEVICE_STATE_Unattached)
 | |
|         {
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             //
 | |
|         }
 | |
| #endif
 | |
|     }
 | |
|     else
 | |
|     {
 | |
| #ifdef BLE_DEBUG
 | |
|         if (!usb_state_sent)
 | |
|         {
 | |
|             if (USB_DeviceState == DEVICE_STATE_Unattached)
 | |
|             {
 | |
|                 send_str(PSTR("USB State Stopped at Unattached\r\n"));
 | |
|             }
 | |
|             if (USB_DeviceState == DEVICE_STATE_Powered)
 | |
|             {
 | |
|                 send_str(PSTR("USB State Stopped at Powered\r\n"));
 | |
|             }
 | |
|             if ((USB_DeviceState == DEVICE_STATE_Default))
 | |
|             {
 | |
|                 send_str(PSTR("USB State Stopped at Default\r\n"));
 | |
|             }
 | |
|             if ((USB_DeviceState == DEVICE_STATE_Addressed))
 | |
|             {
 | |
|                 send_str(PSTR("USB State Stopped at Addressed\r\n"));
 | |
|             }
 | |
|             if (USB_DeviceState == DEVICE_STATE_Configured)
 | |
|             {
 | |
|                 send_str(PSTR("USB State Stopped at Configured\r\n"));
 | |
|             }
 | |
|         }
 | |
| #endif
 | |
|         if (USB_DeviceState == DEVICE_STATE_Unattached)
 | |
|         {
 | |
|             if (host_get_driver() && host_get_driver() != &bluefruit_driver)
 | |
|             {
 | |
| #ifdef BLE_DEBUG
 | |
|                 send_str(PSTR("USB State stopped at Unattached\r\n"));
 | |
| #endif
 | |
|                 ble_task_init();
 | |
| 
 | |
|                 force_usb = 0;
 | |
|                 usb_connected = 0;
 | |
| 
 | |
|                 //Reinit USB to prepare for next connection.
 | |
|                 USB_Init();
 | |
|                 USB_Detach();
 | |
|                 USB_Attach();
 | |
| 
 | |
| #ifdef BLE_DEBUG
 | |
|                 send_str(PSTR("Loading &bluefruit_driver\r\n"));
 | |
| #endif
 | |
|                 host_set_driver(&bluefruit_driver);
 | |
|                 clear_keyboard();
 | |
|                 power_saving();
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 //Do nothing if USB is unattached and the driver is &bluefruit_driver
 | |
|             }
 | |
|         }
 | |
|         if (USB_DeviceState == DEVICE_STATE_Configured)
 | |
|         {
 | |
|             if (host_get_driver() && host_get_driver() != &lufa_driver)
 | |
|             {
 | |
| #ifdef BLE_DEBUG
 | |
|                 send_str(PSTR("USB State stopped at Configured\r\n"));
 | |
| #endif
 | |
|                 power_recover();
 | |
| 
 | |
|                 usb_connected = 1;
 | |
|                 ble_enabled = 0;
 | |
| #ifdef BLE_DEBUG
 | |
|                 send_str(PSTR("Loading &lufa_driver\r\n"));
 | |
| #endif
 | |
|                 host_set_driver(&lufa_driver);
 | |
|                 clear_keyboard();
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 //Do nothing if the driver is &lufa_driver
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         usb_state_sent = true;
 | |
|     }
 | |
| 
 | |
|     USB_DeviceLastState = USB_DeviceState;
 | |
| }
 | |
| 
 | |
| // Use a custom main() function because the task logic is different from the common one.
 | |
| int main(void)
 | |
| {
 | |
| #ifdef MIDI_ENABLE
 | |
|     setup_midi();
 | |
| #endif
 | |
| 
 | |
|     setup_mcu();
 | |
| 
 | |
|     keyboard_setup();
 | |
| 
 | |
|     setup_usb();
 | |
|     sei();
 | |
| 
 | |
| #if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42)
 | |
|     serial_init();
 | |
| #endif
 | |
| 
 | |
|     /* wait for USB startup to get ready for debug output */
 | |
|     uint8_t timeout = 255; // timeout when USB is not available(Bluetooth)
 | |
|     while (timeout-- && USB_DeviceState != DEVICE_STATE_Configured)
 | |
|     {
 | |
|         wait_ms(4);
 | |
| #if defined(INTERRUPT_CONTROL_ENDPOINT)
 | |
|         ;
 | |
| #else
 | |
|         USB_USBTask();
 | |
| #endif
 | |
|     }
 | |
| 
 | |
|     print("\nUSB init\n");
 | |
| 
 | |
|     keyboard_init();
 | |
|     host_set_driver(&lufa_driver);
 | |
| 
 | |
|     backlight_disable();
 | |
|     //host_set_driver(&lufa_driver);
 | |
|     print("Keyboard initialized.\n");
 | |
| 
 | |
|     //Init Hardware UART
 | |
|     usart_init();
 | |
| 
 | |
| #ifdef BLE_DEBUG
 | |
|     send_str(PSTR("Keyboard has been setup up\r\n"));
 | |
| 
 | |
|     if (usb_connected)
 | |
|     {
 | |
|         send_str(PSTR("usb_connected=1\r\n"));
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         send_str(PSTR("usb_connected=0\r\n"));
 | |
|     }
 | |
| #endif
 | |
| 
 | |
| #ifdef SLEEP_LED_ENABLE
 | |
|     sleep_led_init();
 | |
| #endif
 | |
| 
 | |
| #ifdef VIRTSER_ENABLE
 | |
|     virtser_init();
 | |
| #endif
 | |
| 
 | |
|     while (1)
 | |
|     {
 | |
|         ble_task();
 | |
|         keyboard_task();
 | |
| 
 | |
| #ifdef RAW_ENABLE
 | |
|         raw_hid_task();
 | |
| #endif
 | |
| 
 | |
| #if defined(RGBLIGHT_ANIMATIONS) && defined(RGBLIGHT_ENABLE)
 | |
|         rgblight_task();
 | |
| #endif
 | |
| 
 | |
| #if !defined(INTERRUPT_CONTROL_ENDPOINT)
 | |
|         USB_USBTask();
 | |
| #endif
 | |
|     }
 | |
| }
 |