Algo Sobre USB y Pic
Algo Sobre USB y Pic
Algo Sobre USB y Pic
La placa es simple, del tipo modular ya que tiene disponible todas las patillas del PIC, lo
que permite la adaptación a cualquier tipo de proyecto que utilice USB o no. Las
características son las siguientes:
• Zócalo de conexión de 40 pines donde va insertado por defecto el PIC18F4550,
este PIC además de implementar una interfaz integrada para la comunicación
USB dispone de un gran número de pines (idóneo para una placa de desarrollo
donde a priori no sabemos los circuitos que vamos a montar en ella). Con
respecto a las características de conectividad USB este Microcontrolador, presenta
las siguientes: compatibilidad con USB 2.0, velocidad de trasmisión Low Speed
(1.5 Mb/s) y Full Speed (12 Mb/s). Soporta transferencias del tipo: Control,
Interrupción, Isocrónicas y del tipo Bulk (para grandes transferencias de datos).
Soporta hasta 32 Endpoints 16 de los cuales son bidireccionales. Mas adelante
veremos lo que significa cada una de estas nuevas palabras que aparecen cuando
utilizamos conectividad USB.
Consideraciones de diseño.
El que la placa tenga un diseño modular permite mucha flexibilidad a la hora de probar
nuestros prototipos, basta que hagas fijo la funcionalidad de un determinado pin, para
que en el siguiente prototipo lo tengas que utilizar para otra cosa. Otra decisión
importante que hay que tener en cuenta en el diseño de la placa son los conectores a
utilizar, con respecto al conector del programador/debugger la decisión fue rápida decidí
utilizar el RJ-12 ya que los programadores que utilizo (ICD-64 y el ICD2) tienen este
conector y vienen ya con el cablecito incorporado para la conexión, el esquema de
conexión del ICD-U64 a la placa lo tenéis aquí .
Con respecto a los conectores para los puertos del PIC personalmente prefiero los que
te permiten el acceso a los pines individualmente, dentro de esta filosofía se pueden
utilizar regletas de conexiones que permiten utilizar cualquier tipo de cable para
conectar los módulos de expansión ó array de pines (o postes) como se les quiera
llamar, que permiten la conexión fácil a través de cablecillos rígidos,
para esta placa he utilizado los array de pines, con respecto a las regletas de
conexiones tienen la ventaja de que te ahorras el atornillado de los cables, ocupan
menos espacio y son más baratos. Las regletas de conexiones tienen a su favor que los
cables quedan mas sujetos y permiten el movimiento de los módulos sin correr el riesgo
de que se desconecte algún cable. Con respecto al conector USB los que se utilizan
normalmente para los dispositivos son los del tipo B, si he utilizado uno del tipo A
simplemente es porque es el único que tenía disponible (reciclado de una vieja placa
base de ordenador).
Con respecto al software de diseño de la placa podéis utilizar el que más os guste hay
donde elegir: Altium (Antiguo Protel), Eagle, KiCAD, OrCAD, Ares, PCB Wizar, PCB
Artist, etc.
Por último queda la decisión de utilizar para el diseño una placa de circuito impreso
simple o a doble cara, el desarrollo de placas a doble capa utilizando los métodos
caseros tradicionales como el insolado y la técnica de la plancha suele costar un poco
más de trabajo al principio, pero una vez que perfeccionas la técnica su utilización en
circuitos de mediana complejidad es aconsejable, el que solo haga sus diseños a una
cara sabe el tiempo que hay que perder modificando el ruteo de la placa para incluir los
tediosos puentes de conexión.
Interfaz física
La interfaz física está formada por cuatro hilos dos para la alimentación 5v (Rojo) GND
(Negro) y dos para datos D+ (verde) y D- (Blanco) Lo del signo + y - es porque es una
señal diferencial cuyo valor depende de la velocidad del bus (3,3v para low-speed y
400mV para high-speed).
Los conectores se les denomina de tipo A y de tipo B, una imagen de dichos conectores
la tenéis aquí.
• Low speed: 1,5 Mbps. Soportado por las especificaciones 1.1, 2.0 y 3.0. Es la
velocidad utilizada por dispositivos como teclados, ratones, joystick, etc.
• Full speed: 12 Mbps. Soportado por USB 1.1, USB 2.0 y USB 3.0. Un ejemplo
donde se utilizan estas velocidades es en transmisiones de audio.
• High speed: 480 Mbps. Solo USB 2.0 y USB 3.0. Ejemplo transmisiones de
video.
• Super speed: 5Gbps solo soportado en dispositivos USB 3.0, y como he dicho
antes no conozco ningún microcontrolador que soporte esta especificación.
Transferencias
Una transferencia se puede definir como el conjunto global de los datos que forman una
comunicación USB, una transferencia está formada a su vez por una o varias
transacciones que a su vez están formadas por diferentes paquetes de datos que
contienen las tramas de una comunicación USB.
El VID (Vendor ID) y el PIC (Product ID) son dos números de 16 bits representados en
Hexadecimal, si utilizamos la clase CDC (Communications Device Class) de CCS para la
comunicación USB estos valores los podemos modificar en el archivo "usb_desc_cdc.h"
y según el sistema operativo instalado en el Host deberemos modificarlos también en el
archivo .inf, pero esto lo veremos más adelante.
Realmente el modificar estos valores solo es útil si queremos distribuir nuestro producto
comercialmente, en ese caso existe una organización llamada USB Implementers
Forum que se encarga de proporcionarnos previo pago correspondiente (creo que unos
1500 $) un VID valido para que nuestro dispositivo conviva sin problemas con el resto
de dispositivos USB del mercado, además tendremos derecho a poner el logo USB en
nuestro producto certificando de esta manera que ha pasado los controles pertinentes y
cumple con el estándar USB. Todo esto es similar al proceso que se sigue a la hora de
obtener una dirección MAC en una tarjeta de red.
Si esto no estuviera regulado tal y como está y cada dispositivo tuviera el VID y PID que
quisiera, cuando coincidieran en un mismo sistema dos números iguales se presentaría
un conflicto hardware y ambos dispositivos dejarían de funcionar.
¿Que es un endpoint?
Los endpoint son simplemente buffer de memoria RAM que son utilizados para el envío
y recepción de datos o comandos de control durante una comunicación USB. cada
endpoint puede ser de entrada o salida de datos o bidireccional, el endpoint 0 está
reservado para comandos de control, el proceso de enumeración se realiza a través del
endpoint número 0. Este concepto solo se aplica al dispositivo, en el host existen
también buffer para el envío y recepción de datos pero no se les denomina con este
nombre.
• MSD (Mass Storage Device Class): Como su propio nombre indica para
dispositivos de almacenamiento masivo como discos duros, memorias flash,
cámaras digitales, dispositivos ópticos externos como lectores y grabadoras de
CD y DVD, etc. Esta clase se puede utilizar solo en dispositivos que soporten
velocidades Full y High Speed. El tipo de transferencias utilizadas es Bulk o una
combinación formada por transferencias del tipo Control, Bulk y Interrupt.
Microchip tiene notas de aplicación sobre esta clase como la AN1003, CCS
también implementa ejemplos sobre esta clase. No se necesita la instalación de
un driver específico, se utilizan drivers genéricos instalados ya en los Sistemas
Operativos, en Windows se utiliza el driver llamado usbstor.sys ubicado en
C:\Windows\Sistem32\drivers.
• Existe una clase genérica llamada "Custom Class" que se utiliza cuando el
dispositivo no se asemeja a las características de ninguno de los miembros
pertenecientes a otras clases. un ejemplo de dispositivo que utiliza esta clase es
el ICD2 o ICD3 de Microchip.
En su última versión este driver está soportado por los siguientes sistemas
operativos: Windows 2000, Windows Server 2003, Windows XP, Windows
XP 64, Windows Vista, Windows Vista 64 y Windows 7
Nota importante:
cuando utilizamos el driver personalizado de Microchip los datos se
transmiten en raw (crudo) y la aplicación de escritorio intercambia
información con el PIC directamente a través de los enpoints utilizados por
este, en este caso se usa un protocolo de comunicación que a priori no está
definido. Es importante que copiemos del archivo .INF el valor del campo
definido como GUI (Global Unique Identifier), que es un número que sirve
para que la aplicación pueda acceder al dispositivo, luego accederemos a la
dll desde el IDE que hallamos elegido para desarrollar la aplicación de
escritorio editaremos las
propiedades y funciones publicas de la dll buscando un campo que se llame
GUI (o algo así) y si no coincide tendremos que pegar hay ese número, si
no lo hacemos no se podrá crear la tubería de conexión (pipe) entre
nuestra aplicación y el driver.
Cuando utilizamos la clase CDC esto no es necesario ya que la
comunicación está definida a través del puerto serie virtual creado y la
información se transmite por defecto en forma de caracteres ASCII al igual
que un puerto serie físico.
Otros drivers que podemos utilizar para nuestro PIC 18fx550 son:
• WinUSB: es el driver genérico para USB que propone utilizar Microsof cuando
nuestro dispositivo no puede ser manejado directamente por los drivers que ya
incluye por defecto en su sistema operativo. Para ello al igual que Microchip
proporciona los siguientes archivos: Winusb.sys, Winusb.ini y la librería dinámica
Winusb.dll que al igual que la dll de Microchip nos proporciona una serie de
funciones públicas para acceder fácilmente al driver y a las APIs win32 de
Windows desde nuestra aplicación de escritorio.
Toda la información que proporcionada Microsof sobre este driver la podéis
encontrar en el siguiente enlace.
Bueno y con esto se acaba la pequeña introducción sobre USB enfocada a los PIC, la
mayoría de datos y valores numéricos de está información además de los datasheets
está sacada de apuntes y notas tomadas por mí en las diferentes presentaciones y
seminarios de Microchip a los que he podido asistir a lo largo del tiempo que estoy con
esto de los PICs, por lo que no descarto que pueda haber algún error, de vosotros
depende el verificar dichos datos y si encontráis algún error sería bueno para todos que
lo comentarais en el foro.
Unas de las cosas importantes que tenemos que tener en cuenta al programar el
Microcontrolador son los fusibles, en los que entre otras cosas se define la velocidad de
trabajo del PIC. Una característica que hay que tener en cuenta cuando usamos un PIC
con interfaz USB, es que para que dicho módulo funcione la frecuencia de reloj en la
entrada de dicho módulo debe de ser de 48 MHz, para conseguir dicha frecuencia se
dispone de un multiplicador con pre-escaler y post-escaler. A la entrada del
multiplicador tenemos que tener una frecuencia fija de 4 MHz. En la figura de abajo se
muestra como configurar el pre-escaler del PLL cuando en nuestro circuito tenemos un
cristal de 20 MHz.
Como se ve en la figura, en este caso el pre-escaler divide los 20 MHz por 5 para
obtener los 4MHz requeridos a la entrada del PLL, este a su vez produce 96 MHz en su
salida los cuales se distribuyen por un lado al módulo USB, dividiendo previamente la
frecuencia por 2 para obtener los 48 Mz a la entrada del módulo por el otro lado
alimenta el post-divisor del PLL, para que podamos elegir la frecuencia de trabajo del
núcleo del micro, en este caso divide por tres por lo que tendremos 32 MHz para
alimentar al "core" del PIC.
En el caso de este ejemplo que utiliza la clase CDC (Communications Device Class), las
funciones que se han utilizado para enviar y recibir datos por el bus USB son:
• usb_cdc_kbhit(): Es una función que retorna el valor booleano TRUE si hay uno
o mas caracteres esperando en el buffer de recepción.
Hay más funciones disponibles para su uso directo, la descripción de cada una de ellas
las podéis encontrar en la cabecera del archivo usb_cdc.h.
Otra cosa que hay que tener en cuenta es que para que la comunicación USB se
mantenga debe ser realimentada constantemente, para ello hay que llamar
periódicamente a la función usb_task(), por lo que nuestro programa tendrá que
tener un bucle infinito principal donde deberemos incluir la llamada a esta función.
Como veis es adaptar el algoritmo de nuestro programa a los requisitos que necesita el
"Stack" para que funcione correctamente. Para ello CCS dispone de un gran número de
ejemplos que nos sirven como plantillas para nuestros desarrollos.
De las librerías que nos proporciona CCS para la comunicación USB utilizando la clase
CDC hay un archivo el usb_desc_cdc.h donde se guarda la información perteneciente a
los descriptores del
dispositivo ese archivo podemos editarlo y modificar los descriptores perteneciente al
VID, PID, consumo del dispositivo y versión del firware.
view source
print?
1.///////// Opciones de
configuración ///////////////////////////////////
2.#define USB_CONFIG_PID 0x0033
3.#define USB_CONFIG_VID 0x0461
4.#define USB_CONFIG_BUS_POWER 100 //100mA (rango de 0..500)
5.#define USB_CONFIG_VERSION 0x0100 //01.00 //range is 00.00 to
99.99
6.//////// Fin de la
configuración //////////////////////////////////////////
Nota: según la versión del compilador utilizado, puede que haya modificaciones en los
archivos de las librerías, en la que yo tengo las opciones de configuración de los
descriptores vienen definidas por etiquetas al principio del archivo.
Otra cosa que se puede modificar en este archivo son los "Strings" o cadenas de
caracteres que sirven para que Windows muestre información referente al fabricante del
dispositivo, como por ejemplo nombre de la compañía y nombre del producto. Estas
cadenas están colocadas al final del archivo usb_desc_cdc.h y hay que colocarlas en un
formato determinado según se muestra en el siguiente ejemplo:
view source
print?
01.
02. //string 1 - Fabricante
03. 20, //Longitud de la cadena = (Nº caracteres + 1)x2= (9+1)x2=20
04. USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
05. 'F',0,
06. 'A',0,
07. 'B',0,
08. 'R',0,
09. 'I',0,
10. 'C',0,
11. 'A',0,
12. 'N',0,
13. 'T',0,
14. 'E',0,
15.//string 2 - producto
16. 18, //Longitud de la cadena = (Nº caracteres + 1)x2= (8+1)X2=18
17. USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
18. 'P',0,
19. 'R',0,
20. 'O',0,
21. 'D',0,
22. 'U',0,
23. 'C',0,
24. 'T',0,
25. 'O',0
En el archivo .INF también hay un campo llamado [Strings] que podemos editar para
personalizar la información que presentará el Sistema Operativo sobre nuestro
dispositivo.
¿Que diferencia hay entre unas cadenas y otras?, pues bien, las que se encuentran
en el archivo de los descriptores se mostrarán solo la primera vez que se conecta el
dispositivo al ordenador. En Windows esa información aparecerá en el "bocadillo"
informativo que sale a la derecha en la barra de herramientas, cuando el sistema
detecta un nuevo hardware.
Nota: en Linux esta información no aparece y en MAC lo probaré pero claro, cuando
consiga uno.
Después de que el dispositivo haya sido reconocido por el sistema esa información la
cogerá el S.O desde las cadenas contenidas en el archivo .INF y la podremos ver en
Windows si vamos a la ventana de "Administrador de dispositivos" seleccionamos el
dispositivo y hacemos clic en propiedades.
¿Y como se hace todo esto en Linux? pues muy sencillo porque no hay que instalar
ningún archivo .INF automáticamente el Sistema Operativo reconoce el dispositivo y le
asigna el driver correcto. Lo podemos ver si abrimos la carpeta /dev que es el directorio
donde se guardan los controladores de dispositivos en Linux, como ya sabéis todo en
Linux se gestiona como si de un archivo se tratara, después de conectar el dispositivo
veremos que se nos ha creado un nuevo archivo (puerto COM) con el nombre ttyACM0,
ese será el puerto al que tendremos que conectarnos desde la aplicación de escritorio.
La distribución de Linux con la que he probado la demo ha sido Ubuntu 10.04 LTS con el
kernel 2.2.25
Bueno ya hemos conseguido que nuestro ordenador reconozca a nuestro PIC como un
dispositivo válido, lo único que nos queda ahora es crear la aplicación de escritorio para
que podamos comunicarnos con el.
Cada uno de estos IDES compila o interpreta según el caso el código escrito en
diferentes lenguajes como Basic,.NET, C++, Java, Python, G, etc.
Para esta demo he utilizado RealStudio en su versión para Linux, este IDE utiliza como
lenguaje de programación un Basic moderno orientado a objetos, es Multiplataforma y
con un solo clic de ratón compila el mismo código fuente para tres plataformas
diferentes (Windows, Linux y MAC). Produce un ejecutable compilado en código nativo
por lo que no necesita de ninguna máquina virtual ni de ningún pesado Framework en la
máquina donde se ejecute la aplicación. Dispone de un componente (como la mayoría
de los IDES) para gestionar los puertos COM y lleva integrado la base de datos SQLite,
ideal para guardar datos procedentes del PIC. Es un producto comercial pero flexible en
el tema de las licencias, hay varias opciones con diferentes precios, esta demo está
hecha con la versión Trial completamente funcional durante treinta días (mas que
suficientes para hacer este ejemplo y darse una idea de como es el entorno de
programación), toda la información sobre este IDE se encuentra en la página oficial de
Real Software.
¿Quiere decir que por que e elegido este IDE para hacer el ejemplo lo considero mejor
que los demás?, pues ni Si ni NO. es simplemente una opción más a elegir. Cualquiera
de los IDES anteriormente citados
los considero perfectamente válidos para realizar una pequeña interfaz que sirva para
comunicarse con el PIC. Si que es verdad que prefiero los IDE multiplataforma para
poder ejecutar la aplicación en varios Sistemas Operativos concretamente en Windows y
Linux que son los que normalmente utilizo. Mas adelante haré otros ejemplos en otros
IDES Multiplataforma como Boa (Python) y NetBeans (Java).
Microchip hasta ahora a discriminado a los usuarios que utilizan otros sistemas
operativos diferentes a Windows ya que todo su software y aplicaciones de escritorio
estaban hechas para windows, pero parece ser que está filosofía está cambiando,
prueba de ello es la versión de su software estrella el MPLAB, sus desarrolladores se han
puesto a trabajar en una versión Multiplataforma el MPLABX basado en Java, aunque
de momento está en la versión beta su desarrollo permitirá que todo el software que
proporciona Microchip se vaya portando poco a poco a este entorno y el que quiera
utilizar los pics junto con las herramientas que proporciona Microchip lo pueda hacer en
el sistema operativo que quiera sin la imposición de tener que usar Windows.
Bueno la realización en si de la aplicación de escritorio es bastante sencilla de hacer con
el IDE de Real Studio, es recomendable aunque no inprescindible tener conocimientos
sobre POO (Programación Orientada Objetos), aunque este requisito también es
necesario si utilizamos otros IDES como Visual Studio.NET, Java o Python. Todos los
IDES modernos están basados en la Programación Orientada a Objetos, una vez que
dominas esta técnica de programación el pasarte de un IDE a otro es relativamente
sencillo.
Durante la instalación del IDE del RealStudio se instala la carpeta de ejemplos donde
hay un par de ellos sobre como comunicarse con el puerto serie, una vez que se sabe
como funciona el componente COMM lo demás es añadir los botones, etiquetas y
cuadros de texto que necesitemos según las necesidades del ejemplo que hagamos.