Compare commits

..

No commits in common. "master" and "bringup" have entirely different histories.

116 changed files with 1025 additions and 7278 deletions

View file

@ -1,16 +0,0 @@
---
Checks: 'clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-alpha*'
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
User: hyatt
CheckOptions:
- key: google-readability-braces-around-statements.ShortStatementLines
value: '1'
- key: google-readability-function-size.StatementThreshold
value: '800'
- key: google-readability-namespace-comments.ShortNamespaceLines
value: '10'
- key: google-readability-namespace-comments.SpacesBeforeComments
value: '2'
...

2
.gitignore vendored
View file

@ -41,7 +41,6 @@
.Trashes
ehthumbs.db
Thumbs.db
*.attr
# Editor generated files #
##########################
@ -56,7 +55,6 @@ tags
CMakeFiles
CMakeCache.txt
cmake_install.cmake
compile_commands.json
# External Repos #
##################

View file

@ -2,26 +2,17 @@
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{ID_MM_DEVICE_IGNORE}="1"
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{MTP_NO_PROBE}="1"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666"
# Kiibohd Serial Interface
KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", SYMLINK+="kiibohd", MODE:="0666",
KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", SYMLINK+="kiibohd", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", SYMLINK+="kiibohd", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", MODE:="0666"
# Kiibohd Device
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", MODE:="0666"
# DFU Bootloader (MCHCK)
ATTRS{idVendor}=="2323", ATTRS{idProduct}=="0001", ENV{ID_MM_DEVICE_IGNORE}="1"
ATTRS{idVendor}=="2323", ATTRS{idProduct}=="0001", ENV{MTP_NO_PROBE}="1"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2323", ATTRS{idProduct}=="0001", MODE:="0666"
# Kiibohd DFU Bootloader
ATTRS{idVendor}=="1C11", ATTRS{idProduct}=="b007", ENV{ID_MM_DEVICE_IGNORE}="1"
ATTRS{idVendor}=="1C11", ATTRS{idProduct}=="b007", ENV{MTP_NO_PROBE}="1"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b007", MODE:="0666"
# Kiibohd Force Gauge
SUBSYSTEM=="tty", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", GROUP="users", MODE="0666", SYMLINK+="force"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", MODE:="0666"

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
# Just in case there was an extra ledTest.bash (don't care if error)
rm /dev/ttyACM0

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
# Combines a given bootloader image and firmware image into a single firmware binary
# Manufacturing deliverable

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
printf "led\r" > /dev/ttyACM0

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
# Loads firmware image using an SWD Flasher
# Uses MCHCK ruby flasher toolchain
# NOTE: Only tested with a buspirate on Linux

View file

@ -53,7 +53,6 @@ void uart_serial_setup();
// Convenience
#define printHex(hex) printHex_op(hex, 1)
#define printHex32(hex) printHex_op(hex, 1)
void printHex_op( uint32_t in, uint8_t op );
#else
@ -61,7 +60,6 @@ void printHex_op( uint32_t in, uint8_t op );
#define uart_serial_write(buf,size)
#define uart_serial_setup()
#define printHex(hex)
#define printHex32(hex)
#define printHex_op(in,op)
#endif

View file

@ -1,5 +1,5 @@
// Originally Generated from MCHCK Toolkit
/* Copyright (c) Jacob Alexander 2014-2016 <haata@kiibohd.com>
/* Copyright (c) Jacob Alexander 2014-2015 <haata@kiibohd.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
@ -38,7 +38,7 @@ static const struct usb_config_1 usb_config_1 = {
.bConfigurationValue = 1,
.iConfiguration = 0,
.one = 1,
.bMaxPower = 50
.bMaxPower = 100
},
.usb_function_0 = {
.iface = {

View file

@ -192,12 +192,6 @@ void main()
// Setup pin - A5 - See Lib/pin_map.mchck for more details on pins
PORTA_PCR5 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
GPIOA_PSOR |= (1<<5);
// TODO Add CMake configuration for disabling
// Set LCD backlight on ICED to Red
GPIOC_PDDR |= (1<<1);
PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
GPIOC_PCOR |= (1<<1);
#else
#error "Incompatible chip for bootloader"
#endif
@ -216,6 +210,35 @@ void main()
printHex( memcmp( (uint8_t*)&VBAT, sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic) ) == 0 );
print( NL );
// XXX REMOVEME
/*
GPIOB_PDDR |= (1<<16);
PORTB_PCR16 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
GPIOB_PSOR |= (1<<16);
// RST
GPIOC_PDDR |= (1<<8);
PORTC_PCR8 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
GPIOC_PSOR |= (1<<8);
// CS1B
GPIOC_PDDR |= (1<<4);
PORTC_PCR4 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
GPIOC_PCOR |= (1<<4);
*/
// Backlight
/*
GPIOC_PDDR |= (1<<1);
PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
GPIOC_PCOR |= (1<<1);
GPIOC_PDDR |= (1<<2);
PORTC_PCR2 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
GPIOC_PCOR |= (1<<2);
GPIOC_PDDR |= (1<<3);
PORTC_PCR3 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
GPIOC_PCOR |= (1<<3);
*/
#ifdef FLASH_DEBUG
for ( uint8_t sector = 0; sector < 3; sector++ )
sector_print( &_app_rom, sector, 16 );

View file

@ -1,6 +1,6 @@
###| CMAKE Kiibohd Controller |###
#
# Jacob Alexander 2011-2016
# Jacob Alexander 2011-2015
# Due to this file's usefulness:
#
# Released into the Public Domain
@ -22,11 +22,10 @@ set( CHIP
# "at90usb646" # Teensy++ 1.0 (avr)
# "at90usb1286" # Teensy++ 2.0 (avr)
# "mk20dx128" # Teensy 3.0 (arm)
# "mk20dx128vlf5" # McHCK mk20dx128vlf5
# "mk20dx256" # Teensy 3.1,3.2 (arm)
"mk20dx256vlh7" # Kiibohd-dfu mk20dx256vlh7
CACHE STRING "Microcontroller Chip"
)
"mk20dx128vlf5" # McHCK mk20dx128vlf5
# "mk20dx256" # Teensy 3.1 (arm)
# "mk20dx256vlh7" # Kiibohd-dfu mk20dx256vlh7
CACHE STRING "Microcontroller Chip" )
@ -34,14 +33,13 @@ set( CHIP
# Compiler Selection
#
#| gcc has been tested much more (and will likely give smaller binaries)
#| clang does work though
#| *** EXPERIMENTAL ***
#| Stick with gcc unless you know what you're doing
#| Currently only arm is supported with clang
set( COMPILER
"gcc" # arm-none-eabi-gcc / avr-gcc - Default
# "clang" # arm-none-eabi
CACHE STRING "Compiler Type"
)
CACHE STRING "Compiler Type" )
@ -65,7 +63,7 @@ include( initialize )
#| Please look at the {Scan,Macro,Output,Debug} for information on the modules and how to create new ones
##| Deals with acquiring the keypress information and turning it into a key index
set( ScanModule "MDErgo1"
set( ScanModule "MD1"
CACHE STRING "Scan Module" )
##| Provides the mapping functions for DefaultMap and handles any macro processing before sending to the OutputModule
@ -74,13 +72,11 @@ set( MacroModule "PartialMap"
##| Sends the current list of usb key codes through USB HID
set( OutputModule "pjrcUSB"
CACHE STRING "Output Module"
)
CACHE STRING "Output Module" )
##| Debugging source to use, each module has it's own set of defines that it sets
set( DebugModule "full"
CACHE STRING "Debug Module"
)
CACHE STRING "Debug Module" )
@ -110,6 +106,7 @@ set( DebugModule "full"
##| Set the base keyboard .kll map, defaults to "defaultMap" if not found
##| Looks in Scan/<Module Name> for the available BaseMaps
##| TODO Support layering in basemap
set( BaseMap "defaultMap"
CACHE STRING "KLL BaseMap/Scancode Keymapping" )

View file

@ -21,12 +21,14 @@
// ----- Includes -----
// Compiler Includes
//#include <stdarg.h>
// Project Includes
#include <buildvars.h>
#include "cli.h"
#include <led.h>
#include <print.h>
#include <kll_defs.h>
@ -159,12 +161,15 @@ void CLI_process()
}
else
{
// Add the command to the history
CLI_saveHistory( CLILineBuffer );
// Only do command-related stuff if there was actually a command
// Avoids clogging command history with blanks
// Process the current line buffer
CLI_commandLookup();
// Add the command to the history
CLI_saveHistory( CLILineBuffer );
// Keep the array circular, discarding the older entries
if ( CLIHistoryTail < CLIHistoryHead )
CLIHistoryHead = ( CLIHistoryHead + 1 ) % CLIMaxHistorySize;
@ -422,11 +427,6 @@ inline void CLI_saveHistory( char *buff )
return;
}
// Don't write empty lines to the history
const char *cursor = buff;
while (*cursor == ' ') { cursor++; } // advance past the leading whitespace
if (*cursor == '\0') { return ; }
// Copy the line to the history
int i;
for (i = 0; i < CLILineBufferCurrent; i++)
@ -517,14 +517,6 @@ void cliFunc_led( char* args )
void cliFunc_reload( char* args )
{
if ( flashModeEnabled_define == 0 )
{
print( NL );
warn_print("flashModeEnabled not set, cancelling firmware reload...");
info_msg("Set flashModeEnabled to 1 in your kll configuration.");
return;
}
// Request to output module to be set into firmware reload mode
Output_firmwareReload();
}
@ -556,15 +548,5 @@ void cliFunc_version( char* args )
print( " \033[1mCPU:\033[0m " CLI_CPU NL );
print( " \033[1mDevice:\033[0m " CLI_Device NL );
print( " \033[1mModules:\033[0m " CLI_Modules NL );
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_)
print( " \033[1mUnique Id:\033[0m " );
printHex32_op( SIM_UIDH, 4 );
printHex32_op( SIM_UIDMH, 4 );
printHex32_op( SIM_UIDML, 4 );
printHex32_op( SIM_UIDL, 4 );
#elif defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_)
#else
#error "No unique id defined."
#endif
}

View file

@ -28,9 +28,7 @@ Projects
--------
* infinity.bash (Infinity Keyboard 2014/10/15)
* ergodox.bash (Infinity Ergodox 2015/08/15)
* template.bash (Example template for new keyboards)
* whitefox.bash (Soon?)
**Extra files**

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
# This is bash lib file for the convenience build scripts
# Don't call this script directly
# Jacob Alexander 2015
@ -82,19 +82,7 @@ done
mkdir -p "${BuildPath}"
cd "${BuildPath}"
cmake -DCHIP="${Chip}" -DCOMPILER="${Compiler}" -DScanModule="${ScanModule}" -DMacroModule="${MacroModule}" -DOutputModule="${OutputModule}" -DDebugModule="${DebugModule}" -DBaseMap="${BaseMap}" -DDefaultMap="${DefaultMap}" -DPartialMaps="${PartialMapsExpanded}" "${CMakeListsPath}"
return_code=$?
if [ $return_code != 0 ] ; then
echo "Error in cmake. Exiting..."
exit $return_code
fi
make
return_code=$?
if [ $return_code != 0 ] ; then
echo "Error in make. Exiting..."
exit $return_code
fi
echo "Firmware has been compiled into: '${BuildPath}'"
cd -

View file

@ -1,97 +0,0 @@
#!/usr/bin/env bash
# This is a build script template
# These build scripts are just a convenience for configuring your keyboard (less daunting than CMake)
# Jacob Alexander 2015
#################
# Configuration #
#################
######## Left Side ########
# Feel free to change the variables in this section to configure your keyboard
BuildPath="ICED-L"
## KLL Configuration ##
# Generally shouldn't be changed, this will affect every layer
BaseMap="defaultMap leftHand slave1 rightHand"
# This is the default layer of the keyboard
# NOTE: To combine kll files into a single layout, separate them by spaces
# e.g. DefaultMap="mylayout mylayoutmod"
DefaultMap="mdergo1Overlay lcdFuncMap"
# This is where you set the additional layers
# NOTE: Indexing starts at 1
# NOTE: Each new layer is another array entry
# e.g. PartialMaps[1]="layer1 layer1mod"
# PartialMaps[2]="layer2"
# PartialMaps[3]="layer3"
PartialMaps[1]="iced_func"
PartialMaps[2]="iced_numpad"
##########################
# Advanced Configuration #
##########################
# Don't change the variables in this section unless you know what you're doing
# These are useful for completely custom keyboards
# NOTE: Changing any of these variables will require a force build to compile correctly
# Keyboard Module Configuration
ScanModule="MDErgo1"
MacroModule="PartialMap"
OutputModule="pjrcUSB"
DebugModule="full"
# Microcontroller
Chip="mk20dx256vlh7"
# Compiler Selection
Compiler="gcc"
########################
# Bash Library Include #
########################
# Shouldn't need to touch this section
# Check if the library can be found
if [ ! -f cmake.bash ]; then
echo "ERROR: Cannot find 'cmake.bash'"
exit 1
fi
# Load the library
source cmake.bash
#########################
# Re-run for right side #
#########################
######## Right Side ########
# Feel free to change the variables in this section to configure your keyboard
BuildPath="ICED-R"
## KLL Configuration ##
# Only changing the basemap (everything else is the same)
# Generally shouldn't be changed, this will affect every layer
BaseMap="defaultMap rightHand slave1 leftHand"
# Load the library (starts the build)
source cmake.bash

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
# This is a build script template
# These build scripts are just a convenience for configuring your keyboard (less daunting than CMake)
# Jacob Alexander 2015
@ -11,7 +11,7 @@
# Feel free to change the variables in this section to configure your keyboard
BuildPath="IC60"
BuildPath="template"
## KLL Configuration ##

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
# This is a build script template
# These build scripts are just a convenience for configuring your keyboard (less daunting than CMake)
# Jacob Alexander 2015

View file

@ -1,72 +0,0 @@
#!/usr/bin/env bash
# This is a build script template
# These build scripts are just a convenience for configuring your keyboard (less daunting than CMake)
# Jacob Alexander 2015
#################
# Configuration #
#################
# Feel free to change the variables in this section to configure your keyboard
BuildPath="WhiteFox"
## KLL Configuration ##
# Generally shouldn't be changed, this will affect every layer
BaseMap="defaultMap"
# This is the default layer of the keyboard
# NOTE: To combine kll files into a single layout, separate them by spaces
# e.g. DefaultMap="mylayout mylayoutmod"
DefaultMap="stdFuncMap"
# This is where you set the additional layers
# NOTE: Indexing starts at 1
# NOTE: Each new layer is another array entry
# e.g. PartialMaps[1]="layer1 layer1mod"
# PartialMaps[2]="layer2"
# PartialMaps[3]="layer3"
PartialMaps[1]="whitefox"
##########################
# Advanced Configuration #
##########################
# Don't change the variables in this section unless you know what you're doing
# These are useful for completely custom keyboards
# NOTE: Changing any of these variables will require a force build to compile correctly
# Keyboard Module Configuration
ScanModule="WhiteFox"
MacroModule="PartialMap"
OutputModule="pjrcUSB"
DebugModule="full"
# Microcontroller
Chip="mk20dx256vlh7"
# Compiler Selection
Compiler="gcc"
########################
# Bash Library Include #
########################
# Shouldn't need to touch this section
# Check if the library can be found
if [ ! -f cmake.bash ]; then
echo "ERROR: Cannot find 'cmake.bash'"
exit 1
fi
# Load the library
source cmake.bash

View file

@ -1,6 +1,6 @@
###| CMAKE Kiibohd Controller |###
#
# Jacob Alexander 2011-2016
# Jacob Alexander 2011-2014
# Due to this file's usefulness:
#
# Released into the Public Domain
@ -111,13 +111,6 @@ set( COMPILER_SRCS
Lib/delay.c
)
#| Clang needs a few more functions for linking
if ( "${COMPILER}" MATCHES "clang" )
set( COMPILER_SRCS ${COMPILER_SRCS}
Lib/clang.c
)
endif ()
message( STATUS "Compiler Source Files:" )
message( "${COMPILER_SRCS}" )

View file

@ -135,23 +135,3 @@ elseif ( DEFINED TEENSY )
endif()
endif()
###
# Compiler Command Generation
#
#| Generate list of compiler commands for clang-tidy usage
set( CMAKE_EXPORT_COMPILE_COMMANDS ON )
#| Make sure symlink exists (for convenience)
if ( UNIX )
# Make sure symlink is created immediately
execute_process ( COMMAND ln -sfn ${CMAKE_BINARY_DIR}/compile_commands.json ${CMAKE_SOURCE_DIR}/. )
# Also update before each build
add_custom_command( TARGET ${TARGET_ELF} POST_BUILD
COMMAND ln -sfn ${CMAKE_BINARY_DIR}/compile_commands.json ${CMAKE_SOURCE_DIR}/.
)
endif ()

View file

@ -20,22 +20,22 @@ if ( "${MacroModule}" STREQUAL "PartialMap" )
#
if ( NOT EXISTS "${PROJECT_SOURCE_DIR}/kll/kll.py" )
message ( STATUS "Downloading latest kll version:" )
message ( STATUS "Downloading latest kll version:" )
# Make sure git is available
find_package ( Git REQUIRED )
# Make sure git is available
find_package ( Git REQUIRED )
# Clone kll git repo
execute_process ( COMMAND ${GIT_EXECUTABLE} clone https://github.com/kiibohd/kll.git
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
# Clone kll git repo
execute_process ( COMMAND ${GIT_EXECUTABLE} clone https://github.com/kiibohd/kll.git
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
elseif ( REFRESH_KLL ) # Otherwise attempt to update the repo
message ( STATUS "Checking for latest kll version:" )
message ( STATUS "Checking for latest kll version:" )
# Clone kll git repo
execute_process ( COMMAND ${GIT_EXECUTABLE} pull --rebase
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/kll
)
# Clone kll git repo
execute_process ( COMMAND ${GIT_EXECUTABLE} pull --rebase
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/kll
)
endif () # kll/kll.py exists
@ -48,80 +48,69 @@ endif () # kll/kll.py exists
#| Add each of the detected capabilities.kll
foreach ( filename ${ScanModule_KLL} ${MacroModule_KLL} ${OutputModule_KLL} ${DebugModule_KLL} )
set ( BaseMap_Args ${BaseMap_Args} ${filename} )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${filename} )
set ( BaseMap_Args ${BaseMap_Args} ${filename} )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${filename} )
endforeach ()
#| If set BaseMap cannot be found, use default map
set ( pathname "${PROJECT_SOURCE_DIR}/${ScanModulePath}" )
string ( REPLACE " " ";" MAP_LIST ${BaseMap} ) # Change spaces to semicolons
foreach ( MAP ${MAP_LIST} )
# Only check the Scan Module for BaseMap .kll files, default to defaultMap.kll
if ( NOT EXISTS ${pathname}/${MAP}.kll )
set ( BaseMap_Args ${BaseMap_Args} ${pathname}/defaultMap.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/defaultMap.kll )
elseif ( EXISTS "${pathname}/${MAP}.kll" )
set ( BaseMap_Args ${BaseMap_Args} ${pathname}/${MAP}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/${MAP}.kll )
else ()
message ( FATAL " Could not find '${MAP}.kll' BaseMap in Scan module directory" )
endif ()
endforeach ()
if ( NOT EXISTS ${pathname}/${BaseMap}.kll )
set ( BaseMap_Args ${BaseMap_Args} ${pathname}/defaultMap.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/defaultMap.kll )
elseif ( EXISTS "${pathname}/${BaseMap}.kll" )
set ( BaseMap_Args ${BaseMap_Args} ${pathname}/${BaseMap}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${pathname}/${BaseMap}.kll )
else ()
message ( FATAL "Could not find '${BaseMap}.kll'" )
endif ()
#| Configure DefaultMap if specified
if ( NOT "${DefaultMap}" STREQUAL "" )
set ( DefaultMap_Args -d )
set ( DefaultMap_Args -d )
string ( REPLACE " " ";" MAP_LIST ${DefaultMap} ) # Change spaces to semicolons
foreach ( MAP ${MAP_LIST} )
# Check if kll file is in build directory, otherwise default to layout directory
if ( EXISTS "${PROJECT_BINARY_DIR}/${MAP}.kll" )
set ( DefaultMap_Args ${DefaultMap_Args} ${MAP}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_BINARY_DIR}/${MAP}.kll )
elseif ( EXISTS "${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll" )
set ( DefaultMap_Args ${DefaultMap_Args} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll )
elseif ( EXISTS "${PROJECT_SOURCE_DIR}/Layouts/${MAP}.kll" )
set ( PartialMap_Args ${PartialMap_Args} ${PROJECT_SOURCE_DIR}/Layouts/${MAP}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/Layouts/${MAP}.kll )
else ()
message ( FATAL " Could not find '${MAP}.kll' DefaultMap" )
endif ()
endforeach ()
string ( REPLACE " " ";" MAP_LIST ${DefaultMap} ) # Change spaces to semicolons
foreach ( MAP ${MAP_LIST} )
# Check if kll file is in build directory, otherwise default to layout directory
if ( EXISTS "${PROJECT_BINARY_DIR}/${MAP}.kll" )
set ( DefaultMap_Args ${DefaultMap_Args} ${MAP}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_BINARY_DIR}/${MAP}.kll )
elseif ( EXISTS "${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll" )
set ( DefaultMap_Args ${DefaultMap_Args} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP}.kll )
else ()
message ( FATAL "Could not find '${MAP}.kll'" )
endif ()
endforeach ()
endif ()
#| Configure PartialMaps if specified
if ( NOT "${PartialMaps}" STREQUAL "" )
# For each partial layer
foreach ( MAP ${PartialMaps} )
set ( PartialMap_Args ${PartialMap_Args} -p )
# For each partial layer
foreach ( MAP ${PartialMaps} )
set ( PartialMap_Args ${PartialMap_Args} -p )
# Combine each layer
string ( REPLACE " " ";" MAP_LIST ${MAP} ) # Change spaces to semicolons
foreach ( MAP_PART ${MAP_LIST} )
# Check if kll file is in build directory, otherwise default to layout directory
if ( EXISTS "${PROJECT_BINARY_DIR}/${MAP_PART}.kll" )
set ( PartialMap_Args ${PartialMap_Args} ${MAP_PART}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_BINARY_DIR}/${MAP_PART}.kll )
elseif ( EXISTS "${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll" )
set ( PartialMap_Args ${PartialMap_Args} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll )
elseif ( EXISTS "${PROJECT_SOURCE_DIR}/Layouts/${MAP_PART}.kll" )
set ( PartialMap_Args ${PartialMap_Args} ${PROJECT_SOURCE_DIR}/Layouts/${MAP_PART}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/Layouts/${MAP_PART}.kll )
else ()
message ( FATAL " Could not find '${MAP_PART}.kll' PartialMap" )
endif ()
endforeach ()
endforeach ()
# Combine each layer
string ( REPLACE " " ";" MAP_LIST ${MAP} ) # Change spaces to semicolons
foreach ( MAP_PART ${MAP_LIST} )
# Check if kll file is in build directory, otherwise default to layout directory
if ( EXISTS "${PROJECT_BINARY_DIR}/${MAP_PART}.kll" )
set ( PartialMap_Args ${PartialMap_Args} ${MAP_PART}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_BINARY_DIR}/${MAP_PART}.kll )
elseif ( EXISTS "${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll" )
set ( PartialMap_Args ${PartialMap_Args} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll )
set ( KLL_DEPENDS ${KLL_DEPENDS} ${PROJECT_SOURCE_DIR}/kll/layouts/${MAP_PART}.kll )
else ()
message ( FATAL "Could not find '${MAP_PART}.kll'" )
endif ()
endforeach ()
endforeach ()
endif ()
#| Print list of layout sources used
message ( STATUS "Detected Layout Files:" )
foreach ( filename ${KLL_DEPENDS} )
message ( "${filename}" )
message ( "${filename}" )
endforeach ()
@ -139,15 +128,15 @@ set ( kll_output --outputs ${kll_outputname} )
#| KLL Cmd
set ( kll_cmd ${PROJECT_SOURCE_DIR}/kll/kll.py ${BaseMap_Args} ${DefaultMap_Args} ${PartialMap_Args} ${kll_backend} ${kll_template} ${kll_output} )
add_custom_command ( OUTPUT ${kll_outputname}
COMMAND ${kll_cmd}
DEPENDS ${KLL_DEPENDS}
COMMENT "Generating KLL Layout"
COMMAND ${kll_cmd}
DEPENDS ${KLL_DEPENDS}
COMMENT "Generating KLL Layout"
)
#| KLL Regen Convenience Target
add_custom_target ( kll_regen
COMMAND ${kll_cmd}
COMMENT "Re-generating KLL Layout"
COMMAND ${kll_cmd}
COMMENT "Re-generating KLL Layout"
)
#| Append generated file to required sources so it becomes a dependency in the main build

View file

