elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


 


Tema destacado: Introducción a la Factorización De Semiprimos (RSA)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Quiero controlar el DexDrive
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Quiero controlar el DexDrive  (Leído 2,103 veces)
Meta


Desconectado Desconectado

Mensajes: 3.203



Ver Perfil WWW
Quiero controlar el DexDrive
« en: 23 Diciembre 2015, 12:48 »

Hola:

Antes que nada, disculpen si esto no va aquí. Llevo un tiempo averguando como se controla el famoso y popular de la época de piedra el DexDrive con Visual Studio. Es un dispositivo que lee y guarda los datos de la Memory Card de la PlayStation 1 en el PC por puerto serie, lo que se usaba mucho en la época de antes.



Lo he desarmado.



Tiene un Led verde, cuando envia o recibe datos, se cambia a naranja, todo esto con el puerto COM1. Si no ejecutas su aplicación llamado DeXplorer 2.0.920, no funciona nada aunque lo tengas alimentado, me refiero el Led. Sospecho que usa RTS, CTS, DTR, etc. A parte de los Rx, Tx y GND.

Aquí encontré una aplicación o código fuente que no entiendo ni papa y quiero adaptarlo a Visual C#, más bien hacer una interfaz como el DexPlorer, al menos más moderno. Lo curioso que DeXplorer sabe cuando está conectado el dispositivo DexDrive, si tiene la Memory Card insertada o no.

Tal vez aquí me indique como hacerlo.
https://github.com/fbriere/linux-dexdrive/blob/master/protocol.txt

Esos códigos quiero de C, que por eso lo he puesto aquí, pasarlo a Visual C#. El diseño lo tengo hecho, solo el diseño, no la programación.

He intentado hacer caso esta parte en Visual C#.
Citar
COMMANDS
--------

  For all commands specifying a (16-bit) frame number, <lsb> and <msb> are,
  respectively, its least and most significant bytes.  Make sure to pay close
  attention to the order, as it varies between commands.

  Note that the Nintendo 64 DexDrive will get stuck if it is sent an
  incomplete command.  At that point, the only solution is to unplug it
  completely, and plug it back (power first, then serial).

0x00  INIT

  Args: <17 bytes>
  Reply: ID

  Initializes the DexDrive; see the POUTING section below.

  The contents of the 17 bytes does not appear to have any significance,
  except for determining the contents of the "weird" byte in the ID reply.
  See the WEIRD FORMULA section below for more details.

  InterAct's DexPlorer software uses the following hard-coded string:

     10 29 23 be 84 e1 6c d6 ae 52 90 49 f1 f1 bb e9 eb

Enviar esos 17 bytes pero no pasa nada.

Código:
       private void button6_Click(object sender, EventArgs e)
        {
            byte[] mBuffer = new byte[17];
            mBuffer[0] = 0x10;
            mBuffer[1] = 0x29;
            mBuffer[2] = 0x23;
            mBuffer[3] = 0xBE;
            mBuffer[4] = 0x84;
            mBuffer[5] = 0xE1;
            mBuffer[6] = 0x6C;
            mBuffer[7] = 0xD6;
            mBuffer[8] = 0xAE;
            mBuffer[9] = 0x52;
            mBuffer[10] = 0x90;
            mBuffer[11] = 0x49;
            mBuffer[12] = 0xF1;
            mBuffer[13] = 0xF1;
            mBuffer[14] = 0xBB;
            mBuffer[15] = 0xE9;
            mBuffer[16] = 0xEB;
            serialPort1.Write(mBuffer, 0, mBuffer.Length);
        }

Ni una respuesta. Creo y no estoy seguro, que los baudios son 38400.

Boceto que hice con Visual C#,sin programarlo aún.


Saludos.


« Última modificación: 23 Diciembre 2015, 13:51 por Meta » En línea

Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/
MAFUS


Desconectado Desconectado

Mensajes: 1.478



Ver Perfil
Re: Quiero controlar el DexDrive
« Respuesta #1 en: 23 Diciembre 2015, 15:56 »

Muy buenas.

Leyendo el txt que adjuntas veo que te has saltado varias cosas.
Cito:
Every command or reply is prefixed with the string "IAI" (0x49 0x41 0x49)
(possibly standing for "InterAct Accessories, Inc.").  A single byte follows,
indicating which command or reply is being sent.


Eso indica que antes de mandar los 17 bytes debes incluir IAI y después un byte con el número de función que vas a llamar, en este caso 00. Con lo que tu lista de bytes quedaría de esta forma

0x49 0x41 0x49 0x00 0x10 0x29 0x23 0xbe 0x84 0xe1 0x6c 0xd6 0xae 0x52 0x90 0x49 0xf1 0xf1 0xbb 0xe9 0xeb

Después de haber mandado esto DexDrive te va a mandar su ID. Desde que recibes esta tienes 100ms para mandar un magic handshake, como te indica el texto en la sección POUTING. Después, como indica la sección MAGIC HANDSHAKE, el firmware para PSX te responderá con un error, mientras que el firmware N64 no responderá nada.

