English Version
French Version
Spanish Version
MIDIbox Hardware Platform, Module IIC
MIDI
Le module IIC MIDI procure un
pontage entre
les interfaces MIDI et IIC, et a été
conçu
principalement pour les micro-contrôleurs PIC16F88 de Microchip,
il fonctionne avec un firmware spécial (et pas sous MIOS!).
IIC et MIDI sont toutes deux
des interfaces série:
- L'interface IIC (Inter-IC,
l'abrévation "I2C" est aussi
utilisée) a été conçue pour
réaliser
des échanges de données à des
débits
élevés entre différentes puces, via
simplement
deux conducteurs: un signal d'horloge (clock) et un conducteur
données (datas)
- L'interface MIDI (Musical Instrument Digital
Interface) est une interface "asynchrone" que vous devez
déjà bien connaître (pour preuve,
l'intérêt que vous portez à ce site!
;-)
La combinaison de ces deux
interfaces ouvre la possibilité d'accéder
à
plusieurs ports MIDI In et Out à partir d'un seul micro-contrôleur.
De plus, les "esclaves" IIC MIDI prennent en charge eux-même
quelques tâches de gestion "haut-niveau" du protocole MIDI,
ce
qui a pour effet de libérer des ressources en termes de
temps et
de mémoire pour le module CORE "maître". Ceci a
pour effet
d'améliorer les performances générales.
Le firmware a
été
dévellopé pour gérer
jusqu'à 4 esclaves IIC
MIDI via le bus IIC, avec un module CORE maître:
Chaque esclave a besoin d'une
adresse
unique, qui doit être sélectionnée
à l'aide
de deux jumpers (encodage binaire). En théorie,
jusqu'à
127 esclaves pourraient être chaînés sur
le bus en
définissant autant d'adresses dans le firmware, mais en
pratique, la charge sur le bus augmenterait a un tel niveau que les
buffers seraient en surchage, entraînant la perte de
données. Les considérations à propos
des
performances forment un sujet complexe, et je ne suis pas sûr
de
trouver un jour le temps d'en expliquer tous les détails
ici.
Mais je peux déjà dire qu'aucun
problème de
performance ne devrait survenir en utilisant jusqu'à
4
module IIC_MIDI esclaves
- c'est la combinaison que j'utilise pour mon propre MIDI Router, qui sera
sérieusement testé en condition réelle
dans les années à venir :)
Il faut ajouter ici que le
bus IIC peut accueuillir non seulement des modules
MBHP_IIC_MIDI mais aussi des BankSticks
(EEPROMs IIC), des LCDs IIC
ou encore d'autres micro-contrôleurs disposant d'une
interface
esclaves IIC slave - le firmware MBHP_IIC_MIDI peut
être
utiliser comme base pour d'autres
"gadgets", comme des sensors spéciaux, des extensions IO
analogue/digitale, pont vers les ports RS232, PS2 ou...
pourquoi
pas une connectique ethernet, une liaison wireless ou un
modem? ;-)
Cas d'Utilisation
-
Le module a
été dévellopé pour
répondre aux besoins suivant:
- afin de contourner le bug silicone EUSART,
que l'on retrouve sur la plupart des nouveaux PICs comme le PIC18F4620
(64k flash) et le PIC18F4550 (USB), et qui affecte la
stabilité du port
MIDI Out
- comme base pour un MIDI Router
- comme possibilité d'ajouter des
ports MIDI In et Out indépendant pour des projets comme la MIDIbox SEQ et la MIDIbox SID
- comme base pour d'autres applications,
dévellopées par les membres de la
communauté MIDIbox! :-)
Configuration et Interconnections
-
le schéma du
module MBHP_IIC_MIDI
contients une liste exhaustive de tous les composants
supportés par le firmware.
Il existe aussi une
version "OUT
only",
qui contient seulement les composants requis pour réaliser
un
simple port MIDI Out port - cette version est plus
particulièrement intéressante pour ceux qui
souhaitent
utiliser le module pour contourner le bug EUSART.
Notez que le circuit peut être allégé
en retirant
les LEDs
Power et Tx, mais dans ce cas le débuggage pourrait
s'avérer plus difficile. En supposant que le circuit est
réalisé sur une platine d'essai - ou une
stripeboard, le coût pour le PIC16F88, le quartz 20 MHz, 4
condos, 4
résistances et 2 LEDs est de seulement env. 5 EUR au total!
Retournons à la
version
complète: l'adresse
MBHP_IIC_MIDI doit être sélectionnée
à
l'aide de jumpers sur le port J3. Par défaut, les deux
jumpers
doivent être installés afin de
sélectionner
l'adresse 0x10. en retirant des jumpers, les addresses 0x12, 0x14 ou
0x16 peuvent être sélectionnées. Chaque
module esclave a besoin d'une adresse unique sur le bus IIC, de fait
n'utiliser jamais la même configuration pour plus d'un module!
Le Port J4 est un port
"MIDIbox Link",
qui dispose d'un MIDI IN/OUT au niveau TTL. Il peut être
connecté à un module MBHP_LTC
afin de dupliquer le port MIDI OUT, et pour disposer d'un port MIDI
THRU. J4 peut aussi être utilisé pour une
connexion vers
un autre module CORE sans avoir recours à des optocoupleurs.
Le port J1 n'est pour
l'instant pas utilisé, il reste libre pour de future
implémentations dans le firmware.
Et pour finir, le port J2:
c'est le
port IIC, il se présente sous la forme de connecteur DIL
afin de
simplifier le cablâge en 1:1 du bus entre maître et
esclaves. 4 de ses pins (Vs/Vd pour l'alimentation,
SC/SD pour l'IIC) doivent être connectés aux pins
du même nom
du port J4 du module CORE et au port J2 "IIC_MIDI" des autres esclaves.
La sortie RI# fournit un signal spécial qui indique que le
buffer de réception a été
chargé. Il ne
sera utilisé que par un petit nombre d'applications et doit
être connecté au module CORE, vous trouverez plus
de
détails sur les pages des projets correspondants. Si aucune
indication particulière n'est donnée, laissez ce
pin
ouvert. Ne connectez jamais les lignes RI# des esclaves ensembles, car
ceci causerait un court-circuit!
Le diagramme
simplifié des inter-connections:
Une résistance
pull-up de 1k est
requise entre les lignes Vd et SC (normalement soudées
directement au port CORE::J4) afin de permettre le "clock stretching".
C'est une méthode pour retarder les transferts
serie lorsqu'un esclaves ne peut répondre
immédiatement
à une requête du module maître. La
résistance
pull-up pour la connection SD est déjà
installée
sur le module CORE (CORE::R2).
Adaptateur de programmation pour le PIC16F88
-
SmashTV et Mike
proposeront
probablement des PIC16F88 pré-programmé dans le
future,
mais tant que ce service n'est pas disponible, vous devez
"brûler" le firmware par vous-même dans le PIC16F88
(vous
pouvez aussi demandez sur le forum) en utilisant un programmateur de
PIC tel que le MBHP_BURNER.
Pour les
programmateurs 40, un adapteur vers 18 pin est requis, le
schéma est disponible ici.
Photos de l'adaptateur 40
pins vers 18 pins:
La tension de
programmation est de 13.1V (puce PIC16F!), vous devez utiliser le
programme PBrenner .
Protocole de transfert MBHP_IIC_MIDI
-
Vous trouverez des
détails sur le protocole I2C sur la page I2C
bus specification de Philips.
Tant que vous utilisez les fonctions
MIOS pour accéder au module, vous n'avez pas
besoin de vous soucier de ces
bitstreams - continuez simplement au chapître suivant, il
concerne les algorhytme d'accés. .
adresse esclave:
la notation des
adresses peut être source de confusion, il nous faut donc
préciser d'abord que l'adresse
MBHP_IIC_MIDI correspond à l'adresse esclave IIC
décalée d'un bit vers la gauche
(multipliée par deux). Exemple: l'adresse IIC 0x08
correspond
à l'adresse MBHP_IIC_MIDI
0x10. Cette manipulation a pour but de simplifier la programmation
lorsque l'on dirige le bit R/W# bit vers l'adresse. L'autre raison
c'est que les adresses MBHP_IIC_MIDI sont toujours des nombres pairs.
Si 0x10 est
envoyé aprés
le message de début d'échange (Start), nous
commençons une opération d'écriture
sur le premier
module MBHP_IIC_MIDI, lorsque 0x11 est envoyé, nous
lançons une procédure de lecture.
Transferts vers
MIDI OUT: Les
transferts
vers les ports OUT sont des opérations "Master Write".
Aprés que le maître ait
envoyé le message
Start
et l'adresse, il continue avec les bytes "data", qui sont directement
renvoyés vers le tampon MIDI Tx du module
MBHP_IIC_MIDI. Aprés le derniert byte une information de fin
d'échange (Stop) doit être transmis afin de
libérer
le bus:
Le tampon Tx a une taille
de 96 bytes.
Une fois que ce tampon est plein, l'esclave répond par un
"NAK"
(not
acknoweledge, A bit=1). Dans ce cas, le master doit transmettre un
message Stop, il peut ensuite tenter de reprendre la transmission.
Un message "Restart" (Start sans état Stop
préalable)
n'est pas permis en raison d'un bug "sillicone" dans le module SSP de
la plupart des PIC16F.
La donnée d'une
valeur de "0xff"
(255 en décimal) a une fonction spéciale, elle
sert
à activer un "mode commande". Le "mode commande" a
été implémenté pour de
futures extensions
du firmware. Les séquences suivantes sont actuellement
supportées:
- FF 00: entrer et sortir
du "mode commande", sans autre action.
- FF FF: entrer en "mode
commande", envoiyer "0xff" sur le MIDI OUT, sortir du "mode commande".
- FF <cmd>
<data1> ... <data_n>: entrer
en "mode commande",
appel du IIC_CMD_Handler dans le fichier iic_cmd.asm a chaque
byte reçu. Le nombre maximum de
byte-donnée doit
être déterminé dans le gestionnaire,
pour l'instant
le gestionnaire sort du "mode commande" aprés le premier
byte-donnée.
De fait le "mode commande"
requiert la
précaution suivante: si 0xff ("MIDI Reset") doit
être
renvoyé sur le port MIDI OUT, le maître doit
envoyer ce
message deux fois via l'IIC
Transfertd depuis
le MIDI IN: le
maître peut aussi bien scruter les états de
réception via l'IIC, ou il peut
vérifier la sortie
"low-active" RI# du module MBHP_IIC_MIDI (la solution la plus rapide,
mais qui requiert un signal de connection supplémentaire
vers le
maître). En cas d'analyse via l'IIC, un message "Start
condition"
ainsi que l'adresse doivent être envoyés. Le flag
R/W# doit être sur 1 (opération "Master Read"). Le
maître peut ensuite lire le premier byte, qui contient le
"type
de paquet". Si il est à 0, le maître peut
abandonner
l'échange en envoyant un NAK et un "Stop":
Si le type de paquet n'est
pas à zéro, le maître doit lire trois
bytes supplémentaires:
L'encodage d'un "paquet"
est inspiré des spécifications USB MIDI .
L'utilisation de ce format a un avantage: un routeur
MIDI->IIC->USB a besoin de renvoyer
simplement le
paquet au bus IN de l'hôte USB (le type de paquet correspond
au
CIN, et une opération OR peut être
appliqué entre
le "high-nibble" et le numéro de câble). Ceci
simplifie
également l'implémentation d'un merger MIDI, car
pour
tous les paquets en addition aux messages SysEx, le flow
renvoyé
n'a pas besoin d'être vérouiller - le module
MBHP_IIC_MIDI
transmets la totalité de l'évènement
MIDI :
s
Type |
Taille |
Description |
0x00 |
3 |
Pas de paquet
- tous les bytes à zéro |
0x01 |
3 |
réservé |
0x02 |
2 |
messages
système communs sur deux-bytes tels que MTC, Song
Select, etc. |
0x03 |
3 |
messages
système communs sur trois-bytes comme SPP, etc. |
0x04 |
3 |
"début"
ou "continu" SysEx |
0x05 |
1 |
message
système commun "Single-byte" ou envois sysex suivi d'un
simple byte |
0x06 |
2 |
envois sysex
suivi de deux bytes |
0x07 |
3 |
envois sysex
suivi de trois bytes |
0x08 |
3 |
Note Off |
0x09 |
3 |
Note On |
0x0a |
3 |
Poly-Key Press |
0x0b |
3 |
Control Change |
0x0c |
2 |
Program Change |
0x0d |
2 |
Channel
Preassure |
0x0e |
3 |
Changement de
PitchBend |
0x0f |
1 |
Byte simple |
Algorythme d'accés MBHP_IIC_MIDI
-
Avec le MIOS V1.9 et
supérieur, le module MBHP_IIC_MIDI peut être
appellé suivant les procédures suivantes:
Redirection
MIOS Tx Buffer : les opérations MIOS_MIDI_TxBufferPut
peuvent être redirigées vers un esclave en
sélectionnant l'adresse à l'aide de la fonction MIOS_MIDI_InterfaceSet :
// send MIDI clock over internal MIDI Out with normal baudrate MIOS_MIDI_InterfaceSet(MIOS_MIDI_INTERFACE_COMMON); MIOS_MIDI_TxBufferPut(0xf8);
// send MIDI clock over MBHP_IIC_MIDI with address 0x10 MIOS_MIDI_InterfaceSet(0x10); MIOS_MIDI_TxBufferPut(0xf8);
// switch back to default interface MIOS_MIDI_InterfaceAutoSet();
Redirection
Tx par défaut : avec le
MIOS Bootloader V1.2 et supérieur, les opérations
Tx buffer seront automatiquement redirigées vers le module
MBHP_IIC_MIDI en établissant l'adresser dans le bit 5 de
l'en-tête ID. ExEmple d'ID : 0000000000100000: envoi
des données MIDI sortantes vers MBHP_IIC_MODULE
avec l'adresse 0x10. L'addresse peut toujours être
changée avec MIOS_MIDI_InterfaceSet
pendant le fonctionnement, et peut être remise sur son
réglage par défaut avec MIOS_MIDI_InterfaceAutoSet
Fonction
Réception: les fonctions suivantes peuvent
être utilisée pour recevoir des paquets
MIDI :
// global array which stores the package unsigned char iic_midi_package[4];
///////////////////////////////////////////////////////////////////////////// // This function polls the given MBHP_IIC_MIDI module for a new package // it returns != 0 on a new package, the data will be copied into the // global array "iic_midi_package[4]" (this is to speed up parameter passing) ///////////////////////////////////////////////////////////////////////////// unsigned char IIC_MIDI_Receive(unsigned char addr) __wparam { // start IIC access MIOS_IIC_Start();
// send address, abort if NAK received if( !MIOS_IIC_ByteSend(addr | 1) ) { MIOS_IIC_Stop(); return 0; }
// receive package type, abort if type is 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();
// receive three 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();
// stop IIC access MIOS_IIC_Stop();
return 1; }
fonction
Transmission: les fonctions suivantes peuvent
être utilisée pour envoyer des paquets MIDI:
// this table contains the number of bytes depending on the package type const unsigned char iic_midi_type_bytes[16] = { 0,0,2,3,3,1,2,3,3,3,3,3,2,2,3,1 };
///////////////////////////////////////////////////////////////////////////// // This function sends a package to the given MBHP_IIC_MIDI module // the package content is expected in the global array iic_midi_package[4] // 0 is returned if the module is not available ///////////////////////////////////////////////////////////////////////////// unsigned char IIC_MIDI_Send(unsigned char addr) __wparam { unsigned char retry_ctr; unsigned char i; unsigned char num_bytes;
// start IIC access MIOS_IIC_Start();
// send address retry_ctr = 0; while( !MIOS_IIC_ByteSend(addr) ) { // slave has sent a NAK - retry 255 times MIOS_IIC_Stop(); if( ++retry_ctr == 255 ) return 0; MIOS_IIC_Start(); }
// send package 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]) ) { // slave has sent a NAK - retry // the address needs to be sent again! MIOS_IIC_Stop(); MIOS_IIC_Start(); while( !MIOS_IIC_ByteSend(addr) ) { MIOS_IIC_Stop(); if( ++retry_ctr == 255 ) return 0; MIOS_IIC_Start(); } } }
// stop IIC access MIOS_IIC_Stop();
// the complete package has been transmitted return 1; }
Notez que la fonction
IIC_MIDI_Send() peut être améliorée en
utilisant une fonction distincte pour envoyer l'adresse - J'ai choisi
la version longue pour simplifier la lecture. Une version
optimisée en assembleur est disponible dans le
projet MIDI Router .
Notez
également, que cette version ne tient pas compte de la
condition spéciale pour l'envoi d'un byte "0xff" via MIDI -
dans la version optimisée en assembleur l'appel se
fera de manière récursive. Cette
méthode rendra vraiment obsolète l'exemple
ci-dessus.
Routing MIDI :
les exemples ci-dessus peuvent sembler complex, mais il simplifie
énormément le routing MIDI - voici un petit
extraitdans lequel les paquets entrants sont renvoyés du
premier module MBHP_IIC_MIDI vers le second:
///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS after startup to initialize the // application ///////////////////////////////////////////////////////////////////////////// void Init(void) __wparam { // enable clock stretching MIOS_IIC_CtrlSet(0x01); }
///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS in the mainloop when nothing else is to do ///////////////////////////////////////////////////////////////////////////// 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); } } }
Here a variant, which only
forwards Control Change (CC) packages:
///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS in the mainloop when nothing else is to do ///////////////////////////////////////////////////////////////////////////// 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); } } }
Download
-
-
-
Firmware |
Fichier |
Taille |
Description |
mbhp_iic_midi_v1_0c.zip |
23k |
cette archive
contient le firmware pré-compilé et les codes
source pour le PIC16F88 |
-
Test
-
Une application de bouclage logiciel (iic_midi_sw_loopback) est disponible à la section MIOS Download ,
qui détecte les modules esclaves connectés, et renvoie
directement les évènements MIDI entrants vers les ports
de sorties de ces mêmes modules MBHP_IIC_MIDI esclaves.C'est
l'application parfaite pour tester les module(s), et les fichiers
iic_midi.asm/iic_midi.h inclus peuvent servir de pilotes si vous
souhaitez programmer une application particulière.
Quelques Photos
-
un module MBHP_IIC_MIDI complet connecté au module MBHP_CORE (version du PCB de SmashTV)
-
Deux module avec juste le MIDI-Out (version du PCB de SmashTV)
Crédits
-
Remerciements à SmashTV qui a
créer le layout du PCB, et à Michael Klein qui m'a fourni
quelques pcbs pour mes tests.
Last update: 2015-09-24
Copyright © 1998-2015, Thorsten Klose. All rights reserved.
|