Fixed problem in DeviceSettings::strParam, returned wrong string
[avr-sim.git] / test / midi.c
blobc3a1ee9a7c46a584ab168243cd46f8e98598dc6f
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3 #include <stdio.h>
4 #include "midi.h"
6 volatile int16_t midisync_clocked = 0;
8 #define MIDI_Q_SIZE 32
9 volatile uint8_t midi_q[MIDI_Q_SIZE]; // cyclic queue for midi msgs
10 volatile static uint8_t head_idx = 0;
11 volatile static uint8_t tail_idx = 0;
13 #define MIDI_BAUDRATE 31250UL // the MIDI spec baudrate
15 // interrupt on receive char
16 ISR(SIG_USART0_RECV) {
17 char c = UDR0;
19 midi_q[tail_idx++] = c; // place at end of q
20 tail_idx %= MIDI_Q_SIZE;
22 if( tail_idx == head_idx ) {
23 // i.e. there are too many msgs in the q
24 // drop the oldest msg?
25 head_idx++;
26 head_idx %= MIDI_Q_SIZE;
30 void midi_init(void) {
31 /* setup the MIDI UART */
32 uint16_t ubbr = (F_CPU / (16 * MIDI_BAUDRATE)) - 1; // formula in datasheet
33 UCSR0B |= (1<<RXEN0) | (1<<TXEN0)| (1<<RXCIE0); // read and write, interrupt on recv.
34 UBRR0L = (uint8_t)ubbr; // set baudrate
35 UBRR0H = (uint8_t)(ubbr>>8);
38 int midi_putchar(uint8_t c) {
39 loop_until_bit_is_set(UCSR0A, UDRE0);
40 UDR0 = c;
41 return 0;
44 int midi_getch(void) { // checks if there is a character waiting!
45 if (head_idx != tail_idx)
46 return 1;
47 return 0;
50 int midi_getchar(void) {
51 char c;
53 while (head_idx == tail_idx);
55 cli();
56 c = midi_q[head_idx++];
57 head_idx %= MIDI_Q_SIZE;
58 sei();
60 // midi_putchar(c);
61 return c;
64 static uint8_t SYSEX_snd_checksum;
65 void sysex_start(uint8_t command) {
66 // Reset checksum
67 SYSEX_snd_checksum = 0;
69 // Send SYSEX start, manufacturer ID, model number and command
70 midi_putchar(MD_SYSEX_START);
71 midi_putchar(MD_MF_ID_1);
72 midi_putchar(MD_MF_ID_2);
73 midi_putchar(MD_MF_ID_3);
74 midi_putchar(MD_SYNTH_ID);
75 midi_putchar(command);
78 void sysex_data(uint8_t data) {
79 // split one byte of data in two
80 uint8_t msb = data >> 7;
81 uint8_t lsb = data & 0x7f;
82 midi_putchar(msb);
83 midi_putchar(lsb);
85 SYSEX_snd_checksum = (SYSEX_snd_checksum + msb + lsb) % 128;
88 void sysex_end(void) {
89 // Send checksum
90 midi_putchar(SYSEX_snd_checksum);
92 // Send end of SYSEX
93 midi_putchar(MD_SYSEX_END);