martes, 5 de febrero de 2013

Programación del USB de un PIC 18F2550


En lo primero que nos fijamos es en los pragmas, concretamente en la programación del cristal:


Cristal y pragmas

Como podéis ver en OSC1 y OSC2 conectamos nuestro cristal: 4 Mhz, 8 Mhz, 12 Mhz, 16 Mhz, 20 Mhz, 24 Mhz, 40 Mhz  ó 48 Mhz, que son los cristales validos compatibles con lo que sigue a continuación.




Tened en cuenta que este cristal es el mismo para generar la frecuencia de 48 Mhz necesaria para el USB 2.0 y para el Clock del PIC, que pueden ser la misma o no, según la configuración que al final adoptemos, quiere esto decir que podemos tener el USB a 48 Mhz y nuestro programa en el PIC funcionando a 12 Mhz por ejemplo.
Fijaos en que justo tras el Smicht Trigger del Primary Oscillator salen tres líneas en paralelo que van a módulos distintos con distintas posibilidades.
La primera línea, la superior, va directamente al switch USBDIV que si está a cero indica que la frecuencia base original del cristal es directamente inyectada al USB, si pasa el switch FSEN que elige entre todo el sistema directo/PLL o el Primary Clock del CPU. Esta Opción de inyectar directamente la frecuencia del cristal es obviamente solo posible si usamos un Cristal de 48 Mhz que es lo que necesitamos para el USB.
Cualquier otro cristal debe ser tratado para conseguir los 48 Mhz necesarios.

El módulo USB Clock Source tiene a su entrada un PLL Prescaler, o sea un divisor de frecuencia. En cada una de sus salidas vamos a tener FOSCdividida por 1, 2, 3, 4, 5, 6, 10 ó 12. Y mediante PLLDIV que no es mas que un Multiplexor vamos a seleccionar la que deseamos usar.
Así si nuestro cristal es de 12 Mhz y en PLLDIV colocamos un 010 estaremos dividiendo por 3 el valor de FOSC con lo que tendremos 4 Mhz a la salida delMUX. Si por el contrario el cristal es de 20 Mhz y en PLLDIV colocamos un 100 entonces dividiremos por 5 FOSC con lo que tendremos también 4 Mhz a la salida del MUX.
Esta salida del MUX es lo que utilizamos para inyectársela al PLL de 96 Mhz. Si le metemos 4 Mhz él genera 96 Mhz. Es esta capacidad de pasar de 4 Mhz a 96 Mhz la que nos da la posibilidad de usar un montón de cristales distintos.
Pero 96 Mhz es el doble de lo que nos hace falta para el USB que son 48 Mhz. Asi que inmediatamente después tenemos que tener, y tenemos, un divisor por 2 que es el segundo camino por el que llegamos a USBDIV y en este caso le pondremos un 1 para usar la señal proviniente del PLL.
Fijaos que además de inyectar la señal oscilante en USBDIV tambien se conecta la señal del PLL a 96 Mhz en un Postscaler, otro divisor, en este caso por 2, 3, 4 ó 6 y cuyas señales van al CPUDIV. O sea que podemos generar una señal de reloj para nuestro PIC, no para el USB sino para la velocidad de ejecución de nuestro programa tomándola del PLL y que puede ser de 16 Mhz, 24 Mhz, 32 Mhz ó 48 Mhz.
Pero además la señal original llegaba en paralelo al Oscilator Postcaler, otro divisor más, que de forma directa, sin pasar por el módulo PLL nos divide la frecuencia original del cristal por 1, 2, 3 ó 4 y que también va a parar al CPUDIV pero desde otro origen. Con este módulo podemos obtener otra gama de frecuencias distinta para hacer correr el programa.
Los CPUDIV vamos a utilizar lo seleccionamos con el switch FOSC3:FOSC0 que es de donde sacaremos la definitiva frecuencia de ejecución de programas.
Por último también tenemos disponible una entrada proviniente del Primary Clock y que dividida por 4 llega también a FSEN y podemos utilizarla en lugar de la que le llega desde el canal directo/PLL
Como podéis ver es toda una maravilla cómo está montado este tema de los osciladores, sobre todo por lo que respecta a las inmensas capacidades que tiene para hacer correr nuestro PIC a decenas de velocidades distintas siendo capaz, al mismo tiempo de tener disponibles los 48 Mhz imprescindibles para el USB 2.0.
Una vez fijado el cristal se debe de habilitar el pragma VREGEN, algo que no se debe olvidar, sino el PC nunca detectará el PIC y es un error muy difícil de detectar ya que siempre te tiras a buscar el error en el driver del PC cuando en realidad es un error del PIC.