Browse Source

Merge remote-tracking branch 'upstream/master'

simple
Rowan Decker 9 years ago
parent
commit
88ace02e51
65 changed files with 2717 additions and 1008 deletions
  1. 17
    1
      Bootloader/CMakeLists.txt
  2. 18
    0
      Bootloader/Scripts/easyMode.bash
  3. 6
    0
      Bootloader/Scripts/ledTest.bash
  4. 0
    1
      Bootloader/flash.c
  5. 15
    2
      Bootloader/main.c
  6. 16
    1
      CMakeLists.txt
  7. 3
    19
      Debug/cli/setup.cmake
  8. 6
    19
      Debug/full/setup.cmake
  9. 21
    1
      Debug/led/led.c
  10. 3
    14
      Debug/led/setup.cmake
  11. 0
    28
      Debug/off/setup.cmake
  12. 3
    14
      Debug/print/setup.cmake
  13. 34
    7
      Lib/CMake/arm.cmake
  14. 6
    8
      Lib/CMake/avr.cmake
  15. 15
    4
      Lib/CMake/build.cmake
  16. 5
    1
      Lib/CMake/kll.cmake
  17. 72
    71
      Lib/CMake/modules.cmake
  18. 2
    2
      Lib/Interrupts.h
  19. 1
    1
      Lib/MacroLib.h
  20. 1
    1
      Lib/MainLib.h
  21. 1
    1
      Lib/OutputLib.h
  22. 1
    1
      Lib/ScanLib.h
  23. 48
    19
      Lib/mk20dx.c
  24. 1
    1
      Lib/mk20dx.h
  25. 114
    0
      Lib/mk20dx256vlh7.bootloader.ld
  26. 101
    0
      Lib/mk20dx256vlh7.ld
  27. 39
    42
      Lib/pin_map.teensy3
  28. 60
    1
      LoadFile/load.dfu
  29. 62
    3
      LoadFile/load.teensy
  30. 55
    3
      LoadFile/winload.teensy
  31. 1
    1
      Macro/PartialMap/kll.h
  32. 2
    2
      Macro/PartialMap/macro.c
  33. 3
    8
      Macro/PartialMap/setup.cmake
  34. 3
    3
      Output/pjrcUSB/arm/usb_desc.c
  35. 8
    1
      Output/pjrcUSB/arm/usb_dev.c
  36. 1
    1
      Output/pjrcUSB/arm/usb_dev.h
  37. 8
    1
      Output/pjrcUSB/avr/usb_keyboard_serial.c
  38. 1
    1
      Output/pjrcUSB/avr/usb_keyboard_serial.h
  39. 13
    6
      Output/pjrcUSB/output_com.c
  40. 3
    1
      Output/pjrcUSB/output_com.h
  41. 4
    9
      Output/pjrcUSB/setup.cmake
  42. 136
    48
      Output/uartOut/arm/uart_serial.c
  43. 9
    4
      Output/uartOut/output_com.c
  44. 3
    1
      Output/uartOut/output_com.h
  45. 4
    9
      Output/uartOut/setup.cmake
  46. 12
    7
      Output/usbMuxUart/output_com.c
  47. 3
    1
      Output/usbMuxUart/output_com.h
  48. 9
    26
      Output/usbMuxUart/setup.cmake
  49. 0
    489
      README
  50. 643
    0
      README.markdown
  51. 21
    21
      Scan/ADCTest/analog.c
  52. 8
    8
      Scan/ADCTest/scan_loop.c
  53. 3
    9
      Scan/DPH/setup.cmake
  54. 4
    4
      Scan/MBC-55X/scan_loop.c
  55. 3
    6
      Scan/MD1/matrix.h
  56. 73
    0
      Scan/MD1/prototype.kll
  57. 7
    9
      Scan/MD1/setup.cmake
  58. 73
    0
      Scan/MD2/defaultMap.kll
  59. 63
    0
      Scan/MD2/matrix.h
  60. 118
    0
      Scan/MD2/pinout
  61. 682
    0
      Scan/MD2/scan_loop.c
  62. 17
    43
      Scan/MD2/scan_loop.h
  63. 31
    0
      Scan/MD2/setup.cmake
  64. 15
    10
      Scan/MatrixARM/matrix_setup.h
  65. 7
    13
      Scan/MatrixARM/setup.cmake

+ 17
- 1
Bootloader/CMakeLists.txt View File

@@ -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
#

+ 18
- 0
Bootloader/Scripts/easyMode.bash View File

@@ -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


+ 6
- 0
Bootloader/Scripts/ledTest.bash View File

@@ -0,0 +1,6 @@
#!/bin/bash

printf "led\r" > /dev/ttyACM0

exit 0


+ 0
- 1
Bootloader/flash.c View File

@@ -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;

+ 15
- 2
Bootloader/main.c View File

@@ -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 );

+ 16
- 1
CMakeLists.txt View File

@@ -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
#

+ 3
- 19
Debug/cli/setup.cmake View File