@ -277,7 +277,7 @@ if ( CTAGS_EXECUTABLE )
endforeach ()
# Generate the ctags
execute_process ( COMMAND ctags --fields=+l ${CTAG_PATHS}
execute_process ( COMMAND ctags ${CTAG_PATHS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
endif ()

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
#| Jacob Alexander 2014
#| Arg List
#| 1 - size binary (e.g. avr-size)

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
#| Jacob Alexander 2014
#| Arg List
#| 1 - File to write to (e.g. final_chip)

View file

@ -1,61 +0,0 @@
/* Copyright (C) 2016 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// This file adds various functions that clang doesn't link properly
// AFAIK, clang doesn't have an elegant solution for this, so this is what we gotta do...
// ----- Includes -----
// Compiler Includes
#include <string.h>
void __aeabi_memcpy( void *dest, const void *src, size_t n )
{
(void)memcpy(dest, src, n);
}
void __aeabi_memcpy4( void *dest, const void *src, size_t n )
{
memcpy(dest, src, n);
}
void __aeabi_memclr( void *dest, size_t n )
{
memset(dest, 0, n);
}
void __aeabi_memclr4( void *dest, size_t n )
{
memset(dest, 0, n);
}
void __aeabi_memmove( void *dest, const void *src, size_t n )
{
(void)memmove(dest, src, n);
}
void __aeabi_memset( void *s, size_t n, int c )
{
(void)memset(s, c, n);
}

View file

@ -70,7 +70,7 @@ void ResetHandler();
// NVIC - Default ISR
void fault_isr()
{
print("Fault!" NL );
print("Fault!");
while ( 1 )
{
// keep polling some communication while in fault
@ -99,48 +99,35 @@ void systick_default_isr()
// NVIC - Non-Maskable Interrupt ISR
void nmi_default_isr()
{
print("NMI!" NL );
print("NMI!");
}
// NVIC - Hard Fault ISR
void hard_fault_default_isr()
{
print("Hard Fault! SCB_HFSR: ");
printHex32( SCB_HFSR );
print( NL );
SOFTWARE_RESET();
print("Hard Fault!");
}
// NVIC - Memory Manager Fault ISR
void memmanage_fault_default_isr()
{
print("Memory Manager Fault! SCB_CFSR: ");
printHex32( SCB_CFSR );
print(" SCB_MMAR: ");
printHex32( SCB_MMAR );
print( NL );
print("Memory Manager Fault!");
}
// NVIC - Bus Fault ISR
void bus_fault_default_isr()
{
print("Bus Fault! SCB_CFSR: ");
printHex32( SCB_CFSR );
print(" SCB_BFAR: ");
printHex32( SCB_BFAR );
print( NL );
print("Bus Fault!");
}
// NVIC - Usage Fault ISR
void usage_fault_default_isr()
{
print("Usage Fault! SCB_CFSR: ");
printHex32( SCB_CFSR );
print( NL );
print("Usage Fault!");
}

View file

@ -511,37 +511,11 @@
#define DMA_ERQ_ERQ1 ((uint32_t)1<<1) // Enable DMA Request 1
#define DMA_ERQ_ERQ2 ((uint32_t)1<<2) // Enable DMA Request 2
#define DMA_ERQ_ERQ3 ((uint32_t)1<<3) // Enable DMA Request 3
#define DMA_ERQ_ERQ4 ((uint32_t)1<<4) // Enable DMA Request 4
#define DMA_ERQ_ERQ5 ((uint32_t)1<<5) // Enable DMA Request 5
#define DMA_ERQ_ERQ6 ((uint32_t)1<<6) // Enable DMA Request 6
#define DMA_ERQ_ERQ7 ((uint32_t)1<<7) // Enable DMA Request 7
#define DMA_ERQ_ERQ8 ((uint32_t)1<<8) // Enable DMA Request 8
#define DMA_ERQ_ERQ9 ((uint32_t)1<<9) // Enable DMA Request 9
#define DMA_ERQ_ERQ10 ((uint32_t)1<<10) // Enable DMA Request 10
#define DMA_ERQ_ERQ11 ((uint32_t)1<<11) // Enable DMA Request 11
#define DMA_ERQ_ERQ12 ((uint32_t)1<<12) // Enable DMA Request 12
#define DMA_ERQ_ERQ13 ((uint32_t)1<<13) // Enable DMA Request 13
#define DMA_ERQ_ERQ14 ((uint32_t)1<<14) // Enable DMA Request 14
#define DMA_ERQ_ERQ15 ((uint32_t)1<<15) // Enable DMA Request 15
#define DMA_ERQ_ERQ16 ((uint32_t)1<<16) // Enable DMA Request 16
#define DMA_EEI *(volatile uint32_t *)0x40008014 // Enable Error Interrupt Register
#define DMA_EEI_EEI0 ((uint32_t)1<<0) // Enable Error Interrupt 0
#define DMA_EEI_EEI1 ((uint32_t)1<<1) // Enable Error Interrupt 1
#define DMA_EEI_EEI2 ((uint32_t)1<<2) // Enable Error Interrupt 2
#define DMA_EEI_EEI3 ((uint32_t)1<<3) // Enable Error Interrupt 3
#define DMA_EEI_EEI4 ((uint32_t)1<<4) // Enable Error Interrupt 4
#define DMA_EEI_EEI5 ((uint32_t)1<<5) // Enable Error Interrupt 5
#define DMA_EEI_EEI6 ((uint32_t)1<<6) // Enable Error Interrupt 6
#define DMA_EEI_EEI7 ((uint32_t)1<<7) // Enable Error Interrupt 7
#define DMA_EEI_EEI8 ((uint32_t)1<<8) // Enable Error Interrupt 8
#define DMA_EEI_EEI9 ((uint32_t)1<<9) // Enable Error Interrupt 9
#define DMA_EEI_EEI10 ((uint32_t)1<<10) // Enable Error Interrupt 10
#define DMA_EEI_EEI11 ((uint32_t)1<<11) // Enable Error Interrupt 11
#define DMA_EEI_EEI12 ((uint32_t)1<<12) // Enable Error Interrupt 12
#define DMA_EEI_EEI13 ((uint32_t)1<<13) // Enable Error Interrupt 13
#define DMA_EEI_EEI14 ((uint32_t)1<<14) // Enable Error Interrupt 14
#define DMA_EEI_EEI15 ((uint32_t)1<<15) // Enable Error Interrupt 15
#define DMA_EEI_EEI16 ((uint32_t)1<<16) // Enable Error Interrupt 16
#define DMA_CEEI *(volatile uint8_t *)0x40008018 // Clear Enable Error Interrupt Register
#define DMA_CEEI_CEEI(n) ((uint8_t)(n & 3)<<0) // Clear Enable Error Interrupt
#define DMA_CEEI_CAEE ((uint8_t)1<<6) // Clear All Enable Error Interrupts
@ -1494,8 +1468,6 @@ typedef struct {
#define UART0_MA2 *(volatile uint8_t *)0x4006A009 // UART Match Address Registers 2
#define UART0_C4 *(volatile uint8_t *)0x4006A00A // UART Control Register 4
#define UART0_C5 *(volatile uint8_t *)0x4006A00B // UART Control Register 5
#define UART_C5_TDMAS 0x80
#define UART_C5_RDMAS 0x20
#define UART0_ED *(volatile uint8_t *)0x4006A00C // UART Extended Data Register
#define UART0_MODEM *(volatile uint8_t *)0x4006A00D // UART Modem Register
#define UART0_IR *(volatile uint8_t *)0x4006A00E // UART Infrared Register
@ -1979,9 +1951,7 @@ typedef struct {
#define SCB_CFSR *(volatile uint32_t *)0xE000ED28 // Configurable Fault Status Register
#define SCB_HFSR *(volatile uint32_t *)0xE000ED2C // HardFault Status
#define SCB_DFSR *(volatile uint32_t *)0xE000ED30 // Debug Fault Status
#define SCB_MMAR *(volatile uint32_t *)0xE000ED34 // MemManage Fault Address
#define SCB_BFAR *(volatile uint32_t *)0xE000ED38 // BusFault Addreses Register
#define SCB_AFSR *(volatile uint32_t *)0xE000ED3C // Auxilary Fault Status Register
#define SCB_MMFAR *(volatile uint32_t *)0xE000ED34 // MemManage Fault Address
#define SYST_CSR *(volatile uint32_t *)0xE000E010 // SysTick Control and Status
#define SYST_CSR_COUNTFLAG (uint32_t)0x00010000

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
# Convenience script for loading firmware onto a dfu type device
# By default, initiates dfu-util

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
# Convenience script for loading firmware onto a teensy type device
# By default, initiates teensy-load-cli

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
# Convenience script for loading firmware onto a teensy type device
# By default, initiates teensy-load-cli

View file

@ -1,22 +1,17 @@
Name = PartialMapCapabilities;
Version = 0.2;
Author = "HaaTa (Jacob Alexander) 2014-2015";
KLL = 0.3b;
Version = 0.1;
Author = "HaaTa (Jacob Alexander) 2014";
KLL = 0.3a;
# Modified Date
Date = 2015-09-24;
Date = 2014-11-21;
# Capabilties available to the PartialMap module
layerState => Macro_layerState_capability( layer : 2, state : 1 );
layerLatch => Macro_layerLatch_capability( layer : 2 );
layerLock => Macro_layerLock_capability( layer : 2 );
layerShift => Macro_layerShift_capability( layer : 2 );
# By default, rotate to the next layer
# The current rotating layer is stored separately to the layer stack
# But still sets the layer stack using the layerLock/unlock mechanism
# Argument 0 -> Next, 1 -> Previous
layerRotate => Macro_layerRotate_capability( previous : 1 );
layerState => Macro_layerState_capability( layer : 2, state : 1 );
layerLatch => Macro_layerLatch_capability( layer : 2 );
layerLock => Macro_layerLock_capability( layer : 2 );
layerShift => Macro_layerShift_capability( layer : 2 );
# Defines available to the PartialMap module
stateWordSize => StateWordSize_define;

View file

@ -29,11 +29,6 @@
#include "usb_hid.h"
#include <generatedKeymap.h> // Generated using kll at compile time, in build directory
// Connect Includes
#if defined(ConnectEnabled_define)
#include <connect_scan.h>
#endif
// Local Includes
#include "macro.h"
@ -46,7 +41,6 @@ void cliFunc_capSelect ( char* args );
void cliFunc_keyHold ( char* args );
void cliFunc_keyPress ( char* args );
void cliFunc_keyRelease( char* args );
void cliFunc_layerDebug( char* args );
void cliFunc_layerList ( char* args );
void cliFunc_layerState( char* args );
void cliFunc_macroDebug( char* args );
@ -92,7 +86,6 @@ CLIDict_Entry( capSelect, "Triggers the specified capabilities. First two args
CLIDict_Entry( keyHold, "Send key-hold events to the macro module. Duplicates have undefined behaviour." NL "\t\t\033[35mS10\033[0m Scancode 0x0A" );
CLIDict_Entry( keyPress, "Send key-press events to the macro module. Duplicates have undefined behaviour." NL "\t\t\033[35mS10\033[0m Scancode 0x0A" );
CLIDict_Entry( keyRelease, "Send key-release event to macro module. Duplicates have undefined behaviour." NL "\t\t\033[35mS10\033[0m Scancode 0x0A" );
CLIDict_Entry( layerDebug, "Layer debug mode. Shows layer stack and any changes." );
CLIDict_Entry( layerList, "List available layers." );
CLIDict_Entry( layerState, "Modify specified indexed layer state <layer> <state byte>." NL "\t\t\033[35mL2\033[0m Indexed Layer 0x02" NL "\t\t0 Off, 1 Shift, 2 Latch, 4 Lock States" );
CLIDict_Entry( macroDebug, "Disables/Enables sending USB keycodes to the Output Module and prints U/K codes." );
@ -107,7 +100,6 @@ CLIDict_Def( macroCLIDict, "Macro Module Commands" ) = {
CLIDict_Item( keyHold ),
CLIDict_Item( keyPress ),
CLIDict_Item( keyRelease ),
CLIDict_Item( layerDebug ),
CLIDict_Item( layerList ),
CLIDict_Item( layerState ),
CLIDict_Item( macroDebug ),
@ -119,9 +111,6 @@ CLIDict_Def( macroCLIDict, "Macro Module Commands" ) = {
};
// Layer debug flag - If set, displays any changes to layers and the full layer stack on change
uint8_t layerDebugMode = 0;
// Macro debug flag - If set, clears the USB Buffers after signalling processing completion
uint8_t macroDebugMode = 0;
@ -135,7 +124,7 @@ uint16_t macroStepCounter = 0;
// Key Trigger List Buffer and Layer Cache
// The layer cache is set on press only, hold and release events refer to the value set on press
TriggerGuide macroTriggerListBuffer[ MaxScanCode ];
var_uint_t macroTriggerListBufferSize = 0;
uint8_t macroTriggerListBufferSize = 0;
var_uint_t macroTriggerListLayerCache[ MaxScanCode ];
// Pending Trigger Macro Index List
@ -156,13 +145,6 @@ uint16_t macroLayerIndexStackSize = 0;
uint16_t macroResultMacroPendingList[ ResultMacroNum ] = { 0 };
uint16_t macroResultMacroPendingListSize = 0;
// Interconnect ScanCode Cache
#if defined(ConnectEnabled_define)
// TODO This can be shrunk by the size of the max node 0 ScanCode
TriggerGuide macroInterconnectCache[ MaxScanCode ];
uint8_t macroInterconnectCacheSize = 0;
#endif
// ----- Capabilities -----
@ -170,8 +152,8 @@ uint8_t macroInterconnectCacheSize = 0;
// Sets the given layer with the specified layerState
void Macro_layerState( uint8_t state, uint8_t stateType, uint16_t layer, uint8_t layerState )
{
// Ignore if layer does not exist or trying to manipulate layer 0/Default layer
if ( layer >= LayerNum || layer == 0 )
// Ignore if layer does not exist
if ( layer >= LayerNum )
return;
// Is layer in the LayerIndexStack?
@ -222,30 +204,6 @@ void Macro_layerState( uint8_t state, uint8_t stateType, uint16_t layer, uint8_t
// Reduce LayerIndexStack size
macroLayerIndexStackSize--;
}
// Layer Debug Mode
if ( layerDebugMode )
{
dbug_msg("Layer ");
// Iterate over each of the layers displaying the state as a hex value
for ( uint16_t index = 0; index < LayerNum; index++ )
{
printHex_op( LayerState[ index ], 0 );
}
// Always show the default layer (it's always 0)
print(" 0");
// Iterate over the layer stack starting from the bottom of the stack
for ( uint16_t index = macroLayerIndexStackSize; index > 0; index-- )
{
print(":");
printHex_op( macroLayerIndexStack[ index - 1 ], 0 );
}
print( NL );
}
}
// Modifies the specified Layer control byte
@ -350,58 +308,6 @@ void Macro_layerShift_capability( uint8_t state, uint8_t stateType, uint8_t *arg
}
// Rotate layer to next/previous
// Uses state variable to keep track of the current layer position
// Layers are still evaluated using the layer stack
uint16_t Macro_rotationLayer;
void Macro_layerRotate_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("Macro_layerRotate(previous)");
return;
}
// Only use capability on press
// TODO Analog
// XXX Could also be on release, but that's sorta dumb -HaaTa
if ( stateType == 0x00 && state != 0x01 ) // All normal key conditions except press
return;
// Unset previous rotation layer if not 0
if ( Macro_rotationLayer != 0 )
{
Macro_layerState( state, stateType, Macro_rotationLayer, 0x04 );
}
// Get direction of rotation, 0, next, non-zero previous
uint8_t direction = *args;
// Next
if ( !direction )
{
Macro_rotationLayer++;
// Invalid layer
if ( Macro_rotationLayer >= LayerNum )
Macro_rotationLayer = 0;
}
// Previous
else
{
Macro_rotationLayer--;
// Layer wrap
if ( Macro_rotationLayer >= LayerNum )
Macro_rotationLayer = LayerNum - 1;
}
// Toggle the computed layer rotation
Macro_layerState( state, stateType, Macro_rotationLayer, 0x04 );
}
// ----- Functions -----
@ -422,26 +328,11 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire )
nat_ptr_t **map = (nat_ptr_t**)LayerIndex[ cachedLayer ].triggerMap;
const Layer *layer = &LayerIndex[ cachedLayer ];
// Cache trigger list before attempting to expire latch
nat_ptr_t *trigger_list = map[ scanCode - layer->first ];
// Check if latch has been pressed for this layer
uint8_t latch = LayerState[ cachedLayer ] & 0x02;
if ( latch && latch_expire )
{
Macro_layerState( 0, 0, cachedLayer, 0x02 );
#if defined(ConnectEnabled_define) && defined(LCDEnabled_define)
// Evaluate the layerStack capability if available (LCD + Interconnect)
extern void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args );
LCD_layerStack_capability( 0, 0, 0 );
#endif
}
return trigger_list;
return map[ scanCode - layer->first ];
}
// If no trigger macro is defined at the given layer, fallthrough to the next layer
for ( uint16_t layerIndex = macroLayerIndexStackSize; layerIndex != 0xFFFF; layerIndex-- )
for ( uint16_t layerIndex = 0; layerIndex < macroLayerIndexStackSize; layerIndex++ )
{
// Lookup Layer
const Layer *layer = &LayerIndex[ macroLayerIndexStack[ layerIndex ] ];
@ -465,9 +356,9 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire )
// Determine if layer has key defined
// Make sure scanCode is between layer first and last scancodes
if ( map != 0
&& scanCode <= layer->last
&& scanCode >= layer->first
&& *map[ scanCode - layer->first ] != 0 )
&& scanCode <= layer->last
&& scanCode >= layer->first
&& *map[ scanCode - layer->first ] != 0 )
{
// Set the layer cache
macroTriggerListLayerCache[ scanCode ] = macroLayerIndexStack[ layerIndex ];
@ -485,9 +376,9 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire )
// Make sure scanCode is between layer first and last scancodes
if ( map != 0
&& scanCode <= layer->last
&& scanCode >= layer->first
&& *map[ scanCode - layer->first ] != 0 )
&& scanCode <= layer->last
&& scanCode >= layer->first
&& *map[ scanCode - layer->first ] != 0 )
{
// Set the layer cache to default map
macroTriggerListLayerCache[ scanCode ] = 0;
@ -498,80 +389,18 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire )
// Otherwise no defined Trigger Macro
erro_msg("Scan Code has no defined Trigger Macro: ");
printHex( scanCode );
print( NL );
return 0;
}
// Add an interconnect ScanCode
// These are handled differently (less information is sent, hold/off states must be assumed)
#if defined(ConnectEnabled_define)
inline void Macro_interconnectAdd( void *trigger_ptr )
// Update the scancode using a list of TriggerGuides
// TODO Handle led state and analog
inline void Macro_triggerState( void *triggers, uint8_t num )
{
TriggerGuide *trigger = (TriggerGuide*)trigger_ptr;
// Error checking
uint8_t error = 0;
switch ( trigger->type )
{
case 0x00: // Normal key
switch ( trigger->state )
{
case 0x00:
case 0x01:
case 0x02:
case 0x03:
break;
default:
erro_msg("Invalid key state - ");
error = 1;
break;
}
break;
// Invalid TriggerGuide type
default:
erro_msg("Invalid type - ");
error = 1;
break;
}
// Check if ScanCode is out of range
if ( trigger->scanCode > MaxScanCode )
{
warn_msg("ScanCode is out of range/not defined - ");
error = 1;
}
// Display TriggerGuide
if ( error )
{
printHex( trigger->type );
print(" ");
printHex( trigger->state );
print(" ");
printHex( trigger->scanCode );
print( NL );
return;
}
// Add trigger to the Interconnect Cache
// During each processing loop, a scancode may be re-added depending on it's state
for ( var_uint_t c = 0; c < macroInterconnectCacheSize; c++ )
{
// Check if the same ScanCode
if ( macroInterconnectCache[ c ].scanCode == trigger->scanCode )
{
// Update the state
macroInterconnectCache[ c ].state = trigger->state;
return;
}
}
// If not in the list, add it
macroInterconnectCache[ macroInterconnectCacheSize++ ] = *trigger;
// Copy each of the TriggerGuides to the TriggerListBuffer
for ( uint8_t c = 0; c < num; c++ )
macroTriggerListBuffer[ macroTriggerListBufferSize++ ] = ((TriggerGuide*)triggers)[ c ];
}
#endif
// Update the scancode key state
@ -583,35 +412,12 @@ inline void Macro_interconnectAdd( void *trigger_ptr )
// * 0x04 - Unpressed (this is currently ignored)
inline void Macro_keyState( uint8_t scanCode, uint8_t state )
{
#if defined(ConnectEnabled_define)
// Only compile in if a Connect node module is available
if ( !Connect_master )
{
// ScanCodes are only added if there was a state change (on/off)
switch ( state )
{
case 0x00: // Off
case 0x02: // Held
return;
}
}
#endif
// Only add to macro trigger list if one of three states
switch ( state )
{
case 0x01: // Pressed
case 0x02: // Held
case 0x03: // Released
// Check if ScanCode is out of range
if ( scanCode > MaxScanCode )
{
warn_msg("ScanCode is out of range/not defined: ");
printHex( scanCode );
print( NL );
return;
}
macroTriggerListBuffer[ macroTriggerListBufferSize ].scanCode = scanCode;
macroTriggerListBuffer[ macroTriggerListBufferSize ].state = state;
macroTriggerListBuffer[ macroTriggerListBufferSize ].type = 0x00; // Normal key
@ -629,18 +435,8 @@ inline void Macro_keyState( uint8_t scanCode, uint8_t state )
inline void Macro_analogState( uint8_t scanCode, uint8_t state )
{
// Only add to macro trigger list if non-off
// TODO Handle change for interconnect
if ( state != 0x00 )
{
// Check if ScanCode is out of range
if ( scanCode > MaxScanCode )
{
warn_msg("ScanCode is out of range/not defined: ");
printHex( scanCode );
print( NL );
return;
}
macroTriggerListBuffer[ macroTriggerListBufferSize ].scanCode = scanCode;
macroTriggerListBuffer[ macroTriggerListBufferSize ].state = state;
macroTriggerListBuffer[ macroTriggerListBufferSize ].type = 0x02; // Analog key
@ -656,12 +452,8 @@ inline void Macro_analogState( uint8_t scanCode, uint8_t state )
inline void Macro_ledState( uint8_t ledCode, uint8_t state )
{
// Only add to macro trigger list if non-off
// TODO Handle change for interconnect
if ( state != 0x00 )
{
// Check if LedCode is out of range
// TODO
macroTriggerListBuffer[ macroTriggerListBufferSize ].scanCode = ledCode;
macroTriggerListBuffer[ macroTriggerListBufferSize ].state = state;
macroTriggerListBuffer[ macroTriggerListBufferSize ].type = 0x01; // LED key
@ -699,7 +491,7 @@ inline void Macro_appendResultMacroToPendingList( const TriggerMacro *triggerMac
uint8_t scanCode = ((TriggerGuide*)&triggerMacro->guide[ pos - TriggerGuideSize ])->scanCode;
// Lookup scanCode in buffer list for the current state and stateType
for ( var_uint_t keyIndex = 0; keyIndex < macroTriggerListBufferSize; keyIndex++ )
for ( uint8_t keyIndex = 0; keyIndex < macroTriggerListBufferSize; keyIndex++ )
{
if ( macroTriggerListBuffer[ keyIndex ].scanCode == scanCode )
{
@ -905,7 +697,7 @@ TriggerMacroEval Macro_evalTriggerMacro( var_uint_t triggerMacroIndex )
TriggerMacroVote vote = TriggerMacroVote_Invalid;
// Iterate through the key buffer, comparing to each key in the combo
for ( var_uint_t key = 0; key < macroTriggerListBufferSize; key++ )
for ( uint8_t key = 0; key < macroTriggerListBufferSize; key++ )
{
// Lookup key information
TriggerGuide *keyInfo = &macroTriggerListBuffer[ key ];
@ -959,7 +751,7 @@ TriggerMacroEval Macro_evalTriggerMacro( var_uint_t triggerMacroIndex )
}
// If passing and in Waiting state, set macro state to Press
else if ( overallVote & TriggerMacroVote_Pass
&& ( record->state == TriggerMacro_Waiting || record->state == TriggerMacro_Press ) )
&& ( record->state == TriggerMacro_Waiting || record->state == TriggerMacro_Press ) )
{
record->state = TriggerMacro_Press;
@ -1065,7 +857,7 @@ inline ResultMacroEval Macro_evalResultMacro( var_uint_t resultMacroIndex )
inline void Macro_updateTriggerMacroPendingList()
{
// Iterate over the macroTriggerListBuffer to add any new Trigger Macros to the pending list
for ( var_uint_t key = 0; key < macroTriggerListBufferSize; key++ )
for ( uint8_t key = 0; key < macroTriggerListBufferSize; key++ )
{
// TODO LED States
// TODO Analog Switches
@ -1080,10 +872,6 @@ inline void Macro_updateTriggerMacroPendingList()
// Lookup Trigger List
nat_ptr_t *triggerList = Macro_layerLookup( &macroTriggerListBuffer[ key ], latch_expire );
// If there was an error during lookup, skip
if ( triggerList == 0 )
continue;
// Number of Triggers in list
nat_ptr_t triggerListSize = triggerList[0];
@ -1123,59 +911,10 @@ inline void Macro_updateTriggerMacroPendingList()
// Called once per USB buffer send
inline void Macro_process()
{
#if defined(ConnectEnabled_define)
// Only compile in if a Connect node module is available
// If this is a interconnect slave node, send all scancodes to master node
if ( !Connect_master )
{
if ( macroTriggerListBufferSize > 0 )
{
Connect_send_ScanCode( Connect_id, macroTriggerListBuffer, macroTriggerListBufferSize );
macroTriggerListBufferSize = 0;
}
return;
}
#endif
// Only do one round of macro processing between Output Module timer sends
if ( USBKeys_Sent != 0 )
return;
#if defined(ConnectEnabled_define)
// Check if there are any ScanCodes in the interconnect cache to process
if ( Connect_master && macroInterconnectCacheSize > 0 )
{
// Iterate over all the cache ScanCodes
uint8_t currentInterconnectCacheSize = macroInterconnectCacheSize;
macroInterconnectCacheSize = 0;
for ( uint8_t c = 0; c < currentInterconnectCacheSize; c++ )
{
// Add to the trigger list
macroTriggerListBuffer[ macroTriggerListBufferSize++ ] = macroInterconnectCache[ c ];
// TODO Handle other TriggerGuide types (e.g. analog)
switch ( macroInterconnectCache[ c ].type )
{
// Normal (Press/Hold/Release)
case 0x00:
// Decide what to do based on the current state
switch ( macroInterconnectCache[ c ].state )
{
// Re-add to interconnect cache in hold state
case 0x01: // Press
//case 0x02: // Hold // XXX Why does this not work? -HaaTa
macroInterconnectCache[ c ].state = 0x02;
macroInterconnectCache[ macroInterconnectCacheSize++ ] = macroInterconnectCache[ c ];
break;
case 0x03: // Remove
break;
// Otherwise, do not re-add
}
}
}
}
#endif
// If the pause flag is set, only process if the step counter is non-zero
if ( macroPauseMode )
{
@ -1279,9 +1018,6 @@ inline void Macro_setup()
// Make sure macro trigger buffer is empty
macroTriggerListBufferSize = 0;
// Set the current rotated layer to 0
Macro_rotationLayer = 0;
// Initialize TriggerMacro states
for ( var_uint_t macro = 0; macro < TriggerMacroNum; macro++ )
{
@ -1378,19 +1114,6 @@ void cliFunc_capSelect( char* args )
printHex( argSet[2] );
print( "..." NL );
// Make sure this isn't the reload capability
// If it is, and the remote reflash define is not set, ignore
if ( flashModeEnabled_define == 0 ) for ( uint32_t cap = 0; cap < CapabilitiesNum; cap++ )
{
if ( CapabilitiesList[ cap ].func == (const void*)Output_flashMode_capability )
{
print( NL );
warn_print("flashModeEnabled not set, cancelling firmware reload...");
info_msg("Set flashModeEnabled to 1 in your kll configuration.");
return;
}
}
void (*capability)(uint8_t, uint8_t, uint8_t*) = (void(*)(uint8_t, uint8_t, uint8_t*))(CapabilitiesList[ cap ].func);
capability( argSet[0], argSet[1], &argSet[2] );
}
@ -1481,16 +1204,6 @@ void cliFunc_keyRelease( char* args )
}
}
void cliFunc_layerDebug( char *args )
{
// Toggle layer debug mode
layerDebugMode = layerDebugMode ? 0 : 1;
print( NL );
info_msg("Layer Debug Mode: ");
printInt8( layerDebugMode );
}
void cliFunc_layerList( char* args )
{
print( NL );
@ -1586,7 +1299,7 @@ void cliFunc_macroList( char* args )
info_msg("Pending Key Events: ");
printInt16( (uint16_t)macroTriggerListBufferSize );
print(" : ");
for ( var_uint_t key = 0; key < macroTriggerListBufferSize; key++ )
for ( uint8_t key = 0; key < macroTriggerListBufferSize; key++ )
{
printHex( macroTriggerListBuffer[ key ].scanCode );
print(" ");

View file

@ -23,12 +23,21 @@
// ----- Capabilities -----
void Macro_layerState_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void Macro_layerLatch_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void Macro_layerLock_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void Macro_layerShift_capability( uint8_t state, uint8_t stateType, uint8_t *args );
// ----- Functions -----
void Macro_analogState( uint8_t scanCode, uint8_t state );
void Macro_keyState( uint8_t scanCode, uint8_t state );
void Macro_ledState( uint8_t ledCode, uint8_t state );
void Macro_interconnectAdd( void *trigger ); // triggers is of type TriggerGuide, void* for circular dependencies
void Macro_triggerState( void *triggers, uint8_t num ); // triggers is of type TriggerGuide, void* for circular dependencies
void Macro_process();
void Macro_setup();

View file

@ -74,8 +74,8 @@
#define KEY_SPACE 0x2C
#define KEY_MINUS 0x2D
#define KEY_EQUAL 0x2E
#define KEY_LEFT_BRACKET 0x2F
#define KEY_RIGHT_BRACKET 0x30
#define KEY_LEFT_BRACE 0x2F
#define KEY_RIGHT_BRACE 0x30
#define KEY_BACKSLASH 0x31
#define KEY_NUMBER 0x32
#define KEY_SEMICOLON 0x33
@ -438,15 +438,7 @@
#define CONSUMER_BROADCAST_MODE 0x064
#define CONSUMER_SNAPSHOT 0x065
#define CONSUMER_STILL 0x066
// 0x067 - 0x06E Reserved?
#define CONSUMER_BRIGHTNESS_INCREMENT 0x06F
#define CONSUMER_BRIGHTNESS_DECREMENT 0x070
#define CONSUMER_BACKLIGHT_TOGGLE 0x072
#define CONSUMER_BRIGHTNESS_MIN 0x073
#define CONSUMER_BRIGHTNESS_MAX 0x074
#define CONSUMER_BRIGHTNESS_AUTO 0x075
// 0x076 - 0x07F Reserved
// 0x067 - 0x07F Reserved
#define CONSUMER_ASSIGN_SELECTION 0x081
#define CONSUMER_MODE_STEP 0x082
@ -778,6 +770,5 @@
#define AC_SPLIT 0x29A
#define AC_DISTRIBUTE_HORIZONTALLY 0x29B
#define AC_DISTRIBUTE_VERTICALLY 0x29C
#define AC_NEXT_KEYBOARD_LAYOUT_SEL 0x29D
// 0x29E-0xFFFF Reserved
// 0x29D-0xFFFF Reserved

View file

@ -1,7 +1,7 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
* Modified by Jacob Alexander (2013-2016)
* Modified by Jacob Alexander (2013-2014)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -34,9 +34,6 @@
// Local Includes
#include "usb_desc.h"
// Generated Includes
#include <kll_defs.h>
// ----- Macros -----
@ -97,7 +94,7 @@ static uint8_t usb_debug_descriptor[] = {
// ----- USB HID Report Descriptors -----
// ----- USB HID Report Descriptsors -----
// Each HID interface needs a special report descriptor that tells
// the meaning and format of the data.
@ -263,11 +260,8 @@ static uint8_t nkro_keyboard_report_desc[] = {
0x95, 0x01, // Report Count (1),
0x81, 0x03, // Input (Constant),
0xc0, // End Collection - Keyboard
};
// System Control and Consumer Control
static uint8_t sys_ctrl_report_desc[] = {
// System Control Collection (8 bits)
// System Control Collection
//
// NOTES:
// Not bothering with NKRO for this table. If there's need, I can implement it. -HaaTa
@ -285,7 +279,7 @@ static uint8_t sys_ctrl_report_desc[] = {
0x81, 0x00, // Input (Data, Array),
0xc0, // End Collection - System Control
// Consumer Control Collection - Media Keys (16 bits)
// Consumer Control Collection - Media Keys
//
// NOTES:
// Not bothering with NKRO for this table. If there's a need, I can implement it. -HaaTa
@ -296,139 +290,49 @@ static uint8_t sys_ctrl_report_desc[] = {
0x85, 0x03, // Report ID (3),
0x75, 0x10, // Report Size (16),
0x95, 0x01, // Report Count (1),
0x16, 0x01, 0x00, // Logical Minimum (1),
0x26, 0x9D, 0x02, // Logical Maximum (669),
0x16, 0x20, 0x00, // Logical Minimum (32),
0x26, 0x9C, 0x02, // Logical Maximum (668),
0x05, 0x0C, // Usage Page (Consumer),
0x19, 0x01, // Usage Minimum (1),
0x2A, 0x9D, 0x02, // Usage Maximum (669),
0x19, 0x20, // Usage Minimum (32),
0x2A, 0x9C, 0x02, // Usage Maximum (668),
0x81, 0x00, // Input (Data, Array),
0xc0, // End Collection - Consumer Control
};
/* MOUSE
// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
static uint8_t mouse_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x01, // Collection (Application)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x02, // Collection (Logical)
0x09, 0x01, // Usage (Pointer)
// Buttons (16 bits)
0xA1, 0x00, // Collection (Physical) - Buttons
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button 1)
0x29, 0x10, // Usage Maximum (Button 16)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x10, // Report Count (16)
0x81, 0x02, // Input (Data,Var,Abs)
// Pointer (32 bits)
0x05, 0x01, // Usage PAGE (Generic Desktop)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x16, 0x01, 0x80, // Logical Minimum (-32 767)
0x26, 0xFF, 0x7F, // Logical Maximum (32 767)
0x75, 0x10, // Report Size (16)
0x95, 0x02, // Report Count (2)
0x81, 0x06, // Input (Data,Var,Rel)
/*
// Vertical Wheel
// - Multiplier (2 bits)
0xa1, 0x02, // Collection (Logical)
0x09, 0x48, // Usage (Resolution Multiplier)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x35, 0x01, // Physical Minimum (1)
0x45, 0x04, // Physical Maximum (4)
0x75, 0x02, // Report Size (2)
0x95, 0x01, // Report Count (1)
0xa4, // Push
0xb1, 0x02, // Feature (Data,Var,Abs)
// - Device (8 bits)
0x09, 0x38, // Usage (Wheel)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7f, // Logical Maximum (127)
0x35, 0x00, // Physical Minimum (0) - reset physical
0x45, 0x00, // Physical Maximum (0)
0x75, 0x08, // Report Size (8)
0x81, 0x06, // Input (Data,Var,Rel)
0xc0, // End Collection - Vertical Wheel
// Horizontal Wheel
// - Multiplier (2 bits)
0xa1, 0x02, // Collection (Logical)
0x09, 0x48, // Usage (Resolution Multiplier)
0xb4, // Pop
0xb1, 0x02, // Feature (Data,Var,Abs)
// - Padding (4 bits)
0x35, 0x00, // Physical Minimum (0) - reset physical
0x45, 0x00, // Physical Maximum (0)
0x75, 0x04, // Report Size (4)
0xb1, 0x03, // Feature (Cnst,Var,Abs)
// - Device (8 bits)
0x05, 0x0c, // Usage Page (Consumer Devices)
0x0a, 0x38, 0x02, // Usage (AC Pan)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7f, // Logical Maximum (127)
0x75, 0x08, // Report Size (8)
0x81, 0x06, // Input (Data,Var,Rel)
0xc0, // End Collection - Horizontal Wheel
*/
0xc0, // End Collection - Buttons
0xc0, // End Collection - Mouse Logical
0xc0 // End Collection - Mouse Application
};
// Joystick Protocol, HID 1.11 spec, Apendix D, page 64-65
static uint8_t joystick_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x20, // Report Count (32)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x20, // Usage Maximum (Button #32)
0x81, 0x02, // Input (variable,absolute)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x65, 0x14, // Unit (20)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x81, 0x42, // Input (variable,absolute,null_state)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection ()
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x03, // Logical Maximum (1023)
0x75, 0x0A, // Report Size (10)
0x95, 0x04, // Report Count (4)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x35, // Usage (Rz)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x03, // Logical Maximum (1023)
0x75, 0x0A, // Report Size (10)
0x95, 0x02, // Report Count (2)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x81, 0x02, // Input (variable,absolute)
0xC0 // End Collection
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x01, // Collection (Application)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x03, // Usage Maximum (Button #3)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x03, // Report Count (3)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data, Variable, Absolute)
0x95, 0x01, // Report Count (1)
0x75, 0x05, // Report Size (5)
0x81, 0x03, // Input (Constant)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x7F, // Logical Maximum (32767)
0x75, 0x10, // Report Size (16),
0x95, 0x02, // Report Count (2),
0x81, 0x02, // Input (Data, Variable, Absolute)
0x09, 0x38, // Usage (Wheel)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8),
0x95, 0x01, // Report Count (1),
0x81, 0x06, // Input (Data, Variable, Relative)
0xC0 // End Collection
};
*/
@ -448,7 +352,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
1, // bConfigurationValue
0, // iConfiguration
0xA0, // bmAttributes
250, // bMaxPower - Entry Index 8
250, // bMaxPower
// --- Keyboard HID --- Boot Mode Keyboard Interface
// - 9 bytes -
@ -461,13 +365,13 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
0x03, // bInterfaceClass (0x03 = HID)
0x01, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot)
0x01, // bInterfaceProtocol (0x01 = Keyboard)
KEYBOARD_INTERFACE + 4, // iInterface
0, // iInterface
// - 9 bytes -
// HID interface descriptor, HID 1.11 spec, section 6.2.1
9, // bLength
0x21, // bDescriptorType
0x11, 0x01, // bcdHID
KeyboardLocale_define, // bCountryCode
0, // bCountryCode
1, // bNumDescriptors
0x22, // bDescriptorType
LSB(sizeof(keyboard_report_desc)), // wDescriptorLength
@ -492,13 +396,13 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
0x03, // bInterfaceClass (0x03 = HID)
0x00, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot)
0x01, // bInterfaceProtocol (0x01 = Keyboard)
NKRO_KEYBOARD_INTERFACE + 4, // iInterface
0, // iInterface
// - 9 bytes -
// HID interface descriptor, HID 1.11 spec, section 6.2.1
9, // bLength
0x21, // bDescriptorType
0x11, 0x01, // bcdHID
KeyboardLocale_define, // bCountryCode
0, // bCountryCode
1, // bNumDescriptors
0x22, // bDescriptorType
LSB(sizeof(nkro_keyboard_report_desc)), // wDescriptorLength
@ -522,7 +426,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
0x02, // bFunctionClass
0x02, // bFunctionSubClass
0x01, // bFunctionProtocol
CDC_STATUS_INTERFACE + 4, // iFunction
0, // iFunction
// --- Serial CDC --- CDC Data Interface
// - 9 bytes -
@ -535,7 +439,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
0x02, // bInterfaceClass
0x02, // bInterfaceSubClass
0x01, // bInterfaceProtocol
CDC_STATUS_INTERFACE + 4, // iInterface
0, // iInterface
// - 5 bytes -
// CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
5, // bFunctionLength
@ -580,7 +484,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
0x0A, // bInterfaceClass
0x00, // bInterfaceSubClass
0x00, // bInterfaceProtocol
CDC_DATA_INTERFACE + 4, // iInterface
0, // iInterface
// - 7 bytes -
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
7, // bLength
@ -598,7 +502,8 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
CDC_TX_SIZE, 0, // wMaxPacketSize
0, // bInterval
// --- Mouse Interface ---
/*
// Mouse Interface
// - 9 bytes -
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
@ -608,8 +513,8 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
1, // bNumEndpoints
0x03, // bInterfaceClass (0x03 = HID)
0x00, // bInterfaceSubClass (0x01 = Boot)
0x02, // bInterfaceProtocol (0x02 = Mouse)
MOUSE_INTERFACE + 4, // iInterface
0x00, // bInterfaceProtocol (0x02 = Mouse)
0, // iInterface
// - 9 bytes -
// HID interface descriptor, HID 1.11 spec, section 6.2.1
9, // bLength
@ -628,72 +533,10 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
0x03, // bmAttributes (0x03=intr)
MOUSE_SIZE, 0, // wMaxPacketSize
MOUSE_INTERVAL, // bInterval
// --- Joystick Interface ---
// - 9 bytes -
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
4, // bDescriptorType
JOYSTICK_INTERFACE, // bInterfaceNumber
0, // bAlternateSetting
1, // bNumEndpoints
0x03, // bInterfaceClass (0x03 = HID)
0x00, // bInterfaceSubClass
0x00, // bInterfaceProtocol
JOYSTICK_INTERFACE + 4, // iInterface
// - 9 bytes -
// HID interface descriptor, HID 1.11 spec, section 6.2.1
9, // bLength
0x21, // bDescriptorType
0x11, 0x01, // bcdHID
0, // bCountryCode
1, // bNumDescriptors
0x22, // bDescriptorType
LSB(sizeof(joystick_report_desc)), // wDescriptorLength
MSB(sizeof(joystick_report_desc)),
// - 7 bytes -
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
7, // bLength
5, // bDescriptorType
JOYSTICK_ENDPOINT | 0x80, // bEndpointAddress
0x03, // bmAttributes (0x03=intr)
JOYSTICK_SIZE, 0, // wMaxPacketSize
JOYSTICK_INTERVAL, // bInterval
// --- System/Consumer Control ---
// - 9 bytes -
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
4, // bDescriptorType
SYS_CTRL_INTERFACE, // bInterfaceNumber
0, // bAlternateSetting
1, // bNumEndpoints
0x03, // bInterfaceClass (0x03 = HID)
0x01, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot)
0x00, // bInterfaceProtocol (0x00 = None)
SYS_CTRL_INTERFACE + 4, // iInterface
// - 9 bytes -
// HID interface descriptor, HID 1.11 spec, section 6.2.1
9, // bLength
0x21, // bDescriptorType
0x11, 0x01, // bcdHID
KeyboardLocale_define, // bCountryCode
1, // bNumDescriptors
0x22, // bDescriptorType
LSB(sizeof(sys_ctrl_report_desc)), // wDescriptorLength
MSB(sizeof(sys_ctrl_report_desc)),
// - 7 bytes -
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
7, // bLength
5, // bDescriptorType
SYS_CTRL_ENDPOINT | 0x80, // bEndpointAddress
0x03, // bmAttributes (0x03=intr)
SYS_CTRL_SIZE, 0, // wMaxPacketSize
SYS_CTRL_INTERVAL, // bInterval
#endif // MOUSE_INTERFACE
*/
};
uint8_t *usb_bMaxPower = &config_descriptor[8];
// ----- String Descriptors -----
@ -721,23 +564,21 @@ struct usb_string_descriptor_struct string0 = {
{0x0409}
};
#define usb_string_descriptor(name, str) \
struct usb_string_descriptor_struct name = { \
sizeof(str), \
3, \
{str} \
}
usb_string_descriptor( usb_string_manufacturer_name_default, STR_MANUFACTURER );
usb_string_descriptor( usb_string_product_name_default, STR_PRODUCT );
usb_string_descriptor( usb_string_serial_number_default, STR_SERIAL );
usb_string_descriptor( usb_string_keyboard_name, KEYBOARD_NAME );
usb_string_descriptor( usb_string_nkro_keyboard_name, NKRO_KEYBOARD_NAME );
usb_string_descriptor( usb_string_cdc_status_name, CDC_STATUS_NAME );
usb_string_descriptor( usb_string_cdc_data_name, CDC_DATA_NAME );
usb_string_descriptor( usb_string_mouse_name, MOUSE_NAME );
usb_string_descriptor( usb_string_joystick_name, JOYSTICK_NAME );
usb_string_descriptor( usb_string_sys_ctrl_name, SYS_CTRL_NAME );
struct usb_string_descriptor_struct usb_string_manufacturer_name_default = {
sizeof(STR_MANUFACTURER),
3,
{STR_MANUFACTURER}
};
struct usb_string_descriptor_struct usb_string_product_name_default = {
sizeof(STR_PRODUCT),
3,
{STR_PRODUCT}
};
struct usb_string_descriptor_struct usb_string_serial_number_default = {
sizeof(STR_SERIAL),
3,
{STR_SERIAL}
};
@ -751,36 +592,18 @@ const usb_descriptor_list_t usb_descriptor_list[] = {
{0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)},
{0x0600, 0x0000, device_qualifier_descriptor, sizeof(device_qualifier_descriptor)},
{0x0A00, 0x0000, usb_debug_descriptor, sizeof(usb_debug_descriptor)},
{0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)},
{0x2100, KEYBOARD_INTERFACE, config_descriptor + KEYBOARD_DESC_OFFSET, 9},
{0x2200, NKRO_KEYBOARD_INTERFACE, nkro_keyboard_report_desc, sizeof(nkro_keyboard_report_desc)},
{0x2100, NKRO_KEYBOARD_INTERFACE, config_descriptor + NKRO_KEYBOARD_DESC_OFFSET, 9},
/* MOUSE
{0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)},
{0x2100, MOUSE_INTERFACE, config_descriptor + MOUSE_DESC_OFFSET, 9},
{0x2200, JOYSTICK_INTERFACE, joystick_report_desc, sizeof(joystick_report_desc)},
{0x2100, JOYSTICK_INTERFACE, config_descriptor + JOYSTICK_DESC_OFFSET, 9},
{0x2200, SYS_CTRL_INTERFACE, sys_ctrl_report_desc, sizeof(sys_ctrl_report_desc)},
{0x2100, SYS_CTRL_INTERFACE, config_descriptor + SYS_CTRL_DESC_OFFSET, 9},
#define iInterfaceString(num, var) \
{0x0300 + 4 + num, 0x409, (const uint8_t *)&var, 0 }
{0x2100, MOUSE_INTERFACE, config_descriptor+MOUSE_DESC_OFFSET, 9},
*/
{0x0300, 0x0000, (const uint8_t *)&string0, 0},
{0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0},
{0x0302, 0x0409, (const uint8_t *)&usb_string_product_name, 0},
{0x0303, 0x0409, (const uint8_t *)&usb_string_serial_number, 0},
iInterfaceString( KEYBOARD_INTERFACE, usb_string_keyboard_name ),
iInterfaceString( NKRO_KEYBOARD_INTERFACE, usb_string_nkro_keyboard_name ),
iInterfaceString( CDC_STATUS_INTERFACE, usb_string_cdc_status_name ),
iInterfaceString( CDC_DATA_INTERFACE, usb_string_cdc_data_name ),
iInterfaceString( MOUSE_INTERFACE, usb_string_mouse_name ),
iInterfaceString( JOYSTICK_INTERFACE, usb_string_joystick_name ),
iInterfaceString( SYS_CTRL_INTERFACE, usb_string_sys_ctrl_name ),
{0, 0, NULL, 0}
};

View file

@ -1,7 +1,7 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
* Modified by Jacob Alexander (2013-2016)
* Modified by Jacob Alexander (2013-2015)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -54,21 +54,19 @@
#define DEVICE_SUBCLASS 0x00
#define DEVICE_PROTOCOL 0x00
#define EP0_SIZE 64
#define NUM_ENDPOINTS 8
#define NUM_ENDPOINTS 5
#define NUM_USB_BUFFERS 30
#define NUM_INTERFACE 7
#define NUM_INTERFACE 4
#define KEYBOARD_INTERFACE 0 // Keyboard
#define KEYBOARD_ENDPOINT 1
#define KEYBOARD_SIZE 8
#define KEYBOARD_INTERVAL 1
#define KEYBOARD_NAME L"Boot Keyboard"
#define NKRO_KEYBOARD_INTERFACE 1 // NKRO Keyboard
#define NKRO_KEYBOARD_ENDPOINT 2
#define NKRO_KEYBOARD_SIZE 64
#define NKRO_KEYBOARD_INTERVAL 1
#define NKRO_KEYBOARD_NAME L"NKRO Keyboard"
#define CDC_IAD_DESCRIPTOR 1
#define CDC_STATUS_INTERFACE 2
@ -79,34 +77,25 @@
#define CDC_ACM_SIZE 16
#define CDC_RX_SIZE 64
#define CDC_TX_SIZE 64
#define CDC_STATUS_NAME L"Virtual Serial Port - Status"
#define CDC_DATA_NAME L"Virtual Serial Port - Data"
#define MOUSE_INTERFACE 4 // Mouse
#define MOUSE_ENDPOINT 6
#define MOUSE_SIZE 8
#define MOUSE_INTERVAL 1
#define MOUSE_NAME L"Mouse"
#define MOUSE_INTERVAL 2
#define JOYSTICK_INTERFACE 5 // Joystick
#define JOYSTICK_ENDPOINT 7
#define JOYSTICK_SIZE 16
#define JOYSTICK_INTERVAL 1
#define JOYSTICK_NAME L"Joystick"
#define SYS_CTRL_INTERFACE 6 // Media Keys
#define SYS_CTRL_ENDPOINT 8
#define SYS_CTRL_SIZE 8
#define SYS_CTRL_INTERVAL 1
#define SYS_CTRL_NAME L"Media Keys"
#define KEYBOARD_DESC_OFFSET (9 + 9)
#define NKRO_KEYBOARD_DESC_OFFSET (9 + 9+9+7 + 9)
#define SERIAL_CDC_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8)
#define CONFIG_DESC_SIZE (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7)
// XXX Unused
#define MOUSE_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9)
#define JOYSTICK_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9+9+7 + 9)
#define SYS_CTRL_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9)
#define CONFIG_DESC_SIZE (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9+9+7)
#define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY
#define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY
@ -115,7 +104,6 @@
#define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY
#define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY
#define ENDPOINT7_CONFIG ENDPOINT_TRANSIMIT_ONLY
#define ENDPOINT8_CONFIG ENDPOINT_TRANSIMIT_ONLY
@ -137,5 +125,3 @@ extern const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS];
extern const usb_descriptor_list_t usb_descriptor_list[];
extern uint8_t *usb_bMaxPower;

View file

@ -1,7 +1,7 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
* Modifications by Jacob Alexander (2013-2016)
* Modifications by Jacob Alexander (2013-2014)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -34,7 +34,6 @@
// Project Includes
#include <Lib/OutputLib.h>
#include <print.h>
#include <kll_defs.h>
// Local Includes
#include "usb_dev.h"
@ -168,18 +167,13 @@ volatile uint8_t usb_reboot_timer = 0;
static uint8_t reply_buffer[8];
static uint8_t power_neg_delay;
static uint32_t power_neg_time;
volatile uint8_t remote_wakeup_enabled = 0;
// ----- Functions -----
static void endpoint0_stall()
{
#ifdef UART_DEBUG_UNKNOWN
print("STALL" NL );
#endif
USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
}
@ -191,34 +185,6 @@ static void endpoint0_transmit( const void *data, uint32_t len )
ep0_tx_bdt_bank ^= 1;
}
// Used to check any USB state changes that may not have a proper interrupt
// Called once per scan loop, should take minimal processing time or it may affect other modules
void usb_device_check()
{
// Check to see if we're still waiting for the next USB request after Get Configuration Descriptor
// If still waiting, restart the USB initialization with a lower power requirement
if ( power_neg_delay )
{
// Check if 100 ms has elapsed
if ( systick_millis_count - power_neg_time > 100 )
{
// Update bMaxPower
// The value set is in increments of 2 mA
// So 50 * 2 mA = 100 mA
// XXX Currently only transitions to 100 mA
// It may be possible to transition down again to 20 mA
*usb_bMaxPower = 50;
// Re-initialize USB
power_neg_delay = 0;
usb_configuration = 0; // Clear USB configuration if we have one
USB0_CONTROL = 0; // Disable D+ Pullup to simulate disconnect
delay(10); // Delay is necessary to simulate disconnect
usb_init();
}
}
}
static void usb_setup()
{
const uint8_t *data = NULL;
@ -230,30 +196,17 @@ static void usb_setup()
const uint8_t *cfg;
int i;
// If another request is made, disable the power negotiation check
// See GET_DESCRIPTOR - Configuration
if ( power_neg_delay )
{
power_neg_delay = 0;
}
switch ( setup.wRequestAndType )
{
case 0x0500: // SET_ADDRESS
goto send;
break;
case 0x0900: // SET_CONFIGURATION
#ifdef UART_DEBUG
print("CONFIGURE - ");
#endif
usb_configuration = setup.wValue;
Output_Available = usb_configuration;
reg = &USB0_ENDPT1;
cfg = usb_endpoint_config_table;
// Now configured so we can utilize bMaxPower now
Output_update_usb_current( *usb_bMaxPower * 2 );
// clear all BDT entries, free any allocated memory...
for ( i = 4; i < ( NUM_ENDPOINTS + 1) * 4; i++ )
{
@ -335,21 +288,19 @@ static void usb_setup()
table[ index( i, TX, EVEN ) ].desc = 0;
table[ index( i, TX, ODD ) ].desc = 0;
}
goto send;
break;
case 0x0880: // GET_CONFIGURATION
reply_buffer[0] = usb_configuration;
datalen = 1;
data = reply_buffer;
goto send;
break;
case 0x0080: // GET_STATUS (device)
reply_buffer[0] = 0;
//I think this is the corrent endianess
reply_buffer[0] = (remote_wakeup_enabled)<<1;
reply_buffer[1] = 0;
datalen = 2;
data = reply_buffer;
goto send;
break;
case 0x0082: // GET_STATUS (endpoint)
if ( setup.wIndex > NUM_ENDPOINTS )
{
@ -363,72 +314,42 @@ static void usb_setup()
reply_buffer[0] = 1;
data = reply_buffer;
datalen = 2;
goto send;
break;
case 0x0100: // CLEAR_FEATURE (device)
switch ( setup.wValue )
{
// CLEAR_FEATURE(DEVICE_REMOTE_WAKEUP)
// See SET_FEATURE(DEVICE_REMOTE_WAKEUP) for details
case 0x1:
goto send;
//Disable DEVICE_REMOTE_WAKEUP feature
if (setup.wValue == 0x01) {
remote_wakeup_enabled = 0;
}
warn_msg("SET_FEATURE - Device wValue(");
printHex( setup.wValue );
print( ")" NL );
endpoint0_stall();
return;
break;
case 0x0101: // CLEAR_FEATURE (interface)
// TODO: Currently ignoring, perhaps useful? -HaaTa
warn_msg("CLEAR_FEATURE - Interface wValue(");
printHex( setup.wValue );
print(") wIndex(");
printHex( setup.wIndex );
print( ")" NL );
endpoint0_stall();
return;
case 0x0102: // CLEAR_FEATURE (endpoint)
case 0x0102: // CLEAR_FEATURE (interface)
i = setup.wIndex & 0x7F;
if ( i > NUM_ENDPOINTS || setup.wValue != 0 )
{
endpoint0_stall();
return;
}
(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02;
//(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02;
// TODO: do we need to clear the data toggle here?
goto send;
//break;
case 0x0300: // SET_FEATURE (device)
switch ( setup.wValue )
{
// SET_FEATURE(DEVICE_REMOTE_WAKEUP)
// XXX: Only used to confirm Remote Wake
// Used on Mac OSX and Windows not on Linux
// Good post on the behaviour:
// http://community.silabs.com/t5/8-bit-MCU/Remote-wakeup-HID/m-p/74957#M30802
case 0x1:
goto send;
}
warn_msg("SET_FEATURE - Device wValue(");
printHex( setup.wValue );
print( ")" NL );
// FIXME: Clearing causes keyboard to freeze, likely an invalid clear
// XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa
endpoint0_stall();
return;
case 0x0300: // SET_FEATURE (device)
//Enable DEVICE_REMOTE_WAKEUP feature
if (setup.wValue == 0x01) {
remote_wakeup_enabled = 1;
}
break;
case 0x0301: // SET_FEATURE (interface)
// TODO: Currently ignoring, perhaps useful? -HaaTa
warn_msg("SET_FEATURE - Interface wValue(");
printHex( setup.wValue );
print(") wIndex(");
printHex( setup.wIndex );
print( ")" NL );
endpoint0_stall();
return;
case 0x0302: // SET_FEATURE (endpoint)
i = setup.wIndex & 0x7F;
if ( i > NUM_ENDPOINTS || setup.wValue != 0 )
@ -439,8 +360,7 @@ static void usb_setup()
}
(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) |= 0x02;
// TODO: do we need to clear the data toggle here?
goto send;
break;
case 0x0680: // GET_DESCRIPTOR
case 0x0681:
#ifdef UART_DEBUG
@ -466,27 +386,6 @@ static void usb_setup()
{
datalen = list->length;
}
// XXX Power negotiation hack -HaaTa
// Some devices such as the Apple Ipad do not support bMaxPower greater than 100 mA
// However, there is no provision in the basic USB 2.0 stack for power negotiation
// To get around this:
// * Attempt to set bMaxPower to 500 mA first
// * If more than 100 ms passes since retrieving a Get Configuration Descriptor
// (Descriptor with bMaxPower in it)
// * Change usb_bMaxPower to 50 (100 mA)
// * Restart the USB init process
// According to notes online, it says that some Apple devices can only do 20 mA
// However, in my testing this hasn't been the case
// (you can also draw as much current as you want if you just lie in the descriptor :P)
// If this becomes an issue we can use this hack a second time to negotiate down to 20 mA
// (which should be fine for just the mcu)
if ( setup.wValue == 0x0200 && setup.wIndex == 0x0 )
{
power_neg_delay = 1;
power_neg_time = systick_millis_count;
}
#if UART_DEBUG
print("Desc found, ");
printHex32( (uint32_t)data );
@ -513,7 +412,8 @@ static void usb_setup()
case 0x2221: // CDC_SET_CONTROL_LINE_STATE
usb_cdc_line_rtsdtr = setup.wValue;
//serial_print("set control line state\n");
goto send;
endpoint0_stall();
return;
case 0x21A1: // CDC_GET_LINE_CODING
data = (uint8_t*)usb_cdc_line_coding;
@ -523,50 +423,30 @@ static void usb_setup()
case 0x2021: // CDC_SET_LINE_CODING
// XXX Needed?
//serial_print("set coding, waiting...\n");
return;
endpoint0_stall();
return; // Cannot stall here (causes issues)
case 0x0921: // HID SET_REPORT
// Interface
switch ( setup.wIndex & 0xFF )
{
// Keyboard Interface
case KEYBOARD_INTERFACE:
break;
// NKRO Keyboard Interface
case NKRO_KEYBOARD_INTERFACE:
break;
default:
warn_msg("Unknown interface - ");
printHex( setup.wIndex );
print( NL );
endpoint0_stall();
break;
}
#ifdef UART_DEBUG
print("SET_REPORT - ");
printHex( setup.wValue );
print(" - ");
printHex( setup.wValue & 0xFF );
print( NL );
#endif
USBKeys_LEDs = setup.wValue & 0xFF;
endpoint0_stall();
return;
case 0x01A1: // HID GET_REPORT
#ifdef UART_DEBUG
print("GET_REPORT - ");
printHex( setup.wIndex );
printHex( USBKeys_LEDs );
print(NL);
#endif
// Search through descriptors returning necessary info
for ( list = usb_descriptor_list; 1; list++ )
{
if ( list->addr == NULL )
break;
if ( list->wValue != 0x2200 )
continue;
if ( setup.wIndex == list->wIndex )
{
data = list->addr;
datalen = list->length;
goto send;
}
}
endpoint0_stall();
return;
data = (uint8_t*)&USBKeys_LEDs;
datalen = 1;
goto send;
case 0x0A21: // HID SET_IDLE
#ifdef UART_DEBUG
@ -576,7 +456,8 @@ static void usb_setup()
#endif
USBKeys_Idle_Config = (setup.wValue >> 8);
USBKeys_Idle_Count = 0;
goto send;
endpoint0_stall();
return;
case 0x0B21: // HID SET_PROTOCOL
#ifdef UART_DEBUG
@ -587,7 +468,8 @@ static void usb_setup()
print(NL);
#endif
USBKeys_Protocol = setup.wValue & 0xFF; // 0 - Boot Mode, 1 - NKRO Mode
goto send;
endpoint0_stall();
return;
// case 0xC940:
default:
@ -601,16 +483,10 @@ static void usb_setup()
send:
#ifdef UART_DEBUG
print("setup send ");
printHex32( (uint32_t)data );
printHex32((uint32_t)data);
print(",");
for ( uint8_t c = 0; c < datalen; c++ )
{
printHex( data[c] );
print(" ");
}
print(",");
printHex( datalen );
print( NL );
printHex(datalen);
print(NL);
#endif
if ( datalen > setup.wLength )
@ -720,10 +596,6 @@ static void usb_control( uint32_t stat )
printHex(setup.wIndex);
print(", len:");
printHex(setup.wLength);
print(" -- ");
printHex32(setup.word1);
print(" ");
printHex32(setup.word2);
print(NL);
#endif
// actually "do" the setup request
@ -731,25 +603,11 @@ static void usb_control( uint32_t stat )
// unfreeze the USB, now that we're ready
USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit
break;
case 0x01: // OUT transaction received from host
case 0x02:
#ifdef UART_DEBUG_UNKNOWN
print("PID=OUT wRequestAndType:");
printHex(setup.wRequestAndType);
print(", wValue:");
printHex(setup.wValue);
print(", wIndex:");
printHex(setup.wIndex);
print(", len:");
printHex(setup.wLength);
print(" -- ");
printHex32(setup.word1);
print(" ");
printHex32(setup.word2);
print(NL);
#ifdef UART_DEBUG
print("PID=OUT"NL);
#endif
// CDC Interface
if ( setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/ )
{
@ -768,38 +626,17 @@ static void usb_control( uint32_t stat )
endpoint0_transmit( NULL, 0 );
}
// Keyboard SET_REPORT
if ( setup.wRequestAndType == 0x921 && setup.wValue & 0x200 )
// Keyboard Interface
if ( setup.word1 == 0x02000921 && setup.word2 == ( (1<<16) | KEYBOARD_INTERFACE ) )
{
// Interface
switch ( setup.wIndex & 0xFF )
{
// Keyboard Interface
case KEYBOARD_INTERFACE:
USBKeys_LEDs = buf[0];
endpoint0_transmit( NULL, 0 );
break;
// NKRO Keyboard Interface
case NKRO_KEYBOARD_INTERFACE:
// Only use 2nd byte, first byte is the report id
USBKeys_LEDs = buf[1];
endpoint0_transmit( NULL, 0 );
break;
default:
warn_msg("Unknown interface - ");
printHex( setup.wIndex );
print( NL );
break;
}
#ifdef UART_DEBUG
for ( size_t len = 0; len < setup.wLength; len++ )
{
printHex( buf[ len ] );
print(" ");
}
print( NL );
#endif
USBKeys_LEDs = buf[0];
endpoint0_transmit( NULL, 0 );
}
// NKRO Keyboard Interface
if ( setup.word1 == 0x02000921 && setup.word2 == ( (1<<16) | NKRO_KEYBOARD_INTERFACE ) )
{
USBKeys_LEDs = buf[0];
endpoint0_transmit( NULL, 0 );
}
// give the buffer back
@ -837,7 +674,6 @@ static void usb_control( uint32_t stat )
}
break;
default:
#ifdef UART_DEBUG
print("PID=unknown:");
@ -964,11 +800,6 @@ void usb_rx_memory( usb_packet_t *packet )
void usb_tx( uint32_t endpoint, usb_packet_t *packet )
{
// Since we are transmitting data, USB will be brought out of sleep/suspend
// if it's in that state
// Use the currently set descriptor value
Output_update_usb_current( *usb_bMaxPower * 2 );
bdt_t *b = &table[ index( endpoint, TX, EVEN ) ];
uint8_t next;
@ -1019,12 +850,28 @@ void usb_tx( uint32_t endpoint, usb_packet_t *packet )
void usb_device_reload()
{
// MCHCK
// Kiibohd mk20dx256vlh7
#if defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_)
// Copies variable into the VBAT register, must be identical to the variable in the bootloader to jump to the bootloader flash mode
for ( int pos = 0; pos < sizeof(sys_reset_to_loader_magic); pos++ )
(&VBAT)[ pos ] = sys_reset_to_loader_magic[ pos ];
SOFTWARE_RESET();
#if defined(_mk20dx128vlf5_)
// MCHCK Kiibohd Variant
// Check to see if PTA3 (has a pull-up) is connected to GND (usually via jumper)
// Only allow reload if the jumper is present (security)
GPIOA_PDDR &= ~(1<<3); // Input
PORTA_PCR3 = PORT_PCR_PFE | PORT_PCR_MUX(1); // Internal pull-up
// Check for jumper
if ( GPIOA_PDIR & (1<<3) )
{
print( NL );
warn_print("Security jumper not present, cancelling firmware reload...");
info_msg("Replace jumper on middle 2 pins, or manually press the firmware reload button.");
}
else
{
// Copies variable into the VBAT register, must be identical to the variable in the bootloader to jump to the bootloader flash mode
for ( int pos = 0; pos < sizeof(sys_reset_to_loader_magic); pos++ )
(&VBAT)[ pos ] = sys_reset_to_loader_magic[ pos ];
SOFTWARE_RESET();
}
// Teensy 3.0 and 3.1
#else
@ -1145,8 +992,8 @@ restart:
break;
default:
tx_state[ endpoint ] = ((uint32_t)b & 8)
? TX_STATE_ODD_FREE
: TX_STATE_EVEN_FREE;
? TX_STATE_ODD_FREE
: TX_STATE_EVEN_FREE;
break;
}
}
@ -1268,14 +1115,16 @@ restart:
USB0_ISTAT = USB_ISTAT_ERROR;
}
// USB Host signalling device to enter 'sleep' state
// The USB Module triggers this interrupt when it detects the bus has been idle for 3 ms
if ( (status & USB_ISTAT_SLEEP /* 10 */ ) )
{
info_print("Host has requested USB sleep/suspend state");
Output_update_usb_current( 100 ); // Set to 100 mA
//serial_print("sleep\n");
USB0_ISTAT = USB_ISTAT_SLEEP;
}
if ( (status & USB_ISTAT_RESUME /* 20 */ ) ) {
//serial_print("resume\n");
USB0_ISTAT = USB_ISTAT_RESUME;
}
}
@ -1286,6 +1135,11 @@ uint8_t usb_init()
print("USB INIT"NL);
#endif
// If no USB cable is attached, do not initialize usb
// XXX Test -HaaTa
//if ( USB0_OTGISTAT & USB_OTGSTAT_ID )
// return 0;
// Clear out endpoints table
for ( int i = 0; i <= NUM_ENDPOINTS * 4; i++ )
{
@ -1330,9 +1184,6 @@ uint8_t usb_init()
// enable d+ pullup
USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG;
// Do not check for power negotiation delay until Get Configuration Descriptor
power_neg_delay = 0;
return 1;
}

View file

@ -55,6 +55,8 @@ extern volatile uint8_t usb_cdc_line_coding[7];
extern volatile uint8_t usb_cdc_line_rtsdtr;
extern volatile uint8_t usb_cdc_transmit_flush_timer;
extern volatile uint8_t remote_wakeup_enabled;
// ----- Functions -----
@ -81,7 +83,6 @@ static inline uint32_t usb_rx_byte_count(uint32_t endpoint)
}
void usb_device_reload();
void usb_device_check();
extern void usb_serial_flush_callback();

View file

@ -1,114 +0,0 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
* Modified by Jacob Alexander (2015)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
// ----- Includes -----
// Compiler Includes
#include <string.h> // for memcpy()
// Project Includes
#include <Lib/OutputLib.h>
#include <print.h>
// Local Includes
#include "usb_dev.h"
#include "usb_joystick.h"
// ----- Defines -----
// Maximum number of transmit packets to queue so we don't starve other endpoints for memory
#define TX_PACKET_LIMIT 3
// When the PC isn't listening, how long do we wait before discarding data?
#define TX_TIMEOUT_MSEC 30
#if F_CPU == 168000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1100)
#elif F_CPU == 144000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 932)
#elif F_CPU == 120000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 764)
#elif F_CPU == 96000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596)
#elif F_CPU == 72000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512)
#elif F_CPU == 48000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428)
#elif F_CPU == 24000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262)
#endif
// ----- Variables -----
uint32_t usb_joystick_data[3];
static uint8_t transmit_previous_timeout = 0;
// ----- Functions -----
int usb_joystick_send()
{
uint32_t wait_count=0;
usb_packet_t *tx_packet;
//serial_print("send");
//serial_print("\n");
while (1) {
if (!usb_configuration) {
//serial_print("error1\n");
return -1;
}
if (usb_tx_packet_count(JOYSTICK_ENDPOINT) < TX_PACKET_LIMIT) {
tx_packet = usb_malloc();
if (tx_packet) break;
}
if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
transmit_previous_timeout = 1;
//serial_print("error2\n");
return -1;
}
yield();
}
transmit_previous_timeout = 0;
memcpy(tx_packet->buf, usb_joystick_data, 12);
tx_packet->len = 12;
usb_tx(JOYSTICK_ENDPOINT, tx_packet);
//serial_print("ok\n");
return 0;
}

View file

@ -1,48 +0,0 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
* Modified by Jacob Alexander (2015)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
// ----- Includes -----
// Compiler Includes
#include <inttypes.h>
// Local Includes
#include <output_com.h>
// ----- Functions -----
int usb_joystick_send();
extern uint32_t usb_joystick_data[3]; // TODO - Move, more generic

View file

