PS3 Charger Arduino

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;
   }
} 

This code contains a lot lowlevel programming, which can be incompatible between different controllers.
The code that you found is for Attiny mcu family:

so it is unlikely that it will run on Uno or Mega.

1 Like

Is it even possible to make a sketch for Arduino ?

If you know assembler - try to port attiny code to atmega mcu

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.