Sobre la configuración del puerto. Cito:
The serial connection with the DexDrive is established at 38400 baud, 8 bits,
no parity, one stop bit (8N1).


Lo único que se desconoce es si usa RTS/CTS: Se dice que habilita estas lineas pero no está claro si las usa o cuando las usa.

Espero haberte ayudado.


« Última modificación: 23 Diciembre 2015, 16:09 por MAFUS » En línea

while(is_alive(yourself)) {
    make_true(yourself, yourdreams);
}
Meta


Desconectado Desconectado

Mensajes: 3.203



Ver Perfil WWW
Re: Quiero controlar el DexDrive
« Respuesta #2 en: 24 Diciembre 2015, 00:16 »

Hola:

Eso me pasa porque estoy usando el traductor de google ya que no se Inglés, gracias por la aclaración. creí que el IAI es lo que te devuelve, me devolvía solo esto y a veces, "?", un interrogación y sin dobles comillas. Por lo que veo, entregar un total de 21 bytes. Siguiendo con las pruebas, el código par entragar esas tramas de bytes es esta.
Código
  1.        private void button6_Click(object sender, EventArgs e)
  2.        {
  3.            byte[] mBuffer = new byte[21];
  4.            mBuffer[0] = 0x49;
  5.            mBuffer[1] = 0x41;
  6.            mBuffer[2] = 0x49;
  7.            mBuffer[3] = 0x00;
  8.            mBuffer[4] = 0x10;
  9.            mBuffer[5] = 0x29;
  10.            mBuffer[6] = 0x23;
  11.            mBuffer[7] = 0xBE;
  12.            mBuffer[8] = 0x84;
  13.            mBuffer[9] = 0xE1;
  14.            mBuffer[10] = 0x6C;
  15.            mBuffer[11] = 0xD6;
  16.            mBuffer[12] = 0xAE;
  17.            mBuffer[13] = 0x52;
  18.            mBuffer[14] = 0x90;
  19.            mBuffer[15] = 0x49;
  20.            mBuffer[16] = 0xF1;
  21.            mBuffer[17] = 0xF1;
  22.            mBuffer[18] = 0xBB;
  23.            mBuffer[19] = 0xE9;
  24.            mBuffer[20] = 0xEB;
  25.            serialPort1.Write(mBuffer, 0, mBuffer.Length);
  26.        }
  27.    }

No devuelve nada y no hace nada. Antes me devolvía ? y a veces.

Configuración del HyperTerminal.


Desde que pulse cualquier letra del teclado, me devuelve IAI como puedes ver abajo. Por eso creí que no hay que enviarlo todo junto.


¿Relamente hay que usar IAI como indicas y luego el 0x00?

Me da que el DRT y DTS también se usa y lo he puesto en true por si acaso.


Dicen que se puede hacer trampa si los une físicamente.

http://www.moxa.com/resource_file/509820091121333.pdf

Lo quiero hacer sin usar trampas.

Por saber.
1) ¿Dónde sacas que me va a enviar su ID?
2) ¿Cómo puedo saber esa ID?

Parece ser que debo interpretar bien el protocolo de este enlace.

Cualquier apoyo en bienvenido, haber si sacamos una respuesta.

El comportamiento desde que ejecute el DeXplorer con el puerto COM1, parece que que comprueba si está el DexDrive conectado y la Memory Card si está insertada o no con el Led naranja, luego al tiempo se pone verde si no hace nada. Cualquier comando que envíes se pone naranja.

Por lo que haz contado arriba, hay que enviarle 100 ms a magic handshake. Me explicas mejor si es posible lo del magic handshake, aún no lo capto. ;(

Tendré que suar en el Visual C# (más adleante usaré Visual Basic .net para tenerlo también para los demás que le interese) un timer.

Saludos.
En línea

Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/
MAFUS


Desconectado Desconectado

Mensajes: 1.478



Ver Perfil
Re: Quiero controlar el DexDrive
« Respuesta #3 en: 24 Diciembre 2015, 02:09 »

Muy buenas.

Sobre la cadena IAI en toda comunicación el texto dice:

Citar
A cada comando o respuesta le antecede la cadena "IAI" (0x49 0x41 0x49) [...]. Un solo byte las sigue, indicando qué comando o respuesta se está enviando. Pueden seguirle mas bytes, dependiendo del comando o la respuesta exacta; la naturaleza de estos argumentos está listada más abajo por cada comando o respuesta.

Así que según esto toda comunicación, tanto por tu parte, como por el DexDrive tendrá la forma
0x49 0x41 0x49 <byte de comando/respuesta> [<bytes de argumentos>]

El texto dice:
Citar
Cuando un DexDrive se energiza por primera vez, se encuentra en un estado que yo llamo "pouting", y básicamente rechaza realizar cualquier cosa hasta que no se haya inicializado. Cualquier comando válido, a parte de INIT, será respondido mediante POUT, y no sucederá nada.

(El modelo PSX continuará rechazando comandos inválidos con ERROR, mientras el modelo N64, contestará con POUT a todo menos a INIT, siempre y cuando se lleve el prefijo "IAI".)

La para inicializar DexDrive, hay que mandar el comando INIT, seguido por un MAGIC_HANDSHAKE en los subsiguientes 100ms (aprox.) después de recibir la respuesta ID.

Sobre la respuesta de INIT y el ID:
Citar
0x00    INIT

    Argumentos: <17 bytes>
    Respuesta: ID

[...]

0x40    ID

    Argumentos: <byte extraño> <3-bytes modelo> <versión de firmware>

    Identifica el modelo de DexDrive en respuesta a INIT.

    <byte extraño> está derivado de la cadena de 17 bytes mandada con INIT; ver fórmula extraña de mas abajo para mas detalles.

    La cadena 3-bytes modelo es "PSX" o "N64".

    <versión firmware> es la versión firmware x.yz empaquetada en un simple byte de la forma: xxyyyyzz

Sobre la fórmula extraña da el proceso de cómo calcularla, pero hay que tener en cuenta que es algo que hace DexDrive. Por tu parte el sacarla solo te serviría como comprobación. Pero viendo lo que dice el texto el algo que te puedes ahorrar. El texto dice:
Citar
No tengo ni idea de porqué es tan complejo, especialmente por el hecho de que no conduce a ningún sitio. InterAct's DexPlorer no rechazará comunicarse con ningún dispositivo que no produzca el byte esperado, aunque si siempre se envía la misma cadena de 17 bytes, ¿cuál es la idea?. [...]

Básicamente te basta recoger de qué modelo se trata, si PSX o N64, alguna función responde de una forma según el modelo.

Si no sabes inglés te será difícil que puedas crear el programa. Los traductores informáticos no dan buenos resultados a la hora de traducir este texto.

Espero haberte ayudado.
« Última modificación: 24 Diciembre 2015, 02:21 por MAFUS » En línea

while(is_alive(yourself)) {
    make_true(yourself, yourdreams);
}
Meta


Desconectado Desconectado

Mensajes: 3.203



Ver Perfil WWW
Re: Quiero controlar el DexDrive
« Respuesta #4 en: 24 Diciembre 2015, 05:11 »

Hola campeón:

En mi caso el que tengo y uso es el de PSx. En el futuro por ebay, todavía, al menos eso dicen, se puede conseguir de paquete para la N64, cuando tenga algún éxito el de PSx, compraré sea como sea el de la N64.

Quiero sejar claro algunos aspectos del puerto serie como indica en la imagen de abajo. Este está hecho con Visual C#, l a mayoría viene por defecto.


Lo comento porque son detalles que no coinside con el que trae por defecto el serialPort1. Por ejemplo, viendo este código.
Código
  1. /* Timeout (in msecs) when waiting for the device to reply */
  2. #define DEX_TIMEOUT 200

En este otro código, también te habla del timeout y más datos.
Código
  1. #define DEX_NAME "dexdrive" /* Driver name */
  2. #define DEX_BUFSIZE 261 /* Size of input/output buffer */
  3. #define DEX_TIMEOUT 100 /* Timeout in msecs when waiting */
  4. #define DEX_MAX_RETRY 2 /* Maximum number of retries */
  5. #define DEX_MAX_DEVICES 4 /* Maximum number of devices */

Si ves algo que no me he enterado o se me ha escapado, me avisas, aquí en estos códigos parece que le han puesto nombres diferentes y se me escapa muchas cosas, quiero ponerlo idéntico los valores por si acaso. Como dice arribas antes, se cambia aquí.

Aquí nombra el IAI y demás.
Código
  1. /* Prefix sent with all commands/replies */
  2. #define DEX_CMD_PREFIX "IAI"
  3.  
  4. /* Default init string used by InterAct's software */
  5. #define DEX_INIT_STR "\x10\x29\x23\xbe\x84\xe1\x6c\xd6\xae\x52" \
  6. "\x90\x49\xf1\xf1\xbb\xe9\xeb"


Estoy ansioso de ver el Led verde encendido del DexDrive. Desde que ejecutes el DeXplorer, se enciende naranja que está comprobado todo, luego se pone verde, desde que cierre el DeXplorer, deja de funcionar el DexDrive y se apaga el Led. Con las pruebas que estoy haciendo, aún no pasa nada.

Con el Visual C#, en el evento Load, es decir, nada más cargar el formulario, hace comprobaciones, si está conectado DexDrive, si hay alguna Memory Card insertada, si la hay, lee los datos y lo muestra en pantalla, concretamente en ListBox parece ser.

Fijarse mucho en la tabla ASCII. Mejor ver imagen aquí que muestra los valores en hexadecimales.



Este es el código que todavía no sirve en Visual C#.
Código
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10.  
  11. using System.IO.Ports; // No olvidar.
  12.  
  13. namespace DexPlorer
  14. {
  15.    public partial class Form1 : Form
  16.    {
  17.        // Utilizaremos un string como buffer de recepci&#243;n.
  18.        string Recibidos;
  19.  
  20.        public Form1()
  21.        {
  22.            InitializeComponent();
  23.  
  24.            // Puerto abierto desde que arranca la aplicaci&#243;n.
  25.            if (!serialPort1.IsOpen)
  26.            {
  27.                try
  28.                {
  29.                    serialPort1.Open();
  30.                }
  31.                catch (System.Exception ex)
  32.                {
  33.                    MessageBox.Show(ex.ToString());
  34.                }
  35.            }
  36.            serialPort1.DataReceived += new SerialDataReceivedEventHandler(Recepcion);
  37.        }
  38.  
  39.        // Al recibir datos.
  40.        private void Recepcion(object sender, SerialDataReceivedEventArgs e)
  41.        {
  42.            // Acumula los caracteres recibidos a nuestro 'buffer' (string).
  43.            Recibidos += serialPort1.ReadExisting();
  44.  
  45.            // Invocar o llamar al proceso de tramas.
  46.            Invoke(new EventHandler(Actualizar));
  47.  
  48.            //Invoke(new EventHandler(IniciarTimer));
  49.        }
  50.  
  51.        // Procesar los datos recibidos en el bufer y extraer tramas completas.
  52.        private void Actualizar(object sender, EventArgs e)
  53.        {
  54.            // Para ver lo que env&#237;a desde el DexDrive hacia esta interfaz de C#.
  55.            // Asignar el valor de la trama al richTextBox.
  56.            richTextBox1.Text = Recibidos;
  57.  
  58.            // Selecciona la posici&#243;n final para leer los mensajes entrantes.
  59.            richTextBox1.SelectionStart = richTextBox1.Text.Length;
  60.  
  61.            // Mantiene el scroll en la entrada de cada mensaje.
  62.            richTextBox1.ScrollToCaret();
  63.  
  64.  
  65.            switch (Recibidos)
  66.            {
  67.                // Aqu&#237; hay que ejecutar los case cada vez que DexDrive env&#237;a
  68.                // los datos.
  69.  
  70.            }
  71.        }
  72.  
  73.        private void Form1_Load(object sender, EventArgs e)
  74.        {
  75.            byte[] mBuffer = new byte[21];
  76.            // El famoso IAI.
  77.            mBuffer[0] = 0x49; // I en ASCII.
  78.            mBuffer[1] = 0x41; // A.
  79.            mBuffer[2] = 0x49; // I.
  80.  
  81.            // El comando INIT de inicio.
  82.            mBuffer[3] = 0x00; // 0.
  83.  
  84.            // Caract&#233;res extra&#241;os.
  85.            mBuffer[4] = 0x10; // DLE.
  86.            mBuffer[5] = 0x29; // ).
  87.            mBuffer[6] = 0x23; // #.
  88.            mBuffer[7] = 0xBE; // &#165;.
  89.            mBuffer[8] = 0x84; // &#228;.
  90.            mBuffer[9] = 0xE1; // &#223;.
  91.            mBuffer[10] = 0x6C; // l.
  92.            mBuffer[11] = 0xD6; // &#205;.
  93.            mBuffer[12] = 0xAE; // &#171;.
  94.            mBuffer[13] = 0x52; // R.
  95.            mBuffer[14] = 0x90; // &#201;.
  96.            mBuffer[15] = 0x49; // I.
  97.            mBuffer[16] = 0xF1; // &#177;.
  98.            mBuffer[17] = 0xF1; // &#177;.
  99.            mBuffer[18] = 0xBB; // &#9559;.
  100.            mBuffer[19] = 0xE9; // &#218;.
  101.            mBuffer[20] = 0xEB; // &#217;.
  102.            serialPort1.Write(mBuffer, 0, mBuffer.Length);
  103.  
  104.            // Activa el timer para enviar el MAGIC_HANDSHAKE.
  105.            timer1.Enabled = true;
  106.            // timer1.Start(); // Tambi&#233;n v&#225;lido para activar el timer1.
  107.        }
  108.  
  109.        private void timer1_Tick(object sender, EventArgs e)
  110.        {
  111.            // Env&#237;a MAGIC_HANDSHAKE
  112.            byte[] mBuffer = new byte[1];
  113.  
  114.            // Comando MAGIC_HANDSHAKE.
  115.            mBuffer[0] = 0x27; // '.
  116.            serialPort1.Write(mBuffer, 0, 1); // Env&#237;a el byte.
  117.            timer1.Enabled = false; // Detiene el timer1 de 100 ms el intervalo.
  118.            // timer1.Stop();
  119.        }
  120.    }
  121. }
  122.  

En la parte final, se le puede poner esto así para tener más precisión, es decir, la cantidad de byte completo porque se cuanto es. Por ahora lo dejo indicado arriba.
Código
  1. serialPort1.Write(mBuffer, 0, 21);

Estoy ahora en la parte, leyendo bien lo que has escrito arriba de recibir datos directo del DexDrive, dejo claro que la versión o Firmware de mi DexDrive es el mismo que el creador del código de Linux.



En resumen, puede que me equivoque. Envío esta trama de bytes todo junto.
IAI (0x49 0x41 0x49) + INIT (0x00) + caractéres raros que son  (0x10 0x29 0x23 0xbe 0x84 0xe1 0x6c 0xd6 0xae 0x52 0x90 0x49 0xf1 0xf1 0xbb 0xe9 0xeb) + MAGIC_HANDSHAKE (0x27)

Recibo en el chivato richTextBox esto: ?IAI!

Espero haberte ayudado.

Y tanto que me has y estás ayudando. Encantado y agradecido estoy, ya que tienes las cosas claras y aportas mucho para seguir adelante. ;)

Un cordial saludo.
« Última modificación: 24 Diciembre 2015, 10:46 por Meta » En línea

Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/
MAFUS


Desconectado Desconectado

Mensajes: 1.478



Ver Perfil
Re: Quiero controlar el DexDrive
« Respuesta #5 en: 24 Diciembre 2015, 14:28 »

Muy buenas.

Buscando un poco porqué el DexDrive terespondía IAI!, que no parece ser una respuesta ID válida después de INIT, me he encontrado con un código en C# que se comunica con DexDrive. Mirándolo un poco por encima se ve que hay que hacer más cosas que las explicadas en el manual que adjuntaste.

Aquí tienes:
https://github.com/ShendoXT/memcardrex/blob/master/MemcardRex/DexDrive.cs
En línea

while(is_alive(yourself)) {
    make_true(yourself, yourdreams);
}
Meta


Desconectado Desconectado

Mensajes: 3.203



Ver Perfil WWW
Re: Quiero controlar el DexDrive
« Respuesta #6 en: 24 Diciembre 2015, 14:45 »

Hola:

Que casualidad. He encontrado esa página hace minutos y lo iba a publucar, ejjeje. Gracias de todas maneras. ;)

He estado mirando el código por el aire, por lo poco que he visto, tiene muchas funciones que no me interesa, como cambiar el icono, añadir si es de Europa o Japón o de E.E.U.U. Solo me interesa que sea similar y lo justo al DeXplorer 2.0 si es posible.

Concretamente mirando el código de la clase DexDrive.cs.

Código
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO.Ports;
  5. using System.Threading;
  6.  
  7. namespace DexDriveCommunication
  8. {
  9.    class DexDrive
  10.    {
  11.        enum DexCommands { INIT = 0x00, STATUS = 0x01, READ = 0x02, WRITE = 0x04, LIGHT = 0x07, MAGIC_HANDSHAKE = 0x27 };
  12.        enum DexResponses { POUT = 0x20, ERROR = 0x21, NOCARD = 0x22, CARD = 0x23, WRITE_OK = 0x28, WRITE_SAME = 0x29, WAIT = 0x2A, ID = 0x40, DATA = 0x41 };
  13.  
  14.        //DexDrive communication port
  15.        SerialPort OpenedPort = null;
  16.  
  17.        //Contains a firmware version of a detected device
  18.        string FirmwareVersion = null;
  19.  
  20.        //Init DexDrive (string returned if an error happened)
  21.        public string StartDexDrive(string ComPortName)
  22.        {
  23.            //Define a port to open
  24.            OpenedPort = new SerialPort(ComPortName, 38400, Parity.None, 8, StopBits.One);
  25.            OpenedPort.ReadBufferSize = 256;
  26.  
  27.            //Buffer for storing read data from the DexDrive
  28.            byte[] ReadData = null;
  29.  
  30.            //Try to open a selected port (in case of an error return a descriptive string)
  31.            try { OpenedPort.Open(); }
  32.            catch (Exception e) { return e.Message; }
  33.  
  34.            //Dexdrive won't respond if RTS is not toggled on/off
  35.            OpenedPort.RtsEnable = false;
  36.            Thread.Sleep(300);
  37.            OpenedPort.RtsEnable = true;
  38.            Thread.Sleep(300);
  39.  
  40.            //DTR line is used for additional power
  41.            OpenedPort.DtrEnable = true;
  42.  
  43.            //Check if DexDrive is attached to the port
  44.            //Detection may fail 1st or 2nd time, so the command is sent 5 times
  45.            for (int i = 0; i < 5; i++)
  46.            {
  47.                OpenedPort.DiscardInBuffer();
  48.                OpenedPort.Write("XXXXX");
  49.                Thread.Sleep(20);
  50.            }
  51.  
  52.            //Check for "IAI" string
  53.            ReadData = ReadDataFromPort();
  54.            if (ReadData[0] != 0x49 || ReadData[1] != 0x41 || ReadData[2] != 0x49) return "DexDrive was not detected on '" + ComPortName + "' port.";
  55.  
  56.            //Wake DexDrive up (kick it from POUT mode)
  57.            SendDataToPort((byte)DexCommands.INIT, new byte[] { 0x10, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA, 0xBB, 0xCC, 0xDD }, 50);
  58.            //SendDataToPort((byte)DexCommands.INIT, new byte[] { 0x10, 0x29, 0x23, 0xbe, 0x84, 0xe1, 0x6c, 0xd6, 0xae, 0x52, 0x90, 0x49, 0xf1, 0xf1, 0xbb, 0xe9, 0xeb }, 50);
  59.  
  60.            //Check for "PSX" string
  61.            ReadData = ReadDataFromPort();
  62.            if (ReadData[5] != 0x50 || ReadData[6] != 0x53 || ReadData[7] != 0x58) return "Detected device is not a PS1 DexDrive.";
  63.  
  64.            //Fetch the firmware version
  65.            FirmwareVersion = (ReadData[8] >> 6).ToString() + "." + ((ReadData[8] >> 2) & 0xF).ToString() + (ReadData[8] & 0x3).ToString();
  66.  
  67.            //Send magic handshake signal 10 times
  68.            for (int i = 0; i < 10; i++) SendDataToPort((byte)DexCommands.MAGIC_HANDSHAKE, null, 0);
  69.            Thread.Sleep(50);
  70.  
  71.            //Turn on the status light
  72.            SendDataToPort((byte)DexCommands.LIGHT, new byte[] { 1 }, 50);
  73.  
  74.            //Everything went well, DexDrive is ready to recieve commands
  75.            return null;
  76.        }
  77.  
  78.        //Cleanly stop working with DexDrive
  79.        public void StopDexDrive()
  80.        {
  81.            if (OpenedPort.IsOpen == true) OpenedPort.Close();
  82.        }
  83.  
  84.        //Get the firmware version of a DexDrive
  85.        public string GetFirmwareVersion()
  86.        {
  87.            return FirmwareVersion;
  88.        }
  89.  
  90.        //Send DexDrive command on the opened COM port with a delay
  91.        private void SendDataToPort(byte Command, byte[] Data, int Delay)
  92.        {
  93.            //Clear everything in the input buffer
  94.            OpenedPort.DiscardInBuffer();
  95.  
  96.            //Every command must begin with "IAI" string
  97.            OpenedPort.Write("IAI" + (char)Command);
  98.            if (Data != null) OpenedPort.Write(Data, 0, Data.Length);
  99.  
  100.            //Wait for a required timeframe (for the DexDrive response)
  101.            if (Delay > 0) Thread.Sleep(Delay);
  102.        }
  103.  
  104.        //Catch the response from a DexDrive
  105.        private byte[] ReadDataFromPort()
  106.        {
  107.            //Buffer for reading data
  108.            byte[] InputStream = new byte[256];
  109.  
  110.            //Read data from DexDrive
  111.            if(OpenedPort.BytesToRead != 0)OpenedPort.Read(InputStream, 0, 256);
  112.  
  113.            return InputStream;
  114.        }
  115.  
  116.        //Read a specified frame of a Memory Card
  117.        public byte[] ReadMemoryCardFrame(ushort FrameNumber)
  118.        {
  119.            //Buffer for storing read data from the DexDrive
  120.            byte[] ReadData = null;
  121.  
  122.            //128 byte frame data from a Memory Card
  123.            byte[] ReturnDataBuffer = new byte[128];
  124.  
  125.            int DelayCounter = 0;
  126.  
  127.            byte FrameLsb = (byte)(FrameNumber & 0xFF);     //Least significant byte
  128.            byte FrameMsb = (byte)(FrameNumber >> 8);       //Most significant byte
  129.            byte XorData = (byte)(FrameLsb ^ FrameMsb);     //XOR variable for consistency checking
  130.  
  131.            //Read a frame from the Memory Card
  132.            SendDataToPort((byte)DexCommands.READ, new byte[] { FrameLsb, FrameMsb }, 0);
  133.  
  134.            //Wait for the buffer to fill
  135.            while (OpenedPort.BytesToRead < 133 && DelayCounter < 16)
  136.            {
  137.                Thread.Sleep(5);
  138.                DelayCounter++;
  139.            }
  140.  
  141.            //Read Memory Card data
  142.            ReadData = ReadDataFromPort();
  143.  
  144.            //Copy received data (filter IAI prefix)
  145.            Array.Copy(ReadData, 4, ReturnDataBuffer, 0, 128);
  146.  
  147.            //Calculate XOR checksum
  148.            for (int i = 0; i < 128; i++)
  149.            {
  150.                XorData ^= ReturnDataBuffer[i];
  151.            }
  152.  
  153.            //Return null if there is a checksum missmatch
  154.            if (XorData != ReadData[132]) return null;
  155.  
  156.            //Return read data
  157.            return ReturnDataBuffer;
  158.        }
  159.  
  160.        //Write a specified frame to a Memory Card
  161.        public bool WriteMemoryCardFrame(ushort FrameNumber, byte[] FrameData)
  162.        {
  163.            //Buffer for storing read data from the DexDrive
  164.            byte[] ReadData = null;
  165.  
  166.            byte FrameLsb = (byte)(FrameNumber & 0xFF);                                 //Least significant byte
  167.            byte FrameMsb = (byte)(FrameNumber >> 8);                                   //Most significant byte
  168.            byte RevFrameLsb = ReverseByte(FrameLsb);                                   //Reversed least significant byte
  169.            byte RevFrameMsb = ReverseByte(FrameMsb);                                   //Reversed most significant byte
  170.            byte XorData = (byte)(FrameMsb ^ FrameLsb ^ RevFrameMsb ^ RevFrameLsb);     //XOR variable for consistency checking
  171.  
  172.            int DelayCounter = 0;
  173.  
  174.            //Calculate XOR checksum
  175.            for (int i = 0; i < 128; i++)
  176.            {
  177.                XorData ^= FrameData[i];
  178.            }
  179.  
  180.            //Write a frame to a Memory Card
  181.            SendDataToPort((byte)DexCommands.WRITE, new byte[] { FrameMsb, FrameLsb, RevFrameMsb, RevFrameLsb }, 0);        //Frame number
  182.            OpenedPort.Write(FrameData, 0, FrameData.Length);                                                               //Save data
  183.            OpenedPort.Write(new byte[] { XorData }, 0, 1);                                                                 //XOR Checksum
  184.  
  185.            //Wait for the buffer to fill
  186.            while (OpenedPort.BytesToRead < 4 && DelayCounter < 20)
  187.            {
  188.                Thread.Sleep(5);
  189.                DelayCounter++;
  190.            }
  191.  
  192.            //Fetch DexDrive's response to the last command
  193.            ReadData = ReadDataFromPort();
  194.  
  195.            //Check the return status (return true if all went OK)
  196.            if (ReadData[0x3] == (byte)DexResponses.WRITE_OK || ReadData[0x3] == (byte)DexResponses.WRITE_SAME) return true;
  197.  
  198.            //Data was not written sucessfully
  199.            return false;
  200.        }
  201.  
  202.        //Reverse order of bits in a byte
  203.        byte ReverseByte(byte InputByte)
  204.        {
  205.            byte ReturnByte = new byte();
  206.  
  207.            int i = 0;
  208.            int j = 7;
  209.  
  210.            while (i < 8)
  211.            {
  212.                if((InputByte & (1 << i)) > 0) ReturnByte |= (byte)(1 << j);
  213.  
  214.                i++;
  215.                j--;
  216.            }
  217.  
  218.            //Return reversed byte
  219.            return ReturnByte;
  220.        }
  221.    }
  222. }
  223.  

La parte de enumerar los hedaceimales sean comandos o respuestas está muy cómodo.
Código
  1.        enum DexCommands { INIT = 0x00, STATUS = 0x01, READ = 0x02, WRITE = 0x04, LIGHT = 0x07, MAGIC_HANDSHAKE = 0x27 };
  2.        enum DexResponses { POUT = 0x20, ERROR = 0x21, NOCARD = 0x22, CARD = 0x23, WRITE_OK = 0x28, WRITE_SAME = 0x29, WAIT = 0x2A, ID = 0x40, DATA = 0x41 };

Por supuesto, tengo el componente serialPort1 en el formulario, no se el motivo de que este usuario lo ha puesto a base de códigos. En fin, cuestión de gustos.
Código
  1.            //Define a port to open
  2.            OpenedPort = new SerialPort(ComPortName, 38400, Parity.None, 8, StopBits.One);
  3.            OpenedPort.ReadBufferSize = 256;

Voy hacer el código desde 0, así me ahorro muchas cosas que tiene este ejemplo, solo me centraré en el DexDrive. Poco a poco pondré avances y/o pedir ayuda.

Saludos.
En línea

Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/
Meta


Desconectado Desconectado

Mensajes: 3.203



Ver Perfil WWW
Re: Quiero controlar el DexDrive
« Respuesta #7 en: 30 Diciembre 2015, 14:55 »

Hola:



Primera prueba y me costó coger el truco, he logrado encender el Led verde del DexDrive. Por algo se empieza. ;) Lo que he hecho, solo despierta el DeDrive mostrándolo conel Led verde encendido, está preparado para recibir comandos en el cual aún no lo he programado.

En el cuadro negro, muestra letras en verde los caracteres.

Por ahora, este es el código.
Código:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.IO.Ports; // No olvidar.
using System.Threading;

namespace DexPlorer
{
    public partial class Form1 : Form
    {
        public enum Dex_Comandos
        {
            INIT = 0x00, STATUS = 0x01, READ = 0x02, SEEK = 0x03, WRITE = 0x04, PAGE = 0x05, LIGHT = 0x07, MAGIC_HANDSHAKE = 0x27
        }

        public enum Dex_Respuestas
        {
            POUT = 0x20, ERROR = 0x21, NOCARD = 0x22, CARD = 0x23, CARD_NEW = 0x25, SEEK_OK = 0x27, WRITE_OK = 0x28, WRITE_SAME = 0x29, WAIT = 0x2A, ID = 0x40, DATA = 0x41
        }

        byte[] TRAMAS = { 0x10, 0x29, 0x23, 0xbe, 0x84, 0xe1, 0x6c, 0xd6, 0xae, 0x52, 0x90, 0x49, 0xf1, 0xf1, 0xbb, 0xe9, 0xeb };

        // Utilizaremos un string como buffer de recepción.
        string Recibidos;

        // Buffer para almacenar leer datos de la DexDrive.
        byte[] Leer_Datos = null;

        // Contiene una versión de firmware de un dispositivo detectado.
        string Firmware_Version = null;

