English Version
French Version
Spanish Version
Plataforma de Hardware MIDIbox, Módulo IIC MIDI
El módulo IIC MIDI provee un puente entre IIC and MIDI, y solo consiste en un miscocontrolador PIC16F88 de Microchip, que funciona con un firmware especial (¡no MIOS!).
IIC y MIDI son ambas interfaces seriales:
- IIC (Inter-IC, la abreviatura "I2C"
también se usa a menudo) está preparada para intercambio
rápido de datos entre múltiples dispositivos via un solo
reloj y una línea de datos.
- MIDI (Musical Instrument Digital Interface) es una
interfaz asíncrona que probablemente conozcas muy bien (de otro
modo no te interesaría esta web) ;-)
La combinación de estas dos interfaces abre la
posibilidad de acceder a múltiples puertos MIDI In y Out
desde un solo microcontrolador.
Además, los esclavos IIC MIDI se ocupan del manejo de algunos
altos niveles de protocolo MIDI para aliviar al core master
ahorrándole tiempo y tareas de memoria intensiva. Esto mejora el
funcionamiento en general.
Se ha preparado el firmware para hasta 4 esclavos IIC MIDI conectados vía bus IIC a un solo master:
Cada esclavo necesita una dirección
única, que debe ser seleccionada con dos jumpers (codificado
binario). En teoría se podrían añadir127 esclavos
al bus alterando la dirección base desde el firmware, pero en la
práctica, la carga del bus puede incrementarse hasta un nivel en
el que los buffers se saturan y los datos se pierden. Las
consideraciones de Rendimiento son un tema complejo, y no sé si
algún día encontraré tiempo para explicar todos
los aspectos al detalle, pero puedo decir que no debería haber
problemas de rendimiento con 4 esclavos IIC_MIDI - esta es la
configuración que uso para mi propio Router MIDI, que será probado con dureza en , en condiciones de uso real, en los próximos años :)
Hay que mencionar que no sólo se pueden añadir módulos MBHP_IIC_MIDI al bus IIC, sino también BankSticks
(IIC EEPROMs), IIC LCDs o incluso otros microcontroladores con interfaz
de esclavo IIC - el firmware de MBHP_IIC_MIDI se puede usar como
plantilla para este tipo de inventos, como sensores especiales,
extensiones analógicas/digitales IO, puentes a RS232, puertos
PS2 o... ¿qué me dices de ethernet, un enlace
wireless o un módem? ;-)
Casos de Uso
-
El módulo se ha desarrollado con los siguientes usos en mente:
- como "apaño" para el irritante error de silicona EUSART,
que se da en los PICs más recientes como el PIC18F4620
(dispositivo flash 64k) y el PIC18F4550 (dispositivo USB), y que
afecta a la fiabilidad del puerto MIDI Out
- como base para un Router MIDI flexible
- como una simple posibilidad para conseguir puertos MIDI In y Out adicionales, independientes, para proyectos como MIDIbox SEQ y MIDIbox SID
- como plantilla para inventos más poderosos, desarrollados por miembros de la comunidad MIDIbox! :-)
Configuración e Interconexiones
-
El esquema MBHP_IIC_MIDI contiene un super-set de todos los componentes soportados por el firmware.
También hay una versión reducida "OUT solo"
disponible, que solo contiene las partes que hacen falta para un solo
puerto MIDI Out - Esta versión es especialmente
interesante para la gente que quiere usar el módulo como
apaño para el error EUSART. Recuerda que este circuito puede ser
simplificado aún más quitándole los LEDs de Power
y Tx, pero en ese caso, la corrección de errores sería
complicada. Asumiendo que este circuito mínimo se construye en
un vector - o tabla de líneas, el precio del PIC16F88, cristal
de 20 MHz, 4 capacitadores, 4 resistencias y LEDs no supera los 5
€ en total!
De vuelta a la versión completa:hay que
seleccionar con jumpers la dirección de MBHP_IIC_MIDI en el
puerto J3. Por defecto, ambos jumpers deben ser colocados para
seleccionar la dirección 0x10. Quitando los jumpers, se pueden
seleccionar las direcciones 0x12, 0x14 o 0x16. Cada módulo
esclavo necesita una dirección única en el bus IIC,
así que ¡nunca uses la misma configuración para
más de un módulo!
El puerto J4 es un puerto "de enlace MIDIbox" , que da MIDI IN/OUT en el nivel TTL. Se puede conectar a un módulo MBHP_LTC
para duplicar el MIDI OUT, y para obtener un MIDI THRU. También
se puede usar J4 para una conexión directa con otro
módulo Core sin necesidad de usar optoacopladores.
El puerto J1 no se usa actualmente, es de libre personalización en el firmware.
Por último, pero no menos importante, J2: este
es el puerto IIC hecho como un header DIL para simplificar el cableado
del bus 1:1 entre esclavos y master. 4 de estos pines (Vs/Vd para
alimentación, SC/SD para IIC) se tienen que conectar a los pines con el mismo nombre
en CORE::J4 y a IIC_MIDI::J2 de los otros esclavos. La salida RI# es
una señal especial que identifica que el buffer de
recepción se ha llenadoSólo lo usarán un
pequeño número de aplicaciones y debe estar conectado al
módulo Core; puedes encontrar más detalles en las
páginas apropiadas de proyecto. Si no se da ninguna referencia,
deja este pin abierto. Nunca conectes juntas las líneas RI# de
los esclavos, esto causaría un cortocircuito.
Un diagrama de conexión simplificado:
Nota importante para usuarios de MBHP_CORE_V2:
es necesaria una resistencia pull-up de 1k entre el Vd y la
línea SC, soldada directamente al CORE::J4 para permitir
"estrechamiento de reloj" ("clock
stretching"). Este es un método para retrasar transferencias
seriales cuando un esclavo no puede responder inmediatamente a una
petición del master. La resistencia para la línea SD
también está disponible en el módulo Core
(CORE::R2). Los
usuarios de MBHP_CORE_V3 se darán cuenta de que ambas
resistencias ya están puestas - no hace falta añadir nada!
Adaptador de programación para PIC16F88
Es probable que SmashTV y Mike distribuyan PIC16F88
pre-programados en el futuro, pero ya que este servicio aún no
está disponible, tendrás que "quemar" el firmware en el
PIC16F88 por tus propios medios, usando un programador PIC como MBHP_BURNER.
Para programadores de 40 pines será necesario un adaptador a 18 pines. El esquema está aquí.
Fotos del adaptador de programación:
El voltaje de programación es de 13.1V ( ¡dispositivo PIC16F!), Hay que usar el software de programación PBrenner.
Protocolo de transferencia MBHP_IIC_MIDI
-
Se describen los detalles del protocolo I2C en especificaciones de bus I2C de Philips. Mientras estés usando las funciones MIOS
para acceder al módulo, no necesitas ocuparte de estas
corrientes de bits - solo continúa hasta el siguiente
capítulo en el que se describen los algoritmos de acceso.
Dirección del Esclavo:
la dirección puede llevar a confusión, así que he
de aclarar que la dirección de MBHP_IIC_MIDI es la
dirección del esclavo IIC cambiada de puesto hacia la izquierda
(multiplicada por dos). Ejemplo: la dirección IIC 0x08 es la
dirección MBHP_IIC_MIDI 0x10. Esto es para simplificar la
programación cuando se añade el bit R/W# a la
dirección. Esta es también la razón de que las
direcciones MBHP_IIC_MIDI son siempre números.
Si
se envía 0x10 tras una condición de Start (inicio),
estamos comenzando una operación de escritura en el primer
módulo
MBHP_IIC_MIDI, cuando se envía 0x11, comenzamos una
operación de lectura. -
Transferencias a MIDI OUT:
Las transferencias al puerto OUT son operaciones de "escritura Master".
Después de que el master haya mandado la condición de
Start y la dirección, continúa con los bytes de datos,
que son directamente redirigidos hacia el buffer MIDI Tx del
módulo MBHP_IIC_MIDI. Después del último byte, ha
de enviarse una condición de Stop para liberar el bus:
El
buffer
Tx tiene un tamaño de 96 bytes. Una vez que está lleno,
el esclavo responderá con una NAK (not acknoweledge /no
reconocimiento , A bit=1). En este caso, el master tiene que mandar una
condición de Stop, luego puede reintentarlo. No
se permite la condición de Restart (reinicio)(inicio sin
condición de Stop) debido al error de silicona en el
módulo SSP de la mayoría de derivados del PIC16F. -
El
valor de datos "0xff" (255 decimal) tiene un propósito especial
ya que se usa como símbolo de modo de comandos. El modo de
comandos se ha preparado para futuras expansiones del firmware. Se
soportan las siguientes secuencias:
- FF 00: mete y saca el modo de comandos, sin más acciones.
- FF FF: mete el modo de comandos, envía 0xff a través del MIDI OUT, sale del modo de comandos.
- FF <cmd> <data1> ... <data_n>:
mete el modo de comandos, se enrama con IIC_CMD_Handler en iic_cmd.asm
en cada byte que esté siendo recibido. El número
máximo de bytes de datos ha de ser determinado dentro del
handler, actualmente, el handler solo sale del modo de comandos
después del primer byte de datos.
El modo de comandos conlleva al siguiente requerimiento: si
0xff ("MIDI Reset") debe ser redirigido al puerto MIDI OUT, el master tiene que enviarlo dos veces vía IIC.
Transferencias desde MIDI IN:
el master puede o votar el estado de recepción
vía IIC, o comprobar la salida RI# poco-activa del
módulo MBHP_IIC_MIDI (la solución más
rápida, pero requiere una señal adicional de
conexión al master).
En caso de voto vía IIC, han de ser enviadas una
condición de start y la dirección. La etiqutea R/W# debe
ser 1 (Master Read operation). Luego, el master puede leer el primer
byte que contiene el "tipo de paquete" . Si es 0, el master puede
abortar la transacción enviando una NAK y una condición
de Stop:
Si el tipo de paquete no es cero, el master debe leer hasta tres bytes adicionales:
La codificación de un "paquete" está inspirada en la especificación USB MIDI.
Usar este formato tiene una ventaja, que un router MIDI->IIC->USB
sólo necesita redirigir el paquete a la pipa IN del host USB (El
tipo de paquete es el CIN, y el número de cable puede ser OReado
al high-nibble). Esto también simplifica la
implementación de un MIDI merger, ya que para todos los paquetes
aparte de SysEx, las corrientes de redirección no tienen que ser
bloqueadas - MBHP_IIC_MIDI
transmite el evento MIDI completo:
s
Tipo |
Tamaño |
Descripción |
0x00 |
3 |
No paquete - todo los bytes son cero |
0x01 |
3 |
reservado |
0x02 |
2 |
mensajes de dos bytes comunes de sistema como MTC, Song Select, etc. |
0x03 |
3 |
mensajes de tres bytes comunes de sistema como SPP, etc. |
0x04 |
3 |
SysEx comienza o continúa |
0x05 |
1 |
mensaje de un solo byte común de sistema o que envía sysex con el siguiente byte solo |
0x06 |
2 |
SysEx envía con los siguientes dos bytes |
0x07 |
3 |
SysEx envía con los siguientes tres bytes |
0x08 |
3 |
Nota Off |
0x09 |
3 |
Nota On |
0x0a |
3 |
Presión multi-tecla |
0x0b |
3 |
Cambio de Control |
0x0c |
2 |
Cambio de programa |
0x0d |
2 |
Presión de Canal |
0x0e |
3 |
Cambio de PitchBend |
0x0f |
1 |
Único Byte |
algoritmos de acceso MBHP_IIC_MIDI
-
Con MIOS V1.9 y superiores, se puede acceder al dispositivo MBHP_IIC_MIDI de las siguientes maneras:
Redirección del Buffer Tx MIOS: las operaciones de MIOS_MIDI_TxBufferPut se pueden redirigir a un esclavo seleccionando la dirección con la función MIOS_MIDI_InterfaceSet:
// envía reloj MIDI a través del MIDI Out interno con tasa de baudios normal MIOS_MIDI_InterfaceSet(MIOS_MIDI_INTERFACE_COMMON); MIOS_MIDI_TxBufferPut(0xf8);
// envía reloj MIDI a través de MBHP_IIC_MIDI con dirección 0x10 MIOS_MIDI_InterfaceSet(0x10); MIOS_MIDI_TxBufferPut(0xf8);
// vuelve a la interfaz por defecto MIOS_MIDI_InterfaceAutoSet();
Redirección Tx por defecto:
con el Bootloader de MIOS V1.2 y superiores, las operaciones del buffer
Tx serán automáticamente redirigidos a un módulo
MBHP_IIC_MIDI estableciendo la dirección en el byte 5 del
cabecero ID. Ejemplo ID: 0000000000100000: envía los datos MIDI
salientes al módulo MBHP_IIC_MODULE con dirección 0x10.
La dirección se puede cambiar con MIOS_MIDI_InterfaceSet en el tiempo de funcionamiento, y se puede volver a establecer el valor por defecto con MIOS_MIDI_InterfaceAutoSet
Función de Recepción: se puede usar esta función para recibir un paquete MIDI:
// arsenal global que almacena el paquete unsigned char iic_midi_package[4];
///////////////////////////////////////////////////////////////////////////// // Esta función vota el módulo MBHP_IIC_MIDI dado para un nuevo paquete // devuelve != 0 en un nuevo paquete, los datos se copiarán en el arsenal global // "iic_midi_package[4]" (esto es para agilizar el paso de parámetros) ///////////////////////////////////////////////////////////////////////////// unsigned char IIC_MIDI_Receive(unsigned char addr) __wparam { // start IIC access MIOS_IIC_Start();
// envía dirección, aborta si se recibe NAK if( !MIOS_IIC_ByteSend(addr | 1) ) { MIOS_IIC_Stop(); return 0; }
// recibe el tipo de paquete, aborta si el tipo es 0x00 if( (iic_midi_package[0] = MIOS_IIC_ByteReceive()) == 0x00 ) { MIOS_IIC_NakSend(); // abort transfer MIOS_IIC_Stop(); // stop IIC return 0; } MIOS_IIC_AckSend();
// recibe tres bytes iic_midi_package[1] = MIOS_IIC_ByteReceive(); MIOS_IIC_AckSend(); iic_midi_package[2] = MIOS_IIC_ByteReceive(); MIOS_IIC_AckSend(); iic_midi_package[3] = MIOS_IIC_ByteReceive(); MIOS_IIC_NakSend();
//pata acceso IIC MIOS_IIC_Stop();
return 1; }
Función de Transmisión: se puede usar esta función para enviar un paquete MIDI:
//esta tabla contiene el número de bytes, dependiendo del tipo de paquete const unsigned char iic_midi_type_bytes[16] = { 0,0,2,3,3,1,2,3,3,3,3,3,2,2,3,1 };
///////////////////////////////////////////////////////////////////////////// // Esta función envía un paquete al módulo MBHP_IIC_MIDI dado, //el contenido del paquete se espera en el arsenal global iic_midi_package[4] // devuelve 0 si el módulo no está disponible ///////////////////////////////////////////////////////////////////////////// unsigned char IIC_MIDI_Send(unsigned char addr) __wparam { unsigned char retry_ctr; unsigned char i; unsigned char num_bytes;
// inicia acceso IIC MIOS_IIC_Start();
// envía dirección retry_ctr = 0; while( !MIOS_IIC_ByteSend(addr) ) { // el esclavo ha enviado un NAK - reintentar 255 veces MIOS_IIC_Stop(); if( ++retry_ctr == 255 ) return 0; MIOS_IIC_Start(); }
// envía paquete num_bytes = iic_midi_type_bytes[iic_midi_package[0] & 0x0f]; for(i=0; i<num_bytes; ++i) { retry_ctr = 0; while( !MIOS_IIC_ByteSend(iic_midi_package[i+1]) ) { // el esclavo ha enviado un NAK- reintentar // ¡hay que enviar de nuevo la dirección! MIOS_IIC_Stop(); MIOS_IIC_Start(); while( !MIOS_IIC_ByteSend(addr) ) { MIOS_IIC_Stop(); if( ++retry_ctr == 255 ) return 0; MIOS_IIC_Start(); } } }
// para accso IIC MIOS_IIC_Stop();
// se ha transmitido el paquete completo return 1; }
Recuerda
que la función IIC_MIDI_Send() puede ser "embellecida" usando
una función separada para enviar la dirección- He elegido
la versión larga para simplificar su lectura. Puedes encontrar
una versión ensambladora optimizada en el proyecto MIDI Router .
Por
favor, recuerda que esta versión no se ocupa de la
condición especial para mandar un byte "0xff" a
través del MIDI - La versión ensamblada optimizada
solo se llamará recurrentemente. Este método realmente
explotará el ejemplo superior.
Enrutamiento MIDI:
Los ejemplos superiores pueden parecer complejos, pero simplifican
mucho el enrutamiento MIDI -the above examples might look complex, but
they simplify MIDI routing a
lot - aquí un simple y útil código, que redirige
los paquetes entrantes del primer módulo MBHP_IIC_MIDI al
segundo:
///////////////////////////////////////////////////////////////////////////// // MIOS llama a esta función después del arranque para inicializar la aplicación ///////////////////////////////////////////////////////////////////////////// void Init(void) __wparam { // enable clock stretching MIOS_IIC_CtrlSet(0x01); }
///////////////////////////////////////////////////////////////////////////// // MIOS llama a esta función en el loop principal, cuando no hay nada más que hacer ///////////////////////////////////////////////////////////////////////////// void Tick(void) __wparam { if( IIC_MIDI_Receive(0x10) ) { if( !IIC_MIDI_Send(0x12) ) { MIOS_LCD_Clear(); MIOS_LCD_PrintCString("Slave 0x12 not connected"); MIOS_LCD_MessageStart(255); } } }
Aquí una variante que solo redirige los paquetes de Cambio de Control (CC):
///////////////////////////////////////////////////////////////////////////// //MIOS llama a esta función en el loop principal, cuando no hay nada más que hacer ///////////////////////////////////////////////////////////////////////////// void Tick(void) __wparam { if( IIC_MIDI_Receive(0x10) && iic_midi_package[0] == 0x0b ) { if( !IIC_MIDI_Send(0x12) ) { MIOS_LCD_Clear(); MIOS_LCD_PrintCString("Slave 0x12 not connected"); MIOS_LCD_MessageStart(255); } } }
Descarga
-
Firmware |
Archivo |
Tamaño |
Descripción |
mbhp_iic_midi_v1_0c.zip |
23k |
Este paquete contiene el firmware precompilado y el código fuente de para el PIC16F88 |
Probando
Puedes encontrar una aplicación de software loopback (iic_midi_sw_loopback) en la sección MIOS Download,
que escanea buscando esclavos disponibles, y redirige directamente los
datos MIDI entrantes a los puertos de salida de los mismos
esclavos MBHP_IIC_MIDI. Esta es una aplicación perfecta
para probar el módulo ( o los módulos) y se pueden usar
los archivos iic_midi.asm/iic_midi.h incluídos como
controlador de módulo para aplicaciones propias.
Más PICs
A single full stuffed MBHP_IIC_MIDI module connected to a MBHP_CORE (SmashTV's PCB version)
Dos módulos solo MIDI-Out (versión PCB de SmashTV's)
Agradecimientos
Gracias
a SmashTV, que crearon la base PCB y a Michael Klein, que me
proporcionó muchas placas-prototipo de forma gratuíta
(¡gran servicio!)
Last update: 2015-09-24
Copyright © 1998-2015, Thorsten Klose. All rights reserved.
|