Autor Tema: Dudas USB y 12Mbps  (Leído 43328 veces)

0 Usuarios y 4 Visitantes están viendo este tema.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Dudas USB y 12Mbps
« Respuesta #15 en: 20 de Marzo de 2009, 13:15:14 »
uy Pali, pero, ¿cómo aseguro que mi adc lea cada 40us sin retrasos ni adelantos? Mi frecuencia de muestreo debe ser de 25000sps (cada 40us) y el polling (token de la pc) de 1ms lo interrumpiría.

Tengo un plan B, pero no lo quiero usar hasta saber si puedo...

- Medir mi adc cada 40us exactos: 2 bytes por muestra y 20us de tiempo de muestreo, por lo que me sobran 20us para reportar vía usb.
- Reportar la medición sin pérdida de paquetes (20us mencionados arriba pero la realidad es que es 1ms mínimo usando HID o 550us usando CDC).

Si no logro hacerlo, entonces habré de usar 2 pics, un medidor y un transmisor.  :(

Voy a hacer la prueba con HID como tú dices, no pierdo nada.

- La medición ADC se haría cada 40us generando 2 bytes.
- Si la latencia usb hid fuera de 1ms entonces tendría que acumular las siguientes muestras para enviarlas en 1 solo paquete...

1ms / 40us =25 muestras
25 muestras * 2 bytes = 50bytes

~ Puntos a checar en la prueba...

- Verificar si la interrupción de timer que invoca la medición ADC es cada 40us sin importar que lleguen interrupciones usb (a ver si esta vez me quedan bien las prioridades de interrupción)
- Medir el tiempo de envío de los 50 bytes a la pc y determinar si es menor a 20us para que no afecte la medición ADC.
- Verificar que la pc realmente sea capaz de enviar un token cada 1ms. Hemos visto que en sistemas operativos que no son de tiempo real es difícil asegurar tiempos de ejecución menores a 10ms.

Sigue pendiente encontrar un ejemplo isócrono. Voy a ver si encuentro algo en el foro de ccs. :wink:
« Última modificación: 20 de Marzo de 2009, 13:17:30 por migsantiago »

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Dudas USB y 12Mbps
« Respuesta #16 en: 20 de Marzo de 2009, 16:55:57 »
Santiago, creo que la solución al problema es crear un buffer circular para evitar el trabajo de estar cuadrando tiempos.

Digamos que creas un array de un ancho establecido y vayas almacenando datos mientras que por el otro lado estas enviando al PC (usando interrupciones).

Así no detienes ninguno de los 2 procesos (la captura del adc y el envío por el usb). Es que con las velocidad tan lenta del pic, no creo que sea posible mantener un muestreo de ese tipo.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Dudas USB y 12Mbps
« Respuesta #17 en: 23 de Marzo de 2009, 17:45:08 »
Bueno, creo que no se puede habilitar todos los endpoints del pic. Lo maximo que he llegado hacer es esto:

Código: [Seleccionar]

#INCLUDE <18F4550.h>

#FUSES HSPLL, PLL5, CPUDIV1, USBDIV, VREGEN, NOWDT, PUT, NOBROWNOUT, MCLR, NOPROTECT, NOLVP

#USE DELAY (CLOCK = 48 000 000)

#DEFINE USB_HID_DEVICE                    FALSE             //Deshabilitar el uso de las directivas HID o Dispositivos de Interacion Humana.
#DEFINE USB_CDC_DEVICE                    FALSE             //Deshabilitar el uso de las directivas para simulacion de serial con USB.
#DEFINE USB_USE_FULL_SPEED                TRUE              //Velocidad: Full Speed 12 Mb/s.


#DEFINE USB_EP1_TX_ENABLE                 USB_ENABLE_BULK   //Habilitar la transferencia en el EndPoint 1.
#DEFINE USB_EP1_RX_ENABLE                 USB_ENABLE_BULK   //Habilitar el recivimiento en el EndPoint1.
#DEFINE USB_EP1_TX_SIZE                   64                //Tamaño de bytes maximos que se enviara por el EndPoint1 (maximo 64 bytes).
#DEFINE USB_EP1_RX_SIZE                   64                //Tamñao de bytes maximos que se recibira del EndPoint1 (maximo 64 bytes).

#DEFINE USB_EP2_TX_ENABLE                 USB_ENABLE_BULK   //Habilitar la transferencia en el EndPoint 1.
#DEFINE USB_EP2_TX_SIZE                   64                //Tamaño de bytes maximos que se enviara por el EndPoint1 (maximo 64 bytes).

#DEFINE USB_EP3_TX_ENABLE                 USB_ENABLE_BULK   //Habilitar la transferencia en el EndPoint 1.
#DEFINE USB_EP3_TX_SIZE                   64                //Tamaño de bytes maximos que se enviara por el EndPoint1 (maximo 64 bytes).

#DEFINE USB_EP4_TX_ENABLE                 USB_ENABLE_BULK   //Habilitar la transferencia en el EndPoint 1.
#DEFINE USB_EP4_TX_SIZE                   64                //Tamaño de bytes maximos que se enviara por el EndPoint1 (maximo 64 bytes).

#DEFINE USB_EP5_TX_ENABLE                 USB_ENABLE_BULK   //Habilitar la transferencia en el EndPoint 1.
#DEFINE USB_EP5_TX_SIZE                   64                //Tamaño de bytes maximos que se enviara por el EndPoint1 (maximo 64 bytes).

#DEFINE USB_EP6_TX_ENABLE                 USB_ENABLE_BULK   //Habilitar la transferencia en el EndPoint 1.
#DEFINE USB_EP6_TX_SIZE                   64                //Tamaño de bytes maximos que se enviara por el EndPoint1 (maximo 64 bytes).

#DEFINE USB_EP7_TX_ENABLE                 USB_ENABLE_BULK   //Habilitar la transferencia en el EndPoint 1.
#DEFINE USB_EP7_TX_SIZE                   64                //Tamaño de bytes maximos que se enviara por el EndPoint1 (maximo 64 bytes).

#DEFINE USB_EP8_TX_ENABLE                 USB_ENABLE_BULK   //Habilitar la transferencia en el EndPoint 1.
#DEFINE USB_EP8_TX_SIZE                   64                //Tamaño de bytes maximos que se enviara por el EndPoint1 (maximo 64 bytes).

#DEFINE USB_EP9_TX_ENABLE                 USB_ENABLE_BULK   //Habilitar la transferencia en el EndPoint 1.
#DEFINE USB_EP9_TX_SIZE                   64                //Tamaño de bytes maximos que se enviara por el EndPoint1 (maximo 64 bytes).


#DEFINE USB_CON_SENSE_PIN  PIN_A1

#INCLUDE "INC/pic18_usb.h"              // Libreria con funciones para los pic 18Fxx5x para el uso del USB 2.0.
#INCLUDE "INC/USB_descriptores.h"       // Configuración de los descriptores para este dispositivo
#INCLUDE "INC/usb.c"                    // Funciones para el uso del Universal System Bulk o Systema Universal de paquetes (USB).

void Main (void)
{
   usb_init();
   
   while (true)
   {
      usb_task();
     
      if (usb_enumerated() == true)
      {
         
         
         if (usb_kbhit(1) == true)
         {
         
         }
      }
   }   
}

Un endpoint mas y me salta un error que he sobrepasado el limite de espacio. Quee raro  :?


Seguire viendo, salu2.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Dudas USB y 12Mbps
« Respuesta #18 en: 23 de Marzo de 2009, 21:42:26 »
Esa habilitación de endpoints la vi en un post de Medusa, pero ¿cómo se mejora la velocidad de envío usb?

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Dudas USB y 12Mbps
« Respuesta #19 en: 23 de Marzo de 2009, 23:54:17 »
No tenia ni idea de ESE post de medusa pero parece hacer basicamente lo mismo, solo que yo habilito al maximo (64 bytes) los endpoints de salida a la PC. Teniendo como limite solo los 9 endpoints porque se acaba la RAM para el usb al parecer y se tiene que usar el puerto paralelo para usar todos los endpoints restantes creo, ojala que no.

Bueno, ahora estoy probando con esta configuracion de esta manera:
Código: [Seleccionar]
void Main (void)
{
   unsigned int16 i1;
   unsigned int8 BufferUSBSalida[64];

   output_low(PIN_D0);  // D1

   printf("\r\n\nUSB\r\n");

   usb_init();
   
   while (true)
   {
      usb_task();
     
      if (usb_enumerated() == true)
      {
         if (input(PIN_B4) == false)   // S2
         {
            delay_ms(400);
            while (input(PIN_B4 == false))
            {
           
            }
           
            output_high(PIN_D0);    // D1
         
            for (i1 = 0; i1 < 2730; i1++) //2730  24576
            {
               printf("%u ", usb_put_packet(1, BufferUSBSalida, 64, USB_DTS_TOGGLE));
               printf("%u ", usb_put_packet(2, BufferUSBSalida, 64, USB_DTS_TOGGLE));
               printf("%u ", usb_put_packet(3, BufferUSBSalida, 64, USB_DTS_TOGGLE));
               printf("%u ", usb_put_packet(4, BufferUSBSalida, 64, USB_DTS_TOGGLE));
               printf("%u ", usb_put_packet(5, BufferUSBSalida, 64, USB_DTS_TOGGLE));
               printf("%u ", usb_put_packet(6, BufferUSBSalida, 64, USB_DTS_TOGGLE));
               printf("%u ", usb_put_packet(7, BufferUSBSalida, 64, USB_DTS_TOGGLE));
               printf("%u ", usb_put_packet(8, BufferUSBSalida, 64, USB_DTS_TOGGLE));
               printf("%u ", usb_put_packet(9, BufferUSBSalida, 64, USB_DTS_TOGGLE));
               
               printf("|| *");
            }
         
            output_low(PIN_D0);  // D1
         }
         
         
         if (usb_kbhit(1) == true)
         {
         
         }         
      }
   }   
}

Con esta configuracion de los 9 endpoints e podido enviar 12Mb (1.5MB) en 4 o 5 segundos aproximadamente, ocea que si mis calculos no son malo estariamos enviando aproximadamente 307 KB/s  :-/  Para comprobar esto, enves de lo que esta en el ciclo for puse:

Código: [Seleccionar]
            for (i1 = 0; i1 < 24576; i1++) //2730  24576
            {
               printf("%u ", usb_put_packet(1, BufferUSBSalida, 64, USB_DTS_TOGGLE));         
               printf("|| *");
            }
Que hace uso solamente de un endpoint de salida, enviando otra vez 12Mb (1.5MB) pero en 11 segundos aproximadamente.

Bueno, no puedo asegurar esto del todo, yaque los printf's me retornan 1 la primera vez, pero despues me retornan 0. Esto, debido a que no estoy usando ningun programa de software en la PC para leer estos datos. Asique que estos tiempos quiza puedan ser mayores, pero con esto parece que realmente usar mas endpoints acelera la transferencia aunque paresca lo mismo.

Bueno, seguire revisando.

Salu2.
« Última modificación: 23 de Marzo de 2009, 23:57:37 por jeremylf »

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Dudas USB y 12Mbps
« Respuesta #20 en: 24 de Marzo de 2009, 15:11:34 »

Bueno, no puedo asegurar esto del todo, yaque los printf's me retornan 1 la primera vez, pero despues me retornan 0. Esto, debido a que no estoy usando ningun programa de software en la PC para leer estos datos. Asique que estos tiempos quiza puedan ser mayores, pero con esto parece que realmente usar mas endpoints acelera la transferencia aunque paresca lo mismo.

Bueno, seguire revisando.

Salu2.

Cierto, el enviar los paquetes sin alguien que los reciba no demuestra la velocidad real de la comunicación, aunque da un poco de luz el uso de los 9 endpoints simultáneamente. Para comprobar el tiempo real habría que tener el host (pc) con 9 endpoints también e implementar un envío seguro...

Código: [Seleccionar]
               while(transOK==0) //No pudo enviar, intenta de nuevo
                  transOK=usb_put_packet(1, doutprima, 12, USB_DTS_TOGGLE);

Ahora ya tengo 2 pendientes, probar HID con 1ms de latencia y probar Bulk con 9 endpoints siguiendo el ejemplo de Jeremy.  :P


Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Dudas USB y 12Mbps
« Respuesta #21 en: 24 de Marzo de 2009, 18:39:05 »
No lo hago porque nose como hacer una "interrupcion cuando llega un dato del dispositivo a la PC" en Visual C#. Creo que con Labview se puede o lo han echo para el caso de un proyecto de osciloscopio con usb (no estoy seguro) pero no se usar labview. Como lo haces tu migsantiago?

Salu2.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Dudas USB y 12Mbps
« Respuesta #22 en: 24 de Marzo de 2009, 19:06:52 »
Debes tener cuidado con la forma en que se envían los datos USB.

En usb, el host es el que inicia toda comunicación, por lo que el pic nunca enviaría algo sin que el host le de permiso.

Primero, lo que hago en el pic es:

Código: [Seleccionar]
               while(transOK==0) //No pudo enviar, intenta de nuevo
                  transOK=usb_put_packet(1, doutprima, 12, USB_DTS_TOGGLE);

Y después lo que hago en VC# es...

Código: [Seleccionar]
                //Recibe el byte medido
                picusb.RecibePaquetes(rec_buf);

donde el método RecibePaquetes lo defino como:

Código: [Seleccionar]
       
        //Función RecibePaquetes
        //Entrega en variable BufferRec los 12 bytes enviados por el pic
        public void RecibePaquetes(byte* BufferRec)
        {
            DWORD RecvLength = 2;

            ReceivePacketHandle(BufferRec, &RecvLength);
        }


Y el método ReceivePacketHandle a su vez lo definí como:

Código: [Seleccionar]
        //Función ReceivePacketHandle
        //Debe existir un handle abierto en myInPipe antes de llamarla
        public void ReceivePacketHandle(byte* ReceiveData, DWORD* ReceiveLength)
        {
            uint ReceiveDelay = 1000;
            DWORD ExpectedReceiveLength = *ReceiveLength;

            _MPUSBRead(myInPipe, (void*)ReceiveData, ExpectedReceiveLength, ReceiveLength, ReceiveDelay);
        }

Por lo que la situación es así:

- El pic deposita los datos a enviar en el endpoint 1 (usb_put_packet)
- Se espera hasta que el host le de permiso de enviarlos (transOK sigue valiendo 0)
- El host envía la orden de recepción de paquete (_MPUSBRead)
- El pic se entera y vuelca el endpoint al bus (transOK ya valdrá 1)
- Se repite el proceso

Sobre las interrupciones en VC# no sé cómo se haría, pero eso ya involucra el modo isócrono USB.

Para intentar mejorar la velocidad de envío modifiqué la PICUSBAPI.cs de J1M para evitar tener que abrir y cerrar los pipes usb cada que existiera un envío o recepción USB.

La adjunto por si alguien la quiere revisar.
http://www.4shared.com/file/94784026/c3b896d4/PicUSBAPI.html

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Dudas USB y 12Mbps
« Respuesta #23 en: 24 de Marzo de 2009, 20:43:41 »
Siii yo tb hago algo parecido, AQUI lo expongo, donde me meti hasta las entrañas de la DLL, destripandola y modificandola  :x Pero crei que para esta velocidad de comunicacion se necesitaria de hacer uso de alguna interrupcion. Ademas, no confio mucho de esta forma de simular una interrupcion. De todas formas, sigo sin encontrar la forma de tener esta interrupcion ya hace buen tiempo  :(

Bueno, sin salirme del tema, seguire haciendo pruebas con los 9 endpoints pero ahora los recepcionare en el HOST haber que pasa  :mrgreen:
Salu2.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Dudas USB y 12Mbps
« Respuesta #24 en: 24 de Marzo de 2009, 21:18:09 »
Recuerdo que leí tus mensajes mientras pasé por todo el tema de PICUSB de J1M, lo malo es que te estancaste y ya no pudiste salir de tus dudas.

Estaré al pendiente de tus pruebas.

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
Re: Dudas USB y 12Mbps
« Respuesta #25 en: 25 de Marzo de 2009, 10:51:56 »
Yo no he llegado a hacer uso de los modos ping pong, pero no creo que haya mayor problema a la hora de utilizarlos con ccs. Aquí se comenta un poco el tema:

http://www.todopic.com.ar/foros/index.php?topic=21145.0

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Dudas USB y 12Mbps
« Respuesta #26 en: 25 de Marzo de 2009, 12:40:06 »
Hola Modulay

Una vez leí tu tema pero no lo entendí, fue apenas cuando inicié a estudiar usb. Voy a volver a leerlo y te comento.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Dudas USB y 12Mbps
« Respuesta #27 en: 25 de Marzo de 2009, 21:44:06 »
Modulay, ya leí tu desarrollo del manejo de la interrupción. El implementar el modo ping pong implica modificar las funciones usb_put_packet y usb_get_packet para que lean un endpoint par y no lean uno impar y en la siguiente transacción se haga lo contrario.

Leyendo el archivo pic18_usb.h veo que usb_put_packet se implementa así:

Código: [Seleccionar]
int1 usb_put_packet(int8 endpoint, int8 * ptr, int16 len, USB_DTS_BIT tgl) { //done
   int16 j;
   int8 i;
   int8 * buff_add;   

   i=EP_BDxST_I(endpoint);
   if (!bit_test(i,7)) {

      buff_add=EP_BDxADR_I(endpoint);

      for (j=0;j<len;j++) {
         *buff_add=*ptr;
         buff_add++;
         ptr++;
      }

      return(usb_flush_in(endpoint, len, tgl));
    }
    else {
        debug_usb(debug_putc,"\r\nPUT ERR");
    }
    return(0);
}

Pero es aquí donde veo un problema...

Código: [Seleccionar]
i=EP_BDxST_I(endpoint);
Esta función obtiene el valor de BDxSTAT y lo deposita en i. Pero ¿cómo hacerle saber a CCS que el endpoint está en modo ping pong y que STAT existe dos veces... como par y como impar?

Bueno, buscando la definición de la función...

Código: [Seleccionar]
#if (USB_PING_PONG_MODE==USB_PING_PONG_MODE_OFF)
 #define EP_BDxST_O(x)    *(BD0STAT_LOC + x*8)
 #define EP_BDxCNT_O(x)    *(BD0CNT_LOC + x*8)
 #define EP_BDxADR_O(x)   *(int16 *)(BD0ADRL_LOC + x*8)
 #define EP_BDxST_I(x)    *(BD0STAT_LOC + 4 + x*8)
 #define EP_BDxCNT_I(x)    *(BD0CNT_LOC + 4 + x*8)
 #define EP_BDxADR_I(x)   *(int16 *)(BD0ADRL_LOC + 4 + x*8)
#else
#error Right now this driver only supports no ping pong
#endif

Se ve que los de CCS no soportan ping pong, pero nadamás porque no quieren  :D Se puede modificar esa definición y las demás para que lean un EP par y luego un impar de forma automática.

Mañana seguiré leyendo al respecto.

Pero me entra una duda, habilitando el modo ping pong puedo mejorar la velocidad de envío de bytes, pero ¿cuánto tiempo tarda en enviarse el contenido de los 'n' endpoints que emplee? ¿Será un tiempo menor a 20us como para que yo pueda muestrear y enviar al mismo tiempo?  :shock:

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Dudas USB y 12Mbps
« Respuesta #28 en: 31 de Marzo de 2009, 16:35:53 »
Estoy haciendo la prueba con el modo HID y el programa para el pic ya funciona. El problema que tengo es que no he podido comunicarme con el PIC usando la mpusbapi.dll. Me ha funcionado bien con el modo bulk pero ahora con HID no sé qué pasa.

El problema inicial es que ni siquiera se obtienen los handles a los pipes...

Código: [Seleccionar]

------PICUSBAPI.cs
        //Función OpenPipes
        //Regresa un handle a un endpoint con un PID VID específico
        public void OpenPipes()
        {
            DWORD selection = 0;
            myOutPipe = _MPUSBOpen(selection, vid_pid_norm, out_pipe, 0, 0);
            myInPipe = _MPUSBOpen(selection, vid_pid_norm, in_pipe, 1, 0);
        }

------Form1.cs
picusb.OpenPipes();

Al ejecutarse picusb.OpenPipes(); los handles son iguales a 0xffffffff (myOutPipe y myInPipe).



Los VID y PID están bien, en el pic y en el programa.

¿Para usar el modo HID hay que usar otra cosa? No he podido comunicar la pc con el pic.

Probé con la HIDLibrary pero tampoco hubo éxito.
« Última modificación: 31 de Marzo de 2009, 16:43:36 por migsantiago »

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Dudas USB y 12Mbps
« Respuesta #29 en: 31 de Marzo de 2009, 19:20:04 »
Para leer una pipe con la dll mpusbapi tienes que usar la funcion _MPUSBReadInt(...). Pero, antes tienes que cambiar, al abrir la pipe (_MPUSBOpen(...)) en el parametro 3 (pEP), el tipo de pipe. Esto se hace en el string statico in_pipe y/o out_pipe.

El formato para bulk es: \\MCHP_EPz
Pero cuando es comunicacion HID el formato cambia a: \\MCHP_EPz_ASYNC

Eso lo encuentras en un .pdf traducido por Slalen pero posiacaso lo dejo aqui adjuntado.


Salu2.
« Última modificación: 31 de Marzo de 2009, 19:32:31 por jeremylf »