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就可以了。
相关文章推荐
- GBAmultiBoot时的Arduino端针脚控制的程序编写~
- GBA multiBoot时的AVR TIME设置~
- U-Boot源代码阅读笔记(二) —— 对lowlevel_init.S的分析
- 7.Spring Boot Mybatis Multi DataSource
- Arduino双舵机串口控制源代码
- [笔记]符合Multiboot Specification的内核
- MDNet(multi domain CNN用于视觉跟踪)--源代码详解--mdnet_features_fcX.m
- u-boot中SPL源代码分析
- U-Boot的移植之(二)进阶篇:从源代码看系统启动过程
- 通过分析mkbootimg源代码了解boot.img文件结构
- Linux0.11版源代码分析——boot/setup.s
- 【Arduino】开发入门【八】舵机操作+源代码
- 操作系统多重引导规范:Multiboot Specification 0.6.93(中文版)
- linux源代码----bootsect.s
- Arduino作为编程器读写BIOS、bootloader、uboot或者breed
- Linux0.11版源代码分析——boot/head.s
- 2017年山东省机器人比赛 双足竟步 arduino源代码(删去了关键步态程序 gongneng1 和 gongneng2)
- 使用Arduino和DS12C887芯片制作电子时钟(附Arduino源代码)
- GRUB multiboot
- U-Boot源代码阅读笔记(二) —— 对lowlevel_init.S的分析