Merge branch 'dev': rewrites, reorganizations, and fixes
new usb library (my attempt at implementing mouse keys and nkro) in (slow) progress a few larger things - new makefile - added descriptions to most entries in the references.md file - moved keyboard layouts to program space - updated for DOX's PCB! :) see the last PCB update checkin for detailsf13
commit
088fcd5136
|
@ -1,3 +1,9 @@
|
|||
*~
|
||||
*.swp
|
||||
|
||||
*.hex
|
||||
*.eep
|
||||
*.elf
|
||||
*.o
|
||||
*.o.dep
|
||||
|
||||
|
|
|
@ -1,319 +0,0 @@
|
|||
## Electronics Stuff
|
||||
|
||||
* [Resistor Color Codes]
|
||||
(http://www.ladyada.net/wiki/lib/exe/fetch.php?hash=a2c6a9&w=501&h=785&media=http%3A%2F%2Fwww.ladyada.net%2Fimages%2Fmetertutorial%2Frescolorcode.jpg)
|
||||
: image
|
||||
|
||||
* from [the Multimeter Tutorial]
|
||||
(http://www.ladyada.net/learn/multimeter/resistance.html)
|
||||
(on <http://ladyada.net/>)
|
||||
|
||||
* [Schematic Symbols]
|
||||
(http://img.docstoccdn.com/thumb/orig/28066054.png)
|
||||
: image
|
||||
|
||||
* [Vcc, Vdd, Vss, etc.]
|
||||
(http://encyclobeamia.solarbotics.net/articles/vxx.html)
|
||||
|
||||
* [Very Basic Circuits]
|
||||
(http://www.seattlerobotics.org/encoder/mar97/basics.html)
|
||||
: column by Kevin Ross for Encoder
|
||||
|
||||
* [Powering Light Emitting Diodes(LEDs)]
|
||||
(http://wolfstone.halloweenhost.com/Lighting/litlpo_PoweringLEDs.html)
|
||||
|
||||
* can also be reached via <http://thewolfstone.com/>
|
||||
-> [ENTER] ('http://thewolfstone.com/Welcome/Home.html)
|
||||
-> [Wolfstone's Haunted Halloween Page]
|
||||
(http://thewolfstone.com/_ar/Halloween.html)
|
||||
-> [technology]
|
||||
(http://wolfstone.halloweenhost.com/Navigation/TechBase.html)
|
||||
-> [powering LEDs]
|
||||
(http://wolfstone.halloweenhost.com/Lighting/litlpo_PoweringLEDs.html)
|
||||
|
||||
* [All About Circuits : Reference]
|
||||
(http://www.allaboutcircuits.com/vol_5/index.html)
|
||||
|
||||
* [Effects of Varying I2C Pull-Up Resistors]
|
||||
(http://dsscircuits.com/articles/effects-of-varying-i2c-pull-up-resistors.html) : article by Wayne Truchsess
|
||||
|
||||
|
||||
## C Stuff
|
||||
|
||||
* [comp.lang.c Frequently Asked Questions]
|
||||
(http://c-faq.com/index.html)
|
||||
|
||||
* [The C Preprocessor]
|
||||
(http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC1)
|
||||
(on <http://gcc.gnu.org/>)
|
||||
|
||||
* [C Library Reference]
|
||||
(http://www.cplusplus.com/reference/)
|
||||
(on <http://cplusplus.com>)
|
||||
|
||||
* [C Operators/Expressions]
|
||||
(http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/CONCEPT/expressions.html)
|
||||
(on <http://www.lix.polytechnique.fr/>)
|
||||
|
||||
* [Bitwise Operators in C and C++: A Tutorial]
|
||||
(http://www.cprogramming.com/tutorial/bitwise_operators.html)
|
||||
(on <http://cprogramming.com/>)
|
||||
|
||||
* [AVR Tutorials - \[TUT\] \[C\] Bit manipulation (AKA "Programming 101")]
|
||||
(http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=37871&start=0)
|
||||
|
||||
* [In C++ is "const" after type ID acceptable?]
|
||||
(http://stackoverflow.com/questions/988069/in-c-is-const-after-type-id-acceptable)
|
||||
(on <http://stackoverflow.com/>)
|
||||
|
||||
* [Arrays and pointers in C]
|
||||
(http://www.ibiblio.org/pub/languages/fortran/append-c.html)
|
||||
(on <http://www.ibiblio.org/>)
|
||||
|
||||
* [how to use array of function pointers?]
|
||||
(http://stackoverflow.com/questions/252748/how-to-use-array-of-function-pointers)
|
||||
(on <http://stackoverflow.com/>)
|
||||
|
||||
* [The Function Pointer Tutorials]
|
||||
(http://www.newty.de/fpt/index.html)
|
||||
|
||||
* [C preprocessor and concatenation]
|
||||
(http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation)
|
||||
(on <http://stackoverflow.com/>)
|
||||
|
||||
* [The New C: Inline Functions]
|
||||
(http://drdobbs.com/184401540)
|
||||
by Randy Meyers
|
||||
(on <http://drdobbs.com/>)
|
||||
|
||||
### For the AVR
|
||||
|
||||
* [AVR Newbie guide]
|
||||
(http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=70673)
|
||||
by stu_san (on <http://www.avrfreaks.net/>)
|
||||
|
||||
* [AVR Libc Library Reference]
|
||||
(http://www.nongnu.org/avr-libc/user-manual/modules.html)
|
||||
|
||||
* [avr-libc/include/avr/iom32u4.h]
|
||||
(http://svn.savannah.nongnu.org/viewvc/trunk/avr-libc/include/avr/iom32u4.h?revision=2288&root=avr-libc&view=markup)
|
||||
: list of registers and associated bit numbers for ATmega32U4
|
||||
|
||||
* [A Brief Tutorial on Programming the AVR without Arduino]
|
||||
(https://www.mainframe.cx/~ckuethe/avr-c-tutorial/)
|
||||
by Chris Kuethe
|
||||
|
||||
|
||||
## Protocol Stuff
|
||||
|
||||
### I²C
|
||||
|
||||
* [Arduino I²C Expansion IO]
|
||||
(http://www.neufeld.newton.ks.us/electronics/?p=241)
|
||||
(from [Keith's Electronics Blog]
|
||||
(http://www.neufeld.newton.ks.us/electronics/))
|
||||
|
||||
* [Arduino Playground :: Wire Library, Explored]
|
||||
(http://arduino.cc/playground/Main/WireLibraryDetailedReference)
|
||||
|
||||
### USB
|
||||
|
||||
* About Keyboard [Scan Codes]
|
||||
(http://geekhack.org/showwiki.php?title=Scan+Codes)
|
||||
(on <http://geekhack.org/>)
|
||||
|
||||
* [USB - boot mode, NKRO, compatibility, etc...]
|
||||
(http://geekhack.org/showthread.php?13162-USB-boot-mode-NKRO-compatibility-etc/page2)
|
||||
: old thread by [Soarer]
|
||||
(http://geekhack.org/member.php?4274-Soarer)
|
||||
(on <http://geekhack.org/>)
|
||||
|
||||
* [USB 2.0 Specification]
|
||||
(http://www.usb.org/developers/docs/usb_20_101111.zip)
|
||||
: zip (from <http://www.usb.org/developers/docs/>)
|
||||
|
||||
* [HID Device Class Definition]
|
||||
(http://www.usb.org/developers/devclass_docs/HID1_11.pdf)
|
||||
: pdf (from <http://www.usb.org/developers/hidpage>)
|
||||
* HID = Human Interface Device
|
||||
|
||||
* [HID Usage Tables]
|
||||
(http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf)
|
||||
: pdf (from <http://www.usb.org/developers/hidpage>)
|
||||
|
||||
|
||||
## Other People's Code
|
||||
|
||||
### Keyboard Firmware
|
||||
|
||||
* zip: [Phantom Firmware from PrinsValium]
|
||||
(http://geekhack.org/attachment.php?attachmentid=38982&d=1327895092)
|
||||
|
||||
* mentioned in the [Building Phantom Hardware and Firmware Mods]
|
||||
(http://geekhack.org/showwiki.php?title=Island:26742)
|
||||
article (on <http://geekhack.org/>)
|
||||
|
||||
* github: [tmk / tmk_keyboard]
|
||||
(https://github.com/tmk/tmk_keyboard)
|
||||
|
||||
* forked by [Pyrolistical / tmk_keyboard]
|
||||
(https://github.com/Pyrolistical/tmk_keyboard/tree/master/fourway)
|
||||
|
||||
* mentioned in the [KeyPoard]
|
||||
(http://geekhack.org/showwiki.php?title=Island:26845)
|
||||
article on <http://geekhack.org/>
|
||||
|
||||
* forked by [riffautae / tmk_keyboard]
|
||||
(https://github.com/riffautae/tmk_keyboard)
|
||||
|
||||
* mentioned on the [Teensy Keyboard Firmware Discussion]
|
||||
(http://geekhack.org/showthread.php?26730-Teensy-Keyboard-Firmware-Discussion/page2)
|
||||
thread on <http://geekhack.org/>
|
||||
|
||||
* github: [humblehacker / keyboard]
|
||||
(https://github.com/humblehacker/keyboard)
|
||||
|
||||
* mentioned on [the humblehacker keyboard website]
|
||||
(http://humblehacker.com/keyboard/)
|
||||
|
||||
* mentioned on [the humblehacker geekhack page]
|
||||
(http://geekhack.org/showwiki.php?title=Island:6292)
|
||||
|
||||
* mentioned on [the designer's blog]
|
||||
(http://humblehacker.com/blog/)
|
||||
|
||||
### USB Libraries
|
||||
|
||||
* [LUFA (2012) (Lightweight USB Framework for AVRs)]
|
||||
(http://www.fourwalledcubicle.com/LUFA.php)
|
||||
|
||||
### TWI Libraries
|
||||
|
||||
* github: [TWI library in C]
|
||||
(https://github.com/arduino/Arduino/tree/master/libraries/Wire/utility)
|
||||
: (arduino / Arduino / libraries / Wire / utility)
|
||||
|
||||
* zip: [i2cmaster]
|
||||
(http://homepage.hispeed.ch/peterfleury/i2cmaster.zip)
|
||||
(by Peter Fleury, on [his homepage]
|
||||
(http://homepage.hispeed.ch/peterfleury/))
|
||||
|
||||
* forum: [Interfacing MCP23018 io expander via Arduino]
|
||||
(http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282150189)
|
||||
: contains a quick MCP23017 library in C++
|
||||
|
||||
* github: [maniacbug / Arduino / libraries / MCP23018]
|
||||
(https://github.com/maniacbug/Arduino/tree/master/libraries/MCP23018)
|
||||
: library in C++
|
||||
|
||||
### USB
|
||||
|
||||
* zip: [PJRC: usb_keyboard]
|
||||
(http://pjrc.com/teensy/usb_keyboard.zip)
|
||||
|
||||
* mentioned on [the PJRC website]
|
||||
(http://pjrc.com/teensy/usb_keyboard.html)
|
||||
|
||||
### Other
|
||||
|
||||
* zip: [PJRC: blinky]
|
||||
(http://pjrc.com/teensy/blinky.zip)
|
||||
|
||||
* mentioned on [the PJRC website]
|
||||
(http://pjrc.com/teensy/gcc.html)
|
||||
|
||||
|
||||
## Hardware Documentation
|
||||
|
||||
* [Microchip: Analog & Interface Product Selector Guide]
|
||||
(http://ww1.microchip.com/downloads/en/DeviceDoc/21060z.pdf)
|
||||
|
||||
* from [the Microchip website (MCP23017 product listing page)]
|
||||
(http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en023499)
|
||||
|
||||
* [MCP23017 / MCP23S17 Data Sheet]
|
||||
(http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf)
|
||||
|
||||
* from [the Microchip website]
|
||||
(http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en023499)
|
||||
|
||||
* [MCP23018 / MCP23S18 Data Sheet]
|
||||
(http://ww1.microchip.com/downloads/en/DeviceDoc/22103a.pdf)
|
||||
|
||||
* from [the Microchip website]
|
||||
(http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en537375)
|
||||
|
||||
* [Teensy 2.0 (ATMEGA32U4) Data Sheet]
|
||||
(http://pjrc.com/teensy/atmega32u4.pdf)
|
||||
|
||||
* from [the PJRC website]
|
||||
(http://pjrc.com/teensy/datasheets.html)
|
||||
|
||||
* [Teensy++ 2.0 (AT90USB1286) Data Sheet]
|
||||
(http://pjrc.com/teensy/at90usb1286.pdf)
|
||||
|
||||
* from [the PJRC website]
|
||||
(http://pjrc.com/teensy/datasheets.html)
|
||||
|
||||
* [Teensy 2.0 Pin Assignments, Using C]
|
||||
(http://pjrc.com/teensy/card2a.pdf)
|
||||
|
||||
* from [the PJRC website]
|
||||
(http://pjrc.com/teensy/datasheets.html)
|
||||
|
||||
* [Teensy 2.0 Pin Assignments, Using Arduino]
|
||||
(http://pjrc.com/teensy/card2b.pdf)
|
||||
|
||||
* from [the PJRC website]
|
||||
(http://pjrc.com/teensy/datasheets.html)
|
||||
|
||||
* [Cherry MX Series Keyswitches : Specifications]
|
||||
(http://www.cherrycorp.com/english/switches/key/mx.htm)
|
||||
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
### Documentation and Design Tools
|
||||
|
||||
* [Markdown: Syntax]
|
||||
(http://daringfireball.net/projects/markdown/syntax)
|
||||
|
||||
* [KiCAD Tutorial]
|
||||
(http://teholabs.com/knowledge/kicad.html)
|
||||
(on <http://teholabs.com/>)
|
||||
|
||||
* mentioned on the [circuit/block-diagram drawing]
|
||||
(http://stackoverflow.com/questions/6422603/circuit-block-diagram-drawing)
|
||||
question (on <http://stackoverflow.com/>)
|
||||
|
||||
* [Ti_k_Z and PGF]
|
||||
(http://www.texample.net/tikz/)
|
||||
: a TeX graphics package
|
||||
|
||||
* mentioned on the [circuit/block-diagram drawing]
|
||||
(http://stackoverflow.com/questions/6422603/circuit-block-diagram-drawing)
|
||||
question (on <http://stackoverflow.com/>)
|
||||
|
||||
* [Documentation (for version 2010-09-28)]
|
||||
(http://www.texample.net/media/pgf/builds/pgfmanualCVS2010-09-28.pdf)
|
||||
: pdf
|
||||
|
||||
* [Example: Block diagram line junctions]
|
||||
(http://www.texample.net/tikz/examples/line-junctions/)
|
||||
|
||||
* [Inkscape : Connector tool tutorial]
|
||||
(http://wiki.inkscape.org/wiki/index.php/UsingTheConnectorTool)
|
||||
|
||||
### Typical Keyboard Information
|
||||
|
||||
* [Keyboard Scan Rates]
|
||||
(http://geekhack.org/showwiki.php?title=Keyboard+scan+rates)
|
||||
list (on <http://geekhack.org/>)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
Released under The MIT License (MIT) (see "license.md")
|
||||
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
|
48
readme.md
48
readme.md
|
@ -4,14 +4,49 @@
|
|||
[ergodox keyboard]: http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard
|
||||
|
||||
|
||||
## About this File
|
||||
|
||||
If you're viewing this on github, please note that directory links will only
|
||||
work if you're viewing this from the directory, and file links will only work
|
||||
if you're viewing this as a file. This is true for all the '.md' files here.
|
||||
The limitation is due to the way github addresses directories and files, and
|
||||
the fact that Markdown doesn't have any way (that I know of) to rewrite the
|
||||
URLs as would be required.
|
||||
|
||||
|
||||
## About this Project
|
||||
|
||||
This project is definitely in beta, but I'll do my best to keep the 'master'
|
||||
branch working. Please see the source (and especially the accompanying '*.md'
|
||||
files) for documentation.
|
||||
branch working. Please see the source (and especially the accompanying '.md'
|
||||
files) for documentation. And [references.md] (references.md) contains lots of
|
||||
good links, along with descriptions.
|
||||
|
||||
If you're just trying to compile, jump to the bottom of the file and read the
|
||||
[Dependencies] (#dependencies-for-building-from-source) section. Once that's
|
||||
taken care of, navigate to the [src] (src) directory, compile using Make, and
|
||||
fire up your teensy loader to transfer the '.hex' file. Just to be safe, you
|
||||
should also check the '.eep' file. If it's larger than 0 bytes, you need to
|
||||
load it too.
|
||||
|
||||
If you're looking to hack on the source, or just feel like reading it, you
|
||||
probably don't need much direction for a small project like this. I'll try to
|
||||
write more later (for people who are new to AVR programming, like I was when I
|
||||
started this project), but for now:
|
||||
* [src/lib] (src/lib) is for generally useful stuff. The TWI and USB libraries
|
||||
are in there, along with the file containing basic key press and release
|
||||
functions.
|
||||
* [src/keyboard] (src/keyboard) is for keyboard specific stuff. All the chip
|
||||
initialization code is there, along with the layout files, the software
|
||||
matrix to hardware matrix mapping, and hardware specific documentation.
|
||||
* [src/main.c] (src/main.c) ties it all together.
|
||||
|
||||
Open issues and such are tracked [on github]
|
||||
(/benblazak/ergodox-firmware/issues).
|
||||
|
||||
|
||||
## Notes
|
||||
|
||||
### (2012-04-11)
|
||||
### (2012-04-11) (first major release on branch 'main')
|
||||
As of now, it looks like we have a working 6-KRO keyboard firmware for a Teensy
|
||||
2.0 with a MCP23018 I/O expander. It's scanning at ~167 Hz, most of which is
|
||||
spent communicating over I²C. This should be fast enough, I think.
|
||||
|
@ -43,7 +78,12 @@ buy!), please stop by. :) .
|
|||
|
||||
* See the PJRC [Getting Started] (http://pjrc.com/teensy/first_use.html) page
|
||||
for instructions on how to set up an AVR programming environment. This
|
||||
project uses C (not Arduino).
|
||||
project uses C (not Arduino), and Make. I'm compiling with GNU tools under
|
||||
Ubuntu, but other environments (especially [WinAVR]
|
||||
(http://winavr.sourceforge.net/) under Windows) should work too.
|
||||
|
||||
* I also assume that you are using [git] (http://git-scm.com/) (for `make
|
||||
clean`).
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,454 @@
|
|||
## Electronics Stuff
|
||||
|
||||
* [Resistor Color Codes]
|
||||
(http://www.ladyada.net/wiki/lib/exe/fetch.php?hash=a2c6a9&w=501&h=785&media=http%3A%2F%2Fwww.ladyada.net%2Fimages%2Fmetertutorial%2Frescolorcode.jpg)
|
||||
: image
|
||||
|
||||
* from [the Multimeter Tutorial]
|
||||
(http://www.ladyada.net/learn/multimeter/resistance.html)
|
||||
(on <http://ladyada.net/>)
|
||||
|
||||
* [Schematic Symbols]
|
||||
(http://img.docstoccdn.com/thumb/orig/28066054.png)
|
||||
: image
|
||||
|
||||
* [Vcc, Vdd, Vss, etc.]
|
||||
(http://encyclobeamia.solarbotics.net/articles/vxx.html)
|
||||
A neat little discussion of the symbols and where they came from.
|
||||
|
||||
* [Very Basic Circuits]
|
||||
(http://www.seattlerobotics.org/encoder/mar97/basics.html)
|
||||
: column by Kevin Ross for Encoder
|
||||
Includes a short thing about pull-up resistors.
|
||||
|
||||
* [Powering Light Emitting Diodes(LEDs)]
|
||||
(http://wolfstone.halloweenhost.com/Lighting/litlpo_PoweringLEDs.html)
|
||||
Can you use one resistor for multiple parallel LEDs? No. Or, you can, but
|
||||
it's not the best idea.
|
||||
|
||||
* can also be reached via <http://thewolfstone.com/>
|
||||
-> [ENTER] ('http://thewolfstone.com/Welcome/Home.html)
|
||||
-> [Wolfstone's Haunted Halloween Page]
|
||||
(http://thewolfstone.com/_ar/Halloween.html)
|
||||
-> [technology]
|
||||
(http://wolfstone.halloweenhost.com/Navigation/TechBase.html)
|
||||
-> [powering LEDs]
|
||||
(http://wolfstone.halloweenhost.com/Lighting/litlpo_PoweringLEDs.html)
|
||||
|
||||
* [All About Circuits : Reference]
|
||||
(http://www.allaboutcircuits.com/vol_5/index.html)
|
||||
Looks like a great collection of info; didn't get to read much of it.
|
||||
|
||||
* [Effects of Varying I2C Pull-Up Resistors]
|
||||
(http://dsscircuits.com/articles/effects-of-varying-i2c-pull-up-resistors.html) : article by Wayne Truchsess
|
||||
Great discussion on the topic, with oscilloscope graphs. The practical
|
||||
takeaway is that 4.7kΩ is a good value for 100kHz I²C, and 2.2kΩ is good
|
||||
for 400kHz.
|
||||
|
||||
|
||||
## C Stuff
|
||||
|
||||
* [comp.lang.c Frequently Asked Questions]
|
||||
(http://c-faq.com/index.html)
|
||||
Really good information, if they happen to address the question you have.
|
||||
|
||||
* [The C Preprocessor]
|
||||
(http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC1)
|
||||
(on <http://gcc.gnu.org/>)
|
||||
One of my main references.
|
||||
|
||||
* [The GNU C Preprocessor]
|
||||
(http://tigcc.ticalc.org/doc/cpp.html#SEC27)
|
||||
A modified version on a different site. Has a few really useful things that
|
||||
I don't think I saw in the official documentation.
|
||||
|
||||
* [C Library Reference]
|
||||
(http://www.cplusplus.com/reference/)
|
||||
(on <http://cplusplus.com>)
|
||||
|
||||
* [C Operators/Expressions]
|
||||
(http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/CONCEPT/expressions.html)
|
||||
(on <http://www.lix.polytechnique.fr/>)
|
||||
|
||||
* [Bitwise Operators in C and C++: A Tutorial]
|
||||
(http://www.cprogramming.com/tutorial/bitwise_operators.html)
|
||||
(on <http://cprogramming.com/>)
|
||||
|
||||
* [AVR Tutorials - \[TUT\] \[C\] Bit manipulation (AKA "Programming 101")]
|
||||
(http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=37871&start=0)
|
||||
|
||||
* [In C++ is "const" after type ID acceptable?]
|
||||
(http://stackoverflow.com/questions/988069/in-c-is-const-after-type-id-acceptable)
|
||||
(on <http://stackoverflow.com/>)
|
||||
|
||||
* [Arrays and pointers in C]
|
||||
(http://www.ibiblio.org/pub/languages/fortran/append-c.html)
|
||||
(on <http://www.ibiblio.org/>)
|
||||
|
||||
* [how to use array of function pointers?]
|
||||
(http://stackoverflow.com/questions/252748/how-to-use-array-of-function-pointers)
|
||||
(on <http://stackoverflow.com/>)
|
||||
|
||||
* [The Function Pointer Tutorials]
|
||||
(http://www.newty.de/fpt/index.html)
|
||||
|
||||
* [C preprocessor and concatenation]
|
||||
(http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation)
|
||||
(on <http://stackoverflow.com/>)
|
||||
|
||||
* [The New C: Inline Functions]
|
||||
(http://drdobbs.com/184401540)
|
||||
by Randy Meyers
|
||||
(on <http://drdobbs.com/>)
|
||||
|
||||
* [gcc: why the -lm flag is needed to link the math library?]
|
||||
(http://stackoverflow.com/questions/4606301/gcc-why-the-lm-flag-is-needed-to-link-the-math-library)
|
||||
(on <http://stackoverflow.com/>)
|
||||
|
||||
### For the AVR
|
||||
|
||||
* [AVR Newbie guide]
|
||||
(http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=70673)
|
||||
by stu_san (on <http://www.avrfreaks.net/>)
|
||||
Didn't read much of it, but it looks like a great collection of info.
|
||||
|
||||
* [AVR Libc Library Reference]
|
||||
(http://www.nongnu.org/avr-libc/user-manual/modules.html)
|
||||
One of my main references.
|
||||
|
||||
* [AVR : Data in Program Space]
|
||||
(http://www.nongnu.org/avr-libc/user-manual/pgmspace.html)
|
||||
How to use '<avr/pgmspace.h>'.
|
||||
|
||||
* [avr-libc/include/avr/iom32u4.h]
|
||||
(http://svn.savannah.nongnu.org/viewvc/trunk/avr-libc/include/avr/iom32u4.h?revision=2288&root=avr-libc&view=markup)
|
||||
List of registers and associated bit numbers for the ATmega32U4
|
||||
|
||||
* [A Brief Tutorial on Programming the AVR without Arduino]
|
||||
(https://www.mainframe.cx/~ckuethe/avr-c-tutorial/)
|
||||
by Chris Kuethe
|
||||
Goes over a bunch of stuff pretty generally. Useful to me because it was
|
||||
talking about exactly what I was trying to do (e.g. program the thing
|
||||
directly instead of messing around with gratuitous libraries).
|
||||
|
||||
* [Optimisations of AVR programs using avr-gcc]
|
||||
(http://www.tty1.net/blog/2008-04-29-avr-gcc-optimisations_en.html)
|
||||
About compiling and stuff.
|
||||
|
||||
* [Using the EEPROM memory in AVR-GCC]
|
||||
(http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=38417)
|
||||
: tutorial by [Dean Camera] (http://fourwalledcubicle.com/AboutMe.php)
|
||||
(on <http://www.avrfreaks.net/>)
|
||||
The EEPROM is non-volatile data memory that can withstand 100,000 writes and
|
||||
is byte accessible from within the program. On the Teensy 2.0 there's only
|
||||
1,024 bytes of it though (compared to 32,256 bytes of flash, and 2,560 bytes
|
||||
of RAM), so you have to use it sparingly. It's useful because flash
|
||||
(program) memory is not really something that's meant to be written to (it
|
||||
can only withstand 10,000 writes, and has to be written in pages using
|
||||
instructions meant for the bootloader), and RAM is volatile.
|
||||
|
||||
* updated version available as a pdf at
|
||||
[Four Walled Cubicle : AVR Articles]
|
||||
(http://www.fourwalledcubicle.com/AVRArticles.php), along with a few
|
||||
other good articles on AVR programming
|
||||
|
||||
|
||||
## Protocol Stuff
|
||||
|
||||
### I²C
|
||||
|
||||
* [Arduino I²C Expansion IO]
|
||||
(http://www.neufeld.newton.ks.us/electronics/?p=241)
|
||||
(from [Keith's Electronics Blog]
|
||||
(http://www.neufeld.newton.ks.us/electronics/))
|
||||
Didn't use this much, but it's nice (if you're using the Arduino 'Wire'
|
||||
library), and it has pictures.
|
||||
|
||||
* [Arduino Playground :: Wire Library, Explored]
|
||||
(http://arduino.cc/playground/Main/WireLibraryDetailedReference)
|
||||
More about the Wire library. If you're not using interrupts, I think you'll
|
||||
be better off looking throught the datasheet and writing your own trivial
|
||||
library in C. It really is trivial, almost all the code is in the datasheet
|
||||
(at least for the ATmega32U4), and it'll make more sense to you that way :) .
|
||||
|
||||
### USB
|
||||
|
||||
* About Keyboard [Scan Codes]
|
||||
(http://geekhack.org/showwiki.php?title=Scan+Codes)
|
||||
(on <http://geekhack.org/>)
|
||||
Interesting discussion. For practical purposes, if you're just dealing with
|
||||
USB, you can skip this and go straight to the keyboard usage page in the HID
|
||||
Usage Tables (see below).
|
||||
|
||||
* [USB - boot mode, NKRO, compatibility, etc...]
|
||||
(http://geekhack.org/showthread.php?13162-USB-boot-mode-NKRO-compatibility-etc/page2)
|
||||
: old thread by [Soarer]
|
||||
(http://geekhack.org/member.php?4274-Soarer)
|
||||
(on <http://geekhack.org/>)
|
||||
Discussion about getting NKRO to work over USB and still be compatible with
|
||||
various BIOSs.
|
||||
|
||||
* [USB 2.0 Specification]
|
||||
(http://www.usb.org/developers/docs/usb_20_101111.zip)
|
||||
: zip (from <http://www.usb.org/developers/docs/>)
|
||||
|
||||
* [HID Device Class Definition]
|
||||
(http://www.usb.org/developers/devclass_docs/HID1_11.pdf)
|
||||
: pdf (from <http://www.usb.org/developers/hidpage>)
|
||||
* HID = Human Interface Device
|
||||
|
||||
* [HID Usage Tables]
|
||||
(http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf)
|
||||
: pdf (from <http://www.usb.org/developers/hidpage>)
|
||||
|
||||
|
||||
## Other People's Code
|
||||
|
||||
### Keyboard Firmware
|
||||
|
||||
* zip: [Phantom Firmware from PrinsValium]
|
||||
(http://geekhack.org/attachment.php?attachmentid=38982&d=1327895092)
|
||||
Pretty basic (unless I'm missing nuances, which is entirely possible).
|
||||
Helped me a lot when I was learning how to initialize stuff on the Teensy.
|
||||
|
||||
* mentioned in the [Building Phantom Hardware and Firmware Mods]
|
||||
(http://geekhack.org/showwiki.php?title=Island:26742)
|
||||
article (on <http://geekhack.org/>)
|
||||
|
||||
* github: [tmk / tmk_keyboard]
|
||||
(https://github.com/tmk/tmk_keyboard)
|
||||
Firmware by [hasu] (http://geekhack.org/member.php?3412-hasu) on geekhack.
|
||||
Supports NKRO and mouse movements.
|
||||
|
||||
* forked by [Pyrolistical / tmk_keyboard]
|
||||
(https://github.com/Pyrolistical/tmk_keyboard/tree/master/fourway)
|
||||
|
||||
* mentioned in the [KeyPoard]
|
||||
(http://geekhack.org/showwiki.php?title=Island:26845)
|
||||
article on <http://geekhack.org/>
|
||||
|
||||
* forked by [riffautae / tmk_keyboard]
|
||||
(https://github.com/riffautae/tmk_keyboard)
|
||||
|
||||
* mentioned on the [Teensy Keyboard Firmware Discussion]
|
||||
(http://geekhack.org/showthread.php?26730-Teensy-Keyboard-Firmware-Discussion/page2)
|
||||
thread on <http://geekhack.org/>
|
||||
|
||||
* github: [humblehacker / keyboard]
|
||||
(https://github.com/humblehacker/keyboard)
|
||||
Looks like it has some cool ideas, but I haven't read through it well enough
|
||||
to know what's going on.
|
||||
|
||||
* mentioned on [the humblehacker keyboard website]
|
||||
(http://humblehacker.com/keyboard/)
|
||||
|
||||
* mentioned on [the humblehacker geekhack page]
|
||||
(http://geekhack.org/showwiki.php?title=Island:6292)
|
||||
|
||||
* mentioned on [the designer's blog]
|
||||
(http://humblehacker.com/blog/)
|
||||
|
||||
### USB Libraries
|
||||
|
||||
* [LUFA (2012) (Lightweight USB Framework for AVRs)]
|
||||
(http://www.fourwalledcubicle.com/LUFA.php)
|
||||
Very well known USB library for AVRs. And it looks like it be really good
|
||||
too, but the documentation is hard to get into, and the examples don't seem
|
||||
to have enough explanation for me, since I don't have any background in what
|
||||
USB is doing in the first place.
|
||||
|
||||
* zip: [PJRC: usb_keyboard]
|
||||
(http://pjrc.com/teensy/usb_keyboard.zip)
|
||||
From the [LUFA Library : Alternative USB AVR Stacks]
|
||||
(http://www.fourwalledcubicle.com/files/LUFA/Doc/110528/html/_page__alternative_stacks.html)
|
||||
page: "Not so much a complete stack as a collection of USB enabled demos,
|
||||
this library is specifically designed for the PJRC Teensy line of USB AVRs,
|
||||
and thus may need to be modified for other USB AVR chips. These minimal code
|
||||
samples shows the inner workings of the USB controller, without all the
|
||||
abstraction present in most other USB AVR stacks."
|
||||
|
||||
* mentioned on [the PJRC website]
|
||||
(http://pjrc.com/teensy/usb_keyboard.html)
|
||||
|
||||
* [V-USB]
|
||||
(http://vusb.wikidot.com/driver-api)
|
||||
From the [LUFA Library : Alternative USB AVR Stacks]
|
||||
(http://www.fourwalledcubicle.com/files/LUFA/Doc/110528/html/_page__alternative_stacks.html)
|
||||
page: "Well regarded and complete USB 1.1 software stack for several AVR
|
||||
models, implementing Low Speed HID. Used in many commercial and
|
||||
non-commercial designs, with user-submitted projects available for viewing on
|
||||
the company's website. Uses C language code mixed with assembly for
|
||||
time-critical sections."
|
||||
Also, it has really good documentation.
|
||||
|
||||
### TWI Libraries
|
||||
|
||||
* github: [TWI library in C]
|
||||
(https://github.com/arduino/Arduino/tree/master/libraries/Wire/utility)
|
||||
: (arduino / Arduino / libraries / Wire / utility)
|
||||
Well done (as far as I can tell) and complete (includes code for interrupt
|
||||
handling). Meant to be used through the Arduino 'Wire' library interface,
|
||||
but you can use it alone as well. The version on github pulls in a whole
|
||||
bunch of Arduino dependencies though, if you're just going to use the
|
||||
library look for an older version that doesn't (like the one included in the
|
||||
version of Arduino in the Ubuntu 11.10 repos).
|
||||
|
||||
* zip: [i2cmaster]
|
||||
(http://homepage.hispeed.ch/peterfleury/i2cmaster.zip)
|
||||
(by Peter Fleury, on [his homepage]
|
||||
(http://homepage.hispeed.ch/peterfleury/))
|
||||
Good I2C library. Includes stuff both in assembly and C (though, I didn't
|
||||
look at the assembly code). I still think you're better off writing your
|
||||
own, it's not that hard and you'll understand it better. Also, this library
|
||||
is under the GPL (from what it says on his site; couldn't find a licence in
|
||||
the code).
|
||||
|
||||
* forum: [Interfacing MCP23018 io expander via Arduino]
|
||||
(http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1282150189)
|
||||
Contains a quick MCP23017 library in C++. Didn't end up looking at it too
|
||||
hard.
|
||||
|
||||
* github: [maniacbug / Arduino / libraries / MCP23018]
|
||||
(https://github.com/maniacbug/Arduino/tree/master/libraries/MCP23018)
|
||||
Library in C++. Don't think I ended up looking through this one at all.
|
||||
|
||||
### Other
|
||||
|
||||
* [Soarer's Converter (XT/AT/PS2/Terminal to USB Converter with NKRO)]
|
||||
(http://geekhack.org/showwiki.php?title=Island:17458)
|
||||
No code for the part that talks over USB though. Code only available for the
|
||||
tools that allow you to change the keymap and stuff, I think.
|
||||
|
||||
* zip: [PJRC: blinky]
|
||||
(http://pjrc.com/teensy/blinky.zip)
|
||||
Little baby example project for the Teensy. Quite nice.
|
||||
|
||||
* mentioned on [the PJRC website]
|
||||
(http://pjrc.com/teensy/gcc.html)
|
||||
|
||||
|
||||
## Hardware Documentation
|
||||
|
||||
* [Microchip: Analog & Interface Product Selector Guide]
|
||||
(http://ww1.microchip.com/downloads/en/DeviceDoc/21060z.pdf)
|
||||
|
||||
* from [the Microchip website (MCP23017 product listing page)]
|
||||
(http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en023499)
|
||||
|
||||
* [MCP23017 / MCP23S17 Data Sheet]
|
||||
(http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf)
|
||||
|
||||
* from [the Microchip website]
|
||||
(http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en023499)
|
||||
|
||||
* [MCP23018 / MCP23S18 Data Sheet]
|
||||
(http://ww1.microchip.com/downloads/en/DeviceDoc/22103a.pdf)
|
||||
|
||||
* from [the Microchip website]
|
||||
(http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en537375)
|
||||
|
||||
* [Teensy 2.0 (ATMEGA32U4) Data Sheet]
|
||||
(http://pjrc.com/teensy/atmega32u4.pdf)
|
||||
|
||||
* from [the PJRC website]
|
||||
(http://pjrc.com/teensy/datasheets.html)
|
||||
|
||||
* [Teensy++ 2.0 (AT90USB1286) Data Sheet]
|
||||
(http://pjrc.com/teensy/at90usb1286.pdf)
|
||||
|
||||
* from [the PJRC website]
|
||||
(http://pjrc.com/teensy/datasheets.html)
|
||||
|
||||
* [Teensy 2.0 Pin Assignments, Using C]
|
||||
(http://pjrc.com/teensy/card2a.pdf)
|
||||
|
||||
* from [the PJRC website]
|
||||
(http://pjrc.com/teensy/datasheets.html)
|
||||
|
||||
* [Teensy 2.0 Pin Assignments, Using Arduino]
|
||||
(http://pjrc.com/teensy/card2b.pdf)
|
||||
|
||||
* from [the PJRC website]
|
||||
(http://pjrc.com/teensy/datasheets.html)
|
||||
|
||||
* [Cherry MX Series Keyswitches : Specifications]
|
||||
(http://www.cherrycorp.com/english/switches/key/mx.htm)
|
||||
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
### Typical Keyboard Information
|
||||
|
||||
* [Keyboard Scan Rates]
|
||||
(http://geekhack.org/showwiki.php?title=Keyboard+scan+rates)
|
||||
list (on <http://geekhack.org/>)
|
||||
Keyboards seem to typically scan at rates from a little below 100Hz to about
|
||||
300Hz, with the most common values a little below 100Hz. The [PJRC
|
||||
usb_keyboard] (http://pjrc.com/teensy/usb_keyboard.html) example
|
||||
documentation has a limit of 1000 packets (so 500 presses -> releases) per
|
||||
second, but says that even that speed might overwhelm host software, which
|
||||
expects keystrokes to come much more slowly. And, a debounce time of 5ms
|
||||
(which is the spec'ed high value for Cherry MX switches) would give us a max
|
||||
scan rate of 200Hz.
|
||||
|
||||
### Other Awesome Keyboard Projects
|
||||
|
||||
* [My DIY keyboard collection ( or how I became a KB-geek...)]
|
||||
(http://deskthority.net/workshop-f7/my-diy-keyboard-collection-or-how-i-became-a-kb-geek-t2534.html)
|
||||
: post by [suka] (http://deskthority.net/suka-u434/)
|
||||
on <http://deskthority.net/>
|
||||
If I ever decide to do a keyboard completely by myself, I'm going back to
|
||||
this link and starting with this. Looks really well done.
|
||||
|
||||
* linked to in [a post]
|
||||
(http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard&p=582593&viewfull=1#post582593)
|
||||
on the ergoDOX geekhack thread
|
||||
|
||||
### Documentation and Design Tools
|
||||
|
||||
* [Markdown: Syntax]
|
||||
(http://daringfireball.net/projects/markdown/syntax)
|
||||
A necessity if your code is on github :) .
|
||||
|
||||
* [KiCAD Tutorial]
|
||||
(http://teholabs.com/knowledge/kicad.html)
|
||||
(on <http://teholabs.com/>)
|
||||
I like the tool. Didn't need the functionality just for a little circuit
|
||||
diagram though, so I forwent the learning curve and used Inkscape.
|
||||
|
||||
* mentioned on the [circuit/block-diagram drawing]
|
||||
(http://stackoverflow.com/questions/6422603/circuit-block-diagram-drawing)
|
||||
question (on <http://stackoverflow.com/>)
|
||||
|
||||
* [Ti<i>k</i>Z and PGF]
|
||||
(http://www.texample.net/tikz/)
|
||||
: a TeX graphics package
|
||||
This is really cool. And I wish i knew more about LaTeX (and all its
|
||||
variations) so that it would have been time effective for me to use it. If I
|
||||
ever need to do automatic diagram generation, I'm going to give this a more
|
||||
serious try.
|
||||
|
||||
* mentioned on the [circuit/block-diagram drawing]
|
||||
(http://stackoverflow.com/questions/6422603/circuit-block-diagram-drawing)
|
||||
question (on <http://stackoverflow.com/>)
|
||||
|
||||
* [Documentation (for version 2010-09-28)]
|
||||
(http://www.texample.net/media/pgf/builds/pgfmanualCVS2010-09-28.pdf)
|
||||
: pdf
|
||||
|
||||
* [Example: Block diagram line junctions]
|
||||
(http://www.texample.net/tikz/examples/line-junctions/)
|
||||
|
||||
* [Inkscape : Connector tool tutorial]
|
||||
(http://wiki.inkscape.org/wiki/index.php/UsingTheConnectorTool)
|
||||
The open source vector graphics tool. Not the _best_ for diagrams (though,
|
||||
see the link; as that tool improves it will hopefully become much better),
|
||||
but it works and I like it :) .
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
Released under The MIT License (MIT) (see "license.md")
|
||||
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* key functions: code
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
||||
|
||||
#include "lib/data-types.h"
|
||||
#include "lib/usb/keyboard-usage-page.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if 0 // not being used right now
|
||||
static uint8_t _inc_current_layer(uint8_t * current_layer) {
|
||||
if (*current_layer < (KB_LAYERS-1))
|
||||
(*current_layer)++;
|
||||
else
|
||||
return 1; // error: can't increase
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
static uint8_t _dec_current_layer(uint8_t * current_layer) {
|
||||
if (*current_layer > 0)
|
||||
(*current_layer)--;
|
||||
else
|
||||
return 1; // error: can't decrease
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void kbfun_press(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
for (uint8_t i=0; i<6; i++)
|
||||
if (keyboard_keys[i] == 0) {
|
||||
keyboard_keys[i] = *keycode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void kbfun_release(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
for (uint8_t i=0; i<6; i++)
|
||||
if (keyboard_keys[i] == *keycode) {
|
||||
keyboard_keys[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void kbfun_mod_press(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
switch (*keycode) {
|
||||
case KEY_LeftControl: keyboard_modifier_keys |= (1<<0); break;
|
||||
case KEY_LeftShift: keyboard_modifier_keys |= (1<<1); break;
|
||||
case KEY_LeftAlt: keyboard_modifier_keys |= (1<<2); break;
|
||||
case KEY_LeftGUI: keyboard_modifier_keys |= (1<<3); break;
|
||||
case KEY_RightControl: keyboard_modifier_keys |= (1<<4); break;
|
||||
case KEY_RightShift: keyboard_modifier_keys |= (1<<5); break;
|
||||
case KEY_RightAlt: keyboard_modifier_keys |= (1<<6); break;
|
||||
case KEY_RightGUI: keyboard_modifier_keys |= (1<<7); break;
|
||||
}
|
||||
}
|
||||
|
||||
void kbfun_mod_release(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
switch (*keycode) {
|
||||
case KEY_LeftControl: keyboard_modifier_keys &= ~(1<<0); break;
|
||||
case KEY_LeftShift: keyboard_modifier_keys &= ~(1<<1); break;
|
||||
case KEY_LeftAlt: keyboard_modifier_keys &= ~(1<<2); break;
|
||||
case KEY_LeftGUI: keyboard_modifier_keys &= ~(1<<3); break;
|
||||
case KEY_RightControl:keyboard_modifier_keys &= ~(1<<4); break;
|
||||
case KEY_RightShift: keyboard_modifier_keys &= ~(1<<5); break;
|
||||
case KEY_RightAlt: keyboard_modifier_keys &= ~(1<<6); break;
|
||||
case KEY_RightGUI: keyboard_modifier_keys &= ~(1<<7); break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* keyboard specific exports
|
||||
* use this file to include the keyboard you're compiling for
|
||||
*
|
||||
* Different keyboards are included by modifying a variable in the makefile.
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
|
@ -8,5 +9,14 @@
|
|||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "keyboard/ergodox.h" // only supported keyboard right now
|
||||
#undef _str
|
||||
#undef _expstr
|
||||
#undef _inc
|
||||
#define _str(s) #s // stringify
|
||||
#define _expstr(s) _str(s) // expand -> stringify
|
||||
#define _inc _expstr(keyboard/MAKEFILE_KEYBOARD.h) // inc(lude)
|
||||
#include _inc
|
||||
#undef _str
|
||||
#undef _expstr
|
||||
#undef _inc
|
||||
|
||||
|
|
|
@ -14,10 +14,22 @@
|
|||
#include "lib/data-types.h"
|
||||
|
||||
#include "ergodox/layout.h" // number of layers, layout
|
||||
#include "ergodox/led.h" // logical led controls
|
||||
#include "ergodox/matrix.h" // kb dimensions, matrix status
|
||||
#include "ergodox/mcp23018.h" // (nothing right now)
|
||||
#include "ergodox/teensy-2-0.h" // LED controls
|
||||
|
||||
|
||||
// note:
|
||||
// - see your keyswitch specification for the necessary value. for
|
||||
// cherry mx switches, the switch bounce time is speced to be <= 5ms.
|
||||
// it looks like most switches are speced to be between 5 and 8 ms.
|
||||
// - if timing is important, balance this value with the main() loop
|
||||
// run time (~5ms, last i checked, nearly all of it in the i2c
|
||||
// update() function)
|
||||
#define KB_DEBOUNCE_TIME 5 // in ms
|
||||
|
||||
|
||||
uint8_t kb_init(void);
|
||||
uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]);
|
||||
|
||||
|
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 151 KiB |
|
@ -1,94 +0,0 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* ergoDOX layout specific code
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "lib/data-types.h"
|
||||
#include "lib/usb/keyboard-usage-page.h"
|
||||
|
||||
#include "key-functions.h"
|
||||
|
||||
#include "matrix.h"
|
||||
#include "layout.h"
|
||||
|
||||
|
||||
// error check; everything below assumes these dimensions
|
||||
#if KB_LAYERS != 1 || KB_ROWS != 12 || KB_COLUMNS != 7
|
||||
#error "Expecting different keyboard dimensions"
|
||||
#endif
|
||||
|
||||
|
||||
// TODO (before release): put more effort into this
|
||||
uint8_t kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
|
||||
{ // layer 0: default
|
||||
// right hand
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
/* 0 */ { 0, KEY_6_Caret, KEY_7_Ampersand, KEY_8_Asterisk, KEY_9_LeftParenthesis, KEY_0_RightParenthesis, KEY_Dash_Underscore }, /* 0 */
|
||||
/* 1 */ { 0, KEY_y_Y, KEY_u_U, KEY_i_I, KEY_o_O, KEY_p_P, KEY_LeftBracket_LeftBrace }, /* 1 */
|
||||
/* 2 */ { 0,/*unused*/ KEY_h_H, KEY_j_J, KEY_k_K, KEY_l_L, KEY_Semicolon_Colon, KEY_SingleQuote_DoubleQuote }, /* 2 */
|
||||
/* 3 */ { 0, KEY_n_N, KEY_m_M, KEY_Comma_LessThan, KEY_Period_GreaterThan, KEY_Slash_Question, KEY_RightShift }, /* 3 */
|
||||
/* 4 */ { 0,/*unused*/ 0,/*unused*/ KEY_UpArrow, KEY_DownArrow, KEY_Backslash_Pipe, KEY_RightBracket_RightBrace, 0 }, /* 4 */
|
||||
/* 5 */ { 0,/*unused*/ KEY_RightControl, KEY_RightAlt, KEY_PageUp, KEY_PageDown, KEY_ReturnEnter, KEY_Spacebar }, /* 5 */
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
// left hand
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
/* 6 */ { KEY_Equal_Plus, KEY_1_Exclamation, KEY_2_At, KEY_3_Pound, KEY_4_Dollar, KEY_5_Percent, 0 }, /* 6 */
|
||||
/* 7 */ { KEY_Tab, KEY_q_Q, KEY_w_W, KEY_e_E, KEY_r_R, KEY_t_T, 0 }, /* 7 */
|
||||
/* 8 */ { KEY_CapsLock, KEY_a_A, KEY_s_S, KEY_d_D, KEY_f_F, KEY_g_G, 0/*unused*/ }, /* 8 */
|
||||
/* 9 */ { KEY_LeftShift, KEY_z_Z, KEY_x_X, KEY_c_C, KEY_v_V, KEY_b_B, 0 }, /* 9 */
|
||||
/* A */ { 0, KEY_GraveAccent_Tilde, KEY_Backslash_Pipe, KEY_LeftArrow, KEY_RightArrow, 0,/*unused*/ 0/*unused*/ }, /* A */
|
||||
/* B */ { KEY_DeleteBackspace, KEY_DeleteForward, KEY_End, KEY_Home, KEY_LeftAlt, KEY_LeftControl, 0/*unused*/ } /* B */
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
}
|
||||
};
|
||||
|
||||
kbfun_funptr_t kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
|
||||
{ // layer 0: default
|
||||
// right hand
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
/* 0 */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 0 */
|
||||
/* 1 */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 1 */
|
||||
/* 2 */ { NULL,/*unused*/ &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 2 */
|
||||
/* 3 */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_mod_press }, /* 3 */
|
||||
/* 4 */ { NULL,/*unused*/ NULL,/*unused*/ &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 4 */
|
||||
/* 5 */ { NULL,/*unused*/ &kbfun_mod_press, &kbfun_mod_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 5 */
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
// left hand
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
/* 6 */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 6 */
|
||||
/* 7 */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 7 */
|
||||
/* 8 */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL/*unused*/ }, /* 8 */
|
||||
/* 9 */ { &kbfun_mod_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 9 */
|
||||
/* A */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL,/*unused*/ NULL/*unused*/ }, /* A */
|
||||
/* B */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_mod_press, &kbfun_mod_press, NULL/*unused*/ } /* B */
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
}
|
||||
};
|
||||
|
||||
kbfun_funptr_t kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
|
||||
{ // layer 0: default
|
||||
// right hand
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
/* 0 */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 0 */
|
||||
/* 1 */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 1 */
|
||||
/* 2 */ { NULL,/*unused*/ &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 2 */
|
||||
/* 3 */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_mod_release }, /* 3 */
|
||||
/* 4 */ { NULL,/*unused*/ NULL,/*unused*/ &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 4 */
|
||||
/* 5 */ { NULL,/*unused*/ &kbfun_mod_release, &kbfun_mod_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 5 */
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
// left hand
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
/* 6 */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 6 */
|
||||
/* 7 */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 7 */
|
||||
/* 8 */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL/*unused*/ }, /* 8 */
|
||||
/* 9 */ { &kbfun_mod_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 9 */
|
||||
/* A */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL,/*unused*/ NULL/*unused*/ }, /* A */
|
||||
/* B */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_mod_release, &kbfun_mod_release, NULL/*unused*/ } /* B */
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
}
|
||||
};
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* ergoDOX layout specific exports
|
||||
* ergoDOX layout : exports
|
||||
*
|
||||
* Different layouts are included by modifying a variable in the makefile.
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
|
@ -9,20 +11,113 @@
|
|||
#ifndef LAYOUT_h
|
||||
#define LAYOUT_h
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include "lib/data-types.h"
|
||||
#include "lib/key-functions.h" // for `kbfun_funptr_t`
|
||||
|
||||
#include "key-functions.h"
|
||||
#include "matrix.h" // for number of rows and columns, and layout
|
||||
// to matrix macros
|
||||
|
||||
#include "matrix.h"
|
||||
// include the appropriate keyboard layout header
|
||||
// for:
|
||||
// - number of layers
|
||||
// - possible non-default layout matrix definitions
|
||||
// - possible non-default layout 'get' and 'set' definitions
|
||||
#undef _str
|
||||
#undef _expstr
|
||||
#undef _inc
|
||||
#define _str(s) #s // stringify
|
||||
#define _expstr(s) _str(s) // expand -> stringify
|
||||
#define _inc _expstr(layout/MAKEFILE_KEYBOARD_LAYOUT.h) // inc(lude)
|
||||
#include _inc
|
||||
#undef _str
|
||||
#undef _expstr
|
||||
#undef _inc
|
||||
|
||||
#define KB_LAYERS 1 // must match what's defined in "layout.c"
|
||||
|
||||
extern uint8_t
|
||||
kb_layout [KB_LAYERS][KB_ROWS][KB_COLUMNS];
|
||||
extern kbfun_funptr_t
|
||||
kb_layout_press [KB_LAYERS][KB_ROWS][KB_COLUMNS];
|
||||
extern kbfun_funptr_t
|
||||
kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS];
|
||||
// default layout 'get' macros and `extern` matrix declarations
|
||||
//
|
||||
// these are for when the matrices are stored solely in Flash. layouts
|
||||
// may redefine them if they wish and use RAM, EEPROM, or any
|
||||
// combination of the three, as long as they maintain the same
|
||||
// interface.
|
||||
//
|
||||
// - if the macro is overridden, the matrix declaration must be too,
|
||||
// and vice versa.
|
||||
//
|
||||
// - 'set' functions are optional, and should be defined in the layout
|
||||
// specific '.h'. they'll require the use of the EEPROM, possibly in
|
||||
// clever conjunction with one of the other two memories (since the
|
||||
// EEPROM is small). custom key functions will also need to be
|
||||
// written.
|
||||
//
|
||||
// - to override these macros with real functions, set the macro equal
|
||||
// to itself (e.g. `#define kb_layout_get kb_layout_get`) and provide
|
||||
// function prototypes in the layout specific '.h'
|
||||
|
||||
#ifndef kb_layout_get
|
||||
extern uint8_t PROGMEM \
|
||||
_kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS];
|
||||
|
||||
#define kb_layout_get(layer,row,column) \
|
||||
( (uint8_t) \
|
||||
pgm_read_byte(&( \
|
||||
_kb_layout[layer][row][column] )) )
|
||||
#endif
|
||||
|
||||
#ifndef kb_layout_press_get
|
||||
extern kbfun_funptr_t PROGMEM \
|
||||
_kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS];
|
||||
|
||||
#define kb_layout_press_get(layer,row,column) \
|
||||
( (kbfun_funptr_t) \
|
||||
pgm_read_word(&( \
|
||||
_kb_layout_press[layer][row][column] )) )
|
||||
#endif
|
||||
|
||||
#ifndef kb_layout_release_get
|
||||
extern kbfun_funptr_t PROGMEM \
|
||||
_kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS];
|
||||
|
||||
#define kb_layout_release_get(layer,row,column) \
|
||||
( (kbfun_funptr_t) \
|
||||
pgm_read_word(&( \
|
||||
_kb_layout_release[layer][row][column] )) )
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// default logical LED macros (all defined to nothing)
|
||||
#ifndef kb_led_num_on
|
||||
#define kb_led_num_on()
|
||||
#endif
|
||||
#ifndef kb_led_num_off
|
||||
#define kb_led_num_off()
|
||||
#endif
|
||||
#ifndef kb_led_caps_on
|
||||
#define kb_led_caps_on()
|
||||
#endif
|
||||
#ifndef kb_led_caps_off
|
||||
#define kb_led_caps_off()
|
||||
#endif
|
||||
#ifndef kb_led_scroll_on
|
||||
#define kb_led_scroll_on()
|
||||
#endif
|
||||
#ifndef kb_led_scroll_off
|
||||
#define kb_led_scroll_off()
|
||||
#endif
|
||||
#ifndef kb_led_compose_on
|
||||
#define kb_led_compose_on()
|
||||
#endif
|
||||
#ifndef kb_led_compose_off
|
||||
#define kb_led_compose_off()
|
||||
#endif
|
||||
#ifndef kb_led_kana_on
|
||||
#define kb_led_kana_on()
|
||||
#endif
|
||||
#ifndef kb_led_kana_off
|
||||
#define kb_led_kana_off()
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
# Documentation : layout
|
||||
|
||||
Different layouts are included by modifying a variable in the makefile.
|
||||
|
||||
To write a new one:
|
||||
* You must implement everything defined in [layout.h] (layout.h). Take a look
|
||||
at existing layouts in the 'layout' subdir.
|
||||
* Currently, see [qwerty.c] (layout/qwerty.c) and [qwerty.h]
|
||||
(layout/qwerty.h). The latter is only important if you want more than
|
||||
one layer. And I still need to write the functions to make that possible
|
||||
(though that shouldn't be hard, I just haven't gotten to it yet). But
|
||||
(at least for the QWERTY and Dvorak layouts I'd really like to include)
|
||||
if you indicate it clealy in the layout, and provide complete
|
||||
initializations for `kb_layout[][][]`, `kb_layout_press[][][]`, and
|
||||
`kb_layout_release[][][]`, I'll make sure it gets working.
|
||||
* The number of layers must be defined in the layout *.h file.
|
||||
* Use `0` for no-operation (unused) keys, and `NULL` for no-operation (unused)
|
||||
functions.
|
||||
* See [matrix.md] (matrix.md) for how the key matrix maps to hardware.
|
||||
* See [keyboard-usage-page--short-names.h]
|
||||
(../../lib/_usb/keyboard-usage-page--short-names.h) for available keycodes.
|
||||
* See [key-functions.c] (../../lib/_key-functions.c) for what functions keys
|
||||
can call.
|
||||
* See [_defaults.h] (layout/_defaults.h) for default function layers and
|
||||
aliases.
|
||||
|
||||
|
||||
## notes
|
||||
|
||||
* Each full layer takes 420 bytes of memory, wherever it's stored. (The matrix
|
||||
size is 12x7, keycodes are 1 byte each, and function pointers are 2 bytes
|
||||
each.)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
Released under The MIT License (MIT) (see "license.md")
|
||||
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* ergoDOX layout : QWERTY
|
||||
*
|
||||
* This is an overly basic implementation. It needs to be replaced.
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include "lib/data-types.h"
|
||||
#include "lib/usb/usage-page/keyboard--short-names.h"
|
||||
#include "lib/key-functions.h"
|
||||
|
||||
#define KEYBOARD_INCLUDE_PRIVATE
|
||||
#include "../matrix.h"
|
||||
#include "../layout.h"
|
||||
|
||||
|
||||
// error check: everything below assumes these dimensions
|
||||
#if KB_LAYERS != 1 || KB_ROWS != 12 || KB_COLUMNS != 7
|
||||
#error "Expecting different keyboard dimensions"
|
||||
#endif
|
||||
|
||||
|
||||
uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
|
||||
LAYER( // layer 0: default
|
||||
// unused
|
||||
0,
|
||||
// left hand
|
||||
_grave, _1, _2, _3, _4, _5, _equal,
|
||||
_tab, _Q, _W, _E, _R, _T, _esc,
|
||||
_capsLock, _A, _S, _D, _F, _G,
|
||||
_shiftL, _Z, _X, _C, _V, _B, _ctrlL,
|
||||
_guiL, _arrowL, _arrowU, _arrowD, _arrowR,
|
||||
_bs,
|
||||
_del, _ctrlL,
|
||||
_end, _home, _altL,
|
||||
// right hand
|
||||
_backslash, _6, _7, _8, _9, _0, _dash,
|
||||
_bracketL, _Y, _U, _I, _O, _P, _bracketR,
|
||||
_H, _J, _K, _L, _semicolon, _quote,
|
||||
_ctrlR, _N, _M, _comma, _period, _slash, _shiftR,
|
||||
_arrowL, _arrowD, _arrowU, _arrowR, _guiR,
|
||||
_space,
|
||||
_ctrlR, _enter,
|
||||
_altR, _pageU, _pageD )
|
||||
};
|
||||
|
||||
|
||||
kbfun_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
|
||||
LAYER_SET_ALL(NULL, &kbfun_press) // layer 0: default
|
||||
};
|
||||
|
||||
|
||||
kbfun_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
|
||||
LAYER_SET_ALL(NULL, &kbfun_release) // layer 0: default
|
||||
};
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* ergoDOX layout : QWERTY : exports
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef LAYOUT_QWERTY_h
|
||||
#define LAYOUT_QWERTY_h
|
||||
|
||||
#include "../led.h"
|
||||
|
||||
|
||||
#define KB_LAYERS 1 // must match what's defined in "qwerty.c"
|
||||
|
||||
#define kb_led_num_on() _led_1_on()
|
||||
#define kb_led_num_off() _led_1_off()
|
||||
#define kb_led_caps_on() _led_2_on()
|
||||
#define kb_led_caps_off() _led_2_off()
|
||||
#define kb_led_scroll_on() _led_3_on()
|
||||
#define kb_led_scroll_off() _led_3_off()
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* led stuff that isn't microprocessor or layout specific
|
||||
*
|
||||
* you should also include this file for low-level led macros, as it will
|
||||
* always include the file(s) containing those
|
||||
*
|
||||
* - low level led macros should all start with '_led_'
|
||||
* - public led macros should start with 'kb_led_'
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef LED_h
|
||||
#define LED_h
|
||||
|
||||
#include <util/delay.h>
|
||||
|
||||
#include "teensy-2-0.h" // for low-level led macros
|
||||
|
||||
|
||||
#define kb_led_state_power_on() do { \
|
||||
_led_all_set_percent(0.05); \
|
||||
_led_all_on(); \
|
||||
} while(0)
|
||||
|
||||
// note: need to delay for a total of ~1 second
|
||||
#define kb_led_delay_usb_init() do { \
|
||||
_led_1_set_percent(0.5); \
|
||||
_delay_ms(333); \
|
||||
_led_2_set_percent(0.5); \
|
||||
_delay_ms(333); \
|
||||
_led_3_set_percent(0.5); \
|
||||
_delay_ms(333); \
|
||||
} while(0)
|
||||
|
||||
#define kb_led_state_ready() do { \
|
||||
_led_all_off(); \
|
||||
_led_all_set_percent(0.5); \
|
||||
} while(0)
|
||||
|
||||
#endif
|
||||
|
|
@ -19,5 +19,90 @@
|
|||
extern bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS];
|
||||
|
||||
|
||||
#ifdef KEYBOARD_INCLUDE_PRIVATE
|
||||
|
||||
/* mapping from spatial position to matrix position
|
||||
* - spatial position: where the key is spatially, relative to
|
||||
* other keys both on the keyboard and in the layout
|
||||
* - matrix position: the coordinate in the matrix to which
|
||||
* a key is scanned by the update functions
|
||||
*
|
||||
* - location numbers are in the format `row##column`, where
|
||||
* both 'row' and 'column' are single digit hex numbers
|
||||
* corresponding to the matrix position
|
||||
* - coordinates not listed are unused
|
||||
*
|
||||
* --- other info ---------------------------------------------
|
||||
* rows x columns = positions; assigned, unassigned
|
||||
* per hand: 6 x 7 = 42; 38, 4
|
||||
* total: 12 x 7 = 84; 76, 8
|
||||
*
|
||||
* left hand : cols 0..6, rows 6..B
|
||||
* right hand : cols 0..6, rows 0..5
|
||||
* ------------------------------------------------------------
|
||||
*/
|
||||
#define LAYER( \
|
||||
/* for unused positions */ \
|
||||
na, \
|
||||
\
|
||||
/* left hand, spatial positions */ \
|
||||
kB6,kB5,kB4,kB3,kB2,kB1,kB0, \
|
||||
kA6,kA5,kA4,kA3,kA2,kA1,kA0, \
|
||||
k96,k95,k94,k93,k92,k91, \
|
||||
k86,k85,k84,k83,k82,k81,k80, \
|
||||
k76,k75,k74,k73,k72, \
|
||||
k64, \
|
||||
k63, k60, \
|
||||
k65,k62,k61, \
|
||||
\
|
||||
/* right hand, spatial positions */ \
|
||||
k50,k51,k52,k53,k54,k55,k56, \
|
||||
k40,k41,k42,k43,k44,k45,k46, \
|
||||
k31,k32,k33,k34,k35,k36, \
|
||||
k20,k21,k22,k23,k24,k25,k26, \
|
||||
k12,k13,k14,k15,k16, \
|
||||
k04, \
|
||||
k00, k03, \
|
||||
k01,k02,k05 ) \
|
||||
\
|
||||
/* matrix positions */ \
|
||||
{ { k00,k01,k02,k03,k04,k05, na,}, \
|
||||
{ na, na,k12,k13,k14,k15,k16,}, \
|
||||
{ k20,k21,k22,k23,k24,k25,k26,}, \
|
||||
{ na,k31,k32,k33,k34,k35,k36,}, \
|
||||
{ k40,k41,k42,k43,k44,k45,k46,}, \
|
||||
{ k50,k51,k52,k53,k54,k55,k56,}, \
|
||||
{ k60,k61,k62,k63,k64,k65, na,}, \
|
||||
{ na, na,k72,k73,k74,k75,k76,}, \
|
||||
{ k80,k81,k82,k83,k84,k85,k86,}, \
|
||||
{ na,k91,k92,k93,k94,k95,k96,}, \
|
||||
{ kA0,kA1,kA2,kA3,kA4,kA5,kA6,}, \
|
||||
{ kB0,kB1,kB2,kB3,kB4,kB5,kB6 } }
|
||||
|
||||
|
||||
#define LAYER_SET_ALL(na, kxx) \
|
||||
LAYER( \
|
||||
na, \
|
||||
\
|
||||
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
|
||||
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
|
||||
kxx,kxx,kxx,kxx,kxx,kxx, \
|
||||
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
|
||||
kxx,kxx,kxx,kxx,kxx, \
|
||||
kxx, \
|
||||
kxx, kxx, \
|
||||
kxx,kxx,kxx, \
|
||||
\
|
||||
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
|
||||
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
|
||||
kxx,kxx,kxx,kxx,kxx,kxx, \
|
||||
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
|
||||
kxx,kxx,kxx,kxx,kxx, \
|
||||
kxx, \
|
||||
kxx, kxx, \
|
||||
kxx,kxx,kxx )
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
# Documentation : Keyboard Matrix
|
||||
|
||||
## Matrix [row##column] assignments
|
||||
|
||||
* row and column numbers are in hex
|
||||
* coordinates without brackets are unused
|
||||
* left and right hands are mostly the same except that `row += 6` for the left
|
||||
|
||||
....... rows x columns = positions; assigned, unassigned .......
|
||||
....... per hand: 6 x 7 = 42; 38, 4 .......
|
||||
....... total: 12 x 7 = 84; 76, 8 .......
|
||||
----------------------------------------------------------------------------
|
||||
[60][61][62][63][64][65][66] [00][01][02][03][04][05][06]
|
||||
[70][71][72][73][74][75][76] [10][11][12][13][14][15][16]
|
||||
[80][81][82][83][84][85] 86 20 [21][22][23][24][25][26]
|
||||
[90][91][92][93][94][95][96] [30][31][32][33][34][35][36]
|
||||
[A0][A1][A2][A3][A4] A5 A6 40 41 [42][43][44][45][46]
|
||||
[B0] B6 50 [56]
|
||||
[B1] [B5] [51] [55]
|
||||
[B2][B3][B4] [52][53][54]
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
Released under The MIT License (MIT) (see "license.md")
|
||||
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
|
|
@ -8,9 +8,8 @@
|
|||
|
||||
|
||||
#include <util/twi.h>
|
||||
|
||||
#include "lib/data-types.h"
|
||||
#include "lib/teensy-2-0/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c"
|
||||
#include "lib/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c"
|
||||
|
||||
#define KEYBOARD_INCLUDE_PRIVATE
|
||||
#include "matrix.h"
|
||||
|
@ -45,25 +44,26 @@ uint8_t mcp23018_init(void) {
|
|||
|
||||
// set pin direction
|
||||
// - unused : input : 1
|
||||
// - rows : output : 0
|
||||
// - columns : input : 1
|
||||
// - row : input : 1
|
||||
// - column : output : 0
|
||||
twi_start();
|
||||
ret = twi_send(TWI_ADDR_WRITE);
|
||||
if (ret) goto out; // make sure we got an ACK
|
||||
twi_send(IODIRA);
|
||||
twi_send(0b11000000); // IODIRA
|
||||
twi_send(0b11111111); // IODIRB
|
||||
twi_send(0b11111111); // IODIRA
|
||||
twi_send(0b10000000); // IODIRB
|
||||
twi_stop();
|
||||
|
||||
// set pull-up
|
||||
// - unused : on : 1
|
||||
// - rows : off : 0
|
||||
// - columns : on : 1
|
||||
// - rows : on : 1
|
||||
// - columns : off : 0
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
ret = twi_send(TWI_ADDR_WRITE);
|
||||
if (ret) goto out; // make sure we got an ACK
|
||||
twi_send(GPPUA);
|
||||
twi_send(0b11000000); // GPPUA
|
||||
twi_send(0b11111111); // GPPUB
|
||||
twi_send(0b11111111); // GPPUA
|
||||
twi_send(0b10000000); // GPPUB
|
||||
twi_stop();
|
||||
|
||||
// set logical value (doesn't matter on inputs)
|
||||
|
@ -71,7 +71,8 @@ uint8_t mcp23018_init(void) {
|
|||
// - rows : high (hi-Z) : 1
|
||||
// - columns : high (hi-Z) : 1
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
ret = twi_send(TWI_ADDR_WRITE);
|
||||
if (ret) goto out; // make sure we got an ACK
|
||||
twi_send(OLATA);
|
||||
twi_send(0b11111111); //OLATA
|
||||
twi_send(0b11111111); //OLATB
|
||||
|
@ -108,34 +109,34 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
|
|||
}
|
||||
|
||||
// update our part of the matrix
|
||||
for (uint8_t row=0x6; row<=0xB; row++) {
|
||||
// set active row low : 0
|
||||
// set other rows high (hi-Z) : 1
|
||||
for (uint8_t col=0; col<=6; col++) {
|
||||
// set active column low : 0
|
||||
// set other columns high (hi-Z) : 1
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(OLATA);
|
||||
twi_send( 0b11111111 & ~(1<<(row-6)) );
|
||||
twi_send(OLATB);
|
||||
twi_send( 0xFF & ~(1<<col) );
|
||||
twi_stop();
|
||||
|
||||
// read column data
|
||||
// read row data
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(GPIOB);
|
||||
twi_send(GPIOA);
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_READ);
|
||||
twi_read(&data);
|
||||
twi_stop();
|
||||
|
||||
// update matrix
|
||||
for (uint8_t col=0; col<=6; col++)
|
||||
matrix[row][col] = !( data & (1<<col) );
|
||||
for (uint8_t row=0x6; row<=0xB; row++)
|
||||
matrix[row][col] = !( data & (1<<(row-6)) );
|
||||
}
|
||||
|
||||
// set all rows high (hi-Z) : 1
|
||||
// set all columns high (hi-Z) : 1
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(GPIOA);
|
||||
twi_send(0b11111111);
|
||||
twi_send(GPIOB);
|
||||
twi_send(0xFF);
|
||||
twi_stop();
|
||||
|
||||
return ret; // success
|
||||
|
|
|
@ -41,18 +41,18 @@
|
|||
NC o14-------15+ ADDR (see note)
|
||||
|
||||
* notes:
|
||||
* ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND).
|
||||
* The user-defined bits are the three least significant
|
||||
* I2C addresses are 7 bits long (the last bit in the byte is used for
|
||||
indicating read/write)
|
||||
* RESET (pin16) must be externally biased. Since we're not going to trigger
|
||||
it ourselves, we can tie it high.
|
||||
* This is not noted in the I2C Pinout Description section of the MCP23018
|
||||
datasheet, but it's true (empirically), and it is noted in the SPI Pinout
|
||||
Description section, and in the MCP23017 datasheet.
|
||||
* I'm not the first person who's failed to notice ;)
|
||||
* <http://davidn.org/wp/?p=89>
|
||||
* <http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293498979>
|
||||
* ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND).
|
||||
* The user-defined bits are the three least significant
|
||||
* I2C addresses are 7 bits long (the last bit in the byte is used for
|
||||
indicating read/write)
|
||||
* RESET (pin16) must be externally biased. Since we're not going to
|
||||
trigger it ourselves, we can tie it high.
|
||||
* This is not noted in the I2C Pinout Description section of the
|
||||
MCP23018 datasheet, but it's true (empirically), and it is noted in
|
||||
the SPI Pinout Description section, and in the MCP23017 datasheet.
|
||||
* I'm not the first person who's failed to notice ;)
|
||||
* <http://davidn.org/wp/?p=89>
|
||||
* <http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293498979>
|
||||
|
||||
## Notes about Registers
|
||||
|
||||
|
@ -69,28 +69,28 @@
|
|||
pins configured as output
|
||||
|
||||
* IOCON register (see datasheet section 1.6, table 1-5, register 1-8)
|
||||
* BANK: bit 7; read/write; default = 0
|
||||
* 1: The registers associated with each port are separated into different
|
||||
banks
|
||||
* 0: The registers are in the same bank (addresses are sequential)
|
||||
* SEQOP: bit 5; read/write; default = 0
|
||||
* 1: Sequential operation disabled, address pointer does not increment
|
||||
* 0: Sequential operation enabled, address pointer increments
|
||||
* BANK: bit 7; read/write; default = 0
|
||||
* 1: The registers associated with each port are separated into
|
||||
different banks
|
||||
* 0: The registers are in the same bank (addresses are sequential)
|
||||
* SEQOP: bit 5; read/write; default = 0
|
||||
* 1: Sequential operation disabled, address pointer does not increment
|
||||
* 0: Sequential operation enabled, address pointer increments
|
||||
|
||||
* notes:
|
||||
* All addresses given for IOCON.BANK = 0, since that's the default value of
|
||||
the bit, and that's what we'll be using.
|
||||
* We want the row pins set as output high (hi-Z) without pull-ups initially,
|
||||
and the column pins set as input with pull-ups. We'll cycle through
|
||||
driving the row pins low and checking the column pins in the update
|
||||
function.
|
||||
* All addresses given for IOCON.BANK = 0, since that's the default value of
|
||||
the bit, and that's what we'll be using.
|
||||
* We want the column pins set as output high (hi-Z) without pull-ups
|
||||
initially, and the row pins set as input with pull-ups. We'll cycle
|
||||
through driving the column pins low and checking the row pins in the
|
||||
update function.
|
||||
|
||||
* abbreviations:
|
||||
* IODIR = I/O Direction Register
|
||||
* IOCON = I/O Control Register
|
||||
* GPPU = GPIO Pull-Up Resistor Register
|
||||
* GPIO = General Purpose I/O Port Register
|
||||
* OLAT = Output Latch Register
|
||||
* IODIR = I/O Direction Register
|
||||
* IOCON = I/O Control Register
|
||||
* GPPU = GPIO Pull-Up Resistor Register
|
||||
* GPIO = General Purpose I/O Port Register
|
||||
* OLAT = Output Latch Register
|
||||
|
||||
## I²C Device Protocol (see datasheet section 1.3, figure 1-1)
|
||||
|
||||
|
@ -130,8 +130,8 @@
|
|||
Sequential : S OP W ADDR --> SR OP R Dout ... Dout --> P
|
||||
|
||||
* notes:
|
||||
* We'll be using sequential mode (ICON.SEQOP = 0; default) (see datasheet
|
||||
section 1.3.1).
|
||||
* We'll be using sequential mode (ICON.SEQOP = 0; default) (see datasheet
|
||||
section 1.3.1).
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -8,10 +8,9 @@
|
|||
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "lib/data-types.h"
|
||||
#define TWI_FREQ 400000
|
||||
#include "lib/teensy-2-0/twi.h"
|
||||
#include "lib/twi.h"
|
||||
|
||||
#define KEYBOARD_INCLUDE_PRIVATE
|
||||
#include "matrix.h"
|
||||
|
@ -37,19 +36,50 @@
|
|||
* movable, and either are referenced explicitly or have macros defined for
|
||||
* them elsewhere.
|
||||
* - note: if you change pin assignments, please be sure to update
|
||||
* "teensy-2-0.md".
|
||||
* "teensy-2-0.md", and the '.svg' circuit diagram.
|
||||
*/
|
||||
// --- helpers
|
||||
#define TEENSYPIN_WRITE(register, operation, pin) \
|
||||
_TEENSYPIN_WRITE(register, operation, pin)
|
||||
#define _TEENSYPIN_WRITE(register, operation, pin_letter, pin_number) \
|
||||
#define teensypin_write(register, operation, pin) \
|
||||
_teensypin_write(register, operation, pin)
|
||||
#define _teensypin_write(register, operation, pin_letter, pin_number) \
|
||||
((register##pin_letter) operation (1<<(pin_number)))
|
||||
|
||||
#define TEENSYPIN_READ(pin) \
|
||||
_TEENSYPIN_READ(pin)
|
||||
#define _TEENSYPIN_READ(pin_letter, pin_number) \
|
||||
#define teensypin_read(pin) \
|
||||
_teensypin_read(pin)
|
||||
#define _teensypin_read(pin_letter, pin_number) \
|
||||
((PIN##pin_letter) & (1<<(pin_number)))
|
||||
|
||||
#define teensypin_write_all_unused(register, operation) \
|
||||
do { \
|
||||
teensypin_write(register, operation, UNUSED_0); \
|
||||
teensypin_write(register, operation, UNUSED_1); \
|
||||
teensypin_write(register, operation, UNUSED_2); \
|
||||
teensypin_write(register, operation, UNUSED_3); \
|
||||
teensypin_write(register, operation, UNUSED_4); \
|
||||
teensypin_write(register, operation, UNUSED_5); } \
|
||||
while(0)
|
||||
|
||||
#define teensypin_write_all_row(register, operation) \
|
||||
do { \
|
||||
teensypin_write(register, operation, ROW_0); \
|
||||
teensypin_write(register, operation, ROW_1); \
|
||||
teensypin_write(register, operation, ROW_2); \
|
||||
teensypin_write(register, operation, ROW_3); \
|
||||
teensypin_write(register, operation, ROW_4); \
|
||||
teensypin_write(register, operation, ROW_5); } \
|
||||
while(0)
|
||||
|
||||
#define teensypin_write_all_column(register, operation) \
|
||||
do { \
|
||||
teensypin_write(register, operation, COLUMN_0); \
|
||||
teensypin_write(register, operation, COLUMN_1); \
|
||||
teensypin_write(register, operation, COLUMN_2); \
|
||||
teensypin_write(register, operation, COLUMN_3); \
|
||||
teensypin_write(register, operation, COLUMN_4); \
|
||||
teensypin_write(register, operation, COLUMN_5); \
|
||||
teensypin_write(register, operation, COLUMN_6); } \
|
||||
while(0)
|
||||
|
||||
#define SET |=
|
||||
#define CLEAR &=~
|
||||
|
||||
|
@ -90,66 +120,25 @@ uint8_t teensy_init(void) {
|
|||
PORTD &= ~(1<<6); // set D(6) internal pull-up disabled
|
||||
|
||||
// keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md")
|
||||
DDRB |= 0b11100000; // set B(7,6,5) as output
|
||||
_led_all_off(); // (just to put the pins in a known state)
|
||||
TCCR1A = 0b10101001; // set and configure fast PWM
|
||||
TCCR1B = 0b00001001; // set and configure fast PWM
|
||||
|
||||
KB_LED1_SET_PERCENT(0.5); KB_LED1_OFF;
|
||||
KB_LED2_SET_PERCENT(0.5); KB_LED2_OFF;
|
||||
KB_LED3_SET_PERCENT(0.5); KB_LED3_OFF;
|
||||
|
||||
// I2C (TWI)
|
||||
twi_init(); // on pins D(1,0)
|
||||
|
||||
// unused pins
|
||||
// --- set as input
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_0);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_1);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_2);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_3);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_4);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, UNUSED_5);
|
||||
// --- set internal pull-up enabled
|
||||
TEENSYPIN_WRITE(PORT, SET, UNUSED_0);
|
||||
TEENSYPIN_WRITE(PORT, SET, UNUSED_1);
|
||||
TEENSYPIN_WRITE(PORT, SET, UNUSED_2);
|
||||
TEENSYPIN_WRITE(PORT, SET, UNUSED_3);
|
||||
TEENSYPIN_WRITE(PORT, SET, UNUSED_4);
|
||||
TEENSYPIN_WRITE(PORT, SET, UNUSED_5);
|
||||
teensypin_write_all_unused(DDR, CLEAR); // set as input
|
||||
teensypin_write_all_unused(PORT, SET); // set internal pull-up enabled
|
||||
|
||||
// rows
|
||||
// --- set as input (hi-Z)
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_0);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_1);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_2);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_3);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_4);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_5);
|
||||
// --- set internal pull-up disabled
|
||||
TEENSYPIN_WRITE(PORT, CLEAR, ROW_0);
|
||||
TEENSYPIN_WRITE(PORT, CLEAR, ROW_1);
|
||||
TEENSYPIN_WRITE(PORT, CLEAR, ROW_2);
|
||||
TEENSYPIN_WRITE(PORT, CLEAR, ROW_3);
|
||||
TEENSYPIN_WRITE(PORT, CLEAR, ROW_4);
|
||||
TEENSYPIN_WRITE(PORT, CLEAR, ROW_5);
|
||||
teensypin_write_all_row(DDR, CLEAR); // set as input
|
||||
teensypin_write_all_row(PORT, SET); // set internal pull-up enabled
|
||||
|
||||
// columns
|
||||
// --- set as input
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_0);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_1);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_2);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_3);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_4);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_5);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, COLUMN_6);
|
||||
// --- set internal pull-up enabled
|
||||
TEENSYPIN_WRITE(PORT, SET, COLUMN_0);
|
||||
TEENSYPIN_WRITE(PORT, SET, COLUMN_1);
|
||||
TEENSYPIN_WRITE(PORT, SET, COLUMN_2);
|
||||
TEENSYPIN_WRITE(PORT, SET, COLUMN_3);
|
||||
TEENSYPIN_WRITE(PORT, SET, COLUMN_4);
|
||||
TEENSYPIN_WRITE(PORT, SET, COLUMN_5);
|
||||
TEENSYPIN_WRITE(PORT, SET, COLUMN_6);
|
||||
teensypin_write_all_column(DDR, CLEAR); // set as input (hi-Z)
|
||||
teensypin_write_all_column(PORT, CLEAR); // set internal pull-up
|
||||
// disabled
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
@ -160,40 +149,43 @@ uint8_t teensy_init(void) {
|
|||
#if KB_ROWS != 12 || KB_COLUMNS != 7
|
||||
#error "Expecting different keyboard dimensions"
|
||||
#endif
|
||||
static inline void _update_columns(
|
||||
bool matrix[KB_ROWS][KB_COLUMNS], uint8_t row ) {
|
||||
matrix[row][0] = ! TEENSYPIN_READ(COLUMN_0);
|
||||
matrix[row][1] = ! TEENSYPIN_READ(COLUMN_1);
|
||||
matrix[row][2] = ! TEENSYPIN_READ(COLUMN_2);
|
||||
matrix[row][3] = ! TEENSYPIN_READ(COLUMN_3);
|
||||
matrix[row][4] = ! TEENSYPIN_READ(COLUMN_4);
|
||||
matrix[row][5] = ! TEENSYPIN_READ(COLUMN_5);
|
||||
matrix[row][6] = ! TEENSYPIN_READ(COLUMN_6);
|
||||
static inline void _update_rows(
|
||||
bool matrix[KB_ROWS][KB_COLUMNS], uint8_t column ) {
|
||||
matrix[0][column] = ! teensypin_read(ROW_0);
|
||||
matrix[1][column] = ! teensypin_read(ROW_1);
|
||||
matrix[2][column] = ! teensypin_read(ROW_2);
|
||||
matrix[3][column] = ! teensypin_read(ROW_3);
|
||||
matrix[4][column] = ! teensypin_read(ROW_4);
|
||||
matrix[5][column] = ! teensypin_read(ROW_5);
|
||||
}
|
||||
uint8_t teensy_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_0); // set row low (set as output)
|
||||
_update_columns(matrix, 0); // read col 0..6 and update matrix
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_0); // set row hi-Z (set as input)
|
||||
teensypin_write(DDR, SET, COLUMN_0); // set col low (set as output)
|
||||
_update_rows(matrix, 0); // read row 0..5 & update matrix
|
||||
teensypin_write(DDR, CLEAR, COLUMN_0); // set col hi-Z (set as input)
|
||||
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_1);
|
||||
_update_columns(matrix, 1);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_1);
|
||||
teensypin_write(DDR, SET, COLUMN_1);
|
||||
_update_rows(matrix, 1);
|
||||
teensypin_write(DDR, CLEAR, COLUMN_1);
|
||||
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_2);
|
||||
_update_columns(matrix, 2);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_2);
|
||||
teensypin_write(DDR, SET, COLUMN_2);
|
||||
_update_rows(matrix, 2);
|
||||
teensypin_write(DDR, CLEAR, COLUMN_2);
|
||||
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_3);
|
||||
_update_columns(matrix, 3);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_3);
|
||||
teensypin_write(DDR, SET, COLUMN_3);
|
||||
_update_rows(matrix, 3);
|
||||
teensypin_write(DDR, CLEAR, COLUMN_3);
|
||||
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_4);
|
||||
_update_columns(matrix, 4);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_4);
|
||||
teensypin_write(DDR, SET, COLUMN_4);
|
||||
_update_rows(matrix, 4);
|
||||
teensypin_write(DDR, CLEAR, COLUMN_4);
|
||||
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_5);
|
||||
_update_columns(matrix, 5);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_5);
|
||||
teensypin_write(DDR, SET, COLUMN_5);
|
||||
_update_rows(matrix, 5);
|
||||
teensypin_write(DDR, CLEAR, COLUMN_5);
|
||||
|
||||
teensypin_write(DDR, SET, COLUMN_6);
|
||||
_update_rows(matrix, 6);
|
||||
teensypin_write(DDR, CLEAR, COLUMN_6);
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
|
|
@ -11,24 +11,47 @@
|
|||
#define TEENSY_2_0_h
|
||||
|
||||
#include <avr/io.h> // for the register macros
|
||||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
#include "matrix.h"
|
||||
|
||||
|
||||
// LED control
|
||||
#define KB_LED1_ON (DDRB |= (1<<5))
|
||||
#define KB_LED1_OFF (DDRB &= ~(1<<5))
|
||||
#define KB_LED1_SET(n) (OCR1A = (uint8_t)(n))
|
||||
#define KB_LED1_SET_PERCENT(n) (OCR1A = (uint8_t)((n) * 0xFF))
|
||||
#define KB_LED2_ON (DDRB |= (1<<6))
|
||||
#define KB_LED2_OFF (DDRB &= ~(1<<6))
|
||||
#define KB_LED2_SET(n) (OCR1B = (uint8_t)(n))
|
||||
#define KB_LED2_SET_PERCENT(n) (OCR1B = (uint8_t)((n) * 0xFF))
|
||||
#define KB_LED3_ON (DDRB |= (1<<7))
|
||||
#define KB_LED3_OFF (DDRB &= ~(1<<7))
|
||||
#define KB_LED3_SET(n) (OCR1C = (uint8_t)(n))
|
||||
#define KB_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF))
|
||||
#define _led_1_on() (DDRB |= (1<<6))
|
||||
#define _led_1_off() (DDRB &= ~(1<<6))
|
||||
#define _led_1_set(n) (OCR1B = (uint8_t)(n))
|
||||
#define _led_1_set_percent(n) (OCR1B = (uint8_t)((n) * 0xFF))
|
||||
//
|
||||
#define _led_2_on() (DDRB |= (1<<5))
|
||||
#define _led_2_off() (DDRB &= ~(1<<5))
|
||||
#define _led_2_set(n) (OCR1A = (uint8_t)(n))
|
||||
#define _led_2_set_percent(n) (OCR1A = (uint8_t)((n) * 0xFF))
|
||||
//
|
||||
#define _led_3_on() (DDRB |= (1<<7))
|
||||
#define _led_3_off() (DDRB &= ~(1<<7))
|
||||
#define _led_3_set(n) (OCR1C = (uint8_t)(n))
|
||||
#define _led_3_set_percent(n) (OCR1C = (uint8_t)((n) * 0xFF))
|
||||
// ---
|
||||
#define _led_all_on() do { \
|
||||
_led_1_on(); \
|
||||
_led_2_on(); \
|
||||
_led_3_on(); \
|
||||
} while(0)
|
||||
#define _led_all_off() do { \
|
||||
_led_1_off(); \
|
||||
_led_2_off(); \
|
||||
_led_3_off(); \
|
||||
} while(0)
|
||||
#define _led_all_set(n) do { \
|
||||
_led_1_set(n); \
|
||||
_led_2_set(n); \
|
||||
_led_3_set(n); \
|
||||
} while(0)
|
||||
#define _led_all_set_percent(n) do { \
|
||||
_led_1_set_percent(n); \
|
||||
_led_2_set_percent(n); \
|
||||
_led_3_set_percent(n); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#ifdef KEYBOARD_INCLUDE_PRIVATE
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
PB3 o o o + PF5 row3
|
||||
(OC1C) LED3 PB7 + PE6 AREF + PF6 row4
|
||||
(SCL) I2C PD0 + + PF7 row5
|
||||
(SDA) I2C PD1 + + PB6 LED2 (OC1B)
|
||||
column3 PD2 + + PB5 LED1 (OC1A)
|
||||
(SDA) I2C PD1 + + PB6 LED1 (OC1B)
|
||||
column3 PD2 + + PB5 LED2 (OC1A)
|
||||
column4 PD3 + + PB4 column0
|
||||
column1 PC6 + + PD7 column5
|
||||
column2 PC7 +-o-o-o-o-o-+ PD6 onboardLED
|
||||
|
@ -44,10 +44,10 @@
|
|||
GND-------/
|
||||
|
||||
* notes:
|
||||
* SCL and SDA: Need external pull-up resistors. Sometimes the Teensy
|
||||
internal pull-ups are enough (see datasheet section 20.5.1), but i think
|
||||
for this project we'll want external ones. The general recommendation for
|
||||
400kHz I²C seems to be 2.2kΩ.
|
||||
* SCL and SDA: Need external pull-up resistors. Sometimes the Teensy
|
||||
internal pull-ups are enough (see datasheet section 20.5.1), but i think
|
||||
for this project we'll want external ones. The general recommendation
|
||||
for 400kHz I²C seems to be 2.2kΩ.
|
||||
|
||||
|
||||
## Notes about Registers
|
||||
|
@ -65,51 +65,52 @@
|
|||
read returns the logical value (1|0) of the pin
|
||||
|
||||
* notes:
|
||||
* Unused pins should be set as input, with internal pullup enabled in order
|
||||
to give them a defined level (see datasheet section 10.2.6).
|
||||
* PD6 (the onboard LED) already has a defined level (low), so there's no
|
||||
reason to set internal pull-up enabled on it. If we do, it will source
|
||||
current to the LED, which is fine, but unnecessary.
|
||||
* We want the row pins 'hi-Z' initially (set as input with pull-up disabled),
|
||||
and the column pins set as input with internal pull-up enabled. We'll
|
||||
cycle through driving the row pins low (setting them as output) and
|
||||
checking the column pins in the update function.
|
||||
* Switching the row pins between hi-Z and drive low (treating them as if
|
||||
they were open drain) seems just as good as, and a little safer than,
|
||||
driving them high when the row's not active.
|
||||
* Unused pins should be set as input, with internal pullup enabled in order
|
||||
to give them a defined level (see datasheet section 10.2.6).
|
||||
* PD6 (the onboard LED) already has a defined level (low), so there's no
|
||||
reason to set internal pull-up enabled on it. If we do, it will source
|
||||
current to the LED, which is fine, but unnecessary.
|
||||
* We want the columns to be hi-Z when that column's not being scanned,
|
||||
drive low when it is, and the rows to be input with pull-up enabled.
|
||||
We'll cycle through driving the columns low and scanning all rows.
|
||||
* To set a pin hi-Z on this board, set it as input with pull-up
|
||||
disabled.
|
||||
* Switching the row pins between hi-Z and drive low (treating them as
|
||||
if they were open drain) seems just as good as, and a little safer
|
||||
than, driving them high when the row's not active.
|
||||
|
||||
### PWM on ports OC1(A|B|C) (see datasheet section 14.10)
|
||||
|
||||
* notes: settings:
|
||||
* PWM pins should be set as outputs.
|
||||
* we want Waveform Generation Mode 5
|
||||
(fast PWM, 8-bit)
|
||||
(see table 14-5)
|
||||
* set `TCCRB[4,3],TCCRA[1,0]` to `0,1,0,1`
|
||||
* we want "Compare Output Mode, Fast PWM" to be `0b10`
|
||||
"Clear OCnA/OCnB/OCnC on compare match, set OCnA/OCnB/OCnC at TOP"
|
||||
(see table 14-3)
|
||||
this way higher values of `OCR1(A|B|C)` will mean longer 'on' times for the
|
||||
LEDs (provided they're hooked up to GND; other way around if they're hooked
|
||||
up to Vcc)
|
||||
* when in a fast PWM mode, set `TCCR1A[7,6,5,4,3,2]` to `1,0,1,0,1,0`
|
||||
* we want "Clock Select Bit Description" to be `0b001`
|
||||
"clkI/O/1 (No prescaling)"
|
||||
(see table 14-6)
|
||||
* set `TCCR1B[2,1,0]` to `0,0,1`
|
||||
* LEDs will be at minimum brightness until OCR1(A|B|C) are changed (since
|
||||
the default value of all the bits in those registers is 0)
|
||||
* PWM pins should be set as outputs.
|
||||
* we want Waveform Generation Mode 5
|
||||
(fast PWM, 8-bit)
|
||||
(see table 14-5)
|
||||
* set `TCCRB[4,3],TCCRA[1,0]` to `0,1,0,1`
|
||||
* we want "Compare Output Mode, Fast PWM" to be `0b10`
|
||||
"Clear OCnA/OCnB/OCnC on compare match, set OCnA/OCnB/OCnC at TOP"
|
||||
(see table 14-3)
|
||||
this way higher values of `OCR1(A|B|C)` will mean longer 'on' times for
|
||||
the LEDs (provided they're hooked up to GND; other way around if they're
|
||||
hooked up to Vcc)
|
||||
* when in a fast PWM mode, set `TCCR1A[7,6,5,4,3,2]` to `1,0,1,0,1,0`
|
||||
* we want "Clock Select Bit Description" to be `0b001`
|
||||
"clkI/O/1 (No prescaling)"
|
||||
(see table 14-6)
|
||||
* set `TCCR1B[2,1,0]` to `0,0,1`
|
||||
* LEDs will be at minimum brightness until OCR1(A|B|C) are changed
|
||||
(since the default value of all the bits in those registers is 0)
|
||||
|
||||
* notes: behavior:
|
||||
* The pins source current when on, and sink current when off. They aren't
|
||||
set to high impediance for either.
|
||||
* In Fast PWM mode setting `OCR1(A|B|C)` to `0` does not make the output on
|
||||
`OC1(A|B|C)` constant low; just close. Per the datasheet, this isn't true
|
||||
for every PWM mode.
|
||||
* The pins source current when on, and sink current when off. They aren't
|
||||
set to high impediance for either.
|
||||
* In Fast PWM mode setting `OCR1(A|B|C)` to `0` does not make the output on
|
||||
`OC1(A|B|C)` constant low; just close. Per the datasheet, this isn't
|
||||
true for every PWM mode.
|
||||
|
||||
* abbreviations:
|
||||
* OCR = Output Compare Register
|
||||
* TCCR = Timer/Counter Control Register
|
||||
* OCR = Output Compare Register
|
||||
* TCCR = Timer/Counter Control Register
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# src/lib/pjrc
|
||||
|
||||
## links to original files
|
||||
|
||||
* [pjrc] (http://pjrc.com/teensy/)
|
||||
* [usb_keyboard] (http://pjrc.com/teensy/usb_keyboard.zip)
|
||||
<!--
|
||||
* [usb_mouse] (http://pjrc.com/teensy/usb_mouse.zip)
|
||||
* [usb_serial] (http://pjrc.com/teensy/usb_serial.zip)
|
||||
* Directions for host setup [here]
|
||||
(http://pjrc.com/teensy/usb_serial.html)
|
||||
-->
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
Released under The MIT License (MIT) (see "license.md")
|
||||
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
|
|
@ -1,614 +0,0 @@
|
|||
# Hey Emacs, this is a -*- makefile -*-
|
||||
#----------------------------------------------------------------------------
|
||||
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
|
||||
#
|
||||
# Released to the Public Domain
|
||||
#
|
||||
# Additional material for this makefile was written by:
|
||||
# Peter Fleury
|
||||
# Tim Henigan
|
||||
# Colin O'Flynn
|
||||
# Reiner Patommel
|
||||
# Markus Pfaff
|
||||
# Sander Pool
|
||||
# Frederik Rouleau
|
||||
# Carlos Lamas
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
# On command line:
|
||||
#
|
||||
# make all = Make software.
|
||||
#
|
||||
# make clean = Clean out built project files.
|
||||
#
|
||||
# make coff = Convert ELF to AVR COFF.
|
||||
#
|
||||
# make extcoff = Convert ELF to AVR Extended COFF.
|
||||
#
|
||||
# make program = Download the hex file to the device, using avrdude.
|
||||
# Please customize the avrdude settings below first!
|
||||
#
|
||||
# make debug = Start either simulavr or avarice as specified for debugging,
|
||||
# with avr-gdb or avr-insight as the front end for debugging.
|
||||
#
|
||||
# make filename.s = Just compile filename.c into the assembler code only.
|
||||
#
|
||||
# make filename.i = Create a preprocessed source file for use in submitting
|
||||
# bug reports to the GCC project.
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = example
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = $(TARGET).c \
|
||||
usb_keyboard.c
|
||||
|
||||
|
||||
# MCU name, you MUST set this to match the board you are using
|
||||
# type "make clean" after changing this, so all files will be rebuilt
|
||||
#
|
||||
#MCU = at90usb162 # Teensy 1.0
|
||||
MCU = atmega32u4 # Teensy 2.0
|
||||
#MCU = at90usb646 # Teensy++ 1.0
|
||||
#MCU = at90usb1286 # Teensy++ 2.0
|
||||
|
||||
|
||||
# Processor frequency.
|
||||
# Normally the first thing your program should do is set the clock prescaler,
|
||||
# so your program will run at the correct speed. You should also set this
|
||||
# variable to same clock speed. The _delay_ms() macro uses this, and many
|
||||
# examples use this variable to calculate timings. Do not add a "UL" here.
|
||||
F_CPU = 16000000
|
||||
|
||||
|
||||
# Output format. (can be srec, ihex, binary)
|
||||
FORMAT = ihex
|
||||
|
||||
|
||||
# Object files directory
|
||||
# To put object files in current directory, use a dot (.), do NOT make
|
||||
# this an empty or blank macro!
|
||||
OBJDIR = .
|
||||
|
||||
|
||||
# List C++ source files here. (C dependencies are automatically generated.)
|
||||
CPPSRC =
|
||||
|
||||
|
||||
# List Assembler source files here.
|
||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||
# will not be considered source files but generated files (assembler
|
||||
# output from the compiler), and will be deleted upon "make clean"!
|
||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||
# it will preserve the spelling of the filenames, and gcc itself does
|
||||
# care about how the name is spelled on its command-line.
|
||||
ASRC =
|
||||
|
||||
|
||||
# Optimization level, can be [0, 1, 2, 3, s].
|
||||
# 0 = turn off optimization. s = optimize for size.
|
||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||
OPT = s
|
||||
|
||||
|
||||
# Debugging format.
|
||||
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
|
||||
# AVR Studio 4.10 requires dwarf-2.
|
||||
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
|
||||
DEBUG = dwarf-2
|
||||
|
||||
|
||||
# List any extra directories to look for include files here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRAINCDIRS =
|
||||
|
||||
|
||||
# Compiler flag to set the C Standard level.
|
||||
# c89 = "ANSI" C
|
||||
# gnu89 = c89 plus GCC extensions
|
||||
# c99 = ISO C99 standard (not yet fully implemented)
|
||||
# gnu99 = c99 plus GCC extensions
|
||||
CSTANDARD = -std=gnu99
|
||||
|
||||
|
||||
# Place -D or -U options here for C sources
|
||||
CDEFS = -DF_CPU=$(F_CPU)UL
|
||||
|
||||
|
||||
# Place -D or -U options here for ASM sources
|
||||
ADEFS = -DF_CPU=$(F_CPU)
|
||||
|
||||
|
||||
# Place -D or -U options here for C++ sources
|
||||
CPPDEFS = -DF_CPU=$(F_CPU)UL
|
||||
#CPPDEFS += -D__STDC_LIMIT_MACROS
|
||||
#CPPDEFS += -D__STDC_CONSTANT_MACROS
|
||||
|
||||
|
||||
|
||||
#---------------- Compiler Options C ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CFLAGS = -g$(DEBUG)
|
||||
CFLAGS += $(CDEFS)
|
||||
CFLAGS += -O$(OPT)
|
||||
CFLAGS += -funsigned-char
|
||||
CFLAGS += -funsigned-bitfields
|
||||
CFLAGS += -ffunction-sections
|
||||
CFLAGS += -fpack-struct
|
||||
CFLAGS += -fshort-enums
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
#CFLAGS += -mshort-calls
|
||||
#CFLAGS += -fno-unit-at-a-time
|
||||
#CFLAGS += -Wundef
|
||||
#CFLAGS += -Wunreachable-code
|
||||
#CFLAGS += -Wsign-compare
|
||||
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
|
||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
CFLAGS += $(CSTANDARD)
|
||||
|
||||
|
||||
#---------------- Compiler Options C++ ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CPPFLAGS = -g$(DEBUG)
|
||||
CPPFLAGS += $(CPPDEFS)
|
||||
CPPFLAGS += -O$(OPT)
|
||||
CPPFLAGS += -funsigned-char
|
||||
CPPFLAGS += -funsigned-bitfields
|
||||
CPPFLAGS += -fpack-struct
|
||||
CPPFLAGS += -fshort-enums
|
||||
CPPFLAGS += -fno-exceptions
|
||||
CPPFLAGS += -Wall
|
||||
CPPFLAGS += -Wundef
|
||||
#CPPFLAGS += -mshort-calls
|
||||
#CPPFLAGS += -fno-unit-at-a-time
|
||||
#CPPFLAGS += -Wstrict-prototypes
|
||||
#CPPFLAGS += -Wunreachable-code
|
||||
#CPPFLAGS += -Wsign-compare
|
||||
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
|
||||
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
#CPPFLAGS += $(CSTANDARD)
|
||||
|
||||
|
||||
#---------------- Assembler Options ----------------
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns: create listing
|
||||
# -gstabs: have the assembler create line number information; note that
|
||||
# for use in COFF files, additional information about filenames
|
||||
# and function names needs to be present in the assembler source
|
||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
||||
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
|
||||
# dump that will be displayed for a given single line of source input.
|
||||
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
|
||||
|
||||
|
||||
#---------------- Library Options ----------------
|
||||
# Minimalistic printf version
|
||||
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
|
||||
|
||||
# Floating point printf version (requires MATH_LIB = -lm below)
|
||||
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
|
||||
|
||||
# If this is left blank, then it will use the Standard printf version.
|
||||
PRINTF_LIB =
|
||||
#PRINTF_LIB = $(PRINTF_LIB_MIN)
|
||||
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
|
||||
|
||||
|
||||
# Minimalistic scanf version
|
||||
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
|
||||
|
||||
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
|
||||
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
|
||||
|
||||
# If this is left blank, then it will use the Standard scanf version.
|
||||
SCANF_LIB =
|
||||
#SCANF_LIB = $(SCANF_LIB_MIN)
|
||||
#SCANF_LIB = $(SCANF_LIB_FLOAT)
|
||||
|
||||
|
||||
MATH_LIB = -lm
|
||||
|
||||
|
||||
# List any extra directories to look for libraries here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRALIBDIRS =
|
||||
|
||||
|
||||
|
||||
#---------------- External Memory Options ----------------
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# used for variables (.data/.bss) and heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# only used for heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
EXTMEMOPTS =
|
||||
|
||||
|
||||
|
||||
#---------------- Linker Options ----------------
|
||||
# -Wl,...: tell GCC to pass this to linker.
|
||||
# -Map: create map file
|
||||
# --cref: add cross reference to map file
|
||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||
LDFLAGS += -Wl,--relax
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
LDFLAGS += $(EXTMEMOPTS)
|
||||
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
|
||||
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
|
||||
#LDFLAGS += -T linker_script.x
|
||||
|
||||
|
||||
|
||||
#---------------- Programming Options (avrdude) ----------------
|
||||
|
||||
# Programming hardware
|
||||
# Type: avrdude -c ?
|
||||
# to get a full listing.
|
||||
#
|
||||
AVRDUDE_PROGRAMMER = stk500v2
|
||||
|
||||
# com1 = serial port. Use lpt1 to connect to parallel port.
|
||||
AVRDUDE_PORT = com1 # programmer connected to serial device
|
||||
|
||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
||||
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
||||
|
||||
|
||||
# Uncomment the following if you want avrdude's erase cycle counter.
|
||||
# Note that this counter needs to be initialized first using -Yn,
|
||||
# see avrdude manual.
|
||||
#AVRDUDE_ERASE_COUNTER = -y
|
||||
|
||||
# Uncomment the following if you do /not/ wish a verification to be
|
||||
# performed after programming the device.
|
||||
#AVRDUDE_NO_VERIFY = -V
|
||||
|
||||
# Increase verbosity level. Please use this when submitting bug
|
||||
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
|
||||
# to submit bug reports.
|
||||
#AVRDUDE_VERBOSE = -v -v
|
||||
|
||||
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
||||
|
||||
|
||||
|
||||
#---------------- Debugging Options ----------------
|
||||
|
||||
# For simulavr only - target MCU frequency.
|
||||
DEBUG_MFREQ = $(F_CPU)
|
||||
|
||||
# Set the DEBUG_UI to either gdb or insight.
|
||||
# DEBUG_UI = gdb
|
||||
DEBUG_UI = insight
|
||||
|
||||
# Set the debugging back-end to either avarice, simulavr.
|
||||
DEBUG_BACKEND = avarice
|
||||
#DEBUG_BACKEND = simulavr
|
||||
|
||||
# GDB Init Filename.
|
||||
GDBINIT_FILE = __avr_gdbinit
|
||||
|
||||
# When using avarice settings for the JTAG
|
||||
JTAG_DEV = /dev/com1
|
||||
|
||||
# Debugging port used to communicate between GDB / avarice / simulavr.
|
||||
DEBUG_PORT = 4242
|
||||
|
||||
# Debugging host used to communicate between GDB / avarice / simulavr, normally
|
||||
# just set to localhost unless doing some sort of crazy debugging when
|
||||
# avarice is running on a different computer.
|
||||
DEBUG_HOST = localhost
|
||||
|
||||
|
||||
|
||||
#============================================================================
|
||||
|
||||
|
||||
# Define programs and commands.
|
||||
SHELL = sh
|
||||
CC = avr-gcc
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
AR = avr-ar rcs
|
||||
NM = avr-nm
|
||||
AVRDUDE = avrdude
|
||||
REMOVE = rm -f
|
||||
REMOVEDIR = rm -rf
|
||||
COPY = cp
|
||||
WINSHELL = cmd
|
||||
|
||||
|
||||
# Define Messages
|
||||
# English
|
||||
MSG_ERRORS_NONE = Errors: none
|
||||
MSG_BEGIN = -------- begin --------
|
||||
MSG_END = -------- end --------
|
||||
MSG_SIZE_BEFORE = Size before:
|
||||
MSG_SIZE_AFTER = Size after:
|
||||
MSG_COFF = Converting to AVR COFF:
|
||||
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
|
||||
MSG_FLASH = Creating load file for Flash:
|
||||
MSG_EEPROM = Creating load file for EEPROM:
|
||||
MSG_EXTENDED_LISTING = Creating Extended Listing:
|
||||
MSG_SYMBOL_TABLE = Creating Symbol Table:
|
||||
MSG_LINKING = Linking:
|
||||
MSG_COMPILING = Compiling C:
|
||||
MSG_COMPILING_CPP = Compiling C++:
|
||||
MSG_ASSEMBLING = Assembling:
|
||||
MSG_CLEANING = Cleaning project:
|
||||
MSG_CREATING_LIBRARY = Creating library:
|
||||
|
||||
|
||||
|
||||
|
||||
# Define all object files.
|
||||
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
|
||||
|
||||
# Define all listing files.
|
||||
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
|
||||
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
|
||||
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
|
||||
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
|
||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Default target.
|
||||
all: begin gccversion sizebefore build sizeafter end
|
||||
|
||||
# Change the build target to build a HEX file or a library.
|
||||
build: elf hex eep lss sym
|
||||
#build: lib
|
||||
|
||||
|
||||
elf: $(TARGET).elf
|
||||
hex: $(TARGET).hex
|
||||
eep: $(TARGET).eep
|
||||
lss: $(TARGET).lss
|
||||
sym: $(TARGET).sym
|
||||
LIBNAME=lib$(TARGET).a
|
||||
lib: $(LIBNAME)
|
||||
|
||||
|
||||
|
||||
# Eye candy.
|
||||
# AVR Studio 3.x does not check make's exit code but relies on
|
||||
# the following magic strings to be generated by the compile job.
|
||||
begin:
|
||||
@echo
|
||||
@echo $(MSG_BEGIN)
|
||||
|
||||
end:
|
||||
@echo $(MSG_END)
|
||||
@echo
|
||||
|
||||
|
||||
# Display size of file.
|
||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
||||
#ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
|
||||
ELFSIZE = $(SIZE) $(TARGET).elf
|
||||
|
||||
sizebefore:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
|
||||
2>/dev/null; echo; fi
|
||||
|
||||
sizeafter:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
|
||||
2>/dev/null; echo; fi
|
||||
|
||||
|
||||
|
||||
# Display compiler version information.
|
||||
gccversion :
|
||||
@$(CC) --version
|
||||
|
||||
|
||||
|
||||
# Program the device.
|
||||
program: $(TARGET).hex $(TARGET).eep
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
|
||||
|
||||
|
||||
# Generate avr-gdb config/init file which does the following:
|
||||
# define the reset signal, load the target file, connect to target, and set
|
||||
# a breakpoint at main().
|
||||
gdb-config:
|
||||
@$(REMOVE) $(GDBINIT_FILE)
|
||||
@echo define reset >> $(GDBINIT_FILE)
|
||||
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
|
||||
@echo end >> $(GDBINIT_FILE)
|
||||
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
|
||||
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
|
||||
ifeq ($(DEBUG_BACKEND),simulavr)
|
||||
@echo load >> $(GDBINIT_FILE)
|
||||
endif
|
||||
@echo break main >> $(GDBINIT_FILE)
|
||||
|
||||
debug: gdb-config $(TARGET).elf
|
||||
ifeq ($(DEBUG_BACKEND), avarice)
|
||||
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
|
||||
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
|
||||
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
|
||||
@$(WINSHELL) /c pause
|
||||
|
||||
else
|
||||
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
|
||||
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
|
||||
endif
|
||||
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
|
||||
|
||||
|
||||
|
||||
|
||||
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
|
||||
COFFCONVERT = $(OBJCOPY) --debugging
|
||||
COFFCONVERT += --change-section-address .data-0x800000
|
||||
COFFCONVERT += --change-section-address .bss-0x800000
|
||||
COFFCONVERT += --change-section-address .noinit-0x800000
|
||||
COFFCONVERT += --change-section-address .eeprom-0x810000
|
||||
|
||||
|
||||
|
||||
coff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
extcoff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
|
||||
# Create final output files (.hex, .eep) from ELF output file.
|
||||
%.hex: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@
|
||||
|
||||
%.eep: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EEPROM) $@
|
||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
||||
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -S -z $< > $@
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
%.sym: %.elf
|
||||
@echo
|
||||
@echo $(MSG_SYMBOL_TABLE) $@
|
||||
$(NM) -n $< > $@
|
||||
|
||||
|
||||
|
||||
# Create library from object files.
|
||||
.SECONDARY : $(TARGET).a
|
||||
.PRECIOUS : $(OBJ)
|
||||
%.a: $(OBJ)
|
||||
@echo
|
||||
@echo $(MSG_CREATING_LIBRARY) $@
|
||||
$(AR) $@ $(OBJ)
|
||||
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
.SECONDARY : $(TARGET).elf
|
||||
.PRECIOUS : $(OBJ)
|
||||
%.elf: $(OBJ)
|
||||
@echo
|
||||
@echo $(MSG_LINKING) $@
|
||||
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
|
||||
|
||||
|
||||
# Compile: create object files from C source files.
|
||||
$(OBJDIR)/%.o : %.c
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $<
|
||||
$(CC) -c $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create object files from C++ source files.
|
||||
$(OBJDIR)/%.o : %.cpp
|
||||
@echo
|
||||
@echo $(MSG_COMPILING_CPP) $<
|
||||
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C source files.
|
||||
%.s : %.c
|
||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C++ source files.
|
||||
%.s : %.cpp
|
||||
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files.
|
||||
$(OBJDIR)/%.o : %.S
|
||||
@echo
|
||||
@echo $(MSG_ASSEMBLING) $<
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Create preprocessed source for use in sending a bug report.
|
||||
%.i : %.c
|
||||
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Target: clean project.
|
||||
clean: begin clean_list end
|
||||
|
||||
clean_list :
|
||||
@echo
|
||||
@echo $(MSG_CLEANING)
|
||||
$(REMOVE) $(TARGET).hex
|
||||
$(REMOVE) $(TARGET).eep
|
||||
$(REMOVE) $(TARGET).cof
|
||||
$(REMOVE) $(TARGET).elf
|
||||
$(REMOVE) $(TARGET).map
|
||||
$(REMOVE) $(TARGET).sym
|
||||
$(REMOVE) $(TARGET).lss
|
||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
|
||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
|
||||
$(REMOVE) $(SRC:.c=.s)
|
||||
$(REMOVE) $(SRC:.c=.d)
|
||||
$(REMOVE) $(SRC:.c=.i)
|
||||
$(REMOVEDIR) .dep
|
||||
|
||||
|
||||
# Create object files directory
|
||||
$(shell mkdir $(OBJDIR) 2>/dev/null)
|
||||
|
||||
|
||||
# Include the dependency files.
|
||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||
|
||||
|
||||
# Listing of phony targets.
|
||||
.PHONY : all begin finish end sizebefore sizeafter gccversion \
|
||||
build elf hex eep lss sym coff extcoff \
|
||||
clean clean_list program debug gdb-config
|
|
@ -1,124 +0,0 @@
|
|||
/* Keyboard example for Teensy USB Development Board
|
||||
* http://www.pjrc.com/teensy/usb_keyboard.html
|
||||
* Copyright (c) 2008 PJRC.COM, LLC
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "usb_keyboard.h"
|
||||
|
||||
#define LED_CONFIG (DDRD |= (1<<6))
|
||||
#define LED_ON (PORTD &= ~(1<<6))
|
||||
#define LED_OFF (PORTD |= (1<<6))
|
||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
||||
|
||||
uint8_t number_keys[10]=
|
||||
{KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9};
|
||||
|
||||
uint16_t idle_count=0;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint8_t b, d, mask, i, reset_idle;
|
||||
uint8_t b_prev=0xFF, d_prev=0xFF;
|
||||
|
||||
// set for 16 MHz clock
|
||||
CPU_PRESCALE(0);
|
||||
|
||||
// Configure all port B and port D pins as inputs with pullup resistors.
|
||||
// See the "Using I/O Pins" page for details.
|
||||
// http://www.pjrc.com/teensy/pins.html
|
||||
DDRD = 0x00;
|
||||
DDRB = 0x00;
|
||||
PORTB = 0xFF;
|
||||
PORTD = 0xFF;
|
||||
|
||||
// Initialize the USB, and then wait for the host to set configuration.
|
||||
// If the Teensy is powered without a PC connected to the USB port,
|
||||
// this will wait forever.
|
||||
usb_init();
|
||||
while (!usb_configured()) /* wait */ ;
|
||||
|
||||
// Wait an extra second for the PC's operating system to load drivers
|
||||
// and do whatever it does to actually be ready for input
|
||||
_delay_ms(1000);
|
||||
|
||||
// Configure timer 0 to generate a timer overflow interrupt every
|
||||
// 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
|
||||
// This demonstrates how to use interrupts to implement a simple
|
||||
// inactivity timeout.
|
||||
TCCR0A = 0x00;
|
||||
TCCR0B = 0x05;
|
||||
TIMSK0 = (1<<TOIE0);
|
||||
|
||||
while (1) {
|
||||
// read all port B and port D pins
|
||||
b = PINB;
|
||||
d = PIND;
|
||||
// check if any pins are low, but were high previously
|
||||
mask = 1;
|
||||
reset_idle = 0;
|
||||
for (i=0; i<8; i++) {
|
||||
if (((b & mask) == 0) && (b_prev & mask) != 0) {
|
||||
usb_keyboard_press(KEY_B, KEY_SHIFT);
|
||||
usb_keyboard_press(number_keys[i], 0);
|
||||
reset_idle = 1;
|
||||
}
|
||||
if (((d & mask) == 0) && (d_prev & mask) != 0) {
|
||||
usb_keyboard_press(KEY_D, KEY_SHIFT);
|
||||
usb_keyboard_press(number_keys[i], 0);
|
||||
reset_idle = 1;
|
||||
}
|
||||
mask = mask << 1;
|
||||
}
|
||||
// if any keypresses were detected, reset the idle counter
|
||||
if (reset_idle) {
|
||||
// variables shared with interrupt routines must be
|
||||
// accessed carefully so the interrupt routine doesn't
|
||||
// try to use the variable in the middle of our access
|
||||
cli();
|
||||
idle_count = 0;
|
||||
sei();
|
||||
}
|
||||
// now the current pins will be the previous, and
|
||||
// wait a short delay so we're not highly sensitive
|
||||
// to mechanical "bounce".
|
||||
b_prev = b;
|
||||
d_prev = d;
|
||||
_delay_ms(2);
|
||||
}
|
||||
}
|
||||
|
||||
// This interrupt routine is run approx 61 times per second.
|
||||
// A very simple inactivity timeout is implemented, where we
|
||||
// will send a space character.
|
||||
ISR(TIMER0_OVF_vect)
|
||||
{
|
||||
idle_count++;
|
||||
if (idle_count > 61 * 8) {
|
||||
idle_count = 0;
|
||||
usb_keyboard_press(KEY_SPACE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -349,8 +349,8 @@ int8_t usb_keyboard_send(void)
|
|||
//
|
||||
ISR(USB_GEN_vect)
|
||||
{
|
||||
uint8_t intbits, i; // used to declare `t` as well, but it wasn't used
|
||||
// ::Blazak, 2012::
|
||||
uint8_t intbits, i; // used to declare a variable `t` as well, but it
|
||||
// wasn't used ::Ben Blazak, 2012::
|
||||
static uint8_t div4=0;
|
||||
|
||||
intbits = UDINT;
|
||||
|
|
|
@ -19,7 +19,7 @@ extern volatile uint8_t keyboard_leds;
|
|||
#define usb_debug_flush_output()
|
||||
|
||||
|
||||
#if 0 // removed in favor of equilivent code elsewhere ::Ben Blazak, 2012::
|
||||
#if 0 // removed in favor of equivalent code elsewhere ::Ben Blazak, 2012::
|
||||
|
||||
#define KEY_CTRL 0x01
|
||||
#define KEY_SHIFT 0x02
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* key functions: code
|
||||
*
|
||||
* These functions may do.. pretty much anything rational that thay like. If
|
||||
* they want keycodes to be sent to the host in an aggrate report, they're
|
||||
* responsible for modifying the appropriate report variables.
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
||||
#include "lib/data-types.h"
|
||||
#include "lib/usb/usage-page/keyboard.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
#include "key-functions.h"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if 0 // not being used right now
|
||||
static uint8_t _inc_current_layer(uint8_t * current_layer) {
|
||||
if (*current_layer < (KB_LAYERS-1))
|
||||
(*current_layer)++;
|
||||
else
|
||||
return 1; // error: can't increase
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
static uint8_t _dec_current_layer(uint8_t * current_layer) {
|
||||
if (*current_layer > 0)
|
||||
(*current_layer)--;
|
||||
else
|
||||
return 1; // error: can't decrease
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void kbfun_press(
|
||||
uint8_t keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
// no-op
|
||||
if (keycode == 0)
|
||||
return;
|
||||
|
||||
// modifier keys
|
||||
switch (keycode) {
|
||||
case KEY_LeftControl: keyboard_modifier_keys |= (1<<0);
|
||||
return;
|
||||
case KEY_LeftShift: keyboard_modifier_keys |= (1<<1);
|
||||
return;
|
||||
case KEY_LeftAlt: keyboard_modifier_keys |= (1<<2);
|
||||
return;
|
||||
case KEY_LeftGUI: keyboard_modifier_keys |= (1<<3);
|
||||
return;
|
||||
case KEY_RightControl: keyboard_modifier_keys |= (1<<4);
|
||||
return;
|
||||
case KEY_RightShift: keyboard_modifier_keys |= (1<<5);
|
||||
return;
|
||||
case KEY_RightAlt: keyboard_modifier_keys |= (1<<6);
|
||||
return;
|
||||
case KEY_RightGUI: keyboard_modifier_keys |= (1<<7);
|
||||
return;
|
||||
}
|
||||
|
||||
// all others
|
||||
for (uint8_t i=0; i<6; i++)
|
||||
if (keyboard_keys[i] == 0) {
|
||||
keyboard_keys[i] = keycode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void kbfun_release(
|
||||
uint8_t keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
// no-op
|
||||
if (keycode == 0)
|
||||
return;
|
||||
|
||||
// modifier keys
|
||||
switch (keycode) {
|
||||
case KEY_LeftControl: keyboard_modifier_keys &= ~(1<<0);
|
||||
return;
|
||||
case KEY_LeftShift: keyboard_modifier_keys &= ~(1<<1);
|
||||
return;
|
||||
case KEY_LeftAlt: keyboard_modifier_keys &= ~(1<<2);
|
||||
return;
|
||||
case KEY_LeftGUI: keyboard_modifier_keys &= ~(1<<3);
|
||||
return;
|
||||
case KEY_RightControl: keyboard_modifier_keys &= ~(1<<4);
|
||||
return;
|
||||
case KEY_RightShift: keyboard_modifier_keys &= ~(1<<5);
|
||||
return;
|
||||
case KEY_RightAlt: keyboard_modifier_keys &= ~(1<<6);
|
||||
return;
|
||||
case KEY_RightGUI: keyboard_modifier_keys &= ~(1<<7);
|
||||
return;
|
||||
}
|
||||
|
||||
// all others
|
||||
for (uint8_t i=0; i<6; i++)
|
||||
if (keyboard_keys[i] == keycode) {
|
||||
keyboard_keys[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,20 +12,16 @@
|
|||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
typedef void (*kbfun_funptr_t)(uint8_t*, uint8_t*, uint8_t*, uint8_t*);
|
||||
typedef void (*kbfun_funptr_t)(
|
||||
uint8_t, uint8_t *,
|
||||
uint8_t *, uint8_t * );
|
||||
|
||||
void kbfun_press(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
uint8_t keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
void kbfun_release(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
void kbfun_mod_press(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
void kbfun_mod_release(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
uint8_t keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
|
||||
#endif
|
||||
|
|
@ -1,10 +1,5 @@
|
|||
# src/lib-other
|
||||
Files taken from other projects
|
||||
|
||||
## links to original files
|
||||
|
||||
* [pjrc] (http://pjrc.com/teensy/)
|
||||
* [usb_keyboard] (http://pjrc.com/teensy/usb_keyboard.zip)
|
||||
# src/lib
|
||||
Stuff that's generally useful
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* TWI (I2C) : exports
|
||||
*
|
||||
* Code specific to different development boards is used by modifying a
|
||||
* variable in the makefile.
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#undef _str
|
||||
#undef _expstr
|
||||
#undef _inc
|
||||
#define _str(s) #s // stringify
|
||||
#define _expstr(s) _str(s) // expand -> stringify
|
||||
#define _inc _expstr(twi/MAKEFILE_BOARD.h) // inc(lude)
|
||||
#include _inc
|
||||
#undef _str
|
||||
#undef _expstr
|
||||
#undef _inc
|
||||
|
|
@ -3,13 +3,15 @@
|
|||
*
|
||||
* - This is mostly straight from the datasheet, section 20.6.6, figure 20-11
|
||||
* (the code example in C), and section 20.8.1, figure 20-12
|
||||
* - Also see the documentation for `<util/twi.h>` at <http://www.nongnu.org/avr-libc/user-manual/group__util__twi.html#ga8d3aca0acc182f459a51797321728168>
|
||||
* - Also see the documentation for `<util/twi.h>` at
|
||||
* <http://www.nongnu.org/avr-libc/user-manual/group__util__twi.html#ga8d3aca0acc182f459a51797321728168>
|
||||
*
|
||||
* Some other (more complete) TWI libraries for the Teensy 2.0 (and other Amtel
|
||||
* Some other (more complete) TWI libraries for the Teensy 2.0 (and other Atmel
|
||||
* processors):
|
||||
* - [i2cmaster] (http://homepage.hispeed.ch/peterfleury/i2cmaster.zip)
|
||||
* - written by [peter-fleury] (http://homepage.hispeed.ch/peterfleury/)
|
||||
* - [the arduino twi library] (https://github.com/arduino/Arduino/tree/master/libraries/Wire/utility)
|
||||
* - [the arduino twi library]
|
||||
* (https://github.com/arduino/Arduino/tree/master/libraries/Wire/utility)
|
||||
* - look for an older version if you need one that doesn't depend on all the
|
||||
* other Arduino stuff
|
||||
* ----------------------------------------------------------------------------
|
||||
|
@ -19,10 +21,8 @@
|
|||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include <util/delay.h> //dbg
|
||||
#include <util/twi.h>
|
||||
|
||||
#include "twi.h"
|
||||
#include "lib/twi.h"
|
||||
|
||||
|
||||
void twi_init(void) {
|
|
@ -1,4 +1,4 @@
|
|||
# Documentation : Teensy 2.0 I²C
|
||||
# Documentation : I²C : Teensy 2.0
|
||||
|
||||
## I²C Status Codes (for Master modes)
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* TODO: not sure where this stuff should be yet. a lot of it (depending on
|
||||
* what ends up here) will likely be device and application specific.
|
||||
*
|
||||
* - The following document versions were used, unless otherwise noted:
|
||||
* - USB Specification: revision 2.0
|
||||
* - HID Usage Tables: version 1.12
|
||||
* - Device Class Definition for Human Interface Devices (HID): version 1.11
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
// TODO: does stuff from spec sec 9.4.* belong directly in an interrupt vector?
|
||||
|
||||
// - spec sec 9.4.1 (Standard Device Requests / Clear Feature) (pg 252)
|
||||
|
||||
// - spec sec 9.4.2 (Standard Device Requests / Get Configuration) (pg 253)
|
||||
|
||||
// - spec sec 9.4.3 (Standard Device Requests / Get Descriptor) (pg 253)
|
||||
|
||||
// - spec sec 9.4.4 (Standard Device Requests / Get Interface) (pg 254)
|
||||
|
||||
// - spec sec 9.4.5 (Standard Device Requests / Get Status) (pg 254)
|
||||
|
||||
// - spec sec 9.4.6 (Standard Device Requests / Set Address) (pg 256)
|
||||
|
||||
// - spec sec 9.4.7 (Standard Device Requests / Set Configuration) (pg 257)
|
||||
|
||||
// - spec sec 9.4.8 (Standard Device Requests / Set Descriptor) (pg 257)
|
||||
|
||||
// - spec sec 9.4.9 (Standard Device Requests / Set Feature) (pg 258)
|
||||
|
||||
// - spec sec 9.4.10 (Standard Device Requests / Set Interface) (pg 259)
|
||||
|
||||
// - spec sec 9.4.11 (Standard Device Requests / Synch Frame) (pg 260)
|
||||
|
||||
// TODO
|
||||
// - read the hid usage tables .pdf
|
||||
// - read the hid device class definition .pdf
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* USB 2.0 common macros and definitions
|
||||
*
|
||||
* See "notes from usb 2.0 spec sec 9 (usb device framework).h".
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef USB_COMMON_h
|
||||
#define USB_COMMON_h
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// - spec table 9-4 (Standard Request Codes)
|
||||
#define USB_GET_STATUS 0
|
||||
#define USB_CLEAR_FEATURE 1
|
||||
// (reserved for future use): 2
|
||||
#define USB_SET_FEATURE 3
|
||||
// (reserved for future use): 4
|
||||
#define USB_SET_ADDRESS 5
|
||||
#define USB_GET_DESCRIPTOR 6
|
||||
#define USB_SET_DESCRIPTOR 7
|
||||
#define USB_GET_CONFIGURATION 8
|
||||
#define USB_SET_CONFIGURATION 9
|
||||
#define USB_GET_INTERFACE 10
|
||||
#define USB_SET_INTERFACE 11
|
||||
#define USB_SYNCH_FRAME 12
|
||||
|
||||
// - spec table 9-5 (Descriptor Types)
|
||||
#define USB_DEVICE 1
|
||||
#define USB_CONFIGURATION 2
|
||||
#define USB_STRING 3
|
||||
#define USB_INTERFACE 4
|
||||
#define USB_ENDPOINT 5
|
||||
#define USB_DEVICE_QUALIFIER 6
|
||||
#define USB_OTHER_SPEED_CONFIGURATION 7
|
||||
#define USB_INTERFACE_POWER 8
|
||||
|
||||
// - spec table 9-6 (Standard Feature Selectors)
|
||||
#define USB_DEVICE_REMOTE_WAKEUP 1 // recipient: device
|
||||
#define USB_ENDPOINT_HALT 0 // recipient: endpoint
|
||||
#define USB_TEST_MODE 2 // recipient: device
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# Notes from the HID Device Class Definition, version 1.11
|
||||
|
||||
|
||||
* sec 4.1 (The HID Class)
|
||||
* The `bInterfaceClass` member of an Interface descriptor is always 3 for
|
||||
HID class devices.
|
||||
|
||||
* sec 4.2 (Subclass)
|
||||
* The `bInterfaceSubClass` member declares whether a device supports a boot interface.
|
||||
* 0 => no subclass
|
||||
* 1 => boot interface subclass
|
||||
* 2..255 => reserved
|
||||
|
||||
* sec 4.3 (Protocols)
|
||||
* The `bInterfaceProtocol` member of an Interface descriptor only has meaning if the `bInterfaceSubClass` member declares that the device supports a boot interface, otherwise it is 0.
|
||||
* 0 => none
|
||||
* 1 => keyboard
|
||||
* 2 => mouse
|
||||
* 3..255 => reserved
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
Released under The MIT License (MIT) (see "license.md")
|
||||
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
|
|
@ -0,0 +1,858 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* Notes from the USB 2.0 specification
|
||||
*
|
||||
* Written as a header file because I was going to actually use it. Changed my
|
||||
* mind because it's simpler to use uint8_t arrays for things than to use
|
||||
* structs. it's also easier i think to keep the least and most significant
|
||||
* bits of uint16_t values separate initially instead of separating them later.
|
||||
* Kept it as a header because it looks cleaner this way than i could make it
|
||||
* look as an .md file.
|
||||
*
|
||||
* - conventions from the spec
|
||||
* - variable prefixes
|
||||
* - 'b' : bits or bytes; dependent on context
|
||||
* - 'bcd' : binary-coded decimal
|
||||
* - 'bm' : bitmap
|
||||
* - 'd' : descriptor
|
||||
* - 'i' : index
|
||||
* - 'w' : word
|
||||
*
|
||||
* - conventions used in this file
|
||||
* - everything prefixed with or `USB_` (for non-function-like macros) or
|
||||
* `usb_` (for everything else)
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef USB_DATA_STRUCTURES_h
|
||||
#define USB_DATA_STRUCTURES_h
|
||||
|
||||
#pragma pack(push)
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* - spec sec 9.3 (USB Device Requests)
|
||||
* - table 9-2 (Format of Setup Data)
|
||||
*/
|
||||
struct usb_setup_data {
|
||||
uint8_t bmRequestType;
|
||||
/* value: bitmap
|
||||
* - data transfer direction, type, recipient
|
||||
* (see macros below)
|
||||
*/
|
||||
|
||||
uint8_t bRequest;
|
||||
/* value: value
|
||||
* - type of request (depending on bmRequestType)
|
||||
* (see spec table 9-3 (Standard Device Requests))
|
||||
*/
|
||||
|
||||
uint16_t wValue;
|
||||
/* value: value
|
||||
* - varies according to request; used to pass a request specific
|
||||
* parameter to the device
|
||||
*/
|
||||
|
||||
uint16_t wIndex;
|
||||
/* value: index or offset
|
||||
* - varies according to request; often used to specify an endpoint or
|
||||
* an interface
|
||||
* (see spec figure 9-2 and 9-3, copied below)
|
||||
*/
|
||||
|
||||
uint16_t wLength;
|
||||
/* value: count
|
||||
* - number of bytes to transfer if there is a data stage
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
/* - spec sec 9.3 (USB Device Requests)
|
||||
* - table 9-2 (Format of Setup Data)
|
||||
* - bmRequestType
|
||||
*
|
||||
* .-------------------------------------------------------.
|
||||
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||||
* |-------------------------------------------------------|
|
||||
* | direction | type | recipient |
|
||||
* '-------------------------------------------------------'
|
||||
*
|
||||
* - direction: 0 => host to device
|
||||
* 1 => device to host
|
||||
*
|
||||
* - type: 0 => standard
|
||||
* 1 => class
|
||||
* 2 = vendor
|
||||
* 3 = reserved
|
||||
*
|
||||
* - recipient: 0 => device
|
||||
* 1 => interface
|
||||
* 2 => endpoint
|
||||
* 3 => other
|
||||
* 4..31 => reserved
|
||||
*/
|
||||
// --- data transfer direction
|
||||
#define usb_bmRequestType_hostToDevice(val) (((val) & (0b1<<7)) == (0<<7))
|
||||
#define usb_bmRequestType_deviceToHost(val) (((val) & (0b1<<7)) == (1<<7))
|
||||
// --- type
|
||||
#define usb_bmRequestType_standard(val) (((val) & (0b11<<5)) == (0<<5))
|
||||
#define usb_bmRequestType_class(val) (((val) & (0b11<<5)) == (1<<5))
|
||||
#define usb_bmRequestType_vendor(val) (((val) & (0b11<<5)) == (2<<5))
|
||||
#define usb_bmRequestType_reserved(val) (((val) & (0b11<<5)) == (3<<5))
|
||||
// --- recipient
|
||||
#define usb_bmRequestType_device(val) (((val) & (0b11111<<0)) == (0<<0))
|
||||
#define usb_bmRequestType_interface(val) (((val) & (0b11111<<0)) == (1<<0))
|
||||
#define usb_bmRequestType_endpoint(val) (((val) & (0b11111<<0)) == (2<<0))
|
||||
#define usb_bmRequestType_other(val) (((val) & (0b11111<<0)) == (3<<0))
|
||||
#define usb_bmRequestType_reserved(val) (((val) & (0b11100<<0)) != (0<<0))
|
||||
|
||||
|
||||
/* - spec sec 9.3.4 (wIndex)
|
||||
* - figure 9-2 (format when specifying an endpoint)
|
||||
*
|
||||
* .-------------------------------------------------------.
|
||||
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||||
* |-------------------------------------------------------|
|
||||
* | direction | reserved (reset to 0) | endpoint number |
|
||||
* >-----------------------------------------------------<
|
||||
* | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 |
|
||||
* |-------------------------------------------------------|
|
||||
* | reserved (reset to 0) |
|
||||
* '-------------------------------------------------------'
|
||||
*
|
||||
* - direction: 0 => out (to device), 1 => in (to host)
|
||||
*/
|
||||
#define usb_wIndex_endpoint(direction, endpoint_number) \
|
||||
( (uint16_t) (((direction)<<7) | (endpoint_number)) )
|
||||
|
||||
|
||||
/* - spec sec 9.3.4 (wIndex)
|
||||
* - figure 9-3 (format when specifying an interface)
|
||||
*
|
||||
* .-------------------------------------------------------.
|
||||
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||||
* |-------------------------------------------------------|
|
||||
* | interface number |
|
||||
* >-----------------------------------------------------<
|
||||
* | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 |
|
||||
* |-------------------------------------------------------|
|
||||
* | reserved (reset to 0) |
|
||||
* '-------------------------------------------------------'
|
||||
*/
|
||||
#define usb_wIndex_interface(interface_number) \
|
||||
( (uint16_t) (interface_number) )
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* - spec table 9-4 (Standard Request Codes)
|
||||
*/
|
||||
#define USB_GET_STATUS 0
|
||||
#define USB_CLEAR_FEATURE 1
|
||||
// (reserved for future use): 2
|
||||
#define USB_SET_FEATURE 3
|
||||
// (reserved for future use): 4
|
||||
#define USB_SET_ADDRESS 5
|
||||
#define USB_GET_DESCRIPTOR 6
|
||||
#define USB_SET_DESCRIPTOR 7
|
||||
#define USB_GET_CONFIGURATION 8
|
||||
#define USB_SET_CONFIGURATION 9
|
||||
#define USB_GET_INTERFACE 10
|
||||
#define USB_SET_INTERFACE 11
|
||||
#define USB_SYNCH_FRAME 12
|
||||
|
||||
/* - spec table 9-5 (Descriptor Types)
|
||||
*/
|
||||
#define USB_DEVICE 1
|
||||
#define USB_CONFIGURATION 2
|
||||
#define USB_STRING 3
|
||||
#define USB_INTERFACE 4
|
||||
#define USB_ENDPOINT 5
|
||||
#define USB_DEVICE_QUALIFIER 6
|
||||
#define USB_OTHER_SPEED_CONFIGURATION 7
|
||||
#define USB_INTERFACE_POWER 8
|
||||
|
||||
/* - spec table 9-6 (Standard Feature Selectors)
|
||||
*/
|
||||
#define USB_DEVICE_REMOTE_WAKEUP 1 // recipient: device
|
||||
#define USB_ENDPOINT_HALT 0 // recipient: endpoint
|
||||
#define USB_TEST_MODE 2 // recipient: device
|
||||
|
||||
|
||||
/* - spec sec 9.4.5 (Standard Device Requests / Get Status)
|
||||
* - figure 9-4 (information returned by a GetStatus() request to a device)
|
||||
*
|
||||
* .------------------------------------------------------------.
|
||||
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||||
* |------------------------------------------------------------|
|
||||
* | reserved (reset to 0) | remote wakeup | self powered |
|
||||
* >----------------------------------------------------------<
|
||||
* | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 |
|
||||
* |------------------------------------------------------------|
|
||||
* | reserved (reset to 0) |
|
||||
* '------------------------------------------------------------'
|
||||
*
|
||||
* - remote wakeup: 0 => ability of device to signal remote wakeup disabled
|
||||
* (default)
|
||||
* 1 => ability ................................. enabled
|
||||
*
|
||||
* - self powered: 0 => device is bus powered
|
||||
* 1 => device is self powered
|
||||
*/
|
||||
#define usb_getStatus_device(remote_wakeup, self_powered) \
|
||||
( (uint16_t) (((remote_wakeup)<<1) | (self_powered)) )
|
||||
|
||||
|
||||
/* - spec sec 9.4.5 (Standard Device Requests / Get Status)
|
||||
* - figure 9-5 (information returned by a GetStatus() request to an
|
||||
* interface)
|
||||
*
|
||||
* .------------------------------------------------------------.
|
||||
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||||
* |------------------------------------------------------------|
|
||||
* | reserved (reset to 0) |
|
||||
* >----------------------------------------------------------<
|
||||
* | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 |
|
||||
* |------------------------------------------------------------|
|
||||
* | reserved (reset to 0) |
|
||||
* '------------------------------------------------------------'
|
||||
*/
|
||||
#define usb_getStatus_interface() ( (uint16_t) 0 )
|
||||
|
||||
|
||||
/* - spec sec 9.4.5 (Standard Device Requests / Get Status)
|
||||
* - figure 9-6 (information returned by a GetStatus() request to an
|
||||
* endpoint)
|
||||
*
|
||||
* .------------------------------------------------------------.
|
||||
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||||
* |------------------------------------------------------------|
|
||||
* | reserved (reset to 0) | halt |
|
||||
* >----------------------------------------------------------<
|
||||
* | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 |
|
||||
* |------------------------------------------------------------|
|
||||
* | reserved (reset to 0) |
|
||||
* '------------------------------------------------------------'
|
||||
*
|
||||
* - halt: 0 => endpoint not currently halted
|
||||
* 1 => endpoint currently halted
|
||||
*/
|
||||
#define usb_getStatus_endpoint(halt) ( (uint16_t) (halt) )
|
||||
|
||||
|
||||
/* - spec sec 9.4.9 (Set Feature)
|
||||
* - table 9-7 (Test Mode Selectors)
|
||||
*
|
||||
* - in the case of a SetFeature(TEST_MODE...):
|
||||
* - the most significant byte of wIndex is used to specify the test mode
|
||||
* - the lower byte of wIndex must be zero, because the recipient must be the
|
||||
* device
|
||||
*/
|
||||
// (reserved): (0x0000)
|
||||
#define USB_TEST_MODE_wIndex_Test_J ( (uint16_t) (0x0100) )
|
||||
#define USB_TEST_MODE_wIndex_Test_K ( (uint16_t) (0x0200) )
|
||||
#define USB_TEST_MODE_wIndex_Test_SE0_NAK ( (uint16_t) (0x0300) )
|
||||
#define USB_TEST_MODE_wIndex_Test_Packet ( (uint16_t) (0x0400) )
|
||||
#define USB_TEST_MODE_wIndex_Test_Force_Enable ( (uint16_t) (0x0500) )
|
||||
// (reserved for standard test selectors): (0x0600)..(0x3F00)
|
||||
// (reserved): (0x3F00)..(0xBF00)
|
||||
// (reserved for vendor-specific test modes): (0xC000)..(0xFF00)
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* - spec sec 9.6.1 (Standard USB Descriptor Definitions / Device)
|
||||
* - table 9-8 (Standard Device Descriptor)
|
||||
*/
|
||||
struct usb_device_descriptor {
|
||||
uint8_t bLength;
|
||||
/* value: number
|
||||
* - size of this descriptor in bytes
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorType;
|
||||
/* value: constant
|
||||
* - DEVICE Descriptor Type
|
||||
* - a high speed capable device will set this to 2.0 (0x0200). if the
|
||||
* device is full-speed or low-speed only, this version number only
|
||||
* means that it'll send a request error when asked for the
|
||||
* device_qualifier descriptor
|
||||
*/
|
||||
|
||||
uint16_t bcdUSB;
|
||||
/* value: binary coded decimal
|
||||
* - usb spec release number
|
||||
* - format: 0xJJMN, where JJ = major version, M = minor version,
|
||||
* N = sub-minor version; e.g. version 2.1.3 => 0x0213
|
||||
*/
|
||||
|
||||
uint8_t bDeviceClass;
|
||||
/* value: class
|
||||
* - class code (assigned by the USB-IF)
|
||||
* - 0x00 => each interface within a configuration specifies its own
|
||||
* class information and the various interfaces operate independently
|
||||
* - 0x01..0xFE => the device supports different class specifications
|
||||
* on different interfaces and the interfaces may not operate
|
||||
* independently. this value identifies the class definition used
|
||||
* for the aggregate interfaces
|
||||
* - 0xFF => the device class is vendor-specific
|
||||
*/
|
||||
|
||||
uint8_t bDeviceSubClass;
|
||||
/* value: subclass
|
||||
* - subclass code (assigned by the USB-IF)
|
||||
* - qualified by bDeviceClass
|
||||
* - if bDeviceClass is reset to 0, this field must be also
|
||||
* - if bDeviceClass != 0xFF , all values are reserved for assignment
|
||||
* by the USB-IF
|
||||
*/
|
||||
|
||||
uint8_t bDeviceProtocol;
|
||||
/* value: protocol
|
||||
* - protocol code (assigned by the USB-IF)
|
||||
* - qualified by bDeviceClass and bDeviceSubClass
|
||||
* - if a device supports class-specific protocols on a device basis as
|
||||
* opposed to an interface basis, this code identifies the protocols
|
||||
* that the device uses as defined by the specification of the device
|
||||
* class
|
||||
* - 0x00 => the device does not use class-specific protocols on a
|
||||
* device basis. however, it may use class-specific protocols on an
|
||||
* interface basis
|
||||
* - 0xFF => the device uses a vendor-specific protocol on a device
|
||||
* basis
|
||||
*/
|
||||
|
||||
uint8_t bMaxPacketSize0;
|
||||
/* value: number
|
||||
* - max packet size for endpoint 0
|
||||
* - only 8, 16, 32, or 64 are valid
|
||||
* - if operating at high-speed, the value must be 64
|
||||
*/
|
||||
|
||||
uint16_t idVendor;
|
||||
/* value: id
|
||||
* - vendor ID (assigned by the USB-IF)
|
||||
*/
|
||||
|
||||
uint16_t idProduct;
|
||||
/* value: id
|
||||
* - product ID (assigned by the manufacturer)
|
||||
*/
|
||||
|
||||
uint16_t bcdDevice;
|
||||
/* value: binary coded decimal
|
||||
* - device release number
|
||||
*/
|
||||
|
||||
uint8_t iManufacturer;
|
||||
/* value: index
|
||||
* - index of string descriptor describing manufacturer
|
||||
*/
|
||||
|
||||
uint8_t iProduct;
|
||||
/* value: index
|
||||
* - index of string descriptor describing product
|
||||
*/
|
||||
|
||||
uint8_t iSerialNumber;
|
||||
/* value: index
|
||||
* - index of string descriptor describing the device's serial number
|
||||
*/
|
||||
|
||||
uint8_t bNumConfigurations;
|
||||
/* value: number
|
||||
* - number of possible configurations (at the current operating speed)
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* - spec sec 9.6.2 (Standard USB Descriptor Definitions / Device_Qualifier)
|
||||
* - table 9-9 (Device_Qualifier Descriptor)
|
||||
*
|
||||
* - required if the device has different device information for full-speed and
|
||||
* high-speed
|
||||
*
|
||||
* - not valid for a full-speed only device (with a device descriptor version
|
||||
* number equal to 0x0200); if requested, the device must respond with a
|
||||
* request error
|
||||
*/
|
||||
struct usb_device_qualifier_descriptor {
|
||||
uint8_t bLength;
|
||||
/* value: number
|
||||
* - size of descriptor
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorType;
|
||||
/* value: constant
|
||||
* - device qualifier type
|
||||
*/
|
||||
|
||||
uint16_t bcdUSB;
|
||||
/* value: binary coded decimal
|
||||
* - usb spec release number
|
||||
* - format: (see note for usb_device_descriptor.bcdUSB)
|
||||
* - must be at least 2.0 (0x0200) for this descriptor
|
||||
*/
|
||||
|
||||
uint8_t bDeviceClass;
|
||||
/* value: class
|
||||
*/
|
||||
|
||||
uint8_t bDeviceSubClass;
|
||||
/* value: subclass
|
||||
*/
|
||||
|
||||
uint8_t bDeviceProtocol;
|
||||
/* value: protocol
|
||||
*/
|
||||
|
||||
uint8_t bMaxPacketSize0;
|
||||
/* value: number
|
||||
* - max packet size for other speed
|
||||
*/
|
||||
|
||||
uint8_t bNumConfigurations;
|
||||
/* value: number
|
||||
* - number of other-speed configurations
|
||||
*/
|
||||
|
||||
uint8_t bReserved;
|
||||
/* value: 0
|
||||
* - reserved for future use
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* - spec sec 9.6.3 (Standard USB Descriptor Definitions / Configuration)
|
||||
* - table 9-10 (Standard Configuration Descriptor)
|
||||
*
|
||||
* - spec sec 9.6.4 (Standard USB Descriptor Definitions /
|
||||
* Other_Speed_Configuration)
|
||||
* - table 9-11 (Other_Speed_Configuration Descriptor)
|
||||
*
|
||||
* - both descriptors have the same structure. the only specified difference
|
||||
* is the value of the bDescriptorType constant.
|
||||
*/
|
||||
struct usb_configuration_descriptor {
|
||||
uint8_t bLength;
|
||||
/* value: number
|
||||
* - size of this descriptor in bytes
|
||||
|
||||
uint8_t bDescriptorType;
|
||||
* value: constant
|
||||
* - CONFIGURATION Descriptor Type
|
||||
* (for Standard Configuration Descriptor)
|
||||
* - OTHER_SPEED_CONFIGURATION Type
|
||||
* (for Other Speed Configuration Descriptor)
|
||||
*/
|
||||
|
||||
uint16_t wTotalLength;
|
||||
/* value: number
|
||||
* - total length of data returned for this configuration. includes
|
||||
* the combined length of all descriptors (configuration, interface,
|
||||
* endpoint, and class- or vendor-specific) returned for this
|
||||
* configuration.
|
||||
*/
|
||||
|
||||
uint8_t bNumInterfaces;
|
||||
/* value: number
|
||||
* - number of interfaces supported by this configuration
|
||||
*/
|
||||
|
||||
uint8_t bConfigurationValue;
|
||||
/* value: number
|
||||
* - value to use as an argument to the SetConfiguration() request to
|
||||
* select this configuration
|
||||
*/
|
||||
|
||||
uint8_t iConfiguration;
|
||||
/* value: index
|
||||
* - index of string descriptor describing this configuration
|
||||
*/
|
||||
|
||||
uint8_t bmAttributes;
|
||||
/* value: bitmap
|
||||
* - self-powered, remote wakeup
|
||||
* (see macro below)
|
||||
*/
|
||||
|
||||
uint8_t bMaxPower;
|
||||
/* value: mA
|
||||
* - max power consumption of the USB device from the bus
|
||||
* (configuration specific) (when device is fully operational)
|
||||
* - format: expressed in 2 mA units (i.e. value=50 => 100mA)
|
||||
* - note: a device configuration reports whether the configuration is
|
||||
* bus-powered or self-powered. device status reports whether the
|
||||
* device is currently self-powered. if a device is disconnected
|
||||
* from its external power source, it updates device status to
|
||||
* indicate that. it may not increase its power draw from the bus
|
||||
* beyond the amount reported by its configuration. if it can
|
||||
* continue to operate, it does so. if not, it fails operations it
|
||||
* can no longer support, and the host software can determine the
|
||||
* cause of failure by checking the status and noting the loss of the
|
||||
* device's external power.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
/* - spec sec 9.6.3 (Standard USB Descriptor Definitions / Configuration)
|
||||
* - table 9-10 (Standard Configuration Descriptor)
|
||||
* - bmAttributes
|
||||
*
|
||||
* .--------------------------------------------------------.
|
||||
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||||
* |--------------------------------------------------------|
|
||||
* | reserved | self | remote | reserved |
|
||||
* | (set to 1) | powered | wakeup | (reset to 0) |
|
||||
* '--------------------------------------------------------'
|
||||
*
|
||||
* - D7: must be set to 1 for historical reasons
|
||||
*
|
||||
* - self powered: 0 => false
|
||||
* 1 => true
|
||||
* - a device configuration that uses both bus and local power must report a
|
||||
* non-zero value in bMaxPower (to indicate the amount of bus power
|
||||
* required) and set D6 = 1
|
||||
*
|
||||
* - remote wakeup: 0 => not supported by configuration
|
||||
* 1 => supported by configuration
|
||||
*/
|
||||
#define usb_configuration_bmAttributes(self_powered, remote_wakeup) \
|
||||
( (uint8_t) ((1<<7) | ((self_powered)<<6) | ((remote_wakeup)<<5)) )
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* - spec sec 9.6.5 (Standard USB Descriptor Definitions / Interface)
|
||||
* - table 9-12 (Standard Interface Descriptor)
|
||||
*/
|
||||
struct usb_interface_descriptor {
|
||||
uint8_t bLength;
|
||||
/* value: number
|
||||
* - size of this descriptor in bytes
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorType;
|
||||
/* value: constant
|
||||
* - INTERFACE Descriptor Type
|
||||
*/
|
||||
|
||||
uint8_t bInterfaceNumber;
|
||||
/* value: number
|
||||
* - number of this interface
|
||||
* - zero-based value identifying the index in the array of concurrent
|
||||
* interfaces supported by this configuration
|
||||
*/
|
||||
|
||||
uint8_t bAlternateSetting;
|
||||
/* value: number
|
||||
* - value used to select this alternate setting for the interface
|
||||
* identified in the prior field
|
||||
*/
|
||||
|
||||
uint8_t bNumEndpoints;
|
||||
/* value: number
|
||||
* - number of endpoints used by this interface (excluding endpoint
|
||||
* zero)
|
||||
* - if this value is zero, this interface only uses the Default
|
||||
* Control Pipe
|
||||
*/
|
||||
|
||||
uint8_t bInterfaceClass;
|
||||
/* value: class
|
||||
* - class code (assigned by the USB-IF)
|
||||
* - 0x00 => reserved for future standardization
|
||||
* - 0xFF => interface class is vendor specific
|
||||
* - [others] => reserved for assignment by the USB-IF
|
||||
*/
|
||||
|
||||
uint8_t bInterfaceSubClass;
|
||||
/* value: subclass
|
||||
* - subclass code (assigned by the USB-IF)
|
||||
* - qualified by the value of the bInterfaceClass field
|
||||
* - if the bInterfaceClass field is reset to zero, this field must be
|
||||
* also
|
||||
* - if the bInterfaceClass field is not set to 0xFF, all values are
|
||||
* reserved for assignment by the USB-IF
|
||||
*/
|
||||
|
||||
uint8_t bInterfaceProtocol;
|
||||
/* value: protocol
|
||||
* - protocol code (assigned by the USB)
|
||||
* - qualified by the values of the bInterfaceClass and
|
||||
* bInterfaceSubClass fields
|
||||
* - if an interface supports class-specific requests, this code
|
||||
* identifies the protocols that the device uses as defined by the
|
||||
* specification of the device class.
|
||||
* - 0x00 => the device does not use a class-specific protocol on this
|
||||
* interface
|
||||
* - 0xFF => the device uses a vendor-specific protocol for this
|
||||
* interface
|
||||
*/
|
||||
|
||||
uint8_t iInterface;
|
||||
/* value: index
|
||||
* - index of string descriptor describing this interface
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* - spec sec 9.6.6 (Standard USB Descriptor Definitions / Endpoint)
|
||||
* - table 9-13 (Standard Endpoint Descriptor)
|
||||
*
|
||||
* - a feedback endpoint (explicit or implicit) needs to be associated with one
|
||||
* (or more) isochronous data endpoints to which it provides feedback
|
||||
* service. the association is based on endpoint number matching. a
|
||||
* feedback endpoint always has the opposite direction from the data
|
||||
* endpoint(s) it services. if multiple data endpoints are to be serviced by
|
||||
* the same feedback endpoint, the data endpoints must have ascending ordered
|
||||
* (but not necessarily consecutive) endpoint numbers. the first data
|
||||
* endpoint and the feedback endpoint must have the same endpoint number (and
|
||||
* opposite direction). this ensures that a data endpoint can uniquely
|
||||
* identify its feedback endpoint by searching for the first feedback
|
||||
* endpoint that has an endpoint number equal or less than its own endpoint
|
||||
* number.
|
||||
* - see spec figures 9-7 and 9-8
|
||||
*/
|
||||
struct usb_endpoint_descriptor {
|
||||
uint8_t bLength;
|
||||
/* value: number
|
||||
* - size of this descriptor in bytes
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorType;
|
||||
/* value: constant
|
||||
* - ENDPOINT Descriptor Type
|
||||
*/
|
||||
|
||||
uint8_t bEndpointAddress;
|
||||
/* value: endpoint
|
||||
* - the address and direction of the endpoint described
|
||||
* (see macro below)
|
||||
*/
|
||||
|
||||
uint8_t bmAttributes;
|
||||
/* value: bitmap
|
||||
* - endpoint's attributes when it is configured using the
|
||||
* bConfigurationValue
|
||||
* - includes: transfer type
|
||||
* - if transfer type == isochronous, also includes:
|
||||
* synchronization type, usage type
|
||||
* - (see spec chapter 5 for more information)
|
||||
* - (see macros below)
|
||||
*/
|
||||
|
||||
uint16_t wMaxPacketSize;
|
||||
/* value: number
|
||||
* - max packet size this endpoint is capable of sending or receiving
|
||||
* when this configuration is selected
|
||||
* - for isochronous endpoints, this value is used to reserve the bus
|
||||
* time in the schedule, required for the per-(micro)frame data
|
||||
* payloads. the pipe may, on an ongoing basis, actually use less
|
||||
* bandwidth than reserved. the device reports, if necessary, the
|
||||
* actual bandwidth used via its normal, non-USB defined mechanisms
|
||||
* - (see spec chapter 5 for more information)
|
||||
* - (see macro below)
|
||||
*/
|
||||
|
||||
uint8_t bInterval;
|
||||
/* value: number
|
||||
* - interval for polling endpoint for data transfers
|
||||
* - expressed in frames or microframes, depending on the device
|
||||
* operating speed (i.e. either 1 ms or 125 μs units)
|
||||
* - for (full|high)-speed isochronous endpoints and high-speed
|
||||
* interrupt endpoints, this value must be between 1..16 . this
|
||||
* value is used as the exponent for a 2^(bInterval-1) value (e.g. a
|
||||
* bInterval of 4 => a period of 8 == 2^(4-1))
|
||||
* - for (full|low)-speed interrupt endpoints, this value may be
|
||||
* between 1..255
|
||||
* - for high-speed bulk/control OUT endpoints, this value must specify
|
||||
* the max NAK rate of the endpoint. a value of 0 => the endpoint
|
||||
* never NAKs. other values indicate at most 1 NAK each bInterval
|
||||
* number of microframes. this value must be between 0..255
|
||||
* - for high-speed bulk and control OUT endpoints, this field is only
|
||||
* used for compliance purposes (the host controller is not required
|
||||
* to change its behavior based on the value in this field)
|
||||
* - (see spec chapter 5 description of periods for more detail)
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
/* - spec sec 9.6.6 (Standard USB Descriptor Definitions / Endpoint)
|
||||
* - table 9-13 (Standard Endpoint Descriptor)
|
||||
* - bEndpointAddress
|
||||
*
|
||||
* .-------------------------------------------------------.
|
||||
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||||
* |-------------------------------------------------------|
|
||||
* | direction | reserved (reset to 0) | endpoint number |
|
||||
* '-------------------------------------------------------'
|
||||
*
|
||||
* - D7: 0 => OUT endpoint
|
||||
* 1 => IN endpoint
|
||||
* - ignored for control endpoints
|
||||
*/
|
||||
#define usb_endpoint_bEndpointAddress(direction, endpoint_number) \
|
||||
( (uint8_t) ((direction)<<7) | (endpoint_number) )
|
||||
|
||||
|
||||
/* - spec sec 9.6.6 (Standard USB Descriptor Definitions / Endpoint)
|
||||
* - table 9-13 (Standard Endpoint Descriptor)
|
||||
* - bmAttributes
|
||||
*
|
||||
* .------------------------------------------------------------------------.
|
||||
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||||
* |------------------------------------------------------------------------|
|
||||
* | reserved | usage type | synchronization type | transfer type |
|
||||
* | (reset to 0) | (if isochronous) | (if isochronous) | |
|
||||
* | |(else reset to 0) | (else reset to 0) | |
|
||||
* '------------------------------------------------------------------------'
|
||||
*
|
||||
* - transfer type: 0b00 => control
|
||||
* 0b01 => isochronous
|
||||
* 0b10 => bulk
|
||||
* 0b11 => interrupt
|
||||
*
|
||||
* - synchronization type: 0b00 => no synchronization
|
||||
* 0b01 => asynchronous
|
||||
* 0b10 => adaptive
|
||||
* 0b11 => synchronous
|
||||
* - if transfer type != isochronous, field is reset to 0
|
||||
*
|
||||
* - usage type: 0b00 => data endpoint
|
||||
* 0b01 => feedback endpoint
|
||||
* 0b10 => implicit feedback data endpoint
|
||||
* 0b11 => reserved
|
||||
* - if transfer type != isochronous, field is reset to 0
|
||||
*
|
||||
* - if usage type == feedback endpoint, then transfer type must be isochronous
|
||||
* and synchronization type must be no synchronization
|
||||
*/
|
||||
#define usb_endpoint_bmAttributes(transfer_type) \
|
||||
( (uint8_t) (transfer_type) )
|
||||
#define usb_endpoint_bmAttributes_isochronous( \
|
||||
synchronization_type, usage_type ) \
|
||||
( (uint8_t) (0b01 | ((synchronization_type)<<2) | ((usage_type)<<4)) )
|
||||
|
||||
|
||||
/* - spec sec 9.6.6 (Standard USB Descriptor Definitions / Endpoint)
|
||||
* - table 9-13 (Standard Endpoint Descriptor)
|
||||
* - wMaxPacketSize
|
||||
*
|
||||
* .-----------------------------------------------------------------.
|
||||
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||||
* |-----------------------------------------------------------------|
|
||||
* | max packet size |
|
||||
* | (D10..D0) |
|
||||
* | |
|
||||
* >---------------------------------------------------------------<
|
||||
* | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 |
|
||||
* |-----------------------------------------------------------------|
|
||||
* | reserved | number of additional | max packet size |
|
||||
* | (reset to 0) | transaction opportunities | (D10..D0) |
|
||||
* | | per microframe | (continued) |
|
||||
* | | (for high-speed isochronous | |
|
||||
* | | and interrupt endpoints) | |
|
||||
* '-----------------------------------------------------------------'
|
||||
*
|
||||
* - D12..D11 (additional transaction opportunities for each microframe
|
||||
* specified by bInterval):
|
||||
* 0b00 => none (1 transaction per microframe)
|
||||
* => max packet size: 1..1024
|
||||
* 0b01 => 1 additional (2 per microframe)
|
||||
* => max packet size: 513..1024
|
||||
* 0b10 => 2 additional (3 per microframe)
|
||||
* => max packet size: 683..1024
|
||||
* 0b11 => reserved
|
||||
* - for high-speed isochronous and interrupt endpoints only. else reset to
|
||||
* 0, and max packet size can be any allowed value (as defined in spec
|
||||
* chapter 5)
|
||||
*/
|
||||
#define usb_endpoint_wMaxPacketSize(adtl_trans_ops, max_packet_size) \
|
||||
( (uint16_t) (((adtl_trans_ops)<<11) | max_packet_size) )
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* - spec sec 9.6.7 (Standard USB Descriptor Definitions / String)
|
||||
* - table 9-15 (String Descriptor Zero, Specifying Languages Supported by
|
||||
* the Device)
|
||||
*
|
||||
* - string descriptors are optional. if a device does not support them, all
|
||||
* references to them within all descriptors must be reset to 0 .
|
||||
*
|
||||
* - string descriptors use unicode encodings (as defined in version 3.0 of the
|
||||
* unicode standard)
|
||||
*
|
||||
* - the strings may support multiple languages. when requesting a string
|
||||
* descriptor, the requester specifies the desired language using a 16 bit
|
||||
* language ID (LANGID) (defined by the USB-IF; see
|
||||
* <http://www.usb.org/developers/docs.html>).
|
||||
*
|
||||
* - string index 0 for all languages returns a string descriptor that contains
|
||||
* an array of two-byte LANGID codes supported by the device. USB devices
|
||||
* that omit all string descriptors must not return an array of LANGID codes.
|
||||
*/
|
||||
struct usb_string_descriptor_zero {
|
||||
uint8_t bLength;
|
||||
/* value: N+2
|
||||
* - the size of this descriptor in bytes (which equals the size of the
|
||||
* array of LANGIDs (in bytes) plus two)
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorType;
|
||||
/* value: constant
|
||||
* - STRING Descriptor Type
|
||||
*/
|
||||
|
||||
uint16_t (* wLANGID_ptr)[];
|
||||
/* value: a pointer to the array of supported LANGID codes
|
||||
* - note: these must be transmitted as part of the descriptor; a
|
||||
* pointer is used here to avoid using variable length struct members
|
||||
* + malloc()
|
||||
*/
|
||||
};
|
||||
|
||||
/* - spec sec 9.6.7 (Standard USB Descriptor Definitions / String)
|
||||
* - table 9-16 (UNICODE String Descriptor)
|
||||
*/
|
||||
struct usb_string_descriptor {
|
||||
uint8_t bLength;
|
||||
/* value: number
|
||||
* - the size of this descriptor in bytes (which equals the size of the
|
||||
* string (in bytes) plus two)
|
||||
*/
|
||||
|
||||
uint8_t bDescriptorType;
|
||||
/* value: constant
|
||||
* - STRING Descriptor Type
|
||||
*/
|
||||
|
||||
uint8_t bString;
|
||||
/* value: number
|
||||
* - UNICODE encoded string
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* USB Keyboard Key Codes : short names
|
||||
*
|
||||
* These are for convenience (and to help with formatting, keeping stuff from
|
||||
* getting too long). See "keyboard-usage-page.h" for definitions and
|
||||
* everything.
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef USB_USAGE_PAGE_KEYBOARD_SHORT_NAMES_h
|
||||
#define USB_USAGE_PAGE_KEYBOARD_SHORT_NAMES_h
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "keyboard.h"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// protocol
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// error
|
||||
#define _ErrRollover KEY_ErrorRollOver
|
||||
#define _PostFail KEY_POSTFail
|
||||
#define _ErrUndef KEY_ErrorUndefined
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// main keyboard
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// letters
|
||||
#define _A KEY_a_A
|
||||
#define _B KEY_b_B
|
||||
#define _C KEY_c_C
|
||||
#define _D KEY_d_D
|
||||
#define _E KEY_e_E
|
||||
#define _F KEY_f_F
|
||||
#define _G KEY_g_G
|
||||
#define _H KEY_h_H
|
||||
#define _I KEY_i_I
|
||||
#define _J KEY_j_J
|
||||
#define _K KEY_k_K
|
||||
#define _L KEY_l_L
|
||||
#define _M KEY_m_M
|
||||
#define _N KEY_n_N
|
||||
#define _O KEY_o_O
|
||||
#define _P KEY_p_P
|
||||
#define _Q KEY_q_Q
|
||||
#define _R KEY_r_R
|
||||
#define _S KEY_s_S
|
||||
#define _T KEY_t_T
|
||||
#define _U KEY_u_U
|
||||
#define _V KEY_v_V
|
||||
#define _W KEY_w_W
|
||||
#define _X KEY_x_X
|
||||
#define _Y KEY_y_Y
|
||||
#define _Z KEY_z_Z
|
||||
|
||||
// numbers
|
||||
#define _0 KEY_0_RightParenthesis
|
||||
#define _1 KEY_1_Exclamation
|
||||
#define _2 KEY_2_At
|
||||
#define _3 KEY_3_Pound
|
||||
#define _4 KEY_4_Dollar
|
||||
#define _5 KEY_5_Percent
|
||||
#define _6 KEY_6_Caret
|
||||
#define _7 KEY_7_Ampersand
|
||||
#define _8 KEY_8_Asterisk
|
||||
#define _9 KEY_9_LeftParenthesis
|
||||
|
||||
// function
|
||||
#define _F1 KEY_F1
|
||||
#define _F2 KEY_F2
|
||||
#define _F3 KEY_F3
|
||||
#define _F4 KEY_F4
|
||||
#define _F5 KEY_F5
|
||||
#define _F6 KEY_F6
|
||||
#define _F7 KEY_F7
|
||||
#define _F8 KEY_F8
|
||||
#define _F9 KEY_F9
|
||||
#define _F10 KEY_F10
|
||||
#define _F11 KEY_F11
|
||||
#define _F12 KEY_F12
|
||||
#define _F13 KEY_F13
|
||||
#define _F14 KEY_F14
|
||||
#define _F15 KEY_F15
|
||||
#define _F16 KEY_F16
|
||||
#define _F17 KEY_F17
|
||||
#define _F18 KEY_F18
|
||||
#define _F19 KEY_F19
|
||||
#define _F20 KEY_F20
|
||||
#define _F21 KEY_F21
|
||||
#define _F22 KEY_F22
|
||||
#define _F23 KEY_F23
|
||||
#define _F24 KEY_F24
|
||||
|
||||
// whitespace and symbols
|
||||
#define _enter KEY_ReturnEnter
|
||||
#define _space KEY_Spacebar
|
||||
#define _tab KEY_Tab
|
||||
// ---
|
||||
#define _backslash KEY_Backslash_Pipe
|
||||
#define _bracketL KEY_LeftBracket_LeftBrace
|
||||
#define _bracketR KEY_RightBracket_RightBrace
|
||||
#define _comma KEY_Comma_LessThan
|
||||
#define _dash KEY_Dash_Underscore
|
||||
#define _equal KEY_Equal_Plus
|
||||
#define _grave KEY_GraveAccent_Tilde
|
||||
#define _period KEY_Period_GreaterThan
|
||||
#define _quote KEY_SingleQuote_DoubleQuote
|
||||
#define _semicolon KEY_Semicolon_Colon
|
||||
#define _slash KEY_Slash_Question
|
||||
// ---
|
||||
#define _sep_dec KEY_DecimalSeparator
|
||||
#define _sep_thousands KEY_ThousandsSeparator
|
||||
#define _currencyUnit KEY_CurrencyUnit
|
||||
#define _currencySubunit KEY_CurrencySubunit
|
||||
|
||||
// international and language
|
||||
#define _int1 KEY_International1
|
||||
#define _int2 KEY_International2
|
||||
#define _int3 KEY_International3
|
||||
#define _int4 KEY_International4
|
||||
#define _int5 KEY_International5
|
||||
#define _int6 KEY_International6
|
||||
#define _int7 KEY_International7
|
||||
#define _int8 KEY_International8
|
||||
#define _int9 KEY_International9
|
||||
// ---
|
||||
#define _lang1 KEY_LANG1
|
||||
#define _lang2 KEY_LANG2
|
||||
#define _lang3 KEY_LANG3
|
||||
#define _lang4 KEY_LANG4
|
||||
#define _lang5 KEY_LANG5
|
||||
#define _lang6 KEY_LANG6
|
||||
#define _lang7 KEY_LANG7
|
||||
#define _lang8 KEY_LANG8
|
||||
#define _lang9 KEY_LANG9
|
||||
// ---
|
||||
#define _backslash_nonUS KEY_NonUS_Backslash_Pipe
|
||||
#define _pound_nonUS KEY_NonUS_Pound_Tilde
|
||||
|
||||
// text control
|
||||
#define _bs KEY_DeleteBackspace
|
||||
#define _del KEY_DeleteForward
|
||||
#define _home KEY_Home
|
||||
#define _end KEY_End
|
||||
#define _pageU KEY_PageUp
|
||||
#define _pageD KEY_PageDown
|
||||
#define _arrowU KEY_UpArrow
|
||||
#define _arrowD KEY_DownArrow
|
||||
#define _arrowL KEY_LeftArrow
|
||||
#define _arrowR KEY_RightArrow
|
||||
#define _esc KEY_Escape
|
||||
#define _insert KEY_Insert
|
||||
|
||||
// modifier
|
||||
#define _altL KEY_LeftAlt
|
||||
#define _altR KEY_RightAlt
|
||||
#define _ctrlL KEY_LeftControl
|
||||
#define _ctrlR KEY_RightControl
|
||||
#define _guiL KEY_LeftGUI
|
||||
#define _guiR KEY_RightGUI
|
||||
#define _shiftL KEY_LeftShift
|
||||
#define _shiftR KEY_RightShift
|
||||
|
||||
// lock
|
||||
#define _capsLock KEY_CapsLock
|
||||
#define _scrollLock KEY_ScrollLock
|
||||
// (numlock is under keypad)
|
||||
// --- not generally used
|
||||
#define _capsLock_locking KEY_LockingCapsLock
|
||||
#define _numLock_locking KEY_LockingNumLock
|
||||
#define _scrollLock_locking KEY_LockingScrollLock
|
||||
|
||||
// special function
|
||||
#define _pause KEY_Pause
|
||||
#define _print KEY_PrintScreen
|
||||
// ---
|
||||
#define _application KEY_Application
|
||||
#define _execute KEY_Execute
|
||||
#define _power KEY_Power
|
||||
// ---
|
||||
#define _help KEY_Help
|
||||
#define _menu KEY_Menu
|
||||
// ---
|
||||
#define _cut KEY_Cut
|
||||
#define _copy KEY_Copy
|
||||
#define _paste KEY_Paste
|
||||
#define _find KEY_Find
|
||||
#define _select KEY_Select
|
||||
#define _stop KEY_Stop
|
||||
#define _undo KEY_Undo
|
||||
// ---
|
||||
#define _mute KEY_Mute
|
||||
#define _volumeU KEY_VolumeUp
|
||||
#define _volumeD KEY_VolumeDown
|
||||
// ---
|
||||
#define _altErase KEY_AlternateErase
|
||||
// ---
|
||||
#define _again KEY_Again
|
||||
#define _cancel KEY_Cancel
|
||||
#define _clear_again KEY_Clear_Again
|
||||
#define _clear KEY_Clear
|
||||
#define _oper KEY_Oper
|
||||
#define _out KEY_Out
|
||||
#define _prior KEY_Prior
|
||||
#define _return KEY_Return
|
||||
#define _separator KEY_Separator
|
||||
// ---
|
||||
#define _crSel KEY_CrSel_Props
|
||||
#define _exSel KEY_ExSel
|
||||
#define _sysReq KEY_SysReq_Attention
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// keypad
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// numbers and hex letters
|
||||
#define _1_kp KEYPAD_1_End
|
||||
#define _2_kp KEYPAD_2_DownArrow
|
||||
#define _3_kp KEYPAD_3_PageDown
|
||||
#define _4_kp KEYPAD_4_LeftArrow
|
||||
#define _5_kp KEYPAD_5
|
||||
#define _6_kp KEYPAD_6_RightArrow
|
||||
#define _7_kp KEYPAD_7_Home
|
||||
#define _8_kp KEYPAD_8_UpArrow
|
||||
#define _9_kp KEYPAD_9_PageUp
|
||||
#define _0_kp KEYPAD_0_Insert
|
||||
#define _A_kp KEYPAD_A
|
||||
#define _B_kp KEYPAD_B
|
||||
#define _C_kp KEYPAD_C
|
||||
#define _D_kp KEYPAD_D
|
||||
#define _E_kp KEYPAD_E
|
||||
#define _F_kp KEYPAD_F
|
||||
// ---
|
||||
#define _00_kp KEYPAD_00
|
||||
#define _000_kp KEYPAD_000
|
||||
|
||||
// whitespace and symbols
|
||||
#define _tab_kp KEYPAD_Tab
|
||||
#define _space_kp KEYPAD_Space
|
||||
#define _enter_kp KEYPAD_ENTER
|
||||
// ---
|
||||
#define _dec_del_kp KEYPAD_Period_Delete
|
||||
#define _comma_kp KEYPAD_Comma
|
||||
#define _equal_kp KEYPAD_Equal
|
||||
#define _equalSign_kp KEYPAD_EqualSign
|
||||
#define _parenL_kp KEYPAD_LeftParenthesis
|
||||
#define _parenR_kp KEYPAD_RightParenthesis
|
||||
#define _braceL_kp KEYPAD_LeftBrace
|
||||
#define _braceR_kp KEYPAD_RightBrace
|
||||
|
||||
// operations
|
||||
// --- basic
|
||||
#define _add_kp KEYPAD_Plus
|
||||
#define _sub_kp KEYPAD_Minus
|
||||
#define _mul_kp KEYPAD_Asterisk
|
||||
#define _div_kp KEYPAD_Slash
|
||||
#define _plusMinus_kp KEYPAD_PlusMinus
|
||||
// --- logical
|
||||
#define _lt_kp KEYPAD_LessThan
|
||||
#define _gt_kp KEYPAD_GreaterThan
|
||||
#define _xor_kp KEYPAD_XOR
|
||||
#define _and_kp KEYPAD_Ampersand
|
||||
#define _andand_kp KEYPAD_AmpersandAmpersand
|
||||
#define _pipe_kp KEYPAD_Pipe
|
||||
#define _pipepipe_kp KEYPAD_PipePipe
|
||||
#define _caret_kp KEYPAD_Caret
|
||||
#define _exclamation_kp KEYPAD_Exclamation
|
||||
// --- other
|
||||
#define _at_kp KEYPAD_At
|
||||
#define _colon_kp KEYPAD_Colon
|
||||
#define _percent_kp KEYPAD_Percent
|
||||
#define _pound_kp KEYPAD_Pound
|
||||
|
||||
// radix
|
||||
#define _bin_kp KEYPAD_Binary
|
||||
#define _oct_kp KEYPAD_Octal
|
||||
#define _dec_kp KEYPAD_Decimal
|
||||
#define _hex_kp KEYPAD_Hexadecimal
|
||||
|
||||
// text control
|
||||
#define _bs_kp KEYPAD_Backspace
|
||||
#define _clear_kp KEYPAD_Clear
|
||||
#define _clearEntry_kp KEYPAD_ClearEntry
|
||||
|
||||
// lock
|
||||
#define _numLock_kp KEYPAD_NumLock_Clear
|
||||
|
||||
// memory control
|
||||
#define _memStore_kp KEYPAD_MemoryStore
|
||||
#define _memRecall_kp KEYPAD_MemoryRecall
|
||||
#define _memClear_kp KEYPAD_MemoryClear
|
||||
#define _memAdd_kp KEYPAD_MemoryAdd
|
||||
#define _memSub_kp KEYPAD_MemorySubtract
|
||||
#define _memMul_kp KEYPAD_MemoryMultiply
|
||||
#define _memDiv_kp KEYPAD_MemoryDivide
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif
|
||||
|
|
@ -21,6 +21,12 @@
|
|||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef USB_USAGE_PAGE_KEYBOARD_h
|
||||
#define USB_USAGE_PAGE_KEYBOARD_h
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Name ID // PC Mac Unix Boot Keyboard Req.
|
||||
// --------------------------- ---- -- --- ---- ---------------------
|
||||
|
||||
|
@ -241,7 +247,7 @@
|
|||
#define KEYPAD_MemorySubtract 0xD4 // - - - -
|
||||
#define KEYPAD_MemoryMultiply 0xD5 // - - - -
|
||||
#define KEYPAD_MemoryDivide 0xD6 // - - - -
|
||||
#define KEYPAD_PlusMinux 0xD7 // - - - -
|
||||
#define KEYPAD_PlusMinus 0xD7 // - - - -
|
||||
#define KEYPAD_Clear 0xD8 // - - - -
|
||||
#define KEYPAD_ClearEntry 0xD9 // - - - -
|
||||
#define KEYPAD_Binary 0xDA // - - - -
|
||||
|
@ -262,3 +268,8 @@
|
|||
|
||||
// (Reserved) 0xE8..0xFFFF // - - - -
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif
|
||||
|
|
@ -20,6 +20,12 @@
|
|||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef USB_USAGE_PAGE_LED_h
|
||||
#define USB_USAGE_PAGE_LED_h
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Name ID Usage Type Section of HID Tables
|
||||
// --------------------------- ---- ---------- ----------------------
|
||||
|
||||
|
@ -104,3 +110,9 @@
|
|||
#define LED_ExternalPowerConnected 0x4D // OOC 11.6
|
||||
|
||||
// (Reserved) 0x4E..0xFFFF // - -
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif
|
||||
|
58
src/main.c
58
src/main.c
|
@ -9,37 +9,22 @@
|
|||
|
||||
|
||||
#include <util/delay.h>
|
||||
|
||||
#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
||||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
|
||||
|
||||
// note:
|
||||
// - see your keyswitch specification for the necessary value. for cherry mx
|
||||
// switches, bounce time should be <= 5ms. it looks like most switches are
|
||||
// speced between 5 and 8ms.
|
||||
// - if timing is important, balance this value with the main() loop run time
|
||||
// (~5ms, last i checked, nearly all of it in the i2c update() function)
|
||||
#define DEBOUNCE_TIME 5 // in ms
|
||||
|
||||
|
||||
int main(void) {
|
||||
kb_init(); // does controller initialization too
|
||||
|
||||
KB_LED1_ON;
|
||||
KB_LED2_ON;
|
||||
KB_LED3_ON;
|
||||
kb_led_state_power_on();
|
||||
|
||||
usb_init();
|
||||
while (!usb_configured());
|
||||
_delay_ms(1000); // make sure the OS has had time to load drivers, etc.
|
||||
kb_led_delay_usb_init(); // give the OS time to load drivers, etc.
|
||||
|
||||
KB_LED1_OFF;
|
||||
KB_LED2_OFF;
|
||||
KB_LED3_OFF;
|
||||
kb_led_state_ready();
|
||||
|
||||
for (;;) {
|
||||
static uint8_t current_layer = 0;
|
||||
|
@ -51,12 +36,12 @@ int main(void) {
|
|||
|
||||
kb_update_matrix(*kb_is_pressed);
|
||||
|
||||
// call the appropriate function for each key, then send the report if
|
||||
// necessary
|
||||
// call the appropriate function for each key, then send the usb report
|
||||
// if necessary
|
||||
// - everything else is the key function's responsibility; see the
|
||||
// keyboard layout file ("keyboard/ergodox/layout.c") for which key
|
||||
// is assigned which function (per layer), and "key-functions.c" for
|
||||
// their definitions
|
||||
// keyboard layout file ("keyboard/ergodox/layout/*.c") for which key
|
||||
// is assigned which function (per layer), and "lib/key-functions.c"
|
||||
// for their definitions
|
||||
for (uint8_t row=0; row<KB_ROWS; row++) {
|
||||
for (uint8_t col=0; col<KB_COLUMNS; col++) {
|
||||
bool is_pressed = (*kb_is_pressed)[row][col];
|
||||
|
@ -64,36 +49,39 @@ int main(void) {
|
|||
if (is_pressed != was_pressed) {
|
||||
if (is_pressed) {
|
||||
kbfun_funptr_t press_function =
|
||||
kb_layout_press[current_layer][row][col];
|
||||
kb_layout_press_get(current_layer, row, col);
|
||||
if (press_function) {
|
||||
(*press_function)(
|
||||
&kb_layout[current_layer][row][col],
|
||||
kb_layout_get(current_layer, row, col),
|
||||
¤t_layer, &row, &col );
|
||||
}
|
||||
} else {
|
||||
kbfun_funptr_t release_function =
|
||||
kb_layout_release[current_layer][row][col];
|
||||
kb_layout_release_get(current_layer, row, col);
|
||||
if (release_function) {
|
||||
(*release_function)(
|
||||
&kb_layout[current_layer][row][col],
|
||||
kb_layout_get(current_layer, row, col),
|
||||
¤t_layer, &row, &col );
|
||||
}
|
||||
}
|
||||
|
||||
usb_keyboard_send();
|
||||
_delay_ms(DEBOUNCE_TIME);
|
||||
_delay_ms(KB_DEBOUNCE_TIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update LEDs
|
||||
(keyboard_leds & (1<<0)) ? KB_LED1_ON : KB_LED1_OFF; // num lock
|
||||
(keyboard_leds & (1<<1)) ? KB_LED2_ON : KB_LED2_OFF; // caps lock
|
||||
(keyboard_leds & (1<<2)) ? KB_LED3_ON : KB_LED3_OFF; // scroll lock
|
||||
#if 0 // not implemented right now
|
||||
(keyboard_leds & (1<<3)) ? KB_LED4_ON : KB_LED4_OFF; // compose
|
||||
(keyboard_leds & (1<<4)) ? KB_LED5_ON : KB_LED5_OFF; // kana
|
||||
#endif
|
||||
if (keyboard_leds & (1<<0)) { kb_led_num_on(); }
|
||||
else { kb_led_num_off(); }
|
||||
if (keyboard_leds & (1<<1)) { kb_led_caps_on(); }
|
||||
else { kb_led_caps_off(); }
|
||||
if (keyboard_leds & (1<<2)) { kb_led_scroll_on(); }
|
||||
else { kb_led_scroll_off(); }
|
||||
if (keyboard_leds & (1<<3)) { kb_led_compose_on(); }
|
||||
else { kb_led_compose_off(); }
|
||||
if (keyboard_leds & (1<<4)) { kb_led_kana_on(); }
|
||||
else { kb_led_kana_off(); }
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
165
src/makefile
165
src/makefile
|
@ -1,6 +1,11 @@
|
|||
# -----------------------------------------------------------------------------
|
||||
# This is mostly a stub at the moment, but I'm keeping it separate so I can
|
||||
# mess with it later without changing the original
|
||||
# makefile for the ergoDOX project
|
||||
#
|
||||
# - .h file dependencies are automatically generated
|
||||
#
|
||||
# - This makefile was originally (extensively) modified from the WinAVR
|
||||
# makefile template, mostly by removing stuff. The copy I used was from
|
||||
# [pjrc : usb_keyboard] (http://pjrc.com/teensy/usb_keyboard.zip).
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
# Released under The MIT License (MIT) (see "license.md")
|
||||
|
@ -8,33 +13,149 @@
|
|||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
TARGET = firmware
|
||||
TARGET = firmware # the name we want for our program binary
|
||||
FORMAT = ihex # the program binary's format
|
||||
KEYBOARD = ergodox # keyboard model; see "src/keyboard" for what's available
|
||||
LAYOUT = qwerty # keyboard layout; see "src/keyboard/*/layout" for what's
|
||||
# available
|
||||
|
||||
SRC = $(wildcard *.c) \
|
||||
$(wildcard keyboard/*.c) \
|
||||
$(wildcard keyboard/*/*.c) \
|
||||
$(wildcard lib/*.c) \
|
||||
$(wildcard lib/*/*.c) \
|
||||
'./lib-other/pjrc/usb_keyboard/usb_keyboard.c'
|
||||
MCU = atmega32u4 # processor type (for teensy 2.0); must match real life
|
||||
BOARD = teensy-2-0 # see the libraries you're using for what's available
|
||||
F_CPU = 16000000 # processor speed, in Hz
|
||||
|
||||
# firmware stuff
|
||||
SRC = $(wildcard *.c)
|
||||
# keyboard and layout stuff
|
||||
# --- remove whitespace from vars
|
||||
KEYBOARD := $(strip $(KEYBOARD))
|
||||
LAYOUT := $(strip $(LAYOUT))
|
||||
# --- include stuff
|
||||
SRC += $(wildcard keyboard/$(KEYBOARD)*.c)
|
||||
SRC += $(wildcard keyboard/$(KEYBOARD)/*.c)
|
||||
SRC += $(wildcard keyboard/$(KEYBOARD)/layout/$(LAYOUT)*.c)
|
||||
# library stuff
|
||||
# - add more "*/*/..."s as necessary to compile everything.
|
||||
# - parts of the stuff under "lib" may not be necessary, depending on other
|
||||
# options, but it's all included here. hopefully any unnecessary stuff gets
|
||||
# compiled out. else, the makefile will have to become more complicated.
|
||||
SRC += $(wildcard lib/*.c)
|
||||
SRC += $(wildcard lib/*/*.c)
|
||||
SRC += $(wildcard lib/*/*/*.c)
|
||||
SRC += $(wildcard lib-other/*.c)
|
||||
SRC += $(wildcard lib-other/*/*.c)
|
||||
SRC += $(wildcard lib-other/*/*/*.c)
|
||||
|
||||
OBJ = $(SRC:%.c=%.o)
|
||||
|
||||
|
||||
EXTRAINCDIRS = .
|
||||
|
||||
TEENSY_MAKE = $(MAKE) -f 'lib-other/pjrc/usb_keyboard/Makefile' \
|
||||
TARGET='$(TARGET)' \
|
||||
SRC='$(SRC)' \
|
||||
EXTRAINCDIRS='$(EXTRAINCDIRS)'
|
||||
CFLAGS = -mmcu=$(MCU) # processor type (teensy 2.0); must match real
|
||||
# life
|
||||
CFLAGS += -DF_CPU=$(F_CPU) # processor frequency; must match initialization
|
||||
# in source
|
||||
CFLAGS += -I. # search for includes in the current directory
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
CFLAGS += -DMAKEFILE_BOARD='$(strip $(BOARD))'
|
||||
CFLAGS += -DMAKEFILE_KEYBOARD='$(strip $(KEYBOARD))'
|
||||
CFLAGS += -DMAKEFILE_KEYBOARD_LAYOUT='$(strip $(LAYOUT))'
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
CFLAGS += -std=gnu99 # use C99 plus GCC extensions
|
||||
CFLAGS += -Os # optimize for size
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
CFLAGS += -Wall # enable lots of common warnings
|
||||
CFLAGS += -Wstrict-prototypes # "warn if a function is declared or defined
|
||||
# without specifying the argument types"
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
CFLAGS += -fpack-struct # "pack all structure members together without holes"
|
||||
CFLAGS += -fshort-enums # "allocate to an 'enum' type only as many bytes as it
|
||||
# needs for the declared range of possible values"
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
CFLAGS += -ffunction-sections # \ "place each function or data into its own
|
||||
CFLAGS += -fdata-sections # / section in the output file if the
|
||||
# target supports arbitrary sections." for
|
||||
# linker optimizations, and discarding
|
||||
# unused code.
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
LDFLAGS = -Wl,--relax # for some linker optimizations
|
||||
LDFLAGS += -Wl,--gc-sections # discard unused functions and data
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
GENDEPFLAGS += -MMD -MP -MF $@.dep # generate dependency files
|
||||
|
||||
|
||||
.PHONY: all clean debug
|
||||
CC = avr-gcc
|
||||
OBJCOPY = avr-objcopy
|
||||
SIZE = avr-size
|
||||
|
||||
all:
|
||||
$(TEENSY_MAKE) all
|
||||
|
||||
# remove whitespace from some of the variables
|
||||
TARGET := $(strip $(TARGET))
|
||||
FORMAT := $(strip $(FORMAT))
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(TARGET).hex $(TARGET).eep
|
||||
@echo
|
||||
@echo '---------------------------------------------------------------'
|
||||
@echo '------- done --------------------------------------------------'
|
||||
@echo
|
||||
$(SIZE) --target=$(FORMAT) $(TARGET).hex
|
||||
@echo
|
||||
$(SIZE) --target=$(FORMAT) $(TARGET).eep
|
||||
@echo
|
||||
@echo '. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .'
|
||||
@echo
|
||||
$(SIZE) -C --mcu=atmega32u4 $(TARGET).elf
|
||||
@echo '. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .'
|
||||
@echo
|
||||
@echo 'you can load "$(TARGET).hex" and "$(TARGET).eep" onto the'
|
||||
@echo 'Teensy using the Teensy loader'
|
||||
@echo
|
||||
@echo '---------------------------------------------------------------'
|
||||
@echo
|
||||
|
||||
clean:
|
||||
$(TEENSY_MAKE) clean
|
||||
git clean -X
|
||||
@echo
|
||||
@echo --- cleaning ---
|
||||
cd .. ; git clean -dX # remove ignored files and directories
|
||||
|
||||
debug:
|
||||
$(TEENSY_MAKE) debug
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
.SECONDARY:
|
||||
|
||||
%.hex: %.elf
|
||||
@echo
|
||||
@echo --- making $@ ---
|
||||
# from the WinAVR makefile template (modified)
|
||||
$(OBJCOPY) -O $(FORMAT) \
|
||||
-R .eeprom -R .fuse -R .lock -R .signature \
|
||||
$< $@
|
||||
|
||||
%.eep: %.elf
|
||||
@echo
|
||||
@echo --- making $@ ---
|
||||
# from the WinAVR makefile template (modified)
|
||||
-$(OBJCOPY) -O $(FORMAT) \
|
||||
-j .eeprom \
|
||||
--set-section-flags=.eeprom="alloc,load" \
|
||||
--change-section-lma .eeprom=0 \
|
||||
--no-change-warnings \
|
||||
$< $@ || exit 0
|
||||
|
||||
%.elf: $(OBJ)
|
||||
@echo
|
||||
@echo --- making $@ ---
|
||||
$(CC) $(strip $(CFLAGS)) $(strip $(LDFLAGS)) $^ --output $@
|
||||
|
||||
%.o: %.c
|
||||
@echo
|
||||
@echo --- making $@ ---
|
||||
$(CC) -c $(strip $(CFLAGS)) $(strip $(GENDEPFLAGS)) $< -o $@
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
-include $(OBJ:%=%.dep)
|
||||
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
# -----------------------------------------------------------------------------
|
||||
# This is mostly a stub at the moment, but I'm keeping it separate so I can
|
||||
# mess with it later without changing the original
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
# Released under The MIT License (MIT) (see "license.md")
|
||||
# Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
TARGET = test
|
||||
|
||||
EXTRAINCDIRS = ..
|
||||
|
||||
TEENSY_MAKE = $(MAKE) -f '../lib-other/pjrc/blinky/Makefile' \
|
||||
TARGET='$(TARGET)' \
|
||||
EXTRAINCDIRS='$(EXTRAINCDIRS)'
|
||||
|
||||
.PHONY: test_pwm test_twi test_twi_2
|
||||
|
||||
test_pwm:
|
||||
$(TEENSY_MAKE) all \
|
||||
SRC='test_pwm.c'
|
||||
|
||||
test_twi:
|
||||
$(TEENSY_MAKE) all \
|
||||
SRC='test_twi.c'
|
||||
|
||||
test_twi_2:
|
||||
$(TEENSY_MAKE) all \
|
||||
SRC='test_twi_2.c'
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
$(TEENSY_MAKE) clean \
|
||||
SRC='$(shell find -name '*.c')'
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
# src/test
|
||||
Files used for testing (at some point)
|
||||
|
||||
I'm keeping these around for reference; they probably won't be maintained, and
|
||||
are quite likely to become broken at some point in the future.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
Released under The MIT License (MIT) (see "license.md")
|
||||
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* Test the Teensy 2.0 PWM code (see `#include`s)
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include <util/delay.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
|
||||
#define bool _Bool
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
||||
|
||||
// LED control
|
||||
#define KB_LED1_ON (DDRB |= (1<<5))
|
||||
#define KB_LED1_OFF (DDRB &= ~(1<<5))
|
||||
#define KB_LED1_SET(n) (OCR1A = (uint8_t)(n))
|
||||
#define KB_LED1_SET_PERCENT(n) (OCR1A = (uint8_t)((n) * 0xFF))
|
||||
#define KB_LED2_ON (DDRB |= (1<<6))
|
||||
#define KB_LED2_OFF (DDRB &= ~(1<<6))
|
||||
#define KB_LED2_SET(n) (OCR1B = (uint8_t)(n))
|
||||
#define KB_LED2_SET_PERCENT(n) (OCR1B = (uint8_t)((n) * 0xFF))
|
||||
#define KB_LED3_ON (DDRB |= (1<<7))
|
||||
#define KB_LED3_OFF (DDRB &= ~(1<<7))
|
||||
#define KB_LED3_SET(n) (OCR1C = (uint8_t)(n))
|
||||
#define KB_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF))
|
||||
|
||||
|
||||
int main(void) {
|
||||
CPU_PRESCALE(0); // set for 16MHz
|
||||
|
||||
// pwm init for keyboard LEDs
|
||||
// (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md")
|
||||
DDRB |= 0b11100000; // set B(7,6,5) as output
|
||||
TCCR1A = 0b10101001; // set and configure fast PWM
|
||||
TCCR1B = 0b00001001; // set and configure fast PWM
|
||||
|
||||
|
||||
for (uint8_t i=0; i<3; i++) {
|
||||
KB_LED1_SET(0x10);
|
||||
KB_LED2_SET(0x20);
|
||||
KB_LED3_SET(0xFF);
|
||||
_delay_ms(500);
|
||||
KB_LED1_SET(0x20);
|
||||
KB_LED2_SET(0xFF);
|
||||
KB_LED3_SET(0x10);
|
||||
_delay_ms(500);
|
||||
KB_LED1_SET(0xFF);
|
||||
KB_LED2_SET(0x10);
|
||||
KB_LED3_SET(0x20);
|
||||
_delay_ms(500);
|
||||
}
|
||||
|
||||
for (uint8_t i=0; i<2; i++) {
|
||||
KB_LED1_OFF;
|
||||
KB_LED2_OFF;
|
||||
KB_LED3_OFF;
|
||||
_delay_ms(500);
|
||||
KB_LED1_ON;
|
||||
KB_LED2_ON;
|
||||
KB_LED3_ON;
|
||||
_delay_ms(500);
|
||||
}
|
||||
|
||||
bool counting_up = true;
|
||||
for (uint8_t i=0;;) {
|
||||
(counting_up) ? i++ : i--;
|
||||
if (i == 0xFF)
|
||||
counting_up = false;
|
||||
else if (i == 0)
|
||||
counting_up = true;
|
||||
|
||||
KB_LED1_SET(i/2);
|
||||
KB_LED2_SET(i/2);
|
||||
KB_LED3_SET(i/2);
|
||||
_delay_ms(10);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* Test for ACK on address write (with a Teensy 2.0 and I/O expander)
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <util/twi.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
|
||||
// processor frequency (from <http://www.pjrc.com/teensy/prescaler.html>)
|
||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
||||
#define CPU_16MHz 0x00
|
||||
#define CPU_8MHz 0x01
|
||||
#define CPU_4MHz 0x02
|
||||
#define CPU_2MHz 0x03
|
||||
#define CPU_1MHz 0x04
|
||||
#define CPU_500kHz 0x05
|
||||
#define CPU_250kHz 0x06
|
||||
#define CPU_125kHz 0x07
|
||||
#define CPU_62kHz 0x08
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// helper functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define blink_led(time1, time2) { \
|
||||
/* Teensy 2.0 onboard LED on PD6
|
||||
on high, off low */ \
|
||||
PORTD |= (1<<6); \
|
||||
_delay_ms(time1); \
|
||||
PORTD &= ~(1<<6); \
|
||||
_delay_ms(time2); \
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------- // TWI
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void twi_init(void) {
|
||||
TWSR &= ~( (1<<TWPS1)|(1<<TWPS0) );
|
||||
TWBR = ((F_CPU / 100000) - 16) / 2;
|
||||
// TWSR |= (1<<TWPS1)|(1<<TWPS0); //dbg
|
||||
// TWBR = 0xFF; //dbg
|
||||
}
|
||||
|
||||
uint8_t twi_start(void) {
|
||||
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
|
||||
while (!(TWCR & (1<<TWINT)));
|
||||
if ((TWSR & 0xF8) != TW_START)
|
||||
return TWSR & 0xF8; // error
|
||||
}
|
||||
|
||||
void twi_stop(void) {
|
||||
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
|
||||
while (TWCR & (1<<TWSTO));
|
||||
}
|
||||
|
||||
uint8_t twi_send(uint8_t data) {
|
||||
TWDR = data;
|
||||
TWCR = (1<<TWINT)|(1<<TWEN);
|
||||
while (!(TWCR & (1<<TWINT)));
|
||||
if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
|
||||
return TWSR & 0xF8; // error
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// main
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void main(void) {
|
||||
CPU_PRESCALE(CPU_16MHz);
|
||||
uint8_t ret;
|
||||
|
||||
twi_init();
|
||||
|
||||
for (uint8_t i=0;; i+=2) { // try all even (write) addresses
|
||||
twi_start();
|
||||
ret = twi_send(i); // i = address
|
||||
twi_stop();
|
||||
|
||||
if (ret == 0x18) // SLA+W sent; ACK received
|
||||
break;
|
||||
|
||||
if (i == 0xFE) // all done
|
||||
break;
|
||||
}
|
||||
|
||||
// blink the return value
|
||||
// --- initial blink (get ready)
|
||||
blink_led(700, 200);
|
||||
// --- 1st hex number
|
||||
for (uint8_t i=0; i<(ret/0x10); i++) {
|
||||
blink_led(200, 100);
|
||||
}
|
||||
_delay_ms(400);
|
||||
// --- 2nd hex number
|
||||
for (uint8_t i=0; i<(ret%0x10); i++) {
|
||||
blink_led(200, 100);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* Test TWI write (with a Teensy 2.0 and I/O expander)
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <util/twi.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#define TWI_FREQ 400000
|
||||
#include "../lib/teensy-2-0/twi.c"
|
||||
|
||||
|
||||
// processor frequency (from <http://www.pjrc.com/teensy/prescaler.html>)
|
||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
||||
#define CPU_16MHz 0x00
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// helper functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define blink_led(time1, time2) { \
|
||||
/* Teensy 2.0 onboard LED on PD6
|
||||
on high, off low */ \
|
||||
PORTD |= (1<<6); \
|
||||
_delay_ms(time1); \
|
||||
PORTD &= ~(1<<6); \
|
||||
_delay_ms(time2); \
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------- // TWI
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define IODIRA 0x00
|
||||
#define IODIRB 0x01
|
||||
#define GPPUA 0x0C
|
||||
#define GPPUB 0x0D
|
||||
#define GPIOA 0x12
|
||||
#define GPIOB 0x13
|
||||
#define OLATA 0x14
|
||||
#define OLATB 0x15
|
||||
|
||||
#define TWI_ADDR_WRITE (0b0100000<<1)|TW_WRITE
|
||||
#define TWI_ADDR_READ (0b0100000<<1)|TW_READ
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// main
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* notes:
|
||||
* - won't work without the `twi_stop()`s after each block
|
||||
*/
|
||||
int main(void) {
|
||||
CPU_PRESCALE(CPU_16MHz);
|
||||
|
||||
twi_init();
|
||||
|
||||
// set all gpio pins as:
|
||||
|
||||
// output
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(IODIRA);
|
||||
twi_send(0);
|
||||
twi_send(0);
|
||||
twi_stop();
|
||||
|
||||
// with pull-up
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(GPPUA);
|
||||
twi_send(0xff);
|
||||
twi_send(0xff);
|
||||
twi_stop();
|
||||
|
||||
// logical 1
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(OLATA);
|
||||
twi_send(0xff);
|
||||
twi_send(0xff);
|
||||
twi_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue