/* Copyright 2011 Jun Wako 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 #include #include "wait.h" #include "keycode.h" #include "host.h" #include "keymap.h" #include "print.h" #include "debug.h" #include "util.h" #include "timer.h" #include "keyboard.h" #include "bootloader.h" #include "action_layer.h" #include "action_util.h" #include "eeconfig.h" #include "sleep_led.h" #include "led.h" #include "command.h" #include "backlight.h" #include "quantum.h" #include "version.h" #ifdef MOUSEKEY_ENABLE #include "mousekey.h" #endif #ifdef PROTOCOL_PJRC #include "usb_keyboard.h" #ifdef EXTRAKEY_ENABLE #include "usb_extra.h" #endif #endif #ifdef PROTOCOL_VUSB #include "usbdrv.h" #endif #ifdef AUDIO_ENABLE #include "audio.h" #endif /* AUDIO_ENABLE */ static bool command_common(uint8_t code); static void command_common_help(void); static void print_version(void); static void print_status(void); static bool command_console(uint8_t code); static void command_console_help(void); #ifdef MOUSEKEY_ENABLE static bool mousekey_console(uint8_t code); static void mousekey_console_help(void); #endif static void switch_default_layer(uint8_t layer); command_state_t command_state = ONESHOT; bool command_proc(uint8_t code) { switch (command_state) { case ONESHOT: if (!IS_COMMAND()) return false; return (command_extra(code) || command_common(code)); break; case CONSOLE: if (IS_COMMAND()) return (command_extra(code) || command_common(code)); else return (command_console_extra(code) || command_console(code)); break; #ifdef MOUSEKEY_ENABLE case MOUSEKEY: mousekey_console(code); break; #endif default: command_state = ONESHOT; return false; } return true; } /* TODO: Refactoring is needed. */ /* This allows to define extra commands. return false when not processed. */ bool command_extra(uint8_t code) __attribute__ ((weak)); bool command_extra(uint8_t code) { (void)code; return false; } bool command_console_extra(uint8_t code) __attribute__ ((weak)); bool command_console_extra(uint8_t code) { (void)code; return false; } /*********************************************************** * Command common ***********************************************************/ static void command_common_help(void) { print( "\n\t- Magic -\n" STR(MAGIC_KEY_DEBUG ) ": Debug Message Toggle\n" STR(MAGIC_KEY_DEBUG_MATRIX) ": Matrix Debug Mode Toggle - Show keypresses in matrix grid\n" STR(MAGIC_KEY_DEBUG_KBD ) ": Keyboard Debug Toggle - Show keypress report\n" STR(MAGIC_KEY_DEBUG_MOUSE ) ": Debug Mouse Toggle\n" STR(MAGIC_KEY_VERSION ) ": Version\n" STR(MAGIC_KEY_STATUS ) ": Status\n" STR(MAGIC_KEY_CONSOLE ) ": Activate Console Mode\n" #if MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM STR(MAGIC_KEY_LAYER0 ) ": Switch to Layer 0\n" STR(MAGIC_KEY_LAYER1 ) ": Switch to Layer 1\n" STR(MAGIC_KEY_LAYER2 ) ": Switch to Layer 2\n" STR(MAGIC_KEY_LAYER3 ) ": Switch to Layer 3\n" STR(MAGIC_KEY_LAYER4 ) ": Switch to Layer 4\n" STR(MAGIC_KEY_LAYER5 ) ": Switch to Layer 5\n" STR(MAGIC_KEY_LAYER6 ) ": Switch to Layer 6\n" STR(MAGIC_KEY_LAYER7 ) ": Switch to Layer 7\n" STR(MAGIC_KEY_LAYER8 ) ": Switch to Layer 8\n" STR(MAGIC_KEY_LAYER9 ) ": Switch to Layer 9\n" #endif #if MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS "F1-F10: Switch to Layer 0-9 (F10 = L0)\n" #endif #if MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS "0-9: Switch to Layer 0-9\n" #endif STR(MAGIC_KEY_LAYER0_ALT1 ) ": Switch to Layer 0 (alternate key 1)\n" STR(MAGIC_KEY_LAYER0_ALT2 ) ": Switch to Layer 0 (alternate key 2)\n" STR(MAGIC_KEY_BOOTLOADER ) ": Jump to Bootloader (Reset)\n" #ifdef KEYBOARD_LOCK_ENABLE STR(MAGIC_KEY_LOCK ) ": Lock\n" #endif #ifdef BOOTMAGIC_ENABLE STR(MAGIC_KEY_EEPROM ) ": Print EEPROM Settings\n" #endif #ifdef NKRO_ENABLE STR(MAGIC_KEY_NKRO ) ": NKRO Toggle\n" #endif #ifdef SLEEP_LED_ENABLE STR(MAGIC_KEY_SLEEP_LED ) ": Sleep LED Test\n" #endif ); } static void print_version(void) { // print version & information print("\n\t- Version -\n"); print("DESC: " STR(DESCRIPTION) "\n"); print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") " "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") " "VER: " STR(DEVICE_VER) "\n"); print("BUILD: " STR(QMK_VERSION) " (" __TIME__ " " __DATE__ ")\n"); /* build options */ print("OPTIONS:" #ifdef PROTOCOL_PJRC " PJRC" #endif #ifdef PROTOCOL_LUFA " LUFA" #endif #ifdef PROTOCOL_VUSB " VUSB" #endif #ifdef BOOTMAGIC_ENABLE " BOOTMAGIC" #endif #ifdef MOUSEKEY_ENABLE " MOUSEKEY" #endif #ifdef EXTRAKEY_ENABLE " EXTRAKEY" #endif #ifdef CONSOLE_ENABLE " CONSOLE" #endif #ifdef COMMAND_ENABLE " COMMAND" #endif #ifdef NKRO_ENABLE " NKRO" #endif #ifdef KEYMAP_SECTION_ENABLE " KEYMAP_SECTION" #endif " " STR(BOOTLOADER_SIZE) "\n"); print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__) #if defined(__AVR__) " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__ " AVR_ARCH: avr" STR(__AVR_ARCH__) #endif "\n"); return; } static void print_status(void) { print("\n\t- Status -\n"); print_val_hex8(host_keyboard_leds()); #ifndef PROTOCOL_VUSB // these aren't set on the V-USB protocol, so we just ignore them for now print_val_hex8(keyboard_protocol); print_val_hex8(keyboard_idle); #endif #ifdef NKRO_ENABLE print_val_hex8(keymap_config.nkro); #endif print_val_hex32(timer_read32()); #ifdef PROTOCOL_PJRC print_val_hex8(UDCON); print_val_hex8(UDIEN); print_val_hex8(UDINT); print_val_hex8(usb_keyboard_leds); print_val_hex8(usb_keyboard_idle_count); #endif #ifdef PROTOCOL_PJRC # if USB_COUNT_SOF print_val_hex8(usbSofCount); # endif #endif return; } #ifdef BOOTMAGIC_ENABLE static void print_eeconfig(void) { // Print these variables if NO_PRINT or USER_PRINT are not defined. #if !defined(NO_PRINT) && !defined(USER_PRINT) print("default_layer: "); print_dec(eeconfig_read_default_layer()); print("\n"); debug_config_t dc; dc.raw = eeconfig_read_debug(); print("debug_config.raw: "); print_hex8(dc.raw); print("\n"); print(".enable: "); print_dec(dc.enable); print("\n"); print(".matrix: "); print_dec(dc.matrix); print("\n"); print(".keyboard: "); print_dec(dc.keyboard); print("\n"); print(".mouse: "); print_dec(dc.mouse); print("\n"); keymap_config_t kc; kc.raw = eeconfig_read_keymap(); print("keymap_config.raw: "); print_hex8(kc.raw); print("\n"); print(".swap_control_capslock: "); print_dec(kc.swap_control_capslock); print("\n"); print(".capslock_to_control: "); print_dec(kc.capslock_to_control); print("\n"); print(".swap_lalt_lgui: "); print_dec(kc.swap_lalt_lgui); print("\n"); print(".swap_ralt_rgui: "); print_dec(kc.swap_ralt_rgui); print("\n"); print(".no_gui: "); print_dec(kc.no_gui); print("\n"); print(".swap_grave_esc: "); print_dec(kc.swap_grave_esc); print("\n"); print(".swap_backslash_backspace: "); print_dec(kc.swap_backslash_backspace); print("\n"); print(".nk
/*
    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include "ch.h"
#include "hal.h"

static void pwmpcb(PWMDriver *pwmp) {

  (void)pwmp;
  palClearPad(GPIOB, GPIOB_LED4);
}

static void pwmc1cb(PWMDriver *pwmp) {

  (void)pwmp;
  palSetPad(GPIOB, GPIOB_LED4);
}

static PWMConfig pwmcfg = {
  10000,                                    /* 10kHz PWM clock frequency.   */
  10000,                                    /* Initial PWM period 1S.       */
  pwmpcb,
  {
   {PWM_OUTPUT_ACTIVE_HIGH, pwmc1cb},
   {PWM_OUTPUT_DISABLED, NULL},
   {PWM_OUTPUT_DISABLED, NULL},
   {PWM_OUTPUT_DISABLED, NULL}
  },
  0,
  0
};

icucnt_t last_width, last_period;

static void icuwidthcb(ICUDriver *icup) {

  palSetPad(GPIOB, GPIOB_LED3);
  last_width = icuGetWidthX(icup);
}

static void icuperiodcb(ICUDriver *icup) {

  palClearPad(GPIOB, GPIOB_LED3);
  last_period = icuGetPeriodX(icup);
}

static ICUConfig icucfg = {
  ICU_INPUT_ACTIVE_HIGH,
  10000,                                    /* 10kHz ICU clock frequency.   */
  icuwidthcb,
  icuperiodcb,
  NULL,
  ICU_CHANNEL_1,
  0
};

/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Initializes the PWM driver 2 and ICU driver 3.
   * GPIOA15 is the PWM output.
   * GPIOC6 is the ICU input.
   * The two pins have to be externally connected together.
   */
  pwmStart(&PWMD2, &pwmcfg);
  pwmEnablePeriodicNotification(&PWMD2);
  palSetPadMode(GPIOA, 15, PAL_MODE_ALTERNATE(1));
  icuStart(&ICUD3, &icucfg);
  palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2));
  icuStartCapture(&ICUD3);
  icuEnableNotifications(&ICUD3);
  chThdSleepMilliseconds(2000);

  /*
   * Starts the PWM channel 0 using 75% duty cycle.
   */
  pwmEnableChannel(&PWMD2, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, 7500));
  pwmEnableChannelNotification(&PWMD2, 0);
  chThdSleepMilliseconds(5000);

  /*
   * Changes the PWM channel 0 to 50% duty cycle.
   */
  pwmEnableChannel(&PWMD2, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, 5000));
  chThdSleepMilliseconds(5000);

  /*
   * Changes the PWM channel 0 to 25% duty cycle.
   */
  pwmEnableChannel(&PWMD2, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, 2500));
  chThdSleepMilliseconds(5000);

  /*
   * Changes PWM period to half second the duty cycle becomes 50%
   * implicitly.
   */
  pwmChangePeriod(&PWMD2, 5000);
  chThdSleepMilliseconds(5000);

  /*
   * Disables channel 0 and stops the drivers.
   */
  pwmDisableChannel(&PWMD2, 0);
  pwmStop(&PWMD2);
  icuStopCapture(&ICUD3);
  icuStop(&ICUD3);
  palClearPad(GPIOB, GPIOB_LED3);
  palClearPad(GPIOB, GPIOB_LED4);

  /*
   * Normal main() thread activity, in this demo it does nothing.
   */
  while (true) {
    chThdSleepMilliseconds(500);
  }
  return 0;
}