pinewell's farmer blog 農業と電子工作、ソフトウェア、バイク、車

2013年2月2日

RaspberryPiにスーパーファミコンのコントローラを繋ぐ。

Filed under: 副業,未分類 — pinewell @ 5:52 PM

PS2のコントローラを繋ぎたかったのだが、Arduino用のサンプルのみで敷居が高かった。
アナログ部分は使わないので、”ピコーン!”と閃いた。スーパーファミコンのコントローラならもっと簡単じゃね?と。

で、検索してみるとサンプルっぽいもの。さらに、Arduinoに繋ぐlibraryがとても簡潔でわかりやすい。
ので、ハードオフにてドナーとなるコントローラをゲット。1つ105円。
ジャンク本体でもあれば尚良かったのだが、それは無かった。もう扱ってないのだろうか。(ジャンクじゃ無いモノはあった)

さっそくコネクタ部分をばらしてみると、7pinありそうなコネクタだったが、実際は5pin。
電源とGND、その他3pin。Arduinoに繋いで動作確認。問題無し。電源を3.3Vにしてみたが、これも問題無し。
搭載チップMC14021のデータシートでも問題なさそうだった。

電源はraspiの3.3Vから取得。ササササッとコードを書いて、raspiでの動作も確認。
以下ソース

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
 
#define PIN_DATA  RPI_V2_GPIO_P1_13   //Red
#define PIN_CLOCK RPI_V2_GPIO_P1_11   //Yellow
#define PIN_LATCH RPI_V2_GPIO_P1_15   //Orange
                                      //Brown = Ground
				      //White = VCC
#define SFCPAD_B_BTN	0x0001
#define SFCPAD_Y_BTN	0x0002
#define SFCPAD_SELECT	0x0004
#define SFCPAD_START	0x0008
#define SFCPAD_UP 	0x0010
#define SFCPAD_DOWN	0x0020
#define SFCPAD_LEFT	0x0040
#define SFCPAD_RIGHT	0x0080
#define SFCPAD_A_BTN	0x0100
#define SFCPAD_X_BTN	0x0200
#define SFCPAD_L_BTN	0x0400
#define SFCPAD_R_BTN	0x0800
 
uint16_t readsfcpad() {
	int i;
	uint16_t b;
	uint16_t d;
	uint8_t dataval;
 
		b = 1;
		d = 0;
        	dataval = 1;
		bcm2835_gpio_write(PIN_LATCH,LOW);
		usleep(250);
		for (i = 0;i < 16;i++ ){
			dataval = bcm2835_gpio_lev(PIN_DATA);
			//printf("dataval:%d \n",dataval);
			if ( dataval == 0 ) {
				d = d | b;
			}
			b = b<<1;
			bcm2835_gpio_write(PIN_CLOCK,HIGH);
			usleep(500);
			bcm2835_gpio_write(PIN_CLOCK,LOW);
		}	
		bcm2835_gpio_write(PIN_LATCH,HIGH);
	return d;
}
 
int main(int argc,char **argv)
{
	//GPIOを初期化
	if (!bcm2835_init()) { 
		printf("bcm2835 init error.\n");
		exit(1); 
	}
 
	//PINの設定
	bcm2835_gpio_fsel(PIN_DATA ,BCM2835_GPIO_FSEL_INPT);
	bcm2835_gpio_fsel(PIN_CLOCK,BCM2835_GPIO_FSEL_OUTP);
	bcm2835_gpio_fsel(PIN_LATCH,BCM2835_GPIO_FSEL_OUTP);
 
	//VCCまでプルアップ
	bcm2835_gpio_set_pud(PIN_DATA,BCM2835_GPIO_PUD_UP);
 
	//SFC_PAD との通信初期化
	bcm2835_gpio_write(PIN_CLOCK,LOW);
	bcm2835_gpio_write(PIN_LATCH,HIGH);
 
	uint16_t rd;
	while(1) {
		//ボタンの状態を読み、
		rd = readsfcpad();	
		if (rd != 0) {
			//ビット演算により、ボタンが押されているか
			if ( (rd & SFCPAD_B_BTN	) == SFCPAD_B_BTN)  { printf("B\n");   }
	                if ( (rd & SFCPAD_Y_BTN	) == SFCPAD_Y_BTN)  { printf("Y\n");   }
			if ( (rd & SFCPAD_SELECT) == SFCPAD_SELECT) { printf("Sel\n"); }
			if ( (rd & SFCPAD_START	) == SFCPAD_START)  { printf("Sta\n"); }
			if ( (rd & SFCPAD_UP 	) == SFCPAD_UP )    { printf("UP\n");  }
			if ( (rd & SFCPAD_DOWN	) == SFCPAD_DOWN)   { printf("Do\n");  }
			if ( (rd & SFCPAD_LEFT	) == SFCPAD_LEFT)   { printf("Le\n");  }
			if ( (rd & SFCPAD_RIGHT	) == SFCPAD_RIGHT)  { printf("Ri\n");  }
			if ( (rd & SFCPAD_A_BTN	) == SFCPAD_A_BTN)  { printf("A\n");   }
			if ( (rd & SFCPAD_X_BTN	) == SFCPAD_X_BTN)  { printf("X\n");   }
			if ( (rd & SFCPAD_L_BTN	) == SFCPAD_L_BTN)  { printf("L\n");   }
			if ( (rd & SFCPAD_R_BTN	) == SFCPAD_R_BTN)  { printf("R\n");   }
		}
	}
}

コメントはまだありません »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress