@@ -20,10 +20,26 @@ | |||
#| You _MUST_ clean the build directory if you change this value | |||
#| | |||
set( CHIP | |||
"mk20dx128vlf5" # McHCK mk20dx128vlf5 | |||
"mk20dx128vlf5" # McHCK mk20dx128vlf5 | |||
# "mk20dx256vlh7" # Kiibohd-dfu mk20dx256vlh7 | |||
) | |||
### | |||
# Compiler Selection | |||
# | |||
#| *** 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" ) | |||
### | |||
# Bootloader Configuration | |||
# |
@@ -0,0 +1,18 @@ | |||
#!/bin/bash | |||
# Just in case there was an extra ledTest.bash (don't care if error) | |||
rm /dev/ttyACM0 | |||
./swdLoad.bash kiibohd_manufacturing_2014-11-16.bin 0 | |||
echo "Press CTRL+C to Continue" | |||
while true; do | |||
sleep 1 | |||
if [ -e /dev/ttyACM0 ]; then | |||
./ledTest.bash | |||
fi | |||
done | |||
exit 0 | |||
@@ -0,0 +1,6 @@ | |||
#!/bin/bash | |||
printf "led\r" > /dev/ttyACM0 | |||
exit 0 | |||
@@ -68,7 +68,6 @@ int flash_erase_sector(uintptr_t addr) | |||
int flash_program_section(uintptr_t addr, size_t num_words) | |||
{ | |||
GPIOA_PSOR |= (1<<19); | |||
FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION; | |||
FTFL.fccob.program_section.addr = addr; | |||
FTFL.fccob.program_section.num_words = num_words; |
@@ -1,5 +1,5 @@ | |||
/* Copyright (c) 2011,2012 Simon Schubert <[email protected]>. | |||
* Modifications by Jacob Alexander 2014 <[email protected]> | |||
* Modifications by Jacob Alexander 2014-2015 <[email protected]> | |||
* | |||
* 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 | |||
@@ -15,8 +15,9 @@ | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
// ----- Local Includes ----- | |||
// ----- Includes ----- | |||
// Local Includes | |||
#include "mchck.h" | |||
#include "dfu.desc.h" | |||
@@ -79,12 +80,24 @@ void init_usb_bootloader( int config ) | |||
void main() | |||
{ | |||
#if defined(_mk20dx128vlf5_) // Kiibohd-dfu / Infinity | |||
// XXX McHCK uses B16 instead of A19 | |||
// Enabling LED to indicate we are in the bootloader | |||
GPIOA_PDDR |= (1<<19); | |||
// Setup pin - A19 - See Lib/pin_map.mchck for more details on pins | |||
PORTA_PCR19 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); | |||
GPIOA_PSOR |= (1<<19); | |||
#elif defined(_mk20dx256vlh7_) // Kiibohd-dfu | |||
// Enabling LED to indicate we are in the bootloader | |||
GPIOA_PDDR |= (1<<5); | |||
// Setup pin - A5 - See Lib/pin_map.mchck for more details on pins | |||
PORTA_PCR19 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); | |||
GPIOA_PSOR |= (1<<5); | |||
#endif | |||
flash_prepare_flashing(); | |||
usb_init( &dfu_device ); |
@@ -22,12 +22,27 @@ set( CHIP | |||
# "at90usb646" # Teensy++ 1.0 (avr) | |||
# "at90usb1286" # Teensy++ 2.0 (avr) | |||
# "mk20dx128" # Teensy 3.0 (arm) | |||
"mk20dx128vlf5" # McHCK mk20dx128vlf5 | |||
"mk20dx128vlf5" # McHCK mk20dx128vlf5 | |||
# "mk20dx256" # Teensy 3.1 (arm) | |||
# "mk20dx256vlh7" # Kiibohd-dfu mk20dx256vlh7 | |||
CACHE STRING "Microcontroller Chip" ) | |||
### | |||
# Compiler Selection | |||
# | |||
#| *** 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" ) | |||
### | |||
# Compiler Intialization | |||
# |
@@ -1,6 +1,6 @@ | |||
###| CMake Kiibohd Controller Debug Module |### | |||
# | |||
# Written by Jacob Alexander in 2014 for the Kiibohd Controller | |||
# Written by Jacob Alexander in 2014-2015 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
@@ -11,31 +11,15 @@ | |||
# Module C files | |||
# | |||
set( DEBUG_SRCS | |||
set ( Module_SRCS | |||
cli.c | |||
) | |||
### | |||
# Setup File Dependencies | |||
# | |||
### | |||
# Module Specific Options | |||
# | |||
### | |||
# Just in case, you only want this module and are using others as well | |||
# | |||
add_definitions( -I${HEAD_DIR}/Debug/off ) | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( DebugModuleCompatibility | |||
set ( ModuleCompatibility | |||
arm | |||
avr | |||
) |
@@ -1,6 +1,6 @@ | |||
###| CMake Kiibohd Controller Debug Module |### | |||
# | |||
# Written by Jacob Alexander in 2011-2014 for the Kiibohd Controller | |||
# Written by Jacob Alexander in 2011-2015 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
@@ -8,31 +8,18 @@ | |||
### | |||
# Module C files | |||
# Required Submodules | |||
# | |||
#| XXX Requires the ../ due to how the paths are constructed | |||
set( DEBUG_SRCS | |||
../cli/cli.c | |||
../led/led.c | |||
../print/print.c | |||
) | |||
### | |||
# Module Specific Options | |||
# | |||
add_definitions( | |||
-I${HEAD_DIR}/Debug/cli | |||
-I${HEAD_DIR}/Debug/led | |||
-I${HEAD_DIR}/Debug/print | |||
) | |||
AddModule ( Debug cli ) | |||
AddModule ( Debug led ) | |||
AddModule ( Debug print ) | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( DebugModuleCompatibility | |||
set ( ModuleCompatibility | |||
arm | |||
avr | |||
) |
@@ -50,7 +50,7 @@ inline void init_errorLED() | |||
// Setup pin - Pin 13 -> C5 - See Lib/pin_map.teensy3 for more details on pins | |||
PORTC_PCR5 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); | |||
// MCHCK | |||
// MCHCK / Kiibohd-dfu | |||
#elif defined(_mk20dx128vlf5_) | |||
/* Actual MCHCK | |||
@@ -67,6 +67,14 @@ inline void init_errorLED() | |||
// Setup pin - A19 - See Lib/pin_map.mchck for more details on pins | |||
PORTA_PCR19 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); | |||
// Kiibohd-dfu | |||
#elif defined(_mk20dx256vlh7_) | |||
// Kiibohd-dfu | |||
// Enable pin | |||
GPIOA_PDDR |= (1<<5); | |||
// 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); | |||
#endif | |||
} | |||
@@ -120,6 +128,18 @@ inline void errorLED( uint8_t on ) | |||
GPIOA_PCOR |= (1<<19); | |||
} | |||
// Kiibohd-dfu | |||
#elif defined(_mk20dx256vlh7_) | |||
// Kiibohd-dfu | |||
// Error LED On (A5) | |||
if ( on ) { | |||
GPIOA_PSOR |= (1<<5); | |||
} | |||
// Error LED Off | |||
else { | |||
GPIOA_PCOR |= (1<<5); | |||
} | |||
#endif | |||
} | |||
@@ -1,6 +1,6 @@ | |||
###| CMake Kiibohd Controller Debug Module |### | |||
# | |||
# Written by Jacob Alexander in 2011,2014 for the Kiibohd Controller | |||
# Written by Jacob Alexander in 2011-2015 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
@@ -11,26 +11,15 @@ | |||
# Module C files | |||
# | |||
set( DEBUG_SRCS | |||
set ( Module_SRCS | |||
led.c | |||
) | |||
### | |||
# Module Specific Options | |||
# | |||
### | |||
# Just in case, you only want this module and are using others as well | |||
# | |||
add_definitions( -I${HEAD_DIR}/Debug/off ) | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( DebugModuleCompatibility | |||
set ( ModuleCompatibility | |||
arm | |||
avr | |||
) |
@@ -1,28 +0,0 @@ | |||
###| CMake Kiibohd Controller Debug Module |### | |||
# | |||
# Written by Jacob Alexander in 2011 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
### | |||
### | |||
# Module C files | |||
# | |||
#| None! | |||
### | |||
# Module Specific Options | |||
# | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( DebugModuleCompatibility | |||
arm | |||
avr | |||
) | |||
@@ -1,6 +1,6 @@ | |||
###| CMake Kiibohd Controller Debug Module |### | |||
# | |||
# Written by Jacob Alexander in 2011,2014 for the Kiibohd Controller | |||
# Written by Jacob Alexander in 2011-2015 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
@@ -11,26 +11,15 @@ | |||
# Module C files | |||
# | |||
set( DEBUG_SRCS | |||
set ( Module_SRCS | |||
print.c | |||
) | |||
### | |||
# Module Specific Options | |||
# | |||
### | |||
# Just in case, you only want this module and are using others as well | |||
# | |||
add_definitions( -I${HEAD_DIR}/Debug/off ) | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( DebugModuleCompatibility | |||
set ( ModuleCompatibility | |||
arm | |||
avr | |||
) |
@@ -13,9 +13,20 @@ | |||
#| Set the Compilers (must be set first) | |||
include( CMakeForceCompiler ) | |||
cmake_force_c_compiler ( arm-none-eabi-gcc ARMCCompiler ) | |||
cmake_force_cxx_compiler( arm-none-eabi-g++ ARMCxxCompiler ) | |||
set( _CMAKE_TOOLCHAIN_PREFIX arm-none-eabi- ) | |||
message( STATUS "Compiler Selected:" ) | |||
if ( "${COMPILER}" MATCHES "gcc" ) | |||
cmake_force_c_compiler ( arm-none-eabi-gcc ARMCCompiler ) | |||
cmake_force_cxx_compiler( arm-none-eabi-g++ ARMCxxCompiler ) | |||
set( _CMAKE_TOOLCHAIN_PREFIX arm-none-eabi- ) | |||
message( "gcc" ) | |||
elseif ( "${COMPILER}" MATCHES "clang" ) | |||
cmake_force_c_compiler ( clang ARMCCompiler ) | |||
cmake_force_cxx_compiler( clang++ ARMCxxCompiler ) | |||
set( _CMAKE_TOOLCHAIN_PREFIX llvm- ) | |||
message( "clang" ) | |||
else () | |||
message( AUTHOR_WARNING "COMPILER: ${COMPILER} - Unknown compiler selection" ) | |||
endif () | |||
@@ -25,7 +36,9 @@ set( _CMAKE_TOOLCHAIN_PREFIX arm-none-eabi- ) | |||
#| Chip Name (Linker) | |||
#| | |||
#| "mk20dx128" # Teensy 3.0 and McHCK mk20dx128 | |||
#| "mk20dx128vlf5" # McHCK / Kiibohd-dfu | |||
#| "mk20dx256vlh7" # Kiibohd-dfu | |||
#| "mk20dx128" # Teensy 3.0 | |||
#| "mk20dx256" # Teensy 3.1 | |||
message( STATUS "Chip Selected:" ) | |||
@@ -34,11 +47,16 @@ set( MCU "${CHIP}" ) # For loading script compatibility | |||
#| Chip Size Database | |||
#| MCHCK Based | |||
#| MCHCK Based / Kiibohd-dfu | |||
if ( "${CHIP}" MATCHES "mk20dx128vlf5" ) | |||
set( SIZE_RAM 16384 ) | |||
set( SIZE_FLASH 126976 ) | |||
#| Kiibohd-dfu | |||
elseif ( "${CHIP}" MATCHES "mk20dx256vlh7" ) | |||
set( SIZE_RAM 65536 ) | |||
set( SIZE_FLASH 253952 ) | |||
#| Teensy 3.0 | |||
elseif ( "${CHIP}" MATCHES "mk20dx128" ) | |||
set( SIZE_RAM 16384 ) | |||
@@ -89,18 +107,21 @@ message( "${COMPILER_SRCS}" ) | |||
#| USB Defines, this is how the loader programs detect which type of chip base is used | |||
if ( "${CHIP}" MATCHES "mk20dx128vlf5" ) | |||
message( STATUS "Bootloader Type:" ) | |||
if ( "${CHIP}" MATCHES "mk20dx128vlf5" OR "${CHIP}" MATCHES "mk20dx256vlh7" ) | |||
set( VENDOR_ID "0x1C11" ) | |||
set( PRODUCT_ID "0xB04D" ) | |||
set( BOOT_VENDOR_ID "0x1C11" ) | |||
set( BOOT_PRODUCT_ID "0xB007" ) | |||
set( DFU 1 ) | |||
message( "dfu" ) | |||
elseif ( "${CHIP}" MATCHES "mk20dx128" OR "${CHIP}" MATCHES "mk20dx256" ) | |||
set( VENDOR_ID "0x1C11" ) | |||
set( PRODUCT_ID "0xB04D" ) | |||
set( BOOT_VENDOR_ID "0x16c0" ) # TODO Double check, this is likely incorrect | |||
set( BOOT_PRODUCT_ID "0x0487" ) | |||
set( TEENSY 1 ) | |||
message( "Teensy" ) | |||
endif () | |||
@@ -124,6 +145,8 @@ set( WARN "-Wall -ggdb3" ) | |||
if( BOOTLOADER ) | |||
set( TUNING "-D_bootloader_ -Wno-main -msoft-float -mthumb -fplan9-extensions -ffunction-sections -fdata-sections -fno-builtin -fstrict-volatile-bitfields -flto -fno-use-linker-plugin -nostdlib" ) | |||
#set( TUNING "-mthumb -fdata-sections -ffunction-sections -fno-builtin -msoft-float -fstrict-volatile-bitfields -flto -fno-use-linker-plugin -fwhole-program -Wno-main -nostartfiles -fplan9-extensions -D_bootloader_" ) | |||
elseif ( "${COMPILER}" MATCHES "clang" ) | |||
set( TUNING "-target arm-none-eabi -mthumb -nostdlib -fdata-sections -ffunction-sections -fshort-wchar -fno-builtin" ) | |||
else() | |||
set( TUNING "-mthumb -nostdlib -fdata-sections -ffunction-sections -fshort-wchar -fno-builtin -nostartfiles" ) | |||
endif() | |||
@@ -171,5 +194,9 @@ set( BIN_FLAGS -O binary ) | |||
#| Lss Flags | |||
set( LSS_FLAGS -h -S -z ) | |||
if ( "${COMPILER}" MATCHES "clang" ) | |||
set( LSS_FLAGS -section-headers -triple=arm-none-eabi ) | |||
else () | |||
set( LSS_FLAGS -h -S -z ) | |||
endif () | |||
@@ -36,10 +36,6 @@ message( STATUS "MCU Selected:" ) | |||
message( "${MCU}" ) | |||
#| Indicate to later build step that this is a Teensy | |||
set( Teensy ) | |||
#| Chip Size Database | |||
#| Teensy 1.0 | |||
if ( "${CHIP}" MATCHES "at90usb162" ) | |||
@@ -67,10 +63,6 @@ else () | |||
endif () | |||
#| Only Teensy based AVRs supported | |||
set ( TEENSY 1 ) | |||
#| Extra Compiler Sources | |||
#| Mostly for convenience functions like interrupt handlers | |||
set( COMPILER_SRCS | |||
@@ -94,6 +86,12 @@ set( BOOT_VENDOR_ID "0x16C0" ) # TODO Double check, this is likely incorrect | |||
set( BOOT_PRODUCT_ID "0x047D" ) | |||
#| Only Teensy based AVRs supported | |||
set ( TEENSY 1 ) | |||
message( STATUS "Bootloader Type:" ) | |||
message( "Teensy" ) | |||
#| Compiler flag to set the C Standard level. | |||
#| c89 = "ANSI" C | |||
#| gnu89 = c89 plus GCC extensions |
@@ -33,22 +33,33 @@ set_target_properties( ${TARGET_ELF} PROPERTIES | |||
SUFFIX "" # XXX Force Windows to keep the .exe off | |||
) | |||
#| llvm-clang does not have an objcopy equivalent | |||
if ( "${COMPILER}" MATCHES "clang" ) | |||
if ( "${COMPILER_FAMILY}" MATCHES "arm" ) | |||
set ( OBJ_COPY arm-none-eabi-objcopy ) | |||
elseif ( "${COMPILER_FAMILY}" MATCHES "arm" ) | |||
set ( OBJ_COPY avr-objcopy ) | |||
endif () | |||
else () | |||
set ( OBJ_COPY ${CMAKE_OBJCOPY} ) | |||
endif () | |||
#| Convert the .ELF into a .bin to load onto the McHCK | |||
if( DEFINED DFU ) | |||
if ( DEFINED DFU ) | |||
set( TARGET_BIN ${TARGET}.dfu.bin ) | |||
add_custom_command( TARGET ${TARGET_ELF} POST_BUILD | |||
COMMAND ${CMAKE_OBJCOPY} ${BIN_FLAGS} ${TARGET_ELF} ${TARGET_BIN} | |||
COMMAND ${OBJ_COPY} ${BIN_FLAGS} ${TARGET_ELF} ${TARGET_BIN} | |||
COMMENT "Creating dfu binary file: ${TARGET_BIN}" | |||
) | |||
endif() | |||
endif () | |||
#| Convert the .ELF into a .HEX to load onto the Teensy | |||
if ( DEFINED TEENSY ) | |||
set( TARGET_HEX ${TARGET}.teensy.hex ) | |||
add_custom_command( TARGET ${TARGET_ELF} POST_BUILD | |||
COMMAND ${CMAKE_OBJCOPY} ${HEX_FLAGS} ${TARGET_ELF} ${TARGET_HEX} | |||
COMMAND ${OBJ_COPY} ${HEX_FLAGS} ${TARGET_ELF} ${TARGET_HEX} | |||
COMMENT "Creating iHex file to load: ${TARGET_HEX}" | |||
) | |||
endif() |
@@ -20,6 +20,8 @@ if ( "${MacroModule}" STREQUAL "PartialMap" ) | |||
# | |||
if ( NOT EXISTS "${PROJECT_SOURCE_DIR}/kll/kll.py" ) | |||
message ( STATUS "Downloading latest kll version:" ) | |||
# Make sure git is available | |||
find_package ( Git REQUIRED ) | |||
@@ -27,7 +29,9 @@ if ( NOT EXISTS "${PROJECT_SOURCE_DIR}/kll/kll.py" ) | |||
execute_process ( COMMAND ${GIT_EXECUTABLE} clone https://github.com/kiibohd/kll.git | |||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} | |||
) | |||
else () # Otherwise attempt to update the repo | |||
elseif ( REFRESH_KLL ) # Otherwise attempt to update the repo | |||
message ( STATUS "Checking for latest kll version:" ) | |||
# Clone kll git repo | |||
execute_process ( COMMAND ${GIT_EXECUTABLE} pull --rebase | |||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/kll |
@@ -24,6 +24,7 @@ endif () | |||
### | |||
# Path Setup | |||
# | |||
@@ -41,36 +42,16 @@ set( HEAD_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ) | |||
# Module Check Function | |||
# | |||
#| Usage: | |||
#| PathPrepend( ModulePath <ListOfFamiliesSupported> ) | |||
#| Uses the ${COMPILER_FAMILY} variable | |||
function( ModuleCompatibility ModulePath ) | |||
foreach( mod_var ${ARGN} ) | |||
function ( ModuleCompatibility ModulePath ) | |||
foreach ( mod_var ${ARGN} ) | |||
if ( ${mod_var} STREQUAL ${COMPILER_FAMILY} ) | |||
# Module found, no need to scan further | |||
return() | |||
endif () | |||
endforeach() | |||
message( FATAL_ERROR "${ModulePath} does not support the ${COMPILER_FAMILY} family..." ) | |||
endfunction() | |||
### | |||
# Module Configuration | |||
# | |||
endforeach () | |||
#| Additional options, usually define settings | |||
add_definitions() | |||
#| Include path for each of the modules | |||
add_definitions( | |||
-I${HEAD_DIR}/${ScanModulePath} | |||
-I${HEAD_DIR}/${MacroModulePath} | |||
-I${HEAD_DIR}/${OutputModulePath} | |||
-I${HEAD_DIR}/${DebugModulePath} | |||
) | |||
message ( FATAL_ERROR "${ModulePath} does not support the ${COMPILER_FAMILY} family..." ) | |||
endfunction () | |||
@@ -81,54 +62,86 @@ add_definitions( | |||
#| Go through lists of sources and append paths | |||
#| Usage: | |||
#| PathPrepend( OutputListOfSources <Prepend Path> <InputListOfSources> ) | |||
macro( PathPrepend Output SourcesPath ) | |||
unset( tmpSource ) | |||
macro ( PathPrepend Output SourcesPath ) | |||
unset ( tmpSource ) | |||
# Loop through items | |||
foreach( item ${ARGN} ) | |||
foreach ( item ${ARGN} ) | |||
# Set the path | |||
set( tmpSource ${tmpSource} "${SourcesPath}/${item}" ) | |||
endforeach() | |||
set ( tmpSource ${tmpSource} "${SourcesPath}/${item}" ) | |||
endforeach () | |||
# Finalize by writing the new list back over the old one | |||
set( ${Output} ${tmpSource} ) | |||
endmacro() | |||
set ( ${Output} ${tmpSource} ) | |||
endmacro () | |||
#| Scan Module | |||
include ( "${ScanModulePath}/setup.cmake" ) | |||
PathPrepend( SCAN_SRCS ${ScanModulePath} ${SCAN_SRCS} ) | |||
#| Macro Module | |||
include ( "${MacroModulePath}/setup.cmake" ) | |||
PathPrepend( MACRO_SRCS ${MacroModulePath} ${MACRO_SRCS} ) | |||
### | |||
# Add Module Macro | |||
# | |||
# Optional Arg 1: Main Module Check, set to True/1 if adding a main module | |||
function ( AddModule ModuleType ModuleName ) | |||
# Module path | |||
set ( ModulePath ${ModuleType}/${ModuleName} ) | |||
set ( ModuleFullPath ${HEAD_DIR}/${ModuleType}/${ModuleName} ) | |||
# Include setup.cmake file | |||
include ( ${ModuleFullPath}/setup.cmake ) | |||
# Check if this is a main module add | |||
foreach ( extraArg ${ARGN} ) | |||
# Make sure this isn't a submodule | |||
if ( DEFINED SubModule ) | |||
message ( FATAL_ERROR | |||
"The '${ModuleName}' module is not a stand-alone module, and requires further setup." | |||
) | |||
endif () | |||
endforeach () | |||
# PathPrepend to give proper paths to each of the source files | |||
PathPrepend ( Module_SRCS ${ModulePath} ${Module_SRCS} ) | |||
# Check the current scope to see if a sub-module added some source files | |||
set ( Module_SRCS ${${ModuleType}_SRCS} ${Module_SRCS} ) | |||
# Append each of the sources to each type of module srcs list | |||
set ( ${ModuleType}_SRCS ${Module_SRCS} ) | |||
#| Output Module | |||
include ( "${OutputModulePath}/setup.cmake" ) | |||
PathPrepend( OUTPUT_SRCS ${OutputModulePath} ${OUTPUT_SRCS} ) | |||
# Add .h files | |||
add_definitions ( -I${ModuleFullPath} ) | |||
# Check module compatibility | |||
ModuleCompatibility( ${ModulePath} ${ModuleCompatibility} ) | |||
# Check if this is a main module add | |||
foreach ( extraArg ${ARGN} ) | |||
# Display detected source files | |||
if ( NOT DEFINED SubModule ) | |||
message ( STATUS "Detected ${ModuleType} Module Source Files:" ) | |||
message ( "${${ModuleType}_SRCS}" ) | |||
endif () | |||
endforeach () | |||
#| Debugging Module | |||
include ( "${DebugModulePath}/setup.cmake" ) | |||
PathPrepend( DEBUG_SRCS ${DebugModulePath} ${DEBUG_SRCS} ) | |||
# Finally, add the sources to the parent scope (i.e. return) | |||
set ( ${ModuleType}_SRCS ${${ModuleType}_SRCS} PARENT_SCOPE ) | |||
endfunction () | |||
#| Print list of all module sources | |||
message( STATUS "Detected Scan Module Source Files:" ) | |||
message( "${SCAN_SRCS}" ) | |||
message( STATUS "Detected Macro Module Source Files:" ) | |||
message( "${MACRO_SRCS}" ) | |||
message( STATUS "Detected Output Module Source Files:" ) | |||
message( "${OUTPUT_SRCS}" ) | |||
message( STATUS "Detected Debug Module Source Files:" ) | |||
message( "${DEBUG_SRCS}" ) | |||
#| Add main modules | |||
AddModule ( Scan ${ScanModule} 1 ) | |||
AddModule ( Macro ${MacroModule} 1 ) | |||
AddModule ( Output ${OutputModule} 1 ) | |||
AddModule ( Debug ${DebugModule} 1 ) | |||
### | |||
# CMake Module Checking | |||
# | |||
find_package( Git REQUIRED ) | |||
find_package( Ctags ) # Optional | |||
find_package ( Git REQUIRED ) | |||
find_package ( Ctags ) # Optional | |||
@@ -220,10 +233,10 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Lib/_buildvars.h buildvars.h ) | |||
set( SRCS | |||
${MAIN_SRCS} | |||
${COMPILER_SRCS} | |||
${SCAN_SRCS} | |||
${MACRO_SRCS} | |||
${OUTPUT_SRCS} | |||
${DEBUG_SRCS} | |||
${Scan_SRCS} | |||
${Macro_SRCS} | |||
${Output_SRCS} | |||
${Debug_SRCS} | |||
) | |||
#| Directories to include by default | |||
@@ -231,18 +244,6 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) | |||
### | |||
# Module Compatibility Check | |||
# | |||
#| Check for whether the set modules are compatible with the specified compiler family | |||
ModuleCompatibility( ${ScanModulePath} ${ScanModuleCompatibility} ) | |||
ModuleCompatibility( ${MacroModulePath} ${MacroModuleCompatibility} ) | |||
ModuleCompatibility( ${OutputModulePath} ${OutputModuleCompatibility} ) | |||
ModuleCompatibility( ${DebugModulePath} ${DebugModuleCompatibility} ) | |||
### | |||
# ctag Generation | |||
# |
@@ -29,7 +29,7 @@ | |||
#define __INTERRUPTS_H | |||
// ARM | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
#include <Lib/mk20dx.h> | |||
@@ -45,7 +45,7 @@ | |||
// ----- Defines ----- | |||
// ARM | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
// Map the Interrupt Enable/Disable to the AVR names | |||
#define cli() __disable_irq() |
@@ -34,7 +34,7 @@ | |||
// ARM | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
#include <Lib/mk20dx.h> | |||
#include <Lib/delay.h> |
@@ -34,7 +34,7 @@ | |||
// ARM | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
#include <Lib/mk20dx.h> | |||
@@ -30,7 +30,7 @@ | |||
// ----- Includes ----- | |||
// ARM | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
#include <Lib/mk20dx.h> | |||
#include <Lib/delay.h> |
@@ -34,7 +34,7 @@ | |||
// ARM | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
#include <Lib/mk20dx.h> | |||
#include <Lib/delay.h> |
@@ -1,7 +1,7 @@ | |||
/* Teensyduino Core Library | |||
* http://www.pjrc.com/teensy/ | |||
* Copyright (c) 2013 PJRC.COM, LLC. | |||
* Modifications by Jacob Alexander 2014 | |||
* Modifications by Jacob Alexander 2014-2015 | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
@@ -29,6 +29,8 @@ | |||
* SOFTWARE. | |||
*/ | |||
// ----- Includes ----- | |||
// Local Includes | |||
#include "mk20dx.h" | |||
@@ -246,7 +248,7 @@ void (* const gVectors[])() = | |||
portd_isr, // 59 Pin detect (Port D) | |||
porte_isr, // 60 Pin detect (Port E) | |||
software_isr, // 61 Software interrupt | |||
#elif defined(_mk20dx256_) | |||
#elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
dma_ch0_isr, // 16 DMA channel 0 transfer complete | |||
dma_ch1_isr, // 17 DMA channel 1 transfer complete | |||
dma_ch2_isr, // 18 DMA channel 2 transfer complete | |||
@@ -377,12 +379,34 @@ const uint8_t flashconfigbytes[16] = { | |||
0xFF, // EEPROM Protection Byte FEPROT | |||
0xFF, // Data Flash Protection Byte FDPROT | |||
}; | |||
#elif defined(_mk20dx256vlh7_) && defined(_bootloader_) | |||
// XXX Byte labels may be in incorrect positions, double check before modifying | |||
// FSEC is in correct location -Jacob | |||
__attribute__ ((section(".flashconfig"), used)) | |||
const uint8_t flashconfigbytes[16] = { | |||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Backdoor Verif Key 28.3.1 | |||
// | |||
// Protecting the first 8k of Flash memory from being over-written while running (bootloader protection) | |||
// Still possible to overwrite the bootloader using an external flashing device | |||
// For more details see: | |||
// http://cache.freescale.com/files/training/doc/dwf/AMF_ENT_T1031_Boston.pdf (page 8) | |||
// http://cache.freescale.com/files/microcontrollers/doc/app_note/AN4507.pdf | |||
// http://cache.freescale.com/files/32bit/doc/ref_manual/K20P64M72SF1RM.pdf (28.34.6) | |||
// | |||
0xFF, 0xFF, 0xFF, 0xFE, // Program Flash Protection Bytes FPROT0-3 | |||
0xBE, // Flash security byte FSEC | |||
0x03, // Flash nonvolatile option byte FOPT | |||
0xFF, // EEPROM Protection Byte FEPROT | |||
0xFF, // Data Flash Protection Byte FDPROT | |||
#endif | |||
// ----- Functions ----- | |||
#if ( defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_) ) && defined(_bootloader_) // Bootloader Section | |||
__attribute__((noreturn)) | |||
static inline void jump_to_app( uintptr_t addr ) | |||
{ | |||
@@ -393,6 +417,7 @@ static inline void jump_to_app( uintptr_t addr ) | |||
// NOTREACHED | |||
__builtin_unreachable(); | |||
} | |||
#endif | |||
void *memset( void *addr, int val, unsigned int len ) | |||
{ | |||
@@ -430,18 +455,20 @@ void *memcpy( void *dst, const void *src, unsigned int len ) | |||
__attribute__ ((section(".startup"))) | |||
void ResetHandler() | |||
{ | |||
// Disable Watchdog | |||
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; | |||
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; | |||
WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE; | |||
#if defined(_mk20dx128vlf5_) && defined(_bootloader_) // Bootloader Section | |||
#if ( defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_) ) && defined(_bootloader_) // Bootloader Section | |||
extern uint32_t _app_rom; | |||
// We treat _app_rom as pointer to directly read the stack | |||
// pointer and check for valid app code. This is no fool | |||
// proof method, but it should help for the first flash. | |||
if ( RCM_SRS0 & 0x40 || _app_rom == 0xffffffff || | |||
// | |||
// Purposefully disabling the watchdog *after* the reset check this way | |||
// if the chip goes into an odd state we'll reset to the bootloader (invalid firmware image) | |||
// RCM_SRS0 & 0x20 | |||
// | |||
// Also checking for ARM lock-up signal (invalid firmware image) | |||
// RCM_SRS1 & 0x02 | |||
if ( RCM_SRS0 & 0x40 || RCM_SRS0 & 0x20 || RCM_SRS1 & 0x02 || _app_rom == 0xffffffff || | |||
memcmp( (uint8_t*)&VBAT, sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic) ) == 0 ) // Check for soft reload | |||
{ | |||
memset( (uint8_t*)&VBAT, 0, sizeof(VBAT) ); | |||
@@ -453,9 +480,13 @@ void ResetHandler() | |||
jump_to_app( addr ); | |||
} | |||
#endif | |||
// Disable Watchdog | |||
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; | |||
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; | |||
WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE; | |||
uint32_t *src = &_etext; | |||
uint32_t *dest = &_sdata; | |||
uint32_t *src = (uint32_t*)&_etext; | |||
uint32_t *dest = (uint32_t*)&_sdata; | |||
// Enable clocks to always-used peripherals | |||
SIM_SCGC5 = 0x00043F82; // Clocks active to all GPIO | |||
@@ -483,11 +514,11 @@ void ResetHandler() | |||
} | |||
// Prepare RAM | |||
while ( dest < &_edata ) *dest++ = *src++; | |||
dest = &_sbss; | |||
while ( dest < &_ebss ) *dest++ = 0; | |||
while ( dest < (uint32_t*)&_edata ) *dest++ = *src++; | |||
dest = (uint32_t*)&_sbss; | |||
while ( dest < (uint32_t*)&_ebss ) *dest++ = 0; | |||
// MCHCK | |||
// MCHCK / Kiibohd-dfu | |||
#if defined(_mk20dx128vlf5_) | |||
// Default all interrupts to medium priority level | |||
for ( unsigned int i = 0; i < NVIC_NUM_INTERRUPTS; i++ ) | |||
@@ -501,14 +532,12 @@ void ResetHandler() | |||
// USB Clock and FLL select | |||
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_TRACECLKSEL; | |||
// Teensy 3.0 and 3.1 | |||
// Teensy 3.0 and 3.1 and Kiibohd-dfu (mk20dx256vlh7) | |||
#else | |||
unsigned int i; | |||
SCB_VTOR = 0; // use vector table in flash | |||
// default all interrupts to medium priority level | |||
for ( i = 0; i < NVIC_NUM_INTERRUPTS; i++ ) | |||
for ( unsigned int i = 0; i < NVIC_NUM_INTERRUPTS; i++ ) | |||
{ | |||
NVIC_SET_PRIORITY( i, 128 ); | |||
} |
@@ -1847,7 +1847,7 @@ typedef struct { | |||
#define IRQ_SOFTWARE 45 | |||
#define NVIC_NUM_INTERRUPTS 46 | |||
#elif defined(_mk20dx256_) | |||
#elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
#define IRQ_DMA_CH0 0 | |||
#define IRQ_DMA_CH1 1 | |||
#define IRQ_DMA_CH2 2 |
@@ -0,0 +1,114 @@ | |||
/* Teensyduino Core Library | |||
* http://www.pjrc.com/teensy/ | |||
* Copyright (c) 2013 PJRC.COM, LLC. | |||
* Modifications by Jacob Alexander 2014 for use with McHCK and Kiibohd-dfu | |||
* | |||
* 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. | |||
*/ | |||
/* XXX Not tested yet -HaaTa */ | |||
MEMORY | |||
{ | |||
FLASH (rx) : ORIGIN = 0x0, LENGTH = 256K | |||
FLASH_APP (rx) : ORIGIN = 8K, LENGTH = 256K-8K | |||
RAM (rwx) : ORIGIN = 0x20000000 - 64K / 2, LENGTH = 64K | |||
} | |||
/* Starting Address of the application ROM */ | |||
_app_rom = ORIGIN( FLASH_APP ); | |||
FlexRAM = 0x14000000; | |||
FTFL = 0x40020000; | |||
SCB = 0xe000ed00; | |||
USB0 = 0x40072000; | |||
SIM = 0x40047000; | |||
/* Section Definitions */ | |||
SECTIONS | |||
{ | |||
.text : | |||
{ | |||
. = 0; | |||
KEEP(* (.vectors)) | |||
*(.startup*) | |||
*(.rodata*) | |||
. = 0x400; | |||
KEEP(* (.flashconfig)) | |||
*(.text*) | |||
. = ALIGN(4); | |||
KEEP(*(.init)) | |||
} > FLASH | |||
.ARM.exidx : | |||
{ | |||
__exidx_start = .; | |||
*(.ARM.exidx* .gnu.linkonce.armexidx.*) | |||
__exidx_end = .; | |||
} > FLASH | |||
_etext = .; | |||
.usbdescriptortable (NOLOAD) : { | |||
. = ALIGN(512); | |||
*(.usbdescriptortable*) | |||
} > RAM | |||
.dmabuffers (NOLOAD) : { | |||
. = ALIGN(4); | |||
*(.dmabuffers*) | |||
} > RAM | |||
.usbbuffers (NOLOAD) : { | |||
. = ALIGN(4); | |||
*(.usbbuffers*) | |||
} > RAM | |||
.data : AT (_etext) { | |||
. = ALIGN(4); | |||
_sdata = .; | |||
*(SORT_BY_ALIGNMENT(.ramtext.*) SORT_BY_ALIGNMENT(.data*)) | |||
*(.data*) | |||
. = ALIGN(4); | |||
_edata = .; | |||
} > RAM | |||
.noinit (NOLOAD) : { | |||
*(.noinit*) | |||
} > RAM | |||
.bss : { | |||
. = ALIGN(4); | |||
_sbss = .; | |||
*(.bss*) | |||
*(COMMON) | |||
. = ALIGN(4); | |||
_ebss = .; | |||
__bss_end = .; | |||
} > RAM | |||
_estack = ORIGIN(RAM) + LENGTH(RAM); | |||
} | |||
@@ -0,0 +1,101 @@ | |||
/* Teensyduino Core Library | |||
* http://www.pjrc.com/teensy/ | |||
* Copyright (c) 2013 PJRC.COM, LLC. | |||
* Modifications by Jacob Alexander 2014 for use with McHCK and Kiibohd-dfu | |||
* | |||
* 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. | |||
*/ | |||
/* XXX Not tested yet -HaaTa */ | |||
MEMORY | |||
{ | |||
FLASH (rx) : ORIGIN = 8K, LENGTH = 256K-8K | |||
RAM (rwx) : ORIGIN = 0x20000000 - 64K / 2, LENGTH = 64K | |||
} | |||
/* Section Definitions */ | |||
SECTIONS | |||
{ | |||
.text : | |||
{ | |||
. = 0; | |||
KEEP(* (.vectors)) | |||
*(.startup*) | |||
*(.text*) | |||
*(.rodata*) | |||
. = ALIGN(4); | |||
KEEP(*(.init)) | |||
} > FLASH | |||
.ARM.exidx : | |||
{ | |||
__exidx_start = .; | |||
*(.ARM.exidx* .gnu.linkonce.armexidx.*) | |||
__exidx_end = .; | |||
} > FLASH | |||
_etext = .; | |||
.usbdescriptortable (NOLOAD) : { | |||
. = ALIGN(512); | |||
*(.usbdescriptortable*) | |||
} > RAM | |||
.dmabuffers (NOLOAD) : { | |||
. = ALIGN(4); | |||
*(.dmabuffers*) | |||
} > RAM | |||
.usbbuffers (NOLOAD) : { | |||
. = ALIGN(4); | |||
*(.usbbuffers*) | |||
} > RAM | |||
.data : AT (_etext) { | |||
. = ALIGN(4); | |||
_sdata = .; | |||
*(.data*) | |||
. = ALIGN(4); | |||
_edata = .; | |||
} > RAM | |||
.noinit (NOLOAD) : { | |||
*(.noinit*) | |||
} > RAM | |||
.bss : { | |||
. = ALIGN(4); | |||
_sbss = .; | |||
*(.bss*) | |||
*(COMMON) | |||
. = ALIGN(4); | |||
_ebss = .; | |||
__bss_end = .; | |||
} > RAM | |||
_estack = ORIGIN(RAM) + LENGTH(RAM); | |||
} | |||
@@ -1,39 +1,39 @@ | |||
// Pin Name Function Hardware | |||
// Pin Name Function Hardware | |||
// ---------------------------------- | |||
// 0 B16 RX1 | |||
// 1 B17 TX1 | |||
// 2 D0 PCS0 | |||
// 3 A12 FTM1_CH0 PWM (CAN TX - Teensy 3.1) I2S_TXD0 | |||
// 4 A13 FTM1_CH1 PWM (CAN RX - Teensy 3.1) I2S_TX_FS | |||
// 5 D7 FTM0_CH7 PWM | |||
// 6 D4 FTM0_CH4 PWM PCS1 | |||
// 7 D2 RX3 SOUT0 | |||
// 8 D3 TX3 SIN0 | |||
// 9 C3 FTM0_CH2 RX2 PWM PCS1 I2S_TX_BCLK | |||
// 10 C4 FTM0_CH3 TX2 PWM PCS0 | |||
// 11 C6 SOUT0 I2S_RX_BCLK I2S_MCLK | |||
// 12 C7 SIN0 I2S_RX_FS | |||
// 13 C5 LED SCK0 I2S_RXD0 | |||
// 14 D1 SCK0 | |||
// 15 C0 | |||
// 16 B0 (FTM1_CH0) SCL0 | |||
// 17 B1 (FTM1_CH1) SDA0 | |||
// 18 B3 SDA0 | |||
// 19 B2 SCL0 | |||
// 20 D5 FTM0_CH5 PWM PCS2 | |||
// 21 D6 FTM0_CH6 PWM PCS3 | |||
// 22 C1 FTM0_CH0 PWM PCS3 I2S_TXD0 | |||
// 23 C2 FTM0_CH1 PWM PCS2 I2S_TX_FS | |||
// 24 A5 (FTM0_CH2) I2S_TX_BCLK | |||
// 25 B19 (PWM - Teensy 3.1) I2S_TX_FS | |||
// 26 E1 | |||
// 27 C9 I2S_RX_BCLK | |||
// 28 C8 I2S_MCLK | |||
// 29 C10 (SCL1 - Teensy 3.1) I2S_RX_FS | |||
// 30 C11 (SDA1 - Teensy 3.1) I2S_RXD1 | |||
// 31 E0 | |||
// 32 B18 (PWM - Teensy 3.1) I2S_TX_BCLK | |||
// 33 A4 (FTM0_CH1) | |||
// 0 PTB16 RX0 | |||
// 1 PTB17 TX0 | |||
// 2 PTD0 PCS0 | |||
// 3 PTA12 FTM1_CH0 PWM (CAN TX - Teensy 3.1) I2S_TXD0 | |||
// 4 PTA13 FTM1_CH1 PWM (CAN RX - Teensy 3.1) I2S_TX_FS | |||
// 5 PTD7 FTM0_CH7 PWM | |||
// 6 PTD4 FTM0_CH4 PWM PCS1 | |||
// 7 PTD2 RX2 SOUT0 | |||
// 8 PTD3 TX2 SIN0 | |||
// 9 PTC3 FTM0_CH2 RX1 PWM PCS1 I2S_TX_BCLK | |||
// 10 PTC4 FTM0_CH3 TX1 PWM PCS0 | |||
// 11 PTC6 SOUT0 I2S_RX_BCLK I2S_MCLK | |||
// 12 PTC7 SIN0 I2S_RX_FS | |||
// 13 PTC5 LED SCK0 I2S_RXD0 | |||
// 14 PTD1 SCK0 | |||
// 15 PTC0 PCS4 I2S_TXD1 | |||
// 16 PTB0 (FTM1_CH0) SCL0 | |||
// 17 PTB1 (FTM1_CH1) SDA0 | |||
// 18 PTB3 SDA0 | |||
// 19 PTB2 SCL0 | |||
// 20 PTD5 FTM0_CH5 PWM PCS2 | |||
// 21 PTD6 FTM0_CH6 PWM PCS3 | |||
// 22 PTC1 FTM0_CH0 PWM PCS3 I2S_TXD0 | |||
// 23 PTC2 FTM0_CH1 PWM PCS2 I2S_TX_FS | |||
// 24 PTA5 (FTM0_CH2) I2S_TX_BCLK | |||
// 25 PTB19 (PWM - Teensy 3.1) I2S_TX_FS | |||
// 26 PTE1 RX1 SCL1 | |||
// 27 PTC9 I2S_RX_BCLK | |||
// 28 PTC8 I2S_MCLK | |||
// 29 PTC10 (SCL1 - Teensy 3.1) I2S_RX_FS | |||
// 30 PTC11 (SDA1 - Teensy 3.1) I2S_RXD1 | |||
// 31 PTE0 TX1 SDA1 | |||
// 32 PTB18 (PWM - Teensy 3.1) I2S_TX_BCLK | |||
// 33 PTA4 (FTM0_CH1) | |||
// 34 analog only | |||
// 35 analog only | |||
// 36 analog only | |||
@@ -43,13 +43,10 @@ | |||
// 40 DAC/A14 | |||
// not available to user: | |||
// A0 FTM0_CH5 SWD Clock | |||
// A1 FTM0_CH6 USB ID | |||
// A2 FTM0_CH7 SWD Trace | |||
// A3 FTM0_CH0 SWD Data | |||
// misc | |||
C0 PCS4 I2S_TXD1 | |||
// A0 FTM0_CH5 SWD Clock | |||
// A1 FTM0_CH6 USB ID | |||
// A2 FTM0_CH7 SWD Trace | |||
// A3 FTM0_CH0 SWD Data | |||
// Analog Channel Channel | |||
// Pin Pin Name ADC0 ADC1 |
@@ -1,8 +1,67 @@ | |||
#!/bin/bash | |||
# Convenience script for loading firmware onto a dfu type device | |||
# By default, initiates dfu-util | |||
SERIAL_PORT="" | |||
AUTO_SCREEN_SESSION="" | |||
PROG_NAME=$(basename $0) | |||
# Parse all the command line arguments | |||
while (( "$#" >= "1" )); do | |||
# Scan each argument | |||
key="$1" | |||
case $key in | |||
-a|--autoscreen) | |||
AUTO_SCREEN_SESSION="$2" | |||
shift | |||
;; | |||
-f|--fastload) | |||
SERIAL_PORT="$2" | |||
shift | |||
;; | |||
-h|--help) | |||
echo "Usage: $PROG_NAME [options...]" | |||
echo "" | |||
echo "Loads the most recent built firmware (@TARGET_BIN@) to the device." | |||
echo " (load.dfu)" | |||
echo "" | |||
echo "Arguments:" | |||
echo " -a, --autoscreen SERIAL_PORT Use screen on the specified serial port after loading." | |||
echo " e.g. /dev/ttyACM0" | |||
echo " -f, --fastload SERIAL_PORT Send the reload command to the debug terminal." | |||
echo " e.g. /dev/ttyACM0" | |||
echo " NOTE: May not work due to non-functional terminal, or disable remote flashing" | |||
echo " -h, --help This message." | |||
exit 1 | |||
;; | |||
*) | |||
echo "INVALID ARG: '$1'" | |||
exit 2 | |||
;; | |||
esac | |||
# Shift to the next argument | |||
shift | |||
done | |||
# If a SERIAL_PORT was specified set the uC into reflash mode | |||
# XXX May not be successful if uC is not in a good state (or does not allow remote flashing) | |||
if [[ "$SERIAL_PORT" != "" ]] && [[ -e "$SERIAL_PORT" ]]; then | |||
echo "NOTE: This may fail if the uC is in a bad state or does not support remote flashing" | |||
printf "reload\r" > $SERIAL_PORT | |||
sleep 1 | |||
fi | |||
# Load via dfu-util | |||
# Used for McHCK based uCs | |||
dfu-util -D @TARGET_BIN@ | |||
EXIT_STATUS=$? | |||
# Load Screen Session if specified | |||
if (( "$EXIT_STATUS" == "0" )) && [[ "$AUTO_SCREEN_SESSION" != "" ]]; then | |||
sleep 0.1 | |||
screen $AUTO_SCREEN_SESSION | |||
fi | |||
exit $? | |||
exit $EXIT_STATUS | |||
@@ -1,6 +1,50 @@ | |||
#!/bin/bash | |||
# Convenience script for loading firmware onto a teensy type device | |||
# By default, initiates teensy-load-cli | |||
#| First check to see teensy-loader-cli has been compiled | |||
SERIAL_PORT="" | |||
AUTO_SCREEN_SESSION="" | |||
PROG_NAME=$(basename $0) | |||
# Parse all the command line arguments | |||
while (( "$#" >= "1" )); do | |||
# Scan each argument | |||
key="$1" | |||
case $key in | |||
-a|--autoscreen) | |||
AUTO_SCREEN_SESSION="$2" | |||
shift | |||
;; | |||
-f|--fastload) | |||
SERIAL_PORT="$2" | |||
shift | |||
;; | |||
-h|--help) | |||
echo "Usage: $PROG_NAME [options...]" | |||
echo "" | |||
echo "Loads the most recent built firmware (@TARGET_BIN@) to the device." | |||
echo " (load.teensy)" | |||
echo "" | |||
echo "Arguments:" | |||
echo " -a, --autoscreen SERIAL_PORT Use screen on the specified serial port after loading." | |||
echo " e.g. /dev/ttyACM0" | |||
echo " -f, --fastload SERIAL_PORT Send the reload command to the debug terminal." | |||
echo " e.g. /dev/ttyACM0" | |||
echo " NOTE: May not work due to non-functional terminal, or disable remote flashing" | |||
echo " -h, --help This message." | |||
exit 1 | |||
;; | |||
*) | |||
echo "INVALID ARG: '$1'" | |||
exit 2 | |||
;; | |||
esac | |||
# Shift to the next argument | |||
shift | |||
done | |||
# First check to see teensy-loader-cli has been compiled | |||
if [ ! -e teensy-loader-cli/teensy-loader-cli ]; then | |||
# Compile teensy-loader-cli | |||
mkdir -p teensy-loader-cli | |||
@@ -10,8 +54,23 @@ if [ ! -e teensy-loader-cli/teensy-loader-cli ]; then | |||
cd - | |||
fi | |||
#| Loads the hex file onto the teensy | |||
# If a SERIAL_PORT was specified set the uC into reflash mode | |||
# XXX May not be successful if uC is not in a good state (or does not allow remote flashing) | |||
if [[ "$SERIAL_PORT" != "" ]] && [[ -e "$SERIAL_PORT" ]]; then | |||
echo "NOTE: This may fail if the uC is in a bad state or does not support remote flashing" | |||
printf "reload\r" > $SERIAL_PORT | |||
sleep 1 | |||
fi | |||
# Loads the hex file onto the teensy | |||
teensy-loader-cli/teensy-loader-cli -mmcu=@MCU@ -w @TARGET_HEX@ | |||
EXIT_STATUS=$? | |||
# Load Screen Session if specified | |||
if (( "$EXIT_STATUS" == "0" )) && [[ "$AUTO_SCREEN_SESSION" != "" ]]; then | |||
sleep 0.1 | |||
screen $AUTO_SCREEN_SESSION | |||
fi | |||
exit $? | |||
exit $EXIT_STATUS | |||
@@ -1,6 +1,49 @@ | |||
#!/bin/bash | |||
# Convenience script for loading firmware onto a teensy type device | |||
# By default, initiates teensy-load-cli | |||
#| First check to see teensy-loader-cli has been compiled | |||
SERIAL_PORT="" | |||
AUTO_SCREEN_SESSION="" | |||
PROG_NAME=$(basename $0) | |||
# Parse all the command line arguments | |||
while (( "$#" >= "1" )); do | |||
# Scan each argument | |||
key="$1" | |||
case $key in | |||
-a|--autoscreen) | |||
AUTO_SCREEN_SESSION="$2" | |||
shift | |||
;; | |||
-f|--fastload) | |||
SERIAL_PORT="$2" | |||
shift | |||
;; | |||
-h|--help) | |||
echo "Usage: $PROG_NAME [options...]" | |||
echo "" | |||
echo "Loads the most recent built firmware (@TARGET_BIN@) to the device." | |||
echo "Requires Cygwin." | |||
echo " (winload.teensy)" | |||
echo "" | |||
echo "Arguments:" | |||
echo " -f, --fastload SERIAL_PORT Send the reload command to the debug terminal." | |||
echo " e.g. /dev/ttyACM0" | |||
echo " NOTE: May not work due to non-functional terminal, or disable remote flashing" | |||
echo " -h, --help This message." | |||
exit 1 | |||
;; | |||
*) | |||
echo "INVALID ARG: '$1'" | |||
exit 2 | |||
;; | |||
esac | |||
# Shift to the next argument | |||
shift | |||
done | |||
# First check to see teensy-loader-cli has been compiled | |||
if [ ! -e teensy-loader-cli/teensy-loader-cli ]; then | |||
# Compile teensy-loader-cli | |||
mkdir -p teensy-loader-cli | |||
@@ -10,8 +53,17 @@ if [ ! -e teensy-loader-cli/teensy-loader-cli ]; then | |||
cd - | |||
fi | |||
#| Loads the hex file onto the teensy | |||
# If a SERIAL_PORT was specified set the uC into reflash mode | |||
# XXX May not be successful if uC is not in a good state (or does not allow remote flashing) | |||
if [[ "$SERIAL_PORT" != "" ]] && [[ -e "$SERIAL_PORT" ]]; then | |||
echo "NOTE: This may fail if the uC is in a bad state or does not support remote flashing" | |||
printf "reload\r" > $SERIAL_PORT | |||
sleep 1 | |||
fi | |||
# Loads the hex file onto the teensy | |||
teensy-loader-cli/teensy-loader-cli -mmcu=@MCU@ -w @TARGET_HEX@ | |||
EXIT_STATUS=$? | |||
exit $? | |||
exit $EXIT_STATUS | |||
@@ -54,7 +54,7 @@ typedef uint8_t var_uint_t; | |||
// This needs to be defined per microcontroller | |||
// e.g. mk20s -> 32 bit | |||
// atmega -> 16 bit | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) // ARM | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM | |||
typedef uint32_t nat_ptr_t; | |||
#elif defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
typedef uint16_t nat_ptr_t; |
@@ -616,7 +616,7 @@ inline TriggerMacroVote Macro_evalLongTriggerMacroVote( TriggerGuide *key, Trigg | |||
// Evaluate/Update TriggerMacro | |||
inline TriggerMacroEval Macro_evalTriggerMacro( var_uint_t triggerMacroIndex ) | |||
TriggerMacroEval Macro_evalTriggerMacro( var_uint_t triggerMacroIndex ) | |||
{ | |||
// Lookup TriggerMacro | |||
const TriggerMacro *macro = &TriggerMacroList[ triggerMacroIndex ]; | |||
@@ -1006,7 +1006,7 @@ inline void Macro_setup() | |||
void cliFunc_capList( char* args ) | |||
{ | |||
print( NL ); | |||
info_msg("Capabilities List"); | |||
info_msg("Capabilities List "); | |||
printHex( CapabilitiesNum ); | |||
// Iterate through all of the capabilities and display them |
@@ -1,6 +1,6 @@ | |||
###| CMake Kiibohd Controller Macro Module |### | |||
# | |||
# Written by Jacob Alexander in 2014 for the Kiibohd Controller | |||
# Written by Jacob Alexander in 2014-2015 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
@@ -11,20 +11,15 @@ | |||
# Module C files | |||
# | |||
set( MACRO_SRCS | |||
set ( Module_SRCS | |||
macro.c | |||
) | |||
### | |||
# Module Specific Options | |||
# | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( MacroModuleCompatibility | |||
set ( ModuleCompatibility | |||
arm | |||
avr | |||
) |
@@ -567,17 +567,17 @@ struct usb_string_descriptor_struct string0 = { | |||
struct usb_string_descriptor_struct usb_string_manufacturer_name_default = { | |||
sizeof(STR_MANUFACTURER), | |||
3, | |||
STR_MANUFACTURER | |||
{STR_MANUFACTURER} | |||
}; | |||
struct usb_string_descriptor_struct usb_string_product_name_default = { | |||
sizeof(STR_PRODUCT), | |||
3, | |||
STR_PRODUCT | |||
{STR_PRODUCT} | |||
}; | |||
struct usb_string_descriptor_struct usb_string_serial_number_default = { | |||
sizeof(STR_SERIAL), | |||
3, | |||
STR_SERIAL | |||
{STR_SERIAL} | |||
}; | |||
@@ -1098,12 +1098,17 @@ restart: | |||
void usb_init() | |||
uint8_t usb_init() | |||
{ | |||
#ifdef UART_DEBUG | |||
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++ ) | |||
{ | |||
@@ -1147,6 +1152,8 @@ void usb_init() | |||
// enable d+ pullup | |||
USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG; | |||
return 1; | |||
} | |||
// return 0 if the USB is not configured, or the configuration |
@@ -61,8 +61,8 @@ extern volatile uint8_t usb_cdc_transmit_flush_timer; | |||
// ----- Functions ----- | |||
uint8_t usb_configured(); // is the USB port configured | |||
uint8_t usb_init(); // Returns 1 on success, 0 if no cable is attached | |||
void usb_init(); | |||
void usb_isr(); | |||
void usb_tx( uint32_t endpoint, usb_packet_t *packet ); | |||
void usb_tx_isr( uint32_t endpoint, usb_packet_t *packet ); |
@@ -590,8 +590,13 @@ void wdt_init() | |||
// initialize USB | |||
void usb_init() | |||
uint8_t usb_init() | |||
{ | |||
// Check to see if a usb cable has been plugged in | |||
// XXX Not tested (also, not currently needed) -HaaTa | |||
//if ( USB0_STAT & (1 << 1) | |||
// return 0; | |||
HW_CONFIG(); | |||
USB_FREEZE(); // enable USB | |||
PLL_CONFIG(); // config PLL | |||
@@ -604,6 +609,8 @@ void usb_init() | |||
// Disable watchdog timer after possible software reset | |||
//wdt_init(); // XXX Not working...seems to be ok without this, not sure though | |||
return 1; | |||
} | |||
// return 0 if the USB is not configured, or the configuration |
@@ -46,7 +46,7 @@ | |||
// ----- Function Declarations ----- | |||
// Basic USB Configuration | |||
void usb_init(); // initialize everything | |||
uint8_t usb_init(); // initialize everything | |||
uint8_t usb_configured(); // is the USB port configured | |||
// Keyboard HID Functions |
@@ -1,4 +1,4 @@ | |||
/* Copyright (C) 2011-2014 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 | |||
@@ -33,7 +33,7 @@ | |||
// USB Includes | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) | |||
#include "avr/usb_keyboard_serial.h" | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
#include "arm/usb_dev.h" | |||
#include "arm/usb_keyboard.h" | |||
#include "arm/usb_serial.h" | |||
@@ -124,6 +124,11 @@ USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None; | |||
// count until idle timeout | |||
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) | |||
uint8_t Output_Available = 0; | |||
// ----- Capabilities ----- | |||
@@ -473,9 +478,11 @@ inline void Output_setup() | |||
{ | |||
// 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() ); | |||
// 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 ); | |||
@@ -549,7 +556,7 @@ inline int Output_putstr( char* str ) | |||
{ | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
uint16_t count = 0; | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) // ARM | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM | |||
uint32_t count = 0; | |||
#endif | |||
// Count characters until NULL character, then send the amount counted |
@@ -1,4 +1,4 @@ | |||
/* Copyright (C) 2013-2014 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 | |||
@@ -79,6 +79,8 @@ extern uint8_t USBKeys_Idle_Count; | |||
extern USBKeyChangeState USBKeys_Changed; | |||
extern uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working | |||
// ----- Capabilities ----- |
@@ -1,6 +1,6 @@ | |||
###| CMake Kiibohd Controller USB Module |### | |||
# | |||
# Written by Jacob Alexander in 2011-2013 for the Kiibohd Controller | |||
# Written by Jacob Alexander in 2011-2015 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
@@ -11,11 +11,10 @@ | |||
# Module C files | |||
# | |||
#| AVR Compiler | |||
if ( ${COMPILER_FAMILY} MATCHES "avr" ) | |||
set( OUTPUT_SRCS | |||
set ( Module_SRCS | |||
output_com.c | |||
avr/usb_keyboard_serial.c | |||
) | |||
@@ -23,7 +22,7 @@ if ( ${COMPILER_FAMILY} MATCHES "avr" ) | |||
#| ARM Compiler | |||
elseif ( ${COMPILER_FAMILY} MATCHES "arm" ) | |||
set( OUTPUT_SRCS | |||
set ( Module_SRCS | |||
output_com.c | |||
arm/usb_desc.c | |||
arm/usb_dev.c | |||
@@ -35,14 +34,10 @@ elseif ( ${COMPILER_FAMILY} MATCHES "arm" ) | |||
endif ( ${COMPILER_FAMILY} MATCHES "avr" ) | |||
### | |||
# Module Specific Options | |||
# | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( OutputModuleCompatibility | |||
set( ModuleCompatibility | |||
arm | |||
avr | |||
) |
@@ -1,4 +1,4 @@ | |||
/* Copyright (C) 2014 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 | |||
@@ -19,18 +19,74 @@ | |||
* THE SOFTWARE. | |||
*/ | |||
#include "uart_serial.h" | |||
// ----- Includes ----- | |||
// Compiler Includes | |||
#include <string.h> // For memcpy | |||
// Project Includes | |||
#include <Lib/OutputLib.h> | |||
#include <Lib/Interrupts.h> | |||
#include <string.h> // For memcpy | |||
// Local Includes | |||
#include "uart_serial.h" | |||
// ----- Defines ----- | |||
// UART Configuration | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) // UART0 Debug | |||
#define UART_BDH UART0_BDH | |||
#define UART_BDL UART0_BDL | |||
#define UART_C1 UART0_C1 | |||
#define UART_C2 UART0_C2 | |||
#define UART_C3 UART0_C3 | |||
#define UART_C4 UART0_C4 | |||
#define UART_CFIFO UART0_CFIFO | |||
#define UART_D UART0_D | |||
#define UART_PFIFO UART0_PFIFO | |||
#define UART_RCFIFO UART0_RCFIFO | |||
#define UART_RWFIFO UART0_RWFIFO | |||
#define UART_S1 UART0_S1 | |||
#define UART_S2 UART0_S2 | |||
#define UART_SFIFO UART0_SFIFO | |||
#define UART_TWFIFO UART0_TWFIFO | |||
#define SIM_SCGC4_UART SIM_SCGC4_UART0 | |||
#define IRQ_UART_STATUS IRQ_UART0_STATUS | |||
#elif defined(_mk20dx256vlh7_) // UART2 Debug | |||
#define UART_BDH UART2_BDH | |||
#define UART_BDL UART2_BDL | |||
#define UART_C1 UART2_C1 | |||
#define UART_C2 UART2_C2 | |||
#define UART_C3 UART2_C3 | |||
#define UART_C4 UART2_C4 | |||
#define UART_CFIFO UART2_CFIFO | |||
#define UART_D UART2_D | |||
#define UART_PFIFO UART2_PFIFO | |||
#define UART_RCFIFO UART2_RCFIFO | |||
#define UART_RWFIFO UART2_RWFIFO | |||
#define UART_S1 UART2_S1 | |||
#define UART_S2 UART2_S2 | |||
#define UART_SFIFO UART2_SFIFO | |||
#define UART_TWFIFO UART2_TWFIFO | |||
#define SIM_SCGC4_UART SIM_SCGC4_UART2 | |||
#define IRQ_UART_STATUS IRQ_UART2_STATUS | |||
#endif | |||
// ----- Variables ----- | |||
#define uart0_buffer_size 128 // 128 byte buffer | |||
volatile uint8_t uart0_buffer_head = 0; | |||
volatile uint8_t uart0_buffer_tail = 0; | |||
volatile uint8_t uart0_buffer_items = 0; | |||
volatile uint8_t uart0_buffer[uart0_buffer_size]; | |||
#define uart_buffer_size 128 // 128 byte buffer | |||
volatile uint8_t uart_buffer_head = 0; | |||
volatile uint8_t uart_buffer_tail = 0; | |||
volatile uint8_t uart_buffer_items = 0; | |||
volatile uint8_t uart_buffer[uart_buffer_size]; | |||
volatile uint8_t uart_configured = 0; | |||
@@ -38,21 +94,25 @@ volatile uint8_t uart_configured = 0; | |||
// ----- Interrupt Functions ----- | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) // UART0 Debug | |||
void uart0_status_isr() | |||
#elif defined(_mk20dx256vlh7_) // UART2 Debug | |||
void uart2_status_isr() | |||
#endif | |||
{ | |||
cli(); // Disable Interrupts | |||
// UART0_S1 must be read for the interrupt to be cleared | |||
if ( UART0_S1 & ( UART_S1_RDRF | UART_S1_IDLE ) ) | |||
if ( UART_S1 & ( UART_S1_RDRF | UART_S1_IDLE ) ) | |||
{ | |||
uint8_t available = UART0_RCFIFO; | |||
uint8_t available = UART_RCFIFO; | |||
// If there was actually nothing | |||
if ( available == 0 ) | |||
{ | |||
// Cleanup | |||
available = UART0_D; | |||
UART0_CFIFO = UART_CFIFO_RXFLUSH; | |||
available = UART_D; | |||
UART_CFIFO = UART_CFIFO_RXFLUSH; | |||
sei(); | |||
return; | |||
} | |||
@@ -60,25 +120,25 @@ void uart0_status_isr() | |||
// Read UART0 into buffer until FIFO is empty | |||
while ( available-- > 0 ) | |||
{ | |||
uart0_buffer[uart0_buffer_tail++] = UART0_D; | |||
uart0_buffer_items++; | |||
uart_buffer[uart_buffer_tail++] = UART_D; | |||
uart_buffer_items++; | |||
// Wrap-around of tail pointer | |||
if ( uart0_buffer_tail >= uart0_buffer_size ) | |||
if ( uart_buffer_tail >= uart_buffer_size ) | |||
{ | |||
uart0_buffer_tail = 0; | |||
uart_buffer_tail = 0; | |||
} | |||
// Make sure the head pointer also moves if circular buffer is overwritten | |||
if ( uart0_buffer_head == uart0_buffer_tail ) | |||
if ( uart_buffer_head == uart_buffer_tail ) | |||
{ | |||
uart0_buffer_head++; | |||
uart_buffer_head++; | |||
} | |||
// Wrap-around of head pointer | |||
if ( uart0_buffer_head >= uart0_buffer_size ) | |||
if ( uart_buffer_head >= uart_buffer_size ) | |||
{ | |||
uart0_buffer_head = 0; | |||
uart_buffer_head = 0; | |||
} | |||
} | |||
} | |||
@@ -96,14 +156,20 @@ void uart_serial_setup() | |||
uart_configured = 0; | |||
// Setup the the UART interface for keyboard data input | |||
SIM_SCGC4 |= SIM_SCGC4_UART0; // Disable clock gating | |||
SIM_SCGC4 |= SIM_SCGC4_UART; // Disable clock gating | |||
// MCHCK | |||
// MCHCK / Kiibohd-dfu | |||
#if defined(_mk20dx128vlf5_) | |||
// Pin Setup for UART0 | |||
PORTA_PCR1 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(2); // RX Pin | |||
PORTA_PCR2 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(2); // TX Pin | |||
// Kiibohd-dfu | |||
#elif defined(_mk20dx256vlh7_) | |||
// Pin Setup for UART2 | |||
PORTD_PCR2 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); // RX Pin | |||
PORTD_PCR3 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); // TX Pin | |||
// Teensy | |||
#else | |||
// Pin Setup for UART0 | |||
@@ -111,44 +177,66 @@ void uart_serial_setup() | |||
PORTB_PCR17 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); // TX Pin | |||
#endif | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) // UART0 Debug | |||
// Setup baud rate - 115200 Baud | |||
// 48 MHz / ( 16 * Baud ) = BDH/L | |||
// Baud: 115200 -> 48 MHz / ( 16 * 115200 ) = 26.0416667 | |||
// Thus baud setting = 26 | |||
// NOTE: If finer baud adjustment is needed see UARTx_C4 -> BRFA in the datasheet | |||
uint16_t baud = 26; // Max setting of 8191 | |||
UART0_BDH = (uint8_t)(baud >> 8); | |||
UART0_BDL = (uint8_t)baud; | |||
UART0_C4 = 0x02; | |||
UART_BDH = (uint8_t)(baud >> 8); | |||
UART_BDL = (uint8_t)baud; | |||
UART_C4 = 0x02; | |||
#elif defined(_mk20dx256vlh7_) // UART2 Debug | |||
// Setup baud rate - 115200 Baud | |||
// Uses Bus Clock | |||
// 24 MHz / ( 16 * Baud ) = BDH/L | |||
// Baud: 115200 -> 24 MHz / ( 16 * 115200 ) = 13.021 | |||
// Thus baud setting = 13 | |||
// NOTE: If finer baud adjustment is needed see UARTx_C4 -> BRFA in the datasheet | |||
uint16_t baud = 13; // Max setting of 8191 | |||
UART_BDH = (uint8_t)(baud >> 8); | |||
UART_BDL = (uint8_t)baud; | |||
UART_C4 = 0x01; | |||
#endif | |||
// 8 bit, No Parity, Idle Character bit after stop | |||
UART0_C1 = UART_C1_ILT; | |||
UART_C1 = UART_C1_ILT; | |||
// Interrupt notification watermarks | |||
UART0_TWFIFO = 2; | |||
UART0_RWFIFO = 4; | |||
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) // UART0 Debug | |||
UART_TWFIFO = 2; | |||
UART_RWFIFO = 4; | |||
#elif defined(_mk20dx256vlh7_) // UART2 Debug | |||
// UART2 has a single byte FIFO | |||
UART_TWFIFO = 1; | |||
UART_RWFIFO = 1; | |||
#endif | |||
// TX FIFO Disabled, TX FIFO Size 1 (Max 8 datawords), RX FIFO Enabled, RX FIFO Size 1 (Max 8 datawords) | |||
// TX FIFO Enabled, TX FIFO Size 1 (Max 8 datawords), RX FIFO Enabled, RX FIFO Size 1 (Max 8 datawords) | |||
// TX/RX FIFO Size: | |||
// 0x0 - 1 dataword | |||
// 0x1 - 4 dataword | |||
// 0x2 - 8 dataword | |||
UART0_PFIFO = UART_PFIFO_TXFE | UART_PFIFO_RXFE; | |||
UART_PFIFO = UART_PFIFO_TXFE | UART_PFIFO_RXFE; | |||
// Reciever Inversion Disabled, LSBF | |||
// UART_S2_RXINV UART_S2_MSBF | |||
UART0_S2 |= 0x00; | |||
UART_S2 |= 0x00; | |||
// Transmit Inversion Disabled | |||
// UART_C3_TXINV | |||
UART0_C3 |= 0x00; | |||
UART_C3 |= 0x00; | |||
// TX Enabled, RX Enabled, RX Interrupt Enabled, Generate idles | |||
// UART_C2_TE UART_C2_RE UART_C2_RIE UART_C2_ILIE | |||
UART0_C2 = UART_C2_TE | UART_C2_RE | UART_C2_RIE | UART_C2_ILIE; | |||
UART_C2 = UART_C2_TE | UART_C2_RE | UART_C2_RIE | UART_C2_ILIE; | |||
// Add interrupt to the vector table | |||
NVIC_ENABLE_IRQ( IRQ_UART0_STATUS ); | |||
NVIC_ENABLE_IRQ( IRQ_UART_STATUS ); | |||
// UART is now ready to use | |||
uart_configured = 1; | |||
@@ -164,15 +252,15 @@ int uart_serial_getchar() | |||
unsigned int value = -1; | |||
// Check to see if the FIFO has characters | |||
if ( uart0_buffer_items > 0 ) | |||
if ( uart_buffer_items > 0 ) | |||
{ | |||
value = uart0_buffer[uart0_buffer_head++]; | |||
uart0_buffer_items--; | |||
value = uart_buffer[uart_buffer_head++]; | |||
uart_buffer_items--; | |||
// Wrap-around of head pointer | |||
if ( uart0_buffer_head >= uart0_buffer_size ) | |||
if ( uart_buffer_head >= uart_buffer_size ) | |||
{ | |||
uart0_buffer_head = 0; | |||
uart_buffer_head = 0; | |||
} | |||
} | |||
@@ -183,16 +271,16 @@ int uart_serial_getchar() | |||
// Number of bytes available in the receive buffer | |||
int uart_serial_available() | |||
{ | |||
return uart0_buffer_items; | |||
return uart_buffer_items; | |||
} | |||
// Discard any buffered input | |||
void uart_serial_flush_input() | |||
{ | |||
uart0_buffer_head = 0; | |||
uart0_buffer_tail = 0; | |||
uart0_buffer_items = 0; | |||
uart_buffer_head = 0; | |||
uart_buffer_tail = 0; | |||
uart_buffer_items = 0; | |||
} | |||
@@ -202,8 +290,8 @@ int uart_serial_putchar( uint8_t c ) | |||
if ( !uart_configured ) | |||
return -1; | |||
while ( !( UART0_SFIFO & UART_SFIFO_TXEMPT ) ); // Wait till there is room to send | |||
UART0_D = c; | |||
while ( !( UART_SFIFO & UART_SFIFO_TXEMPT ) ); // Wait till there is room to send | |||
UART_D = c; | |||
return 0; | |||
} | |||
@@ -220,8 +308,8 @@ int uart_serial_write( const void *buffer, uint32_t size ) | |||
// While buffer is not empty and transmit buffer is | |||
while ( position < size ) | |||
{ | |||
while ( !( UART0_SFIFO & UART_SFIFO_TXEMPT ) ); // Wait till there is room to send | |||
UART0_D = data[position++]; | |||
while ( !( UART_SFIFO & UART_SFIFO_TXEMPT ) ); // Wait till there is room to send | |||
UART_D = data[position++]; | |||
} | |||
return 0; | |||
@@ -231,7 +319,7 @@ int uart_serial_write( const void *buffer, uint32_t size ) | |||
void uart_serial_flush_output() | |||
{ | |||
// Delay until buffer has been sent | |||
while ( !( UART0_SFIFO & UART_SFIFO_TXEMPT ) ); // Wait till there is room to send | |||
while ( !( UART_SFIFO & UART_SFIFO_TXEMPT ) ); // Wait till there is room to send | |||
} | |||
@@ -1,4 +1,4 @@ | |||
/* Copyright (C) 2014 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 | |||
@@ -32,7 +32,7 @@ | |||
// USB Includes | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
#include "arm/uart_serial.h" | |||
#endif | |||
@@ -107,6 +107,11 @@ USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None; | |||
// count until idle timeout | |||
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) | |||
uint8_t Output_Available = 0; | |||
// ----- Capabilities ----- | |||
@@ -180,7 +185,7 @@ inline int Output_putstr( char* str ) | |||
{ | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
uint16_t count = 0; | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) // ARM | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM | |||
uint32_t count = 0; | |||
#endif | |||
// Count characters until NULL character, then send the amount counted | |||
@@ -195,7 +200,7 @@ inline int Output_putstr( char* str ) | |||
inline void Output_softReset() | |||
{ | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) // ARM | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM | |||
SOFTWARE_RESET(); | |||
#endif | |||
} |
@@ -1,4 +1,4 @@ | |||
/* Copyright (C) 2013-2014 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 | |||
@@ -76,6 +76,8 @@ extern uint8_t USBKeys_Idle_Count; | |||
extern USBKeyChangeState USBKeys_Changed; | |||
extern uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working | |||
// ----- Capabilities ----- |
@@ -1,6 +1,6 @@ | |||
###| CMake Kiibohd Controller UART Output Module |### | |||
# | |||
# Written by Jacob Alexander in 2014 for the Kiibohd Controller | |||
# Written by Jacob Alexander in 2014-2015 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
@@ -11,11 +11,10 @@ | |||
# Module C files | |||
# | |||
#| AVR Compiler | |||
if ( ${COMPILER_FAMILY} MATCHES "avr" ) | |||
set( OUTPUT_SRCS | |||
set ( Module_SRCS | |||
output_com.c | |||
avr/uart_serial.c | |||
) | |||
@@ -23,7 +22,7 @@ if ( ${COMPILER_FAMILY} MATCHES "avr" ) | |||
#| ARM Compiler | |||
elseif ( ${COMPILER_FAMILY} MATCHES "arm" ) | |||
set( OUTPUT_SRCS | |||
set ( Module_SRCS | |||
output_com.c | |||
arm/uart_serial.c | |||
) | |||
@@ -31,14 +30,10 @@ elseif ( ${COMPILER_FAMILY} MATCHES "arm" ) | |||
endif () | |||
### | |||
# Module Specific Options | |||
# | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( OutputModuleCompatibility | |||
set( ModuleCompatibility | |||
arm | |||
# avr # TODO | |||
) |
@@ -1,4 +1,4 @@ | |||
/* Copyright (C) 2014 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 | |||
@@ -32,11 +32,11 @@ | |||
// USB Includes | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) | |||
#include "../uartOut/arm/uart_serial.h" | |||
#include "../pjrcUSB/arm/usb_dev.h" | |||
#include "../pjrcUSB/arm/usb_keyboard.h" | |||
#include "../pjrcUSB/arm/usb_serial.h" | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
#include <uartOut/arm/uart_serial.h> | |||
#include <pjrcUSB/arm/usb_dev.h> | |||
#include <pjrcUSB/arm/usb_keyboard.h> | |||
#include <pjrcUSB/arm/usb_serial.h> | |||
#endif | |||
// Local Includes | |||
@@ -130,6 +130,11 @@ USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None; | |||
// count until idle timeout | |||
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) | |||
uint8_t Output_Available = 0; | |||
// ----- Capabilities ----- | |||
@@ -468,7 +473,7 @@ inline int Output_putstr( char* str ) | |||
{ | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
uint16_t count = 0; | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) // ARM | |||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM | |||
uint32_t count = 0; | |||
#endif | |||
// Count characters until NULL character, then send the amount counted |
@@ -1,4 +1,4 @@ | |||
/* Copyright (C) 2013-2014 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 | |||
@@ -78,6 +78,8 @@ extern uint8_t USBKeys_Idle_Count; | |||
extern USBKeyChangeState USBKeys_Changed; | |||
extern uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working | |||
// ----- Capabilities ----- |
@@ -1,6 +1,6 @@ | |||
###| CMake Kiibohd Controller Muxed UART and USB Output Module |### | |||
# | |||
# Written by Jacob Alexander in 2014 for the Kiibohd Controller | |||
# Written by Jacob Alexander in 2014-2015 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
@@ -8,43 +8,26 @@ | |||
### | |||
# Module C files | |||
# Required Submodules | |||
# | |||
#| AVR Compiler | |||
if ( ${COMPILER_FAMILY} MATCHES "avr" ) | |||
set( OUTPUT_SRCS | |||
) | |||
#| ARM Compiler | |||
elseif ( ${COMPILER_FAMILY} MATCHES "arm" ) | |||
set( OUTPUT_SRCS | |||
output_com.c | |||
../pjrcUSB/arm/usb_desc.c | |||
../pjrcUSB/arm/usb_dev.c | |||
../pjrcUSB/arm/usb_keyboard.c | |||
../pjrcUSB/arm/usb_mem.c | |||
../pjrcUSB/arm/usb_serial.c | |||
../uartOut/arm/uart_serial.c | |||
) | |||
endif () | |||
AddModule ( Output pjrcUSB ) | |||
AddModule ( Output uartOut ) | |||
### | |||
# Module Specific Options | |||
# Module C files | |||
# | |||
set( Module_SRCS | |||
output_com.c | |||
) | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( OutputModuleCompatibility | |||
set( ModuleCompatibility | |||
arm | |||
# avr # TODO | |||
) |
@@ -1,489 +0,0 @@ | |||
The Kiibohd Controller | |||
---------------------- | |||
This README is a bit long, just look at the sections you are interested in. | |||
Linux is the ideal build environment (preferably recent'ish). | |||
Building on Mac should be ok for 99% of users with Macports (haven't tried Brew). | |||
The dfu Bootloader will not build correctly with the old version of arm-none-eabi-gcc that Macports currently has (4.7.3). | |||
This is due to a bug with lto (link time optimizations) which makes the resulting binary too big to fit on the chip (must be less than 4096 Bytes). | |||
Building on Windows should also be fine for 99% of users, but takes a bunch of work to setup (because Windows is a crappy dev environment). | |||
Cygwin is currently required along with some non-Cygwin compilers and utilities (because they are not available for Cygwin). | |||
The dfu Bootloader will not build because of a Make 3.81+ bug/feature that removed support for non-Unix (Windows) filenames as dependencies of targets. | |||
If you replace the version of Make in Cygwin it should work (e.g. http://stackoverflow.com/questions/601516/cygwin-make-error-target-pattern-contains-no). | |||
However, make sure that the flash size is no larger than 4096 Bytes or the bootloader will not work. | |||
Please give authors credit for modules used if you use in a distributed product :D | |||
---------------------- | |||
Dependencies | |||
---------------------- | |||
Below listed are the Arch Linux pacman names, AUR packages may be required. | |||
These depend a bit on which targets you are trying to build, but the general one: | |||
- cmake (2.8 and higher) | |||
- git | |||
- ctags (recommended, not required) | |||
- python3 | |||
- libusb1.0 (and -devel) | |||
- make | |||
AVR Specific (Teensy 1.0/++,2.0/++) (try to use something recent, suggested versions below) | |||
- avr-gcc (~4.8.0) | |||
- avr-binutils (~2.23.2) | |||
- avr-libc (~1.8.0) | |||
ARM Specific (Teensy 3.0/3.1) (Sourcery CodeBench Lite for ARM EABI | |||
(http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/) | |||
- arm-none-eabi | |||
OR | |||
- arm-none-eabi-gcc | |||
- arm-none-eaby-binutils | |||
(I've actually had some issues with Sourcery CodeBench on Linux, so I often just use these) | |||
---------------------- | |||
Windows Setup | |||
---------------------- | |||
Compiling on Windows does work, just it's a bunch more work. | |||
First make sure Cygwin is installed - http://www.cygwin.com/ - 32bit or 64bit is fine. Make sure the following are installed: | |||
- make | |||
- git (needed for some compilation info) | |||
- cmake | |||
- gcc-core | |||
- gcc-g++ | |||
- libusb1.0 | |||
- libusb1.0-devel | |||
- python3 | |||
- ctags (recommended, not required) | |||
Please note, I use cygwin term exclusively for any command line options. Unless mentioned otherwise use it. | |||
Do NOT use CMD or Powershell. | |||
Also install the Windows version of CMake (3+ is ideal) - http://cmake.org/cmake/resources/software.html | |||
This is in addition to the Cygwin version. This is an easier alternative to installing another C compiler. | |||
Add the following line to your .bashrc, making sure the CMake path is correct: | |||
echo "alias wincmake=\"PATH='/cygdrive/c/Program Files (x86)/CMake'/bin:'${PATH}' cmake -G 'Unix Makefiles'\"" >> ~/.bashrc | |||
Install the PJRC Virtual Serial Port Driver: | |||
(http://pjrc.com/teensy/serial_install.exe) | |||
Next, install the compiler(s) you want. | |||
--------- | |||
| AVR GCC | | |||
--------- | |||
You just need the Atmel AVR 8-bit Toolchain. The latest should be fine, as of writing it was 3.4.3. | |||
http://www.atmel.com/tools/atmelavrtoolchainforwindows.aspx | |||
(Atmel AVR 8-bit Toolchain 3.4.3 - Windows) | |||
Extract the files to a directory, say C:\avr8-gnu-toolchain. Then copy all the folders in that directory to the Cygwin /usr/local directory. | |||
Mine is C:\cygwin64\usr\local. | |||
(You can also just setup the paths, but this is faster/simpler. Might screw up your Cygwin though). | |||
---------- | |||
| ARM EABI | | |||
---------- | |||
Download the latest version of Mentor Graphics Sourcery CodeBench ARM EABI. | |||
http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/ | |||
Look for "Download the EABI Release". | |||
Enter your info to get the download link. | |||
Select the most recent download. | |||
Then download the "IA32 Windows Installer". | |||
Then copy all the folders/files installed (e.g. C:\Users\Haata\MentorGraphics\Sourcery_CodeBench_Lite_for_ARM_EABI\) to Cygwin /usr/local directory. | |||
Mine is C:\cygwin64\usr\local. | |||
Or, you can setup paths using the installer (you have to be more careful though). | |||
---------------------- | |||
Selecting Microcontroller | |||
---------------------- | |||
This is where you select the chip you want to compile for. | |||
The build system will automatically select the compiler needed to compile for your chip. | |||
Open up CMakeLists.txt in your favourite text editor. | |||
You are looking for: | |||
### | |||
# Chip Selection | |||
# | |||
#| You _MUST_ set this to match the microcontroller you are trying to compile for | |||
#| You _MUST_ clean the build directory if you change this value | |||
#| | |||
set( CHIP | |||
# "at90usb162" # Teensy 1.0 (avr) | |||
# "atmega32u4" # Teensy 2.0 (avr) | |||
# "at90usb646" # Teensy++ 1.0 (avr) | |||
"at90usb1286" # Teensy++ 2.0 (avr) | |||
# "mk20dx128" # Teensy 3.0 (arm) | |||
# "mk20dx256" # Teensy 3.1 (arm) | |||
) | |||
Just uncomment the chip you want, and comment out the old one. | |||
NOTE: If you change this option, you will *need* to delete the build directory that is created in the Building sections below. | |||
---------------------- | |||
Selecting Modules | |||
---------------------- | |||
WARNING: Not all modules are compatible, and some modules may have dependencies on other modules. | |||
This is where the options start getting interesting. | |||
The Kiibohd Controller is designed around a set of 4 types of modules that correspond to different functionality: | |||
- Scan Module | |||
- Macro Module | |||
- Output Module | |||
- Debug Module | |||
The Scan Module is where the most interesting stuff happens. These modules take in "keypress data". | |||
A converter Scan Module will interpret a protocol into key press/releases. | |||
A matrix Scan Module may inherit from the matrix module to scan keypress from a matrix | |||
This module just has to give press/release codes, but does have some callback control to other modules depending on the lifecycle for press/release codes (this can be very complicated depending on the protocol). | |||
Each Scan Module has it's own default keymap/modifier map. (TODO recommend keymap changing in the Macro Module). | |||
Some scan modules have very specialized hardware requirements, each module directory should have at least a link to the needed parts and/or schematics (TODO!). | |||
The Macro Module takes care of the mapping of the key press/release code into an Output (USB) scan code. | |||
Any layering, macros, keypress intelligence/reaction is done here. | |||
The Output Module is the module dealing with output from the microcontroller. Currently USB is the only output protocol. | |||
Different USB output implementations are available, pjrc being the safest/least featureful one. | |||
Debug capabilities may depend on the module selected. | |||
The Debug Module enables various things like the Teensy LED on errors, debug terminal output. | |||
(TODO get true UART working in avr, not just arm) | |||
Open up CMakeLists.txt in your favourite text editor. | |||
Look for: | |||
### | |||
# Project Modules | |||
# | |||
#| Note: This is the only section you probably want to modify | |||
#| Each module is defined by it's own folder (e.g. Scan/Matrix represents the "Matrix" module) | |||
#| All of the modules must be specified, as they generate the sources list of files to compile | |||
#| Any modifications to this file will cause a complete rebuild of the project | |||
#| Please look at the {Scan,Macro,Output,Debug}/module.txt 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 "avr-capsense" ) | |||
##| Uses the key index and potentially applies special conditions to it, mapping it to a usb key code | |||
set( MacroModule "buffer" ) | |||
##| Sends the current list of usb key codes through USB HID | |||
set( OutputModule "pjrc" ) | |||
##| Debugging source to use, each module has it's own set of defines that it sets | |||
set( DebugModule "full" ) | |||
Look at each module individually for it's requirements. There is chip/architecture dependency checking but some permutations of modules may not be tested/compile. | |||
There are also CMake options for temporarily selecting modules. But it's easier to just edit the file. | |||
e.g. cmake -DScanModuleOverride=<module name> | |||
---------------------- | |||
Linux Building | |||
---------------------- | |||
From this directory. | |||
mkdir build | |||
cd build | |||
cmake .. | |||
make | |||
Example output: | |||
[master]: cmake .. [...sy/avr-capsense-haata/build](hyatt@901Mas:pts/4) | |||
-- Compiler Family: | |||
avr | |||
-- MCU Selected: | |||
at90usb1286 | |||
-- Detected Scan Module Source Files: | |||
Scan/avr-capsense/scan_loop.c | |||
-- Detected Macro Module Source Files: | |||
Macro/buffer/macro.c | |||
-- Detected Output Module Source Files: | |||
Output/pjrc/usb_com.c;Output/pjrc/avr/usb_keyboard_debug.c | |||
-- Detected Debug Module Source Files: | |||
Debug/full/../led/led.c;Debug/full/../print/print.c | |||
-- Configuring done | |||
-- Generating done | |||
-- Build files have been written to: /home/hyatt/Source/Teensy/avr-capsense-haata/build | |||
[master]: make [...sy/avr-capsense-haata/build](hyatt@901Mas:pts/4) | |||
Scanning dependencies of target kiibohd.elf | |||
[ 12%] Building C object CMakeFiles/kiibohd.elf.dir/main.c.o | |||
[ 25%] Building C object CMakeFiles/kiibohd.elf.dir/Scan/avr-capsense/scan_loop.c.o | |||
[ 37%] Building C object CMakeFiles/kiibohd.elf.dir/Macro/buffer/macro.c.o | |||
[ 50%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrc/usb_com.c.o | |||
[ 62%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrc/avr/usb_keyboard_debug.c.o | |||
[ 75%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/led/led.c.o | |||
[ 87%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/print/print.c.o | |||
Linking C executable kiibohd.elf | |||
Creating load file for Flash: kiibohd.hex | |||
Creating Extended Listing: kiibohd.lss | |||
Creating Symbol Table: kiibohd.sym | |||
[ 87%] Built target kiibohd.elf | |||
Scanning dependencies of target SizeAfter | |||
[100%] Size after generation: | |||
text data bss dec hex filename | |||
0 6112 0 6112 17e0 kiibohd.hex | |||
5792 320 852 6964 1b34 kiibohd.elf | |||
[100%] Built target SizeAfter | |||
---------------------- | |||
Linux Loading Firmware | |||
---------------------- | |||
First place the keyboard into re-flash mode. | |||
This can be done either by pressing the re-flash button on the PCB/Teensy. | |||
Or by entering the Kiibohd Virtual Serial Port and using the 'reload' command. | |||
The 'load' script that is created during the build can load the firmware over USB. | |||
Either run it with sudo, or install the 98-kiibohd.rules to /etc/udev/rules.d | |||
and run: udevadm control --reload-rules | |||
To load the newly built firmware: | |||
./load | |||
---------------------- | |||
Linux Building Bootloader | |||
---------------------- | |||
*NOTE* Does not apply to Teensy based builds. | |||
From this directory. | |||
cd Bootloader | |||
mkdir build | |||
cd build | |||
cmake .. | |||
make | |||
Example output: | |||
TODO | |||
---------------------- | |||
Linux Loading Bootloader | |||
---------------------- | |||
*NOTE* Does not apply to Teensy based builds. | |||
It's recommended to use an SWD-type flasher like a Bus Pirate. | |||
TODO | |||
(Guidelines here https://github.com/mchck/mchck/wiki/Getting-Started) | |||
---------------------- | |||
Windows Building | |||
---------------------- | |||
From this directory. | |||
mkdir build | |||
cd build | |||
wincmake .. | |||
make | |||
Example output: | |||
$ cmake -G "Unix Makefiles" .. | |||
-- Compiler Family: | |||
avr | |||
-- MCU Selected: | |||
atmega32u4 | |||
-- CPU Selected: | |||
megaAVR | |||
-- Detected Scan Module Source Files: | |||
Scan/SKM67001/../matrix/matrix_scan.c;Scan/SKM67001/../matrix/scan_loop.c | |||
-- Detected Macro Module Source Files: | |||
Macro/PartialMap/macro.c | |||
-- Detected Output Module Source Files: | |||
Output/pjrcUSB/output_com.c;Output/pjrcUSB/avr/usb_keyboard_serial.c | |||
-- Detected Debug Module Source Files: | |||
Debug/full/../cli/cli.c;Debug/full/../led/led.c;Debug/full/../print/print.c | |||
-- Found Git: C:/cygwin64/bin/git.exe (found version "1.7.9") | |||
-- Configuring done | |||
-- Generating done | |||
-- Build files have been written to: C:/cygwin64/home/jacob.alexander/src/capsense-beta/build | |||
jacob.alexander@JALEXANDER2-LT ~/src/capsense-beta/build | |||
$ make | |||
Scanning dependencies of target kiibohd.elf | |||
[ 10%] Building C object CMakeFiles/kiibohd.elf.dir/main.c.obj | |||
[ 20%] Building C object CMakeFiles/kiibohd.elf.dir/Scan/matrix/matrix_scan.c.obj | |||
[ 30%] Building C object CMakeFiles/kiibohd.elf.dir/Scan/matrix/scan_loop.c.obj | |||
[ 40%] Building C object CMakeFiles/kiibohd.elf.dir/Macro/PartialMap/macro.c.obj | |||
[ 50%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/output_com.c.obj | |||
[ 60%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/avr/usb_keyboard_serial.c.obj | |||
[ 70%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/cli/cli.c.obj | |||
[ 80%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/led/led.c.obj | |||
[ 90%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/print/print.c.obj | |||
Linking C executable kiibohd.elf | |||
Creating load file for Flash: kiibohd.hex | |||
Creating Extended Listing: kiibohd.lss | |||
Creating Symbol Table: kiibohd.sym | |||
[ 90%] Built target kiibohd.elf | |||
Scanning dependencies of target SizeAfter | |||
[100%] Size after generation | |||
Flash Usage: data (hex) | |||
RAM Usage: data (elf) | |||
text data bss dec hex filename | |||
0 9738 0 9738 260a kiibohd.hex | |||
7982 1756 264 10002 2712 kiibohd.elf | |||
[100%] Built target SizeAfter | |||
---------------------- | |||
Windows Loading Firmware | |||
---------------------- | |||
First place the keyboard into re-flash mode. | |||
This can be done either by pressing the re-flash button on the PCB/Teensy. | |||
Or by entering the Kiibohd Virtual Serial Interface and using the 'reload' command. | |||
The 'load' script that is created during the build can load the firmware over USB. | |||
To load the newly built firmware: | |||
./load | |||
Be patient the couple of times, Windows is slow at installing drivers... | |||
---------------------- | |||
Mac OS X Building | |||
---------------------- | |||
From this directory. | |||
mkdir build | |||
cd build | |||
cmake .. | |||
make | |||
Example output: | |||
TODO | |||
---------------------- | |||
Mac OS X Loading Firmware | |||
---------------------- | |||
First place the keyboard into re-flash mode. | |||
This can be done either by pressing the re-flash button on the PCB/Teensy. | |||
Or by entering the Kiibohd Virtual Serial Port and using the 'reload' command. | |||
The 'load' script that is created during the build can load the firmware over USB. | |||
To load the newly built firmware: | |||
./load | |||
---------------------- | |||
Virtual Serial Port - CLI | |||
---------------------- | |||
Rather than use a special program that can interpret Raw HID, this controller exposes a USB Serial CDC endpoint. | |||
This allows for you to use a generic serial terminal to debug/control the keyboard firmware (e.g. Tera Term, minicom, screen) | |||
------- | |||
| Linux | | |||
------- | |||
I generally use screen. | |||
You will need sudo/root priviledges if you haven't installed the 98-kiibohd.rules file to /etc/udev/rules.d | |||
screen /dev/ttyACM0 | |||
(Might be ACM1, ACM2, etc.) | |||
--------- | |||
| Windows | | |||
--------- | |||
Make sure the Teensy Virtual Serial Port driver is installed. | |||
If possible use screen (as part of Cygwin). | |||
Check which COM port the virtual serial port has been assigned to: | |||
Device Manager->Ports (COM & LPT)->Teensy USB Serial | |||
In brackets it will say which COM port (e.g. COM3) | |||
putty works well when using DTR/DSR or RTS/CTS flow control. | |||
Connection type: Serial | |||
Serial line: <Your COM port, e.g. COM3> | |||
Speed: (doesn't matter, it's auto-negotiated) | |||
Under Category->Connections->Serial | |||
Flow control: DTR/DSR | |||
If stuff is hard to read (you have a dumb colour scheme): | |||
Category->Window->Colours->Use system colur | |||
That seems to make text at least readable (I use a custom colour scheme that makes each colour easy to see -HaaTa). | |||
Unfortunately, screen for Cygwin seems to be broken for serial ports, but you can try it... | |||
screen /dev/ttyS2 | |||
(Might be a different file, ttyS0, ttyACM0, ttyUSB0, etc.) | |||
Gnu screen doesn't seem to echo all the characters (it works though). | |||
I believe it's a problem with stty, but I don't know how to fix it... | |||
---------- | |||
| Mac OS X | | |||
---------- | |||
I recommend screen (can be installed via Macports). | |||
screen /dev/tty.<usb something> |
@@ -0,0 +1,643 @@ | |||
The Kiibohd Controller | |||
====================== | |||
This README is a bit long, just look at the sections you are interested in. | |||
You only need to install avr-gcc if you want to build for the Teensy 2.0/2.0++. | |||
Everything else needs an arm-none-eabi-gcc compiler (e.g. Infinity keyboard, | |||
Teensy 3.0/3.1, McHCK). | |||
Linux is the ideal build environment (preferably recent'ish). In the near | |||
future I'll make available an Arch Linux VM for building/manufacturing tests. | |||
Building on Mac should be ok for 99% of users with Macports (haven't tried | |||
Brew). The dfu Bootloader will not build correctly with the old version of | |||
arm-none-eabi-gcc that Macports currently has (4.7.3). This is due to a bug | |||
with lto (link time optimizations) which makes the resulting binary too big to | |||
fit on the chip (must be less than 4096 Bytes). | |||
Building on Windows should also be fine for 99% of users, but takes a bunch of | |||
work to setup (because Windows is a crappy dev environment). Cygwin is | |||
currently required along with some non-Cygwin compilers and utilities (because | |||
they are not available for Cygwin). The dfu Bootloader will not build because | |||
of a Make 3.81+ bug/feature that removed support for non-Unix (Windows) | |||
filenames as dependencies of targets. If you [replace the version of Make in | |||
Cygwin](http://stackoverflow.com/questions/601516/cygwin-make-error-target-pattern-contains-no) | |||
it should work. However, make sure that the flash size is no larger than 4096 | |||
Bytes or the bootloader will not work. Things will likely break if there are | |||
**SPACES IN YOUR PATHS**. I install cygwin to `C:\cygwin64`. If you are brave | |||
and have programming knowledge, I will accept patches to fix any issues | |||
regarding spaces in paths. | |||
Please give authors credit for modules used if you use in a distributed | |||
product :D | |||
General Dependencies | |||
-------------------- | |||
Below listed are the Arch Linux pacman names, AUR packages may be required. | |||
These depend a bit on which targets you are trying to build, but the general | |||
one: | |||
- cmake (2.8 and higher) | |||
- git | |||
- ctags (recommended, not required) | |||
- python3 | |||
- libusb1.0 (and -devel) | |||
- make | |||
AVR Specific (Teensy 1.0/++,2.0/++) (try to use something recent, suggested | |||
versions below) | |||
- avr-gcc (~4.8.0) | |||
- avr-binutils (~2.23.2) | |||
- avr-libc (~1.8.0) | |||
ARM Specific (Teensy 3.0/3.1, Infinity Keyboard, McHCK) | |||
- Arch Linux / Mac Ports | |||
- arm-none-eabi-gcc | |||
- arm-none-eaby-binutils | |||
- Windows (https://launchpad.net/gcc-arm-embedded/+download) | |||
- gcc-arm-none-eabi (win32.zip) | |||
Windows Setup | |||
------------- | |||
Compiling on Windows does work, just it's a bunch more work. | |||
First make sure Cygwin is installed - http://www.cygwin.com/ - 32bit or 64bit | |||
is fine. Make sure the following are installed: | |||
- make | |||
- git (needed for some compilation info) | |||
- cmake | |||
- gcc-core | |||
- gcc-g++ | |||
- libusb1.0 | |||
- libusb1.0-devel | |||
- python3 | |||
- ctags (recommended, not required) | |||
Please note, I use cygwin term exclusively for any command line options. | |||
Unless mentioned otherwise, use it. Do NOT use CMD or Powershell. | |||
Also install the [Windows version of CMake](http://cmake.org/cmake/resources/software.html) | |||
(3+ is ideal) - Select "Do not add CMake to system PATH". This is in addition | |||
to the Cygwin version. This is an easier alternative to installing another C | |||
compiler. Add the following line to your .bashrc, making sure the CMake path | |||
is correct: | |||
echo "alias wincmake=\"PATH='/cygdrive/c/Program Files (x86)/CMake'/bin:'${PATH}' cmake -G 'Unix Makefiles'\"" >> ~/.bashrc | |||
Install the [PJRC Virtual Serial Port Driver](http://pjrc.com/teensy/serial_install.exe). | |||
Next, install the compiler(s) you want. | |||
### AVR GCC | |||
You just need the | |||
[Atmel AVR 8-bit Toolchain](http://www.atmel.com/tools/atmelavrtoolchainforwindows.aspx). | |||
The latest should be fine, as of writing it was 3.4.3. | |||
Extract the files to a directory, say `C:\avr8-gnu-toolchain`. Then copy all | |||
the folders in that directory to the Cygwin `/usr/local` directory. Mine is | |||
`C:\cygwin64\usr\local`. (You can also just setup the paths, but this is | |||
faster/simpler. Might screw up your Cygwin though). | |||
### ARM EABI | |||
Download the latest | |||
[GNU Tools for Embedded Processors | |||
gcc-arm-none-eabi](https://launchpad.net/gcc-arm-embedded/+download). | |||
Download `gcc-arm-none-eabi*win32.zip`. | |||
Then extract all the folders/files in the zip to the Cygwin `/usr/local` | |||
directory. Mine is `C:\cygwin64\usr\local`. Or, you can setup paths using | |||
the installer (you have to be more careful, avoid spaces in paths). | |||
CMake Info | |||
---------- | |||
One of the big benefits of using CMake is the ability to build multiple | |||
configurations (for different microcontrollers) at the same time. The | |||
following sections explain in detail what each CMakeLists.txt configuration | |||
option does and what you can change it to. However, it is possible to | |||
configure each of these options using the `-D` command line flag. | |||
For example, to build the Infinity Keyboard default configuration: | |||
```bash | |||
$ mkdir build_infinity | |||
$ cd build_infinity | |||
$ cmake -DCHIP=mk20dx128vlf5 -DScanModule=MD1 -DMacroModule=PartialMap \ | |||
-DOutputModule=pjrcUSB -DDebugModule=full -DBaseMap=defaultMap \ | |||
-DDefaultMap="md1Overlay stdFuncMap" -DPartialMaps="hhkbpro2" \ | |||
.. | |||
$ make | |||
``` | |||
CMake defaults to the values specified in CMakeLists.txt if not overridden via | |||
the command line. | |||
> NOTE: On Windows, you will have to use "wincmake" instead of "cmake". | |||
Selecting Microcontroller | |||
------------------------- | |||
This is where you select the chip you want to compile for. The build system | |||
will automatically select the compiler needed to compile for your chip. | |||
Open up CMakeLists.txt in your favourite text editor. You are looking for: | |||
```cmake | |||
### | |||
# Chip Selection | |||
# | |||
#| You _MUST_ set this to match the microcontroller you are trying to compile for | |||
#| You _MUST_ clean the build directory if you change this value | |||
#| | |||
set( CHIP | |||
# "at90usb162" # Teensy 1.0 (avr) | |||
# "atmega32u4" # Teensy 2.0 (avr) | |||
# "at90usb646" # Teensy++ 1.0 (avr) | |||
# "at90usb1286" # Teensy++ 2.0 (avr) | |||
# "mk20dx128" # Teensy 3.0 (arm) | |||
"mk20dx128vlf5" # McHCK mk20dx128vlf5 | |||
# "mk20dx256" # Teensy 3.1 (arm) | |||
CACHE STRING "Microcontroller Chip" ) | |||
``` | |||
Just uncomment the chip you want, and comment out the old one. | |||
> NOTE: If you change this option, you will *need* to delete the build | |||
> directory that is created in the Building sections below. | |||
Selecting Modules | |||
----------------- | |||
> WARNING: Not all modules are compatible, and some modules may have | |||
> dependencies on other modules. | |||
This is where the options start getting interesting. The Kiibohd Controller | |||
is designed around a set of 4 types of modules that correspond to different | |||
functionality: | |||
- Scan Module | |||
- Macro Module | |||
- Output Module | |||
- Debug Module | |||
The Scan Module is where the most interesting stuff happens. These modules | |||
take in "keypress data". A converter Scan Module will interpret a protocol | |||
into key press/releases. A matrix Scan Module may inherit from the matrix | |||
module to scan keypress from a matrix This module just has to give | |||
press/release codes, but does have some callback control to other modules | |||
depending on the lifecycle for press/release codes (this can be very | |||
complicated depending on the protocol). Each Scan Module has it's own default | |||
keymap/modifier map. (TODO recommend keymap changing in the Macro Module). | |||
Some scan modules have very specialized hardware requirements, each module | |||
directory should have at least a link to the needed parts and/or schematics | |||
(TODO!). | |||
The Macro Module takes care of the mapping of the key press/release code into | |||
an Output (USB) scan code. Any layering, macros, keypress | |||
intelligence/reaction is done here. | |||
The Output Module is the module dealing with output from the microcontroller. | |||
Currently USB is the only output protocol. Different USB output | |||
implementations are available, pjrc being the safest/least featureful one. | |||
Debug capabilities may depend on the module selected. | |||
The Debug Module enables various things like the Teensy LED on errors, debug | |||
terminal output. (TODO get true UART working in avr, not just arm) | |||
Open up CMakeLists.txt in your favourite text editor. Look for: | |||
```cmake | |||
### | |||
# Project Modules | |||
# | |||
#| Note: This is the only section you probably want to modify | |||
#| Each module is defined by it's own folder (e.g. Scan/Matrix represents the "Matrix" module) | |||
#| All of the modules must be specified, as they generate the sources list of files to compile | |||
#| Any modifications to this file will cause a complete rebuild of the project | |||
#| 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 "MD1" | |||
CACHE STRING "Scan Module" ) | |||
##| Provides the mapping functions for DefaultMap and handles any macro processing before sending to the OutputModule | |||
set( MacroModule "PartialMap" | |||
CACHE STRING "Macro Module" ) | |||
##| Sends the current list of usb key codes through USB HID | |||
set( OutputModule "pjrcUSB" | |||
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" ) | |||
``` | |||
Look at each module individually for it's requirements. There is | |||
chip/architecture dependency checking but some permutations of modules may not | |||
be tested/compile. | |||
There are also CMake options for temporarily selecting modules. But it's | |||
easier to just edit the file. e.g. `cmake -DScanModuleOverride=<module name>`. | |||
Linux Building | |||
-------------- | |||
From this directory. | |||
```bash | |||
$ mkdir build | |||
$ cd build | |||
$ cmake .. | |||
$ make | |||
``` | |||
Example output: | |||
``` | |||
$ cmake .. | |||
-- Compiler Family: | |||
arm | |||
-- Chip Selected: | |||
mk20dx128vlf5 | |||
-- Chip Family: | |||
mk20dx | |||
-- CPU Selected: | |||
cortex-m4 | |||
-- Compiler Source Files: | |||
Lib/mk20dx.c;Lib/delay.c | |||
-- Bootloader Type: | |||
dfu | |||
-- Detected Scan Module Source Files: | |||
Scan/MD1/scan_loop.c;Scan/MD1/../MatrixARM/matrix_scan.c | |||
-- Detected Macro Module Source Files: | |||
Macro/PartialMap/macro.c | |||
-- Detected Output Module Source Files: | |||
Output/pjrcUSB/output_com.c;Output/pjrcUSB/arm/usb_desc.c;Output/pjrcUSB/arm/usb_dev.c; | |||
Output/pjrcUSB/arm/usb_keyboard.c;Output/pjrcUSB/arm/usb_mem.c;Output/pjrcUSB/arm/usb_serial.c | |||
-- Detected Debug Module Source Files: | |||
Debug/full/../cli/cli.c;Debug/full/../led/led.c;Debug/full/../print/print.c | |||
-- Found Git: /usr/bin/git (found version "2.2.1") | |||
-- Found Ctags: /usr/bin/ctags (found version "5.8") | |||
-- Checking for latest kll version: | |||
Current branch master is up to date. | |||
-- Detected Layout Files: | |||
/home/hyatt/Source/controller/Macro/PartialMap/capabilities.kll | |||
/home/hyatt/Source/controller/Output/pjrcUSB/capabilities.kll | |||
/home/hyatt/Source/controller/Scan/MD1/defaultMap.kll | |||
/home/hyatt/Source/controller/kll/layouts/md1Overlay.kll | |||
/home/hyatt/Source/controller/kll/layouts/stdFuncMap.kll | |||
/home/hyatt/Source/controller/kll/layouts/hhkbpro2.kll | |||
-- Configuring done | |||
-- Generating done | |||
-- Build files have been written to: /home/hyatt/Source/controller/build | |||
[master]: make [~/Source/controller/build](hyatt@x230mas:pts/6) | |||
[ 5%] Generating KLL Layout | |||
Scanning dependencies of target kiibohd.elf | |||
[ 11%] Building C object CMakeFiles/kiibohd.elf.dir/main.c.o | |||
[ 17%] Building C object CMakeFiles/kiibohd.elf.dir/Lib/mk20dx.c.o | |||
[ 23%] Building C object CMakeFiles/kiibohd.elf.dir/Lib/delay.c.o | |||
[ 29%] Building C object CMakeFiles/kiibohd.elf.dir/Scan/MD1/scan_loop.c.o | |||
[ 35%] Building C object CMakeFiles/kiibohd.elf.dir/Scan/MatrixARM/matrix_scan.c.o | |||
[ 41%] Building C object CMakeFiles/kiibohd.elf.dir/Macro/PartialMap/macro.c.o | |||
[ 47%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/output_com.c.o | |||
[ 52%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/arm/usb_desc.c.o | |||
[ 58%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/arm/usb_dev.c.o | |||
[ 64%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/arm/usb_keyboard.c.o | |||
[ 70%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/arm/usb_mem.c.o | |||
[ 76%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/arm/usb_serial.c.o | |||
[ 82%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/cli/cli.c.o | |||
[ 88%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/led/led.c.o | |||
[ 94%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/print/print.c.o | |||
Linking C executable kiibohd.elf | |||
[ 94%] Built target kiibohd.elf | |||
Scanning dependencies of target SizeAfter | |||
[100%] Chip usage for mk20dx128vlf5 | |||
SRAM: 32% 5384/16384 bytes | |||
Flash: 18% 23384/126976 bytes | |||
[100%] Built target SizeAfter | |||
``` | |||
Linux Loading Firmware | |||
---------------------- | |||
First place the keyboard into re-flash mode. This can be done either by | |||
pressing the re-flash button on the PCB/Teensy. Or by entering the Kiibohd | |||
Virtual Serial Port and using the 'reload' command. | |||
The `load` script that is created during the build can load the firmware over | |||
USB. Either run it with sudo, or install the `98-kiibohd.rules` to | |||
`/etc/udev/rules.d` and run: `udevadm control --reload-rules`. | |||
To load the newly built firmware: `./load`. | |||
Linux Building Bootloader | |||
------------------------- | |||
> NOTE: Does not apply to Teensy based builds. | |||
From this directory. | |||
```bash | |||
$ cd Bootloader | |||
$ mkdir build | |||
$ cd build | |||
$ cmake .. | |||
$ make | |||
``` | |||
Example output: | |||
```bash | |||
$ cmake .. | |||
-- Compiler Family: | |||
arm | |||
-- Chip Selected: | |||
mk20dx128vlf5 | |||
-- Chip Family: | |||
mk20dx | |||
-- CPU Selected: | |||
cortex-m4 | |||
-- Compiler Source Files: | |||
Lib/mk20dx.c;Lib/delay.c | |||
-- Bootloader Type: | |||
dfu | |||
-- Bootloader Source Files: | |||
main.c;dfu.c;dfu.desc.c;flash.c;kinetis.c;usb.c | |||
-- Found Git: /usr/bin/git (found version "2.2.1") | |||
-- Found Ctags: /usr/bin/ctags (found version "5.8") | |||
-- Configuring done | |||
-- Generating done | |||
-- Build files have been written to: /home/hyatt/Source/controller/Bootloader/build | |||
[master]: make [~/Source/controller/Bootloader/build](hyatt@x230mas:pts/6) | |||
Scanning dependencies of target kiibohd_bootloader.elf | |||
[ 11%] Building C object CMakeFiles/kiibohd_bootloader.elf.dir/main.c.o | |||
[ 22%] Building C object CMakeFiles/kiibohd_bootloader.elf.dir/dfu.c.o | |||
[ 33%] Building C object CMakeFiles/kiibohd_bootloader.elf.dir/dfu.desc.c.o | |||
[ 44%] Building C object CMakeFiles/kiibohd_bootloader.elf.dir/flash.c.o | |||
[ 55%] Building C object CMakeFiles/kiibohd_bootloader.elf.dir/kinetis.c.o | |||
[ 66%] Building C object CMakeFiles/kiibohd_bootloader.elf.dir/usb.c.o | |||
[ 77%] Building C object CMakeFiles/kiibohd_bootloader.elf.dir/home/hyatt/Source/controller/Lib/mk20dx.c.o | |||
[ 88%] Building C object CMakeFiles/kiibohd_bootloader.elf.dir/home/hyatt/Source/controller/Lib/delay.c.o | |||
Linking C executable kiibohd_bootloader.elf | |||
[ 88%] Built target kiibohd_bootloader.elf | |||
Scanning dependencies of target SizeAfter | |||
[100%] Chip usage for mk20dx128vlf5 | |||
SRAM: 19% 3176/16384 bytes | |||
Flash: 2% 3736/126976 bytes | |||
[100%] Built target SizeAfter | |||
``` | |||
Linux Loading Bootloader | |||
------------------------ | |||
> NOTE: Does not apply to Teensy based builds. | |||
It's recommended to use an SWD-type flasher like a Bus Pirate. There is a | |||
convenience script for loading the firmware once the system is setup. | |||
```bash | |||
$ cd Bootloader/Scripts | |||
$ ./swdLoad.bash | |||
``` | |||
The above script requires Ruby, Ruby serial port module, git, and a | |||
`/dev/buspirate` udev rule. | |||
Additional Notes: | |||
* https://github.com/mchck/mchck/wiki/Getting-Started (See Bus-Pirate section) | |||
* https://wiki.archlinux.org/index.php/Bus_pirate | |||
Windows Building | |||
---------------- | |||
From this directory. | |||
```bash | |||
$ mkdir build | |||
$ cd build | |||
$ wincmake .. | |||
$ make | |||
``` | |||
Example output: | |||
```bash | |||
$ wincmake .. | |||
-- Compiler Family: | |||
arm | |||
-- Chip Selected: | |||
mk20dx128vlf5 | |||
-- Chip Family: | |||
mk20dx | |||
-- CPU Selected: | |||
cortex-m4 | |||
-- Compiler Source Files: | |||
Lib/mk20dx.c;Lib/delay.c | |||
-- Bootloader Type: | |||
dfu | |||
-- Detected Scan Module Source Files: | |||
Scan/MD1/scan_loop.c;Scan/MD1/../MatrixARM/matrix_scan.c | |||
-- Detected Macro Module Source Files: | |||
Macro/PartialMap/macro.c | |||
-- Detected Output Module Source Files: | |||
Output/pjrcUSB/output_com.c;Output/pjrcUSB/arm/usb_desc.c;Output/pjrcUSB/arm/usb_dev.c;Output/pjrcUSB/arm/usb_keyboard.c;Output/pjrcUSB/arm/usb_mem.c;Output/pjrcUSB/arm/usb_serial.c | |||
-- Detected Debug Module Source Files: | |||
Debug/full/../cli/cli.c;Debug/full/../led/led.c;Debug/full/../print/print.c | |||
-- Found Git: C:/cygwin64/bin/git.exe (found version "2.1.1") | |||
-- Found Ctags: C:/cygwin64/bin/ctags.exe (found version "5.8") | |||
-- Checking for latest kll version: | |||
Current branch master is up to date. | |||
-- Detected Layout Files: | |||
C:/cygwin64/home/Jacob/controller/Macro/PartialMap/capabilities.kll | |||
C:/cygwin64/home/Jacob/controller/Output/pjrcUSB/capabilities.kll | |||
C:/cygwin64/home/Jacob/controller/Scan/MD1/defaultMap.kll | |||
C:/cygwin64/home/Jacob/controller/kll/layouts/md1Overlay.kll | |||
C:/cygwin64/home/Jacob/controller/kll/layouts/stdFuncMap.kll | |||
C:/cygwin64/home/Jacob/controller/kll/layouts/hhkbpro2.kll | |||
-- Configuring done | |||
-- Generating done | |||
-- Build files have been written to: C:/cygwin64/home/Jacob/controller/build | |||
$ make | |||
[ 5%] Generating KLL Layout | |||
Scanning dependencies of target kiibohd.elf | |||
[ 11%] Building C object CMakeFiles/kiibohd.elf.dir/main.c.obj | |||
[ 17%] Building C object CMakeFiles/kiibohd.elf.dir/Lib/mk20dx.c.obj | |||
[ 23%] Building C object CMakeFiles/kiibohd.elf.dir/Lib/delay.c.obj | |||
[ 29%] Building C object CMakeFiles/kiibohd.elf.dir/Scan/MD1/scan_loop.c.obj | |||
[ 35%] Building C object CMakeFiles/kiibohd.elf.dir/Scan/MatrixARM/matrix_scan.c.obj | |||
[ 41%] Building C object CMakeFiles/kiibohd.elf.dir/Macro/PartialMap/macro.c.obj | |||
[ 47%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/output_com.c.obj | |||
[ 52%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/arm/usb_desc.c.obj | |||
[ 58%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/arm/usb_dev.c.obj | |||
[ 64%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/arm/usb_keyboard.c.obj | |||
[ 70%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/arm/usb_mem.c.obj | |||
[ 76%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrcUSB/arm/usb_serial.c.obj | |||
[ 82%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/cli/cli.c.obj | |||
[ 88%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/led/led.c.obj | |||
[ 94%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/print/print.c.obj | |||
Linking C executable kiibohd.elf | |||
[ 94%] Built target kiibohd.elf | |||
Scanning dependencies of target SizeAfter | |||
[100%] Chip usage for mk20dx128vlf5 | |||
SRAM: 32% 5384/16384 bytes | |||
Flash: 18% 23296/126976 bytes | |||
[100%] Built target SizeAfter | |||
``` | |||
### NOTES: | |||
If you get the following error, you have not setup wincmake correctly: | |||
```bash | |||
$ make | |||
[ 5%] Generating KLL Layout | |||
Scanning dependencies of target kiibohd.elf | |||
[ 11%] Building C object CMakeFiles/kiibohd.elf.dir/main.c.o | |||
../main.c:28:19: fatal error: macro.h: No such file or directory | |||
#include <macro.h> | |||
^ | |||
compilation terminated. | |||
CMakeFiles/kiibohd.elf.dir/build.make:67: recipe for target 'CMakeFiles/kiibohd.elf.dir/main.c.o' failed | |||
make[2]: *** [CMakeFiles/kiibohd.elf.dir/main.c.o] Error 1 | |||
CMakeFiles/Makefile2:98: recipe for target 'CMakeFiles/kiibohd.elf.dir/all' failed | |||
make[1]: *** [CMakeFiles/kiibohd.elf.dir/all] Error 2 | |||
Makefile:75: recipe for target 'all' failed | |||
make: *** [all] Error 2 | |||
``` | |||
If you have already added the line to your `~/.bashrc` try restarting your | |||
cygwin shell. | |||
Windows Loading Firmware | |||
------------------------ | |||
First place the keyboard into re-flash mode. This can be done either by | |||
pressing the re-flash button on the PCB/Teensy. Or by entering the Kiibohd | |||
Virtual Serial Interface and using the `reload` command. | |||
The `load` script that is created during the build can load the firmware over | |||
USB. | |||
To load the newly built firmware: `./load` | |||
Be patient the couple of times, Windows is slow at installing drivers... | |||
Mac OS X Building | |||
----------------- | |||
From this directory. | |||
```bash | |||
$ mkdir build | |||
$ cd build | |||
$ cmake .. | |||
$ make | |||
``` | |||
Example output: | |||
> TODO | |||
Mac OS X Loading Firmware | |||
------------------------- | |||
First place the keyboard into re-flash mode. This can be done either by | |||
pressing the re-flash button on the PCB/Teensy. Or by entering the Kiibohd | |||
Virtual Serial Port and using the `reload` command. | |||
The `load` script that is created during the build can load the firmware over | |||
USB. | |||
To load the newly built firmware: `./load`. | |||
Virtual Serial Port - CLI | |||
------------------------- | |||
Rather than use a special program that can interpret Raw HID, this controller exposes a USB Serial CDC endpoint. | |||
This allows for you to use a generic serial terminal to debug/control the keyboard firmware (e.g. Tera Term, minicom, screen) | |||
### Linux | |||
I generally use screen. You will need sudo/root priviledges if you haven't | |||
installed the `98-kiibohd.rules` file to `/etc/udev/rules.d`. | |||
``` | |||
$ screen /dev/ttyACM0 | |||
# (Might be ACM1, ACM2, etc.) | |||
``` | |||
### Windows | |||
Make sure the Teensy Virtual Serial Port driver is installed. If possible use | |||
screen (as part of Cygwin). Check which COM port the virtual serial port has | |||
been assigned to: `Device Manager->Ports (COM & LPT)->Teensy USB Serial`. In | |||
brackets it will say which COM port (e.g. COM3) | |||
putty works well when using DTR/DSR or RTS/CTS flow control. | |||
| Setting | Value | | |||
| --------------- | ------------------------------------- | | |||
| Connection type | Serial | | |||
| Serial line | Your COM port, e.g. COM3 | | |||
| Speed | doesn't matter, it's auto-negotiated | | |||
Under `Category->Connections->Serial`: `Flow control: DTR/DSR`. | |||
If stuff is hard to read (you have a dumb colour scheme): | |||
`Category->Window->Colours->Use system color`. That seems to make text at | |||
least readable | |||
> I use a custom colour scheme that makes each colour easy to see. | |||
> -HaaTa. | |||
Unfortunately, screen for Cygwin seems to be broken for serial ports, but you | |||
can try it... | |||
```bash | |||
$ screen /dev/ttyS2 | |||
# Might be a different file, ttyS0, ttyACM0, ttyUSB0, etc. | |||
``` | |||
Gnu screen doesn't seem to echo all the characters (it works though). | |||
I believe it's a problem with stty, but I don't know how to fix it... | |||
### Mac OS X | |||
I recommend screen (can be installed via Macports). | |||
```bash | |||
$ screen /dev/tty.<usb something> | |||
``` |
@@ -62,28 +62,28 @@ void analog_init(void) | |||
if (analog_config_bits == 8) { | |||
ADC0_CFG1 = ADC_CFG1_24MHZ + ADC_CFG1_MODE(0); | |||
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3); | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_CFG1 = ADC_CFG1_24MHZ + ADC_CFG1_MODE(0); | |||
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3); | |||
#endif | |||
} else if (analog_config_bits == 10) { | |||
ADC0_CFG1 = ADC_CFG1_12MHZ + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP; | |||
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3); | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_CFG1 = ADC_CFG1_12MHZ + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP; | |||
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3); | |||
#endif | |||
} else if (analog_config_bits == 12) { | |||
ADC0_CFG1 = ADC_CFG1_12MHZ + ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP; | |||
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2); | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_CFG1 = ADC_CFG1_12MHZ + ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP; | |||
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2); | |||
#endif | |||
} else { | |||
ADC0_CFG1 = ADC_CFG1_12MHZ + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP; | |||
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2); | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_CFG1 = ADC_CFG1_12MHZ + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP; | |||
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2); | |||
#endif | |||
@@ -91,12 +91,12 @@ void analog_init(void) | |||
if (analog_reference_internal) { | |||
ADC0_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref | |||
#endif | |||
} else { | |||
ADC0_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref | |||
#endif | |||
} | |||
@@ -104,27 +104,27 @@ void analog_init(void) | |||
num = analog_num_average; | |||
if (num <= 1) { | |||
ADC0_SC3 = ADC_SC3_CAL; // begin cal | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_SC3 = ADC_SC3_CAL; // begin cal | |||
#endif | |||
} else if (num <= 4) { | |||
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(0); | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(0); | |||
#endif | |||
} else if (num <= 8) { | |||
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(1); | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(1); | |||
#endif | |||
} else if (num <= 16) { | |||
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(2); | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(2); | |||
#endif | |||
} else { | |||
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(3); | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(3); | |||
#endif | |||
} | |||
@@ -140,7 +140,7 @@ static void wait_for_cal(void) | |||
while (ADC0_SC3 & ADC_SC3_CAL) { | |||
// wait | |||
} | |||
#elif defined(_mk20dx256_) | |||
#elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
while ((ADC0_SC3 & ADC_SC3_CAL) || (ADC1_SC3 & ADC_SC3_CAL)) { | |||
// wait | |||
} | |||
@@ -160,7 +160,7 @@ static void wait_for_cal(void) | |||
//serial_print("ADC0_MG = "); | |||
//serial_phex16(sum); | |||
//serial_print("\n"); | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
sum = ADC1_CLPS + ADC1_CLP4 + ADC1_CLP3 + ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0; | |||
sum = (sum / 2) | 0x8000; | |||
ADC1_PG = sum; | |||
@@ -192,7 +192,7 @@ void analogReference(uint8_t type) | |||
analog_reference_internal = 1; | |||
if (calibrating) { | |||
ADC0_SC3 = 0; // cancel cal | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_SC3 = 0; // cancel cal | |||
#endif | |||
} | |||
@@ -204,7 +204,7 @@ void analogReference(uint8_t type) | |||
analog_reference_internal = 0; | |||
if (calibrating) { | |||
ADC0_SC3 = 0; // cancel cal | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
ADC1_SC3 = 0; // cancel cal | |||
#endif | |||
} | |||
@@ -266,7 +266,7 @@ static const uint8_t channel2sc1a[] = { | |||
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, | |||
0, 19, 3, 21, 26, 22, 23 | |||
}; | |||
#elif defined(_mk20dx256_) | |||
#elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
static const uint8_t channel2sc1a[] = { | |||
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, | |||
0, 19, 3, 19+128, 26, 22, 23, | |||
@@ -284,7 +284,7 @@ static const uint8_t channel2sc1a[] = { | |||
// TODO: perhaps this should store the NVIC priority, so it works recursively? | |||
static volatile uint8_t analogReadBusyADC0 = 0; | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
static volatile uint8_t analogReadBusyADC1 = 0; | |||
#endif | |||
@@ -300,7 +300,7 @@ int analogRead(uint8_t pin) | |||
index = pin; // 0-13 refer to A0-A13 | |||
} else if (pin <= 23) { | |||
index = pin - 14; // 14-23 are A0-A9 | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
} else if (pin >= 26 && pin <= 31) { | |||
index = pin - 9; // 26-31 are A15-A20 | |||
#endif | |||
@@ -323,7 +323,7 @@ int analogRead(uint8_t pin) | |||
if (calibrating) wait_for_cal(); | |||
//pin = 5; // PTD1/SE5b, pin 14, analog 0 | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
if (channel & 0x80) goto beginADC1; | |||
#endif | |||
@@ -350,7 +350,7 @@ startADC0: | |||
yield(); | |||
} | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
beginADC1: | |||
__disable_irq(); | |||
startADC1: | |||
@@ -387,7 +387,7 @@ startADC1: | |||
void analogWriteDAC0(int val) | |||
{ | |||
#if defined(_mk20dx256_) | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) | |||
SIM_SCGC2 |= SIM_SCGC2_DAC0; | |||
if (analog_reference_internal) { | |||
DAC0_C0 = DAC_C0_DACEN; // 1.2V ref is DACREF_1 |
@@ -67,7 +67,7 @@ volatile uint8_t KeyIndex_BufferUsed; | |||
// Scan Module command dictionary | |||
char scanCLIDictName[] = "ADC Test Module Commands"; | |||
const CLIDictItem scanCLIDict[] = { | |||
#if defined(_mk20dx128_) || defined(_mk20dx256_) // ARM | |||
#if defined(_mk20dx128_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM | |||
{ "adc", "Read the specified number of values from the ADC at the given pin: <pin> [# of reads]" | |||
NL "\t\t See \033[35mLib/pin_map.teensy3\033[0m for ADC0 channel number.", cliFunc_adc }, | |||
{ "adcInit", "Intialize/calibrate ADC: <ADC Resolution> <Vref> <Hardware averaging samples>" | |||
@@ -75,7 +75,7 @@ const CLIDictItem scanCLIDict[] = { | |||
NL "\t\t Vref -> 0 (1.2 V), 1 (External)" | |||
NL "\t\tHw Avg Samples -> 0 (disabled), 4, 8, 16, 32", cliFunc_adcInit }, | |||
#endif | |||
#if defined(_mk20dx256_) // DAC is only supported on Teensy 3.1 | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // DAC is only supported on Teensy 3.1 | |||
{ "dac", "Set DAC output value, from 0 to 4095 (1/4096 Vref to Vref).", cliFunc_dac }, | |||
{ "dacVref", "Set DAC Vref. 0 is 1.2V. 1 is 3.3V.", cliFunc_dacVref }, | |||
#endif | |||
@@ -94,7 +94,7 @@ inline void Scan_setup() | |||
// Register Scan CLI dictionary | |||
CLI_registerDictionary( scanCLIDict, scanCLIDictName ); | |||
} | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM | |||
{ | |||
// Register Scan CLI dictionary | |||
CLI_registerDictionary( scanCLIDict, scanCLIDictName ); | |||
@@ -103,7 +103,7 @@ inline void Scan_setup() | |||
VREF_TRM = 0x60; | |||
VREF_SC = 0xE1; // Enable 1.2V Vref | |||
#if defined(_mk20dx256_) // DAC is only supported on Teensy 3.1 | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // DAC is only supported on Teensy 3.1 | |||
// DAC Setup | |||
SIM_SCGC2 |= SIM_SCGC2_DAC0; | |||
DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS; // 3.3V VDDA is DACREF_2 | |||
@@ -167,7 +167,7 @@ void cliFunc_adc( char* args ) | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
{ | |||
} | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM | |||
{ | |||
// Parse code from argument | |||
// NOTE: Only first argument is used | |||
@@ -220,7 +220,7 @@ void cliFunc_adcInit( char* args ) | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
{ | |||
} | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM | |||
{ | |||
// Parse code from argument | |||
// NOTE: Only first argument is used | |||
@@ -335,7 +335,7 @@ void cliFunc_adcInit( char* args ) | |||
void cliFunc_dac( char* args ) | |||
{ | |||
#if defined(_mk20dx256_) // DAC is only supported on Teensy 3.1 | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // DAC is only supported on Teensy 3.1 | |||
// Parse code from argument | |||
// NOTE: Only first argument is used | |||
char* arg1Ptr; | |||
@@ -354,7 +354,7 @@ void cliFunc_dac( char* args ) | |||
void cliFunc_dacVref( char* args ) | |||
{ | |||
#if defined(_mk20dx256_) // DAC is only supported on Teensy 3.1 | |||
#if defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // DAC is only supported on Teensy 3.1 | |||
// Parse code from argument | |||
// NOTE: Only first argument is used | |||
char* arg1Ptr; |
@@ -1,6 +1,6 @@ | |||
###| CMake Kiibohd Controller Scan Module |### | |||
# | |||
# Written by Jacob Alexander in 2013-2014 for the Kiibohd Controller | |||
# Written by Jacob Alexander in 2013-2015 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
@@ -10,21 +10,15 @@ | |||
### | |||
# Module C files | |||
# | |||
set( SCAN_SRCS | |||
set ( Module_SRCS | |||
scan_loop.c | |||
) | |||
### | |||
# Module Specific Options | |||
# | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( ScanModuleCompatibility | |||
set ( ModuleCompatibility | |||
avr | |||
) | |||
@@ -61,7 +61,7 @@ void removeKeyValue( uint8_t keyValue ); | |||
// UART Receive Buffer Full Interrupt | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
ISR(USART1_RX_vect) | |||
#elif defined(_mk20dx128_) // ARM | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM | |||
void uart0_status_isr(void) | |||
#endif | |||
{ | |||
@@ -72,7 +72,7 @@ void uart0_status_isr(void) | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
keyValue = UDR1; | |||
#elif defined(_mk20dx128_) // ARM | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM | |||
// UART0_S1 must be read for the interrupt to be cleared | |||
if ( UART0_S1 & UART_S1_RDRF ) | |||
{ | |||
@@ -129,7 +129,7 @@ inline void Scan_setup() | |||
// Reset the keyboard before scanning, we might be in a wierd state | |||
Scan_resetKeyboard(); | |||
} | |||
#elif defined(_mk20dx128_) // ARM | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM | |||
{ | |||
// Setup the the UART interface for keyboard data input | |||
SIM_SCGC4 |= SIM_SCGC4_UART0; // Disable clock gating | |||
@@ -345,7 +345,7 @@ uint8_t Scan_sendData( uint8_t dataPayload ) | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
UDR1 = dataPayload; | |||
#elif defined(_mk20dx128_) // ARM | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM | |||
UART0_D = dataPayload; | |||
#endif | |||
@@ -22,13 +22,10 @@ | |||
#ifndef __MATRIX_H | |||
#define __MATRIX_H | |||
// ----- Macros ----- | |||
// ----- Includes ----- | |||
// Convenience Macros | |||
#define gpio( port, pin ) { Port_##port, Pin_##pin } | |||
#define Matrix_colsNum sizeof( Matrix_cols ) / sizeof( GPIO_Pin ) | |||
#define Matrix_rowsNum sizeof( Matrix_rows ) / sizeof( GPIO_Pin ) | |||
#define Matrix_maxKeys sizeof( Matrix_scanArray ) / sizeof( KeyState ) | |||
// Project Includes | |||
#include <matrix_setup.h> | |||
@@ -0,0 +1,73 @@ | |||
Name = MD1; | |||
Version = 0.2; | |||
Author = "HaaTa (Jacob Alexander) 2014"; | |||
KLL = 0.3; | |||
# Modified Date | |||
Date = 2014-09-14; | |||
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"Tab"; | |||
S0x0F : U"Q"; | |||
S0x10 : U"W"; | |||
S0x11 : U"E"; | |||
S0x12 : U"R"; | |||
S0x13 : U"T"; | |||
S0x14 : U"Y"; | |||
S0x15 : U"U"; | |||
S0x16 : U"I"; | |||
S0x17 : U"O"; | |||
S0x18 : U"P"; | |||
S0x19 : U"LBrace"; | |||
S0x1A : U"RBrace"; | |||
S0x1B : U"Backspace"; | |||
S0x1C : U"Ctrl"; | |||
S0x1D : U"A"; | |||
S0x1E : U"S"; | |||
S0x1F : U"D"; | |||
S0x20 : U"F"; | |||
S0x21 : U"G"; | |||
S0x22 : U"H"; | |||
S0x23 : U"J"; | |||
S0x24 : U"K"; | |||
S0x25 : U"L"; | |||
S0x26 : U"Semicolon"; | |||
S0x27 : U"Quote"; | |||
S0x28 : U"Enter"; | |||
S0x29 : U"LShift"; | |||
S0x2A : U"Z"; | |||
S0x2B : U"X"; | |||
S0x2C : U"C"; | |||
S0x2D : U"V"; | |||
S0x2E : U"B"; | |||
S0x2F : U"N"; | |||
S0x30 : U"M"; | |||
S0x31 : U"Comma"; | |||
S0x32 : U"Period"; | |||
S0x33 : U"Slash"; | |||
S0x34 : U"RShift"; | |||
S0x35 : U"Function1"; # Fun key | |||
S0x36 : U"Function2"; # Left Blank Key | |||
S0x37 : U"LAlt"; | |||
S0x38 : U"LGui"; | |||
S0x39 : U"Space"; | |||
S0x3A : U"RGui"; | |||
S0x3B : U"RAlt"; | |||
S0x3C : U"Function3"; # Right Blank Key 1 | |||
S0x3D : U"Function4"; # Right Blank Key 2 | |||
S0x3E : U"BackTick"; | |||
@@ -8,27 +8,25 @@ | |||
### | |||
# Module C files | |||
# Required Submodules | |||
# | |||
set( SCAN_SRCS | |||
scan_loop.c | |||
../MatrixARM/matrix_scan.c | |||
) | |||
AddModule ( Scan MatrixARM ) | |||
### | |||
# Module Specific Options | |||
# Module C files | |||
# | |||
add_definitions( | |||
-I${HEAD_DIR}/Scan/MatrixARM | |||
set ( Module_SRCS | |||
scan_loop.c | |||
) | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( ScanModuleCompatibility | |||
set ( ModuleCompatibility | |||
arm | |||
) | |||
@@ -0,0 +1,73 @@ | |||
Name = MD1; | |||
Version = 0.2; | |||
Author = "HaaTa (Jacob Alexander) 2014"; | |||
KLL = 0.3; | |||
# Modified Date | |||
Date = 2014-09-14; | |||
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"Tab"; | |||
S0x0F : U"Q"; | |||
S0x10 : U"W"; | |||
S0x11 : U"E"; | |||
S0x12 : U"R"; | |||
S0x13 : U"T"; | |||
S0x14 : U"Y"; | |||
S0x15 : U"U"; | |||
S0x16 : U"I"; | |||
S0x17 : U"O"; | |||
S0x18 : U"P"; | |||
S0x19 : U"LBrace"; | |||
S0x1A : U"RBrace"; | |||
S0x1B : U"Backspace"; | |||
S0x1C : U"Ctrl"; | |||
S0x1D : U"A"; | |||
S0x1E : U"S"; | |||
S0x1F : U"D"; | |||
S0x20 : U"F"; | |||
S0x21 : U"G"; | |||
S0x22 : U"H"; | |||
S0x23 : U"J"; | |||
S0x24 : U"K"; | |||
S0x25 : U"L"; | |||
S0x26 : U"Semicolon"; | |||
S0x27 : U"Quote"; | |||
S0x28 : U"Enter"; | |||
S0x29 : U"LShift"; | |||
S0x2A : U"Z"; | |||
S0x2B : U"X"; | |||
S0x2C : U"C"; | |||
S0x2D : U"V"; | |||
S0x2E : U"B"; | |||
S0x2F : U"N"; | |||
S0x30 : U"M"; | |||
S0x31 : U"Comma"; | |||
S0x32 : U"Period"; | |||
S0x33 : U"Slash"; | |||
S0x34 : U"RShift"; | |||
S0x35 : U"Function1"; # Fun key | |||
S0x36 : U"Function2"; # Left Blank Key | |||
S0x37 : U"LAlt"; | |||
S0x38 : U"LGui"; | |||
S0x39 : U"Space"; | |||
S0x3A : U"RGui"; | |||
S0x3B : U"RAlt"; | |||
S0x3C : U"Function3"; # Right Blank Key 1 | |||
S0x3D : U"Function4"; # Right Blank Key 2 | |||
S0x3E : U"BackTick"; | |||
@@ -0,0 +1,63 @@ | |||
/* 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. | |||
*/ | |||
#ifndef __MATRIX_H | |||
#define __MATRIX_H | |||
// ----- Macros ----- | |||
// Convenience Macros | |||
#define gpio( port, pin ) { Port_##port, Pin_##pin } | |||
#define Matrix_colsNum sizeof( Matrix_cols ) / sizeof( GPIO_Pin ) | |||
#define Matrix_rowsNum sizeof( Matrix_rows ) / sizeof( GPIO_Pin ) | |||
#define Matrix_maxKeys sizeof( Matrix_scanArray ) / sizeof( KeyState ) | |||
// ----- 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(B,0), gpio(B,1), gpio(B,2), gpio(B,3), gpio(B,16), gpio(B,17), gpio(C,4), gpio(C,5), 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; | |||
#endif // __MATRIX_H | |||
@@ -0,0 +1,118 @@ | |||
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 | |||
PTB1 - SDA0 | |||
* Reserve - Might be used later if I2C bus is too slow with more than 1 ISSI chip | |||
PTE0 - SDA1 | |||
PTE1 - SCL1 | |||
* ISSI Control (enough pins for 3 chips reserved) | |||
PTC0 - INTB Chip 1 | |||
PTC1 - INTB Chip 2 | |||
PTC2 - INTB Chip 3 (Only needed if more than 96 RGB LEDs are required) | |||
PTA4 - SDB (tied to tall Chips, hardware shutdown) | |||
--- | |||
|DAC| | |||
--- | |||
DAC0 (N/C) | |||
---- | |||
|UART| | |||
---- | |||
* Comm - Will be used on split keyboards | |||
PTC3 - RX1 (N/C) | |||
PTC4 - TX1 (N/C) | |||
----- | |||
|Debug| | |||
----- | |||
* SWD - (Main reflash header) | |||
PTA0 (Pull-down) | |||
PTA3 (Pull-up) | |||
* LEDs | |||
PTA5 (LED only for PCB, not Teensy) | |||
* UARTs | |||
PTA1 - RX0 (UART Debug Header) | |||
PTA2 - TX0 (UART Debug Header) | |||
------ | |||
|Unused| | |||
------ | |||
* GPIO | |||
PTA12 | |||
PTA13 | |||
PTB2 | |||
PTB3 | |||
PTB16 | |||
PTB17 | |||
PTB18 | |||
PTB19 | |||
PTC5 | |||
PTC6 | |||
PTC7 | |||
PTC8 | |||
PTC9 | |||
PTC10 | |||
PTC11 | |||
PTD0 | |||
PTD1 | |||
PTD2 | |||
PTD3 | |||
PTD4 | |||
PTD5 | |||
PTD6 | |||
PTD7 | |||
* Analog | |||
TODO | |||
@@ -0,0 +1,682 @@ | |||
/* 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> | |||
// Local Includes | |||
#include "scan_loop.h" | |||
#include "macro.h" | |||
typedef struct I2C_Buffer { | |||
uint16_t head; | |||
uint16_t tail; | |||
uint8_t sequencePos; | |||
uint16_t size; | |||
uint8_t *buffer; | |||
} I2C_Buffer; | |||
// ----- Function Declarations ----- | |||
// CLI Functions | |||
void cliFunc_echo( char* args ); | |||
void cliFunc_i2cRecv( char* args ); | |||
void cliFunc_i2cSend( char* args ); | |||
void cliFunc_ledZero( char* args ); | |||
uint8_t I2C_TxBufferPop(); | |||
void I2C_BufferPush( uint8_t byte, I2C_Buffer *buffer ); | |||
uint16_t I2C_BufferLen( I2C_Buffer *buffer ); | |||
uint8_t I2C_Send( uint8_t *data, uint8_t sendLen, uint8_t recvLen ); | |||
// ----- Variables ----- | |||
// Scan Module command dictionary | |||
CLIDict_Entry( echo, "Example command, echos the arguments." ); | |||
CLIDict_Entry( i2cRecv, "Send I2C sequence of bytes and expect a reply of 1 byte on the last sequence. Use |'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( ledZero, "Zero out LED register pages (non-configuration)." ); | |||
CLIDict_Def( scanCLIDict, "Scan Module Commands" ) = { | |||
CLIDict_Item( echo ), | |||
CLIDict_Item( i2cRecv ), | |||
CLIDict_Item( i2cSend ), | |||
CLIDict_Item( ledZero ), | |||
{ 0, 0, 0 } // Null entry for dictionary end | |||
}; | |||
// Number of scans since the last USB send | |||
uint16_t Scan_scanCount = 0; | |||
// Before sending the sequence, I2C_TxBuffer_CurLen is assigned and as each byte is sent, it is decremented | |||
// Once I2C_TxBuffer_CurLen reaches zero, a STOP on the I2C bus is sent | |||
#define I2C_TxBufferLength 300 | |||
#define I2C_RxBufferLength 8 | |||
volatile uint8_t I2C_TxBufferPtr[ I2C_TxBufferLength ]; | |||
volatile uint8_t I2C_RxBufferPtr[ I2C_TxBufferLength ]; | |||
volatile I2C_Buffer I2C_TxBuffer = { 0, 0, 0, I2C_TxBufferLength, (uint8_t*)I2C_TxBufferPtr }; | |||
volatile I2C_Buffer I2C_RxBuffer = { 0, 0, 0, I2C_RxBufferLength, (uint8_t*)I2C_RxBufferPtr }; | |||
void I2C_setup() | |||
{ | |||
// Enable I2C internal clock | |||
SIM_SCGC4 |= SIM_SCGC4_I2C0; // Bus 0 | |||
// External pull-up resistor | |||
PORTB_PCR0 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2); | |||
PORTB_PCR1 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2); | |||
// SCL Frequency Divider | |||
// 400kHz -> 120 (0x85) @ 48 MHz F_BUS | |||
I2C0_F = 0x85; | |||
I2C0_FLT = 4; | |||
I2C0_C1 = I2C_C1_IICEN; | |||
I2C0_C2 = I2C_C2_HDRS; // High drive select | |||
// Enable I2C Interrupt | |||
NVIC_ENABLE_IRQ( IRQ_I2C0 ); | |||
} | |||
// ----- Interrupt Functions ----- | |||
void i2c0_isr() | |||
{ | |||
cli(); // Disable Interrupts | |||
uint8_t status = I2C0_S; // Read I2C Bus status | |||
// Master Mode Transmit | |||
if ( I2C0_C1 & I2C_C1_TX ) | |||
{ | |||
// Check current use of the I2C bus | |||
// Currently sending data | |||
if ( I2C_TxBuffer.sequencePos > 0 ) | |||
{ | |||
// Make sure slave sent an ACK | |||
if ( status & I2C_S_RXAK ) | |||
{ | |||
// NACK Detected, disable interrupt | |||
erro_print("I2C NAK detected..."); | |||
I2C0_C1 = I2C_C1_IICEN; | |||
// Abort Tx Buffer | |||
I2C_TxBuffer.head = 0; | |||
I2C_TxBuffer.tail = 0; | |||
I2C_TxBuffer.sequencePos = 0; | |||
} | |||
else | |||
{ | |||
// Transmit byte | |||
I2C0_D = I2C_TxBufferPop(); | |||
} | |||
} | |||
// Receiving data | |||
else if ( I2C_RxBuffer.sequencePos > 0 ) | |||
{ | |||
// Master Receive, addr sent | |||
if ( status & I2C_S_ARBL ) | |||
{ | |||
// Arbitration Lost | |||
erro_print("Arbitration lost..."); | |||
// TODO Abort Rx | |||
I2C0_C1 = I2C_C1_IICEN; | |||
I2C0_S = I2C_S_ARBL | I2C_S_IICIF; // Clear ARBL flag and interrupt | |||
} | |||
if ( status & I2C_S_RXAK ) | |||
{ | |||
// Slave Address NACK Detected, disable interrupt | |||
erro_print("Slave Address I2C NAK detected..."); | |||
// TODO Abort Rx | |||
I2C0_C1 = I2C_C1_IICEN; | |||
} | |||
else | |||
{ | |||
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 | |||
} | |||
} | |||
else | |||
{ | |||
/* | |||
dbug_msg("STOP - "); | |||
printHex( I2C_BufferLen( (I2C_Buffer*)&I2C_TxBuffer ) ); | |||
print(NL); | |||
*/ | |||
// Delay around STOP to make sure it actually happens... | |||
delayMicroseconds( 1 ); | |||
I2C0_C1 = I2C_C1_IICEN; // Send STOP | |||
delayMicroseconds( 7 ); | |||
// If there is another sequence, start sending | |||
if ( I2C_BufferLen( (I2C_Buffer*)&I2C_TxBuffer ) < I2C_TxBuffer.size ) | |||
{ | |||
// Clear status flags | |||
I2C0_S = I2C_S_IICIF | I2C_S_ARBL; | |||
// Wait...till the master dies | |||
while ( I2C0_S & I2C_S_BUSY ); | |||
// Enable I2C interrupt | |||
I2C0_C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TX; | |||
// Transmit byte | |||
I2C0_D = I2C_TxBufferPop(); | |||
} | |||
} | |||
} | |||
// Master Mode Receive | |||
else | |||
{ | |||
// XXX Do we need to handle 2nd last byte? | |||
//I2C0_C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TXAK; // No STOP, Rx, NAK on recv | |||
// Last byte | |||
if ( I2C_TxBuffer.sequencePos <= 1 ) | |||
{ | |||
// Change to Tx mode | |||
I2C0_C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX; | |||
// Grab last byte | |||
I2C_BufferPush( I2C0_D, (I2C_Buffer*)&I2C_RxBuffer ); | |||
delayMicroseconds( 1 ); // Should be enough time before issuing the stop | |||
I2C0_C1 = I2C_C1_IICEN; // Send STOP | |||
} | |||
else | |||
{ | |||
// Retrieve data | |||
I2C_BufferPush( I2C0_D, (I2C_Buffer*)&I2C_RxBuffer ); | |||
} | |||
} | |||
I2C0_S = I2C_S_IICIF; // Clear interrupt | |||
sei(); // Re-enable Interrupts | |||
} | |||
// ----- Functions ----- | |||
void LED_zeroPages( uint8_t startPage, uint8_t numPages, uint8_t pageLen ) | |||
{ | |||
// Page Setup | |||
uint8_t pageSetup[] = { 0xE8, 0xFD, 0x00 }; | |||
// Max length of a page + chip id + reg start | |||
uint8_t fullPage[ 0xB3 + 2 ] = { 0 }; | |||
fullPage[0] = 0xE8; // Set chip id, starting reg is already 0x00 | |||
// Iterate through given pages, zero'ing out the given register regions | |||
for ( uint8_t page = startPage; page < startPage + numPages; page++ ) | |||
{ | |||
// Set page | |||
pageSetup[2] = page; | |||
// Setup page | |||
while ( I2C_Send( pageSetup, sizeof( pageSetup ), 0 ) == 0 ) | |||
delay(1); | |||
// Zero out page | |||
while ( I2C_Send( fullPage, pageLen + 2, 0 ) == 0 ) | |||
delay(1); | |||
} | |||
} | |||
// Setup | |||
inline void LED_setup() | |||
{ | |||
I2C_setup(); | |||
// Zero out Frame Registers | |||
LED_zeroPages( 0x00, 8, 0xB3 ); // LED Registers | |||
LED_zeroPages( 0x0B, 1, 0x0C ); // Control Registers | |||
// Disable Hardware shutdown of ISSI chip (pull high) | |||
GPIOD_PDDR |= (1<<1); | |||
PORTD_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); | |||
GPIOD_PSOR |= (1<<1); | |||
} | |||
inline uint8_t I2C_BufferCopy( uint8_t *data, uint8_t sendLen, uint8_t recvLen, I2C_Buffer *buffer ) | |||
{ | |||
uint8_t reTurn = 0; | |||
// If sendLen is greater than buffer fail right away | |||
if ( sendLen > buffer->size ) | |||
return 0; | |||
// Calculate new tail to determine if buffer has enough space | |||
// The first element specifies the expected number of bytes from the slave (+1) | |||
// The second element in the new buffer is the length of the buffer sequence (+1) | |||
uint16_t newTail = buffer->tail + sendLen + 2; | |||
if ( newTail >= buffer->size ) | |||
newTail -= buffer->size; | |||
if ( I2C_BufferLen( buffer ) < sendLen + 2 ) | |||
return 0; | |||
/* | |||
print("|"); | |||
printHex( sendLen + 2 ); | |||
print("|"); | |||
printHex( *tail ); | |||
print("@"); | |||
printHex( newTail ); | |||
print("@"); | |||
*/ | |||
// If buffer is clean, return 1, otherwise 2 | |||
reTurn = buffer->head == buffer->tail ? 1 : 2; | |||
// Add to buffer, already know there is enough room (simplifies adding logic) | |||
uint8_t bufferHeaderPos = 0; | |||
for ( uint16_t c = 0; c < sendLen; c++ ) | |||
{ | |||
// Add data to buffer | |||
switch ( bufferHeaderPos ) | |||
{ | |||
case 0: | |||
buffer->buffer[ buffer->tail ] = recvLen; | |||
bufferHeaderPos++; | |||
c--; | |||
break; | |||
case 1: | |||
buffer->buffer[ buffer->tail ] = sendLen; | |||
bufferHeaderPos++; | |||
c--; | |||
break; | |||
default: | |||
buffer->buffer[ buffer->tail ] = data[ c ]; | |||
break; | |||
} | |||
// Check for wrap-around case | |||
if ( buffer->tail + 1 >= buffer->size ) | |||
{ | |||
buffer->tail = 0; | |||
} | |||
// Normal case | |||
else | |||
{ | |||
buffer->tail++; | |||
} | |||
} | |||
return reTurn; | |||
} | |||
inline uint16_t I2C_BufferLen( I2C_Buffer *buffer ) | |||
{ | |||
// Tail >= Head | |||
if ( buffer->tail >= buffer->head ) | |||
return buffer->head + buffer->size - buffer->tail; | |||
// Head > Tail | |||
return buffer->head - buffer->tail; | |||
} | |||
void I2C_BufferPush( uint8_t byte, I2C_Buffer *buffer ) | |||
{ | |||
// Make sure buffer isn't full | |||
if ( buffer->tail + 1 == buffer->head || ( buffer->head > buffer->tail && buffer->tail + 1 - buffer->size == buffer->head ) ) | |||
{ | |||
warn_msg("I2C_BufferPush failed, buffer full: "); | |||
printHex( byte ); | |||
print( NL ); | |||
return; | |||
} | |||
// Check for wrap-around case | |||
if ( buffer->tail + 1 >= buffer->size ) | |||
{ | |||
buffer->tail = 0; | |||
} | |||
// Normal case | |||
else | |||
{ | |||
buffer->tail++; | |||
} | |||
// Add byte to buffer | |||
buffer->buffer[ buffer->tail ] = byte; | |||
} | |||
uint8_t I2C_TxBufferPop() | |||
{ | |||
// Return 0xFF if no buffer left (do not rely on this) | |||
if ( I2C_BufferLen( (I2C_Buffer*)&I2C_TxBuffer ) >= I2C_TxBuffer.size ) | |||
{ | |||
erro_msg("No buffer to pop an entry from... "); | |||
printHex( I2C_TxBuffer.head ); | |||
print(" "); | |||
printHex( I2C_TxBuffer.tail ); | |||
print(" "); | |||
printHex( I2C_TxBuffer.sequencePos ); | |||
print(NL); | |||
return 0xFF; | |||
} | |||
// If there is currently no sequence being sent, the first entry in the RingBuffer is the length | |||
if ( I2C_TxBuffer.sequencePos == 0 ) | |||
{ | |||
I2C_TxBuffer.sequencePos = 0xFF; // So this doesn't become an infinite loop | |||
I2C_RxBuffer.sequencePos = I2C_TxBufferPop(); | |||
I2C_TxBuffer.sequencePos = I2C_TxBufferPop(); | |||
} | |||
uint8_t data = I2C_TxBuffer.buffer[ I2C_TxBuffer.head ]; | |||
// Prune head | |||
I2C_TxBuffer.head++; | |||
// Wrap-around case | |||
if ( I2C_TxBuffer.head >= I2C_TxBuffer.size ) | |||
I2C_TxBuffer.head = 0; | |||
// Decrement buffer sequence (until next stop will be sent) | |||
I2C_TxBuffer.sequencePos--; | |||
/* | |||
dbug_msg("Popping: "); | |||
printHex( data ); | |||
print(" "); | |||
printHex( I2C_TxBuffer.head ); | |||
print(" "); | |||
printHex( I2C_TxBuffer.tail ); | |||
print(" "); | |||
printHex( I2C_TxBuffer.sequencePos ); | |||
print(NL); | |||
*/ | |||
return data; | |||
} | |||
uint8_t I2C_Send( uint8_t *data, uint8_t sendLen, uint8_t recvLen ) | |||
{ | |||
// Check head and tail pointers | |||
// If full, return 0 | |||
// If empty, start up I2C Master Tx | |||
// If buffer is non-empty and non-full, just append to the buffer | |||
switch ( I2C_BufferCopy( data, sendLen, recvLen, (I2C_Buffer*)&I2C_TxBuffer ) ) | |||
{ | |||
// Not enough buffer space... | |||
case 0: | |||
/* | |||
erro_msg("Not enough Tx buffer space... "); | |||
printHex( I2C_TxBuffer.head ); | |||
print(":"); | |||
printHex( I2C_TxBuffer.tail ); | |||
print("+"); | |||
printHex( sendLen ); | |||
print("|"); | |||
printHex( I2C_TxBuffer.size ); | |||
print( NL ); | |||
*/ | |||
return 0; | |||
// Empty buffer, initialize I2C | |||
case 1: | |||
// Clear status flags | |||
I2C0_S = I2C_S_IICIF | I2C_S_ARBL; | |||
// Check to see if we already have control of the bus | |||
if ( I2C0_C1 & I2C_C1_MST ) | |||
{ | |||
// Already the master (ah yeah), send a repeated start | |||
I2C0_C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_RSTA | I2C_C1_TX; | |||
} | |||
// Otherwise, seize control | |||
else | |||
{ | |||
// Wait...till the master dies | |||
while ( I2C0_S & I2C_S_BUSY ); | |||
// Now we're the master (ah yisss), get ready to send stuffs | |||
I2C0_C1 = I2C_C1_IICEN | I2C_C1_MST | I2C_C1_TX; | |||
} | |||
// Enable I2C interrupt | |||
I2C0_C1 = I2C_C1_IICEN | I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TX; | |||
// Depending on what type of transfer, the first byte is configured for R or W | |||
I2C0_D = I2C_TxBufferPop(); | |||
return 1; | |||
} | |||
// Dirty buffer, I2C already initialized | |||
return 2; | |||
} | |||
// LED State processing loop | |||
inline uint8_t LED_loop() | |||
{ | |||
// I2C Busy | |||
// S & I2C_S_BUSY | |||
//I2C_S_BUSY | |||
} | |||
// 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; | |||
// Setup LED Drivers | |||
LED_setup(); | |||
} | |||
// Main Detection Loop | |||
inline uint8_t Scan_loop() | |||
{ | |||
//Matrix_scan( Scan_scanCount++ ); | |||
//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; | |||
} | |||
// ----- 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 ); | |||
} | |||
} | |||
void cliFunc_i2cSend( char* args ) | |||
{ | |||
char* curArgs; | |||
char* arg1Ptr; | |||
char* arg2Ptr = args; | |||
// Buffer used after interpretting the args, will be sent to I2C functions | |||
// NOTE: Limited to 8 bytes currently (can be increased if necessary | |||
#define i2cSend_BuffLenMax 8 | |||
uint8_t buffer[ i2cSend_BuffLenMax ]; | |||
uint8_t bufferLen = 0; | |||
// No \r\n by default after the command is entered | |||
print( NL ); | |||
info_msg("Sending: "); | |||
// Parse args until a \0 is found | |||
while ( bufferLen < i2cSend_BuffLenMax ) | |||
{ | |||
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; | |||
// If | is found, end sequence and start new one | |||
if ( *arg1Ptr == '|' ) | |||
{ | |||
print("| "); | |||
I2C_Send( buffer, bufferLen, 0 ); | |||
bufferLen = 0; | |||
continue; | |||
} | |||
// Interpret the argument | |||
buffer[ bufferLen++ ] = (uint8_t)numToInt( arg1Ptr ); | |||
// Print out the arg | |||
dPrint( arg1Ptr ); | |||
print(" "); | |||
} | |||
print( NL ); | |||
I2C_Send( buffer, bufferLen, 0 ); | |||
} | |||
void cliFunc_i2cRecv( char* args ) | |||
{ | |||
char* curArgs; | |||
char* arg1Ptr; | |||
char* arg2Ptr = args; | |||
// Buffer used after interpretting the args, will be sent to I2C functions | |||
// NOTE: Limited to 8 bytes currently (can be increased if necessary | |||
#define i2cSend_BuffLenMax 8 | |||
uint8_t buffer[ i2cSend_BuffLenMax ]; | |||
uint8_t bufferLen = 0; | |||
// No \r\n by default after the command is entered | |||
print( NL ); | |||
info_msg("Sending: "); | |||
// Parse args until a \0 is found | |||
while ( bufferLen < i2cSend_BuffLenMax ) | |||
{ | |||
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; | |||
// If | is found, end sequence and start new one | |||
if ( *arg1Ptr == '|' ) | |||
{ | |||
print("| "); | |||
I2C_Send( buffer, bufferLen, 0 ); | |||
bufferLen = 0; | |||
continue; | |||
} | |||
// Interpret the argument | |||
buffer[ bufferLen++ ] = (uint8_t)numToInt( arg1Ptr ); | |||
// Print out the arg | |||
dPrint( arg1Ptr ); | |||
print(" "); | |||
} | |||
print( NL ); | |||
I2C_Send( buffer, bufferLen, 1 ); // Only 1 byte is ever read at a time with the ISSI chip | |||
} | |||
void cliFunc_ledZero( char* args ) | |||
{ | |||
print( NL ); // No \r\n by default after the command is entered | |||
LED_zeroPages( 0x00, 8, 0xB3 ); | |||
} | |||
@@ -1,15 +1,15 @@ | |||
/* Copyright (C) 2011 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 | |||
* 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 | |||
@@ -19,52 +19,26 @@ | |||
* THE SOFTWARE. | |||
*/ | |||
#ifndef print_h__ | |||
#define print_h__ | |||
#ifndef __SCAN_LOOP_H | |||
#define __SCAN_LOOP_H | |||
// ----- Disabler Defines ----- | |||
// ----- Includes ----- | |||
#define dPrint(c) | |||
#define dPrintStr(c) | |||
#define dPrintStrs(...) | |||
#define dPrintStrNL(c) | |||
#define dPrintStrsNL(...) | |||
// Compiler Includes | |||
#include <stdint.h> | |||
// Special Msg Constructs (Uses VT100 tags) | |||
#define dPrintMsg(colour_code_str,msg,...) | |||
#define printMsg(colour_code_str,msg,str) | |||
// Info Messages | |||
#define info_dPrint(...) | |||
#define info_print(str) | |||
// Warning Messages | |||
#define warn_dPrint(...) | |||
#define warn_print(str) | |||
// ----- Functions ----- | |||
// Error Messages | |||
#define erro_dPrint(...) | |||
#define erro_print(str) | |||
// Functions to be called by main.c | |||
void Scan_setup( void ); | |||
uint8_t Scan_loop( void ); | |||
// Debug Messages | |||
#define dbug_dPrint(...) | |||
#define dbug_print(str) | |||
// Call-backs | |||
void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module | |||
void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module | |||
// Static String Printing | |||
#define print(s) _print(PSTR(s)) | |||
// Output Functions | |||
#define _print(s) | |||
#define usb_debug_putstr(s) | |||
#define usb_debug_putstrs(s, ...) | |||
// String Functions | |||
#define hexToStr(hex, out) | |||
#define int8ToStr(in, out) | |||
#define int16ToStr(in, out) | |||
#define hexToStr_op(in, out, op) | |||
#define revsStr(in) | |||
#define lenStr(in) | |||
#endif | |||
#endif // __SCAN_LOOP_H | |||
@@ -0,0 +1,31 @@ | |||
###| 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 ) | |||
### | |||
# Module C files | |||
# | |||
set( Module_SRCS | |||
scan_loop.c | |||
) | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( ModuleCompatibility | |||
arm | |||
) | |||
@@ -1,15 +1,15 @@ | |||
/* Copyright (C) 2011 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 | |||
* 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 | |||
@@ -19,12 +19,17 @@ | |||
* THE SOFTWARE. | |||
*/ | |||
#ifndef __led_h | |||
#define __led_h | |||
#ifndef __MATRIX_SETUP_H | |||
#define __MATRIX_SETUP_H | |||
// ----- Disabler Defines ----- | |||
#define init_errorLED() | |||
#define errorLED(on) | |||
// ----- Macros ----- | |||
#endif | |||
// Convenience Macros | |||
#define gpio( port, pin ) { Port_##port, Pin_##pin } | |||
#define Matrix_colsNum sizeof( Matrix_cols ) / sizeof( GPIO_Pin ) | |||
#define Matrix_rowsNum sizeof( Matrix_rows ) / sizeof( GPIO_Pin ) | |||
#define Matrix_maxKeys sizeof( Matrix_scanArray ) / sizeof( KeyState ) | |||
#endif // __MATRIX_SETUP_H | |||
@@ -1,36 +1,30 @@ | |||
###| CMake Kiibohd Controller Scan Module |### | |||
# | |||
# Written by Jacob Alexander in 2014 for the Kiibohd Controller | |||
# Written by Jacob Alexander in 2014-2015 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# | |||
### | |||
### | |||
# Warning, that this module is not meant to be built stand-alone | |||
# Sub-module flag, cannot be included stand-alone | |||
# | |||
message( FATAL_ERROR | |||
"The 'MatrixARM' module is not a stand-alone module, and requires further setup." | |||
) | |||
set ( SubModule 1 ) | |||
### | |||
# Module C files | |||
# | |||
set( SCAN_SRCS | |||
set ( Module_SRCS | |||
matrix_scan.c | |||
) | |||
### | |||
# Module Specific Options | |||
# | |||
### | |||
# Compiler Family Compatibility | |||
# | |||
set( ScanModuleCompatibility | |||
set ( ModuleCompatibility | |||
arm | |||
) | |||