first commit
This commit is contained in:
182
static/vibration.ino
Normal file
182
static/vibration.ino
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Nintendo 64 Controller to Arduino sketch
|
||||
* By Waffle (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?action=viewprofile;username=Waffle)
|
||||
* See this Arduino forum thread for info: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1261980415
|
||||
*
|
||||
* Connect N64 controller +3.3V line to Arduino 3.3V line
|
||||
* Connect N64 controller ground line to Arduino ground
|
||||
* Connect N64 controller data line to an Arduino I/O pin with a 1K pull-up resistor to 3.3V line
|
||||
*
|
||||
* Set Arduino pin used for data line in the follow three #defines:
|
||||
* Example for Arduino pin 9: N64_DATA_DDR = DDRB, N64_DATA_PIN = PINB, N64_DATA_PIN_NO = PINB1
|
||||
*/
|
||||
|
||||
#define N64_DATA_DDR DDRB
|
||||
#define N64_DATA_PIN PINB
|
||||
#define N64_DATA_PIN_NO PINB1
|
||||
|
||||
#include <util/delay.h>
|
||||
|
||||
/* based off the 'N64/Gamecube controller to USB adapter' by Raphaël Assénat (http://www.raphnet.net/electronique/gc_n64_usb/index_en.php)
|
||||
* modifications/improvements:
|
||||
* - adjusted timing for 16 MHz
|
||||
* - support writing variable length data
|
||||
* - receive variable length data directly packed into destination buffer
|
||||
*/
|
||||
uint8_t n64cmd(uint8_t rxdata[], uint8_t rxlen, uint8_t txdata[], uint8_t txlen) {
|
||||
uint8_t num = 0;
|
||||
uint8_t oldSREG = SREG;
|
||||
|
||||
cli();
|
||||
asm volatile(
|
||||
"nextByte%=: \n"
|
||||
" cpi %[txlen], 0 \n" // 1
|
||||
" breq done%= \n" // 1
|
||||
" dec %[txlen] \n" // 1
|
||||
" ld r16, z+ \n" // 2
|
||||
" ldi r17, 0x80 \n" // 1
|
||||
"nextBit%=: \n"
|
||||
" mov r18, r16 \n" // 1
|
||||
" and r18, r17 \n" // 1
|
||||
" breq send0%= \n" // 2
|
||||
" nop \n"
|
||||
|
||||
// 1us low, 1us high
|
||||
"send1%=: \n"
|
||||
" sbi %[ddr], %[pinNo] \n" // 2
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop \n" // 2
|
||||
" cbi %[ddr], %[pinNo] \n" // 2
|
||||
" ldi r19, 11 \n" // 1
|
||||
"lp1%=: dec r19 \n" // 1
|
||||
" brne lp1%= \n" // 2
|
||||
" lsr r17 \n" // 1
|
||||
" breq nextByte%= \n" // 1
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop \n" // 1
|
||||
" rjmp nextBit%= \n" // 2
|
||||
|
||||
// 3us low, 1us high
|
||||
"send0%=: sbi %[ddr], %[pinNo] \n" // 2
|
||||
" ldi r19, 15 \n" // 1
|
||||
"lp0%=: dec r19 \n" // 1
|
||||
" brne lp0%= \n" // 2
|
||||
" nop \n" // 1
|
||||
" cbi %[ddr], %[pinNo] \n" // 2
|
||||
" nop \n" // 1
|
||||
" lsr r17 \n" // 1
|
||||
" breq nextByte%= \n" // 1
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop \n" // 1
|
||||
" rjmp nextBit%= \n" // 2
|
||||
|
||||
// finished sending, sync up to the stop bit time
|
||||
"done%=: \n"
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop\nnop \n" // 3
|
||||
|
||||
// stop bit
|
||||
" sbi %[ddr], %[pinNo] \n" // 2
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop \n" // 2
|
||||
" cbi %[ddr], %[pinNo] \n"
|
||||
|
||||
// stop now if there's nothing to receive
|
||||
" cpi %[rxlen], 0 \n" // 1
|
||||
" breq end%= \n" // 1
|
||||
|
||||
// receiving
|
||||
" clr r18 \n" // 1 current byte
|
||||
" ldi r17, 0x80 \n" // 1 current bit
|
||||
"st%=: \n"
|
||||
" ldi r16, 0xff \n" // 1 setup timeout
|
||||
"waitFall%=: \n"
|
||||
" dec r16 \n" // 1
|
||||
" breq end%= \n" // 1
|
||||
" sbic %[pin], %[pinNo] \n" // 2
|
||||
" rjmp waitFall%= \n"
|
||||
|
||||
// wait about 2us to check the state
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
" nop\nnop\nnop\nnop \n" // 4
|
||||
|
||||
" sbic %[pin], %[pinNo] \n" // 2
|
||||
" or r18, r17 \n"
|
||||
" lsr r17 \n" // 1
|
||||
" brne nextRxBit%= \n" // 2
|
||||
|
||||
"nextRxByte%=: \n"
|
||||
" st x+, r18 \n" // 2 store the value
|
||||
" inc %[num] \n" // 1 increase number of received bytes
|
||||
" cp %[rxlen], %[num] \n" // 1 check for finish
|
||||
" breq end%= \n" // 1
|
||||
" clr r18 \n" // 1
|
||||
" ldi r17, 0x80 \n" // 1
|
||||
|
||||
"nextRxBit%=: \n"
|
||||
" ldi r16, 0xff \n" // 1 setup timeout
|
||||
"waitHigh%=: \n"
|
||||
" dec r16 \n" // 1 decrement timeout
|
||||
" breq end%= \n" // 1 handle timeout condition
|
||||
" sbis %[pin], %[pinNo] \n" // 2
|
||||
" rjmp waitHigh%= \n"
|
||||
" rjmp st%= \n" // 2
|
||||
|
||||
"end%=: \n"
|
||||
: [num] "=r"(num)
|
||||
: [ddr] "I"(_SFR_IO_ADDR(N64_DATA_DDR)), [pin] "I"(_SFR_IO_ADDR(N64_DATA_PIN)), [pinNo] "I"(N64_DATA_PIN_NO),
|
||||
[rxdata] "x"(rxdata), [rxlen] "r"(rxlen),
|
||||
[txdata] "z"(txdata), [txlen] "r"(txlen), "0"(num)
|
||||
: "r16", "r17", "r18", "r19"
|
||||
);
|
||||
SREG = oldSREG;
|
||||
|
||||
_delay_us(100); // some commands leave the controller unresponsive for a while
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
uint8_t command[40];
|
||||
uint8_t result[40];
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
command[0] = 0x00;
|
||||
n64cmd(result, 3, command, 1);
|
||||
// logiquement, faudrait faire des vrais vérifs là maintenant, genre est-ce que le kit vibration est branché, etc…
|
||||
// initialisation du rumble pak
|
||||
command[0] = 0x03;
|
||||
command[1] = 0x80;
|
||||
command[2] = 0x01;
|
||||
memset(command + 3, 0x80, 32);
|
||||
n64cmd(result, 1, command, 35);
|
||||
Serial.println(result[0], HEX);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// vibration activée
|
||||
command[0] = 0x03;
|
||||
command[1] = 0xC0;
|
||||
command[2] = 0x1B;
|
||||
memset(command + 3, 0x01, 32);
|
||||
|
||||
n64cmd(result, 1, command, 35);
|
||||
|
||||
delay(1000);
|
||||
|
||||
// vibration désactivée
|
||||
memset(command + 3, 0x00, 32);
|
||||
|
||||
n64cmd(result, 1, command, 35);
|
||||
|
||||
delay(1000);
|
||||
}
|
Reference in New Issue
Block a user