Brick Groove Machine 0.9.3
Firmware embarqué pour contrôleur/synthé Brick
 
Chargement...
Recherche...
Aucune correspondance
Référence du fichier midi.c

Implémentation du module MIDI (UART + USB) pour ChibiOS. Plus de détails...

#include "ch.h"
#include "hal.h"
#include "brick_config.h"
#include "midi.h"
#include "usbcfg.h"
#include <stdbool.h>
#include <stdint.h>

Macros

#define MIDI_USB_TX_PRIO   (NORMALPRIO + 1)
 Priorité du thread de transmission USB-MIDI.
 
#define MIDI_USB_TX_WAIT_MS   2
 Timeout d’attente du sémaphore TX en thread (ms).
 
#define MIDI_UART   &SD2 /* PA2=TX, PA3=RX */
 Périphérique série utilisé pour la sortie DIN MIDI (UART2).
 
#define MIDI_USB_QUEUE_LEN   256
 Taille de la file (mailbox) de messages USB-MIDI (en éléments de 32 bits).
 
#define MIDI_NOTE_MICROWAIT_US   80
 Micro-attente maximale (µs) tolérée pour envoyer une Note (endpoint opportuniste).
 

Fonctions

void midi_init (void)
 Initialise le sous-système MIDI.
 
void midi_note_on (midi_dest_t d, uint8_t ch, uint8_t n, uint8_t v)
 Envoie une note ON.
 
void midi_note_off (midi_dest_t d, uint8_t ch, uint8_t n, uint8_t v)
 Envoie une note OFF.
 
void midi_poly_aftertouch (midi_dest_t d, uint8_t ch, uint8_t n, uint8_t p)
 Envoie un message de pression polyphonique (aftertouch).
 
void midi_cc (midi_dest_t d, uint8_t ch, uint8_t c, uint8_t v)
 Envoie un message de changement de contrôle (Control Change).
 
void midi_program_change (midi_dest_t d, uint8_t ch, uint8_t pg)
 Envoie un changement de programme (Program Change).
 
void midi_channel_pressure (midi_dest_t d, uint8_t ch, uint8_t p)
 Envoie une pression de canal (Channel Pressure).
 
void midi_pitchbend (midi_dest_t d, uint8_t ch, int16_t v14)
 Envoie un pitch bend 14 bits.
 
void midi_mtc_quarter_frame (midi_dest_t d, uint8_t qf)
 
void midi_song_position (midi_dest_t d, uint16_t p14)
 
void midi_song_select (midi_dest_t d, uint8_t s)
 
void midi_tune_request (midi_dest_t d)
 
void midi_clock (midi_dest_t d)
 
void midi_start (midi_dest_t d)
 
void midi_continue (midi_dest_t d)
 
void midi_stop (midi_dest_t d)
 
void midi_active_sensing (midi_dest_t d)
 
void midi_system_reset (midi_dest_t d)
 
void midi_all_sound_off (midi_dest_t dest, uint8_t ch)
 
void midi_reset_all_controllers (midi_dest_t dest, uint8_t ch)
 
void midi_local_control (midi_dest_t dest, uint8_t ch, bool on)
 
void midi_all_notes_off (midi_dest_t dest, uint8_t ch)
 
void midi_omni_mode_off (midi_dest_t dest, uint8_t ch)
 
void midi_omni_mode_on (midi_dest_t dest, uint8_t ch)
 
void midi_mono_mode_on (midi_dest_t dest, uint8_t ch, uint8_t num_channels)
 
void midi_poly_mode_on (midi_dest_t dest, uint8_t ch)
 
uint16_t midi_usb_queue_high_watermark (void)
 Retourne le plus haut niveau de remplissage observé sur la mailbox USB.
 
void midi_stats_reset (void)
 Réinitialise les statistiques de transmission MIDI.
 

Variables

volatile bool usb_midi_tx_ready
 Indicateur d’état de l’USB MIDI.
 
