您的位置:首页 > 产品设计 > UI/UE

GBA multiBoot时的Arduino源代码~

2013-09-22 20:51 926 查看
//Description: The GBA connector pinouts are as follows:
//(Looing at GBA)
// __________________
// /_______________/
// |   /_ _ _ _ _ /|
// |  /2_/_4_/_6_//|
// |  ===========/ |
//  \ -1- -3- -5- /
//   \___/ / /___/
//       |/__|

//(Looking at cable)
//   _________________
//  /                 \
//  |  /          /\   |
//  | /__________/  \  |
//  |/___________\  /| |
//  /|_6_|_4_|_2_|\//  |
//  ||___/___/___||/   |
//  \|_5_|_3_|_1_|/___/
//   \____   ____/
//        ---

//Pin Numbers:
//1: V+ (3.3v)
//2: SO
//3: SI
//4: SD
//5: SC
//6: GND
#include
//default baud rate of gba is 115.2kbps
#define BAUDRATE16 115200
#define BAUDRATE32 256000//2097152//
#define BITTIME16 (F_CPU/BAUDRATE16) // 138ish clocks per bit @ 16mhz
#define BITTIME32 (F_CPU/BAUDRATE32)
#define HALFBITTIME16 BITTIME16 / 2
#define HALFBITTIME32 BITTIME32 / 2

#define GBA_DDR DDRB
#define GBA_OUT PORTB
#define GBA_IN PINB

#define SI 0    //Arduino pin 8 connect to SO on the GBA
#define SO 1    //Arduino Pin 9 connect to SI on the GBA
#define SD 2    //Arduino Pin 10 connect to SD on the GBA
#define SC 3    //Arduino Pin 11 connect to SC on the gba
#define LED 5   //Arduino Pin 13
inline void InitTmr32() {
OCR0A = BITTIME32;
TCCR0A = 1 << WGM00 | 1 << WGM01;
TCCR0B = 1 << WGM02 | 1 << CS00;
TIMSK0 = 0;
}
//Timer
inline void InitTmr16() {
OCR0A = BITTIME16;
TCCR0A = 1 << WGM00 | 1 << WGM01;
TCCR0B = 1 << WGM02 | 1 << CS00;
TIMSK0 = 0;
}
//reset the timer to 0 and clear the overflow flag
inline void ResetTmr() {
TCNT0 = 0;
bitSet(TIFR0, OCF0A);
}

//wait for the overflow flag to ge set then clear it
inline void WaitTmr() {
wait: if (!bitRead(TIFR0, OCF0A)) goto wait;
bitSet(TIFR0, OCF0A);
}

inline uint8_t getachar() {
wait: if (!Serial.available()) goto wait;
return Serial.read();
}

//
// GBA serial IO routines
//

inline void txData(uint8_t high, uint8_t low) {
GBA_DDR |= (1 << SD | 1 << SC); //configure SD and SC as output
bitSet(GBA_OUT, SO);            //tell the gba we're sending
ResetTmr();

GBA_OUT &= ~((1 << SD) | (1 << SC));    //Start bit
WaitTmr();    //wait 1 bit time (start bit)

for (int i = 0; i < 8; i++) {    //low byte
bitWrite(GBA_OUT, SD, bitRead(low,i));
WaitTmr();
}
for (int i = 0; i < 8; i++) {    //high byte
bitWrite(GBA_OUT, SD, bitRead(high,i));
WaitTmr();
}

bitSet(GBA_OUT, SD);    //stop bit
WaitTmr();
}

inline void rxData(uint8_t *high, uint8_t *low) {
bitClear(GBA_DDR, SD);
bitClear(GBA_OUT, SO); //tell the gba we're rxing
//wait for SD to go low
wait: if (GBA_IN & (1 << SD)) goto wait;

//wait until the middle of the start bit
ResetTmr();
TCNT0 = HALFBITTIME16;
WaitTmr();

//should be in the middle of the start bit
uint8_t start = 0;
bitWrite(start, 0, bitRead(GBA_IN,SD));
WaitTmr();

for (int i = 0; i < 8; i++) {    //low byte
bitWrite(*low, i, bitRead(GBA_IN,SD));
WaitTmr();
}
for (int i = 0; i < 8; i++) {    //high byte
bitWrite(*high, i, bitRead(GBA_IN,SD));
WaitTmr();
}

//stop bit
uint8_t stop = 0;
bitWrite(stop, 0, bitRead(GBA_IN,SD));
WaitTmr();

//done recieving
bitSet(GBA_OUT, SO);

delay(1);
bitSet(GBA_OUT, SC);
}

void xfer16(uint8_t *high, uint8_t *low) {
cli();
GBA_DDR |= (1 << SO) | (1 << SC);
GBA_OUT |= (1 << SO) | (1 << SC);
InitTmr16();
bitClear(GBA_OUT, LED);
txData(*high, *low);
rxData(high, low);
bitSet(GBA_OUT, LED);
sei();
}

void xfer32(uint32_t *data_) {
bitClear(GBA_OUT, LED);
uint32_t data = *data_;
cli();
GBA_DDR &= ~(1 << SI);
GBA_DDR |= (1 << SO) | (1 << SC);
InitTmr32();
// while (GBA_IN & (1 << SI))        ;
ResetTmr();
for (int i = 0; i < 32; i++) {
bitClear(GBA_OUT, SC);
bitWrite(GBA_OUT, SO, ((data >> 31) & 1));
WaitTmr();
bitSet(GBA_OUT, SC);

data <<= 1;
data |= bitRead(GBA_IN , SI);
WaitTmr();
}
*data_ = data;
sei();
bitSet(GBA_OUT, LED);
}

void setup() {
bitSet(GBA_DDR, LED);
Serial.begin(115200);
bitSet(GBA_OUT, LED);
}
//should just have to convert this to main to get it to build as plain c
void loop() {
uint8_t in = getachar();
switch (in) {
case 16: {
uint8_t datalow = getachar();
uint8_t datahigh = getachar();
xfer16(&datahigh, &datalow);
Serial.write(datalow);
Serial.write(datahigh);
break;
}
case 32: {
uint32_t a = getachar();
uint32_t b = getachar();
uint32_t c = getachar();
uint32_t d = getachar();
uint32_t data = a | (b << 8) | (c << 16) | (d << 24);
xfer32(&data);
Serial.write(data & 0xff);
Serial.write((data >> 8) & 0xff);
Serial.write((data >> 16) & 0xff);
Serial.write((data >> 24) & 0xff);
break;
}
case 8: {
Serial.write("Gba cable is Good.\n");
Serial.write("Arduino pin 8  PB0 connect to SO on the GBA\n");
Serial.write("Arduino Pin 9  PB1 connect to SI on the GBA\n");
Serial.write("Arduino Pin 10 PB2 connect to SD on the GBA\n");
Serial.write("Arduino Pin 11 PB3 connect to SC on the GBA\n");
Serial.write("Arduino Pin 13 PB5 is LED\n");
Serial.write("http://blog.csdn.net/eszeta");
break;
}
}
}

这个没啥好说的了,关键点都在其它的文档里提过了。。
由于要兼容两种通信协义,所以我是先用UART发个16再跟16位的数据对应该GBA的16位Multi-player模式,先把32再接32位数据对应该GBA的32位NORMAL模式。
而两种模式都是以Arduion为主机,GBA为从机。由于这两种都是同步通信所以只能PC端向GBA发数据的同时接收GBA的数据,不能GBA主动来发数据。
如果想用GBA跟PC通信,直接用GBA的UART模式吧。异步的,而且不用模拟。直接接PC的USB转TTL就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  GBA arduino