Autor Tema: Wii Motion Plus con MCF51JM128  (Leído 3805 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado mauricio2346

  • PIC10
  • *
  • Mensajes: 7
Wii Motion Plus con MCF51JM128
« en: 08 de Junio de 2012, 23:05:08 »
Saludos a todos.   este es mi primer post en Todopic.  primero me presento.  Soy Mauricio Fernandez Montoya, Ingeniero Mecatrónico de la EIA en Colombia.  pese a que llevo un buen rato programando en microcontroladores Freescale (más que todo en las familias HCS08 y Coldfire V1), también he hecho aplicaciones muy interesantes para microcontroladores PIC y arduino.

ahora si, vamos al tema.    resulta que llevo casi un mes intentando comunicarme con un Wii motion plus desde mi core POLARIS32 (este core lo diseñé para mi tesis de grado.. es suceptible de ponerlo a la venta, pero todavía estoy evaluandolo).  una foto del core:


ya puedo comunicarme perfectamente con una memoria 24LC01B, leo y escribo bien!!.
estoy teniendo problemas con el Wii motion plus.  se supone que debo enviarle (luego de apagar el sensor, encenderlo y redireccionarlo, como se debe), logro leer los bytes que este sensor me envía solo cuando hago simulación paso a paso desde el debugger.  este tema lo he llevado a la gente del foro de Freescale, pero insisten en que cambie completamente mi programa, cosa que no estoy deacuerdo ya que el programa está hecho basandose en documentación oficial de Freescale y funciona bien para lecturas de un solo byte.
esta es la rutina de lectura que implementé para el sensor:
Código: [Seleccionar]
void IIC_read_bytes(byte Command, byte addr){
  byte RD_data;
  char i;
 
  IIC1C1_TXAK = 0; 
  IIC1C1 |= 0X30;
  IIC1D = Command|I2C_WRITE;
  while (!IIC1S_IICIF){}
  IIC1S_IICIF=1;
  while (IIC1S_RXAK){}
  DelayMs(5);

 
  IIC1D = addr;
  while (!IIC1S_IICIF){}
  IIC1S_IICIF=1;
  while (IIC1S_RXAK){}
  DelayMs(5); 
  IIC1C1_RSTA = 1;
   
  IIC1D = Command|I2C_READ;
  while (!IIC1S_IICIF){}
  IIC1S_IICIF=1;
  while (IIC1S_RXAK){}
    DelayMs(5);
  IIC1C1_TX = 0;
  Dato[0] = IIC1D;
  while (!IIC1S_IICIF){}
  IIC1S_IICIF=1;
  while (IIC1S_RXAK){}
    DelayMs(5);
  for(i=0;i<5;i++){
    IIC1C1_TXAK = 0; 
    Dato[i] = IIC1D;
     
  }
  IIC1C1_TXAK = 1;
   
  Dato[5] = IIC1D;
  IIC1C1_MST = 0; 
}

adicionalmente, de esta forma estoy arrancando el wii motion plus.  el sensor está recibiendo los comandos, porque puedo leer la información paso a paso correctamente, pero al ejecutar de corrido.. todo falla y se queda enganchado en un bucle infinito.

Código: [Seleccionar]
void main(void) {
  MCU_Init();
Clock_Init();
Port_Init();
        Init_I2C();
SCI1_Init();
SCI1C2_RIE=1;
    State_Led=1;
EnableInterrupts;
 
 

    //Iniciar el Wii Motion Plus
    //**** Desactiva el Wii Motion Plus inicialmente
    IIC_Start();
    IIC_PutChar(0XA6);
    IIC_PutChar(0XF0);
    IIC_PutChar(0X55);
    IIC_Stop();
    //****Activa el Wii motion Plus
    DelayMs(10);
    IIC_Start();
    IIC_PutChar(0XA6);
    IIC_PutChar(0XFE);
    IIC_PutChar(0X04);
    IIC_Stop();
    //****
    DelayMs(10);
    IIC_Start();
    IIC_PutChar(0XA4);
    IIC_PutChar(0XFB);
    IIC_PutChar(0X00);
    IIC_Stop();
    //****
   
 
    DelayMs(40);
   
  for(;;) {
   
   
    IIC_read_bytes(0XA4,0X00);
   
    SCI1_Puts("Informacion Wii Motion Plus");
    SCI1_PutChar(LF);
    SCI1_PutChar(CR);
    SCI1_PutChar(Dato[0]|0X30);
    SCI1_PutChar(Dato[1]|0X30);
    SCI1_PutChar(Dato[2]|0X30);
    SCI1_PutChar(Dato[3]|0X30);
    SCI1_PutChar(Dato[4]|0X30);
    SCI1_PutChar(Dato[5]|0X30);
    SCI1_PutChar(LF);
    SCI1_PutChar(CR);
    SCI1_PutChar(LF);
    SCI1_PutChar(CR);
   
   
    State_Led=~State_Led;
    DelayMs(100);
           
}
}

como pueden ver, es la unica rutina que estoy ejecutando en el microcontrolador,( aparte del modulo serial, que uso solo para ver los datos en hyperterminal, aparte de corroborar los registros desde el debugger).

alguien ha podido leer varios bytes seguidos desde el modulo I2C de Freescale???.   las rutinas para HCS08 y para el JM60 me servirían, ya que el core es completamente compatible registro a registro.   

Les agradezco mucho su ayuda,

Atentamente;

Mauricio

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Wii Motion Plus con MCF51JM128
« Respuesta #1 en: 11 de Junio de 2012, 17:52:39 »
Hola Mauricio, las recomendaciones en el foro de FreeScale se refieren a que es recomendable usar el IIC por medio de interrupciones y no por polling ( es como lo estas realizando ). La otra consideración a tener en cuenta en códigos de producción es colocar de alguna manera un timer para detectar dead-loops, como en este ejemplo:

Código: C
  1. while (!IIC1S_IICIF){}

Este código tiene dos problemas si algo anda mal, primero si trabajas con watch-dog este nunca se refresca, y si por casualidad el componente exterior no funciona o no responde nunca salís del while.

Lo idea para mi sería hacer algo asi.

Código: C
  1. timer_event_set_msec( &Event, 1500 );
  2.  
  3.   do
  4.   {
  5.     /* Kick the dog */
  6.     WatchDog_Clear();
  7.  
  8.     if ( IIC1S_IICIF)
  9.     {
  10.       break;
  11.     }
  12.    }while ( !timer_event_has_expired( &Event ))

Aunque el código es más largo, es más seguro. Se espera porque cambie ese flag, mientras se resetea el watch dog, si esto no pasa en cierta cantidad salís del loop.

Saludos !

Desconectado mauricio2346

  • PIC10
  • *
  • Mensajes: 7
Re: Wii Motion Plus con MCF51JM128
« Respuesta #2 en: 14 de Junio de 2012, 23:40:25 »
Hola Mauricio, las recomendaciones en el foro de FreeScale se refieren a que es recomendable usar el IIC por medio de interrupciones y no por polling ( es como lo estas realizando ). La otra consideración a tener en cuenta en códigos de producción es colocar de alguna manera un timer para detectar dead-loops, como en este ejemplo:

Código: C
  1. while (!IIC1S_IICIF){}

Este código tiene dos problemas si algo anda mal, primero si trabajas con watch-dog este nunca se refresca, y si por casualidad el componente exterior no funciona o no responde nunca salís del while.

Lo idea para mi sería hacer algo asi.

Código: C
  1. timer_event_set_msec( &Event, 1500 );
  2.  
  3.   do
  4.   {
  5.     /* Kick the dog */
  6.     WatchDog_Clear();
  7.  
  8.     if ( IIC1S_IICIF)
  9.     {
  10.       break;
  11.     }
  12.    }while ( !timer_event_has_expired( &Event ))

Aunque el código es más largo, es más seguro. Se espera porque cambie ese flag, mientras se resetea el watch dog, si esto no pasa en cierta cantidad salís del loop.

Saludos !
Saludos.  muchas gracias por la respuesta.  acabo de probar otro codigo desde una librería para I2C de este archivo: HCS08QRUGSW.
sigo sin tener exito.  solo hice los cambios respectivos de rata de baudios para la velocidad de reloj que tengo en mi core, y aún sigo sin tener exito.  peor aún, compré un nunchuck que probé con una rutina de arduino (perfecto), hice los cambios para nunchuck y este no alcanza a enviar siquiera los comandos de inicio.

no que se hacer... alguien tiene una rutina para HCs08, para enviar y recibir varios bytes por I2C??
gracias