The guy from Tynemouth software created a lot of USB keyboards. He using Arduino however, and I like plain C better. Also, I cannot find his code right now. Because I don't think scanning & debouncing could be that hard, I made a start. This guy did however inspire me by showing that an ATmega microcontroller with V-USB is capable of being used as a keyboard.
My plan is to write a code generation tool, and today I started. It's only the init routine for now, but it's a start. :-) The code generation tool will justify the name AnyHardKeyboard; the plan is to be able to give a CSV of the keyboard layout to this little program, and have it generate the keyboard routines from it.
A big thanks to the guys of FreeBSD who put a text format key table online (everyone else points to the PDF). I'll use a modified version of that one for the key mapping.
What I have now is the following:
,"B5","B6","C0","C1","C2","C3","C4","C5" "D0","ESCAPE","F12","`","Tab","Caps Lock","A",,1 "D1","F3","F2",2,"W","S","X","Z","Q" "D3","Fn","LeftShift","LeftControl","Left GUI","RightShift","LeftAlt","RightAlt","RightControl" "D4","F6",6,5,"R","G","F","V","T" "D5","F5","F4",4,"ENTER","D","C3",,3 "D6","F7",8,7,"Y","H","N","B","U" "B0","F9","F8","I","K","M",",","Spacebar","J" "B1","F10",9,"O","L",";",".",,"P" "B2","F11","F12",0,"[","'","/",,"-" "C6","Scroll Lock","Pause","=",,,,,"]" "B3","Delete","Insert","Backspace","ENTER","\","PageDown","DownArrow","RightArrow"
The topmost row and the leftmost column designate the ATmega8's pins used.
The proof-of-concept Python code:
import csv
with open('esprimo.csv', 'rb') as csvfile:
csvreader = csv.reader(csvfile, delimiter=',', quotechar='"')
i = 0
inputmatrix = []
writepins = []
for row in csvreader:
inputmatrix.append(row)
if i > 0:
writepins.append(row[0])
#writepins[i] = row[1]
i = i + 1
readpins = inputmatrix[0][1:]
writepins.sort()
readpins.sort()
outfile = "init_kb_pins() {\r\n"
outfile = outfile + "\t" + '// write pins\r\n'
buf = ''
lastp = ''
for p in writepins:
if lastp != p[0] and lastp != '':
outfile = outfile + "\t" + 'DDR' + lastp + ' |= ' + buf + "; // set the bits as input\r\n"
outfile = outfile + "\t" + 'PORT' + lastp + ' &= ~('+ buf + "); // set voltage low in case bits are set as output while scanning\r\n";
buf = ''
if buf != '':
buf = buf + ' |'
buf = buf + ' (1 << '+p[1]+')'
lastp = p[0]
outfile = outfile + "\t" + 'DDR' + lastp + ' |= ' + buf + "; // set the bits as input\r\n"
outfile = outfile + "\t" + 'PORT' + lastp + ' &= ~('+ buf + "); // set voltage low in case bits are set as output while scanning\r\n";
buf = ''
lastp = ''
outfile = outfile + "\r\n\t// read pins\r\n"
for p in readpins:
if lastp != p[0] and lastp != '':
outfile = outfile + "\t" + 'DDR' + lastp + ' |= ' + buf + "; // set the bits as input\r\n"
outfile = outfile + "\t" + 'PORT' + lastp + ' |= '+ buf + "; // activate pull-ups\r\n";
buf = ''
lastp = p[0]
if buf != '':
buf = buf + ' |'
buf = buf + ' (1 << '+p[1]+')'
outfile = outfile + "\t" + 'DDR' + lastp + ' |= ' + buf + "; // set the bits as input\r\n"
outfile = outfile + "\t" + 'PORT' + lastp + ' |= '+ buf + "; // activate pull-ups\r\n";
outfile = outfile + "}\r\n\r\n"
print outfile
print writepins
print readpins
which nicely generates:
init_kb_pins() {
// write pins
DDRB |= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3); // set the bits as input
PORTB &= ~( (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); // set voltage low in case bits are set as output while scanning
DDRC |= (1 << 6); // set the bits as input
PORTC &= ~( (1 << 6)); // set voltage low in case bits are set as output while scanning
DDRD |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6); // set the bits as input
PORTD &= ~( (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6)); // set voltage low in case bits are set as output while scanning
// read pins
DDRB |= (1 << 5) | (1 << 6); // set the bits as input
PORTB |= (1 << 5) | (1 << 6); // activate pull-ups
DDRC |= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5); // set the bits as input
PORTC |= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5); // activate pull-ups
}
Please don't punish me for all the code duplication... I really miss IntelliJ's "extract method" and other refactoring functionality. Perhaps I should rewrite it in Java, or try IDLE...
I also still have to find out if I used the correct bit fiddling operators, but I think I have it right.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.