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

los datos PCB se pueden visionar, modificar y convertir con Eagle Light
Módulo Esquema Datos de base Vista Rápida
MBHP_IIC_MIDI mbhp_iic_midi.pdf mbhp_iic_midi_v3.brd mbhp_iic_midi_v3.gif
MBHP_IIC_MIDI mbhp_iic_midi_out_only.pdf no planeado -
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
Información adicional
Archivo Tamaño Descripción
mbhp_iic_midi_orderlist.txt 1k lista de pedido Reichelt

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.