!gEDA
Linuxで回路図を書こうとして探してたらこれを発見
>>
# aptitude install geda-gschem
<<
でインストール(Debian)
http://www.mail-archive.com/geda-user@moria.seul.org/msg17056.html
ここからatmega168のデータを借りてくる
シンボルの作成は
http://www5a.biglobe.ne.jp/~nkgwtty/njaLinuxgEDA01.html#SYM_MK を参考にした。
とりあえず回路図: http://inajob.no-ip.org/dev/rakuchord_mobile/keykey.png
なんかうまく使いこなせてない感。とりあえず書いてみた。
画像書き出しの範囲指定がなんか微妙で上切れちゃった(スクロール位置と関係がある?)
CON1は後から書きこむ用のピンです。動作には使いません。
あとPS/2の配線は書いてないですが5番がCLK、6番がDATA
!!ソース
取り回しの関係でコメントが謎英語になってます。
breakってのはキーアップのことです。
PROGMEM使うつもりで使ってないのも あとで直す って思っててそのまま放置した跡です。
見苦しい点は少しずつ直していきます。
キーボードの周りはhttp://www.arduino.cc/playground/Main/PS2Keyboard このへん参考にした
!!!あれ? 直したい!
- 1<<14 がなんで出てきたのか不明。まぁ周波数は合ってるから音はでるけど変な波形になる気が…?
- 普通に↑のライブラリを使ったほうがよさげ。 スキャンコードとASCIIの対応表とかパターン多そうだし…
>>
#define PS2_KC_BREAK 0xf0
#define PS2_KC_ENTER 0x5a
#define PS2_KC_ESC 0x76
#define PS2_KC_KPLUS 0x79
#define PS2_KC_KMINUS 0x7b
#define PS2_KC_KMULTI 0x7c
#define PS2_KC_NUM 0x77
#define PS2_KC_BKSP 0x66
#define PS2_INT_PIN 3
class PS2Keyboard {
private:
int m_dataPin;
byte m_charBuffer;
public:
PS2Keyboard();
void begin(int dataPin);
bool available();
bool available2();
byte read();
byte read2();
};
#include <avr/pgmspace.h>
#define PS2_KC_LUT_CAPACITY 56
//PROGMEM
prog_uchar PS2_KC_LUT_DATA[PS2_KC_LUT_CAPACITY] = {0x70, 0x69, 0x72, 0x7a, 0x6b, 0x73, 0x74, 0x6c, 0x75, 0x7d, 0x15,0x16,0x1A,0x1B,0x1C,0x1D,0x1E,0x21,0x22,0x23,0x24,0x25,0x26,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x31,0x32,0x33,0x34,0x35,0x36,0x3A,0x3B,0x3C,0x3D,0x3E,0x42,0x43,0x44,0x45,0x46,0x4B,0x4D,
0x4c,0x52,0x41,0x49,0x4A ,0x54,0x5B,0x5d,
0x66 // BS
};
//PROGMEM
prog_uchar PS2_KC_LUT_CHAR[PS2_KC_LUT_CAPACITY] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','Q','1','Z','S','A','W','2','C','X','D','E','4','3',' ','V','F','T','R','5','N','B','H','G','Y','6','M','J','U','7','8','K','I','O','0','9','L','P',
';',':',',','.','\\','@','[',']',
0x08 // BS
};
int ps2Keyboard_DataPin;
volatile byte ps2Keyboard_CurrentBuffer;
volatile byte ps2Keyboard_CharBuffer;
volatile byte ps2Keyboard_CharBuffer2; // for break
volatile byte ps2Keyboard_BufferPos;
volatile bool ps2Keyboard_BreakActive;
volatile bool value;
volatile bool value2; // for break
volatile bool ring[128]; // 2^7 ring buffer
volatile unsigned char ringc = 0; // current write position
volatile unsigned char ringr = 0; // current read position
// The ISR for the external interrupt
ISR(INT1_vect) {
value = (PIND&(0b00010000))?1:0;//digitalRead(ps2Keyboard_DataPin);
ring[ringc] = value;
ringc = (ringc + 1) & 0b1111111;
}
PS2Keyboard::PS2Keyboard() {
// nothing to do here
}
void PS2Keyboard::begin(int dataPin) {
// Prepare the global variables
ps2Keyboard_DataPin = dataPin;
ps2Keyboard_CurrentBuffer = 0;
ps2Keyboard_CharBuffer = 0;
ps2Keyboard_BufferPos = 0;
ps2Keyboard_BreakActive = false;
// initialize the pins
pinMode(PS2_INT_PIN, INPUT);
digitalWrite(PS2_INT_PIN, HIGH); // pull up mode
pinMode(PS2_INT_PIN, OUTPUT);
digitalWrite(PS2_INT_PIN, HIGH);
pinMode(dataPin, INPUT);
digitalWrite(dataPin, HIGH); // pull up mode
// Global Enable INT1 interrupt
EIMSK |= ( 1 << INT1);
// Falling edge triggers interrupt
EICRA |= (0 << ISC10) | (1 << ISC11);
}
bool PS2Keyboard::available() {
return ps2Keyboard_CharBuffer != 0;
}
bool PS2Keyboard::available2() {
return ps2Keyboard_CharBuffer2 != 0;
}
byte PS2Keyboard::read() {
byte result = ps2Keyboard_CharBuffer;
for(int i = 0; i < PS2_KC_LUT_CAPACITY; i++) {
if(ps2Keyboard_CharBuffer == /*pgm_read_byte_near*/(PS2_KC_LUT_DATA[i]/* + i*/)) {
result = /*pgm_read_byte_near*/(PS2_KC_LUT_CHAR[i]/* + i*/);
}
}
ps2Keyboard_CharBuffer = 0;
return result;
}
byte PS2Keyboard::read2() {
byte result = ps2Keyboard_CharBuffer2;
for(int i = 0; i < PS2_KC_LUT_CAPACITY; i++) {
if(ps2Keyboard_CharBuffer2 == /*pgm_read_byte_near*/(PS2_KC_LUT_DATA[i]/* + i*/)) {
result = /*pgm_read_byte_near*/(PS2_KC_LUT_CHAR[i]/* + i*/);
}
}
ps2Keyboard_CharBuffer2 = 0;
return result;
}
const int DataPin = 4;
const int IRQpin = 3;
const int speakerPin = 9;
const unsigned int timerLoadValue = 254;
volatile unsigned char level = 0;
volatile unsigned int d[5] = {80,260,330,390,520}; // default value( for debug)
const unsigned int tones[] = {95,106,123,127,145,160,179,190
,212,246,254,290,320,358,380};
volatile unsigned int dn[5] = {0,0,0,0,0}; // work variable
volatile unsigned char vol[5] = {32,16,16,16,16}; // volume par channel
volatile unsigned int counter = 0;
volatile unsigned char bend = 0;
ISR(TIMER2_OVF_vect) { // Timer/Counter2 Overflow
TCNT2 = timerLoadValue; // Reset the timer
dn[0] = dn[0] + d[0] + bend;
dn[1] = dn[1] + d[1] + bend;
dn[2] = dn[2] + d[2] + bend;
dn[3] = dn[3] + d[3] + bend;
dn[4] = dn[4] + d[4] + bend;
//chord composite
level = ((dn[0]&(1<<14))?vol[0]:0) +
((dn[1]&(1<<14))?vol[1]:0) +
((dn[2]&(1<<14))?vol[2]:0) +
((dn[3]&(1<<14))?vol[3]:0) +
((dn[4]&(1<<14))?vol[4]:0);
OCR1A = level;
}
PS2Keyboard keyboard;
void setup() {
delay(1000);
keyboard.begin(DataPin);
Serial.begin(9600);
Serial.println("Keyboard Test:");
pinMode(speakerPin, OUTPUT);
TCCR1A = _BV(COM2A1) | _BV(COM2B1)| _BV(WGM20);
TCCR1B = _BV(CS22) | _BV(WGM12) | _BV(WGM13);
OCR1A = 180; // for debug
//OCR1B = 50;
TCCR1B = TCCR1B & 0b11100000 | 0b00001; // pwm: 31250Hz
TCCR2A = 0; // Normal Timer
TCCR2B = 1<<CS22 | 0<<CS21 | 1<<CS20; // clk/128 prescale
TIMSK2 = 1<<TOIE2; // Timer/Counter2 Overflow Interrupt Enable
TCNT2 = timerLoadValue;
}
unsigned int rythm[8] = {0,0,0,0,0,0,0,0};
char rythmSel = -1;
char rythmStep = 0;
char rythmCount = 0;
char rythmMode = 0;
void loop() {
bend = analogRead(0) >> 2;
counter ++;
if(counter & (1 << 8)){
counter = 0;
if(vol[0] > 0)vol[0]--; // volume down
if(rythmMode){ // step sequencer mode?
rythmCount ++;
if(rythmCount & (1<<2)){
rythmCount = 0;
rythmStep = (rythmStep + 1) & 0b111;
dn[4] = 0;
d[4] = rythm[rythmStep];
}
}
}
if (keyboard.available2()) { // for break
char c = keyboard.read2();
switch(c){
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
rythmSel = -1;
Serial.println("[break]");
}
}
if (keyboard.available()) {
// read the next key
char c = keyboard.read();
{
// otherwise, just print all normal characters
Serial.print(c);
switch(c){
case PS2_KC_ESC:
d[0] = d[1] = d[2] = d[3] = d[4] = 0;
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
rythmSel = c - '1';
break;
case '0':
rythmMode = !rythmMode;
default:
char tmp = c2c(c);
if(tmp < 19 && tmp>=0){
if(rythmSel != -1){
rythm[rythmSel] = tones[tmp];
}else{
d[0] = (tones[tmp]<<0);
vol[0] = 32;
}
}
if(tmp >=19 && tmp <=31){
dn[1] = dn[2] = dn[3] = 0;
d[1] = (tones[tmp - 19]<<0);
d[2] = (tones[tmp - 19 + 2]<<0);
d[3] = (tones[tmp - 19 + 4]<<0);
}
}
}
}
//===================
if(ringr != ringc){
value2 = ring[ringr];
ringr = (ringr + 1) & 0b1111111;
if(ps2Keyboard_BufferPos==0){
if(value2!=0){
ps2Keyboard_BufferPos = 0;
ps2Keyboard_CurrentBuffer = 0;
ps2Keyboard_CharBuffer = 0;
ps2Keyboard_BreakActive = false;
return;
}
}
if(ps2Keyboard_BufferPos > 0 && ps2Keyboard_BufferPos < 9) {
ps2Keyboard_CurrentBuffer |= (value2 << (ps2Keyboard_BufferPos - 1));
}
ps2Keyboard_BufferPos++;
if(ps2Keyboard_BufferPos == 11) {
if(ps2Keyboard_CurrentBuffer == PS2_KC_BREAK) {
ps2Keyboard_BreakActive = true;
} else if(ps2Keyboard_BreakActive) {
ps2Keyboard_BreakActive = false;
Serial.print("break:");
Serial.println(ps2Keyboard_CurrentBuffer,HEX);
ps2Keyboard_CharBuffer2 = ps2Keyboard_CurrentBuffer;
} else {
Serial.print("input:");
Serial.println(ps2Keyboard_CurrentBuffer,HEX);
ps2Keyboard_CharBuffer = ps2Keyboard_CurrentBuffer;
}
ps2Keyboard_CurrentBuffer = 0;
ps2Keyboard_BufferPos = 0;
}
}
//===================
}
int c2c(char c){
switch(c){
case 'A': return 0;
case 'S': return 1;
case 'D': return 2;
case 'F': return 3;
case 'G': return 4;
case 'H': return 5;
case 'J': return 6;
case 'K': return 7;
case 'L': return 8;
case ';': return 9;
case ':': return 10;
case 'Z': return 7;
case 'X': return 8;
case 'C': return 9;
case 'V': return 10;
case 'B': return 11;
case 'N': return 12;
case 'M': return 13;
case ',': return 14;
case '.': return 15;
case '?': return 16;
case '\\': return 17;
case 'Q': return 19;
case 'W': return 20;
case 'E': return 21;
case 'R': return 22;
case 'T': return 23;
case 'Y': return 24;
case 'U': return 25;
case 'I': return 26;
case 'O': return 27;
case 'P': return 28;
case '@': return 29;
case '[': return 30;
case ']': return 31;
}
return -1;
}
<<
5643382
wiki
1323187463