@ -52,16 +52,10 @@
// When the PC isn't listening, how long do we wait before discarding data?
#define TX_TIMEOUT_MSEC 50
#if F_CPU == 168000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1100)
#elif F_CPU == 144000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 932)
#elif F_CPU == 120000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 764)
#elif F_CPU == 96000000
#if F_CPU == 96000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596)
#elif F_CPU == 72000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512)
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512) // XXX Correct?
#elif F_CPU == 48000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428)
#elif F_CPU == 24000000
@ -84,6 +78,13 @@ void usb_keyboard_send()
uint32_t wait_count = 0;
usb_packet_t *tx_packet;
if (remote_wakeup_enabled) {
USB0_CTL |= USB_CTL_RESUME;
_delay_ms(5); //wait 1 to 15ms
USB0_CTL &= ~USB_CTL_RESUME;
_delay_ms(5);
}
// Wait till ready
while ( 1 )
{
@ -95,7 +96,7 @@ void usb_keyboard_send()
if ( USBKeys_Protocol == 0 ) // Boot Mode
{
if ( usb_tx_packet_count( KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT )
if ( usb_tx_packet_count( NKRO_KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT )
{
tx_packet = usb_malloc();
if ( tx_packet )
@ -104,18 +105,7 @@ void usb_keyboard_send()
}
else if ( USBKeys_Protocol == 1 ) // NKRO Mode
{
if ( usb_tx_packet_count( NKRO_KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT )
{
tx_packet = usb_malloc();
if ( tx_packet )
break;
}
}
else if ( USBKeys_Changed &
( USBKeyChangeState_System | USBKeyChangeState_Consumer )
)
{
if ( usb_tx_packet_count( SYS_CTRL_ENDPOINT ) < TX_PACKET_LIMIT )
if ( usb_tx_packet_count( KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT )
{
tx_packet = usb_malloc();
if ( tx_packet )
@ -135,47 +125,6 @@ void usb_keyboard_send()
// Pointer to USB tx packet buffer
uint8_t *tx_buf = tx_packet->buf;
// Check system control keys
if ( USBKeys_Changed & USBKeyChangeState_System )
{
if ( Output_DebugMode )
{
print("SysCtrl[");
printHex_op( USBKeys_SysCtrl, 2 );
print( "] " NL );
}
*tx_buf++ = 0x02; // ID
*tx_buf = USBKeys_SysCtrl;
tx_packet->len = 2;
// Send USB Packet
usb_tx( SYS_CTRL_ENDPOINT, tx_packet );
USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent
return;
}
// Check consumer control keys
if ( USBKeys_Changed & USBKeyChangeState_Consumer )
{
if ( Output_DebugMode )
{
print("ConsCtrl[");
printHex_op( USBKeys_ConsCtrl, 2 );
print( "] " NL );
}
*tx_buf++ = 0x03; // ID
*tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF);
*tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8);
tx_packet->len = 3;
// Send USB Packet
usb_tx( SYS_CTRL_ENDPOINT, tx_packet );
USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent
return;
}
switch ( USBKeys_Protocol )
{
// Send boot keyboard interrupt packet(s)
@ -215,6 +164,45 @@ void usb_keyboard_send()
dbug_msg("NKRO USB: ");
}
// Check system control keys
if ( USBKeys_Changed & USBKeyChangeState_System )
{
if ( Output_DebugMode )
{
print("SysCtrl[");
printHex_op( USBKeys_SysCtrl, 2 );
print( "] " NL );
}
*tx_buf++ = 0x02; // ID
*tx_buf = USBKeys_SysCtrl;
tx_packet->len = 2;
// Send USB Packet
usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent
}
// Check consumer control keys
if ( USBKeys_Changed & USBKeyChangeState_Consumer )
{
if ( Output_DebugMode )
{
print("ConsCtrl[");
printHex_op( USBKeys_ConsCtrl, 2 );
print( "] " NL );
}
*tx_buf++ = 0x03; // ID
*tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF);
*tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8);
tx_packet->len = 3;
// Send USB Packet
usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent
}
// Standard HID Keyboard
if ( USBKeys_Changed )
{

View file

@ -1,296 +0,0 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
* Modified by Jacob Alexander (2015-2016)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
// ----- Includes -----
// Compiler Includes
#include <string.h> // for memcpy()
// Project Includes
#include <Lib/OutputLib.h>
#include <print.h>
// Local Includes
#include "usb_dev.h"
#include "usb_mouse.h"
// ----- Defines -----
// Maximum number of transmit packets to queue so we don't starve other endpoints for memory
#define TX_PACKET_LIMIT 3
// When the PC isn't listening, how long do we wait before discarding data?
#define TX_TIMEOUT_MSEC 30
#if F_CPU == 168000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1100)
#elif F_CPU == 144000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 932)
#elif F_CPU == 120000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 764)
#elif F_CPU == 96000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596)
#elif F_CPU == 72000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512)
#elif F_CPU == 48000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428)
#elif F_CPU == 24000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262)
#endif
//#define DEFAULT_XRES 640
//#define DEFAULT_YRES 480
//#define DEFAULT_XRES 800
//#define DEFAULT_YRES 600
//#define DEFAULT_XRES 1024
//#define DEFAULT_YRES 768
//#define DEFAULT_XRES 1280
//#define DEFAULT_YRES 720
//#define DEFAULT_XRES 1280
//#define DEFAULT_YRES 800
#define DEFAULT_XRES 1366
#define DEFAULT_YRES 768
//#define DEFAULT_XRES 1440
//#define DEFAULT_YRES 900
//#define DEFAULT_XRES 1920
//#define DEFAULT_YRES 1080
//#define DEFAULT_XRES 2560
//#define DEFAULT_YRES 1440
//#define DEFAULT_XRES 2560
//#define DEFAULT_YRES 1600
//#define DEFAULT_XRES 2880
//#define DEFAULT_YRES 1800
//#define DEFAULT_XRES 3840
//#define DEFAULT_YRES 2160
//#define DEFAULT_XRES 7680
//#define DEFAULT_YRES 4320
#define DEFAULT_XSCALE ((0x80000000ul+DEFAULT_XRES/2)/DEFAULT_XRES)
#define DEFAULT_YSCALE ((0x80000000ul+DEFAULT_YRES/2)/DEFAULT_YRES)
// ----- Variables -----
static uint8_t transmit_previous_timeout = 0;
// which buttons are currently pressed
uint8_t usb_mouse_buttons_state = 0;
static uint16_t usb_mouse_resolution_x = DEFAULT_XRES;
static uint16_t usb_mouse_resolution_y = DEFAULT_YRES;
static uint16_t usb_mouse_position_x = DEFAULT_XRES / 2;
static uint16_t usb_mouse_position_y = DEFAULT_YRES / 2;
static uint32_t usb_mouse_scale_x = DEFAULT_XSCALE;
static uint32_t usb_mouse_scale_y = DEFAULT_YSCALE;
static uint32_t usb_mouse_offset_x = DEFAULT_XSCALE / 2 - 1;
static uint32_t usb_mouse_offset_y = DEFAULT_YSCALE / 2 - 1;
// ----- Functions -----
// Process pending mouse commands
// XXX Missing mouse movement and wheels
// Proper support will require KLL generation of the USB descriptors
// Similar support will be required for joystick control
void usb_mouse_send()
{
uint32_t wait_count = 0;
usb_packet_t *tx_packet;
// Wait till ready
while ( 1 )
{
if ( !usb_configuration )
{
erro_print("USB not configured...");
return;
}
// Attempt to acquire a USB packet for the mouse endpoint
if ( usb_tx_packet_count( MOUSE_ENDPOINT ) < TX_PACKET_LIMIT )
{
tx_packet = usb_malloc();
if ( tx_packet )
break;
}
if ( ++wait_count > TX_TIMEOUT || transmit_previous_timeout )
{
transmit_previous_timeout = 1;
warn_print("USB Transmit Timeout...");
return;
}
yield();
}
transmit_previous_timeout = 0;
// Prepare USB Mouse Packet
// TODO Dynamically generate this code based on KLL requirements
uint16_t *packet_data = (uint16_t*)(&tx_packet->buf[0]);
packet_data[0] = USBMouse_Buttons;
packet_data[1] = USBMouse_Relative_x;
packet_data[2] = USBMouse_Relative_y;
tx_packet->len = 6;
usb_tx( MOUSE_ENDPOINT, tx_packet );
// Clear status and state
USBMouse_Buttons = 0;
USBMouse_Relative_x = 0;
USBMouse_Relative_y = 0;
USBMouse_Changed = 0;
}
// Move the mouse. x, y and wheel are -127 to 127. Use 0 for no movement.
int usb_mouse_move(int8_t x, int8_t y, int8_t wheel)
{
uint32_t wait_count=0;
usb_packet_t *tx_packet;
//serial_print("move");
//serial_print("\n");
if (x == -128) x = -127;
if (y == -128) y = -127;
if (wheel == -128) wheel = -127;
while (1) {
if (!usb_configuration) {
return -1;
}
if (usb_tx_packet_count(MOUSE_ENDPOINT) < TX_PACKET_LIMIT) {
tx_packet = usb_malloc();
if (tx_packet) break;
}
if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
transmit_previous_timeout = 1;
return -1;
}
yield();
}
transmit_previous_timeout = 0;
*(tx_packet->buf + 0) = 1;
*(tx_packet->buf + 1) = usb_mouse_buttons_state;
*(tx_packet->buf + 2) = x;
*(tx_packet->buf + 3) = y;
*(tx_packet->buf + 4) = wheel;
tx_packet->len = 5;
usb_tx(MOUSE_ENDPOINT, tx_packet);
return 0;
}
int usb_mouse_position(uint16_t x, uint16_t y)
{
uint32_t wait_count=0, val32;
usb_packet_t *tx_packet;
if (x >= usb_mouse_resolution_x) x = usb_mouse_resolution_x - 1;
usb_mouse_position_x = x;
if (y >= usb_mouse_resolution_y) y = usb_mouse_resolution_y - 1;
usb_mouse_position_y = y;
while (1) {
if (!usb_configuration) {
return -1;
}
if (usb_tx_packet_count(MOUSE_ENDPOINT) < TX_PACKET_LIMIT) {
tx_packet = usb_malloc();
if (tx_packet) break;
}
if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
transmit_previous_timeout = 1;
return -1;
}
yield();
}
transmit_previous_timeout = 0;
*(tx_packet->buf + 0) = 2;
val32 = usb_mouse_position_x * usb_mouse_scale_x + usb_mouse_offset_x;
//serial_print("position:");
//serial_phex16(usb_mouse_position_x);
//serial_print("->");
//serial_phex32(val32);
*(tx_packet->buf + 1) = val32 >> 16;
*(tx_packet->buf + 2) = val32 >> 24;
val32 = usb_mouse_position_y * usb_mouse_scale_y + usb_mouse_offset_y;
//serial_print(",");
//serial_phex16(usb_mouse_position_y);
//serial_print("->");
//serial_phex32(val32);
//serial_print("\n");
*(tx_packet->buf + 3) = val32 >> 16;
*(tx_packet->buf + 4) = val32 >> 24;
tx_packet->len = 5;
usb_tx(MOUSE_ENDPOINT, tx_packet);
return 0;
}
void usb_mouse_screen_size(uint16_t width, uint16_t height, uint8_t mac)
{
if (width < 128) width = 128;
else if (width > 7680) width = 7680;
if (height < 128) height = 128;
else if (height > 7680) height = 7680;
usb_mouse_resolution_x = width;
usb_mouse_resolution_y = height;
usb_mouse_position_x = width / 2;
usb_mouse_position_y = height / 2;
usb_mouse_scale_x = (0x80000000ul + (width >> 1)) / width;
usb_mouse_scale_y = (0x80000000ul + (height >> 1)) / height;
usb_mouse_offset_x = (usb_mouse_scale_x >> 1) - 1;
usb_mouse_offset_y = (usb_mouse_scale_y >> 1) - 1;
if (mac) {
// ugly workaround for Mac's HID coordinate scaling:
// http://lists.apple.com/archives/usb/2011/Jun/msg00032.html
usb_mouse_offset_x += 161061273ul;
usb_mouse_offset_y += 161061273ul;
usb_mouse_scale_x = (1825361101ul + (width >> 1)) / width;
usb_mouse_scale_y = (1825361101ul + (height >> 1)) / height;
}
}

View file

@ -1,53 +0,0 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
* Modified by Jacob Alexander (2015-2016)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
// ----- Includes -----
// Compiler Includes
#include <inttypes.h>
// Local Includes
#include <output_com.h>
// ----- Functions -----
// Proces pending mouse commands
void usb_mouse_send();
// TODO - More generic
int usb_mouse_move( int8_t x, int8_t y, int8_t wheel );
int usb_mouse_position( uint16_t x, uint16_t y );
void usb_mouse_screen_size( uint16_t width, uint16_t height, uint8_t mac );

View file

@ -1,10 +1,10 @@
Name = pjrcUSBCapabilities;
Version = 0.8;
Author = "HaaTa (Jacob Alexander) 2014-2016";
KLL = 0.3d;
Version = 0.4;
Author = "HaaTa (Jacob Alexander) 2014-2015";
KLL = 0.3b;
# Modified Date
Date = 2016-03-21;
Date = 2015-05-02;
# Output capabilities
@ -12,28 +12,8 @@ consCtrlOut => Output_consCtrlSend_capability( consCode : 2 );
noneOut => Output_noneSend_capability();
sysCtrlOut => Output_sysCtrlSend_capability( sysCode : 1 );
usbKeyOut => Output_usbCodeSend_capability( usbCode : 1 );
mouseOut => Output_usbMouse_capability( mouseCode : 2, relative_x : 2, relative_y : 2 );
# Configuration capabilities
kbdProtocolBoot => Output_kbdProtocolBoot_capability();
kbdProtocolNKRO => Output_kbdProtocolNKRO_capability();
# Locale Settings
keyboardLocale => KeyboardLocale_define;
keyboardLocale = 0;
# Default KRO Mode
# Set to 0 for Boot Mode (6KRO)
# Set to 1 for NKRO Mode (default)
usbProtocol => USBProtocol_define;
usbProtocol = 1;
# Bootloader Mode capability
# XXX
# By default this is disabled on purpose
# It is a large security hazard
flashModeEnabled => flashModeEnabled_define;
flashModeEnabled = 0;
flashMode => Output_flashMode_capability();

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2011-2016 by Jacob Alexander
/* Copyright (C) 2011-2015 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -37,12 +37,8 @@
#include "arm/usb_dev.h"
#include "arm/usb_keyboard.h"
#include "arm/usb_serial.h"
#include "arm/usb_mouse.h"
#endif
// KLL
#include <kll_defs.h>
// Local Includes
#include "output_com.h"
@ -51,15 +47,14 @@
// ----- Macros -----
// Used to build a bitmap lookup table from a byte addressable array
#define byteLookup( byte ) \
case (( byte ) * ( 8 )): bytePosition = byte; byteShift = 0; break; \
case (( byte ) * ( 8 ) + ( 1 )): bytePosition = byte; byteShift = 1; break; \
case (( byte ) * ( 8 ) + ( 2 )): bytePosition = byte; byteShift = 2; break; \
case (( byte ) * ( 8 ) + ( 3 )): bytePosition = byte; byteShift = 3; break; \
case (( byte ) * ( 8 ) + ( 4 )): bytePosition = byte; byteShift = 4; break; \
case (( byte ) * ( 8 ) + ( 5 )): bytePosition = byte; byteShift = 5; break; \
case (( byte ) * ( 8 ) + ( 6 )): bytePosition = byte; byteShift = 6; break; \
case (( byte ) * ( 8 ) + ( 7 )): bytePosition = byte; byteShift = 7; break
#define byteLookup( byte ) case (( byte ) * ( 8 )): bytePosition = byte; byteShift = 0; break; \
case (( byte ) * ( 8 ) + ( 1 )): bytePosition = byte; byteShift = 1; break; \
case (( byte ) * ( 8 ) + ( 2 )): bytePosition = byte; byteShift = 2; break; \
case (( byte ) * ( 8 ) + ( 3 )): bytePosition = byte; byteShift = 3; break; \
case (( byte ) * ( 8 ) + ( 4 )): bytePosition = byte; byteShift = 4; break; \
case (( byte ) * ( 8 ) + ( 5 )): bytePosition = byte; byteShift = 5; break; \
case (( byte ) * ( 8 ) + ( 6 )): bytePosition = byte; byteShift = 6; break; \
case (( byte ) * ( 8 ) + ( 7 )): bytePosition = byte; byteShift = 7; break
@ -98,67 +93,49 @@ CLIDict_Def( outputCLIDict, "USB Module Commands" ) = {
// Which modifier keys are currently pressed
// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui
// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui
uint8_t USBKeys_Modifiers = 0;
uint8_t USBKeys_ModifiersCLI = 0; // Separate CLI send buffer
uint8_t USBKeys_Modifiers = 0;
uint8_t USBKeys_ModifiersCLI = 0; // Separate CLI send buffer
// Currently pressed keys, max is defined by USB_MAX_KEY_SEND
uint8_t USBKeys_Keys [USB_NKRO_BITFIELD_SIZE_KEYS];
uint8_t USBKeys_KeysCLI[USB_NKRO_BITFIELD_SIZE_KEYS]; // Separate CLI send buffer
uint8_t USBKeys_Keys [USB_NKRO_BITFIELD_SIZE_KEYS];
uint8_t USBKeys_KeysCLI[USB_NKRO_BITFIELD_SIZE_KEYS]; // Separate CLI send buffer
// System Control and Consumer Control 1KRO containers
uint8_t USBKeys_SysCtrl;
uint16_t USBKeys_ConsCtrl;
uint8_t USBKeys_SysCtrl;
uint16_t USBKeys_ConsCtrl;
// The number of keys sent to the usb in the array
uint8_t USBKeys_Sent = 0;
uint8_t USBKeys_SentCLI = 0;
uint8_t USBKeys_Sent = 0;
uint8_t USBKeys_SentCLI = 0;
// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
volatile uint8_t USBKeys_LEDs = 0;
// Currently pressed mouse buttons, bitmask, 0 represents no buttons pressed
volatile uint16_t USBMouse_Buttons = 0;
// Relative mouse axis movement, stores pending movement
volatile uint16_t USBMouse_Relative_x = 0;
volatile uint16_t USBMouse_Relative_y = 0;
// Protocol setting from the host.
// 0 - Boot Mode
// 1 - NKRO Mode (Default, unless set by a BIOS or boot interface)
volatile uint8_t USBKeys_Protocol = USBProtocol_define;
volatile uint8_t USBKeys_Protocol = 1;
// Indicate if USB should send update
// OS only needs update if there has been a change in state
USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None;
// Indicate if USB should send update
USBMouseChangeState USBMouse_Changed = 0;
// the idle configuration, how often we send the report to the
// host (ms * 4) even when it hasn't changed
uint8_t USBKeys_Idle_Config = 125;
uint8_t USBKeys_Idle_Config = 125;
// count until idle timeout
uint8_t USBKeys_Idle_Count = 0;
uint8_t USBKeys_Idle_Count = 0;
// Indicates whether the Output module is fully functional
// 0 - Not fully functional, 1 - Fully functional
// 0 is often used to show that a USB cable is not plugged in (but has power)
volatile uint8_t Output_Available = 0;
uint8_t Output_Available = 0;
// Debug control variable for Output modules
// 0 - Debug disabled (default)
// 1 - Debug enabled
uint8_t Output_DebugMode = 0;
// mA - Set by outside module if not using USB (i.e. Interconnect)
// Generally set to 100 mA (low power) or 500 mA (high power)
uint16_t Output_ExtCurrent_Available = 0;
// mA - Set by USB module (if exists)
// Initially 100 mA, but may be negotiated higher (e.g. 500 mA)
uint16_t Output_USBCurrent_Available = 0;
uint8_t Output_DebugMode = 0;
@ -507,76 +484,6 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
}
}
void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("Output_flashMode()");
return;
}
// Start flash mode
Output_firmwareReload();
}
// Sends a mouse command over the USB Output buffer
// XXX This function *will* be changing in the future
// If you use it, be prepared that your .kll files will break in the future (post KLL 0.5)
// Argument #1: USB Mouse Button (16 bit)
// Argument #2: USB X Axis (16 bit) relative
// Argument #3: USB Y Axis (16 bit) relative
void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("Output_usbMouse(mouseButton,relX,relY)");
return;
}
// Determine which mouse button was sent
// The USB spec defines up to a max of 0xFFFF buttons
// The usual are:
// 1 - Button 1 - (Primary)
// 2 - Button 2 - (Secondary)
// 3 - Button 3 - (Tertiary)
uint16_t mouse_button = *(uint16_t*)(&args[0]);
// X/Y Relative Axis
uint16_t mouse_x = *(uint16_t*)(&args[2]);
uint16_t mouse_y = *(uint16_t*)(&args[4]);
// Adjust for bit shift
uint16_t mouse_button_shift = mouse_button - 1;
// Only send mouse button if in press or hold state
if ( stateType == 0x00 && state == 0x03 ) // Release state
{
// Release
if ( mouse_button )
USBMouse_Buttons &= ~(1 << mouse_button_shift);
}
else
{
// Press or hold
if ( mouse_button )
USBMouse_Buttons |= (1 << mouse_button_shift);
if ( mouse_x )
USBMouse_Relative_x = mouse_x;
if ( mouse_y )
USBMouse_Relative_y = mouse_y;
}
// Trigger updates
if ( mouse_button )
USBMouse_Changed |= USBMouseChangeState_Buttons;
if ( mouse_x || mouse_y )
USBMouse_Changed |= USBMouseChangeState_Relative;
}
// ----- Functions -----
@ -598,11 +505,13 @@ void Output_flushBuffers()
// USB Module Setup
inline void Output_setup()
{
// Initialize the USB
// If a USB connection does not exist, just ignore it
// All usb related functions will non-fatally fail if called
// If the USB initialization is delayed, then functionality will just be delayed
usb_init();
// Initialize the USB, and then wait for the host to set configuration.
// This will hang forever if USB does not initialize
// If no USB cable is attached, does not try and initialize USB
if ( usb_init() )
{
while ( !usb_configured() );
}
// Register USB Output CLI dictionary
CLI_registerDictionary( outputCLIDict, outputCLIDictName );
@ -615,19 +524,11 @@ inline void Output_setup()
// USB Data Send
inline void Output_send()
{
// USB status checks
// Non-standard USB state manipulation, usually does nothing
usb_device_check();
// Boot Mode Only, unset stale keys
if ( USBKeys_Protocol == 0 )
for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
USBKeys_Keys[c] = 0;
// Process mouse actions
while ( USBMouse_Changed )
usb_mouse_send();
// Send keypresses while there are pending changes
while ( USBKeys_Changed )
usb_keyboard_send();
@ -702,72 +603,6 @@ inline void Output_softReset()
}
// Update USB current (mA)
// Triggers power change event
void Output_update_usb_current( unsigned int current )
{
// Only signal if changed
if ( current == Output_USBCurrent_Available )
return;
// Update USB current
Output_USBCurrent_Available = current;
unsigned int total_current = Output_current_available();
info_msg("USB Available Current Changed. Total Available: ");
printInt32( total_current );
print(" mA" NL);
// Send new total current to the Scan Modules
Scan_currentChange( Output_current_available() );
}
// Update external current (mA)
// Triggers power change event
void Output_update_external_current( unsigned int current )
{
// Only signal if changed
if ( current == Output_ExtCurrent_Available )
return;
// Update external current
Output_ExtCurrent_Available = current;
unsigned int total_current = Output_current_available();
info_msg("External Available Current Changed. Total Available: ");
printInt32( total_current );
print(" mA" NL);
// Send new total current to the Scan Modules
Scan_currentChange( Output_current_available() );
}
// Power/Current Available
unsigned int Output_current_available()
{
unsigned int total_current = 0;
// Check for USB current source
total_current += Output_USBCurrent_Available;
// Check for external current source
total_current += Output_ExtCurrent_Available;
// XXX If the total available current is still 0
// Set to 100 mA, which is generally a safe assumption at startup
// before we've been able to determine actual available current
if ( total_current == 0 )
{
total_current = 100;
}
return total_current;
}
// ----- CLI Command Functions -----
void cliFunc_kbdProtocol( char* args )

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2013-2016 by Jacob Alexander
/* Copyright (C) 2013-2015 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -56,14 +56,6 @@ typedef enum USBKeyChangeState {
USBKeyChangeState_All = 0x7F,
} USBKeyChangeState;
// Allows for selective USB descriptor pushes
// However, in most cases everything is updated for each packet push
typedef enum USBMouseChangeState {
USBMouseChangeState_None = 0x00,
USBMouseChangeState_Buttons = 0x01,
USBMouseChangeState_Relative = 0x02,
} USBMouseChangeState;
// ----- Variables -----
@ -80,22 +72,29 @@ extern uint16_t USBKeys_ConsCtrl; // 1KRO container for Consumer Contro
extern volatile uint8_t USBKeys_Protocol; // 0 - Boot Mode, 1 - NKRO Mode
extern volatile uint16_t USBMouse_Buttons; // Bitmask for mouse buttons
extern volatile uint16_t USBMouse_Relative_x;
extern volatile uint16_t USBMouse_Relative_y;
// Misc variables (XXX Some are only properly utilized using AVR)
extern uint8_t USBKeys_Idle_Config;
extern uint8_t USBKeys_Idle_Count;
extern USBKeyChangeState USBKeys_Changed;
extern USBMouseChangeState USBMouse_Changed;
extern USBKeyChangeState USBKeys_Changed;
extern volatile uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working
extern uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working
extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enabled
extern uint16_t Output_ExtCurrent_Available; // mA - Set by outside module if not using USB (i.e. Interconnect)
// ----- Capabilities -----
// Output capabilities
void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void Output_noneSend_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args );
// Configuration capabilities
void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args );
@ -112,12 +111,6 @@ void Output_softReset();
// Relies on USB serial module
unsigned int Output_availablechar();
// Returns the total mA available (total, if used in a chain, each device will have to use a slice of it)
unsigned int Output_current_available();
void Output_update_external_current( unsigned int current );
void Output_update_usb_current( unsigned int current );
int Output_getchar();
int Output_putchar( char c );
int Output_putstr( char* str );

View file

@ -26,10 +26,8 @@ elseif ( ${COMPILER_FAMILY} MATCHES "arm" )
output_com.c
arm/usb_desc.c
arm/usb_dev.c
arm/usb_joystick.c
arm/usb_keyboard.c
arm/usb_mem.c
arm/usb_mouse.c
arm/usb_serial.c
)

View file

@ -27,8 +27,6 @@
// Project Includes
#include <Lib/OutputLib.h>
#include <Lib/Interrupts.h>
#include <print.h>
#include <kll_defs.h>
// Local Includes
#include "uart_serial.h"
@ -327,48 +325,6 @@ void uart_serial_flush_output()
void uart_device_reload()
{
if ( flashModeEnabled_define == 0 )
{
print( NL );
warn_print("flashModeEnabled not set, cancelling firmware reload...");
info_msg("Set flashModeEnabled to 1 in your kll configuration.");
return;
}
// MCHCK
#if defined(_mk20dx128vlf5_)
// MCHCK Kiibohd Variant
// Check to see if PTA3 (has a pull-up) is connected to GND (usually via jumper)
// Only allow reload if the jumper is present (security)
GPIOA_PDDR &= ~(1<<3); // Input
PORTA_PCR3 = PORT_PCR_PFE | PORT_PCR_MUX(1); // Internal pull-up
// Check for jumper
if ( GPIOA_PDIR & (1<<3) && flashModeEnabled_define != 0 )
{
print( NL );
warn_print("Security jumper not present, cancelling firmware reload...");
info_msg("Replace jumper on middle 2 pins, or manually press the firmware reload button.");
}
else
{
// Copies variable into the VBAT register, must be identical to the variable in the bootloader to jump to the bootloader flash mode
for ( int pos = 0; pos < sizeof(sys_reset_to_loader_magic); pos++ )
(&VBAT)[ pos ] = sys_reset_to_loader_magic[ pos ];
SOFTWARE_RESET();
}
// Kiibohd mk20dx256vlh7
#elif defined(_mk20dx256vlh7_)
// Copies variable into the VBAT register, must be identical to the variable in the bootloader to jump to the bootloader flash mode
for ( int pos = 0; pos < sizeof(sys_reset_to_loader_magic); pos++ )
(&VBAT)[ pos ] = sys_reset_to_loader_magic[ pos ];
SOFTWARE_RESET();
// Teensy 3.0 and 3.1
#else
asm volatile("bkpt");
#endif
}

View file

@ -1,21 +1,12 @@
Name = uartOutCapabilities;
Version = 0.2;
Version = 0.1;
Author = "HaaTa (Jacob Alexander) 2014";
KLL = 0.3;
# Modified Date
Date = 2014-08-21;
Date = 2014-09-27;
# Capabilties available to the uartOut output module
usbKeyOut => Output_usbCodeSend_capability( usbCode : 1 );
# Bootloader Mode capability
# XXX
# By default this is disabled on purpose
# It is a large security hazard
flashModeEnabled => flashModeEnabled_define;
flashModeEnabled = 0;
flashMode => Output_flashMode_capability();

View file

@ -129,19 +129,6 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
}
}
void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("Output_flashMode(usbCode)");
return;
}
// Start flash mode
Output_firmwareReload();
}
// ----- Functions -----

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
/* Copyright (C) 2014-2015 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -61,7 +61,6 @@
// ----- Function Declarations -----
void cliFunc_kbdProtocol( char* args );
void cliFunc_outputDebug( char* args );
void cliFunc_readLEDs ( char* args );
void cliFunc_readUART ( char* args );
void cliFunc_sendKeys ( char* args );
@ -75,7 +74,6 @@ void cliFunc_setMod ( char* args );
// Output Module command dictionary
CLIDict_Entry( kbdProtocol, "Keyboard Protocol Mode: 0 - Boot, 1 - OS/NKRO Mode" );
CLIDict_Entry( outputDebug, "Toggle Output Debug mode." );
CLIDict_Entry( readLEDs, "Read LED byte:" NL "\t\t1 NumLck, 2 CapsLck, 4 ScrlLck, 16 Kana, etc." );
CLIDict_Entry( readUART, "Read UART buffer until empty." );
CLIDict_Entry( sendKeys, "Send the prepared list of USB codes and modifier byte." );
@ -85,7 +83,6 @@ CLIDict_Entry( setMod, "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4
CLIDict_Def( outputCLIDict, "USB Module Commands" ) = {
CLIDict_Item( kbdProtocol ),
CLIDict_Item( outputDebug ),
CLIDict_Item( readLEDs ),
CLIDict_Item( readUART ),
CLIDict_Item( sendKeys ),
@ -99,20 +96,20 @@ CLIDict_Def( outputCLIDict, "USB Module Commands" ) = {
// Which modifier keys are currently pressed
// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui
// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui
uint8_t USBKeys_Modifiers = 0;
uint8_t USBKeys_ModifiersCLI = 0; // Separate CLI send buffer
uint8_t USBKeys_Modifiers = 0;
uint8_t USBKeys_ModifiersCLI = 0; // Separate CLI send buffer
// Currently pressed keys, max is defined by USB_MAX_KEY_SEND
uint8_t USBKeys_Keys [USB_NKRO_BITFIELD_SIZE_KEYS];
uint8_t USBKeys_KeysCLI[USB_NKRO_BITFIELD_SIZE_KEYS]; // Separate CLI send buffer
uint8_t USBKeys_Keys [USB_NKRO_BITFIELD_SIZE_KEYS];
uint8_t USBKeys_KeysCLI[USB_NKRO_BITFIELD_SIZE_KEYS]; // Separate CLI send buffer
// System Control and Consumer Control 1KRO containers
uint8_t USBKeys_SysCtrl;
uint16_t USBKeys_ConsCtrl;
uint8_t USBKeys_SysCtrl;
uint16_t USBKeys_ConsCtrl;
// The number of keys sent to the usb in the array
uint8_t USBKeys_Sent = 0;
uint8_t USBKeys_SentCLI = 0;
uint8_t USBKeys_Sent = 0;
uint8_t USBKeys_SentCLI = 0;
// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
volatile uint8_t USBKeys_LEDs = 0;
@ -120,7 +117,7 @@ volatile uint8_t USBKeys_LEDs = 0;
// Protocol setting from the host.
// 0 - Boot Mode
// 1 - NKRO Mode (Default, unless set by a BIOS or boot interface)
volatile uint8_t USBKeys_Protocol = 1;
volatile uint8_t USBKeys_Protocol = 0;
// Indicate if USB should send update
// OS only needs update if there has been a change in state
@ -128,28 +125,20 @@ USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None;
// the idle configuration, how often we send the report to the
// host (ms * 4) even when it hasn't changed
uint8_t USBKeys_Idle_Config = 125;
uint8_t USBKeys_Idle_Config = 125;
// count until idle timeout
uint8_t USBKeys_Idle_Count = 0;
uint8_t USBKeys_Idle_Count = 0;
// Indicates whether the Output module is fully functional
// 0 - Not fully functional, 1 - Fully functional
// 0 is often used to show that a USB cable is not plugged in (but has power)
volatile uint8_t Output_Available = 0;
uint8_t Output_Available = 0;
// Debug control variable for Output modules
// 0 - Debug disabled (default)
// 1 - Debug enabled
uint8_t Output_DebugMode = 0;
// mA - Set by outside module if not using USB (i.e. Interconnect)
// Generally set to 100 mA (low power) or 500 mA (high power)
uint16_t Output_ExtCurrent_Available = 0;
// mA - Set by USB module (if exists)
// Initially 100 mA, but may be negotiated higher (e.g. 500 mA)
uint16_t Output_USBCurrent_Available = 0;
uint8_t Output_DebugMode = 0;
@ -233,10 +222,7 @@ void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *
// Only send keypresses if press or hold state
if ( stateType == 0x00 && state == 0x03 ) // Release state
{
USBKeys_ConsCtrl = 0;
return;
}
// Set consumer control code
USBKeys_ConsCtrl = *(uint16_t*)(&args[0]);
@ -282,10 +268,7 @@ void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
// Only send keypresses if press or hold state
if ( stateType == 0x00 && state == 0x03 ) // Release state
{
USBKeys_SysCtrl = 0;
return;
}
// Set system control code
USBKeys_SysCtrl = args[0];
@ -334,10 +317,9 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
// Depending on which mode the keyboard is in, USBKeys_Keys array is used differently
// Boot mode - Maximum of 6 byte codes
// NKRO mode - Each bit of the 26 byte corresponds to a key
// Bits 0 - 45 (bytes 0 - 5) correspond to USB Codes 4 - 49 (Main)
// Bits 48 - 161 (bytes 6 - 20) correspond to USB Codes 51 - 164 (Secondary)
// Bits 168 - 213 (bytes 21 - 26) correspond to USB Codes 176 - 221 (Tertiary)
// Bits 214 - 216 unused
// Bits 0 - 160 (first 20 bytes) correspond to USB Codes 4 - 164
// Bits 161 - 205 (last 6 bytes) correspond to USB Codes 176 - 221
// Bits 206 - 208 (last byte) correspond to the 3 padded bits in USB (unused)
uint8_t bytePosition = 0;
uint8_t byteShift = 0;
switch ( USBKeys_Protocol )
@ -389,12 +371,11 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
USBKeys_Changed |= USBKeyChangeState_Modifiers;
break;
}
// First 6 bytes
else if ( key >= 4 && key <= 49 )
// First 20 bytes
else if ( key >= 4 && key <= 164 )
{
// Lookup (otherwise division or multiple checks are needed to do alignment)
// Starting at 0th position, each byte has 8 bits, starting at 4th bit
uint8_t keyPos = key + (0 * 8 - 4); // Starting position in array, Ignoring 4 keys
uint8_t keyPos = key - 4; // Starting position in array
switch ( keyPos )
{
byteLookup( 0 );
@ -403,18 +384,6 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
byteLookup( 3 );
byteLookup( 4 );
byteLookup( 5 );
}
USBKeys_Changed |= USBKeyChangeState_MainKeys;
}
// Next 14 bytes
else if ( key >= 51 && key <= 155 )
{
// Lookup (otherwise division or multiple checks are needed to do alignment)
// Starting at 6th byte position, each byte has 8 bits, starting at 51st bit
uint8_t keyPos = key + (6 * 8 - 51); // Starting position in array
switch ( keyPos )
{
byteLookup( 6 );
byteLookup( 7 );
byteLookup( 8 );
@ -431,52 +400,29 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
byteLookup( 19 );
}
USBKeys_Changed |= USBKeyChangeState_SecondaryKeys;
}
// Next byte
else if ( key >= 157 && key <= 164 )
{
// Lookup (otherwise division or multiple checks are needed to do alignment)
uint8_t keyPos = key + (20 * 8 - 157); // Starting position in array, Ignoring 6 keys
switch ( keyPos )
{
byteLookup( 20 );
}
USBKeys_Changed |= USBKeyChangeState_TertiaryKeys;
USBKeys_Changed |= USBKeyChangeState_MainKeys;
}
// Last 6 bytes
else if ( key >= 176 && key <= 221 )
{
// Lookup (otherwise division or multiple checks are needed to do alignment)
uint8_t keyPos = key + (21 * 8 - 176); // Starting position in array
uint8_t keyPos = key - 176; // Starting position in array
switch ( keyPos )
{
byteLookup( 20 );
byteLookup( 21 );
byteLookup( 22 );
byteLookup( 23 );
byteLookup( 24 );
byteLookup( 25 );
byteLookup( 26 );
}
USBKeys_Changed |= USBKeyChangeState_QuartiaryKeys;
}
// Received 0x00
// This is a special USB Code that internally indicates a "break"
// It is used to send "nothing" in order to break up sequences of USB Codes
else if ( key == 0x00 )
{
USBKeys_Changed |= USBKeyChangeState_MainKeys;
// Also flush out buffers just in case
Output_flushBuffers();
break;
USBKeys_Changed |= USBKeyChangeState_SecondaryKeys;
}
// Invalid key
else
{
warn_msg("USB Code not within 4-49 (0x4-0x31), 51-155 (0x33-0x9B), 157-164 (0x9D-0xA4), 176-221 (0xB0-0xDD) or 224-231 (0xE0-0xE7) NKRO Mode: ");
warn_msg("USB Code not within 4-164 (0x4-0xA4) or 176-221 (0xB0-0xDD) NKRO Mode: ");
printHex( key );
print( NL );
break;
@ -498,19 +444,6 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
}
}
void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("Output_flashMode()");
return;
}
// Start flash mode
Output_firmwareReload();
}
// ----- Functions -----
@ -534,28 +467,26 @@ inline void Output_setup()
{
// Setup UART
uart_serial_setup();
print("\033[2J"); // Clear screen
// Initialize the USB
// If a USB connection does not exist, just ignore it
// All usb related functions will non-fatally fail if called
// If the USB initialization is delayed, then functionality will just be delayed
// Initialize the USB, and then wait for the host to set configuration.
// This will hang forever if USB does not initialize
usb_init();
while ( !usb_configured() );
// Register USB Output CLI dictionary
CLI_registerDictionary( outputCLIDict, outputCLIDictName );
// Flush key buffers
Output_flushBuffers();
// Zero out USBKeys_Keys array
for ( uint8_t c = 0; c < USB_NKRO_BITFIELD_SIZE_KEYS; c++ )
USBKeys_Keys[ c ] = 0;
}
// USB Data Send
inline void Output_send()
{
// USB status checks
// Non-standard USB state manipulation, usually does nothing
usb_device_check();
// Boot Mode Only, unset stale keys
if ( USBKeys_Protocol == 0 )
for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
@ -565,15 +496,14 @@ inline void Output_send()
while ( USBKeys_Changed )
usb_keyboard_send();
// Clear keys sent
USBKeys_Sent = 0;
// Clear modifiers and keys
USBKeys_Modifiers = 0;
USBKeys_Sent = 0;
// Signal Scan Module we are finished
switch ( USBKeys_Protocol )
{
case 0: // Boot Mode
// Clear modifiers only in boot mode
USBKeys_Modifiers = 0;
Scan_finishedWithOutput( USBKeys_Sent <= USB_BOOT_MAX_KEYS ? USBKeys_Sent : USB_BOOT_MAX_KEYS );
break;
case 1: // NKRO Mode
@ -584,9 +514,9 @@ inline void Output_send()
// Sets the device into firmware reload mode
void Output_firmwareReload()
inline void Output_firmwareReload()
{
usb_device_reload();
uart_device_reload();
}
@ -653,72 +583,6 @@ inline void Output_softReset()
}
// Update USB current (mA)
// Triggers power change event
void Output_update_usb_current( unsigned int current )
{
// Only signal if changed
if ( current == Output_USBCurrent_Available )
return;
// Update USB current
Output_USBCurrent_Available = current;
unsigned int total_current = Output_current_available();
info_msg("USB Available Current Changed. Total Available: ");
printInt32( total_current );
print(" mA" NL);
// Send new total current to the Scan Modules
Scan_currentChange( Output_current_available() );
}
// Update external current (mA)
// Triggers power change event
void Output_update_external_current( unsigned int current )
{
// Only signal if changed
if ( current == Output_ExtCurrent_Available )
return;
// Update external current
Output_ExtCurrent_Available = current;
unsigned int total_current = Output_current_available();
info_msg("External Available Current Changed. Total Available: ");
printInt32( total_current );
print(" mA" NL);
// Send new total current to the Scan Modules
Scan_currentChange( Output_current_available() );
}
// Power/Current Available
unsigned int Output_current_available()
{
unsigned int total_current = 0;
// Check for USB current source
total_current += Output_USBCurrent_Available;
// Check for external current source
total_current += Output_ExtCurrent_Available;
// XXX If the total available current is still 0
// Set to 100 mA, which is generally a safe assumption at startup
// before we've been able to determine actual available current
if ( total_current == 0 )
{
total_current = 100;
}
return total_current;
}
// ----- CLI Command Functions -----
void cliFunc_kbdProtocol( char* args )
@ -729,24 +593,6 @@ void cliFunc_kbdProtocol( char* args )
}
void cliFunc_outputDebug( char* args )
{
// Parse number from argument
// NOTE: Only first argument is used
char* arg1Ptr;
char* arg2Ptr;
CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
// Default to 1 if no argument is given
Output_DebugMode = 1;
if ( arg1Ptr[0] != '\0' )
{
Output_DebugMode = (uint16_t)numToInt( arg1Ptr );
}
}
void cliFunc_readLEDs( char* args )
{
print( NL );

View file

@ -12,9 +12,7 @@ Please refer to the [KLL](https://github.com/kiibohd/kll) repo or [kiibohd.com](
Official Keyboards
------------------
* MD1 (Infinity Keyboard/IC60 2014/10/15)
* MDErgo1 (Infinity Ergodox /ICED 2015/03/31)
* WhiteFox (Soon to be released?)
* MD1 (Infinity Keyboard 2014/10/15)
The Kiibohd firmware supports a lot of other keyboards, but these are more obscure/custom/lesser known.
@ -38,8 +36,8 @@ Supported Microcontrollers
* Teensy 2.0 (Partial)
* Teensy 2.0++
* Teensy 3.0
* Teensy 3.1/3.2
* Teesny 3.0
* Teensy 3.1
* mk20dx128vlf5
* mk20dx256vlh7
@ -84,7 +82,6 @@ Contact
If you really need to get a hold of HaaTa, email is best: `haata@kiibohd.com`
IRC is likely faster though.
`#input.club@irc.freenode.net`
`#geekhack@irc.freenode.net`
`#deskthority@irc.freenode.net`

View file

@ -1,132 +0,0 @@
Name = CK3;
Version = 0.3;
Author = "Crystal Hammer 2016";
KLL = 0.3d;
# Modified Date
Date = 2016-03-01;
# this is nearly the default map
S0x0F : U"Esc";
S0x8C : U"F1";
S0x8B : U"F2";
S0x67 : U"F3";
S0x0D : U"F4";
S0x6E : U"F5";
S0x06 : U"F6";
S0x5F : U"F7";
S0x83 : U"F8";
S0x7F : U"F9";
S0x6D : U"F10";
S0x01 : U"F11";
S0x13 : U"F12";
S0x6F : U"PrintScreen";
S0x4B : U"ScrollLock";
S0x4A : U"Pause";
S0x39 : U"F16";
S0x8D : U"BackTick";
S0x7B : U"1";
S0x7A : U"2";
S0x79 : U"3";
S0x74 : U"4";
S0x86 : U"5";
S0x85 : U"6";
S0x73 : U"7";
S0x72 : U"8";
S0x71 : U"9";
S0x6C : U"0";
S0x7E : U"-";
S0x84 : U"=";
S0x5B : U"Backspace";
S0x69 : U"Tab";
S0x57 : U"Q";
S0x56 : U"W";
S0x55 : U"E";
S0x50 : U"R";
S0x62 : U"T";
S0x61 : U"Y";
S0x4F : U"U";
S0x4E : U"I";
S0x4D : U"O";
S0x48 : U"P";
S0x5A : U"[";
S0x60 : U"]";
S0x37 : U"\";
S0x68 : U"CapsLock";
S0x45 : U"A";
S0x44 : U"S";
S0x43 : U"D";
S0x3E : U"F";
S0x08 : U"G";
S0x07 : U"H";
S0x3D : U"J";
S0x3C : U"K";
S0x3B : U"L";
S0x36 : U";";
S0x00 : U"'";
S0x25 : U"Enter";
S0x5E : U"LShift";
S0x33 : U"Z";
S0x32 : U"X";
S0x31 : U"C";
S0x2C : U"V";
S0x1A : U"B";
S0x19 : U"N";
S0x2B : U"M";
S0x2A : U",";
S0x29 : U".";
S0x12 : U"/";
S0x3A : U"RShift";
# bottom
S0x80 : U"LCtrl";
S0x6A : U"LGui";
S0x0E : U"LAlt";
S0x03 : U"LAlt";
S0x09 : U"Space";
S0x15 : U"RAlt";
S0x17 : U"RGui";
S0x88 : U"RCtrl";
S0x87 : U"RCtrl";
# middle right column, custom
S0x8A : U"Esc";
S0x89 : U"Backspace";
S0x77 : U"Enter";
S0x78 : U"RShift";
# arrows
S0x1E : U"Left";
S0x0C : U"Up";
S0x1B : U"Down";
S0x1C : U"Right";
# S0x1C : U"RCtrl";
# numpad
S0x2D : U"NumLock";
S0x2E : U"P/";
S0x2F : U"P*";
S0x1D : U"P-";
S0x51 : U"P7";
S0x52 : U"P8";
S0x53 : U"P9";
S0x54 : U"P+";
S0x63 : U"P4";
S0x64 : U"P5";
S0x65 : U"P6";
S0x3F : U"P1";
S0x40 : U"P2";
S0x41 : U"P3";
S0x42 : U"PEnter";
S0x0A : U"P0";
S0x0B : U"P.";

View file

@ -1,68 +0,0 @@
/* Copyright (C) 2014-2016 by Jacob Alexander, Crystal Hammer
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
// ----- Includes -----
// Project Includes
#include <matrix_setup.h>
// ----- Matrix Definition -----
// CK3
// Columns (Strobe) 18
// Rows (Sense) 8
// This is the default map of just A4Tech KX-100 matrix
// scan codes for keys are defined in defaultMap.kll
/*
1| 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
-
1 Mcmp Bstp Esc \ F4 Up Del Ins Spc G H F6 == Vol- AltL xx F11 '
2 Calc ExA4 ExC2 ExE2 ExE1 <- Sub -> Dn B N ExC1 Apps Mnxt AltR xx F12 /
3 Mstp Bbck Z X C Mpau Mul Div NumL V M , . Vol+ xx CtrR Ent \
4 GuiR Bfwd A S D Ent PgDn Dn End F J K L ShiR xx == \ ;
5 xx Mail Q W E Add PgUp Up Home R U I O xx ScrL Paus ExE3 P
6 ExB1 GuiL Tab Caps F3 RB~ -> Del <- T Y ] F7 ShiL == Pwr Back [
7 xx Bsch 1 2 3 End PgDn xx Pwr 4 7 8 9 Msel Ptr F5 F10 0
8 Bhom Vmut `~ F1 F2 Home PgUp Ins Del 5 6 = F8 Mprv == CtrL F9 -
rows - columns |
1 3 5 7 1 3 5 7 9 11 13 15 17
2 4 6 8 2 4 6 8 10 12 14 16 18 connectors, PCB view
*/
GPIO_Pin Matrix_cols[] = {
gpio(B,16), gpio(B,17), gpio(D,0), gpio(A,12), gpio(A,13), gpio(D,7), gpio(D,4), gpio(D,2), gpio(D,3),
gpio(C,2), gpio(C,1), gpio(D,6), gpio(D,5), gpio(B,2), gpio(B,3), gpio(B,1), gpio(B,0), gpio(C,0) };
GPIO_Pin Matrix_rows[] = {
gpio(C,10), gpio(C,11), gpio(B,18), gpio(A,4), gpio(A,5), gpio(B,19), gpio(C,9), gpio(C,8) };
// Define type of scan matrix
Config Matrix_type = Config_Pullup;
// Define this if your matrix has ghosting (i.e. regular keyboard without diodes)
// this will enable the anti-ghosting code
#define GHOSTING_MATRIX
// delay in microseconds before and after each strobe change during matrix scan
#define STROBE_DELAY 10

View file

@ -1,213 +0,0 @@
/* Copyright (C) 2014 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// ----- Includes -----
// Compiler Includes
#include <Lib/ScanLib.h>
// Project Includes
#include <cli.h>
#include <led.h>
#include <print.h>
#include <matrix_scan.h>
#include <macro.h>
// Local Includes
#include "scan_loop.h"
// ----- Function Declarations -----
// CLI Functions
void cliFunc_echo( char* args );
// ----- Variables -----
// Scan Module command dictionary
CLIDict_Entry( echo, "Example command, echos the arguments." );
CLIDict_Def( scanCLIDict, "Scan Module Commands" ) = {
CLIDict_Item( echo ),
{ 0, 0, 0 } // Null entry for dictionary end
};
// Number of scans since the last USB send
uint16_t Scan_scanCount = 0;
// ----- Functions -----
// Setup
inline void Scan_setup()
{
// Register Scan CLI dictionary
CLI_registerDictionary( scanCLIDict, scanCLIDictName );
// Setup GPIO pins for matrix scanning
Matrix_setup();
// Reset scan count
Scan_scanCount = 0;
}
// Main Detection Loop
inline uint8_t Scan_loop()
{
Matrix_scan( Scan_scanCount++ );
return 0;
}
// Signal from Macro Module that all keys have been processed (that it knows about)
inline void Scan_finishedWithMacro( uint8_t sentKeys )
{
}
// Signal from Output Module that all keys have been processed (that it knows about)
inline void Scan_finishedWithOutput( uint8_t sentKeys )
{
// Reset scan loop indicator (resets each key debounce state)
// TODO should this occur after USB send or Macro processing?
Scan_scanCount = 0;
}
// ----- Capabilities -----
// Custom capability examples
// Refer to kll.h in Macros/PartialMap for state and stateType information
void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
// XXX This is required for debug cli to give you a list of capabilities
if ( stateType == 0xFF && state == 0xFF )
{
print("CustomAction_action1_capability()");
return;
}
// Prints Action1 info message to the debug cli
info_print("Action1");
}
uint8_t CustomAction_blockHold_storage = 0;
void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("CustomAction_blockHold_capability(usbCode)");
return;
}
// Retrieve 8-bit argument
uint8_t key = args[0];
// We only care about normal keys
if ( stateType == 0x00 )
{
// Block given key if we're in the "Press" or "Hold" state
if ( ( state == 0x01 || state == 0x02 )
&& CustomAction_blockHold_storage == 0 )
{
CustomAction_blockHold_storage = key;
info_msg("Blocking Key: ");
printHex( key );
print( NL );
}
// Release if in the "Off" or "Release" state and we're blocking
else if ( ( state == 0x00 || state == 0x03 )
&& key == CustomAction_blockHold_storage )
{
info_msg("Unblocking Key: ");
printHex( CustomAction_blockHold_storage );
print( NL );
CustomAction_blockHold_storage = 0;
}
}
}
void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("CustomAction_blockKey_capability(usbCode)");
return;
}
// Retrieve 8-bit argument
uint8_t key = args[0];
// If key is not blocked, process
if ( key != CustomAction_blockHold_storage )
{
extern void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args );
Output_usbCodeSend_capability( state, stateType, &key );
}
}
// Signal from the Output Module that the available current has changed
// current - mA
void Scan_currentChange( unsigned int current )
{
// Indicate to all submodules current change
Matrix_currentChange( current );
}
// ----- CLI Command Functions -----
// XXX Just an example command showing how to parse arguments (more complex than generally needed)
void cliFunc_echo( char* args )
{
char* curArgs;
char* arg1Ptr;
char* arg2Ptr = args;
// Parse args until a \0 is found
while ( 1 )
{
print( NL ); // No \r\n by default after the command is entered
curArgs = arg2Ptr; // Use the previous 2nd arg pointer to separate the next arg from the list
CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
// Stop processing args if no more are found
if ( *arg1Ptr == '\0' )
break;
// Print out the arg
dPrint( arg1Ptr );
}
}

View file

@ -1,50 +0,0 @@
/* Copyright (C) 2014-2015 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
// ----- Includes -----
// Compiler Includes
#include <stdint.h>
// ----- Functions -----
// Functions to be called by main.c
void Scan_setup( void );
uint8_t Scan_loop( void );
// Call-backs
void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module
void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module
void Scan_currentChange( unsigned int current ); // Called by Output Module
// ----- Capabilities -----
// Example capabilities
void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args );

View file

@ -1,32 +0,0 @@
###| CMake Kiibohd Controller Scan Module |###
#
# Written by Jacob Alexander in 2014 for the Kiibohd Controller
#
# Released into the Public Domain
#
###
###
# Required Submodules
#
AddModule ( Scan MatrixARM )
###
# Module C files
#
set ( Module_SRCS
scan_loop.c
)
###
# Compiler Family Compatibility
#
set ( ModuleCompatibility
arm
)

View file

@ -1,23 +1,18 @@
/* Copyright (C) 2011-2013 by Joseph Makuch (jmakuch+f@gmail.com)
* Additions by Jacob Alexander (2013-2014) (haata@kiibohd.com)
/* Copyright (C) 2011-2013 by Joseph Makuch
* Additions by Jacob Alexander (2013-2014)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* This library 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
* Lesser General Public License for more details.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
// ----- Includes -----

View file

@ -1,22 +1,17 @@
/* Copyright (C) 2013-2015 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* This library 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
* Lesser General Public License for more details.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

View file

@ -1,75 +0,0 @@
Name = ISSILedCapabilities;
Version = 0.2;
Author = "HaaTa (Jacob Alexander) 2015";
KLL = 0.3c;
# Modified Date
Date = 2015-10-09;
# Basic ISSI Capabilities
# Modes
# 0: Decrease single led brightness
# 1: Increase single led brightness
# 2: Set single led brightness
# 3: Decrease brightness of all leds
# 4: Increase brightness of all leds
# 5: Set brightness of all leds
# Amount -> 0 -> 255
# Index:
# Depends on keyboard. At least from from 0 -> 143 (single chip).
# Remember, it may be possible that all leds on a single chip are connected.
# So it may be possible that you may have index gaps.
# i.e. 23 then 144
ledControl => LED_control_capability( mode : 1, amount : 1, index : 2 );
# Defines available to the ISSILed sub-module
# LED Default Enable Mask
#
# By default, all LEDs are enabled
# However, this may cause issuse with some led matrices, so it is recommended to disable unused positions
# Each LED is represented by a single bit
# See (http://www.issi.com/WW/pdf/31FL3731C.pdf) for details
ISSILedMask1 => ISSILedMask1_define;
ISSILedMask1 = "
0xFF, 0xFF, /* C1-1 -> C1-16 */
0xFF, 0xFF, /* C2-1 -> C2-16 */
0xFF, 0xFF, /* C3-1 -> C3-16 */
0xFF, 0xFF, /* C4-1 -> C4-16 */
0xFF, 0xFF, /* C5-1 -> C5-16 */
0xFF, 0xFF, /* C6-1 -> C6-16 */
0xFF, 0xFF, /* C7-1 -> C7-16 */
0xFF, 0xFF, /* C8-1 -> C8-16 */
0xFF, 0xFF, /* C9-1 -> C9-16 */
";
# LED Default Brightness
#
# By default, all LEDs are set to max brightness
# Each LED channel supports 256 levels (8-bit control)
ISSILedBrightness1 => ISSILedBrightness1_define;
ISSILedBrightness1 = "
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C1-1 -> C1-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C2-1 -> C2-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C3-1 -> C3-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C4-1 -> C4-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C5-1 -> C5-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C6-1 -> C6-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C7-1 -> C7-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C8-1 -> C8-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* C9-1 -> C9-16 */
";
# Example starting from 0 brightness to 0x8F
ISSILedBrightness_example = "
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* C1-1 -> C1-16 */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* C2-1 -> C2-16 */
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, /* C3-1 -> C3-16 */
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, /* C4-1 -> C4-16 */
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, /* C5-1 -> C5-16 */
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, /* C6-1 -> C6-16 */
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, /* C7-1 -> C7-16 */
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, /* C8-1 -> C8-16 */
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, /* C9-1 -> C9-16 */
";

View file

@ -1,37 +0,0 @@
#!/usr/bin/env bash
# ISSILed
# Virtual Serial Port API Example
# Jacob Alexander 2015
if [ $# -eq 0 ]; then
echo "You must specify your virtual serialport. (/dev/ttyACM0 on linux, /dev/cu.usbmodemXXXX on OSX)"
echo " ex: $0 /dev/ttyACM0"
exit 1
fi
# XXX Set this to match your virtual serialport
# TODO Show examples for Cygwin/Windows
# For Mac OSX it will be something like /dev/cu.usbmodem1413 (number may differ)
SERIALPORT=$1
# NOTE: Make sure you don't write too quickly to the serial port, it can get overwhelmed by a modern computer
# Generally this just means commands will get ignored
# I'm using 100 ms sleeps here, but much smaller are probably sufficient
# Clear out cli buffer
printf "\r" > $SERIALPORT
# Write to ISSI Page
# Arguments
# - page
# - starting address
# - data (usually brightness) (8 bits)
#
# For brightness control, set the starting address to 0x24
# By default only page 0x00 is used
# There are 8 pages of memory (these can be cycled through for animiations)
# 144 led channels
# Page 0x0A is used for configuration
# See the datasheet for full details http://www.issi.com/WW/pdf/31FL3731C.pdf
sleep 0.1
printf "ledWPage 0x00 0x24 0x10 0x20 0x30 0x40 0x50\r" > $SERIALPORT

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
/* Copyright (C) 2014-2015 by Jacob Alexander
*
* This file is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,14 +21,9 @@
// Project Includes
#include <cli.h>
#include <kll_defs.h>
#include <led.h>
#include <print.h>
// Interconnect module if compiled in
#if defined(ConnectEnabled_define)
#include <connect_scan.h>
#endif
#include <led_conf.h> // Located with scan_loop.c
// Local Includes
#include "led_scan.h"
@ -42,10 +37,6 @@
#define LED_BufferLength 144
// TODO Needs to be defined per keyboard
#define LED_TotalChannels 144
// ----- Structs -----
@ -58,8 +49,6 @@ typedef struct I2C_Buffer {
} I2C_Buffer;
typedef struct LED_Buffer {
uint8_t i2c_addr;
uint8_t reg_addr;
uint8_t buffer[LED_BufferLength];
} LED_Buffer;
@ -68,14 +57,12 @@ typedef struct LED_Buffer {
// ----- Function Declarations -----
// CLI Functions
void cliFunc_i2cRecv ( char* args );
void cliFunc_i2cSend ( char* args );
void cliFunc_ledCtrl ( char* args );
void cliFunc_ledRPage( char* args );
void cliFunc_i2cRecv( char* args );
void cliFunc_i2cSend( char* args );
void cliFunc_ledPage( char* args );
void cliFunc_ledStart( char* args );
void cliFunc_ledTest ( char* args );
void cliFunc_ledWPage( char* args );
void cliFunc_ledZero ( char* args );
void cliFunc_ledTest( char* args );
void cliFunc_ledZero( char* args );
uint8_t I2C_TxBufferPop();
void I2C_BufferPush( uint8_t byte, I2C_Buffer *buffer );
@ -89,21 +76,17 @@ uint8_t I2C_Send( uint8_t *data, uint8_t sendLen, uint8_t recvLen );
// Scan Module command dictionary
CLIDict_Entry( i2cRecv, "Send I2C sequence of bytes and expect a reply of 1 byte on the last sequence." NL "\t\tUse |'s to split sequences with a stop." );
CLIDict_Entry( i2cSend, "Send I2C sequence of bytes. Use |'s to split sequences with a stop." );
CLIDict_Entry( ledCtrl, "Basic LED control. Args: <mode> <amount> [<index>]" );
CLIDict_Entry( ledRPage, "Read the given register page." );
CLIDict_Entry( ledPage, "Read the given register page." );
CLIDict_Entry( ledStart, "Disable software shutdown." );
CLIDict_Entry( ledTest, "Test out the led pages." );
CLIDict_Entry( ledWPage, "Write to given register page starting at address. i.e. 0x2 0x24 0xF0 0x12" );
CLIDict_Entry( ledZero, "Zero out LED register pages (non-configuration)." );
CLIDict_Def( ledCLIDict, "ISSI LED Module Commands" ) = {
CLIDict_Item( i2cRecv ),
CLIDict_Item( i2cSend ),
CLIDict_Item( ledCtrl ),
CLIDict_Item( ledRPage ),
CLIDict_Item( ledPage ),
CLIDict_Item( ledStart ),
CLIDict_Item( ledTest ),
CLIDict_Item( ledWPage ),
CLIDict_Item( ledZero ),
{ 0, 0, 0 } // Null entry for dictionary end
};
@ -120,18 +103,92 @@ volatile I2C_Buffer I2C_RxBuffer = { 0, 0, 0, I2C_RxBufferLength, (uint8_t*)I2C_
LED_Buffer LED_pageBuffer;
/*
// A bit mask determining which LEDs are enabled in the ISSI chip
const uint8_t LED_ledEnableMask1[] = {
0xE8, // I2C address
0x00, // Starting register address
ISSILedMask1_define
// All channel mask example
// 0x00 -> 0x11
const uint8_t LED_ledEnableMask[] = {
0xE8, // I2C address
0x00, // Starting register address
0xFF, 0xFF, // C1-1 -> C1-16
0xFF, 0xFF, // C2-1 -> C2-16
0xFF, 0xFF, // C3-1 -> C3-16
0xFF, 0xFF, // C4-1 -> C4-16
0xFF, 0xFF, // C5-1 -> C5-16
0xFF, 0xFF, // C6-1 -> C6-16
0xFF, 0xFF, // C7-1 -> C7-16
0xFF, 0xFF, // C8-1 -> C8-16
0xFF, 0xFF, // C9-1 -> C9-16
};
*/
// Default LED brightness
const uint8_t LED_defaultBrightness1[] = {
0xE8, // I2C address
0x24, // Starting register address
ISSILedBrightness1_define
/*
// A bit mask determining which LEDs are enabled in the ISSI chip
// Infinity ErgoDox full mask
// 0x00 -> 0x11
const uint8_t LED_ledEnableMask[] = {
0xE8, // I2C address
0x00, // Starting register address
0xFC, 0xFC, // C1-1 -> C1-16
0xFB, 0xFB, // C2-1 -> C2-16
0xFF, 0xFF, // C3-1 -> C3-16
0xFE, 0xFE, // C4-1 -> C4-16
0x7F, 0x7F, // C5-1 -> C5-16
0xFF, 0xFF, // C6-1 -> C6-16
0xCF, 0xCF, // C7-1 -> C7-16
0xC7, 0xC7, // C8-1 -> C8-16
0x43, 0x43, // C9-1 -> C9-16
};
*/
/*
const uint8_t LED_ledEnableMask[] = {
0xE8, // I2C address
0x00, // Starting register address
0x00, 0x00, // C1-1 -> C1-16
//0xEC, 0xEC, // C1-1 -> C1-16
0x00, 0x00, // C2-1 -> C2-16
0x00, 0x00, // C3-1 -> C3-16
0x00, 0x00, // C4-1 -> C4-16
0x00, 0x00, // C5-1 -> C5-16
0x00, 0x00, // C6-1 -> C6-16
0x08, 0x08, // C7-1 -> C7-16
0x00, 0x00, // C8-1 -> C8-16
0x00, 0x00, // C9-1 -> C9-16
};
*/
/*
// XXX Pre-fill example of buffers
const uint8_t examplePage[] = {
0xE8, // I2C address
0x24, // Starting register address
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C1-1 -> C1-16
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C2-1 -> C2-16
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C3-1 -> C3-16
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C4-1 -> C4-16
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C5-1 -> C5-16
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C6-1 -> C6-16
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C7-1 -> C7-16
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C8-1 -> C8-16
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // C9-1 -> C9-16
};
*/
// XXX Pre-fill example of buffers
const uint8_t examplePage[] = {
0xE8, // I2C address
0x24, // Starting register address
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // C1-1 -> C1-16
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, // C2-1 -> C2-16
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // C3-1 -> C3-16
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // C4-1 -> C4-16
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // C5-1 -> C5-16
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, // C6-1 -> C6-16
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // C7-1 -> C7-16
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, // C8-1 -> C8-16
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, // C9-1 -> C9-16
};
@ -192,9 +249,7 @@ void i2c0_isr()
}
else
{
dbug_msg("Attempting to read byte - ");
printHex( I2C_RxBuffer.sequencePos );
print( NL );
dbug_print("Attempting to read byte");
I2C0_C1 = I2C_RxBuffer.sequencePos == 1
? I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TXAK // Single byte read
: I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST; // Multi-byte read
@ -325,6 +380,34 @@ void LED_sendPage( uint8_t *buffer, uint8_t len, uint8_t page )
}
void LED_readPage( uint8_t len, uint8_t page )
{
// Page Setup
uint8_t pageSetup[] = { 0xE8, 0xFD, page };
// Setup page
while ( I2C_Send( pageSetup, sizeof( pageSetup ), 0 ) == 0 )
delay(1);
// Register Setup
uint8_t regSetup[] = { 0xE8, 0x00 };
// Setup starting register
while ( I2C_Send( regSetup, sizeof( regSetup ), 0 ) == 0 )
delay(1);
// Register Read Command
uint8_t regReadCmd[] = { 0xE9 };
// Read each register in the page
for ( uint8_t reg = 0; reg < len; reg++ )
{
// Request register data
while ( I2C_Send( regReadCmd, sizeof( regReadCmd ), 0 ) == 0 )
delay(1);
}
}
void LED_writeReg( uint8_t reg, uint8_t val, uint8_t page )
{
// Page Setup
@ -341,44 +424,6 @@ void LED_writeReg( uint8_t reg, uint8_t val, uint8_t page )
delay(1);
}
void LED_readPage( uint8_t len, uint8_t page )
{
// Software shutdown must be enabled to read registers
LED_writeReg( 0x0A, 0x00, 0x0B );
// Page Setup
uint8_t pageSetup[] = { 0xE8, 0xFD, page };
// Setup page
while ( I2C_Send( pageSetup, sizeof( pageSetup ), 0 ) == 0 )
delay(1);
// Register Setup
uint8_t regSetup[] = { 0xE8, 0x00 };
// Read each register in the page
for ( uint8_t reg = 0; reg < len; reg++ )
{
// Update register to read
regSetup[1] = reg;
// Configure register
while ( I2C_Send( regSetup, sizeof( regSetup ), 0 ) == 0 )
delay(1);
// Register Read Command
uint8_t regReadCmd[] = { 0xE9 };
// Request single register byte
while ( I2C_Send( regReadCmd, sizeof( regReadCmd ), 1 ) == 0 )
delay(1);
dbug_print("NEXT");
}
// Disable software shutdown
LED_writeReg( 0x0A, 0x01, 0x0B );
}
// Setup
inline void LED_setup()
{
@ -401,19 +446,10 @@ inline void LED_setup()
LED_zeroPages( 0x00, 8, 0x00, 0xB4 ); // LED Registers
// Enable LEDs based upon mask
LED_sendPage( (uint8_t*)LED_ledEnableMask1, sizeof( LED_ledEnableMask1 ), 0 );
LED_sendPage( (uint8_t*)LED_ledEnableMask, sizeof( LED_ledEnableMask ), 0 );
// Set default brightness
LED_sendPage( (uint8_t*)LED_defaultBrightness1, sizeof( LED_defaultBrightness1 ), 0 );
// Do not disable software shutdown of ISSI chip unless current is high enough
// Require at least 150 mA
// May be enabled/disabled at a later time
if ( Output_current_available() >= 150 )
{
// Disable Software shutdown of ISSI chip
LED_writeReg( 0x0A, 0x01, 0x0B );
}
// Disable Software shutdown of ISSI chip
LED_writeReg( 0x0A, 0x01, 0x0B );
}
@ -639,219 +675,20 @@ uint8_t I2C_Send( uint8_t *data, uint8_t sendLen, uint8_t recvLen )
// LED State processing loop
unsigned int LED_currentEvent = 0;
inline uint8_t LED_scan()
{
// Check for current change event
if ( LED_currentEvent )
{
// TODO dim LEDs in low power mode instead of shutting off
if ( LED_currentEvent < 150 )
{
// Enable Software shutdown of ISSI chip
LED_writeReg( 0x0A, 0x00, 0x0B );
}
else
{
// Disable Software shutdown of ISSI chip
LED_writeReg( 0x0A, 0x01, 0x0B );
}
LED_currentEvent = 0;
}
// I2C Busy
// S & I2C_S_BUSY
//I2C_S_BUSY
return 0;
}
// Called by parent Scan Module whenver the available current has changed
// current - mA
void LED_currentChange( unsigned int current )
{
// Delay action till next LED scan loop (as this callback sometimes occurs during interrupt requests)
LED_currentEvent = current;
}
// ----- Capabilities -----
// Basic LED Control Capability
typedef enum LedControlMode {
// Single LED Modes
LedControlMode_brightness_decrease,
LedControlMode_brightness_increase,
LedControlMode_brightness_set,
// Set all LEDs (index argument not required)
LedControlMode_brightness_decrease_all,
LedControlMode_brightness_increase_all,
LedControlMode_brightness_set_all,
} LedControlMode;
typedef struct LedControl {
LedControlMode mode; // XXX Make sure to adjust the .kll capability if this variable is larger than 8 bits
uint8_t amount;
uint16_t index;
} LedControl;
void LED_control( LedControl *control )
{
// Only send if we've completed all other transactions
/*
if ( I2C_TxBuffer.sequencePos > 0 )
return;
*/
// Configure based upon the given mode
// TODO Perhaps do gamma adjustment?
switch ( control->mode )
{
case LedControlMode_brightness_decrease:
// Don't worry about rolling over, the cycle is quick
LED_pageBuffer.buffer[ control->index ] -= control->amount;
break;
case LedControlMode_brightness_increase:
// Don't worry about rolling over, the cycle is quick
LED_pageBuffer.buffer[ control->index ] += control->amount;
break;
case LedControlMode_brightness_set:
LED_pageBuffer.buffer[ control->index ] = control->amount;
break;
case LedControlMode_brightness_decrease_all:
for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ )
{
// Don't worry about rolling over, the cycle is quick
LED_pageBuffer.buffer[ channel ] -= control->amount;
}
break;
case LedControlMode_brightness_increase_all:
for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ )
{
// Don't worry about rolling over, the cycle is quick
LED_pageBuffer.buffer[ channel ] += control->amount;
}
break;
case LedControlMode_brightness_set_all:
for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ )
{
LED_pageBuffer.buffer[ channel ] = control->amount;
}
break;
}
// Sync LED buffer with ISSI chip buffer
// TODO Support multiple frames
LED_pageBuffer.i2c_addr = 0xE8; // Chip 1
LED_pageBuffer.reg_addr = 0x24; // Brightness section
LED_sendPage( (uint8_t*)&LED_pageBuffer, sizeof( LED_Buffer ), 0 );
}
uint8_t LED_control_timer = 0;
void LED_control_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("LED_control_capability(mode,amount,index)");
return;
}
// Only use capability on press
// TODO Analog
if ( stateType == 0x00 && state == 0x03 ) // Not on release
return;
// XXX
// ISSI Chip locks up if we spam updates too quickly (might be an I2C bug on this side too -HaaTa)
// Make sure we only send an update every 30 milliseconds at most
// It may be possible to optimize speed even further, but will likely require serious time with a logic analyzer
uint8_t currentTime = (uint8_t)systick_millis_count;
int8_t compare = (int8_t)(currentTime - LED_control_timer) & 0x7F;
if ( compare < 30 )
{
return;
}
LED_control_timer = currentTime;
// Set the input structure
LedControl *control = (LedControl*)args;
// Interconnect broadcasting
#if defined(ConnectEnabled_define)
uint8_t send_packet = 0;
uint8_t ignore_node = 0;
// By default send to the *next* node, which will determine where to go next
extern uint8_t Connect_id; // connect_scan.c
uint8_t addr = Connect_id + 1;
switch ( control->mode )
{
// Calculate the led address to send
// If greater than the Total hannels
// Set address - Total channels
// Otherwise, ignore
case LedControlMode_brightness_decrease:
case LedControlMode_brightness_increase:
case LedControlMode_brightness_set:
// Ignore if led is on this node
if ( control->index < LED_TotalChannels )
break;
// Calculate new led index
control->index -= LED_TotalChannels;
ignore_node = 1;
send_packet = 1;
break;
// Broadcast to all nodes
// XXX Do not set broadcasting address
// Will send command twice
case LedControlMode_brightness_decrease_all:
case LedControlMode_brightness_increase_all:
case LedControlMode_brightness_set_all:
send_packet = 1;
break;
}
// Only send interconnect remote capability packet if necessary
if ( send_packet )
{
// generatedKeymap.h
extern const Capability CapabilitiesList[];
// Broadcast layerStackExact remote capability (0xFF is the broadcast id)
Connect_send_RemoteCapability(
addr,
LED_control_capability_index,
state,
stateType,
CapabilitiesList[ LED_control_capability_index ].argCount,
args
);
}
// If there is nothing to do on this node, ignore
if ( ignore_node )
return;
#endif
// Modify led state of this node
LED_control( control );
}
// ----- CLI Command Functions -----
// TODO Currently not working correctly
void cliFunc_i2cSend( char* args )
{
char* curArgs;
@ -948,8 +785,7 @@ void cliFunc_i2cRecv( char* args )
I2C_Send( buffer, bufferLen, 1 ); // Only 1 byte is ever read at a time with the ISSI chip
}
// TODO Currently not working correctly
void cliFunc_ledRPage( char* args )
void cliFunc_ledPage( char* args )
{
// Parse number from argument
// NOTE: Only first argument is used
@ -962,62 +798,13 @@ void cliFunc_ledRPage( char* args )
if ( arg1Ptr[0] != '\0' )
{
page = (uint8_t)numToInt( arg1Ptr );
page = (uint8_t)numToInt( arg1Ptr );
}
// No \r\n by default after the command is entered
print( NL );
LED_readPage( 0x1, page );
//LED_readPage( 0xB4, page );
}
void cliFunc_ledWPage( char* args )
{
char* curArgs;
char* arg1Ptr;
char* arg2Ptr = args;
// First process page and starting address
curArgs = arg2Ptr;
CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
// Stop processing args if no more are found
if ( *arg1Ptr == '\0' )
return;
uint8_t page[] = { 0xE8, 0xFD, numToInt( arg1Ptr ) };
curArgs = arg2Ptr;
CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
// Stop processing args if no more are found
if ( *arg1Ptr == '\0' )
return;
uint8_t data[] = { 0xE8, numToInt( arg1Ptr ), 0 };
// Set the register page
while ( I2C_Send( page, sizeof( page ), 0 ) == 0 )
delay(1);
// Process all args
for ( ;; )
{
curArgs = arg2Ptr;
CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
// Stop processing args if no more are found
if ( *arg1Ptr == '\0' )
break;
data[2] = numToInt( arg1Ptr );
// Write register location and data to I2C
while ( I2C_Send( data, sizeof( data ), 0 ) == 0 )
delay(1);
// Increment address
data[1]++;
}
LED_readPage( 0xB4, page );
}
void cliFunc_ledStart( char* args )
@ -1026,14 +813,14 @@ void cliFunc_ledStart( char* args )
LED_zeroPages( 0x0B, 1, 0x00, 0x0C ); // Control Registers
//LED_zeroPages( 0x00, 8, 0x00, 0xB4 ); // LED Registers
LED_writeReg( 0x0A, 0x01, 0x0B );
LED_sendPage( (uint8_t*)LED_ledEnableMask1, sizeof( LED_ledEnableMask1 ), 0 );
LED_sendPage( (uint8_t*)LED_ledEnableMask, sizeof( LED_ledEnableMask ), 0 );
}
void cliFunc_ledTest( char* args )
{
print( NL ); // No \r\n by default after the command is entered
LED_sendPage( (uint8_t*)LED_defaultBrightness1, sizeof( LED_defaultBrightness1 ), 0 );
LED_sendPage( (uint8_t*)examplePage, sizeof( examplePage ), 0 );
}
void cliFunc_ledZero( char* args )
@ -1042,40 +829,3 @@ void cliFunc_ledZero( char* args )
LED_zeroPages( 0x00, 8, 0x24, 0xB4 ); // Only PWMs
}
void cliFunc_ledCtrl( char* args )
{
char* curArgs;
char* arg1Ptr;
char* arg2Ptr = args;
LedControl control;
// First process mode
curArgs = arg2Ptr;
CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
// Stop processing args if no more are found
if ( *arg1Ptr == '\0' )
return;
control.mode = numToInt( arg1Ptr );
// Next process amount
curArgs = arg2Ptr;
CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
// Stop processing args if no more are found
if ( *arg1Ptr == '\0' )
return;
control.amount = numToInt( arg1Ptr );
// Finally process led index, if it exists
// Default to 0
curArgs = arg2Ptr;
CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
control.index = *arg1Ptr == '\0' ? 0 : numToInt( arg1Ptr );
// Process request
LED_control( &control );
}

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
/* Copyright (C) 2014-2015 by Jacob Alexander
*
* This file is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -28,5 +28,3 @@
void LED_setup();
uint8_t LED_scan();
void LED_currentChange( unsigned int current );

View file

@ -1,97 +0,0 @@
Name = KType;
Version = 0.1;
Author = "HaaTa (Jacob Alexander) 2015";
KLL = 0.3c;
# Modified Date
Date = 2015-09-29;
S0x00 : U"Esc";
S0x01 : U"F1";
S0x02 : U"F2";
S0x03 : U"F3";
S0x04 : U"F4";
S0x05 : U"F5";
S0x06 : U"F6";
S0x07 : U"F7";
S0x08 : U"F8";
S0x09 : U"F9";
S0x0A : U"F10";
S0x0B : U"F11";
S0x0C : U"F12";
S0x0D : U"PrintScreen";
S0x0E : U"ScrollLock";
S0x0F : U"Pause";
S0x10 : U"Backtick";
S0x11 : U"1";
S0x12 : U"2";
S0x13 : U"3";
S0x14 : U"4";
S0x15 : U"5";
S0x16 : U"6";
S0x17 : U"7";
S0x18 : U"8";
S0x19 : U"9";
S0x1A : U"0";
S0x1B : U"Minus";
S0x1C : U"Equals";
S0x1D : U"Backspace";
S0x1E : U"Insert";
S0x1F : U"Home";
S0x20 : U"PageUp";
S0x21 : U"Tab";
S0x22 : U"Q";
S0x23 : U"W";
S0x24 : U"E";
S0x25 : U"R";
S0x26 : U"T";
S0x27 : U"Y";
S0x28 : U"U";
S0x29 : U"I";
S0x2A : U"O";
S0x2B : U"P";
S0x2C : U"LBrace";
S0x2D : U"RBrace";
S0x2E : U"Backslash";
S0x2F : U"Delete";
S0x30 : U"End";
S0x31 : U"PageDown";
S0x32 : U"CapsLock";
S0x33 : U"A";
S0x34 : U"S";
S0x35 : U"D";
S0x36 : U"F";
S0x37 : U"G";
S0x38 : U"H";
S0x39 : U"J";
S0x3A : U"K";
S0x3B : U"L";
S0x3C : U"Semicolon";
S0x3D : U"Quote";
S0x3E : U"Enter";
S0x3F : U"LShift";
S0x40 : U"Z";
S0x41 : U"X";
S0x42 : U"C";
S0x43 : U"V";
S0x44 : U"B";
S0x45 : U"N";
S0x46 : U"M";
S0x47 : U"Comma";
S0x48 : U"Period";
S0x49 : U"Slash";
S0x4A : U"RShift";
S0x4B : U"Up";
S0x4C : U"LCtrl";
S0x4D : U"LGui";
S0x4E : U"LAlt";
S0x4F : U"Space";
S0x50 : U"RAlt";
S0x51 : U"RGui";
S0x52 : U"Menu";
S0x53 : U"RCtrl";
S0x54 : U"Left";
S0x55 : U"Down";
S0x56 : U"Right";

View file

@ -1,57 +0,0 @@
/* Copyright (C) 2014-2015 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
// ----- Includes -----
// Project Includes
#include <matrix_setup.h>
// ----- Matrix Definition -----
// Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31
// Not all chips have access to all of these pins (most don't have 160 pins :P)
//
// NOTE:
// Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down
// Checking this is completely on the ownness of the user
// MDErgo1
//
// Column (Strobe) - 9 Total
// PTB2,3,18,19
// PTC0,9..11
// PTD0
//
// Rows (Sense) - 5 Total
// PTD1,4..7
// Define Rows (Sense) and Columns (Strobes)
// TODO
GPIO_Pin Matrix_cols[] = { gpio(B,2), gpio(B,3), gpio(B,18), gpio(B,19), gpio(C,0), gpio(C,8), gpio(C,9), gpio(C,10), gpio(C,11) };
GPIO_Pin Matrix_rows[] = { gpio(D,0), gpio(D,1), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7), gpio(C,1), gpio(C,2) };
// Define type of scan matrix
Config Matrix_type = Config_Pulldown;

View file

@ -1,110 +0,0 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// ----- Includes -----
// Compiler Includes
#include <Lib/ScanLib.h>
// Project Includes
#include <cli.h>
#include <connect_scan.h>
#include <led.h>
#include <led_scan.h>
#include <print.h>
#include <matrix_scan.h>
#include <macro.h>
#include <output_com.h>
// Local Includes
#include "scan_loop.h"
// ----- Function Declarations -----
// ----- Variables -----
// Number of scans since the last USB send
uint16_t Scan_scanCount = 0;
// ----- Functions -----
// Setup
inline void Scan_setup()
{
// Setup UART Connect, if Output_Available, this is the master node
Connect_setup( Output_Available );
// Setup GPIO pins for matrix scanning
Matrix_setup();
// Setup ISSI chip to control the leds
LED_setup();
// Reset scan count
Scan_scanCount = 0;
}
// Main Detection Loop
inline uint8_t Scan_loop()
{
// Scan Matrix
Matrix_scan( Scan_scanCount++ );
// Process any interconnect commands
Connect_scan();
// Process any LED events
LED_scan();
return 0;
}
// Signal from Macro Module that all keys have been processed (that it knows about)
inline void Scan_finishedWithMacro( uint8_t sentKeys )
{
}
// Signal from Output Module that all keys have been processed (that it knows about)
inline void Scan_finishedWithOutput( uint8_t sentKeys )
{
// Reset scan loop indicator (resets each key debounce state)
// TODO should this occur after USB send or Macro processing?
Scan_scanCount = 0;
}
// Signal from the Output Module that the available current has changed
// current - mA
void Scan_currentChange( unsigned int current )
{
// Indicate to all submodules current change
Connect_currentChange( current );
Matrix_currentChange( current );
LED_currentChange( current );
}

View file

@ -1,42 +0,0 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
// ----- Includes -----
// Compiler Includes
#include <stdint.h>
// ----- Functions -----
// Functions to be called by main.c
void Scan_setup();
uint8_t Scan_loop();
// Call-backs
void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module
void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module
void Scan_currentChange( unsigned int current ); // Called by Output Module

View file

@ -1,32 +0,0 @@
###| CMake Kiibohd Controller Scan Module |###
#
# Written by Jacob Alexander in 2015 for the Kiibohd Controller
#
# Released into the Public Domain
#
###
###
# Required Sub-modules
#
AddModule ( Scan ISSILed )
AddModule ( Scan MatrixARM )
AddModule ( Scan UARTConnect )
###
# Module C files
#
set ( Module_SRCS
scan_loop.c
)
###
# Compiler Family Compatibility
#
set ( ModuleCompatibility
arm
)

View file

@ -1,134 +0,0 @@
Name = MD1.1;
Version = 0.3d;
Author = "HaaTa (Jacob Alexander) 2014-2016";
KLL = 0.3c;
# Modified Date
Date = 2016-02-06;
S0x00 : U"Esc";
S0x01 : U"1";
S0x02 : U"2";
S0x03 : U"3";
S0x04 : U"4";
S0x05 : U"5";
S0x06 : U"6";
S0x07 : U"7";
S0x08 : U"8";
S0x09 : U"9";
S0x0A : U"0";
S0x0B : U"Minus";
S0x0C : U"Equal";
S0x0D : U"Backslash";
S0x0E : U"Backtick";
S0x0F : U"Tab";
S0x10 : U"Q";
S0x11 : U"W";
S0x12 : U"E";
S0x13 : U"R";
S0x14 : U"T";
S0x15 : U"Y";
S0x16 : U"U";
S0x17 : U"I";
S0x18 : U"O";
S0x19 : U"P";
S0x1A : U"LBrace";
S0x1B : U"RBrace";
S0x1C : U"Backspace";
S0x1D : U"Ctrl";
S0x1E : U"A";
S0x1F : U"S";
S0x20 : U"D";
S0x21 : U"F";
S0x22 : U"G";
S0x23 : U"H";
S0x24 : U"J";
S0x25 : U"K";
S0x26 : U"L";
S0x27 : U"Semicolon";
S0x28 : U"Quote";
S0x29 : U"Enter";
S0x2A : U"LShift";
S0x2B : U"Z";
S0x2C : U"X";
S0x2D : U"C";
S0x2E : U"V";
S0x2F : U"B";
S0x30 : U"N";
S0x31 : U"M";
S0x32 : U"Comma";
S0x33 : U"Period";
S0x34 : U"Slash";
S0x35 : U"RShift";
S0x36 : U"Function1"; # Fun key
S0x37 : U"Function2"; # Left Blank Key
S0x38 : U"LAlt";
S0x39 : U"LGui";
S0x3A : U"Space";
S0x3B : U"RGui";
S0x3C : U"RAlt";
S0x3D : U"Function3"; # Right Blank Key 1
S0x3E : U"Function4"; # Right Blank Key 2
# Custom Action Examples
# Example capability, prints to cli
action1 => CustomAction_action1_capability(); # No arguments
# Blocks given USB Code, must be used with blockLink
# Simple example, supports only blocking a single key at a time
# Keys must be specified using numbers see Macro/PartialMap/usb_hid.h
blockHold => CustomAction_blockHold_capability( usbCode : 1 ); # Single 8-bit argument
blockKey => CustomAction_blockKey_capability( usbCode : 1 );
# Defines available to the MD1_1 Scan Module
# LED Default Enable Mask Override
#
# Each LED is represented by a single bit
# See (http://www.issi.com/WW/pdf/31FL3731C.pdf) for details
ISSILedMask1 = "
0xFF, 0x00, /* C1-1 -> C1-16 */
0xFF, 0x00, /* C2-1 -> C2-16 */
0xFF, 0x00, /* C3-1 -> C3-16 */
0xFF, 0x00, /* C4-1 -> C4-16 */
0xFF, 0x00, /* C5-1 -> C5-16 */
0xFF, 0x00, /* C6-1 -> C6-16 */
0xFF, 0x00, /* C7-1 -> C7-16 */
0x7F, 0x00, /* C8-1 -> C8-16 */
0x00, 0x00, /* C9-1 -> C9-16 */
";
# LED Brightness Override
#
# Each LED channel supports 256 levels (8-bit control)
# By default, LEDs are set to 0 brightness
#ISSILedBrightness1 = "
#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */
#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */
#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */
#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */
#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */
#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */
#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */
#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */
#0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */
#";
# Full brightness example
ISSILedBrightness1 = "
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */
";

View file

@ -1,56 +0,0 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
// ----- Includes -----
// Project Includes
#include <matrix_setup.h>
// ----- Matrix Definition -----
// Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31
// Not all chips have access to all of these pins (most don't have 160 pins :P)
//
// NOTE:
// Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down
// Checking this is completely on the ownness of the user
// MD1
//
// Columns (Strobe)
// PTB0..3,16,17
// PTC4,5
// PTD0
//
// Rows (Sense)
// PTD1..7
// Define Rows (Sense) and Columns (Strobes)
GPIO_Pin Matrix_cols[] = { gpio(C,0), gpio(C,1), gpio(C,2), gpio(C,3), gpio(C,4), gpio(C,5), gpio(C,6), gpio(C,7), gpio(D,0) };
GPIO_Pin Matrix_rows[] = { gpio(D,1), gpio(D,2), gpio(D,3), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7) };
// Define type of scan matrix
Config Matrix_type = Config_Pulldown;

View file

@ -1,93 +0,0 @@
Pin Usage
=========
mk20dx128vlf5
----
|Keys|
----
* Strobe (Columns)
TODO
* Sense (Rows)
PTD1
PTD2
PTD3
PTD4
PTD5
PTD6
PTD7
---
|I2C|
---
* IS31FL3731C
PTB0 - SCL0 (add header pin, label as SCL0)
PTB1 - SDA0 (add header pin, label as SDA0)
PTB17 - INTB Chip 1
PTB16 - SDB (tied to all Chips, hardware shutdown)
-----
|Debug|
-----
* SWD
PTA0 (Pull-down)
PTA3 (Pull-up)
* LEDs
PTA19 (LED only for PCB, not McHCK) (XTAL)
* UARTs
PTA1 - RX0
PTA2 - TX0
* Tag Connect
1 - Vdd +5
2 - PTA3 / SWD_IO
3 - Vss / Gnd
4 - PTA0 / SWD_CLK
5 - +5V
6 - PTA2 / TRACE_SWO
7 - N/C
8 - PTA1 / JTAG_TDI
9 - N/C
10 - Reset_b
------
|Unused|
------
* GPIO
PTA1 (Not broken out on PCB, available on McHCK) (Pull-up)
PTA2 (")
PTA4 (Pull-up)
PTA18 (EXTAL)
PTC0
PTC1
PTC2
PTC3
PTC6
PTC7
* Analog
ADC0_DP0
ADC0_DM0

View file

@ -1,178 +0,0 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// ----- Includes -----
// Compiler Includes
#include <Lib/ScanLib.h>
// Project Includes
#include <cli.h>
#include <led.h>
#include <led_scan.h>
#include <print.h>
#include <matrix_scan.h>
#include <macro.h>
#include <output_com.h>
// Local Includes
#include "scan_loop.h"
// ----- Function Declarations -----
// ----- Variables -----
// Number of scans since the last USB send
uint16_t Scan_scanCount = 0;
// ----- Functions -----
// Setup
inline void Scan_setup()
{
// Setup GPIO pins for matrix scanning
Matrix_setup();
// Setup ISSI chip to control the leds
LED_setup();
// Reset scan count
Scan_scanCount = 0;
}
// Main Detection Loop
inline uint8_t Scan_loop()
{
Matrix_scan( Scan_scanCount++ );
// Process any LED events
LED_scan();
return 0;
}
// Signal from Macro Module that all keys have been processed (that it knows about)
inline void Scan_finishedWithMacro( uint8_t sentKeys )
{
}
// Signal from Output Module that all keys have been processed (that it knows about)
inline void Scan_finishedWithOutput( uint8_t sentKeys )
{
// Reset scan loop indicator (resets each key debounce state)
// TODO should this occur after USB send or Macro processing?
Scan_scanCount = 0;
}
// Signal from the Output Module that the available current has changed
// current - mA
void Scan_currentChange( unsigned int current )
{
// Indicate to all submodules current change
Matrix_currentChange( current );
LED_currentChange( current );
}
// ----- Capabilities -----
// Custom capability examples
// Refer to kll.h in Macros/PartialMap for state and stateType information
void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
// XXX This is required for debug cli to give you a list of capabilities
if ( stateType == 0xFF && state == 0xFF )
{
print("CustomAction_action1_capability()");
return;
}
// Prints Action1 info message to the debug cli
info_print("Action1");
}
uint8_t CustomAction_blockHold_storage = 0;
void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("CustomAction_blockHold_capability(usbCode)");
return;
}
// Retrieve 8-bit argument
uint8_t key = args[0];
// We only care about normal keys
if ( stateType == 0x00 )
{
// Block given key if we're in the "Press" or "Hold" state
if ( ( state == 0x01 || state == 0x02 )
&& CustomAction_blockHold_storage == 0 )
{
CustomAction_blockHold_storage = key;
info_msg("Blocking Key: ");
printHex( key );
print( NL );
}
// Release if in the "Off" or "Release" state and we're blocking
else if ( ( state == 0x00 || state == 0x03 )
&& key == CustomAction_blockHold_storage )
{
info_msg("Unblocking Key: ");
printHex( CustomAction_blockHold_storage );
print( NL );
CustomAction_blockHold_storage = 0;
}
}
}
void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("CustomAction_blockKey_capability(usbCode)");
return;
}
// Retrieve 8-bit argument
uint8_t key = args[0];
// If key is not blocked, process
if ( key != CustomAction_blockHold_storage )
{
extern void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args );
Output_usbCodeSend_capability( state, stateType, &key );
}
}