@@ -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
)

+ 6
- 19
Debug/full/setup.cmake View File

@@ -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
)

+ 21
- 1
Debug/led/led.c View File

@@ -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
}


+ 3
- 14
Debug/led/setup.cmake View File

@@ -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
)

+ 0
- 28
Debug/off/setup.cmake View File

@@ -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
)


+ 3
- 14
Debug/print/setup.cmake View File

@@ -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
)

+ 34
- 7
Lib/CMake/arm.cmake View File

@@ -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 ()


+ 6
- 8
Lib/CMake/avr.cmake View File

@@ -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

+ 15
- 4
Lib/CMake/build.cmake View File

@@ -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()

+ 5
- 1
Lib/CMake/kll.cmake View File

@@ -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

+ 72
- 71
Lib/CMake/modules.cmake View File

@@ -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
#

+ 2
- 2
Lib/Interrupts.h View File

@@ -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()

+ 1
- 1
Lib/MacroLib.h View File

@@ -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
- 1
Lib/MainLib.h View File

@@ -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>


+ 1
- 1
Lib/OutputLib.h View File

@@ -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>

+ 1
- 1
Lib/ScanLib.h View File

@@ -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>

+ 48
- 19
Lib/mk20dx.c View File

@@ -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 );
}

+ 1
- 1
Lib/mk20dx.h View File

@@ -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

+ 114
- 0
Lib/mk20dx256vlh7.bootloader.ld View File

@@ -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);
}


+ 101
- 0
Lib/mk20dx256vlh7.ld View File

@@ -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);
}


+ 39
- 42
Lib/pin_map.teensy3 View File

@@ -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

+ 60
- 1
LoadFile/load.dfu View File

@@ -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


+ 62
- 3
LoadFile/load.teensy View File

@@ -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


+ 55
- 3
LoadFile/winload.teensy View File

@@ -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


+ 1
- 1
Macro/PartialMap/kll.h View File

@@ -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;

+ 2
- 2
Macro/PartialMap/macro.c View File

@@ -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

+ 3
- 8
Macro/PartialMap/setup.cmake View File

@@ -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
)

+ 3
- 3
Output/pjrcUSB/arm/usb_desc.c View File

@@ -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}
};



+ 8
- 1
Output/pjrcUSB/arm/usb_dev.c View File

@@ -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

+ 1
- 1
Output/pjrcUSB/arm/usb_dev.h View File

@@ -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 );

+ 8
- 1
Output/pjrcUSB/avr/usb_keyboard_serial.c View File

@@ -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

+ 1
- 1
Output/pjrcUSB/avr/usb_keyboard_serial.h View File

@@ -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

+ 13
- 6
Output/pjrcUSB/output_com.c View File

@@ -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

+ 3
- 1
Output/pjrcUSB/output_com.h View File

@@ -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 -----

+ 4
- 9
Output/pjrcUSB/setup.cmake View File

@@ -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
)

+ 136
- 48
Output/uartOut/arm/uart_serial.c View File

@@ -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
}



+ 9
- 4
Output/uartOut/output_com.c View File

@@ -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
}

+ 3
- 1
Output/uartOut/output_com.h View File

@@ -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 -----

+ 4
- 9
Output/uartOut/setup.cmake View File

@@ -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
)

+ 12
- 7
Output/usbMuxUart/output_com.c View File

@@ -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

+ 3
- 1
Output/usbMuxUart/output_com.h View File

@@ -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 -----

+ 9
- 26
Output/usbMuxUart/setup.cmake View File

@@ -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
)

+ 0
- 489
README View File

@@ -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>

+ 643
- 0
README.markdown View File

@@ -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>
```

+ 21
- 21
Scan/ADCTest/analog.c View File

@@ -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

+ 8
- 8
Scan/ADCTest/scan_loop.c View File

@@ -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;

+ 3
- 9
Scan/DPH/setup.cmake View File

@@ -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
)


+ 4
- 4
Scan/MBC-55X/scan_loop.c View File

@@ -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


+ 3
- 6
Scan/MD1/matrix.h View File

@@ -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>




+ 73
- 0
Scan/MD1/prototype.kll View File

@@ -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";


+ 7
- 9
Scan/MD1/setup.cmake View File

@@ -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
)


+ 73
- 0
Scan/MD2/defaultMap.kll View File

@@ -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";


+ 63
- 0
Scan/MD2/matrix.h View File

@@ -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


+ 118
- 0
Scan/MD2/pinout View File

@@ -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


+ 682
- 0
Scan/MD2/scan_loop.c View File

@@ -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 );
}


Debug/off/print.h → Scan/MD2/scan_loop.h View File

@@ -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


+ 31
- 0
Scan/MD2/setup.cmake View File

@@ -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
)


Debug/off/led.h → Scan/MatrixARM/matrix_setup.h View File

@@ -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


+ 7
- 13
Scan/MatrixARM/setup.cmake View File

@@ -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
)