diff --git a/.gitignore b/.gitignore index 70bb2a2..b7bdca1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ *~ *.swp +*.hex +*.eep +*.elf +*.o +*.o.dep + diff --git a/doc/references.md b/doc/references.md deleted file mode 100644 index c1e8826..0000000 --- a/doc/references.md +++ /dev/null @@ -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 ) - -* [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 - -> [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 ) - -* [C Library Reference] - (http://www.cplusplus.com/reference/) - (on ) - -* [C Operators/Expressions] - (http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/CONCEPT/expressions.html) - (on ) - -* [Bitwise Operators in C and C++: A Tutorial] - (http://www.cprogramming.com/tutorial/bitwise_operators.html) - (on ) - -* [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 ) - -* [Arrays and pointers in C] - (http://www.ibiblio.org/pub/languages/fortran/append-c.html) - (on ) - -* [how to use array of function pointers?] - (http://stackoverflow.com/questions/252748/how-to-use-array-of-function-pointers) - (on ) - -* [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 ) - -* [The New C: Inline Functions] - (http://drdobbs.com/184401540) - by Randy Meyers - (on ) - -### For the AVR - -* [AVR Newbie guide] - (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=70673) - by stu_san (on ) - -* [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 ) - -* [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 ) - -* [USB 2.0 Specification] - (http://www.usb.org/developers/docs/usb_20_101111.zip) - : zip (from ) - -* [HID Device Class Definition] - (http://www.usb.org/developers/devclass_docs/HID1_11.pdf) - : pdf (from ) - * HID = Human Interface Device - -* [HID Usage Tables] - (http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf) - : pdf (from ) - - -## 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 ) - -* 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 - - * 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 - -* 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 ) - - * mentioned on the [circuit/block-diagram drawing] - (http://stackoverflow.com/questions/6422603/circuit-block-diagram-drawing) - question (on ) - -* [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 ) - - * [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 ) - - -------------------------------------------------------------------------------- - -Copyright © 2012 Ben Blazak -Released under The MIT License (MIT) (see "license.md") -Project located at - diff --git a/readme.md b/readme.md index aaef982..730b885 100644 --- a/readme.md +++ b/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`). ------------------------------------------------------------------------------- diff --git a/references.md b/references.md new file mode 100644 index 0000000..c6b899c --- /dev/null +++ b/references.md @@ -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 ) + +* [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 + -> [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 ) + 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 ) + +* [C Operators/Expressions] + (http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/CONCEPT/expressions.html) + (on ) + +* [Bitwise Operators in C and C++: A Tutorial] + (http://www.cprogramming.com/tutorial/bitwise_operators.html) + (on ) + +* [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 ) + +* [Arrays and pointers in C] + (http://www.ibiblio.org/pub/languages/fortran/append-c.html) + (on ) + +* [how to use array of function pointers?] + (http://stackoverflow.com/questions/252748/how-to-use-array-of-function-pointers) + (on ) + +* [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 ) + +* [The New C: Inline Functions] + (http://drdobbs.com/184401540) + by Randy Meyers + (on ) + +* [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 ) + +### For the AVR + +* [AVR Newbie guide] + (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=70673) + by stu_san (on ) + 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-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 ) + 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 ) + 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 ) + 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 ) + +* [HID Device Class Definition] + (http://www.usb.org/developers/devclass_docs/HID1_11.pdf) + : pdf (from ) + * HID = Human Interface Device + +* [HID Usage Tables] + (http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf) + : pdf (from ) + + +## 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 ) + +* 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 + + * 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 + +* 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 ) + 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 + 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 ) + 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 ) + +* [TikZ 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 ) + + * [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 +Released under The MIT License (MIT) (see "license.md") +Project located at + diff --git a/src/key-functions.c b/src/key-functions.c deleted file mode 100644 index ff5112b..0000000 --- a/src/key-functions.c +++ /dev/null @@ -1,96 +0,0 @@ -/* ---------------------------------------------------------------------------- - * key functions: code - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#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; - } -} - diff --git a/src/keyboard.h b/src/keyboard.h index 6b0dd15..6a472b4 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -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 * 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 diff --git a/src/keyboard/ergodox.h b/src/keyboard/ergodox.h index 13d096b..5174f31 100644 --- a/src/keyboard/ergodox.h +++ b/src/keyboard/ergodox.h @@ -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]); diff --git a/src/keyboard/ergodox/_circuit-diagram.svg b/src/keyboard/ergodox/circuit-diagram.svg similarity index 100% rename from src/keyboard/ergodox/_circuit-diagram.svg rename to src/keyboard/ergodox/circuit-diagram.svg diff --git a/src/keyboard/ergodox/layout.c b/src/keyboard/ergodox/layout.c deleted file mode 100644 index 663de73..0000000 --- a/src/keyboard/ergodox/layout.c +++ /dev/null @@ -1,94 +0,0 @@ -/* ---------------------------------------------------------------------------- - * ergoDOX layout specific code - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#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 -------------------------- */ -} -}; - diff --git a/src/keyboard/ergodox/layout.h b/src/keyboard/ergodox/layout.h index 8b786f1..7454dff 100644 --- a/src/keyboard/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -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 * Released under The MIT License (MIT) (see "license.md") @@ -9,20 +11,113 @@ #ifndef LAYOUT_h #define LAYOUT_h + #include #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 diff --git a/src/keyboard/ergodox/layout.md b/src/keyboard/ergodox/layout.md new file mode 100644 index 0000000..732fac7 --- /dev/null +++ b/src/keyboard/ergodox/layout.md @@ -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 +Released under The MIT License (MIT) (see "license.md") +Project located at + diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c new file mode 100644 index 0000000..65ce0d4 --- /dev/null +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -0,0 +1,61 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX layout : QWERTY + * + * This is an overly basic implementation. It needs to be replaced. + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#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 +}; + diff --git a/src/keyboard/ergodox/layout/qwerty.h b/src/keyboard/ergodox/layout/qwerty.h new file mode 100644 index 0000000..a94f2c5 --- /dev/null +++ b/src/keyboard/ergodox/layout/qwerty.h @@ -0,0 +1,26 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX layout : QWERTY : exports + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#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 + diff --git a/src/keyboard/ergodox/led.h b/src/keyboard/ergodox/led.h new file mode 100644 index 0000000..78ddf00 --- /dev/null +++ b/src/keyboard/ergodox/led.h @@ -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 + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef LED_h + #define LED_h + + #include + + #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 + diff --git a/src/keyboard/ergodox/matrix.h b/src/keyboard/ergodox/matrix.h index 1ee9907..832a805 100644 --- a/src/keyboard/ergodox/matrix.h +++ b/src/keyboard/ergodox/matrix.h @@ -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 diff --git a/src/keyboard/ergodox/matrix.md b/src/keyboard/ergodox/matrix.md deleted file mode 100644 index 7042086..0000000 --- a/src/keyboard/ergodox/matrix.md +++ /dev/null @@ -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 -Released under The MIT License (MIT) (see "license.md") -Project located at - diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c index 67d30be..ca960a1 100644 --- a/src/keyboard/ergodox/mcp23018.c +++ b/src/keyboard/ergodox/mcp23018.c @@ -8,9 +8,8 @@ #include - #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< - * + * 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 ;) + * + * ## 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). ------------------------------------------------------------------------------- diff --git a/src/keyboard/ergodox/teensy-2-0.c b/src/keyboard/ergodox/teensy-2-0.c index d692218..82096df 100644 --- a/src/keyboard/ergodox/teensy-2-0.c +++ b/src/keyboard/ergodox/teensy-2-0.c @@ -8,10 +8,9 @@ #include - #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 } diff --git a/src/keyboard/ergodox/teensy-2-0.h b/src/keyboard/ergodox/teensy-2-0.h index b7f6d32..048072d 100644 --- a/src/keyboard/ergodox/teensy-2-0.h +++ b/src/keyboard/ergodox/teensy-2-0.h @@ -11,24 +11,47 @@ #define TEENSY_2_0_h #include // 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 diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/teensy-2-0.md index 42113b2..e1edf5b 100644 --- a/src/keyboard/ergodox/teensy-2-0.md +++ b/src/keyboard/ergodox/teensy-2-0.md @@ -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 ------------------------------------------------------------------------------- diff --git a/src/lib-other/pjrc/readme.md b/src/lib-other/pjrc/readme.md new file mode 100644 index 0000000..ec7ad28 --- /dev/null +++ b/src/lib-other/pjrc/readme.md @@ -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) + + +------------------------------------------------------------------------------- + +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") +Project located at + diff --git a/src/lib-other/pjrc/usb_keyboard/Makefile b/src/lib-other/pjrc/usb_keyboard/Makefile deleted file mode 100644 index 1ef8689..0000000 --- a/src/lib-other/pjrc/usb_keyboard/Makefile +++ /dev/null @@ -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 -# 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 diff --git a/src/lib-other/pjrc/usb_keyboard/example.c b/src/lib-other/pjrc/usb_keyboard/example.c deleted file mode 100644 index 9e090ba..0000000 --- a/src/lib-other/pjrc/usb_keyboard/example.c +++ /dev/null @@ -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 -#include -#include -#include -#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< 61 * 8) { - idle_count = 0; - usb_keyboard_press(KEY_SPACE, 0); - } -} - - diff --git a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c index 1501f2a..46e1b20 100644 --- a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c +++ b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c @@ -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; diff --git a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.h b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.h index cd9e8a9..853905e 100644 --- a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.h +++ b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.h @@ -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 diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c new file mode 100644 index 0000000..de037ef --- /dev/null +++ b/src/lib/key-functions.c @@ -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 + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#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; + } +} + diff --git a/src/key-functions.h b/src/lib/key-functions.h similarity index 55% rename from src/key-functions.h rename to src/lib/key-functions.h index 887dfa6..9437251 100644 --- a/src/key-functions.h +++ b/src/lib/key-functions.h @@ -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 diff --git a/src/lib-other/readme.md b/src/lib/readme.md similarity index 60% rename from src/lib-other/readme.md rename to src/lib/readme.md index e7188b8..2f676c7 100644 --- a/src/lib-other/readme.md +++ b/src/lib/readme.md @@ -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 ------------------------------------------------------------------------------- diff --git a/src/lib/twi.h b/src/lib/twi.h new file mode 100644 index 0000000..6221bd5 --- /dev/null +++ b/src/lib/twi.h @@ -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 + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#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 + diff --git a/src/lib/teensy-2-0/twi.c b/src/lib/twi/teensy-2-0.c similarity index 88% rename from src/lib/teensy-2-0/twi.c rename to src/lib/twi/teensy-2-0.c index 1492d9c..7c3ed69 100644 --- a/src/lib/teensy-2-0/twi.c +++ b/src/lib/twi/teensy-2-0.c @@ -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 `` at + * - Also see the documentation for `` at + * * - * 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 //dbg #include - -#include "twi.h" +#include "lib/twi.h" void twi_init(void) { diff --git a/src/lib/teensy-2-0/twi.h b/src/lib/twi/teensy-2-0.h similarity index 100% rename from src/lib/teensy-2-0/twi.h rename to src/lib/twi/teensy-2-0.h diff --git a/src/lib/teensy-2-0/twi.md b/src/lib/twi/teensy-2-0.md similarity index 96% rename from src/lib/teensy-2-0/twi.md rename to src/lib/twi/teensy-2-0.md index eaa880e..ec511cb 100644 --- a/src/lib/teensy-2-0/twi.md +++ b/src/lib/twi/teensy-2-0.md @@ -1,4 +1,4 @@ -# Documentation : Teensy 2.0 I²C +# Documentation : I²C : Teensy 2.0 ## I²C Status Codes (for Master modes) diff --git a/src/lib/usb/TODO.c b/src/lib/usb/TODO.c new file mode 100644 index 0000000..0f6aec1 --- /dev/null +++ b/src/lib/usb/TODO.c @@ -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 + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +// 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 + diff --git a/src/lib/usb/common.h b/src/lib/usb/common.h new file mode 100644 index 0000000..2da9e7e --- /dev/null +++ b/src/lib/usb/common.h @@ -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 + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#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 + diff --git a/src/lib/usb/notes from hid device class definition 1.11.md b/src/lib/usb/notes from hid device class definition 1.11.md new file mode 100644 index 0000000..3faa927 --- /dev/null +++ b/src/lib/usb/notes from hid device class definition 1.11.md @@ -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 +Released under The MIT License (MIT) (see "license.md") +Project located at + diff --git a/src/lib/usb/notes from usb 2.0 spec sec 9 (usb device framework).h b/src/lib/usb/notes from usb 2.0 spec sec 9 (usb device framework).h new file mode 100644 index 0000000..f6650d6 --- /dev/null +++ b/src/lib/usb/notes from usb 2.0 spec sec 9 (usb device framework).h @@ -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 + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#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 + * ). + * + * - 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 + diff --git a/src/lib/usb/usage-page/keyboard--short-names.h b/src/lib/usb/usage-page/keyboard--short-names.h new file mode 100644 index 0000000..c611e14 --- /dev/null +++ b/src/lib/usb/usage-page/keyboard--short-names.h @@ -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 + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#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 + diff --git a/src/lib/usb/keyboard-usage-page.h b/src/lib/usb/usage-page/keyboard.h similarity index 97% rename from src/lib/usb/keyboard-usage-page.h rename to src/lib/usb/usage-page/keyboard.h index 8f429b1..7e79b09 100644 --- a/src/lib/usb/keyboard-usage-page.h +++ b/src/lib/usb/usage-page/keyboard.h @@ -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 + diff --git a/src/lib/usb/led-usage-page.h b/src/lib/usb/usage-page/led.h similarity index 93% rename from src/lib/usb/led-usage-page.h rename to src/lib/usb/usage-page/led.h index 45c9754..edfed5b 100644 --- a/src/lib/usb/led-usage-page.h +++ b/src/lib/usb/usage-page/led.h @@ -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 + diff --git a/src/main.c b/src/main.c index 206d969..eaa76d4 100644 --- a/src/main.c +++ b/src/main.c @@ -9,37 +9,22 @@ #include - #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 # 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) diff --git a/src/test/makefile b/src/test/makefile deleted file mode 100644 index d0a472e..0000000 --- a/src/test/makefile +++ /dev/null @@ -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 -# Released under The MIT License (MIT) (see "license.md") -# Project located at -# ----------------------------------------------------------------------------- - - -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')' - diff --git a/src/test/readme.md b/src/test/readme.md deleted file mode 100644 index fbefe39..0000000 --- a/src/test/readme.md +++ /dev/null @@ -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 -Released under The MIT License (MIT) (see "license.md") -Project located at - diff --git a/src/test/test_pwm.c b/src/test/test_pwm.c deleted file mode 100644 index 1b6110e..0000000 --- a/src/test/test_pwm.c +++ /dev/null @@ -1,85 +0,0 @@ -/* ---------------------------------------------------------------------------- - * Test the Teensy 2.0 PWM code (see `#include`s) - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#include -#include - - -#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); - } -} - diff --git a/src/test/test_twi.c b/src/test/test_twi.c deleted file mode 100644 index 4801c8f..0000000 --- a/src/test/test_twi.c +++ /dev/null @@ -1,105 +0,0 @@ -/* ---------------------------------------------------------------------------- - * Test for ACK on address write (with a Teensy 2.0 and I/O expander) - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - -#include -#include -#include - - -// processor frequency (from ) -#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< - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - -#include -#include -#include - -#define TWI_FREQ 400000 -#include "../lib/teensy-2-0/twi.c" - - -// processor frequency (from ) -#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; -} -