        public Form1()
        {
            InitializeComponent();

            // Puerto abierto desde que arranca la aplicación.
            if (!serialPort1.IsOpen)
            {
                try
                {
                    serialPort1.Open();
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }

            //Dexdrive won't respond if RTS is not toggled on/off
            serialPort1.RtsEnable = false;
            Thread.Sleep(300);
            serialPort1.RtsEnable = true;
            Thread.Sleep(300);

            //DTR line is used for additional power
            serialPort1.DtrEnable = true;

            // Comprobar si DexDrive está conectado al puerto.
            // La detección puede fallar primera o segunda vez, por lo que el comando es enviado 5 veces.
            for (int i = 0; i < 5; i++)
            {
                serialPort1.DiscardInBuffer();
                serialPort1.Write("XXXXX");
                Thread.Sleep(20);
            }

            // Compruebe cadena "IAI".
            Leer_Datos = Leer_datos_del_puerto();
            if ((Leer_Datos[0] != 0x49) || (Leer_Datos[1] != 0x41) || (Leer_Datos[2] != 0x49)) return;

            // Despierta DexDrive arriba (patear desde el modo POUT).
            //Envia_dato_al_puerto((byte)Dex_Comandos.INIT, new byte[] { 0x10, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA, 0xBB, 0xCC, 0xDD }, 50);
            Envia_dato_al_puerto((byte)Dex_Comandos.INIT, new byte[] { 0x10, 0x29, 0x23, 0xbe, 0x84, 0xe1, 0x6c, 0xd6, 0xae, 0x52, 0x90, 0x49, 0xf1, 0xf1, 0xbb, 0xe9, 0xeb }, 50);

            // Compruebe cadena "PSX".
            Leer_Datos = Leer_datos_del_puerto();
            if ((Leer_Datos[5] != 0x50) || (Leer_Datos[6] != 0x53) || (Leer_Datos[7] != 0x58)) return; // "Dispositivo detectado no es un PS1 DexDrive."

            // Obtener la versión del firmware.
            Firmware_Version = (Leer_Datos[8] >> 6).ToString() + "." + ((Leer_Datos[8] >> 2) & 0xF).ToString() + (Leer_Datos[8] & 0x3).ToString();

            // Enviar señal de handshake magia 10 veces.
            for (int i = 0; i < 10; i++) Envia_dato_al_puerto((byte)Dex_Comandos.MAGIC_HANDSHAKE, null, 0);
            Thread.Sleep(50);

            // Enciende la luz de estado.
            Envia_dato_al_puerto((byte)Dex_Comandos.LIGHT, new byte[] { 1 }, 50);

            // Todo ha ido bien, DexDrive está listo para recibir comandos.
            //return null;

            Recibidos = Encoding.ASCII.GetString(Leer_Datos);

            // Recibidos = Encoding.Default.GetString(Leer_Datos);

            // Para ver lo que envía desde el DexDrive hacia esta interfaz de C#.
            // Asignar el valor de la trama al richTextBox.
            richTextBox1.Text = Recibidos;

            //    // Para ver lo que envía desde el DexDrive hacia esta interfaz de C#.
            //    // Asignar el valor de la trama al richTextBox.
            richTextBox1.Text = Recibidos;

            // Selecciona la posición final para leer los mensajes entrantes.
            richTextBox1.SelectionStart = richTextBox1.Text.Length;

            //serialPort1.DataReceived += new SerialDataReceivedEventHandler(Recepcion);
        }

        // Enviar comando DexDrive en el puerto COM se abrió con un retraso.
        private void Envia_dato_al_puerto(byte Comando, byte[] Dato, int Delay)
        {
            // Borrar todo en el búfer de entrada.
            serialPort1.DiscardInBuffer();

            // Cada comando debe comenzar con la cadena "IAI".
            serialPort1.Write("IAI" + (char)Comando);
            if (Dato != null) serialPort1.Write(Dato, 0, Dato.Length);

            // Espere un tiempo establecido (para la respuesta DexDrive).
            if (Delay > 0) Thread.Sleep(Delay);
        }

        // Captura la respuesta de un DexDrive.
        private byte[] Leer_datos_del_puerto()
        {
            // Buffer para la lectura de datos.
            byte[] Flujo_de_entrada = new byte[256];

            // Leer datos de DexDrive.
            if (serialPort1.BytesToRead != 0) serialPort1.Read(Flujo_de_entrada, 0, 256);

            return Flujo_de_entrada;
        }
    }
}

Sigo con ello intentar enviar comandos a ver si se deja, como formatear, leer, borrar, algo.

Felices fiesta.
En línea

Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
controlar usb con VB
Electrónica
c00rd3L 5 7,829 Último mensaje 26 Diciembre 2008, 13:24
por c00rd3L
Yo quiero ser Inmortal - NO quiero morir ¿y TU? « 1 2 ... 10 11 »
Foro Libre
traviatØ 102 25,368 Último mensaje 12 Febrero 2011, 06:23
por chopy1989
Lo quiero todo y lo quiero inmediatemente: la pantalla de inicio como una ....
Noticias
wolfbcn 0 643 Último mensaje 19 Febrero 2013, 21:41
por wolfbcn
De nuevo al ataque jeje no logro controlar que no me muestre lo que quiero
.NET (C#, VB.NET, ASP)
luis456 4 1,373 Último mensaje 24 Octubre 2013, 19:53
por luis456
Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines