<div dir="ltr"><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">Hi,</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">I would keep the ISR very simple like this and handle rest in main loop.</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif"><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">#define RCVBUFSIZEMASK 0x3F // for 64 bytes, 0x1F for 32 bytes<br>unsigned char rcvbuf[RCVBUFSIZEMASK+1];<br>unsigned int rcvoffset = 0;<br><br>void interrupt USART_isr (void) {<br> unsigned char x;<br> if (RCIF == 1) {<br> x = RCREG;<br> rcvbuf[rcvoffset++ & RCVBUFSIZEMASK] = x; <br> }<br>}<br><br>void main() {<br> // TODO setup UART & ISR<br> unsigned int readoffset = 0;<br> unsigned char running_status = 0;<br> unsigned char databyte_cnt = 0; // keep count of data bytes<br> unsigned char data;<br> RCIE = 1 // enable interrupts<br> // other initialisations <br> while (1) {<br> unsigned char x;<br>
while (rcvoffset != readoffset) {<br>
MIDI_ACTIVITY_LED = ON;<br>
x = rcvbuf[readoffset++ & RCVBUFSIZEMASK];<br>
if (x & 0x80 == 0x80) { // handle status<br>
running_status = x;<br>
continue;<br>
}<br>
switch (running_status) {<br>
case NOTE_ON:<br>
if (databyte_cnt == 0) {<br>
data = x;<br>
databyte_cnt++;<br>
continue;<br>
}<br>
if (databyte_cnt == 1) {<br>
handle_midi_note_on_off(data, x); // key, velocity, velocity = 0 => note off<br>
databyte_cnt = 0;<br>
}<br>
break;<br>
}<br>
}<br>
MIDI_ACTIVITY_LED = OFF;<br>
}<br>}<br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif"><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">or something like that. If you have to send something from MIDI out I would just use polling like</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">TXREG = midi_data_to_send;</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">while (!TRMT);</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif"><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">--Mikko</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 20, 2020 at 4:11 PM Jean-Pierre Desrochers <<a href="mailto:jpdesroc@oricom.ca">jpdesroc@oricom.ca</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div lang="FR-CA"><div class="gmail-m_3137521837195103064WordSection1"><p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">Hi Mikko,<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p><p class="MsoNormal"><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">Here is my USART Rx interrupt routine :<br>Maybe you’ll spot any errors or things I forgot.. ??<u></u><u></u></span></p><p class="MsoNormal"><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">void interrupt tmr0_USART_isr (void) <u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> {<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> char x; // intermediate byte value<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> // RS232 receive interrupt <u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> if (RCIF == TRUE && RCIE == TRUE) <u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> { <u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> if (OERR == TRUE) // overrun, reset UART<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> { <u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> CREN = FALSE; // disable UART<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> CREN = TRUE; // re-enable UART<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> } <u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> <u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> else <u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> { <u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> x = RCREG;<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(228,108,10)"> if((x & 0xF0) != 0xF0) // Ignore all 1 byte commands<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> { // data without errors<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> rcvbuf[rcvoffset] = x; // move byte to rcv buffer <u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> rcvoffset++; // offset next byte<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> if (rcvoffset == RCVBUFSIZE) // beyond buffer boundary<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> rcvoffset = 0; // wrap to begin<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> } <u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> MIDI_ACTIVITY_LED = ON; //RC0 = 0; // Set led MIDI ACTIVITY to ON<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> TMR0 = 0; // restart timer0<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> T0IE=1; // Activates overflow interrupt of TMR0 register<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span></i></b><b><i><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">RCIF = 0; // Erase MIDI RX flag<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> }<u></u><u></u></span></i></b></p><p class="MsoNormal"><b><i><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span></i></b><b><i><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">}<u></u><u></u></span></i></b></p><p class="MsoNormal"><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p><p class="MsoNormal"><b><span lang="FR" style="font-size:10pt;font-family:Tahoma,sans-serif">De :</span></b><span lang="FR" style="font-size:10pt;font-family:Tahoma,sans-serif"> Synth-diy [mailto:<a href="mailto:synth-diy-bounces@synth-diy.org" target="_blank">synth-diy-bounces@synth-diy.org</a>] <b>De la part de</b> Mikko Helin<br><b>Envoyé :</b> 20 mars 2020 01:39<br><b>À :</b> <a href="mailto:synth-diy@synth-diy.org" target="_blank">synth-diy@synth-diy.org</a> List<br><b>Objet :</b> Re: [sdiy] MIDI I/O c code..<u></u><u></u></span></p><p class="MsoNormal"><u></u> <u></u></p><div><p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">>Running status are ignored here</span><u></u><u></u></p><div><p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">So you are ignoring the data bytes that belong to next note on which is using running status, meaning the sender does not send the same status byte again but just skips it and just sends the key and velocity bytes?</span><u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div></div><p class="MsoNormal"><u></u> <u></u></p><div><div><p class="MsoNormal">pe 20. maalisk. 2020 klo 3.29 Jean-Pierre Desrochers <<a href="mailto:jpdesroc@oricom.ca" target="_blank">jpdesroc@oricom.ca</a>> kirjoitti:<u></u><u></u></p></div><blockquote style="border-top:none;border-right:none;border-bottom:none;border-left:1pt solid rgb(204,204,204);padding:0cm 0cm 0cm 6pt;margin-left:4.8pt;margin-right:0cm"><div><div><p class="MsoNormal"><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">></span><span lang="EN-CA"> Are you handling running status and note off sent as zero velocity note on?</span><u></u><u></u></p><p class="MsoNormal"><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">Yes I handle both.</span><u></u><u></u></p><p class="MsoNormal"><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">Running status are ignored here,</span><u></u><u></u></p><p class="MsoNormal"><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">And I consider both NOTE OFF and NOTE ON with zero velocity</span><u></u><u></u></p><p class="MsoNormal"><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">As the end of a note.</span><u></u><u></u></p><p class="MsoNormal"><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span><u></u><u></u></p><p class="MsoNormal"><span lang="EN-CA" style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span><u></u><u></u></p><p class="MsoNormal"><b><span lang="FR" style="font-size:10pt;font-family:Tahoma,sans-serif">De :</span></b><span lang="FR" style="font-size:10pt;font-family:Tahoma,sans-serif"> dougall [mailto:<a href="mailto:dougalli@gmail.com" target="_blank">dougalli@gmail.com</a>] <br><b>Envoyé :</b> 19 mars 2020 21:06<br><b>À :</b> <a href="mailto:eidorian@aladan.net" target="_blank">eidorian@aladan.net</a><br><b>Cc :</b> Jean-Pierre Desrochers; <a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a><br><b>Objet :</b> Re: [sdiy] MIDI I/O c code..</span><u></u><u></u></p><p class="MsoNormal"> <u></u><u></u></p><div><p class="MsoNormal">Are you handling running status and note off sent as zero velocity note on?<u></u><u></u></p><div><p class="MsoNormal"> <u></u><u></u></p></div><div><p class="MsoNormal">-d<u></u><u></u></p></div></div><p class="MsoNormal"> <u></u><u></u></p><div><div><p class="MsoNormal">On Fri, 20 Mar 2020 at 11:55, <<a href="mailto:eidorian@aladan.net" target="_blank">eidorian@aladan.net</a>> wrote:<u></u><u></u></p></div><blockquote style="border-top:none;border-right:none;border-bottom:none;border-left:1pt solid rgb(204,204,204);padding:0cm 0cm 0cm 6pt;margin:5pt 0cm 5pt 4.8pt"><div><p><span style="font-size:10pt;font-family:Verdana,sans-serif">Sorry, I don't have example code for you, but here is some analysis that I hope might help point you in the right direction:</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">20MHz / 31,250Hz => ~640 instructions per MIDI data bit, or 6,400 instructions per MIDI data byte. That's quite a lot of instruction execution time between notes, so I'd be checking the efficiency/optimisation of the code.</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">How long is it taking to update the analog outputs and do other processing? If it's updating all 8 CVs via a "slow" protocol like I2C every time it loops then that might be taking a while, and maybe you need a different approach (i.e. only update a CV output when it changes).</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">How have you implemented the FIFO? Do you have locking to ensure the interrupt isn't writing to it while the main loop is updating it?</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">Create a debug version that has checks on the FIFO size in the interrupt, and sets an LED on if it overflows, so you can confirm for certainly whether or not that's the problem.</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">What I do (with 30+ years of programming experience) is pretend I'm the CPU, and "execute" the code in my head (or on paper if complex) in order to try to work out what unplanned or unexpected things might be happening to cause the problematic behaviour.</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">Cheers,<br>A.</span><u></u><u></u></p><div id="gmail-m_3137521837195103064m_-1322366504434334221gmail-m_5822220122528591338signature"><p class="MsoNormal"><span style="font-size:10pt;font-family:Verdana,sans-serif">---</span><u></u><u></u></p><div><p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New""> </span><u></u><u></u></p></div></div><p><span style="font-size:10pt;font-family:Verdana,sans-serif"> </span><u></u><u></u></p><p id="gmail-m_3137521837195103064m_-1322366504434334221gmail-m_5822220122528591338reply-intro"><span style="font-size:10pt;font-family:Verdana,sans-serif">On 20-03-2020 11:14, Jean-Pierre Desrochers wrote:</span><u></u><u></u></p><blockquote style="border-top:none;border-right:none;border-bottom:none;border-left:1.5pt solid rgb(16,16,255);padding:0cm 0cm 0cm 5pt;margin:5pt 0cm"><blockquote style="border-top:none;border-right:none;border-bottom:none;border-left:1.5pt solid rgb(16,16,255);padding:0cm 0cm 0cm 5pt;margin:5pt 0cm"><div><p class="MsoNormal"><span style="font-size:10pt;font-family:Verdana,sans-serif"> </span><u></u><u></u></p></div></blockquote></blockquote><blockquote style="border-top:none;border-right:none;border-bottom:none;border-left:1.5pt solid rgb(16,16,255);padding:0cm 0cm 0cm 5pt;margin:5pt 0cm"><div id="gmail-m_3137521837195103064m_-1322366504434334221gmail-m_5822220122528591338replybody1"><div><div><p><span style="font-size:10pt;font-family:Verdana,sans-serif">I’m working on a new polyphonic MIDI to CV module (8 voices).</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">So far I did my tests with an old PIC16F887 @ 20Mhz micro I had on hand.</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">I use a USART interrupt driven c function to ‘catch’ all the incoming MIDI bytes.</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">My code is pretty fast, but still, since I only read one MIDI channel (1-16) at the time <br>when I play very fast chords on an external keyboard</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">all the notes are read in the incoming queue but sometimes</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">I get stuck notes or unread ones..</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">Same thing happens when playing MIDI files on Cakewalk SONAR <br>feeding my prototype with a MIDI cable.<br>The interrupt function grabs each incoming byte and put them</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">In a receive buffer of 32 bytes and the main () reads and treats them in a FIFO manner</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">Later in the main loop.</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif"> </span><u></u><u></u></p><p><em><span style="font-family:Verdana,sans-serif">-Would a 32Mhz micro do a difference in the USART interrupt reading speed ?</span></em><u></u><u></u></p><p><em><span style="font-family:Verdana,sans-serif">-And is 32 bytes long enough for the RxBuffer to handle a 6 voices chords ?</span></em><u></u><u></u></p><p><em><span style="font-family:Verdana,sans-serif">-And finaly I checked the web for a ‘decent’ C code examples</span></em><u></u><u></u></p><p><em><span style="font-family:Verdana,sans-serif"> for MIDI reception (MIDI Tx is much easier to implement) with no success..</span></em><i><span style="font-family:Verdana,sans-serif"><br><em><span style="font-family:Verdana,sans-serif"> ‘Obscure’ Arduino libraries all around with no explainations of its inner code.</span></em></span></i><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif"> </span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">Did anybody use good C code available ?</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif">JP</span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif"> </span><u></u><u></u></p><p><span style="font-size:10pt;font-family:Verdana,sans-serif"><a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a></span><u></u><u></u></p></div></div></div><p class="MsoNormal"><span style="font-size:10pt;font-family:Verdana,sans-serif"> </span><u></u><u></u></p><div><p class="MsoNormal"><span style="font-size:10pt;font-family:"Courier New"">_______________________________________________<br>Synth-diy mailing list<br><a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a><br><a href="http://synth-diy.org/mailman/listinfo/synth-diy" target="_blank">http://synth-diy.org/mailman/listinfo/synth-diy</a></span><u></u><u></u></p></div></blockquote></div><p class="MsoNormal">_______________________________________________<br>Synth-diy mailing list<br><a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a><br><a href="http://synth-diy.org/mailman/listinfo/synth-diy" target="_blank">http://synth-diy.org/mailman/listinfo/synth-diy</a><u></u><u></u></p></blockquote></div></div></div><p class="MsoNormal">_______________________________________________<br>Synth-diy mailing list<br><a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a><br><a href="http://synth-diy.org/mailman/listinfo/synth-diy" target="_blank">http://synth-diy.org/mailman/listinfo/synth-diy</a><u></u><u></u></p></blockquote></div></div></div></blockquote></div>