binary_semaphore_t tx_sem
 Sémaphore “endpoint libre”.
 
midi_tx_stats_t midi_tx_stats = {0}
 Statistiques globales de transmission MIDI (USB/DIN).
 

Description détaillée

Implémentation du module MIDI (UART + USB) pour ChibiOS.

Ce module fournit l’envoi de messages MIDI vers deux destinations :

  • DIN UART (31250 bauds) via SD2,
  • USB MIDI (class compliant) via l’endpoint IN (EP2).

Principes d’implémentation :

  • Un thread dédié agrège les paquets USB-MIDI en trames de 64 octets (EP IN bulk) à partir d’une mailbox non bloquante.
  • Les messages “Realtime” (F8, FA/FB/FC/FE/FF) bénéficient d’un chemin rapide avec micro-attente pour l’envoi immédiat si l’endpoint est libre.
  • Les statistiques d’envoi sont tenues dans midi_tx_stats pour le diagnostic.

Contraintes temps réel :

  • Le thread de TX USB doit avoir une priorité au moins égale ou supérieure à l’UI.
  • Les callbacks d’USB doivent rester courts (signalement de sémaphore/flags uniquement).
  • Aucun appel bloquant en ISR ; pas d’allocations dynamiques à l’exécution.
Note
L’API publique est déclarée dans midi.h.

Documentation des macros

◆ MIDI_NOTE_MICROWAIT_US

#define MIDI_NOTE_MICROWAIT_US   80

Micro-attente maximale (µs) tolérée pour envoyer une Note (endpoint opportuniste).

Si l’EP n’est pas saisi dans ce délai, le paquet partira via la mailbox (agrégé).

◆ MIDI_UART

#define MIDI_UART   &SD2 /* PA2=TX, PA3=RX */

Périphérique série utilisé pour la sortie DIN MIDI (UART2).

Mapping Nucleo-144 STM32F429ZI : PA2=TX, PA3=RX.

◆ MIDI_USB_QUEUE_LEN

#define MIDI_USB_QUEUE_LEN   256

Taille de la file (mailbox) de messages USB-MIDI (en éléments de 32 bits).

Chaque élément correspond à un paquet USB-MIDI de 4 octets packé dans un msg_t.

◆ MIDI_USB_TX_PRIO

#define MIDI_USB_TX_PRIO   (NORMALPRIO + 1)

Priorité du thread de transmission USB-MIDI.

Doit être ≥ priorité UI pour garantir une latence stable des I/O.

◆ MIDI_USB_TX_WAIT_MS

#define MIDI_USB_TX_WAIT_MS   2

Timeout d’attente du sémaphore TX en thread (ms).

Évite les blocages si l’hôte USB ne réarme pas l’endpoint.

Documentation des fonctions

◆ midi_active_sensing()

void midi_active_sensing ( midi_dest_t  d)

◆ midi_all_notes_off()

void midi_all_notes_off ( midi_dest_t  dest,
uint8_t  ch 
)

◆ midi_all_sound_off()

void midi_all_sound_off ( midi_dest_t  dest,
uint8_t  ch 
)

◆ midi_cc()

void midi_cc ( midi_dest_t  d,
uint8_t  ch,
uint8_t  c,
uint8_t  v 
)

Envoie un message de changement de contrôle (Control Change).

◆ midi_channel_pressure()

void midi_channel_pressure ( midi_dest_t  d,
uint8_t  ch,
uint8_t  p 
)

Envoie une pression de canal (Channel Pressure).

◆ midi_clock()

void midi_clock ( midi_dest_t  d)

◆ midi_continue()

void midi_continue ( midi_dest_t  d)

◆ midi_init()

void midi_init ( void  )

Initialise le sous-système MIDI.

Initialise le module MIDI (UART + thread TX USB).

  • Configure l’UART DIN à 31250 bauds,
  • Initialise la mailbox et son buffer circulaire,
  • Initialise le sémaphore d’EP libre,
  • Démarre le thread de transmission USB-MIDI.

◆ midi_local_control()

void midi_local_control ( midi_dest_t  dest,
uint8_t  ch,
bool  on 
)

◆ midi_mono_mode_on()

void midi_mono_mode_on ( midi_dest_t  dest,
uint8_t  ch,
uint8_t  num_channels 
)

◆ midi_mtc_quarter_frame()

void midi_mtc_quarter_frame ( midi_dest_t  d,
uint8_t  qf 
)

◆ midi_note_off()

void midi_note_off ( midi_dest_t  d,
uint8_t  ch,
uint8_t  n,
uint8_t  v 
)

Envoie une note OFF.

◆ midi_note_on()

void midi_note_on ( midi_dest_t  dest,
uint8_t  ch,
uint8_t  note,
uint8_t  vel 
)

Envoie une note ON.

Paramètres
destDestination d’envoi (UART/USB/BOTH)
chCanal MIDI [0–15]
noteNuméro de note [0–127]
velVélocité [0–127] (0 = Note Off)

◆ midi_omni_mode_off()

void midi_omni_mode_off ( midi_dest_t  dest,
uint8_t  ch 
)

◆ midi_omni_mode_on()

void midi_omni_mode_on ( midi_dest_t  dest,
uint8_t  ch 
)

◆ midi_pitchbend()

void midi_pitchbend ( midi_dest_t  dest,
uint8_t  ch,
int16_t  value14b 
)

Envoie un pitch bend 14 bits.

Paramètres
value14bValeur entre -8192 et +8191

◆ midi_poly_aftertouch()

void midi_poly_aftertouch ( midi_dest_t  d,
uint8_t  ch,
uint8_t  n,
uint8_t  p 
)

Envoie un message de pression polyphonique (aftertouch).

◆ midi_poly_mode_on()

void midi_poly_mode_on ( midi_dest_t  dest,
uint8_t  ch 
)

◆ midi_program_change()

void midi_program_change ( midi_dest_t  d,
uint8_t  ch,
uint8_t  pg 
)

Envoie un changement de programme (Program Change).

◆ midi_reset_all_controllers()

void midi_reset_all_controllers ( midi_dest_t  dest,
uint8_t  ch 
)

◆ midi_song_position()

void midi_song_position ( midi_dest_t  d,
uint16_t  p14 
)

◆ midi_song_select()

void midi_song_select ( midi_dest_t  d,
uint8_t  s 
)

◆ midi_start()

void midi_start ( midi_dest_t  d)

◆ midi_stats_reset()

void midi_stats_reset ( void  )

Réinitialise les statistiques de transmission MIDI.

Réinitialise les compteurs de statistiques MIDI.

◆ midi_stop()

void midi_stop ( midi_dest_t  d)

◆ midi_system_reset()

void midi_system_reset ( midi_dest_t  d)

◆ midi_tune_request()

void midi_tune_request ( midi_dest_t  d)

◆ midi_usb_queue_high_watermark()

uint16_t midi_usb_queue_high_watermark ( void  )

Retourne le plus haut niveau de remplissage observé sur la mailbox USB.

Documentation des variables

◆ midi_tx_stats

midi_tx_stats_t midi_tx_stats = {0}

Statistiques globales de transmission MIDI (USB/DIN).

Statistiques globales d’état et de performance MIDI.

◆ tx_sem

Sémaphore “endpoint libre”.

Callback IN (EP2) — signale la fin de transmission MIDI.

Signalé dans le callback d’EP IN (ex. ep2_in_cb() côté usbcfg.c).

◆ usb_midi_tx_ready

volatile bool usb_midi_tx_ready
extern

Indicateur d’état de l’USB MIDI.

Positionné à true lorsque l’USB est configuré et l’EP prêt. Fourni par usbcfg.c (déclaré ici en extern).

Indicateur d’état de l’USB MIDI.

Indique si la couche MIDI USB est prête à l’envoi. Défini et mis à jour dans usb/usbcfg.c.