Hey Guys,
i would like to load my PS3 Controller without PC und PS3, but the Controller need some of USB Protocol Handshake to load via AC Power Plug 5V 2A.
I have found this sketch on the Internet, how can i do this with my Arduino Nano, Uno or Mega?
/* ATTINY24 code to emulate enough of a USB host to get a PS3
controller to charge.
Copyright (c) 2010 Jim Paris <jim@jtan.com>
BSD license
*/
#include <avr/io.h>
FUSES =
{
.low = 0xff,
.high = 0xff & FUSE_RSTDISBL & FUSE_SPIEN & FUSE_BODLEVEL0,
.extended = 0xff & EFUSE_DEFAULT,
};
/* Connections:
D+ PA3
D- PA7
*/
#define MASK_DP (1 << 3)
#define MASK_DM (1 << 7)
#define MASK_BOTH (MASK_DP | MASK_DM)
#define MASK_NONE 0
#define MASK_OUT MASK_BOTH
#define MASK_IN MASK_NONE
#define FS_J MASK_DP
#define FS_K MASK_DM
#define SE0 0
#define J "out %[_porta], %[_j]\n"
#define K "out %[_porta], %[_k]\n"
#define X "out %[_porta], %[_x]\n"
#define IN "out %[_ddra], %[_in]\n"
#define OUT "out %[_ddra], %[_out]\n"
#define D "nop\n" // delay 1 bit time
#define asmblock(str) asm volatile (str \
: \
: [_porta] "I" (_SFR_IO_ADDR(PORTA)), \
[_ddra] "I" (_SFR_IO_ADDR(DDRA)), \
[_j] "r" (FS_J), \
[_k] "r" (FS_K), \
[_x] "r" (SE0), \
[_in] "r" (MASK_IN), \
[_out] "r" (MASK_OUT) \
: "memory")
/* wait for the next "ms" timer ticks, which occur at 1ms intervals */
void mwait(int ms)
{
static int initialized = 0;
if (!initialized) {
TIMSK1 = 0x00; /* no interrupts */
OCR1A = 12000 - 1; /* 12000 cycles = 1 ms */
TCCR1B = _BV(WGM12) | _BV(CS10); /* no prescale, CTC mode */
initialized = 1;
}
while (ms-- > 0) {
TIFR1 &= ~_BV(TOV1);
while((TIFR1 & _BV(TOV1)) == 0)
continue;
}
}
/* Send a bus reset */
static void send_reset(void)
{
/* SE0 for >= 10 ms */
PORTA = SE0;
DDRA = MASK_OUT;
mwait(10);
DDRA = MASK_IN;
}
/* Wait for next frame and send SOF.
Returns 0 if the device is not present. */
static int send_SOF(int count)
{
while (count--) {
mwait(1);
if ((PINA & MASK_BOTH) != FS_J)
return 0;
asmblock(
OUT
// send SOF 1337
K J K J K J K K K J J K J J K K K J K K K K J K K J J J J J J K X X J
IN
X
);
}
return 1;
}
/* Send SET_ADDRESS */
static void send_SET_ADDRESS(void)
{
asmblock(
OUT
// send SETUP
K J K J K J K K K J J J K K J K J K J K J K J K J K J K K J K J X X J
// delay a little
D D D D D D D D
// send DATA0
K J K J K J K K K K J K J K K K J K J K J K J K K J J K J K J K K J K
J K J K J K J K J K J K J K J K J K J K J K J K J K J K J K J K J K J
K J K J K J K J K J J J K K J J J J J K K J K K J K X X J
IN
X
// device will send ACK now (within 16 bit times)
);
// wait until new frame; an immediate IN will just get NAKed
send_SOF(1);
asmblock(
OUT
// send IN
K J K J K J K K K J K K J J J K J K J K J K J K J K J K K J K J X X J
// device will send DATA1 now.
IN
// delay for the expected 35 bits of data
X D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D
// wait 12 more bit times (16 is max turnaround)
D D D D D D D D D D D D
OUT
// send ACK
K J K J K J K K J J K J J K K K X X J
IN
X
);
}
/* Send SET_CONFIGURATION */
static void send_SET_CONFIGURATION(void)
{
asmblock(
OUT
// send SETUP
K J K J K J K K K J J J K K J K K J K J K J K J K J K K J J J J X X J
// delay a little
D D D D D D D D
// send DATA0
K J K J K J K K K K J K J K K K J K J K J K J K K J K K J K J K K J K
J K J K J K J K J K J K J K J K J K J K J K J K J K J K J K J K J K J
K J K J K J K J K J J J J K J J K J J K K J K K J K X X J
IN
X
// device will send ACK now (within 16 bit times)
);
// wait until new frame; an immediate IN will just get NAKed
send_SOF(1);
asmblock(
OUT
// send IN
K J K J K J K K K J K K J J J K K J K J K J K J K J K K J J J J X X J
// device will send DATA1 now.
IN
// delay for the expected 35 bits of data
X D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D D
// wait 12 more bit times (16 is max turnaround)
D D D D D D D D D D D D
OUT
// send ACK
K J K J K J K K J J K J J K K K X X J
IN
X
);
}
int main(void)
{
/* Tristate D+ and D- */
DDRA = MASK_IN;
PORTA = SE0;
mwait(100);
for (;;) {
/* if the device doesn't appear present, do nothing */
while ((PINA & MASK_BOTH) != FS_J) {
mwait(1);
}
// perform reset
mwait(100);
send_reset();
// perform basic enumeration
send_SOF(10);
send_SET_ADDRESS();
send_SOF(3);
send_SET_CONFIGURATION();
// now send empty frames as long as the device is present.
while (send_SOF(1))
continue;
}
}