View file

@ -1,50 +0,0 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
// ----- Includes -----
// Compiler Includes
#include <stdint.h>
// ----- Functions -----
// Functions to be called by main.c
void Scan_setup( void );
uint8_t Scan_loop( void );
// Call-backs
void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module
void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module
void Scan_currentChange( unsigned int current ); // Called by Output Module
// ----- Capabilities -----
// Example capabilities
void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args );

View file

@ -1,33 +0,0 @@
###| CMake Kiibohd Controller Scan Module |###
#
# Written by Jacob Alexander in 2014,2016 for the Kiibohd Controller
#
# Released into the Public Domain
#
###
###
# Required Submodules
#
AddModule ( Scan ISSILed )
AddModule ( Scan MatrixARM )
###
# Module C files
#
set ( Module_SRCS
scan_loop.c
)
###
# Compiler Family Compatibility
#
set ( ModuleCompatibility
arm
)

View file

@ -1,10 +1,10 @@
Name = MD1;
Version = 0.3;
Author = "HaaTa (Jacob Alexander) 2014-2015";
KLL = 0.3c;
Version = 0.2;
Author = "HaaTa (Jacob Alexander) 2014";
KLL = 0.3;
# Modified Date
Date = 2015-08-16;
Date = 2014-09-14;
S0x00 : U"Esc";
@ -71,15 +71,3 @@ S0x3C : U"RAlt";
S0x3D : U"Function3"; # Right Blank Key 1
S0x3E : U"Function4"; # Right Blank Key 2
# Custom Action Examples
# Example capability, prints to cli
action1 => CustomAction_action1_capability(); # No arguments
# Blocks given USB Code, must be used with blockLink
# Simple example, supports only blocking a single key at a time
# Keys must be specified using numbers see Macro/PartialMap/usb_hid.h
blockHold => CustomAction_blockHold_capability( usbCode : 1 ); # Single 8-bit argument
blockKey => CustomAction_blockKey_capability( usbCode : 1 );

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
/* Copyright (C) 2014 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -98,93 +98,6 @@ inline void Scan_finishedWithOutput( uint8_t sentKeys )
}
// ----- Capabilities -----
// Custom capability examples
// Refer to kll.h in Macros/PartialMap for state and stateType information
void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
// XXX This is required for debug cli to give you a list of capabilities
if ( stateType == 0xFF && state == 0xFF )
{
print("CustomAction_action1_capability()");
return;
}
// Prints Action1 info message to the debug cli
info_print("Action1");
}
uint8_t CustomAction_blockHold_storage = 0;
void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("CustomAction_blockHold_capability(usbCode)");
return;
}
// Retrieve 8-bit argument
uint8_t key = args[0];
// We only care about normal keys
if ( stateType == 0x00 )
{
// Block given key if we're in the "Press" or "Hold" state
if ( ( state == 0x01 || state == 0x02 )
&& CustomAction_blockHold_storage == 0 )
{
CustomAction_blockHold_storage = key;
info_msg("Blocking Key: ");
printHex( key );
print( NL );
}
// Release if in the "Off" or "Release" state and we're blocking
else if ( ( state == 0x00 || state == 0x03 )
&& key == CustomAction_blockHold_storage )
{
info_msg("Unblocking Key: ");
printHex( CustomAction_blockHold_storage );
print( NL );
CustomAction_blockHold_storage = 0;
}
}
}
void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("CustomAction_blockKey_capability(usbCode)");
return;
}
// Retrieve 8-bit argument
uint8_t key = args[0];
// If key is not blocked, process
if ( key != CustomAction_blockHold_storage )
{
extern void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args );
Output_usbCodeSend_capability( state, stateType, &key );
}
}
// Signal from the Output Module that the available current has changed
// current - mA
void Scan_currentChange( unsigned int current )
{
// Indicate to all submodules current change
Matrix_currentChange( current );
}
// ----- CLI Command Functions -----
// XXX Just an example command showing how to parse arguments (more complex than generally needed)

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
/* Copyright (C) 2014-2015 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -38,13 +38,3 @@ uint8_t Scan_loop( void );
void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module
void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module
void Scan_currentChange( unsigned int current ); // Called by Output Module
// ----- Capabilities -----
// Example capabilities
void CustomAction_action1_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void CustomAction_blockHold_capability( uint8_t state, uint8_t stateType, uint8_t *args );
void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t *args );

View file

@ -1,83 +0,0 @@
Name = MDErgo1;
Version = 0.2;
Author = "HaaTa (Jacob Alexander) 2014-2015";
KLL = 0.3c;
# Modified Date
Date = 2015-08-15;
########
# NOTE #
########
# Default ScanCode mappings are in rightHand.kll and leftHand.kll
# To change which node you are refering to, set the ConnectId variable
# i.e.
# ConnectId = 0;
# S0x02 : U"A"; # Sets scan code 0x02 on keyboard connected to USB
# ConnectId = 1;
# S0x02 : U"B"; # Sets scan code 0x02 on the first slave node
#
# ConnectId may be set in the previously parsed kll file
# In general you shouldn't have to worry about setting ConnectId unless you want a single configuration file
#
# Defines available to the MDErgo1 Scan Module
#
# LED Default Enable Mask Override
#
# Each LED is represented by a single bit
# See (http://www.issi.com/WW/pdf/31FL3731C.pdf) for details
ISSILedMask1 = "
0xFF, 0x00, /* C1-1 -> C1-16 */
0xFF, 0x00, /* C2-1 -> C2-16 */
0xFF, 0x00, /* C3-1 -> C3-16 */
0xFF, 0x00, /* C4-1 -> C4-16 */
0x3F, 0x00, /* C5-1 -> C5-16 */
0x00, 0x00, /* C6-1 -> C6-16 */
0x00, 0x00, /* C7-1 -> C7-16 */
0x00, 0x00, /* C8-1 -> C8-16 */
0x00, 0x00, /* C9-1 -> C9-16 */
";
# LED Brightness Override
#
# Each LED channel supports 256 levels (8-bit control)
ISSILedBrightness1 = "
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C1-1 -> C1-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C2-1 -> C2-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C3-1 -> C3-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C4-1 -> C4-16 */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C5-1 -> C5-16 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C6-1 -> C6-16 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C7-1 -> C7-16 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C8-1 -> C8-16 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C9-1 -> C9-16 */
";
# LCD Backlight Channel Brightness Override
# There are 3 channels, RGB
# In order to get other colors you must mix the 3 colors
# Each channel is a 16-bit register (65536 levels)
# Technically, this means, the backlight is a 48-bit RGB pixel
# In practice, it may be difficult to get color consistency at times if too bright or too dim
#
# Defaults to 6% brightness, white
STLcdBacklightRed = 0x0FFF;
STLcdBacklightGreen = 0x0FFF;
STLcdBacklightBlue = 0x0FFF;
# LCD Image Override
#
# The easiest way to generate this data is using the bitmap2Struct.py script in the STLcd folder
# It will output the necessary uint8_t array to set here
#
STLcdDefaultImage = "
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
";

View file

@ -1,74 +0,0 @@
/* Copyright (C) 2015 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
// ----- Variables -----
// A bit mask determining which LEDs are enabled in the ISSI chip
// Infinity ErgoDox full mask
// 0x00 -> 0x11
/*
const uint8_t LED_ledEnableMask[] = {
0xE8, // I2C address
0x00, // Starting register address
0x37, 0x37, // C1-1 -> C1-16
0xBF, 0xBF, // C2-1 -> C2-16
0xFF, 0xFF, // C3-1 -> C3-16
0xEF, 0xEF, // C4-1 -> C4-16
0xF7, 0xF7, // C5-1 -> C5-16
0xFF, 0xFF, // C6-1 -> C6-16
0xF3, 0xF3, // C7-1 -> C7-16
0x6C, 0x6C, // C8-1 -> C8-16
0x24, 0x24, // C9-1 -> C9-16
};
*/
/*
const uint8_t LED_ledEnableMask[] = {
0xE8, // I2C address
0x00, // Starting register address
0x00, 0x00, // C1-1 -> C1-16
//0xEC, 0xEC, // C1-1 -> C1-16
//0xFD, 0xFD, // C2-1 -> C2-16
0x00, 0x00, // C3-1 -> C3-16
0x00, 0x00, // C4-1 -> C4-16
0x00, 0x00, // C5-1 -> C5-16
0x00, 0x00, // C6-1 -> C6-16
0x00, 0x00, // C7-1 -> C7-16
0x00, 0x00, // C8-1 -> C8-16
0x00, 0x00, // C9-1 -> C9-16
};
*/
const uint8_t LED_ledEnableMask[] = {
0xE8, // I2C address
0x00, // Starting register address
0xFF, 0xFF, // C1-1 -> C1-16
0xFF, 0xFF, // C2-1 -> C2-16
0xFF, 0xFF, // C3-1 -> C3-16
0xFF, 0xFF, // C4-1 -> C4-16
0xFF, 0xFF, // C5-1 -> C5-16
0xFF, 0xFF, // C6-1 -> C6-16
0xFF, 0xFF, // C7-1 -> C7-16
0xFF, 0xFF, // C8-1 -> C8-16
0xFF, 0xFF, // C9-1 -> C9-16
};

View file

@ -1,61 +0,0 @@
Name = MDErgo1 Left Hand;
Version = 0.1;
Author = "HaaTa (Jacob Alexander) 2015";
KLL = 0.3c;
# Modified Date
Date = 2015-08-06;
# Top Row
S0x02 : U"Esc";
S0x03 : U"5";
S0x04 : U"4";
S0x05 : U"3";
S0x06 : U"2";
S0x07 : U"1";
S0x08 : U"Equals";
# Top-Middle Row
S0x0B : U"Function1";
S0x0C : U"T";
S0x0D : U"R";
S0x0E : U"E";
S0x0F : U"W";
S0x10 : U"Q";
S0x11 : U"Backslash";
# Middle Row
S0x15 : U"G";
S0x16 : U"F";
S0x17 : U"D";
S0x18 : U"S";
S0x19 : U"A";
S0x1A : U"Tab";
# Top Thumb Cluster
S0x1B : U"LAlt";
S0x1C : U"LCtrl";
# Bottom-Middle Row
S0x1D : U"Function2";
S0x1E : U"B";
S0x1F : U"V";
S0x20 : U"C";
S0x21 : U"X";
S0x22 : U"Z";
S0x23 : U"Left Shift";
# Bottom Thumb Cluster
S0x24 : U"Home";
S0x25 : U"End";
S0x26 : U"Delete";
S0x27 : U"Backspace";
# Bottom Row
S0x28 : U"Function5";
S0x29 : U"Function4";
S0x2A : U"Function3";
S0x2B : U"Backtick";
S0x2C : U"LGui";

View file

@ -1,117 +0,0 @@
Name = MDErgo1 Left then Right;
Version = 0.1;
Author = "HaaTa (Jacob Alexander) 2015";
KLL = 0.3c;
# Modified Date
Date = 2015-09-12;
# Top Row
S0x02 : U"Esc";
S0x03 : U"5";
S0x04 : U"4";
S0x05 : U"3";
S0x06 : U"2";
S0x07 : U"1";
S0x08 : U"Equals";
# Top-Middle Row
S0x0B : U"Function1";
S0x0C : U"T";
S0x0D : U"R";
S0x0E : U"E";
S0x0F : U"W";
S0x10 : U"Q";
S0x11 : U"Backslash";
# Middle Row
S0x15 : U"G";
S0x16 : U"F";
S0x17 : U"D";
S0x18 : U"S";
S0x19 : U"A";
S0x1A : U"Tab";
# Top Thumb Cluster
S0x1B : U"LAlt";
S0x1C : U"LCtrl";
# Bottom-Middle Row
S0x1D : U"Function2";
S0x1E : U"B";
S0x1F : U"V";
S0x20 : U"C";
S0x21 : U"X";
S0x22 : U"Z";
S0x23 : U"LShift";
# Bottom Thumb Cluster
S0x24 : U"Home";
S0x25 : U"End";
S0x26 : U"Delete";
S0x27 : U"Backspace";
# Bottom Row
S0x28 : U"Function5";
S0x29 : U"Function4";
S0x2A : U"Function3";
S0x2B : U"Backtick";
S0x2C : U"LGui";
# Sets all future Scan Code definitions to be applied to the first slave node
ConnectId = 1;
# Top Row
S0x02 : U"Function6";
S0x03 : U"6";
S0x04 : U"7";
S0x05 : U"8";
S0x06 : U"9";
S0x07 : U"0";
S0x08 : U"Minus";
# Top-Middle Row
S0x0B : U"LBrace";
S0x0C : U"Y";
S0x0D : U"U";
S0x0E : U"I";
S0x0F : U"O";
S0x10 : U"P";
S0x11 : U"RBrace";
# Middle Row
S0x15 : U"H";
S0x16 : U"J";
S0x17 : U"K";
S0x18 : U"L";
S0x19 : U"Semicolon";
S0x1A : U"Quote";
# Top Thumb Cluster
S0x1B : U"RAlt";
S0x1C : U"RCtrl";
# Bottom-Middle Row
S0x1D : U"Function7";
S0x1E : U"N";
S0x1F : U"M";
S0x20 : U"Comma";
S0x21 : U"Period";
S0x22 : U"Slash";
S0x23 : U"RShift";
# Bottom Thumb Cluster
S0x24 : U"PageUp";
S0x25 : U"PageDown";
S0x26 : U"Enter";
S0x27 : U"Space";
# Bottom Row
S0x28 : U"Left";
S0x29 : U"Down";
S0x2A : U"Up";
S0x2B : U"Right";
S0x2C : U"RGui";

View file

@ -1,56 +0,0 @@
/* Copyright (C) 2014-2015 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
// ----- Includes -----
// Project Includes
#include <matrix_setup.h>
// ----- Matrix Definition -----
// Freescale ARM MK20's support GPIO PTA, PTB, PTC, PTD and PTE 0..31
// Not all chips have access to all of these pins (most don't have 160 pins :P)
//
// NOTE:
// Before using a pin, make sure it supports being a GPIO *and* doesn't have a default pull-up/pull-down
// Checking this is completely on the ownness of the user
// MDErgo1
//
// Column (Strobe) - 9 Total
// PTB2,3,18,19
// PTC0,9..11
// PTD0
//
// Rows (Sense) - 5 Total
// PTD1,4..7
// Define Rows (Sense) and Columns (Strobes)
GPIO_Pin Matrix_cols[] = { gpio(B,2), gpio(B,3), gpio(B,18), gpio(B,19), gpio(C,0), gpio(C,9), gpio(C,10), gpio(C,11), gpio(D,0) };
GPIO_Pin Matrix_rows[] = { gpio(D,1), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7) };
// Define type of scan matrix
Config Matrix_type = Config_Pulldown;

View file

@ -1,144 +0,0 @@
Pin Usage
=========
mk20dx256vlh7
----
|Keys|
----
* Strobe (Columns)
TODO
* Sense (Rows)
TODO
-----
|Clock|
-----
PTA18 <-> PTA19
---
|I2C|
---
* Main - Connect to all ISSI Chips - Also break out header for debugging
PTB0 - SCL0 (add header pin, label as SCL0)
PTB1 - SDA0 (add header pin, label as SDA0)
* Reserved for I2C usage
PTC10 - SCL1 (Reserved, can use as GPIO)
PTC11 - SDA1 (Reserved, can use as GPIO)
* ISSI Control (enough pins for 3 chips reserved)
PTB17 - INTB Chip 1
PTB18 - INTB Chip 2 (Reserved, can use as GPIO)
PTB19 - INTB Chip 3 (Reserved, can use as GPIO)
PTB16 - SDB (tied to all Chips, hardware shutdown)
---
|PWM|
---
NHD-C12832A1Z-FS(RGB)-FBW-3V
PTC1 - K(R)
PTC2 - K(G)
PTC3 - K(B)
---
|SPI|
---
NHD-C12832A1Z-FS(RGB)-FBW-3V
PTC4 - CS1B - SS1
PTC5 - SCL - SCLK
PTC6 - SDA(SI) - MOSI
PTC7 - A0 (Not SPI, used for display)
PTC8 - RST (Not SPI, used for display)
---
|DAC|
---
DAC0 (N/C)
----
|UART|
----
* Comm - For bi-directional communication between halves
PTA1 - RX0 (Master Side)
PTA2 - TX0 (Master Side)
PTE0 - TX1 (Slave Side)
PTE1 - RX1 (Slave Side)
PTD2 - RX2 (UART Debug Header)
PTD3 - TX2 (UART Debug Header)
-----
|Debug|
-----
* SWD - (Main reflash header)
PTA0 (Pull-down)
PTA3 (Pull-up)
* LEDs
PTA5 (LED only for PCB, not Teensy)
* UARTs
PTD2 - RX2 (UART Debug Header, label as RX2)
PTD3 - TX2 (UART Debug Header, label as TX2)
------
|Unused|
------
* GPIO
PTA4
PTA12
PTA13
PTB2
PTB3
PTB16
PTB17
PTB18
PTB19
PTC0
PTC9
PTC10
PTC11
PTD0
PTD1
PTD4
PTD5
PTD6
PTD7
* Analog
TODO

View file

@ -1,61 +0,0 @@
Name = MDErgo1 Right Hand;
Version = 0.1;
Author = "HaaTa (Jacob Alexander) 2015";
KLL = 0.3c;
# Modified Date
Date = 2015-08-06;
# Top Row
S0x02 : U"Function6";
S0x03 : U"6";
S0x04 : U"7";
S0x05 : U"8";
S0x06 : U"9";
S0x07 : U"0";
S0x08 : U"Minus";
# Top-Middle Row
S0x0B : U"Left Brace";
S0x0C : U"Y";
S0x0D : U"U";
S0x0E : U"I";
S0x0F : U"O";
S0x10 : U"P";
S0x11 : U"Right Brace";
# Middle Row
S0x15 : U"H";
S0x16 : U"J";
S0x17 : U"K";
S0x18 : U"L";
S0x19 : U"Semicolon";
S0x1A : U"Quote";
# Top Thumb Cluster
S0x1B : U"RAlt";
S0x1C : U"RCtrl";
# Bottom-Middle Row
S0x1D : U"Function7";
S0x1E : U"N";
S0x1F : U"M";
S0x20 : U"Comma";
S0x21 : U"Period";
S0x22 : U"Slash";
S0x23 : U"Right Shift";
# Bottom Thumb Cluster
S0x24 : U"PageUp";
S0x25 : U"PageDown";
S0x26 : U"Enter";
S0x27 : U"Space";
# Bottom Row
S0x28 : U"Left";
S0x29 : U"Down";
S0x2A : U"Up";
S0x2B : U"Right";
S0x2C : U"RGui";

View file

@ -1,116 +0,0 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// ----- Includes -----
// Compiler Includes
#include <Lib/ScanLib.h>
// Project Includes
#include <cli.h>
#include <connect_scan.h>
#include <lcd_scan.h>
#include <led.h>
#include <led_scan.h>
#include <print.h>
#include <matrix_scan.h>
#include <macro.h>
#include <output_com.h>
// Local Includes
#include "scan_loop.h"
// ----- Variables -----
// Number of scans since the last USB send
uint16_t Scan_scanCount = 0;
// ----- Functions -----
// Setup
inline void Scan_setup()
{
// Setup UART Connect, if Output_Available, this is the master node
Connect_setup( Output_Available );
// Setup GPIO pins for matrix scanning
Matrix_setup();
// Setup ISSI chip to control the leds
LED_setup();
// Setup the ST/NHD lcd display
LCD_setup();
// Reset scan count
Scan_scanCount = 0;
}
// Main Detection Loop
inline uint8_t Scan_loop()
{
// Scan Matrix
Matrix_scan( Scan_scanCount++ );
// Process any interconnect commands
Connect_scan();
// Process any LED events
LED_scan();
// Process any LCD events
LCD_scan();
return 0;
}
// Signal from Macro Module that all keys have been processed (that it knows about)
inline void Scan_finishedWithMacro( uint8_t sentKeys )
{
}
// Signal from Output Module that all keys have been processed (that it knows about)
inline void Scan_finishedWithOutput( uint8_t sentKeys )
{
// Reset scan loop indicator (resets each key debounce state)
// TODO should this occur after USB send or Macro processing?
Scan_scanCount = 0;
}
// Signal from the Output Module that the available current has changed
// current - mA
void Scan_currentChange( unsigned int current )
{
// Indicate to all submodules current change
Connect_currentChange( current );
Matrix_currentChange( current );
LED_currentChange( current );
LCD_currentChange( current );
}

View file

@ -1,42 +0,0 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
// ----- Includes -----
// Compiler Includes
#include <stdint.h>
// ----- Functions -----
// Functions to be called by main.c
void Scan_setup();
uint8_t Scan_loop();
// Call-backs
void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module
void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module
void Scan_currentChange( unsigned int current ); // Called by Output Module

View file

@ -1,33 +0,0 @@
###| CMake Kiibohd Controller Scan Module |###
#
# Written by Jacob Alexander in 2014-2015 for the Kiibohd Controller
#
# Released into the Public Domain
#
###
###
# Required Sub-modules
#
AddModule ( Scan ISSILed )
AddModule ( Scan MatrixARM )
AddModule ( Scan STLcd )
AddModule ( Scan UARTConnect )
###
# Module C files
#
set ( Module_SRCS
scan_loop.c
)
###
# Compiler Family Compatibility
#
set ( ModuleCompatibility
arm
)

View file

@ -1,11 +0,0 @@
Name = MDErgo1 Slave1;
Version = 0.1;
Author = "HaaTa (Jacob Alexander) 2015";
KLL = 0.3c;
# Modified Date
Date = 2015-08-06;
# Sets all future Scan Code definitions to be applied to the first slave node
ConnectId = 1;

View file

@ -32,10 +32,3 @@ DebounceThrottleDiv => DebounceThrottleDiv_define;
DebounceThrottleDiv = 0; # Default
#DebounceThrottleDiv = 2; # /4 divider
# This defines the minimum amount of time after a transition until allowing another transition
# Generally switches require a minimum 5 ms debounce period
# Since a decision can usually be made quite quickly, there is little latency on each press
# However, this defines the latency at which the switch state can change
MinDebounceTime => MinDebounceTime_define;
MinDebounceTime = 5; # 5 ms

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
/* Copyright (C) 2014-2015 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -26,11 +26,10 @@
// Project Includes
#include <cli.h>
#include <kll_defs.h>
#include <kll.h>
#include <led.h>
#include <print.h>
#include <macro.h>
#include <Lib/delay.h>
// Local Includes
#include "matrix_scan.h"
@ -52,7 +51,6 @@ nat_ptr_t Matrix_divCounter = 0;
// CLI Functions
void cliFunc_matrixDebug( char* args );
void cliFunc_matrixInfo( char* args );
void cliFunc_matrixState( char* args );
@ -61,12 +59,10 @@ void cliFunc_matrixState( char* args );
// Scan Module command dictionary
CLIDict_Entry( matrixDebug, "Enables matrix debug mode, prints out each scan code." NL "\t\tIf argument \033[35mT\033[0m is given, prints out each scan code state transition." );
CLIDict_Entry( matrixInfo, "Print info about the configured matrix." );
CLIDict_Entry( matrixState, "Prints out the current scan table N times." NL "\t\t \033[1mO\033[0m - Off, \033[1;33mP\033[0m - Press, \033[1;32mH\033[0m - Hold, \033[1;35mR\033[0m - Release, \033[1;31mI\033[0m - Invalid" );
CLIDict_Def( matrixCLIDict, "Matrix Module Commands" ) = {
CLIDict_Item( matrixDebug ),
CLIDict_Item( matrixInfo ),
CLIDict_Item( matrixState ),
{ 0, 0, 0 } // Null entry for dictionary end
};
@ -74,15 +70,6 @@ CLIDict_Def( matrixCLIDict, "Matrix Module Commands" ) = {
// Debounce Array
KeyState Matrix_scanArray[ Matrix_colsNum * Matrix_rowsNum ];
// Ghost Arrays
#ifdef GHOSTING_MATRIX
KeyGhost Matrix_ghostArray[ Matrix_colsNum * Matrix_rowsNum ];
uint8_t col_use[Matrix_colsNum], row_use[Matrix_rowsNum]; // used count
uint8_t col_ghost[Matrix_colsNum], row_ghost[Matrix_rowsNum]; // marked as having ghost if 1
#endif
// Matrix debug flag - If set to 1, for each keypress the scan code is displayed in hex
// If set to 2, for each key state change, the scan code is displayed along with the state
uint8_t matrixDebugMode = 0;
@ -95,9 +82,6 @@ uint16_t matrixMaxScans = 0;
uint16_t matrixCurScans = 0;
uint16_t matrixPrevScans = 0;
// System Timer used for delaying debounce decisions
extern volatile uint32_t systick_millis_count;
// ----- Functions -----
@ -114,9 +98,7 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type )
// Assumes 0x40 between GPIO Port registers and 0x1000 between PORT pin registers
// See Lib/mk20dx.h
volatile unsigned int *GPIO_PDDR = (unsigned int*)(&GPIOA_PDDR) + gpio_offset;
#ifndef GHOSTING_MATRIX
volatile unsigned int *GPIO_PSOR = (unsigned int*)(&GPIOA_PSOR) + gpio_offset;
#endif
volatile unsigned int *GPIO_PCOR = (unsigned int*)(&GPIOA_PCOR) + gpio_offset;
volatile unsigned int *GPIO_PDIR = (unsigned int*)(&GPIOA_PDIR) + gpio_offset;
volatile unsigned int *PORT_PCR = (unsigned int*)(&PORTA_PCR0) + port_offset;
@ -125,30 +107,16 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type )
switch ( type )
{
case Type_StrobeOn:
#ifdef GHOSTING_MATRIX
*GPIO_PCOR |= (1 << gpio.pin);
*GPIO_PDDR |= (1 << gpio.pin); // output, low
#else
*GPIO_PSOR |= (1 << gpio.pin);
#endif
break;
case Type_StrobeOff:
#ifdef GHOSTING_MATRIX
// Ghosting martix needs to put not used (off) strobes in high impedance state
*GPIO_PDDR &= ~(1 << gpio.pin); // input, high Z state
#endif
*GPIO_PCOR |= (1 << gpio.pin);
break;
case Type_StrobeSetup:
#ifdef GHOSTING_MATRIX
*GPIO_PDDR &= ~(1 << gpio.pin); // input, high Z state
*GPIO_PCOR |= (1 << gpio.pin);
#else
// Set as output pin
*GPIO_PDDR |= (1 << gpio.pin);
#endif
// Configure pin with slow slew, high drive strength and GPIO mux
*PORT_PCR = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
@ -167,11 +135,7 @@ uint8_t Matrix_pin( GPIO_Pin gpio, Type type )
break;
case Type_Sense:
#ifdef GHOSTING_MATRIX // inverted
return *GPIO_PDIR & (1 << gpio.pin) ? 0 : 1;
#else
return *GPIO_PDIR & (1 << gpio.pin) ? 1 : 0;
#endif
case Type_SenseSetup:
// Set as input pin
@ -207,31 +171,36 @@ void Matrix_setup()
// Register Matrix CLI dictionary
CLI_registerDictionary( matrixCLIDict, matrixCLIDictName );
info_msg("Columns: ");
printHex( Matrix_colsNum );
// Setup Strobe Pins
for ( uint8_t pin = 0; pin < Matrix_colsNum; pin++ )
{
Matrix_pin( Matrix_cols[ pin ], Type_StrobeSetup );
}
print( NL );
info_msg("Rows: ");
printHex( Matrix_rowsNum );
// Setup Sense Pins
for ( uint8_t pin = 0; pin < Matrix_rowsNum; pin++ )
{
Matrix_pin( Matrix_rows[ pin ], Type_SenseSetup );
}
print( NL );
info_msg("Max Keys: ");
printHex( Matrix_maxKeys );
// Clear out Debounce Array
for ( uint8_t item = 0; item < Matrix_maxKeys; item++ )
{
Matrix_scanArray[ item ].prevState = KeyState_Off;
Matrix_scanArray[ item ].curState = KeyState_Off;
Matrix_scanArray[ item ].activeCount = 0;
Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state
Matrix_scanArray[ item ].prevDecisionTime = 0;
#ifdef GHOSTING_MATRIX
Matrix_ghostArray[ item ].prev = KeyState_Off;
Matrix_ghostArray[ item ].cur = KeyState_Off;
Matrix_ghostArray[ item ].saved = KeyState_Off;
#endif
Matrix_scanArray[ item ].prevState = KeyState_Off;
Matrix_scanArray[ item ].curState = KeyState_Off;
Matrix_scanArray[ item ].activeCount = 0;
Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state
}
// Clear scan stats counters
@ -293,25 +262,12 @@ void Matrix_scan( uint16_t scanNum )
matrixCurScans++;
}
// Read systick for event scheduling
uint8_t currentTime = (uint8_t)systick_millis_count;
// For each strobe, scan each of the sense pins
for ( uint8_t strobe = 0; strobe < Matrix_colsNum; strobe++ )
{
#ifdef STROBE_DELAY
uint32_t start = micros();
while ((micros() - start) < STROBE_DELAY);
#endif
// Strobe Pin
Matrix_pin( Matrix_cols[ strobe ], Type_StrobeOn );
#ifdef STROBE_DELAY
start = micros();
while ((micros() - start) < STROBE_DELAY);
#endif
// Scan each of the sense pins
for ( uint8_t sense = 0; sense < Matrix_rowsNum; sense++ )
{
@ -349,16 +305,11 @@ void Matrix_scan( uint16_t scanNum )
}
// Check for state change if it hasn't been set
// But only if enough time has passed since last state change
// Only check if the minimum number of scans has been met
// the current state is invalid
// and either active or inactive count is over the debounce threshold
if ( state->curState == KeyState_Invalid )
{
// Determine time since last decision
uint8_t lastTransition = currentTime - state->prevDecisionTime;
// Attempt state transition
switch ( state->prevState )
{
case KeyState_Press:
@ -369,15 +320,6 @@ void Matrix_scan( uint16_t scanNum )
}
else
{
// If not enough time has passed since Hold
// Keep previous state
if ( lastTransition < MinDebounceTime_define )
{
//warn_print("FAST Release stopped");
state->curState = state->prevState;
continue;
}
state->curState = KeyState_Release;
}
break;
@ -386,15 +328,6 @@ void Matrix_scan( uint16_t scanNum )
case KeyState_Off:
if ( state->activeCount > state->inactiveCount )
{
// If not enough time has passed since Hold
// Keep previous state
if ( lastTransition < MinDebounceTime_define )
{
//warn_print("FAST Press stopped");
state->curState = state->prevState;
continue;
}
state->curState = KeyState_Press;
}
else
@ -409,13 +342,8 @@ void Matrix_scan( uint16_t scanNum )
break;
}
// Update decision time
state->prevDecisionTime = currentTime;
// Send keystate to macro module
#ifndef GHOSTING_MATRIX
Macro_keyState( key, state->curState );
#endif
// Matrix Debug, only if there is a state change
if ( matrixDebugMode && state->curState != state->prevState )
@ -441,97 +369,6 @@ void Matrix_scan( uint16_t scanNum )
Matrix_pin( Matrix_cols[ strobe ], Type_StrobeOff );
}
// Matrix ghosting check and elimination
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
#ifdef GHOSTING_MATRIX
// strobe = column, sense = row
// Count (rows) use for columns
//print("C ");
for ( uint8_t col = 0; col < Matrix_colsNum; col++ )
{
uint8_t used = 0;
for ( uint8_t row = 0; row < Matrix_rowsNum; row++ )
{
uint8_t key = Matrix_colsNum * row + col;
KeyState *state = &Matrix_scanArray[ key ];
if ( keyOn(state->curState) )
used++;
}
//printInt8(used);
col_use[col] = used;
col_ghost[col] = 0; // clear
}
// Count (columns) use for rows
//print(" R ");
for ( uint8_t row = 0; row < Matrix_rowsNum; row++ )
{
uint8_t used = 0;
for ( uint8_t col = 0; col < Matrix_colsNum; col++ )
{
uint8_t key = Matrix_colsNum * row + col;
KeyState *state = &Matrix_scanArray[ key ];
if ( keyOn(state->curState) )
used++;
}
//printInt8(used);
row_use[row] = used;
row_ghost[row] = 0; // clear
}
// Check if matrix has ghost
// Happens when key is pressed and some other key is pressed in same row and another in same column
//print(" G ");
for ( uint8_t col = 0; col < Matrix_colsNum; col++ )
{
for ( uint8_t row = 0; row < Matrix_rowsNum; row++ )
{
uint8_t key = Matrix_colsNum * row + col;
KeyState *state = &Matrix_scanArray[ key ];
if ( keyOn(state->curState) && col_use[col] >= 2 && row_use[row] >= 2 )
{
// mark col and row as having ghost
col_ghost[col] = 1;
row_ghost[row] = 1;
//print(" "); printInt8(col); print(","); printInt8(row);
}
}
}
//print( NL );
// Send keys
for ( uint8_t col = 0; col < Matrix_colsNum; col++ )
{
for ( uint8_t row = 0; row < Matrix_rowsNum; row++ )
{
uint8_t key = Matrix_colsNum * row + col;
KeyState *state = &Matrix_scanArray[ key ];
KeyGhost *st = &Matrix_ghostArray[ key ];
// col or row is ghosting (crossed)
uint8_t ghost = (col_ghost[col] > 0 || row_ghost[row] > 0) ? 1 : 0;
st->prev = st->cur; // previous
// save state if no ghost or outside ghosted area
if ( ghost == 0 )
st->saved = state->curState; // save state if no ghost
// final
// use saved state if ghosting, or current if not
st->cur = ghost > 0 ? st->saved : state->curState;
// Send keystate to macro module
KeyPosition k = !st->cur
? (!st->prev ? KeyState_Off : KeyState_Release)
: ( st->prev ? KeyState_Hold : KeyState_Press);
Macro_keyState( key, k );
}
}
#endif
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
// State Table Output Debug
if ( matrixDebugStateCounter > 0 )
{
@ -578,33 +415,9 @@ void Matrix_scan( uint16_t scanNum )
}
// Called by parent scan module whenever the available current changes
// current - mA
void Matrix_currentChange( unsigned int current )
{
// TODO - Any potential power savings?
}
// ----- CLI Command Functions -----
void cliFunc_matrixInfo( char* args )
{
print( NL );
info_msg("Columns: ");
printHex( Matrix_colsNum );
print( NL );
info_msg("Rows: ");
printHex( Matrix_rowsNum );
print( NL );
info_msg("Max Keys: ");
printHex( Matrix_maxKeys );
}
void cliFunc_matrixDebug( char* args )
void cliFunc_matrixDebug ( char* args )
{
// Parse number from argument
// NOTE: Only first argument is used
@ -638,7 +451,7 @@ void cliFunc_matrixDebug( char* args )
printInt8( matrixDebugMode );
}
void cliFunc_matrixState( char* args )
void cliFunc_matrixState ( char* args )
{
// Parse number from argument
// NOTE: Only first argument is used

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2016 by Jacob Alexander
/* Copyright (C) 2014-2015 by Jacob Alexander
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -40,12 +40,6 @@
#error "Debounce threshold is too high... 32 bit max. Check .kll defines."
#endif
#if ( MinDebounceTime_define > 0xFF )
#error "MinDebounceTime is a maximum of 255 ms"
#elif ( MinDebounceTime_define < 0x00 )
#error "MinDebounceTime is a minimum 0 ms"
#endif
// ----- Enums -----
@ -132,25 +126,12 @@ typedef struct GPIO_Pin {
// Debounce Element
typedef struct KeyState {
DebounceCounter activeCount;
DebounceCounter inactiveCount;
KeyPosition prevState;
KeyPosition curState;
uint8_t prevDecisionTime;
} __attribute__((packed)) KeyState;
DebounceCounter activeCount;
DebounceCounter inactiveCount;
} KeyState;
// Ghost Element, after ghost detection/cancelation
typedef struct KeyGhost {
KeyPosition prev;
KeyPosition cur;
KeyPosition saved; // state before ghosting
} __attribute__((packed)) KeyGhost;
// utility
inline uint8_t keyOn(/*KeyPosition*/uint8_t st)
{
return (st == KeyState_Press || st == KeyState_Hold) ? 1 : 0;
}
// ----- Functions -----
@ -158,5 +139,3 @@ inline uint8_t keyOn(/*KeyPosition*/uint8_t st)
void Matrix_setup();
void Matrix_scan( uint16_t scanNum );
void Matrix_currentChange( unsigned int current );

View file

@ -19,7 +19,7 @@
import sys
from array import *
from PIL import Image # Use pillow instead of PIL, it works with Python 3
from PIL import Image
# Convenience class to deal with converting images to a C array
@ -110,10 +110,7 @@ class STLcdGraphic:
return display
filename = sys.argv[1]
if filename is None:
print( "You must specify a bitmap filename. Try './bitmap2Struct.py ic_logo_lcd.bmp'" )
sys.exit( 1 )
filename = "ic_logo_lcd.bmp"
max_height = 32
max_width = 128
x_offset = 0

View file

@ -1,77 +0,0 @@
Name = STLcdCapabilities;
Version = 0.1;
Author = "HaaTa (Jacob Alexander) 2015";
KLL = 0.3c;
# Modified Date
Date = 2015-08-01;
# Defines available to the STLcd sub-module
# PWM Prescalar
# In general this can be left alone
# A higher prescalar should be lower power usage (less switching)
# However, flickering may be noticeable.
#
# Here's a calculation table valid at a 72 MHz system clock
# Prescalars range from 0 to 7 (1 to 128)
# Base FTM clock selection (72 MHz system clock)
# @ 0xFFFF period, 72 MHz / (0xFFFF * 2) = Actual period
# Higher pre-scalar will use the most power (also look the best)
# Pre-scalar calculations
# 0 - 72 MHz -> 549 Hz
# 1 - 36 MHz -> 275 Hz
# 2 - 18 MHz -> 137 Hz
# 3 - 9 MHz -> 69 Hz (Slightly visible flicker)
# 4 - 4 500 kHz -> 34 Hz (Visible flickering)
# 5 - 2 250 kHz -> 17 Hz
# 6 - 1 125 kHz -> 9 Hz
# 7 - 562 500 Hz -> 4 Hz
STLcdBacklightPrescalar => STLcdBacklightPrescalar_define;
STLcdBacklightPrescalar = 0;
# Default Backlight Channel Brightness
# There are 3 channels, RGB
# In order to get other colors you must mix the 3 colors
# Each channel is a 16-bit register (65536 levels)
# Technically, this means, the backlight is a 48-bit RGB pixel
# In practice, it may be difficult to get color consistency at times if too bright or too dim
STLcdBacklightRed => STLcdBacklightRed_define;
STLcdBacklightGreen => STLcdBacklightGreen_define;
STLcdBacklightBlue => STLcdBacklightBlue_define;
# Defaults to 6% brightness, white
STLcdBacklightRed = 0x0FFF;
STLcdBacklightGreen = 0x0FFF;
STLcdBacklightBlue = 0x0FFF;
# Default LCD Image
#
# The easiest way to generate this data is using the bitmap2Struct.py script in this folder
# It will output the necessary uint8_t array to set here
#
STLcdDefaultImage => STLcdDefaultImage_define;
# Only the data portion is required
# Must be on a single line
STLcdDefaultImage = "
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
";
# Layer Status Display
LCDLayerDisplay => LCD_layerStack_capability();
LCDLayerDisplayExact => LCD_layerStackExact_capability( display : 1, stack1 : 2, stack2 : 2, stack3 : 2, stack4 : 2 );
# LCD Module Enabled
LCDEnabled => LCDEnabled_define;
LCDEnabled = 1;

View file

@ -1,50 +0,0 @@
#!/usr/bin/env bash
# STLcd
# Virtual Serial Port API Example
# Jacob Alexander 2015
if [ $# -eq 0 ]; then
echo "You must specify your virtual serialport. (/dev/ttyACM0 on linux, /dev/cu.usbmodemXXXX on OSX)"
echo " ex: $0 /dev/ttyACM0"
exit 1
fi
# XXX Set this to match your virtual serialport
# TODO Show example for Cygwin/Windows
# For Mac OSX it will be something like /dev/cu.usbmodem1413 (number may differ)
SERIALPORT=$1
# NOTE: Make sure you don't write too quickly to the serial port, it can get overwhelmed by a modern computer
# Generally this just means commands will get ignored
# I'm using 100 ms sleeps here, but much smaller are probably sufficient
# Clear out cli buffer
printf "\r" > $SERIALPORT
# Change backlight color
# 3 16-bit numbers (hex or decimal) Red, Green and Blue
sleep 0.1
printf "lcdColor 0x100 0x2000 0x4000\r" > $SERIALPORT # Light blue
# Change the lcd image
# Arguments:
# - page
# - starting address
# - pixels (1 bit per pixel)
#
# There are 9 total pages of display memory, but only 4 are visable at time (it is possible to scroll though)
# Each page is 128 bits wide (16 bytes)
# See the datasheet for full details http://www.newhavendisplay.com/specs/NHD-C12832A1Z-FSRGB-FBW-3V.pdf
sleep 0.1
printf "lcdDisp 0x0 0x0 0xFF 0x13 0xFF 0x11 0xFF\r" > $SERIALPORT
sleep 0.1
printf "lcdDisp 0x1 0x10 0xFF 0x13 0xFF 0x11 0xFF 0x44\r" > $SERIALPORT
sleep 0.1
printf "lcdDisp 0x2 0x20 0xFF 0x13 0xFF 0x11 0xFF\r" > $SERIALPORT
sleep 0.1
printf "lcdDisp 0x3 0x30 0xFF 0x13 0xFF 0x11 0xFF\r" > $SERIALPORT
# Send command directly to the lcd
# See the datasheet for full details http://www.newhavendisplay.com/specs/NHD-C12832A1Z-FSRGB-FBW-3V.pdf
sleep 0.1
printf "lcdCmd 0xA7\r" > $SERIALPORT # Reverse display (0xA6 is Normal)

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2016 by Jacob Alexander
/* Copyright (C) 2015 by Jacob Alexander
*
* This file is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,15 +21,9 @@
// Project Includes
#include <cli.h>
#include <kll_defs.h>
#include <led.h>
#include <print.h>
// Interconnect module if compiled in
#if defined(ConnectEnabled_define)
#include <connect_scan.h>
#endif
// Local Includes
#include "lcd_scan.h"
@ -38,7 +32,6 @@
// ----- Defines -----
#define LCD_TOTAL_VISIBLE_PAGES 4
#define LCD_TOTAL_PAGES 9
#define LCD_PAGE_LEN 128
@ -55,19 +48,14 @@
// ----- Function Declarations -----
// CLI Functions
void cliFunc_lcdCmd ( char* args );
void cliFunc_lcdColor( char* args );
void cliFunc_lcdDisp ( char* args );
void cliFunc_lcdInit ( char* args );
void cliFunc_lcdTest ( char* args );
void cliFunc_lcdCmd( char* args );
void cliFunc_lcdInit( char* args );
void cliFunc_lcdTest( char* args );
// ----- Variables -----
// Default Image - Displays on startup
const uint8_t STLcdDefaultImage[] = { STLcdDefaultImage_define };
// Full Toggle State
uint8_t cliFullToggleState = 0;
@ -76,15 +64,11 @@ uint8_t cliNormalReverseToggleState = 0;
// Scan Module command dictionary
CLIDict_Entry( lcdCmd, "Send byte via SPI, second argument enables a0. Defaults to control." );
CLIDict_Entry( lcdColor, "Set backlight color. 3 16-bit numbers: R G B. i.e. 0xFFF 0x1444 0x32" );
CLIDict_Entry( lcdDisp, "Write byte(s) to given page starting at given address. i.e. 0x1 0x5 0xFF 0x00" );
CLIDict_Entry( lcdInit, "Re-initialize the LCD display." );
CLIDict_Entry( lcdTest, "Test out the LCD display." );
CLIDict_Def( lcdCLIDict, "ST LCD Module Commands" ) = {
CLIDict_Item( lcdCmd ),
CLIDict_Item( lcdColor ),
CLIDict_Item( lcdDisp ),
CLIDict_Item( lcdInit ),
CLIDict_Item( lcdTest ),
{ 0, 0, 0 } // Null entry for dictionary end
@ -213,7 +197,7 @@ inline void LCD_clearPage( uint8_t page )
void LCD_clear()
{
// Setup each page
for ( uint8_t page = 0; page < LCD_TOTAL_PAGES; page++ )
for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ )
{
LCD_clearPage( page );
}
@ -274,6 +258,7 @@ inline void LCD_setup()
// Initialize SPI
SPI_setup();
// Setup Register Control Signal (A0)
// Start in display register mode (1)
GPIOC_PDDR |= (1<<7);
@ -289,256 +274,51 @@ inline void LCD_setup()
// Run LCD intialization sequence
LCD_initialize();
// Write default image to LCD
for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ )
LCD_writeDisplayReg( page, (uint8_t*)&STLcdDefaultImage[page * LCD_PAGE_LEN], LCD_PAGE_LEN );
// Setup Backlight
SIM_SCGC6 |= SIM_SCGC6_FTM0;
FTM0_CNT = 0; // Reset counter
// PWM Period
// 16-bit maximum
FTM0_MOD = 0xFFFF;
// Set FTM to PWM output - Edge Aligned, Low-true pulses
FTM0_C0SC = 0x24; // MSnB:MSnA = 10, ELSnB:ELSnA = 01
FTM0_C1SC = 0x24;
FTM0_C2SC = 0x24;
// Base FTM clock selection (72 MHz system clock)
// @ 0xFFFF period, 72 MHz / (0xFFFF * 2) = Actual period
// Higher pre-scalar will use the most power (also look the best)
// Pre-scalar calculations
// 0 - 72 MHz -> 549 Hz
// 1 - 36 MHz -> 275 Hz
// 2 - 18 MHz -> 137 Hz
// 3 - 9 MHz -> 69 Hz (Slightly visible flicker)
// 4 - 4 500 kHz -> 34 Hz (Visible flickering)
// 5 - 2 250 kHz -> 17 Hz
// 6 - 1 125 kHz -> 9 Hz
// 7 - 562 500 Hz -> 4 Hz
// Using a higher pre-scalar without flicker is possible but FTM0_MOD will need to be reduced
// Which will reduce the brightness range
// System clock, /w prescalar setting
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS( STLcdBacklightPrescalar_define );
// Red
FTM0_C0V = STLcdBacklightRed_define;
PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(4);
// Green
FTM0_C1V = STLcdBacklightGreen_define;
PORTC_PCR2 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(4);
// Blue
FTM0_C2V = STLcdBacklightBlue_define;
PORTC_PCR3 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(4);
}
// LCD State processing loop
inline uint8_t LCD_scan()
{
// NOP - Screen Refresh
//LCD_writeControlReg( 0xE3 );
return 0;
}
// Signal from parent Scan Module that available current has changed
// current - mA
void LCD_currentChange( unsigned int current )
{
// TODO - Power savings?
}
// ----- Capabilities -----
// Takes 1 8 bit length and 4 16 bit arguments, each corresponding to a layer index
// Ordered from top to bottom
// The first argument indicates how many numbers to display (max 4), set to 0 to load default image
uint16_t LCD_layerStackExact[4];
uint8_t LCD_layerStackExact_size = 0;
typedef struct LCD_layerStackExact_args {
uint8_t numArgs;
uint16_t layers[4];
} LCD_layerStackExact_args;
void LCD_layerStackExact_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("LCD_layerStackExact_capability(num,layer1,layer2,layer3,layer4)");
return;
}
// Read arguments
LCD_layerStackExact_args *stack_args = (LCD_layerStackExact_args*)args;
// Number data for LCD
const uint8_t numbers[10][128] = {
{ STLcdNumber0_define },
{ STLcdNumber1_define },
{ STLcdNumber2_define },
{ STLcdNumber3_define },
{ STLcdNumber4_define },
{ STLcdNumber5_define },
{ STLcdNumber6_define },
{ STLcdNumber7_define },
{ STLcdNumber8_define },
{ STLcdNumber9_define },
};
// Color data for numbers
const uint16_t colors[10][3] = {
{ STLcdNumber0Color_define },
{ STLcdNumber1Color_define },
{ STLcdNumber2Color_define },
{ STLcdNumber3Color_define },
{ STLcdNumber4Color_define },
{ STLcdNumber5Color_define },
{ STLcdNumber6Color_define },
{ STLcdNumber7Color_define },
{ STLcdNumber8Color_define },
{ STLcdNumber9Color_define },
};
// Only display if there are layers active
if ( stack_args->numArgs > 0 )
{
// Set the color according to the "top-of-stack" layer
uint16_t layerIndex = stack_args->layers[0];
FTM0_C0V = colors[ layerIndex ][0];
FTM0_C1V = colors[ layerIndex ][1];
FTM0_C2V = colors[ layerIndex ][2];
// Iterate through each of the pages
// XXX Many of the values here are hard-coded
// Eventually a proper font rendering engine should take care of things like this... -HaaTa
for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ )
{
// Set the register page
LCD_writeControlReg( 0xB0 | ( 0x0F & page ) );
// Set starting address
LCD_writeControlReg( 0x10 );
LCD_writeControlReg( 0x00 );
// Write data
for ( uint16_t layer = 0; layer < stack_args->numArgs; layer++ )
{
layerIndex = stack_args->layers[ layer ];
// Default to 0, if over 9
if ( layerIndex > 9 )
{
layerIndex = 0;
}
// Write page of number to display
SPI_write( (uint8_t*)&numbers[ layerIndex ][ page * 32 ], 32 );
}
// Blank out rest of display
uint8_t data = 0;
for ( uint8_t c = 0; c < 4 - stack_args->numArgs; c++ )
{
for ( uint8_t byte = 0; byte < 32; byte++ )
{
SPI_write( &data, 1 );
}
}
}
}
else
{
// Set default backlight
FTM0_C0V = STLcdBacklightRed_define;
FTM0_C1V = STLcdBacklightGreen_define;
FTM0_C2V = STLcdBacklightBlue_define;
// Write default image
for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ )
LCD_writeDisplayReg( page, (uint8_t *)&STLcdDefaultImage[page * LCD_PAGE_LEN], LCD_PAGE_LEN );
}
}
// Determines the current layer stack, and sets the LCD output accordingly
// Will only work on a master node when using the interconnect (use LCD_layerStackExact_capability instead)
uint16_t LCD_layerStack_prevSize = 0;
uint16_t LCD_layerStack_prevTop = 0;
void LCD_layerStack_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
// Display capability name
if ( stateType == 0xFF && state == 0xFF )
{
print("LCD_layerStack_capability()");
return;
}
// Parse the layer stack, top to bottom
extern uint16_t macroLayerIndexStack[];
extern uint16_t macroLayerIndexStackSize;
// Ignore if the stack size hasn't changed and the top of the stack is the same
if ( macroLayerIndexStackSize == LCD_layerStack_prevSize
&& macroLayerIndexStack[macroLayerIndexStackSize - 1] == LCD_layerStack_prevTop )
{
return;
}
LCD_layerStack_prevSize = macroLayerIndexStackSize;
LCD_layerStack_prevTop = macroLayerIndexStack[macroLayerIndexStackSize - 1];
LCD_layerStackExact_args stack_args;
memset( stack_args.layers, 0, sizeof( stack_args.layers ) );
// Use the LCD_layerStackExact_capability to set the LCD using the determined stack
// Construct argument set for capability
stack_args.numArgs = macroLayerIndexStackSize;
for ( uint16_t layer = 1; layer <= macroLayerIndexStackSize; layer++ )
{
stack_args.layers[ layer - 1 ] = macroLayerIndexStack[ macroLayerIndexStackSize - layer ];
}
// Only deal with the interconnect if it has been compiled in
#if defined(ConnectEnabled_define)
if ( Connect_master )
{
// generatedKeymap.h
extern const Capability CapabilitiesList[];
// Broadcast layerStackExact remote capability (0xFF is the broadcast id)
Connect_send_RemoteCapability(
0xFF,
LCD_layerStackExact_capability_index,
state,
stateType,
CapabilitiesList[ LCD_layerStackExact_capability_index ].argCount,
(uint8_t*)&stack_args
);
}
#endif
// Call LCD_layerStackExact directly
LCD_layerStackExact_capability( state, stateType, (uint8_t*)&stack_args );
}
// ----- CLI Command Functions -----
void cliFunc_lcdInit( char* args )
{
print( NL ); // No \r\n by default after the command is entered
LCD_initialize();
}
void cliFunc_lcdTest( char* args )
{
// Write default image
print( NL ); // No \r\n by default after the command is entered
//LCD_initialize();
// Test pattern
uint8_t pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t logo[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//uint8_t pattern[] = { 0xFF, 0x00, 0x96, 0xFF, 0x00, 0xFF, 0x00 };
// Write to page D0
//LCD_writeDisplayReg( 0, pattern, sizeof( pattern ) );
for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ )
LCD_writeDisplayReg( page, (uint8_t *)&STLcdDefaultImage[page * LCD_PAGE_LEN], LCD_PAGE_LEN );
{
LCD_writeDisplayReg( page, &logo[page * LCD_PAGE_LEN], LCD_PAGE_LEN );
}
}
void cliFunc_lcdCmd( char* args )
@ -574,79 +354,3 @@ cmd:
LCD_writeControlReg( cmd );
}
void cliFunc_lcdColor( char* args )
{
char* curArgs;
char* arg1Ptr;
char* arg2Ptr = args;
// Colors
uint16_t rgb[3]; // Red, Green, Blue
// Parse integers from 3 arguments
for ( uint8_t color = 0; color < 3; color++ )
{
curArgs = arg2Ptr;
CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
// Give up if not enough args given
if ( *arg1Ptr == '\0' )
return;
// Convert argument to integer
rgb[ color ] = numToInt( arg1Ptr );
}
// Set PWM channels
FTM0_C0V = rgb[0];
FTM0_C1V = rgb[1];
FTM0_C2V = rgb[2];
}
void cliFunc_lcdDisp( char* args )
{
char* curArgs;
char* arg1Ptr;
char* arg2Ptr = args;
// First process page and starting address
curArgs = arg2Ptr;
CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
// Stop processing args if no more are found
if ( *arg1Ptr == '\0' )
return;
uint8_t page = numToInt( arg1Ptr );
curArgs = arg2Ptr;
CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
// Stop processing args if no more are found
if ( *arg1Ptr == '\0' )
return;
uint8_t address = numToInt( arg1Ptr );
// Set the register page
LCD_writeControlReg( 0xB0 | ( 0x0F & page ) );
// Set starting address
LCD_writeControlReg( 0x10 | ( ( 0xF0 & address ) >> 4 ) );
LCD_writeControlReg( 0x00 | ( 0x0F & address ));
// Process all args
for ( ;; )
{
curArgs = arg2Ptr;
CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
// Stop processing args if no more are found
if ( *arg1Ptr == '\0' )
break;
uint8_t value = numToInt( arg1Ptr );
// Write buffer to SPI
SPI_write( &value, 1 );
}
}

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2015-2016 by Jacob Alexander
/* Copyright (C) 2015 by Jacob Alexander
*
* This file is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -28,5 +28,3 @@
void LCD_setup();
uint8_t LCD_scan();
void LCD_currentChange( unsigned int current );

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Some files were not shown because too many files have changed in this diff Show more