This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
hidkey_gpio [2012/11/26 16:06] steve_m [Hardware] |
hidkey_gpio [2012/11/30 19:01] steve_m [Software] |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== AVR Programmer built from a USB Keyboard ====== | ====== AVR Programmer built from a USB Keyboard ====== | ||
- | Recently, my old keyboard became louder and louder while typing, so I decided to buy a new one. But what to do with the old one? Ever since I saw the [[http://www.pjrc.com/hub_isp/|AVR programmer that uses a USB hub]], I thought of abusing a USB keyboard for that. | + | Recently, my keyboard became louder and louder while typing, so I decided to buy a new one. But what to do with the old one? Ever since I saw the [[http://www.pjrc.com/hub_isp/|AVR programmer that uses a USB hub]], I thought of abusing a USB keyboard for that. |
===== Theory ===== | ===== Theory ===== | ||
Line 30: | Line 30: | ||
|Caps lock|MOSI|out| | |Caps lock|MOSI|out| | ||
|Scroll lock|Reset|out| | |Scroll lock|Reset|out| | ||
- | |row/column of right shift key|MISO|in| | + | |row/column of right shift key|MISO (through optocoupler)|in| |
For the optocoupler I added a 470Ω current limiting resistor. | For the optocoupler I added a 470Ω current limiting resistor. | ||
Line 36: | Line 36: | ||
===== Software ===== | ===== Software ===== | ||
- | First I wrote a small libusb-based test utility for experimenting with the keyboard. I'm directly communicating with the keyboard from userspace, unloading the kernel driver first. | + | First I wrote a [[https://github.com/steve-m/hidkey_gpio|small libusb-based test utility]] for experimenting with the keyboard. I'm directly communicating with the keyboard from userspace, unloading the kernel driver first. |
==== Speed ==== | ==== Speed ==== | ||
Line 59: | Line 59: | ||
==== Results ==== | ==== Results ==== | ||
<code> | <code> | ||
- | $ ./avrdude -c hidkey -C avrdude.conf -pattiny2313 -U flash:w:main.hex:i -V | + | $ ./avrdude -c hidkey -C avrdude.conf -p attiny2313 -U flash:w:main.hex:i -V |
avrdude: AVR device initialized and ready to accept instructions | avrdude: AVR device initialized and ready to accept instructions | ||
Line 79: | Line 79: | ||
</code> | </code> | ||
- | Well, as you can see, programming takes quite a while, mainly because of the slow input speed I mentioned before, but is very reliable. Since I assume that many people have some old USB keyboard laying around collecting dust, it still could be used as a bootstrap flasher for solving the old chicken-and-egg problem when building a faster programmer like the [[http://www.fischl.de/usbasp/|USBasp]], or as low-speed general purpose output for other applications. For example, many outputs could be driven using a simple serial-in, parallel-out shift register. | + | Well, as you can see, programming takes quite a while, mainly because of the slow input speed I mentioned before, but is very reliable. Since I assume that many people have some old USB keyboard laying around collecting dust, it still could be used as a bootstrap flasher for solving the old chicken-and-egg problem when building a faster programmer ([[http://www.fischl.de/usbasp/|USBasp]], [[http://www.ladyada.net/make/usbtinyisp/|USBtinyISP]]) or as low-speed general purpose output for other applications. For example, many outputs could be driven using a simple serial-in, parallel-out shift register. |
+ | |||
+ | ===== Update #1 ===== | ||
+ | |||
+ | Since reading the MISO input is much slower than writing the outputs, as I mentioned above, I took a closer look at the avrdude code. As it turns out, the inputs are read every time, even if the data isn't used at all afterwards (like when writing a byte). I applied a crude hack, so that MISO is only being read if the data is used afterwards. I pushed that change to a new [[https://github.com/steve-m/avrdude/tree/speedup|speedup branch]] on github. | ||
+ | |||
+ | With those changes, flashing my 86 byte demo application is now over ten times faster (11.75s vs. 123.79s)! | ||
+ | <code> | ||
+ | $ ./avrdude -c hidkey -C avrdude.conf -p attiny2313 -U flash:w:main.hex:i | ||
+ | |||
+ | avrdude: AVR device initialized and ready to accept instructions | ||
+ | |||
+ | Reading | ################################################## | 100% 4.33s | ||
+ | |||
+ | avrdude: Device signature = 0x1e910a | ||
+ | avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed | ||
+ | To disable this feature, specify the -D option. | ||
+ | avrdude: erasing chip | ||
+ | avrdude: reading input file "/home/steve/dev/hid_gpio/avr_demo/main.hex" | ||
+ | avrdude: writing flash (86 bytes): | ||
+ | |||
+ | Writing | ################################################## | 100% 11.75s | ||
+ | |||
+ | avrdude: 86 bytes of flash written | ||
+ | avrdude: verifying flash memory against /home/steve/dev/hid_gpio/avr_demo/main.hex: | ||
+ | avrdude: load data flash data from input file /home/steve/dev/hid_gpio/avr_demo/main.hex: | ||
+ | avrdude: input file /home/steve/dev/hid_gpio/avr_demo/main.hex contains 86 bytes | ||
+ | avrdude: reading on-chip flash data: | ||
+ | |||
+ | Reading | ################################################## | 100% 124.25s | ||
+ | |||
+ | avrdude: verifying ... | ||
+ | avrdude: 86 bytes of flash verified | ||
+ | |||
+ | avrdude: safemode: Fuses OK | ||
+ | |||
+ | avrdude done. Thank you. | ||
+ | </code> | ||
+ | |||
+ | Programming the whole flash of the ATiny2313 now only takes 4 minutes 37 seconds: | ||
+ | |||
+ | <code> | ||
+ | $ ./avrdude -c hidkey -C avrdude.conf -p attiny2313 -U flash:w:/tmp/usbtiny.hex:i | ||
+ | avrdude: AVR device initialized and ready to accept instructions | ||
+ | |||
+ | Reading | ################################################## | 100% 4.33s | ||
+ | |||
+ | avrdude: Device signature = 0x1e910a | ||
+ | avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed | ||
+ | To disable this feature, specify the -D option. | ||
+ | avrdude: erasing chip | ||
+ | avrdude: reading input file "/tmp/usbtiny.hex" | ||
+ | avrdude: writing flash (2046 bytes): | ||
+ | |||
+ | Writing | ################################################## | 100% 276.90s | ||
+ | |||
+ | avrdude: 2046 bytes of flash written | ||
+ | avrdude: verifying flash memory against /tmp/usbtiny.hex: | ||
+ | avrdude: load data flash data from input file /tmp/usbtiny.hex: | ||
+ | avrdude: input file /tmp/usbtiny.hex contains 2046 bytes | ||
+ | avrdude: reading on-chip flash data: | ||
+ | |||
+ | Reading | ########## | 20% 593.63s^C | ||
+ | </code> | ||
+ | |||
+ | I'd say that's quite an improvement, and very well acceptable for a chicken-and-egg bootstrap flasher :-) | ||
== Reference Literature == | == Reference Literature == |