TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: migsantiago en 13 de Marzo de 2009, 20:33:58

Título: Dudas USB y 12Mbps
Publicado por: migsantiago en 13 de Marzo de 2009, 20:33:58
Hola

Llevo ya varias semanas estudiando y echando a andar los ejemplos de USB que hay, el bulk mode y el cdc con el PIC18F2550 @ 48MHz y usando CCS 4.084. Mi objetivo es obtener una velocidad de transferencia de mínimo 100000Bps, o dicho de otra forma, transmitir del PIC a la PC 4bytes cada 40us. De esos 40us, 20us se usan en la medición ADC y 20us en el envío USB.

Estoy muy frustrado porque en ningún modo he logrado llegar a 100kBps.

- En el modo bulk usando 1 endpoint he llegado a transmitir con velocidad de 5.85kBps.
- En modo cdc con velocidad de conexión de 921600bps y con conexión Hyperterminal he llegado a transmitir 1 byte cada 3.4us usando usb_cdc_putc(), pero el envío no es constante, hay tiempos "muertos" de 500us aprox. entre envíos.
- Después usando cdc bajo las mismas condiciones pero esta vez usando printf(usb_cdc_putc,"12345678901"); logré enviar 12 bytes en 63.2us, con el mismo tiempo "muerto" entre envíos cada n envíos.
- Mejoré los 63.2us a 40.2us enviando los 12 caracteres uno por uno con usb_cdc_putc() (12 veces seguidas) con el mismo tiempo muerto entre envíos.
- Luego implementé un timer0 para forzar el envío cada 40us pero no funciona, incluso poniendo prioridades de interrupciones.
- Por último intenté usar manualmente la función usb_isr() (atención a la interrupción) para evitar los tiempos muertos entre envíos, pero ni siquiera se enumera el pic ante windows.

Todos estos tiempos los medí con un osciloscopio que se conecta a un led que indica mediante ceros y unos la ejecución del usb (a modo de breakpoint).

Quisiera saber si alguien me puede asesorar para lograr llegar a los 100kBps (4bytes cada 40us) que requiero, ya sea usando el modo Bulk o el modo Isócrono, que creo que es el más apropiado.

Si es el caso del modo Bulk, no sé cómo llegar a los 12Mbps virtuales usando los 15 endpoints al mismo tiempo. Para el modo isócrono no tengo ni idea de cómo implementarlo en CCS.

Muchas muchas gracias al que se anime a ayudarme.

