SenPi Posted January 17, 2009 Share Posted January 17, 2009 Ok, well I mentioned in another thread that I was essentially making a synth out of an FPGA board. Now, I have a midi controller im going to use for crontrolling this beast (Axiom-25). Now, Ive spliced a midi cord in to a serial cord to send data to the FPGA, and I am definitely getting the bits, but the timing is what is killing me. From what I have read, midi will send 1 start bit, 8 data bits, and 1 stop bit, all within 320 micro seconds (1000 milli = 1 second, 1000 micro = 1 milli), and its kind of a bitch to time properly. So far, I have been getting constant results, but the bytes im getting dont quite make sense with the midi signal data ive read (like It doesnt look like im getting the proper signals.. when I hit a note I seem to be getting the tune up signal or something). So yeah, just wondering if anybody has any sort of info or knows where I can get infor on this stuff. I would really appreciate it. Thanks. Quote Link to comment Share on other sites More sharing options...
po! Posted January 17, 2009 Share Posted January 17, 2009 Ok, well I mentioned in another thread that I was essentially making a synth out of an FPGA board. i've actually done that for a class project. i found this MIDI spec: http://www.ibiblio.org/emusic-l/info-docs-FAQs/MIDI-doc/ and of course an easy way to find out whats going on is to press a button on your controller and look at the signal coming out of it on the scope Quote Link to comment Share on other sites More sharing options...
SenPi Posted January 17, 2009 Author Share Posted January 17, 2009 scope? Also have found that site. The bit streams I was getting (assuming I was capturing them properly) didnt seem to properly match what I was pressing on the keyboard. I might have to work on the timings a bit more perhaps. btw Im using a Cyclone II http://rocky.digikey.com/weblib/Altera/Web%20photos/mfgDK-CYCII-2C20Nboard.jpg, Also I am doing this for a class, so I am not allowed to use ANY libraries or anything at all. Im coding all the drivers and stuff from scratch. EDIT: hmm after reading a bit more about my axiom, I found out that I was on a different preset. Preset 1 is General MIDI, and I was on a preset used for reason, so those bit streams probably mean different stuff in the context of reason . Im gonna try with preset 1 and see if I get proper things. Edit2:... omg so it turns out the data the midi controller sends, is opposite. 1 = off, and 0 = on. I thought it was the other way (looks like I didnt read carefully enough). This is awesome, Im finally getting the bytes im expecing. Thanks for that site also Quote Link to comment Share on other sites More sharing options...
The Pezman Posted January 18, 2009 Share Posted January 18, 2009 Can you post more details about this? I've become pretty interested in this idea. How do you code drivers, anyway? Is it as difficult as it sounds? Quote Link to comment Share on other sites More sharing options...
SenPi Posted January 18, 2009 Author Share Posted January 18, 2009 short answer... yes. Different hardware requires a different way to code I think. Anyways, I posted a pic of what hardware I was using. It is a Field Programmable Gate Array (FPGA). The way I am progeamming for it right now is with a language called Verilog. I could show you what I have going so far. If you have any questions about the code just ask. NOTE: This code is dirty as hell. Since im just messing around so far just trying to figure stuff out, I havent taken the time to clean the code or anything. module Drivers(SW,KEY,LEDR,LEDG,UART_RXD,CLOCK_27,HEX0,HEX1,SRAM_ADDR,SRAM_DQ,SRAM_WE_N,SRAM_OE_N,SRAM_CE_N); input [9:0] SW; //Switches input [3:0] KEY; //Keys input [1:0] CLOCK_27; //27 Mhz Clock input UART_RXD; //Serial Input output [9:0] LEDR; //Red LED's output [7:0] LEDG; //Green LED's output [6:0] HEX0; //Seven Segment Display 0 output [6:0] HEX1; //Seven Segment Display 1 output [17:0] SRAM_ADDR; //SRAM Address inout [15:0] SRAM_DQ; //SRAM Data output SRAM_WE_N; //SRAM Write Enable output SRAM_OE_N; //SRAM Output Enable output SRAM_CE_N; //SRAM Chip Enable assign LEDG[7] = UART_RXD; //Every time UART_RXD (i.e. midi) sends a bit, light the 7th green LED// sramStuff ss(SRAM_ADDR,SRAM_DQ,SRAM_WE_N,SRAM_OE_N,SRAM_CE_N,~KEY[1:0],LEDG[7:0]); getMidi gM(UART_RXD,CLOCK_27[1],LEDR[9:0],HEX0, HEX1);endmodule//module sramStuff (Addr, Data, WriteEnable, OutputEnable, ChipEnable, Keys, LED);//endmodulemodule getMidi(MidiIn,Clock,RedLED,Hex0,Hex1); input MidiIn; input Clock; output [9:0] RedLED; output [6:0] Hex0; //Seven Segment Display 0 output [6:0] Hex1; //Seven Segment Display 1 wire newClock; //Anything with reg means Register. Just think of it like an int or something. reg cool; initial cool = 0; reg notCool; initial notCool = 0; reg [32:0] counter; initial counter = 0; reg [7:0] data; initial data = 0; clocker c(Clock,newClock); //Start the clock changeSSD a(data[3:0],Hex0); //Set SSD 0 to the rightmost 4 bits of data changeSSD b(data[7:4],Hex1); //Set SSD 1 to the leftmost 4 bits of data assign RedLED = data; //Make the Red LED's the same as data (if data = 1, led0 is on, if data = 2, led 1 is on, if data = 4 led 2 is on, etc) always @(posedge newClock) //Whenever newClock becomes positive, do this... begin if(cool == 1) //If we are reading in midi bits... begin data[counter] = ~MidiIn; //Set the proper bit in data to the NOT of the midi bit coming in. counter = counter + 1; //Increment counter if(counter == 9) //If we are at the 9th bit, just stop getting in bits begin notCool = notCool + 1; cool = 0; end end else //if we are not getting bits yet begin if(MidiIn == 1) //Check if the midi controller sent the Start Bit begin if(notCool == 0) //If we havent stopped, set cool to 1 begin cool = 1; //This means we will start to grab the bits end end end endendmodulemodule clocker(inclock, outclock); input inclock; output outclock; reg [32:0] counter; reg tick; initial counter = 160; assign outclock = tick;//Basically we want tick to = 1 every 32 micro seconds. always @(posedge inclock) //Everytime the 27 MHz clock fires do this... begin counter = counter + 1;//Just ignore this math stuff, Basically we are making tick = 1 every 32 micro seconds. if(counter == 1024) begin tick = 1; counter = 160; end if(counter == 592) begin tick = 0; end endendmodule//This method just takes in a 4 bit value and sets the proper bits for the seven segment displaysmodule changeSSD(value,SSD); input [3:0] value; output [6:0] SSD; reg [6:0] SSD; always @(value) case(value) 0: SSD = 7'b1000000; 1: SSD = 7'b1111001; 2: SSD = 7'b0100100; 3: SSD = 7'b0110000; 4: SSD = 7'b0011001; 5: SSD = 7'b0010010; 6: SSD = 7'b0000010; 7: SSD = 7'b1111000; 8: SSD = 7'b0000000; 9: SSD = 7'b0010000; 10:SSD = 7'b0001000; 11:SSD = 7'b0000011; 12:SSD = 7'b1000110; 13:SSD = 7'b0100001; 14:SSD = 7'b0000110; 15:SSD = 7'b0001110; endcaseendmodule Ok so I'll kind of break this down for you. Basically I have a 27 MHz clock running. Midi data sends 1 bit every 32 micro seconds. So when midi isnt sending anything its just zero. So basically every 32 micro seconds I am checking to see if my midi controller has sent the midi start bit (basically it sends a 1 first to let you now that it will now start to send data. So midi will send a status byte (telling you what to do, i.e. Note on, Note Off, etc), then depending on the status byte it will send one or two more bytes. The code above is basically just reading in the first byte and storing it and displaying it on the LED's and as Hex on the Seven Segment Displays. And thats really all this code is doing .. seems like alot of work for only this.. . Note, it took me like 24 hours so far of working on this to figure what I know so far out. This is from knowing NOTHING about verilog or driver programming, or how midi sends stuff. Quote Link to comment Share on other sites More sharing options...
Sengin Posted January 18, 2009 Share Posted January 18, 2009 Man that sounds freaking awesome. I can't wait until I'm in the part of my Real-Time class where we're doing that stuff (right now it's just modeling state transition diagrams (i.e. finite state automata), but eventually we'll be synthesizing sounds). Quote Link to comment Share on other sites More sharing options...
SenPi Posted January 18, 2009 Author Share Posted January 18, 2009 Heh yeah. Our class is different I think. Basically instead of a final exam our teacher just went "here is an FPGA, make a Real-Time project out of it". So I chose synth with midi . My friend is making a Chip-8 Emulator. its fun stuff. Quote Link to comment Share on other sites More sharing options...
po! Posted January 18, 2009 Share Posted January 18, 2009 scope? oscilloscope but i guess you're not dealing with that low level stuff, so it prolly won't help u Quote Link to comment Share on other sites More sharing options...
SenPi Posted January 18, 2009 Author Share Posted January 18, 2009 well... wouldnt it be too fast for it to matter anyways? I mean.. a byte every 320 micro seconds.. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.