Título: Re: Dudas USB y 12Mbps
Publicado por: Suky en 15 de Marzo de 2009, 14:49:34
Yo también he hecho pruebas de este tipo y con resultados similares, baja velocidad de transferencia. Me dedique a buscar información de cómo utilizar el modo isócrono con PIC, pero no encontré absolutamente nada. Así que estoy muy interesado en este hilo, y estaré atento a sus experiencias.
Saludos!
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 15 de Marzo de 2009, 15:04:59
Sí, ese es el problema cuando se intenta implementar algo complejo de forma empírica... prueba y error.  :(

Estoy estudiando la especificación USB2.0 pero voy lento. Espero que alguien pueda ayudarnos con un ejemplo.
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 15 de Marzo de 2009, 16:07:37
El modo isocrono solo se usa video, audio y ese tipo de informacion que no es necesaria que se modifique algun bit de algun byte. Lo que intento decir, es que si necesitas enviar informacion sin tener la posibilidad de que se modifique o se pierda algun bit de todo los datos es mejor usar el modo Bulk, aun que tiene menos velocidad ya que solo usa tramas que le sobran al USB, algo asi...

La cosa va asi, el modo isocrono es el que te garantiza mayor rapidez pero no te garantiza que algun bit o byte se modifique o se pierda, es mas nisiquiera tiene recuperacion de dato. El modo bulk es el mas lento pero te garantiza que todos los datos llegaran sea como sea sin ningun error y tiene hasta recuperacion de dato. El modo interrupcion, no estoy seguro si es mas rapido que el bulk, pero es menos seguro que el bulk pero mas seguro que el isocrono. Aun que el pickit 2 usa este modo para comunicarse asique debe ser tan seguro como el bulk digo yo, aunq esta mas pensando para dispositivos como mouse's, teclados y esas cosas, quea diferencia del modo bulk este esta pensando para impresoras que hasta el ultimo bit es importante.

Espero que se entienda esto  :lol:
Ahora, lo de mejorar la velocidad pues es habilitando todos los enpoints del pic, cosa que nose como se hace, pero tengo la duda de como migsantiago logras capturar los datos en la PC simplemente enviandolos desde el pic ? que software estas usando o pensando usar para la adquisicion de datos en la PC?

Otra cosa, en el modo bulk la transmicion de datos lo has echo byte por byte? porque se puede enviar en un paquete hasta 64 bytes cosa que reduce lso tiempos si necesitas enviar mucha informacion. Es mas, existe una funcion, que no la he usado, llamada usb_puts(...) que dicen ser mas eficiente para enviar mas paquetes en un solo mensaje.


Salu2.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 15 de Marzo de 2009, 16:19:18
Sí, se entiende.

Ya conocía las características del modo isócrono y del bulk. Para el modo bulk envío 12 bytes por paquete y 1 endpoint y obtengo las velocidades que menciono en el primer post.

Lo ideal es implementar el modo isócrono pero CCS no trae ejemplos con ese modo. Y la otra opción es habilitar los otros 15 endpoints para el envío bulk, pero ni idea de cómo hacerlo.
Título: Re: Dudas USB y 12Mbps
Publicado por: Suky en 15 de Marzo de 2009, 18:15:10
Yo también conocía las características del modo isócrono. Estoy trabajando con LabWindows y NI-VISA, y para manejar este modo de comunicación se necesita  “USB Test and Measurement Class” (USBTMC). Este está diseñado para emular el estándar IEEE 488.1, y se pueden programar instrumentos que soportan USBTMC, como sus homólogos GPIB. Esta clase de dispositivo simplifica enormemente el control de instrumentos, ya que se pueden usar interfaces de programación estándar (APIs) como NI-VISA para enviar y leer comandos de instrumentos sin tener que implementar protocolos de comunicación de bajo nivel.(Sin crear driver!)
Pero por más que busque información no encontré nada.  :cry:  :cry:
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 18 de Marzo de 2009, 16:18:06
Oye como que está dificil llegar a esa velocidad. Yo no he podido medir la velocidad con presición.

usando VB6 inserté un código especialmente para medir la velocidad de los datos, según los resultados, llego a 5kbps en transmitir y como 500kbps en recibir. Pero no me fío porque el vb6 es monoproceso  :?

la pregunta que te iba hacer santiago es como estas midiendo la velocidad, de cuanto es el ancho del endpoint? porque si lo configuras por ejemplo a 64bytes y envias 11, entonces los calculos podrian ser erroneos.


...
Todos estos tiempos los medí con un osciloscopio que se conecta a un led que indica mediante ceros y unos la ejecución del usb (a modo de breakpoint).
...

y ¿cuando empiezas a contar el tiempo de inicio de transmisión?

Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 18 de Marzo de 2009, 17:59:18
Ah, es fácil Pali. Usando un osciloscopio conectado a un pin del pic y enviando datos por usb cíclicamente modo bulk...

Código: [Seleccionar]
            do{
               output_high(USBOK);
               MideMCP3201(); //Hace medición de los 5 ADC's
               output_low(USBOK);           
               transOK=0; //No ha enviado paquete
               while(transOK==0) //No pudo enviar, intenta de nuevo
                  transOK=usb_put_packet(1, doutprima, 12, USB_DTS_TOGGLE);
               }while(ByteRec[1]--);

Cuando el led está encendido está llevándose a cabo la medición ADC. Cuando el led está apagado se está intentando enviar el paquete de 12 bytes a la pc.

La función usb_put_packet entrega un 1 cuando el paquete ya llegó a la pc. Cuando el paquete sigue en espera en el endpoint del pic (ya se pasó al buffer pero no ha llegado a la pc) entonces usb_put_packet entrega un 0.

Esta rutina en particular es la que me entrega 5.85kBps (kilo Bytes por segundo). El cálculo es el siguiente...

Tiempo ADC = 10us (medido con osciloscopio y confirmado contando instrucciones en ensamblador).
Tiempo envío paquete 12 bytes = 2ms (medido con osciloscopio)

Tadc + Tusb = 2.01ms

12bytes / 2.01ms = 5970.1 Bytes / s = 5.9kBps

Ahora una rutina cdc...

Código: [Seleccionar]
      if(usb_cdc_kbhit()) //Si se recibe petición
         {
         comando=usb_cdc_getc();
         //Si el comando es 'a'
         if(comando=='a')
            {
            while(1)
               {
               //Para medir el tiempo desde la medición hasta que ya se envió por USB
               //enciendo la terminal RB7 (solo para debug)
               //Tiempo en alto = Medición ADC (se espera que sea 10us)
               //Tiempo en bajo = Lectura y envío USB (se espera que sea 40.2us)
               output_high(USBOK);
               MideMCP3201(); //Hace medición de los 5 ADC's
               output_low(USBOK);
               usb_cdc_putc(doutprima[0]);
               usb_cdc_putc(doutprima[1]);
               usb_cdc_putc(doutprima[2]);
               usb_cdc_putc(doutprima[3]);
               usb_cdc_putc(doutprima[4]);
               usb_cdc_putc(doutprima[5]);
               usb_cdc_putc(doutprima[6]);
               usb_cdc_putc(doutprima[7]);
               usb_cdc_putc(doutprima[8]);
               usb_cdc_putc(doutprima[9]);
               usb_cdc_putc(doutprima[10]);
               usb_cdc_putc(doutprima[11]);
               }
            }
         }

De la misma forma, cuando el led está encendido se está midiendo el ADC (10us). El tiempo que tarda enviar 12 bytes usando usb_cdc_putc es de 40.2us (led apagado), pero no es constante, hay unos tiempos "muertos" de 550us entre envíos que sospecho son los tiempos en que la pc le manda el token de petición de datos al usb; sospecho que el pic atiende esa interrupción para escuchar a la pc.

No hay forma de calcular la velocidad ya que los 550us se presentan de forma aleatoria entre envíos. Si esos 550us no existieran o los despreciara entonces me aventuraría a calcular la velocidad así...

Tadc = 10us
Tusb = 40.2us

Tadc + Tusb = 50.2us

12bytes / 50.2us = 239043 bytes/s

Te darás cuenta que el método que implemento es a modo de breakpoint, pero no detengo la ejecución del programa, con un led veo exactamente cuándo el pic pasa por cada instrucción y qué tiempo toma llevar a acabo varias.

Edito:

Y contestando tu pregunta de cuándo empiezo a contar el tiempo, no cuento tiempo de inicio... saco una velocidad con un solo envío de paquete (bulk) o byte (cdc). El método funciona al 100% con el modo bulk ya que los envíos son casi constantes, pero no funciona con el cdc porque hay tiempos muertos aleatorios entre envíos.

Lo que puedo hacer es implementar una rutina como la tuya en la que se cuentan los bytes recibidos y se dividen entre el tiempo transcurrido, de esa forma sacaría una velocidad promedio.

Mi problema es que no puedo trabajar con una velocidad promedio, necesito una velocidad constante ya que no puedo retrasar o adelantar la toma de muestras del adc. Los tiempos muertos de 550us son los que me ponen en jaque mate.  :(
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 19 de Marzo de 2009, 12:51:07
he revisado un poco los drivers de ccs y configuran el ancho de los datos a 64 bytes

usb_cdc.h

...
//pic to pc endpoint config
...
#define USB_CDC_DATA_IN_SIZE           64
#define USB_EP2_TX_ENABLE  USB_ENABLE_BULK
...


asi que tendrás que enviar el máximo de datos disponible ó fijar el size que necesites, (yo creo que es mejor enviar los mas que se pueda)

para asegurarte que funciona de esta manera, usa algún sniffer usb, puede ser el snoopy o el USBTrace. allí te mostrará los paquetes de datos que recibe el host.

Lo que queda de momento es mirar secciones de código donde se cambien los parámetros, porque del resto es hacer ensayos y ensayos  :(


Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 19 de Marzo de 2009, 15:25:18
De todas formas el cdc que emula serial no me va a servir. La máxima velocidad que la hyperterminal puede emplear con el puerto virtual es de 921600bps. Si eso lo paso a bytes "reales"...

921600bits/s = 92160bytes / s (8 bits + bit inicio + bit stop = 10 bits por byte enviado)

92.1kBps

Apenas y llego a la velocidad deseada, pero bueno haré la prueba de enviar 64 bytes juntos y te aviso.
Título: Re: Dudas USB y 12Mbps
Publicado por: MGLSOFT en 19 de Marzo de 2009, 16:50:20
No se supone que USB 2.0 funciona a 10 o 12 Mbit/seg ??? :shock: :shock: :shock:
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 19 de Marzo de 2009, 17:02:06
12Mbps con el hardware y el software apropiado. A mi me falta el software (firmware) apropiado para el pic.
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 19 de Marzo de 2009, 20:14:32
Recuerdo que habia algo llamado PING PONG, no soportado en las librerias del ccs pero si implementado en el hardware de los pic18 con usb. Lei tb que esto hacia que la velocidad sea mas rapida ya que era algo como que enviaba mientras guardaba o algo asi, no recuerdo bien. Pero quiza habilitando esto se pueda llegar o aproximarse mas a los 12mbps del USB que tienen los pic18. No he nisiquiera intentado usar el PING PONG tampoco, losiento.  :(

Salu2.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 19 de Marzo de 2009, 22:55:24
Cierto, he leído sobre el ping pong y su posible mejora de velocidad pero usando CCS no podremos llegar lejos...

http://www.todopic.com.ar/foros/index.php?topic=2348.msg203749#msg203749
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 20 de Marzo de 2009, 11:12:01
No se supone que USB 2.0 funciona a 10 o 12 Mbit/seg ??? :shock: :shock: :shock:

12Mbps solo por el tránsito en el cable, más no el tiempo que tarda que el pic en enviar el dato, hasta que lo recibe la aplicación en el PC. El mismo microchip lo advierte en uno de sus documentos.

El otro problema Santiago es el tiempo de latencia, como sabrás en USB nada se hace sin que el host pregunte, bueno hay un tiempo en el que el host debe preguntar para que el device le envíe nuevos datos.

Hay que buscar en la maraña de codigos del stack usb del ccs la parte donde debe ajustarse ese tiempo.

Te voy a poner un ejemplo en el que estoy trabajando ahorita.

con la clase HID a full speed, se puede enviar 64000 bytes/segundo, esto sería un poco mas de 500kbps, pero las preguntas(reportes) tienen un tiempo de latencia que cuando mucho 10ms para el low speed.

Bién, en el archivo usb_desc_hid.h aparece la configuración de este tiempo:

Código: C
  1. ...
  2.     #if USB_USE_FULL_SPEED
  3.          1,  //polling interval, in ms.  (cant be smaller than 10)      ==34
  4.       #else
  5.          10,  //polling interval, in ms.  (cant be smaller than 10)      ==34
  6.       #endif
  7. ...

es decir, que para full speed podemos tener 1ms de pérdida de tiempo cuando máximo!!

si envias 64 bytes por transacción, tal vez puedas compensar los tiempos de retraso para lograr una transmisión contínua.

¿porque no intentas usar HID?, no se pierde nada con intentar  :wink:


Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago 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:
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 20 de Marzo de 2009, 16:55:57
Santiago, creo que la solución al problema es crear un buffer circular (http://en.wikipedia.org/wiki/Circular_buffer) 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.

Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf 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.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago 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?
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 23 de Marzo de 2009, 23:54:17
No tenia ni idea de ESE (http://www.todopic.com.ar/foros/index.php?topic=25141.msg205522#msg205522) 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.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago 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

Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf 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.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago 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
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 24 de Marzo de 2009, 20:43:41
Siii yo tb hago algo parecido, AQUI (http://www.todopic.com.ar/foros/index.php?topic=2260.msg153477#msg153477) 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.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago 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.
Título: Re: Dudas USB y 12Mbps
Publicado por: Modulay 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 (http://www.todopic.com.ar/foros/index.php?topic=21145.0)
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago 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.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago 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:
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago 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).

(http://img22.imageshack.us/img22/5188/handles.jpg)

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 (http://labs.mike-obrien.net/view.aspx?projectid=hidlibrary) pero tampoco hubo éxito.
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf 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.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 31 de Marzo de 2009, 19:38:55
Puff con razón  :D

Gracias Jeremy.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 01 de Abril de 2009, 14:36:23
Todavía no logro echarlo a andar.

Ya modifiqué la función OpenPipes y aún así no me regresa handles válidos.

(http://img187.imageshack.us/img187/5188/handles.jpg)

Mi programa en el pic es así...

Código: [Seleccionar]
while(TRUE)
   {
   if(usb_enumerated())
      {
      //Si la pc ya pidió el paquete
      if(usb_kbhit(1))
         {
         usb_get_packet(1, buffer_in, 2);
         //Si el comando es envío de muestras 0xee
         if(buffer_in[0]==0xee)
            envio_pend=1;
         }
      //Si hay envío pendiente y ya hay paquete de 50 bytes armado
      if((envio_pend)&&(apunta>49))
         {
         //Envía arreglo de mediciones
         usb_put_packet(1, buffer_out, 64, USB_DTS_TOGGLE);
         //En último byte de paquete indica las muestras que contiene
         buffer_out[63]=apunta;
         apunta=0;
         envio_pend=0;
         }     
      }   
   }

Lo que hace es enviar el paquete de 64 bytes solo cuando la pc lo pide (buffer_in[0]==0xee).

¿Hay algún otro detalle sobre el modo HID que yo esté ignorando? ¿Hay que hacer envíos en todo momento para mantener viva la conexión usb?
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 01 de Abril de 2009, 22:05:26
migsantiago, has cambiado los drivers en el pic para configurarlo de Bulk a HID ?? Me refiero al archivo descriptor y el uso de los endpoints como USB_ENABLE_INTERRUPT y esas cosas.

Prueba tb modificando los pid y reinstalando todo d nuevo.

salu2.
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 02 de Abril de 2009, 13:30:35
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.

...

un par de preguntas:

¿con HID lograste hacer transferencias exitosas pc<->pic?

no entiendo porque mezclas bulk con hid, si el modo permitido en hid es interrupt.


....¿Hay algún otro detalle sobre el modo HID que yo esté ignorando? ¿Hay que hacer envíos en todo momento para mantener viva la conexión usb?

Aún no me he metido con la libreria HIDLibrary, pero esos pipes que ellos mencionan allí no tienen relación con la dll de microchip (para corroborar mira el source code de HIDLibrary)

la forma en la que la he probado, se basa en usar apis de windows, allí para iniciar una conexión, se llama  la api CreateFile.

una vez checado CreateFile, la única forma de cerrar el "pipe" es con la api CloseHandle


Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 02 de Abril de 2009, 14:46:16
migsantiago, has cambiado los drivers en el pic para configurarlo de Bulk a HID ?? Me refiero al archivo descriptor y el uso de los endpoints como USB_ENABLE_INTERRUPT y esas cosas.

Prueba tb modificando los pid y reinstalando todo d nuevo.

salu2.

Hola Jeremy y Pedro

Los drivers del pic ya están como HID, usé el archivo usb_desc_hid.h para configurarlo y el archivo principal está basado en el ex_usb_hid.c de CCS. EL VID&PID (04d8 y 0101) que uso, también ya está configurado en el descriptor hid. Adjunto el archivo usb_desc_hid.h por si ustedes creen que merece una 2da revisión.

http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=25188.0;attach=8839

Al conectar el PIC al puerto USB de la PC se reconoce como HID y Windows lo instala sin problemas; aparece en el administrador de dispositivos 2 veces (cosa rara).

Una dice HID\VID_04D8&PID_0101\6&3907A97F&0&0000
Y la otra dice USB\VID_04D8&PID_0101\5&11DAD59D&0&1

(http://img208.imageshack.us/img208/3293/pidvid.jpg)

Mi problema está en que no logro comunicar el pic con mi aplicación en C# usando la mpusbapi.dll ni la HIDLibrary.  :8}
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 08 de Abril de 2009, 17:34:57
Hola

Descubrí que para implementar comunicaciones HID con reportes de envío y recepción mayores a 2 bytes no basta con declarar:

Código: [Seleccionar]
#DEFINE USB_HID_DEVICE  TRUE
#define USB_EP1_TX_ENABLE  USB_ENABLE_INTERRUPT   //turn on EP1 for IN bulk/interrupt transfers
#define USB_EP1_TX_SIZE    64  //allocate 8 bytes in the hardware for transmission
#define USB_EP1_RX_ENABLE  USB_ENABLE_INTERRUPT   //turn on EP1 for OUT bulk/interrupt transfers
#define USB_EP1_RX_SIZE    8  //allocate 8 bytes in the hardware for reception

También hay que modificar el archivo descriptor en la parte de los reportes. El reporte INPUT es el tamaño de transmisión hacia la pc (punto de vista invertido) y el OUTPUT es el recibido por el pic. Las modificaciones están marcadas:

Código: [Seleccionar]
   const char USB_CLASS_SPECIFIC_DESC[] = {
      6, 0, 255,    // Usage Page = Vendor Defined
      9, 1,            // Usage = IO device
      0xa1, 1,       // Collection = Application
      0x19, 1,        // Usage minimum
      0x29, 8,        // Usage maximum

      0x15, 0x80,        // Logical minimum (-128)
      0x25, 0x7F,        // Logical maximum (127)

      0x75, 8,        // Report size = 8 (bits)
      //0x95, 2,        // Report count = 16 bits (2 bytes)
      0x95, 64,        // Report count = 64 bytes (MODIFICACION)
      0x81, 2,        // Input (Data, Var, Abs)
      0x19, 1,        // Usage minimum
      0x29, 8,        // Usage maximum
      0x75, 8,        // Report size = 8 (bits)
      //0x95, 2,        // Report count = 16 bits (2 bytes)
      0x95, 8,        // Report count = 8 bytes (MODIFICACION)
      0x91, 2,        // Output (Data, Var, Abs)
      0xc0            // End Collection
   };

Para probar mi programa estoy usando una aplicación que encontré llamada GenericHID en VC#:

http://www.lvr.com/hidpage.htm

(http://img227.imageshack.us/img227/2432/dibujoyuz.th.jpg) (http://img227.imageshack.us/img227/2432/dibujoyuz.jpg)

El programa envía un reporte del tamaño declarado en el descriptor y recibe un reporte de parte del pic. Cuando yo no había configurado el descriptor, el programa se trababa y mandaba excepciones o a veces sólo indicaba que no pudo leer el reporte de entrada.

Ahora que ya entablo correcta comunicación con la pc tendré que estudiar el generichid para ver si lo puedo usar. Por ahora ya me quité de otro peso de encima :)

Si no, tendré que seguir probando con la mpusbapi.  :P
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 17 de Abril de 2009, 18:43:04
Ya logré comunicar el pic con la pc con esta configuración:

HID con polling in y out de 1ms (descriptor)
Endpoint 1
64bytes por paquete

El paquete lo envío hasta que acumulo 25 mediciones de la señal (2bytes x 25 = 50bytes). Lo curioso es que el pic no puede enviar paquetes cada 1ms, lo hace cada 1.73ms aproximadamente. Esto lo mido con osciloscopio y sabiendo que usb_put_packet confirma la entrega del paquete (regresa un bool = 1).

Código: [Seleccionar]
      //debug
      output_high(USBOK);
      //Pone el buffer en el endpoint y espera hasta que se haya enviado
      while(!(usb_put_packet(1, buffer_out, 64, USB_DTS_TOGGLE)));     
      //debug
      output_low(USBOK);

El retraso se debe en parte a que usb_put_packet hace muchas cosas:

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

Así es como entiendo lo que hace putpacket:
- Primero verifica si la SIE no está manipulando el arreglo del endpoint de envío (bit 7 de i UOWN)
- Luego obtiene la dirección ram de dónde empieza el arreglo del endpoint
- Luego copia byte por byte el arreglo que se va a enviar al arreglo del endpoint
- Por último, ejecuta usb_flush_in que hace lo siguiente:

Código: [Seleccionar]
int1 usb_flush_in(int8 endpoint, int16 len, USB_DTS_BIT tgl) {
   int8 i;

   debug_usb(debug_putc,"\r\nPUT %X %U %LU",endpoint, tgl, len);

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

      EP_BDxCNT_I(endpoint)=len;

     debug_display_ram(len, EP_BDxADR_I(endpoint));

     #if USB_IGNORE_TX_DTS
      i=0x80;
     #else
      if (tgl == USB_DTS_TOGGLE) {
         i=EP_BDxST_I(endpoint);
         if (bit_test(i,6))
            tgl=USB_DTS_DATA0;  //was DATA1, goto DATA0
         else
            tgl=USB_DTS_DATA1;  //was DATA0, goto DATA1
      }
      else if (tgl == USB_DTS_USERX) {
         i=EP_BDxST_O(endpoint);
         if (bit_test(i,6))
            tgl=USB_DTS_DATA1;
         else
            tgl=USB_DTS_DATA0;
      }
      if (tgl == USB_DTS_DATA1) {
         i=0xC8;  //DATA1, UOWN
      }
      else if (tgl == USB_DTS_DATA0) {
         i=0x88; //DATA0, UOWN
      }
     #endif

      //set BC8 and BC9
      if (bit_test(len,8)) {bit_set(i,0);}
      if (bit_test(len,9)) {bit_set(i,1);}

      debug_usb(debug_putc," %X",i);

      EP_BDxST_I(endpoint)=i;//save changes

      return(1);
   }
    else {
         debug_usb(debug_putc,"\r\nPUT ERR");
    }
   return(0);
}

   + Vuelve a verificar si la SIE está haciendo algo con el endpoint
   + Escribe en un registro USB (CNTI) los bytes que se enviarán del arreglo del endpoint
   + Por último copia los 2 bits más significativos de len y los anexa a BDSTAT
   + Todo lo anterior solo si la SIE no está manipulando el endpoint, y regresará un 1
   + Si la SIE estaba trabajando, entonces no se ejecuta lo anterior y se regresa un 0

Todo esto toma mucho tiempo y pues talvez se pueda mejorar. Voy a ver si mejoro esta función y si logro un polling menor a 1.73ms. Todo basándome en el tema de Modulay en el que gestiona una parte de la interrupción USB. :mrgreen:
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 18 de Abril de 2009, 01:16:34
a eso es lo que microchip le llama overhead, todo el código que tiene que procesar de forma tranasparente al programador. siempre habrá overhead, la pregunta es si con los otros modos, podrás disminuir ese tiempo. :(

Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 18 de Abril de 2009, 15:10:45
a eso es lo que microchip le llama overhead, todo el código que tiene que procesar de forma tranasparente al programador. siempre habrá overhead, la pregunta es si con los otros modos, podrás disminuir ese tiempo. :(



Hey Pali, ¿a qué otros modos te refieres?

En el modo pingpong podría ahorrarme la copia del buffer a enviar hacia el buffer del endpoint, pero hay mucho que modificar para que el pingpong se habilite  :?
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 18 de Abril de 2009, 22:51:54
me refiero a bulk ó cdc.

cada vez reconozco que cualquier transmisión de datos sea por el puerto que sea debe ser asíncrona, es decir, aún la transmisión de datos en tiempo real se monta sobre un proceso asincrono, es como el tema de enviar voz sobre ip.

yo creo santiago que la clave es enviar mas datos en cada transacción para compensar el muestreo que quieres mantener.

hay que estudiar la posibilidad de usar los otros endpoints, no importa si usas hid, cdc o bulk por mpusbaapi.dll, ahora el problema no es enviar datos sino mantener el tiempo de muestreo máximo.




Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 19 de Abril de 2009, 12:11:23
Sí, ahora solo uso 1 endpoint y con el máximo de 64bytes. Dame chance de escribir una función usb_put_packet súper ligera y luego veo si puedo implementar al menos un 2do endpoint.  :mrgreen:
Título: Re: Dudas USB y 12Mbps
Publicado por: ElVale en 27 de Abril de 2009, 01:55:23
Esta discusión está interesante y la he seguido con atención aunque no la he entendido 100% ya que no estoy tan versado en USB como ustedes pero mi objetivo es al parecer el mismo: aclarar las dudas sobre la máxima velocidad de transmisión por USB. Al respecto comento que leyendo un pdf (AN1164 (http://ww1.microchip.com/downloads/en/AppNotes/01164a.pdf)) de microchip sobre implementación cdc en 18f4550 me llamó la atención un parrafo:

Citar
The following macros define the default line coding settings
that the CDC serial driver reports in response to
the host’s GET_LINE_CODING request. Keep in mind
that, in a USB environment, communication occurs at
speeds defined by the USB protocol and most hosts
will set the line coding parameters as desired. None the
less, the default values reported can be changed by
changing the following macros.
// Bit Rate
CDC_DEFAULT_BPS 115200

// 1 stop bit
CDC_DEFAULT_FORMAT 0
// No parity
CDC_DEFAULT_PARITY 0
// 8-bits per word
CDC_DEFAULT_NUM_BITS 8

Osea que los baudios que uno conoce en rs232 son solo una formalidad en cdc pero que en realidad uno pone lo que quiere, o mas bien lo que puede. A respecto encontré un post en un foro (link (http://forum.sparkfun.com/viewtopic.php?p=57591&sid=5f285ef57f556c7110067a03b38ae60d))en donde se expone como en teoría se pueden alcanzar hasta 700KB/s en cdc aunque no quedarían ciclos de CPU suficientes para hacer algo útil al respecto.

Respecto a los endpoints, leyendo el pic18_usb.h se tienen hasta 16 endpoints en el 18f4550, no lo he probado pero entonces llamando el MPUSBRead() con tamaño de buffer de 1024 al pic le llegarían 16 tokens por cada trama de 1ms serían 1048576 Bytes por segundo o más de 8Mbps. Referencia: link (http://www.microchip.com/forums/tm.aspx?m=321195)

Respecto a isocrono, bueno al parecer CCS está en pañales al respecto y por lo que he leído el data packet no es de 64 sino de 1023 bytes y no se pero parece que es un data packet por 1ms alcanzando los 8Mbps pero sin los tiempos muertos sin embargo como los 18f solo tienen 200 bytes de ram usb, esto no se puede.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 27 de Abril de 2009, 11:02:53
Hola Vale

Cierto lo del modo CDC, en CCS se modifica en usb_cdc.h en esta sección:

Código: [Seleccionar]
void usb_cdc_init(void) {
   usb_cdc_line_coding.dwDTERrate=921600;
   usb_cdc_line_coding.bCharFormat=0;
   usb_cdc_line_coding.bParityType=0;
   usb_cdc_line_coding.bDataBits=8;
   (int8)usb_cdc_carrier=0;
   usb_cdc_got_set_line_coding=FALSE;
   usb_cdc_break=0;
   usb_cdc_put_buffer_nextin=0;
   usb_cdc_get_buffer_status.got=0;
   usb_cdc_put_buffer_free=TRUE;
}

El máximo que acepta la hyperterminal es de 921600. Si dividimos entre 10 (1 bit de inicio, 8 bits dato, 1 bit stop) tenemos 92160 bytes por segundo, 92.16kB/s.

Además el envío de este tipo es con velocidad no constante como lo vi en una prueba. Todavía tengo que experimentarlo más, pero por ahora me está gustando el modo HID ya que es con polling constante.

Lo malo es que esta semana va a estar difícil experimentar porque dejé mi programador en la escuela y acá en México estamos en cuarentena  :(

Sobre la ram usb, el pic18f2550 tiene 1kByte de ram específica para USB, donde el banco 4 (256bytes) se usa para control y el 5, 6 y 7 para datos (768bytes en endpoints).

(http://img26.imageshack.us/img26/1103/ramlkm.jpg)
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 28 de Abril de 2009, 17:12:41
Esta discusión está interesante y la he seguido con atención aunque no la he entendido 100% ya que no estoy tan versado en USB como ustedes...

no te creas, yo también estoy en pañales con esto del usb, las cosas que he hecho han sido por mas de pruebas de ensayo y error. La teoría es muy bonita pero cuando toca entender una implementación, todo se viene abajo  :D

Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 28 de Abril de 2009, 17:56:57
Cierto, yo también aprendo con prueba y error. El saberse el USB completo está muuuy difícil.
Título: Re: Dudas USB y 12Mbps
Publicado por: washi_w_z_r en 01 de Mayo de 2009, 14:29:57
hola , yo envio datos por cinco canales analog , al recepcionar solo uno en mi prgo en c# vuela como los dioses  :-/ , pero al habilitar cicanales se pone muy lento , por mi parte vi este parrafo en archivo .h

Código: C#
  1. //interface descriptor 0 alt 0
  2.          USB_DESC_INTERFACE_LEN,  //length of descriptor
  3.          USB_DESC_INTERFACE_TYPE,      //constant INTERFACE (0x04)
  4.          0x00,                //number defining this interface (IF we had more than one interface)
  5.          0x00,                //alternate setting
  6.          2,       //number of endpoints, not counting endpoint 0.
  7.          0xFF,                //class code, FF = vendor defined
  8.          0xFF,                //subclass code, FF = vendor
  9.          0xFF,                //protocol code, FF = vendor
  10.          0x00,                //index of string descriptor for interface

en la parte del descriptor , observo lo siguiente :

  2,       //number of endpoints, not counting endpoint 0.

intente aumentar el numero de endpoint hasta 6(contando con el enpoint 0 correspondiente ala descripcion del pic)


  6,       //number of endpoints, not counting endpoint 0.

luego en la parte de :

#DEFINE USB_TOTAL_CONFIG_LEN     32//config+interface+class+endpoint

cambio por:

#DEFINE USB_TOTAL_CONFIG_LEN      88 //config+interface+class+endpoint

 todo esto para obtener mayor velocidad en la transmicion de los datos del adc ,eso fue lo que pense ,
compile sin problemas , pero la PC ya no reconoce mi dispositvo, al parecer el driver no me lo permite , asi que volvi a un solo endpoint y envio 10 bytes (particionando los LSB y MSB ya que uso pic18f4458 q soporta USB2.0+12bit ADC), pero bueno hice varias pruebas enviar 50 bytes , 40 bytes ,.... hasta llegar al minimo de 10 bytes , cuando envio mas de 10 bytes si que se pone lento aun no tengo idea del ¿por que? , sera por mi prog en c# , por el cod firmware , aun no lo se , pero aqui le dejo un pantallazo de lo que reciboe ne mi prog en c# , saludos



Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 01 de Mayo de 2009, 15:23:21
Me parece que el muestreo de la imagen que adjuntas es inestable.

¿Cómo es la señal original que mides en cada canal del pic? ¿Cuánta velocidad has obtenido? ¿Tienes una frecuencia de muestreo mayor a la frecuencia útil de la señal? Es recomendable que sea de hasta 10 veces la frecuencia útil. ¿Das tiempo al canal del pic para que el capacitor sample&hold se cargue?

Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 20 de Mayo de 2009, 18:03:13
Bueno, después de un retraso inesperado regresé a lo del USB.

Logré mejorar el tiempo de ejecución de la función usb_put_packet de 740us a 570us.  :mrgreen:

(http://img199.imageshack.us/img199/4817/dsc00156p.th.jpg) (http://img199.imageshack.us/img199/4817/dsc00156p.jpg) (http://img199.imageshack.us/img199/5324/dsc00162e.th.jpg) (http://img199.imageshack.us/img199/5324/dsc00162e.jpg)

Básicamente reduje el tiempo usando constantes de direcciones RAM, eliminé unas rutinas redundantes en las que se hace el toggle del PID DATA0 o DATA1, coloqué el buffer a enviar en el mismo banco de los endpoint USB (banco 5 0x05C0) y quité la opción de enviar 1024bytes por paquete ya que en HID el máximo es de 64bytes.

La función siempre espera a que el endpoint esté disponible (UOWN = 0) para manipularlo, no es como la de CCS que entrega un 0 si no pudo manipularlo. Esta se espera hasta que se puede.

Todavía me falta mejorar el tiempo de otras funciones, pero bueno 170us de ahorro son algo  :D

Descarga usb_fast.h
http://www.4shared.com/file/106692845/cb1ba8bd/usb_fast.html

Para implementarla solo se requiere:
- Solo debe haberse configurado el EP0 y EP1
- Paquete debe ser de hasta 64bytes de largo
- El buffer a enviar deberá iniciar en 0x05C0 (banco 5, usar #locate)
- El PID de la transacción lleva toggle DATA0 y DATA1

El prototipo de la función es más simple:

Código: [Seleccionar]
/*
Librería USB Fast
Santiago Villafuerte
http://www.migsantiago.com
*/

#define STATUS_EP1_IN   0x040C
#define UOWN            7
#define DTS             6
#define CNT_EP1_IN      0x040D
#define ADRL_EP1_IN     0x040E
#define ADRH_EP1_IN     0x040F

////////////////////////////////////////////////////////////////////////////////
//Función put_usb_fast1
//Ejecuta put_usb_packet de forma rápida para el endpoint 1
//
//Requisitos:
//- Solo debe haberse configurado el EP0 y EP1
//- Paquete debe ser de hasta 64bytes de largo
//- El buffer a enviar deberá iniciar en 0x05C0 (banco 5)
//- El paquete lleva toggle DATA0 y DATA1
//
void usb_put_fast_1(int8 *buffer, int8 len)
{
int8 i;
int8 *buffer_ep1;

//Copia la dirección del buffer ep1
buffer_ep1 = *(int16 *)ADRL_EP1_IN;

//Espera a que la SIE deje de manipular el endpoint
while(bit_test(*(STATUS_EP1_IN),UOWN));

//Copia los bytes del buffer al endpoint
//Es recomendable que buffer esté ubicado en las 64 últimas posiciones del
//banco 5 para reducir tiempo entre saltos de banco
for(i=0; i<len; ++i)
   {
   *buffer_ep1 = *buffer;
   ++buffer_ep1;
   ++buffer;
   }

//Indica cuántos bytes de enviarán (no hace falta escribir BC9:BC8)
*(CNT_EP1_IN) = len;

//Invierte el bit de datos de paquete DTS (data toggle sync) y
//activa el envío del endpoint levantando UOWN
if(bit_test(*(STATUS_EP1_IN),DTS))
   *(STATUS_EP1_IN)= 0b10001000; //UOWN=1, DTS=0, DTSEN=1
else
   *(STATUS_EP1_IN)= 0b11001000; //UOWN=1, DTS=1, DTSEN=1
}
////////////////////////////////////////////////////////////////////////////////
Título: Re: Dudas USB y 12Mbps
Publicado por: MGLSOFT en 20 de Mayo de 2009, 18:23:23
Alguien sabe como hacer una aplicacion CDC que maneje las lineas de control del port serial, ademas de RX y TX ??
Perdon si no es el lugar de consulta, por favor moverlo a donde crean conveniente... :)
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 07 de Agosto de 2009, 16:56:30
migsantiago, eso lo estas haciendo con la mpusbapi.dll ?? Porque ahora que yo lo estoy necesitando (comunicion USB HID en VC# por mpusbapi.dll) no me esta funcionando, ni un byte puedo enviar. Lograste saber porque era esto ??


Gracias, Salu2.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 07 de Agosto de 2009, 17:20:12
Hola Jeremy

Mi HID no funcionaba porque me faltó modificar correctamente el archivo de descriptores, acá publiqué mi error:

http://www.todopic.com.ar/foros/index.php?topic=25188.msg208502#msg208502
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 07 de Agosto de 2009, 17:50:13
Estas usando el VC# con la mpusbapi.dll ?? Que es lo que haces entonces en el vc# porque simplemente quiero enviar un byte al pic y que se prenda un led pero ni eso pasa =S no encuentro el error.

Código: [Seleccionar]

#INCLUDE <18F4550.h>
#FUSES XTPLL, PLL1, CPUDIV1, VREGEN, USBDIV, NOMCLR, NOWDT, PROTECT, NOLVP, NODEBUG
#USE DELAY(CLOCK = 48000000)

#DEFINE USB_HID_DEVICE     TRUE
#DEFINE USB_EP1_TX_ENABLE  USB_ENABLE_INTERRUPT
#DEFINE USB_EP1_TX_SIZE    8 
#DEFINE USB_EP1_RX_ENABLE  USB_ENABLE_INTERRUPT 
#DEFINE USB_EP1_RX_SIZE    8 

#DEFINE USB_CON_SENSE_PIN  PIN_C2
#DEFINE LED_TEST_1         PIN_A0
#DEFINE LED_TEST_2         PIN_A1

#INCLUDE <pic18_usb.h>   
#INCLUDE "usb_desc_hid.h"
#INCLUDE <usb.c>     

unsigned int8 Recibe[64], Envia[64];

void Main(void)
{
   int16 Cont = 0;

   usb_init_cs();
   
   while (true)
   {
      usb_task();
     
      if (Cont++ > 10000) {output_toggle(LED_TEST_1); Cont = 0;}
     
      if (usb_enumerated() == true)
      {     
         if (usb_kbhit(1) == true)
         {
            output_high(LED_TEST_2);
            usb_get_packet(1, Recibe, 2);
         }
      }
   }
}


La pc reconoce todo bien el dispositivo como hid y lo instala y todo. pero no puedo enviar un misero byte para que se prenda el led_test_2. Cambiando los papeles, aora yo soy el de los problemas con el HID  :D


Salu2
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 07 de Agosto de 2009, 19:46:12
Jeremy para HID no hace falta usar esa libreria. usa el software de Jan:


(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=25188.0;attach=9820)


se descarga en: http://www.lvr.com/hidpage.htm

Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 07 de Agosto de 2009, 21:48:49
Ayaaaaaaaaa... ya entendi. Pense que cuando migsantiago mencionaba al GenreHID en el post al que memando, se referia a esos programas que es para ver lo que pasa en las comunicaciones usb. Por eso creia que no lo habia solucionado (almnos no con la mpusbapi.dll)

Pero bueno, al parecer con esto lo tengo tb solucionado. Ahora a investigar todo lo que hace y ajustarlo deacuerdo a lo que necesito.

Gracias Pali y migsantiago.
Salu2.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 07 de Agosto de 2009, 23:15:36
Exacto, usé la librería de Jan Axelson.

Nunca pude usar HID con mpusbapi.dll.
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 08 de Agosto de 2009, 02:15:36
Nunca pude usar HID con mpusbapi.dll.
Nadie hombre. He estado buscando info en el foro, en san google y nada, no he encontrado nada. Tan dificil o algo asi es xD!


Salu2
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 08 de Agosto de 2009, 03:07:32
Porcierto, sabes donde en esa libreria en VC# modifico para enviar más o menos bytes? Porque por default (nose donde) esta en 3, almeenos asi me lo muestra cuando hago:
Código: [Seleccionar]
MessageBox.Show(MyHid.Capabilities.OutputReportByteLength.ToString());


Gracias, salu2.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 08 de Agosto de 2009, 11:55:13
No depende de VC# el tamaño de los reportes, depende de cuántos bytes el PIC les dé.

Código: [Seleccionar]
     0x75, 8,        // Report size = 8 (bits)
      //0x95, 2,        // Report count = 16 bits (2 bytes)
      0x95, 64,        // Report count = 64 bytes (MODIFICACION)
      0x81, 2,        // Input (Data, Var, Abs)
      0x19, 1,        // Usage minimum
      0x29, 8,        // Usage maximum
      0x75, 8,        // Report size = 8 (bits)
      //0x95, 2,        // Report count = 16 bits (2 bytes)
      0x95, 8,        // Report count = 8 bytes (MODIFICACION)
      0x91, 2,        // Output (Data, Var, Abs)
      0xc0            // End Collection

Checa tu archivo .h de descriptores. Si te salen 3 es porque se agrega un byte al inicio de los reportes y solo son 2 los que has declarado.

En el caso de arriba, el input report será de 65 bytes y el output deberá ser de 9 bytes. El primer byte de ambos es como un identificador de reporte que aún no entiendo pero que debes dejar en 0x00, sin que afecte tus I/O de datos.

Puedes usar este software para verificar el tamaño de reporte de tu pic:

SimpleHIDWrite3.zip
http://www.lvr.com/hidpage.htm
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 08 de Agosto de 2009, 16:24:38
Eso lo supe por algun post anterior qe pusiste. Y lo hice asi tb, puse a los dos en 64 bytes (el maximo) y por el lado de la PC el:
Código: [Seleccionar]
MessageBox.Show(MyHid.Capabilities.OutputReportByteLength.ToString()); me seguie mandando 3 nomas =S

Gracias, seguire probando.
Salu2
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 08 de Agosto de 2009, 17:40:17
Veo inconsistencias en tu código... mencionas que en el descriptor ambos endpoints son de 64 bytes, pero en el main.c declaras los endpoints de 8 bytes y en la petición de datos pides 2 bytes  :z)

Código: [Seleccionar]
#DEFINE USB_HID_DEVICE     TRUE
#DEFINE USB_EP1_TX_ENABLE  USB_ENABLE_INTERRUPT
#DEFINE USB_EP1_TX_SIZE    8 
#DEFINE USB_EP1_RX_ENABLE  USB_ENABLE_INTERRUPT 
#DEFINE USB_EP1_RX_SIZE    8

Código: [Seleccionar]
usb_get_packet(1, Recibe, 2);
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 08 de Agosto de 2009, 23:25:18
jaja bueno he estado haciendo pruebas rapidas y pues, seguro se me paso por alto eso, a pesar de creer que lo hice todo correctamente. Ya seguire con esas pruebas, ahora, estoy teniendo problemas con otra cosa y pues nada, estare probando luego.

Gracias, salu2.
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 10 de Agosto de 2009, 12:35:10
Nunca pude usar HID con mpusbapi.dll.
Nadie hombre. He estado buscando info en el foro, en san google y nada, no he encontrado nada. Tan dificil o algo asi es xD!


Salu2

la respuesta es sencilla. mpusbapi.dll fué creada unicamente para manejar el modo BULK, los otros modos CDC y HID son clases, esto significa que son estandares que los sistemas operativos reconocen y traen en sus sistemas.

con BULK tienes que usar librerias (aunque se puede embeber el código fuente de mpusbapi.dll en la aplicación según leí en un post del amigo Jesús)

con CDC solamente necesitas un .inf para configurar el dispositivo.

con HID no necesitas NADA, enchufas y listo.


Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 10 de Agosto de 2009, 13:14:09
Bueno, pero la mpusbapi.dll sus funciones tb estan disponibles para manejar pipes de interrupcion, osea HID y, es mas, hasta el modo iscocrono. Aun asi, ya estoy bien con la mencionada antes, va bien!

Salu2.
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 10 de Agosto de 2009, 13:26:02
bueno yo no le he estudiado a fondo como funciona la dll, pero esos conceptos que mencionas estan en capas inferiores y se siguen usando en ambas clases. Los pipes siempre se crearan ya sea en hid o en bulk.

lo que pasa es que hablar de HID y modo isócrono son 2 cosas distintas, el usb es tab complejo que cuando se reunen un conjunto de caracteristicas, le asignan un nombre, lo separan y lo juntan en una "capa"

modos de transferencias:

http://usuarios.lycos.es/kurganz/datos_tecnicos/protocolo/prototrans.html

HID CDC MSD son interfaces o relación de software-dispositivo. Microchip no deberia mezclar BULK con HID porque son 2 cosas distintas,

Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 12 de Agosto de 2009, 18:42:11
Migsantiago, era eso. Ya lo probe bien todo y ahora me devuelve bien todo, gracias.

Gracias por la info tb Pali.


Salu2.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 12 de Agosto de 2009, 18:47:43
Vientos Jeremy.

A ver si en este semestre logro acelerar el USB del PIC con el modo ping pong, porque el pasado con la influenza y demás detalles me estanqué en esto.  :police:
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 25 de Agosto de 2009, 14:39:05
Bueno pues les traigo noticias sobre mis problemas  :D

Al fin he logrado que el PIC18F2550 pueda enviar 50 bytes cada 1ms usando modo HID.

Se sabe que el HID trabaja hasta 64kB/s en Full Speed. Esto se debe a que se configura un polling de 1ms con paquetes de 64bytes, por lo que en 1s se tienen 64,000 bytes enviados. HID en USB 2.0 no permite el uso de más de 2 endpoints: uno del tipo control para el setup y otro para datos interruptivo. Si hubiera más EP's la historia sería otra.

Al usar el ejemplo HID que CCS trae estos tiempos son imposibles de alcanzar ya que las librerías vienen muy generalizadas y ejecutan muchas instrucciones que toman mucho tiempo.

En uno de tantos intentos integré el uso del modo ping pong en el pic, pero por más que le busqué no encontré porqué el pic se desenumeraba  :oops:

Tuve que estudiar el funcionamiento de los Buffer Descriptors, la SIE y el procedimiento de envío de paquetes y para lograr un envío de 50kB/s esto es lo que hice.

- Configurar el HID con endpoint 1tx de 50 bytes de tamaño y 1ms de polling. El endpoint 1rx puede tener cualquier tamaño y polling (por ahora no lo usaré excesivamente).

- Mi muestreo se hace en una subrutina con el timer0 cada 40us, escribiendo 2 bytes por evento, teniendo 50bytes cada 1ms. Esta subrutina escribe en el primer buffer clon... directamente sobre la USB ram. Cuando se llena el buffer pasa al segundo buffer y así sucesivamente. En total hay 4 buffers de 50 bytes cada uno, localizados en estas direcciones de la usb ram (todas en el banco 6):

Buffer1 0x0600 a 0x0631
Buffer2 0x0632 a 0x0663
Buffer3 0x0664 a 0x0695
Buffer4 0x0696 a 0x06C7

- Cuando algún buffer se ha llenado entonces en el main se llama una función de envío USB que hace lo siguiente:
   + Recibe el número del buffer que está listo para envío
   + Espera indefinidamente que la SIE deje de controlar el endpoint 1
   + Escribe en el BD_CNT del EP1 el número 50 que equivale a los bytes a enviar por paquete (o reporte)
   + Modifica el ADRL_EP1 y ADRH_EP1 con la dirección ram del inicio del buffer a enviar
   + Invierte el bit DTS que sirve para dar paridad a los paquetes, de forma tal que si el paquete anterior es un DATA0, entonces el siguiente sea un DATA1
   + Por último levanta la bandera de la SIE que activa el envío del buffer cuando el HOST lo indique. Esto sucederá exactamente cada 1ms.

La ventaja de usar 4 buffers clones es que mientras la SIE está manipulando los 50 bytes de un buffer, yo me doy el lujo de estar preparando otro buffer para enviarlo. Esto es similar al modo ping pong, pero con trampa  :D

Otra ventaja que tiene mi función de envío es que el buffer ya está ubicado en la usb ram. La función de CCS mueve un buffer de la ram del usuario a la usb ram y eso toma tiempo. También se tarda porque espera a que la SIE pierda control de la ram, mientras que mi función garantiza que la usb ram está más que lista para salir del pic.

Código: [Seleccionar]
void usb_put_fast_1(int8 buffer, int8 len)
{
//Espera a que la SIE deje de manipular el endpoint
while(bit_test(*(STATUS_EP1_IN),UOWN));

//Indica cuántos bytes se enviarán (no hace falta escribir BC9:BC8)
*(CNT_EP1_IN) = len;

//Indica el comienzo del buffer a la SIE
//El byte alto siempre es 0x06
*(ADRH_EP1_IN) = 0x06; //primer buffer
//El byte bajo sí cambia
switch(buffer)
   {
   case 1:
      *(ADRL_EP1_IN) = 0x00; break;
   case 2:
      *(ADRL_EP1_IN) = 0x32; break;
   case 3:
      *(ADRL_EP1_IN) = 0x64; break;
   case 4:
      *(ADRL_EP1_IN) = 0x96; break;
   }

//Invierte el bit de datos de paquete DTS (data toggle sync) y
//activa el envío del endpoint levantando UOWN
if(bit_test(*(STATUS_EP1_IN),DTS))
   *(STATUS_EP1_IN)= 0b10001000; //UOWN=1, DTS=0, DTSEN=1
else
   *(STATUS_EP1_IN)= 0b11001000; //UOWN=1, DTS=1, DTSEN=1
}

Después para verificar que el pic realmente estuviera enviando los datos en tiempo y forma usé un analizador usb por software y otro por hardware.

(http://img22.imageshack.us/img22/4356/usbhidsan.th.jpg) (http://img22.imageshack.us/img22/4356/usbhidsan.jpg)

En la imagen se ve que cada que el HOST envía un paquete del tipo Start Of Frame también envía un paquete IN al pic pidiéndole los 50 bytes. El SOF en Full Speed es cada 1ms por lo que el PIC funciona como debe.

Y bueno... ahora la segunda problemática... leer desde Windows esos paquetes cada 1ms sin perderlos. Difícil porque Windows no garantiza ejecución de código en tiempos tan pequeños... pero bueno. A ver qué se me ocurre  :D
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 25 de Agosto de 2009, 16:56:56
vaya, ya tienes resuelto mas de la mitad del problema  :-/ :-/

...La ventaja de usar 4 buffers clones es que mientras la SIE está manipulando los 50 bytes de un buffer, yo me doy el lujo de estar preparando otro buffer para enviarlo. Esto es similar al modo ping pong, pero con trampa  :D
...

eso me recuerda a un tema del que estoy ansioso por meterle mano, se llama buffer circular.

http://en.wikipedia.org/wiki/Circular_buffer

se trata de usar una porción de memoria RAM y manipularlo en forma de arrays, e ir introduciendo datos de muestras e ir sacando datos de muestras. La idea es no detener un proceso síncrono o en tiempo real.

los sistemas de multimedia usan ese mismo proceso, Santiago me imagino que a estas alturas habrás notado que cualquier transferencia que se haga a un ordenador se hace por rafagas, asi que para mantener un muestreo en tiempo real, hay que montar un buffer circular del lado del pic y otro de lado del software del ordenador.

Esto yo lo veo maravilloso porque asi hacemos cualquier proceso de ejecución independiente de la velocidad de operación del micro. -¡Ven!- -ya me dieron ganas de ponerme a estudiar otra vez-  :mrgreen:

Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 25 de Agosto de 2009, 20:24:39
jajaja ¿y qué tiene de malo estudiar?  :D

Recuerdo el asunto del buffer circular, me lo recomendaste en este mismo tema... al parecer me sirvió de mucho  :D La pregunta es ¿para qué lo piensas usar?

Por otro lado estuve leyendo el USB complete de Jan Axelson y me enteré de que hay forma de usar la hid.dll como API. También hay forma de escribir drivers que manejan los devices directamente desde el kernel de Windows... acarreando la ventaja de que podría leer el usb cuando yo quiera ya que el kernel sí garantiza tiempos.

Vamos a ver qué puedo lograr  :D
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 27 de Agosto de 2009, 16:17:35
...Recuerdo el asunto del buffer circular, me lo recomendaste en este mismo tema... al parecer me sirvió de mucho  :D La pregunta es ¿para qué lo piensas usar?
...

para muchas cosas, con esas limitaciones de velocidad que tienen los pics...  :-)



Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 27 de Agosto de 2009, 16:52:46
Bueno pues leyendo el libro de Jan Axelson descubrí que el host usb cuenta con un ring buffer para almacenar los reportes HID mientras Windows no los recupere. Cuando el buffer se llena, el host borra el reporte más viejo.

Ya estoy escribiendo mi librería HID y la voy a implementar para poder leer más bytes que los que acarrea un simple paquete. Con esto espero vaciar el ring buffer más rápido sin tener el problemilla de 1ms de latencia... más reportes por leída.

(http://img34.imageshack.us/img34/8739/enprogreso.th.png) (http://img34.imageshack.us/img34/8739/enprogreso.png)

Este buffer circular está en todas partes Pedro  :D
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 31 de Agosto de 2009, 13:03:45
Haciendo uso del libro USB Complete de Jan Axelson pude recibir los paquetes de mi PIC en modo HID sin tener pérdidas de información. Es necesario importar algunas funciones de las librerías internas de Windows XP: hid.dll, setupapi.dll y kernel32.dll.

Cuando Windows enumera un dispositivo HID y lo pasa al estado CONFIGURED es cuando el dispositivo comienza a enviar los reportes o paquetes cada que el host se lo indique, entendiendo host como hardware USB y no Windows.

El periodo del polling en los HID va desde 1ms hasta 255ms. Mi PIC quedó configurado a 1ms con reportes de 50bytes. Este periodo de 1ms es altamente exacto porque depende del host y no del scheduler de procesos de Winxp.

El kernel de windows se encarga de recibir los reportes que el pic envía cada 1ms y los almacena en un buffer circular. Este buffer tiene un tamaño predeterminado de 32 reportes en Windows XP y 2 reportes en Windows 98.

El usuario debe leer estos reportes antes de que el buffer circular se llene. Si llegan 33 reportes y no se lee el buffer entonces el reporte más viejo es sobreescrito y por lo tanto perdido.

Si cada reporte llega exactamente cada 1ms, entonces con 32 reportes es necesario que el usuario vacíe el buffer cada 32ms o menos. Mi problema era que las librerías que andan por internet solo leen un reporte por evento y para cuando se quiere leer otro, los viejos ya fueron sobreescritos.

Tuve que escribir mis propias importaciones de funciones para no perder paquetes. Las funciones importantes y que no vienen completas en el libro de Jan son:

Código: [Seleccionar]
       [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern Boolean ReadFile(
            SafeFileHandle hFile,
            byte[] buffer, //IntPtr lpBuffer,
            Int32 nNumberOfBytesToRead,
            ref Int32 lpNumberOfBytesRead,
            IntPtr lpOverlapped);

        //Investiga tamaño del ring buffer de input reports
        [DllImport("hid.dll", SetLastError = true)]
        public static extern Boolean HidD_GetNumInputBuffers(
            SafeFileHandle HidDeviceObject,
            ref Int32 NumberBuffers);

        //Establece tamaño del ring buffer de input reports
        [DllImport("hid.dll", SetLastError = true)]
        public static extern Boolean HidD_SetNumInputBuffers(
            SafeFileHandle HidDeviceObject,
            Int32 NumberBuffers);

- GetNumInputBuffers
http://msdn.microsoft.com/en-us/library/ms790938.aspx
Sirve para leer el tamaño del buffer circular.

- SetNumInputBuffers
http://msdn.microsoft.com/en-us/library/ms790946.aspx
Sirve para cambiar el tamaño del buffer circular. Entre más grande el buffer circular menos frecuentemente habrá que hacer lecturas al mismo. Bajo Windows XP este buffer puede almacenar hasta 512 reportes.

- ReadFile
Después de obtener un handle al dispositivo USB se pueden leer de un solo paso todos los reportes que estén en el buffer circular, pidiendo nNumberOfBytesToRead como (reportes * bytes_por_reporte).

Al configurar el buffer circular con 512 reportes se tiene un alamcenamiento de hasta 512ms de datos, obligando al usuario a solo vaciar el buffer cada 512ms o menos. Esto es bastante fácil de lograr con timers incluidos en Visual Studio sin importar cuanta carga tenga el CPU de Windows.

Un muestreo de 32ms pone mucha carga al procesador mientras que uno de 512ms es más ligero.

Gracias a estas funciones y que el kernel de windows nos guarda los paquetes temporalmente es posible leer datos a 50kB/s desde un PIC en modo HID sin pérdida de paquetes.

Velocidades de hasta 64kB/s por interfaz USB son posibles ya que el endpoint HID interruptivo puede enviar hasta 64bytes por polling.

Con esto doy por terminado este hilo que duró como medio año abierto, pero así es esto del USB, hay que leer por todos lados para aprenderlo a usar como debe ser.

Gracias a los que me ayudaron en esto espero poder publicar una DLL con estas mejoras algún día... todavía me estoy peleando con la búsqueda de varios PICs al mismo tiempo.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 03 de Septiembre de 2009, 21:57:53
Hola

Les dejo el link a mi página en donde pueden descargar el probador de HID's (no solo de pics). Es útil para ver si su pic está bien enumerado y si les está enviando los paquetes que ustedes requieren.

Prueba tu HID con SL HID Tester
http://migsantiago.com/index.php?option=com_content&view=article&id=15&Itemid=17

Basado en el código fuente de Jan Axelson www.lvr.com y su libro.  ;-)
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 03 de Septiembre de 2009, 22:02:34
que mas puedo decir Maestro Santiago:

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=25188.0;attach=10010)




uno solito please!!! te lo mereces
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 03 de Septiembre de 2009, 22:19:30
jajaja

No es para tanto Pedro, la magia la hace la Sra. Jan Axelson con sus tutoriales mega excelentes.  ;-)

Borra por favor los muñequitos que me siento invadido y sobrepasado :D
Título: Re: Dudas USB y 12Mbps
Publicado por: PalitroqueZ en 04 de Septiembre de 2009, 12:41:57
jajaja

No es para tanto Pedro, la magia la hace la Sra. Jan Axelson con sus tutoriales mega excelentes.  ;-)
...

la verdadera magia es comprender todo ese chorro de lineas de programación  :D

Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 04 de Septiembre de 2009, 13:17:53
Un tip... en el libro vienen perfectamente explicadas Pedro.  ;-)

Capítulo 10 para obtener un handle al dispositivo HID y Capítulo 13 para leer los reportes. En el 13 se hace mención al ring buffer pero hay que buscar un poco en internet para saber cómo redimensionarlo. Acá arriba ya está cómo importar las funciones de la DLL.

Y lo bueno es que el código viene para Visual Basic o C# 2008... ambos funcionando incluso en la Express Edition.  :mrgreen:
Título: Re: Dudas USB y 12Mbps
Publicado por: BrunoF en 06 de Octubre de 2009, 08:12:23
Hola muchachos.

Creo que tarde o temprano todos terminamos con este mísmo problema. A uno lo emociona leer 12Mbps, pero de ahí a conseguirlos...un abismo.

Actualmente estoy requiriendo la mayor velocidad posible. Usando modo Bulk, estoy en 5.5kBps. Actualmente mi tamaño de buffer es de 32, y sólo tengo habiltada 1 endpoint. Voy a intentar subirlo a 64 bytes de buffer, y 6 endpoints.

Haciendo pruebas, la mejor relación que he obtenido ha sido enviar paquetes de a 16 bytes por vez, y con una latencia de 3ms. Esto es desde la PC al uC usando la mpusbapi.dll. Estoy transmitiendo "video" a una matriz de LEDs. Por eso es crítica la velocidad. La matriz actual es pequeña(7x80 LEDs) y por ello llego a 50fps actualmente.Pero tengo matrices mas grandes y ya tendré grandes problemas con la velocidad actual.

Cualquier ayuda será bienvenida. Si todo falla tendré que pasar al modo HID como santiago y construir algo desde allí.

Un saludo.

Título: Re: Dudas USB y 12Mbps
Publicado por: Modulay en 06 de Octubre de 2009, 10:16:28
Alguno probó con endpoints de tipo isócrono?
Me consta que este tipo de endpoints se usan para transferencias a tiempo real de volúmenes de datos considerables (tramas de audio digitalizado, por ejemplo)...el tamaño de paquete para estos tipos de transferencias pueden alcanzar el Kbyte, a lo que se sumaría el uso de modos ping-pong, uso de varios endpoints para el mismo propósito, etc...
Lo que no se es si los dispositivos MSD, que son un claro ejemplo de velocidad de transferencia , también usan dicho tipo de endpoints.
Título: Re: Dudas USB y 12Mbps
Publicado por: Modulay en 06 de Octubre de 2009, 10:32:19
Pues éste, al menos, usa endpoints tipo bulk (página 5) de 64 bytes (página 7):

http://ww1.microchip.com/downloads/en/AppNotes/01189a.pdf (http://ww1.microchip.com/downloads/en/AppNotes/01189a.pdf)
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 06 de Octubre de 2009, 12:34:42
Bruno, para agilizar el envío de bytes desde los endpoints lo más recomendable es que reescribas las funciones de envío de CCS y hagas las tuyas, así es como solucioné mi problema de envío cada 1ms. CCS pierde mucho tiempo moviendo buffers de aquí a allá, eso ralentiza en sobremanera la preparación de endpoints (overhead processing como alguna vez Pali mencionó).

El segundo problema es que la PC sea capaz de leer todos los datos enviados al PIC sin perder información. Esto es el mayor problema ya que Windows hace mil cosas al mismo tiempo y no hay forma de asegurar que el procesador esté al tanto de los paquetes recibidos por el PIC. Usé código para ejecutar el hilo en tiempo real (System.Diagnostics - Process Priority) pero aún así no logré mejorar.

Usé el modo HID por sugerencia de Palitroquez, pero posteriormente descubrí que Windows contaba con el Ring Buffer y que el HID tenía muchas ventajas. Este ring buffer es llenado por el kernel de Windows y es 100% seguro que no se pierdan paquetes desde el PIC. Lo único que uno debe hacer como usuario es vaciar el buffer antes de que se llene.

Estuve viendo las funciones BULK de la mpusbapi.dll y no encontré una sola que lea de un solo golpe varios endpoints, implicando que entre peticiones de lectura Windows pueda desviar la ejecución del proceso hacia otro proceso acarreando retrasos. Con mi poca experiencia como programador creo que es necesario escribir un driver a nivel KERNEL (tiempo de uso del procesador asegurado) que se encargue de pedir paquetes al PIC y guardarlos en un buffer circular. Posteriormente solo se deberá vaciar el buffer a nivel usuario (tiempo de uso del procesador no asegurado).

Si deseas reescribir las funciones de envío por endpoints BULK hasta 64 bytes para agilizarlas, cuentas con mi ayuda  :mrgreen:

El problema con HID es que el máximo a transmitir es de 64kB/s por interfaz, pero tiene solución... agregar más HIDs por PIC, es decir, más interfaces por dispositivo. De esa forma puedes tener n * 64kB/s de transferencia constante y sonante y n ring buffers para no perder datos y todo con un solo PIC.

Sobre el modo isócrono... tiene la ventaja de enviar datos a velocidades altas y constantes pero tiene una desventaja peor, no hay detección ni corrección de errores... por ello se usa en audio y video para el usuario final. No se usa isócrono en Mass Storage Devices porque no es permitido ni un solo error en esa clase.

El modo Bulk solo transmite datos cuando el bus USB está desocupado, pero si tienes más dispositivos conectados el ancho de banda no será suficiente.
Título: Re: Dudas USB y 12Mbps
Publicado por: BrunoF en 06 de Octubre de 2009, 16:43:31
Ok. Voy a revisar las funciones del BULK ahora...

Y sería muy bueno escribir una nueva dll que logre velocidades superiores. Seguro que más de uno estaría agradecido de que lo hiciesemos. ;)
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 06 de Octubre de 2009, 18:02:40
Bueno, el código fuente de la mpusbapi.dll viene en el USB Framework de Microchip (Borland C++ creo). Lo difícil creo que sería escribir código a nivel kernel.

Te puedo ayudar del lado del pic con las funciones de envío pero del lado de la PC habría que estudiar un poco más la dll de microchip.
Título: Re: Dudas USB y 12Mbps
Publicado por: Infernum1001 en 22 de Octubre de 2009, 15:50:24
Saludos! estoy muy interesado en este tema ya que yo mismo estoy haciendo un proyecto con el puerto usb del 18f4550, no entiendo del todo de lo que exponen pero me parece excelente toda la informacion que se ha publicado.

migsantiago sera que puedes publicar el descriptor modificado que hicistes para la transmision a full speed y el codigo del firmware q hicistes para el pic, eso nos ayudaria mucho a entender mas este tema.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 22 de Octubre de 2009, 15:53:05
Leyendo el tema completo puedes encontrar las modificaciones necesarias.
Título: Re: Dudas USB y 12Mbps
Publicado por: Armando702 en 23 de Octubre de 2009, 10:29:38
Hola a todos! Yo estoy trabajando en un proyecto que tambien tiene que ver con usb, usando unos de los ejemplos de CCS compile un programa para el pic y a traves de easyHID genere un programa en visual basic para el programa en la PC. Veo que necesito modificar las rutinas del descriptor para poder llegar a enviar cada 1ms. Pero por lo que tengo ahora hecho el problema que tengo es que a traves del analizador USB del Proteus me dice que entre un dato y otro los intervalos de tiempo no son constantes, envia cada 10ms, 15ms, 5ms ...

Y en visual basic genero una grafica de la forma que muestro en el archivo adjunto.

Esta en mi rutina para el envio:

   while (TRUE) {
      usb_task();   
      usb_debug_task();
      if (usb_enumerated()) {   
         if (!send_timer) {
            send_timer=0;
            set_adc_channel (0); // Habilitacion del canal 0 del ADC
            delay_us(10);
            usb_out_data[0]=read_adc();
            set_adc_channel (1); // Habilitacion del canal 1 del ADC
            delay_us(10);
            usb_out_data[1]=read_adc();
            set_adc_channel (2); // Habilitacion del canal 2 del ADC
            delay_us(10);
            usb_out_data[2]=read_adc();
            set_adc_channel (3); // Habilitacion del canal 3 del ADC
            delay_us(10);
            usb_out_data[3]=read_adc();
            set_adc_channel (4); // Habilitacion del canal 4 del ADC
            delay_us(10);
            usb_out_data[4]=read_adc();
            set_adc_channel (5); // Habilitacion del canal 5 del ADC
            delay_us(10);
            usb_out_data[5]=read_adc();
       
            usb_put_packet(1, usb_out_data, 6, USB_DTS_TOGGLE);
         }
         if (usb_kbhit(1)) {
            usb_get_packet(1, usb_in_data, 2);
            printf("\r\n--> Received data: 0x%X 0x%X",usb_in_data[0],usb_in_data[1]);
            output_d (usb_in_data[0]);
         }
         send_timer--;
      }
   }
}

Mi pregunta es, a q se debe q el envio de datos sea a intervalos tan diferentes? que es send_timer?

Les agradeceria la ayuda que me podrian brindar!

Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 23 de Octubre de 2009, 12:54:16
Creo que no has leído el tema completo, ahí está la respuesta al porqué del retraso en los paquetes.

Ah y no es necesario que crees una cuenta nueva para publicar otro mensaje.
Título: Re: Dudas USB y 12Mbps
Publicado por: Armando702 en 23 de Octubre de 2009, 21:58:42
Pues dejame decirte que yo no tengo dos cuentas, de que un amigo mio q esta trabajando en los mismo q yo, alla escrito aqui y yo tambien, no significa q yo alla creado dos cuentas para publicar otro mensaje. Por lo menos se q no cuento con tu ayuda!

Alguien mas q me pueda ayudar!
Título: Re: Dudas USB y 12Mbps
Publicado por: alejandro20 en 24 de Noviembre de 2009, 07:51:10
Hola muchachos, yo también me uno a su dolor porque he intentado también diferentes formas de transmisión del pic  al computador por usb (modo bulk, interrupción, intenté el modo isochronous pero no me funcionó, en clase cdc  y nada, claro que utilizando siempre un solo endppoint out-in) sin lograr resultados de velocidad, la recepción de datos en el compu  la hago con labview 8.5 y el envió desde labview al pic es muy buena, pero en todas los modos de transmisión del pic  a labview siempre ahi una demora ahi fastidiosa.  probé el envio de una señal senoidal de 5v/1hz  utilizando el adc del pic  y luego la envio en modo bulk a la cpu y la visualización en labview  y me la muestra muy distorsionada, nooo  1hz.  Ahora estoy teniendo problema con la clase cdc,  en la misma forma del pic  hacia la cpu  si se demoraba en bulk, en cdc peor!! no se q estoy haciendo mal, este es el codigo q  estoy utilizando pero sin adc , solo  lo que ahi en el puerto  d  que me lo envie a la cpu  y si le envio un byte desde la cpu me lo muestre por el pto b:

# include<18f4550.h>
# use delay (clock=48Mhz)
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,VREGEN,CPUDIV1,PLL5
#include<usb_cdc.h>
#include<usb.h>
#include <pic18_usb.h>
#include <usb_desc_cdc.h>
#include <usb.c>

#byte port_d=0xF83
#byte port_b=0xF81

char dato=0;
   


void main (void){

   
    char data;     

   enable_interrupts(global);
     usb_cdc_init();
    usb_init();
       
    output_b(0X00);
    set_tris_b (0x80);
    set_tris_d(0XFF);
     output_b(0x01);// ENERGY ON
   enable_interrupts(INT_EXT);
   EXT_INT_EDGE(L_TO_H);
   if(usb_enumerated())
     {   output_b(0X02);}
   else
      {usb_wait_for_enumeration();
     output_b(0X02);
                  }
     while (TRUE)
      {    usb_task();
          
          if (usb_cdc_kbhit())
              {port_b=usb_cdc_getc(); }   
         
         dato=port_d;
         if (usb_cdc_putready())
         {usb_cdc_putc(dato);}         
             
   
 }
   }

lo que le envio desde la cpu al pic si me lo muestra rápido pero lo q le envio desde el pic si toma demasiado tiempo,,, no se q hacer por favor ayuda si esta mal algo  en el codigo...  gracias.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 24 de Noviembre de 2009, 12:46:39
Hola, un consejo... la clase CDC es muy mala en cuanto a velocidades de envío constantes debido a que utiliza printf's y el tiempo de muestreo del endpoint de salida es de 250ms. Los printf consumen mucho tiempo de procesamiento.

Mi recomendación es que uses HID con polling de 10ms en adelante, modificable en el archivo usb_desc_hid.c.
Título: Re: Dudas USB y 12Mbps
Publicado por: alejandro20 en 01 de Diciembre de 2009, 16:45:18
Muchas gracias migsantiago voy a probarlo más adelante cuando salga de estos proyectos en la universidad, por lo pronto lo voy a dejar en modo Bulk.
Título: Re: Dudas USB y 12Mbps
Publicado por: mmij en 19 de Diciembre de 2009, 03:23:20
Muchas gracias, MigSantiago, he leido este post y me ha ayudado mucho a comprender muchas cosas sobre comunicacion USB con pic y como eficientarla  :-/ Espero seguir leyendo articulos tan interesante como este!

Suerte
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 20 de Diciembre de 2009, 16:11:27
Te quedo te lujo santiago, felicidades. Ahora estoy denuevo con este proyecto en el que tengo que integrar comunicacion usb, y pues al parecer, aparte como ya lo abia integrado, me voi a quedar con el modo HID. Aunq tengo mis dudas, en algun momento me parece haber visto uno o dos datos erroneos cuando transferia de la PC al PIC como 5000 bytes asi. Es realmente seguro el modo HID? Algo que tranquiliza es que el pickit 2 usa este modo y, para ser un programador y depurador de PICS, pues va bien. Espero no tener que cambiar al modo Bulk porque quiero evitar la necesidad de instalar un driver.

Felicitaciones dnuevo, aunq esto del usb nunca se acabe xD!
Suerte, sau2.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 20 de Diciembre de 2009, 16:16:35
Gracias Jeremy.

El modo HID es muy seguro porque implementa CRC y si llega mal algún reporte se pide la retransmisión. La única transferencia que no revisa el estado de los paquetes es la isócrona, comúnmente usada para las clases de audio y video para usuario final.

Seguramente el error que tuviste fue por algún dato mal mandado.
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 20 de Diciembre de 2009, 17:07:02
Si, debio ser eso. Otra cosa, el HID por ahi comentas que solo permite usar un solo endpoint por interfaz ? Ocea, uno de tx y otro de rx nomas? no se puede mas?  :o
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 20 de Diciembre de 2009, 17:28:42
La clase HID especifica que solo puedes tener un endpoint de control y un endpoint interruptivo por interfaz. Pero si tienes un dispositivo (PIC) puedes tener varias interfaces en él, pudiendo implementar varios HID en un solo PIC y así incrementando la velocidad.

Y bueno, cada pipe interruptivo soporta un endpoint tx y otro rx.

Nadamás habría que modificar el descriptor, pero en eso no tengo experiencia aún, aunque no debería ser complicado porque son puras tablas.
Título: Re: Dudas USB y 12Mbps
Publicado por: jeremylf en 20 de Diciembre de 2009, 20:10:07
Vaya, no peudo creer que no se pueda habilitar mas endpoint en HID. Tas seguro de ello? Donde lo viste, has probado? buneo aunq yo no, no dejo de pnsar que es por el cambio de funciona que hiciste y ttodo eso? Bueno, seria bien desilusioante que no se pueda habiltar mas endpoints pero es buneo saber que se puede solucionar aumetnando las interfaces.


Salu2l
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 21 de Diciembre de 2009, 15:05:12
Poder agregar más de un HID por dispositivo es posible, pero de poder hacer lo mismo usando el ejemplo de CCS... quién sabe.

Lo que quisiera es lograr usar el modo bulk y los 15 endpoints. El problema reside en que no sé cómo hacer que la pc lea los 15 endpoints velozmente.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 01 de Enero de 2010, 16:48:44
Encontré el artículo que permite a los usuarios pedir un Product ID a Microchip de forma gratuita y con licencia de hasta 10,000 unidades.

Lo dejo aquí por si luego olvido dónde lo leí.

APPLICATION FOR SUBLICENSE TO
MICROCHIP UNIVERSAL SERIAL BUS VENDOR ID
http://ww1.microchip.com/downloads/en/AppNotes/Application%20for%20USB%20Vendor%20ID%20Sublicense.pdf
Título: Re: Dudas USB y 12Mbps
Publicado por: giff en 15 de Abril de 2010, 23:44:36
Hoy estuve revisando y probando en mi PIC18F2550 como activar dos ENDPOINTS y lo logre, también configure la mpusbapi para tal función.

Leyendo de un post del foro pero que no recuerdo que palabras usé, empece a probar y realice unos cambios en los descriptores.

Esto es la parte importante del archivo PICUSB.c. Copié esto solamente ya que en USB_CONFIG_DESC[] fue donde modifique y añadí cosas
Código: [Seleccionar]
   #DEFINE USB_TOTAL_CONFIG_LEN      46 //config+interface+class+endpoint


   char const USB_CONFIG_DESC[] = {
   //config_descriptor for config index 1
         USB_DESC_CONFIG_LEN,     //length of descriptor size =1
         USB_DESC_CONFIG_TYPE,         //constant CONFIGURATION (0x02)
         USB_TOTAL_CONFIG_LEN,0,  //size of all data returned for this config ==3,4
         1,      //number of interfaces this device supports
         0x01,                //identifier for this configuration.  (IF we had more than one configurations)
         0x00,                //index of string descriptor for this configuration
         0xC0,                //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 reserved and bit7=1
         0x32,                //maximum bus power required (maximum milliamperes/2)  (0x32 = 100mA) =9

   //interface descriptor 0 alt 0
         USB_DESC_INTERFACE_LEN,  //length of descriptor ==10
         USB_DESC_INTERFACE_TYPE,      //constant INTERFACE (0x04)
         0x00,                //number defining this interface (IF we had more than one interface)
         0x00,                //alternate setting
         4,       //number of endpoints, not counting endpoint 0.-------------------------------------------------------------------------->NOTA1
         0xFF,                //class code, FF = vendor defined
         0xFF,                //subclass code, FF = vendor
         0xFF,                //protocol code, FF = vendor
         0x00,                //index of string descriptor for interface =18

   //endpoint descriptor
         USB_DESC_ENDPOINT_LEN, //length of descriptor
         USB_DESC_ENDPOINT_TYPE,     //constant ENDPOINT (0x05)
         0x81,              //endpoint number and direction (0x81 = EP1 IN)
         0x02,              //transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt)
         USB_EP1_TX_SIZE,0x00,         //maximum packet size supported =23,24
         0x01,              //polling interval in ms. (for interrupt transfers ONLY)=25

   //endpoint descriptor
         USB_DESC_ENDPOINT_LEN, //length of descriptor ==26
         USB_DESC_ENDPOINT_TYPE,     //constant ENDPOINT (0x05)
         0x01,              //endpoint number and direction (0x01 = EP1 OUT)
         0x02,              //transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt)
         USB_EP1_RX_SIZE,0x00,         //maximum packet size supported =30,31
         0x01,              //polling interval in ms. (for interrupt transfers ONLY) =32
        
   //endpoint descriptor ////AGREGADO
         USB_DESC_ENDPOINT_LEN, //length of descriptor == 33
         USB_DESC_ENDPOINT_TYPE,     //constant ENDPOINT (0x05)
         0x82,              //endpoint number and direction (0x82 = EP2 IN)
         0x02,              //transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt)
         USB_EP2_TX_SIZE,0x00,         //maximum packet size supported ==37,38
         0x01,              //polling interval in ms. (for interrupt transfers ONLY) ==39

   //endpoint descriptor
         USB_DESC_ENDPOINT_LEN, //length of descriptor ==40
         USB_DESC_ENDPOINT_TYPE,     //constant ENDPOINT (0x05)
         0x02,              //endpoint number and direction (0x02 = EP2 OUT)
         0x02,              //transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt)
         USB_EP2_RX_SIZE,0x00,         //maximum packet size supported ==44,45
         0x01              //polling interval in ms. (for interrupt transfers ONLY)  == 46[/b]
  };


NOTA1: Agregué la información para usar el ENDPOINT 2, por lo que donde indico se debe poner un 4. Sin contar el EP0 serian 4 Endpoints en total (2 in y 2 OUT). También modifiqué respectivamente   #DEFINE USB_TOTAL_CONFIG_LEN      46 //config+interface+class+endpoint. De esta forma ya tengo habilitados dos endpoints. Si quisiera añadir 3 Endpoints deberia agregar dos "endpoint descriptor" (uno para In y otro para OUT) asi como también contar nuevamente las lineas para poner el numero respectivo en USB_TOTAL_CONFIG_LEN. Además donde indico la NOTA1 no sería 4, sino un 6.

Por otra parte, en el archivo que tiene el main(), fuses y todo lo demás; para ver si hay datos en cada ENDPOINT se procede de la misma forma como lo hizo J1M en su proyecto PicUSB pero hay que ir constatando usb_kbhit() por cada endpoint, es decir:

usb_kbhit(1) para endpoint 1
usb_kbhit(2) para endpoint 2, y asi suma y sigue.

Se me olvidaba, declaren los #define para cada enpoint IN y/o OUT.
Código: [Seleccionar]

#define USB_EP1_TX_ENABLE USB_ENABLE_BULK // turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK // turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP2_TX_ENABLE USB_ENABLE_BULK // turn on EP2(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP2_RX_ENABLE USB_ENABLE_BULK // turn on EP2(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE 5 // size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE 1 // size to allocate for the rx endpoint 1 buffer
#define USB_EP2_TX_SIZE 5 // size to allocate for the tx endpoint 2 buffer
#define USB_EP2_RX_SIZE 1



Para enviar y/o recibir, hacer uso de las funciones que me enseñaron uds aca como usb_get_packet(0x02, recibe, 1)  y usb_put_packet(0x02, envia, 5, USB_DTS_TOGGLE). si se fijan use el Endpoint 2 para enviar y recibir algo.

Finalmente, ahora solo constaté cambiando el STRING que define el endpoint para usar con la libreria importada mpusbapi que usa J1M para realizar su programa PicUSB, o sea:

Código: [Seleccionar]
       #region Definición de los Strings: EndPoint y VID_PID
        string vid_pid_norm = "vid_04d8&pid_0011";

        string out_pipe = "\\MCHP_EP2";
        string in_pipe = "\\MCHP_EP2";

        #endregion

y funcionó igual que como si hubiese estado con el ENDPOINT1. En un rato más probare usando dos enpoint con BULK TRANSFERS simultaneamente para una aplicación que estoy realizando para mi seminario. Les aviso luego.

migsantiago como te manejas más con el código quizas le saques más provecho, me gustaria saber que tendra esa mente tuya para este tema

PD: como miercale se usa el Geshi?, quiero poner codigo con colores y cosas bonitas
Título: Re: Dudas USB y 12Mbps
Publicado por: giff en 16 de Abril de 2010, 03:27:12
Pude hacer comunicación con dos endpoint.

Adjunto los archivos picusbapi.cs y picusb.h para que los miren y se hagan una idea.

Para la parte de CCS, sigan las recomendaciones del post anterior.

Por lo que veo, uso dos EP con bulk pero la transferencia la hace secuencialmente, porque según mi programación hago un usb_kbhit(1) para procesar y responder en el EP1 y despues un usb_kbhit(2) para resonder a lo que me pide el host en el EP2.

¿Esto se optimizaria con el ping pong mode?


Agregado: acabo de releer por enésima vez este hilo y veo que quizás se tenga que editar la funcion usb_put_packet pararedir tiempos en el envio asi como también ver si se puede hacer buffer circular, rayos; y eso que no llevo mucho con el asunto de visual C#
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 16 de Abril de 2010, 09:59:04
Qué bueno que estás aprendiendo a usar USB.

Lo que comentas sobre usar más endpoints ya se había logrado, lo que nos interesa es lograr transmitir a 12Mbps.

Si logras una velocidad de más de 1Mbps... real, nos avisas.
Título: Re: Dudas USB y 12Mbps
Publicado por: giff en 16 de Abril de 2010, 11:36:36
ok, no sabia que lo habías hecho ya. Por donde recomiendas seguir la investigación?
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 16 de Abril de 2010, 11:51:20
Del lado de la PC.

Hacer un programa que sea capaz de leer los 15 endpoints en modo bulk del PIC sin retrasos, preferentemente en modo kernel. Si se logra, el PIC enviaría constantemente datos en los endpoints (sin usar ping-pong) y como mínimo la PC los leería a 1Mbps.
Título: Re: Dudas USB y 12Mbps
Publicado por: giff en 16 de Abril de 2010, 12:28:30
Del lado de la PC.

Hacer un programa que sea capaz de leer los 15 endpoints en modo bulk del PIC sin retrasos, preferentemente en modo kernel. Si se logra, el PIC enviaría constantemente datos en los endpoints (sin usar ping-pong) y como mínimo la PC los leería a 1Mbps.

En campaña entonces
Título: Re: Dudas USB y 12Mbps
Publicado por: giff en 21 de Abril de 2010, 00:18:31
Hola nuevamente. ¿Han intentado (del lado del PC) mantener siempre los pipes out enviando datos? Pregunto porque, al momento de que el PIC este listo de enviar la información al host este ya tenga asegurado el dato que el buffer.

pongo un ejemplo en el lado del PIC, con el EP2:

Código: C
  1. usb_task();
  2.       if(usb_enumerated())        
  3.          {  
  4.              while(usb_kbhit(2)) /*mientras tenga algo, no importa que dato sea, envie.*/
  5.              {    
  6.             usb_put_packet(2, envia_int32, 24,USB_DTS_TOGGLE); /*enviamos el paquete de tamaño 1byte del EP2 al host  */  
  7.             }
  8.          }

En el lado del PC se activa un evento activado por un timer solo datos para el EP2 OUT enviando mas rápido que nuestra rutina en el pic solo para asegurar la transferencia que hay dato. En mi caso, envio datos cada un segundo al host pero se me desincroniza este porque no se como cuadrar los tiempos del PIC con los del PC. Así que uso un EP2 IN exclusivo para enviar las lecturas al host, mientras que el OUT lo voi sobreescribiendo a una velocidad mayor al envió propiamente tal.

Lo probare para mas EP, pero no tengo como tasar la velocidad de transferencia.

PD: wii aprendi a usar geshi :D
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 21 de Abril de 2010, 10:19:36
Para el modo bulk no hace falta enviarle un dato al pic para que el endpoint responda.

Sólo basta con enviar el dato y que la PC siempre los esté recibiendo. La PC no debe enviar nada a nivel datos, sólo a nivel protocolo pero esta parte es invisible a nivel usuario.

La siguiente rutina en el pic sería más que suficiente...

Código: [Seleccionar]
while(condicion[0])
{
while(usb_put_packet(2, condicion, 24,USB_DTS_TOGGLE)==0);
}

Mientras haya algo que enviar, que lo envíe, pero que espere a que se haya enviado.
Título: Re: Dudas USB y 12Mbps
Publicado por: giff en 21 de Abril de 2010, 14:09:01
Ouch, gracias por dar correcciones de concepto migsantiago, aun me falta pero iré a las montañas y seguir practicando. Claro, tal como dices, dicho y hecho ya que no es necesaria una condicion para que el pic envíe al host, eso lo torna mucho más facil para mi.

Del lado del pc dejo un timer corriendo cada 1 ms haciendo esto:

Código: C#
  1. public devolver_calculo Lect_calculo(){
  2.            
  3.             devolver_calculo dvc;
  4. envia_denueo:          
  5.             byte* receive_buf = stackalloc byte[24];
  6.  
  7.             DWORD RecvLength = 24;
  8.        
  9.             ReceivePacket2(receive_buf, &RecvLength);
  10.  
  11.            
  12.                 byte[] buffsal = new byte[24];
  13.        
  14.                 int suma = 0;
  15.                 for (int i = 0; i < 23; i++)
  16.                 {
  17.                     buffsal[i] = receive_buf[i];
  18.                     suma +=  buffsal[i];
  19.                 }
  20.             if(suma == 0)
  21.             {
  22.                 goto envia_denueo;
  23.  
  24.             dvc.p_total = (float)0.001234 * (BitConverter.ToInt32(buffsal, 0)) - (float) 0.0012;
  25.             dvc.p_off =(float) 0.001234 * BitConverter.ToInt32(buffsal, 4) - (float) 0.0012;
  26.             dvc.p_on = BitConverter.ToInt32(buffsal, 8);
  27.             dvc.dato_p_off_pctaje = BitConverter.ToInt32(buffsal, 12);
  28.             dvc.dato_p_on_pctaje = BitConverter.ToInt32(buffsal, 16);
  29.             dvc.dato_p_ahorro_pctaje = BitConverter.ToInt32(buffsal, 20);
  30.            
  31.             return dvc;
  32.             }

Ahí aseguro que lleguen mis datos al buffer, que llegue lo que llegue y si es cero realizo un goto para volver a recibir packetes desde ese EP2 bajo un timer que hace polling "cada 1ms" (ni idea de cuan exacto será). El programa se me pega cuando desconecto el usb y es porque este se va a un loop indefinido. Debo ingresar otra condicion que me detecte que está conectado o no el PIC al bus. Hay una funcion importada del archivo creo y en un blog (unpocodeelectronica) creo que vi como proceder. Seguire investigando
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 21 de Abril de 2010, 14:18:30
Los timers que Visual Studio tiene no son precisos. Es muy difícil obtener tiempos precisos menores a 5ms a nivel usuario.

Si el CPU está atendiendo más procesos al mismo tiempo, esos tiempos de 1ms crecen.

Para garantizarlos hay que ejecutarlos a nivel kernel según lo que he leído.
Título: Re: Dudas USB y 12Mbps
Publicado por: WOOD_girl en 16 de Mayo de 2010, 23:58:54
hola migsantiago, te felicito por este post, esta realmente bueno, pues te comento que yo tambien soy una de las tantas personas que necesitan enviar datos hacia el PC de manera rapida y eficiente. yo he utlizado el modo BULK para tratar de transmitir 1000 bytes obtenidos previamente por el conversor ADC del pic (lo mismo que tu intentabas hacer al inicio del post) pero intente enviar primero un array tipo char y lo simule en proteus y funciono muy  bien, pero al probarlo en fisico, no llegaban ni 200 bytes (estoy usando el  usb_puts), note que tu mencionaste un retraso de 250mS, no hay posibilidad de bajarle a este restraso??.   se que tu solucionaste el problema usando el HID, pero he intentado descargar la informacion que has posteado pero los enlaces dicen que no hay archivos, podrias actualizar los links porfavor???

yo estoy trabajando en labview 8.2 y la verdad que tampoco colabora mucho (es muy lento). sera facil manejar el HID en labview??


agradezco mucho tu colaboración
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 17 de Mayo de 2010, 13:47:30
Hola Woodgirl

El retraso de 250ms es usando la clase CDC (RS232 virtual), no con bulk (según recuerdo porque esas pruebas las hice hace como un año).

Yo dejé de usar el modo bulk porque tiene un enorme inconveniente... el host (el controlador USB en la PC) no pide los datos constantemente. Los endpoint BULK sólo transmiten información cuando el bus USB está desocupado.

Sobre los archivos HID, la mejor librería que he visto está en www.lvr.com. No sé a qué archivos te refieras.

Rara vez uso Proteus porque tiene muchos inconvenientes y bugs. Uno se alegra cuando el firmware opera virtualmente; pero cuando se prueba en la realidad y falla, es un caos.

Hace unos meses quise probar Labview y HID mediante una enumeración especial (se hace un driver único para el dispositivo USB). El HID se desenumeraba (desconectaba) constantemente por lo que mejor desistí.
Título: Re: Dudas USB y 12Mbps
Publicado por: WOOD_girl en 17 de Mayo de 2010, 14:19:42
hola migssantiago, gracias por tu respuesta, mira yo estoy adquiriendo datos por el ADC  almaceno 1000 datos en un array y luego los envio, entonces me recomiendas que me pase a HID?? (si pasa lo que tu dices, entonces va a ser un lio!). y  pues estuve mirando lo que te comente en mi anterior post y ya pude visualizar 766 bytes  en el labview desde el pic18f2550,  la solución?,  cambiar el receivedelay de 1mS a 50mS.


los archivos a los que hago referencia es a la libreria que tu modificaste y que nombraste USB_fast.
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 17 de Mayo de 2010, 17:32:16
Si te es sencillo entender el código de www.lvr.com entonces pasa a HID. Pero si te es complicado mejor sigue con bulk.

Todos usamos CCS para echar a andar USB pero C18 tiene muy buenos ejemplos de USB. Hay unos endpoints isócronos que son como los hermanos menores de los interruptivos (los usados en HID). Los isócronos envían datos de forma constante (velocidad y tiempo) pero tienen la desventaja de que no corrigen errores. Los interruptivos son iguales pero sí corrigen errores.

Dale una revisada a la Microchip Applications Library y a los muchos ejemplos USB que trae. Talvez encuentres algo que satisfaga tu problema.

http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en547784

La clase de Audio implementa endpoints isócronos.

Sobre la librería usb_fast, el código está en este tema:

http://www.todopic.com.ar/foros/index.php?topic=25188.msg224608#msg224608
Título: Re: Dudas USB y 12Mbps
Publicado por: WOOD_girl en 18 de Mayo de 2010, 00:13:57
muchas gracias santiago me pondre de inmediato a leer ( y tratar de digerir) la info, y muchas gracias por la libreria, estare comentando los avances o tropiezos,  :g)
Título: Re: Dudas USB- Interrupciones en CCS
Publicado por: Suky en 19 de Mayo de 2010, 15:13:24
Hoy se me ha venido a la cabeza los comentarios de algunos foreros que indicando que al trabajar con USB y otras interrupciones ocurren problemas con la comunicación.  :roll: Me llama la atención el problema, porque seguramente con una buena administración del uso de las interrupciones esto seguramente no ocurre. Pero encontré otro detalle a mi parecer importante, el cual es que en CCS se acostumbra a no trabajar con las prioridades de las interrupciones que nos provee el hardware de los PIC18F. La solución es sencilla, solo hay que definir:

Código: C
  1. #device high_ints=TRUE

Y cambiar en el archivo pic18_usb.c

Código: C
  1. #int_usb
  2. void usb_isr()
  3. {
  4.    int8 TRNAttempts;

por

Código: C
  1. #int_usb fast
  2. void usb_isr()
  3. {
  4.    int8 TRNAttempts;

Y listo, se trabaja con los 2 vectores de interrupciones, y a la interrupción de USB se le asigna el vector de alta prioridad, por lo cual aunque haya una mala administración de las interrupciones no debería ocurrir problema alguno con la comunicación.

Espero no haber repetido el comentario de algún compañero, pero sinceramente no lo he leído en ningún sitio  :mrgreen:


Saludos!   ;-)
Título: Re: Dudas USB y 12Mbps
Publicado por: migsantiago en 03 de Septiembre de 2010, 10:39:35
Alguien sabe como hacer una aplicacion CDC que maneje las lineas de control del port serial, ademas de RX y TX ??
Perdon si no es el lugar de consulta, por favor moverlo a donde crean conveniente... :)

Un poco tarde la respuesta, pero bueno  :D

Conociendo a los PIC24 me entero que su USART ya incluye los pines que pides RTS y CTS o algo así. Seguro que la librería CDC USB los implementa completamente en hardware, nadamás hay que revisar el código.