jsflint Posted April 15, 2007 Report Share Posted April 15, 2007 Hi everybody!After a long time I decided to try out my midiboxing skills...I just started coding yesterday and I have no experience whatsoever with this.. So please be nice... Additionally I have not yet started building the damn thing so many of my questions will probably be solved when switching it on the first time. But I'm afraid I'll fry it up ;)Anyway, I need a lot of help with my code cause I have no freakin idea if anything I coded is correct... But before I post the respective code snippets I will try to describe what my small midi box should do in the end and post a picture so you know what I have in mind...The box is going to act as a floorboard controller for my guitar effects rig. Although I have some commercial controllers I thought they could do better for my purposes so I ended up here ;)The box has 6 buttons (DIN 0x00 - 0x05 sorry for the typo in the pic) and two external inputs for buttons (DIN 0x6 and 0x7).Buttons 4-6 send Control Changes; Button 1 switches between 2 Program Changes (for the distorted guitar channel), same goes for Button 2 (for the clean guitar channel). Button 3 is a shift button, that switches between 3 banks. The Program Changes of Buttons 1 and 2 act correspondingly.External Button 2 sends a Control Change message, Ext Button 1 is a little bit more complicated. It is somehow a remote control for Button 1 and 2. It switches between the two Program Change messages of these Buttons, dependent on the last pressed Button (which channel is selected).The LEDs 0x07 - 0xA are regular LEDs. The first 3 light up when Control Changes are received, LED 0xA ist just a status LED that turns on, when the midibox is on.The lower row of LEDs should be RGB Leds that light up in a different color, when the corresponding button is pressed.So far for the concept.... Now comes the really big part, a million questions (I have read the wiki and the forum but still need help, since I'm really a newbie at this...Sorry).The whole main.c (WIP) can be downloaded at hxxp://www.dailymojo.org/main.zip if it is easier for you...I'll continue now by posting code snippets and then asking the questions for this part, ok?Alright.../////////////////////////////////////////////////////////////////////////////// Local variables/////////////////////////////////////////////////////////////////////////////// last_button + shift + dirty lead + clean lead + ext1 unsigned char last_button;unsigned char shift;unsigned char dirty;unsigned char clean;unsigned char ext1;/////////////////////////////////////////////////////////////////////////////// This function is called by MIOS after startup to initialize the // application/////////////////////////////////////////////////////////////////////////////void Init(void) __wparam{ // set shift register update frequency MIOS_SRIO_UpdateFrqSet(1); // ms // we need to set at least one IO shift register pair MIOS_SRIO_NumberSet(NUMBER_OF_SRIO); // debouncing value for DINs MIOS_SRIO_DebounceSet(DIN_DEBOUNCE_VALUE); MIOS_SRIO_TS_SensitivitySet(DIN_TS_SENSITIVITY); // only one DOUTX4 module is connected // the maximum value is 16 (-> 128 digital outputs) MIOS_SRIO_NumberSet(16); // intialize start-up status etc MIOS_DOUT_PinSet(0xA, 1); // Status LED MIOS_DOUT_PinSet(0x00, 1); // LED Dirty Rhythm On MIOS_DOUT_PinSet(0x01, 0); // Other Channel LEDs off MIOS_DOUT_PinSet(0x02, 0); MIOS_DOUT_PinSet(0x03, 0); MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 16 MIOS_MIDI_TxBufferPut(0x1 + shift); // ProgramChange 1 + shift DIRTY RHYTHM EQ MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 1 MIOS_MIDI_TxBufferPut(0x59); // ProgramChange 89 MIOS_MIDI_TxBufferPut(0xC1); // Midichannel 2 MIOS_MIDI_TxBufferPut(0x0); // ProgramChange 0 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // High-Active State MIOS_MIDI_EndStream(); last_button = 0; }The first 'couple' of questions:1) Do I have to declare the local variables somewhere else as well? (total C noob question..)2) In the void Init part I included my personal start-up status. Does this belong here or after the void init function?3) As I stated above, I want to use RGB LEDs to make it cooler-looking. In the code I treat every color of the LED as a single DOUT, is this the correct way?4) Whatfor is the MIOS_MIDI_BeginStream command? In some examples this command was left out... I included it anyway..5) Is this the correct way to send multiple midi messages at once? As you can see I send three messages simutaneously...6) In the beginning I introduced the char 'shift' , which indicates the status of the shift button (see above). Now in my first midi out message (and in some others too) I want to send a Program Change command which is "ProgChange 1 + shift value" but I don't know if this is the correct way, probably not since I add a decimal value to the Hex value..7) the last line shall set the last_button char value as a 0, is this correct?Ok, this was the first part, many of these commands will come up again and again so ignore them in the next code parts.../////////////////////////////////////////////////////////////////////////////// This function is called by MIOS when a complete MIDI event has been received/////////////////////////////////////////////////////////////////////////////void MPROC_NotifyReceivedEvnt( unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam{ // BLOCK STATUS RECEIVE -> LED 4-6 if( evnt0 == 0xBF ) {// evnt0 == 0xBF = Control Change on MidiChannel 16 if( evnt2 == 0x00 ) { // Control Change Value 0 MIOS_DOUT_PinSet(evnt1 +=6, 0); } else { // Control Change Value 127 MIOS_DOUT_PinSet(evnt1 +=6, 1); } }}The corresponding DOUT_PinSet value should be the received Control Change Number (evnt1) + a decimal 6 (as you can see above the LEDs that should react to these messages are 0x07 to 0x09, so I want to add a 6 to the cc number). How do I do that?Ok, the next part describes what happens if a button is pressed... I tried to code it the most easiest way I could (or as I could learn from this forum) but due to my inability to code in C there are probably some errors.. I have no specific questions here, please just have a look at it (especially case 0x06 - is there an easier way to do this?) and tell me if I should jump from a bridge or if there is someway to make me a midiboxer ;)/////////////////////////////////////////////////////////////////////////////// This function is called by MIOS when an button has been toggled// pin_value is 1 when button released, and 0 when button pressed/////////////////////////////////////////////////////////////////////////////void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) __wparam{switch( pin ) { case 0x02: // Bank Button as a Shift button to toggle between three equalizer modes shift++; if(shift > 2) { shift = 0; } switch(shift) { case 0: MIOS_DOUT_PinSet(0x04, 1); MIOS_DOUT_PinSet(0x05, 0); MIOS_DOUT_PinSet(0x06, 0); break; case 1: MIOS_DOUT_PinSet(0x04, 0); MIOS_DOUT_PinSet(0x05, 1); MIOS_DOUT_PinSet(0x06, 0); break; case 2: MIOS_DOUT_PinSet(0x04, 0); MIOS_DOUT_PinSet(0x05, 0); MIOS_DOUT_PinSet(0x06, 1); break; } // switch shift case 0x00: // Dirty Rhythm/Lead dirty++; if(dirty >1) {dirty = 0} switch(dirty) { case 0: MIOS_DOUT_PinSet(0x00, 1); // LED Dirty Rhythm On MIOS_DOUT_PinSet(0x01, 0); // Other Channel LEDs off MIOS_DOUT_PinSet(0x02, 0); MIOS_DOUT_PinSet(0x03, 0); MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 16 MIOS_MIDI_TxBufferPut(0x1 + shift); // ProgramChange 1 + shift DIRTY RHYTHM EQ MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 1 MIOS_MIDI_TxBufferPut(0x59); // ProgramChange 89 MIOS_MIDI_TxBufferPut(0xC1); // Midichannel 2 MIOS_MIDI_TxBufferPut(0x0); // ProgramChange 0 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // High-Active State MIOS_MIDI_EndStream(); last_button = 0; break; case 1: MIOS_DOUT_PinSet(0x00, 0); // LED Dirty Lead On MIOS_DOUT_PinSet(0x01, 1); // Other Channel LEDs off MIOS_DOUT_PinSet(0x02, 0); MIOS_DOUT_PinSet(0x03, 0); MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 16 MIOS_MIDI_TxBufferPut(0x7 + shift); // ProgramChange 7 + shift DIRTY LEAD EQ MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 1 MIOS_MIDI_TxBufferPut(0x7E); // ProgramChange 126 MIOS_MIDI_TxBufferPut(0xC1); // Midichannel 2 MIOS_MIDI_TxBufferPut(0x0); // ProgramChange 0 EVENTUELL ÄNDERN WEGEN LOOPER AUF 1 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // High-Active State MIOS_MIDI_EndStream(); last_button = 1; break; } // switch dirty case 0x01: // Clean Rhythm/Lead clean++; if(clean >1) {clean = 0} switch(clean) { case 0: MIOS_DOUT_PinSet(0x00, 0); // LED Clean Rhythm On MIOS_DOUT_PinSet(0x01, 0); // Other Channel LEDs off MIOS_DOUT_PinSet(0x02, 1); MIOS_DOUT_PinSet(0x03, 0); MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 16 MIOS_MIDI_TxBufferPut(0x44 + shift); // ProgramChange 4 + shift Clean RHYTHM EQ MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 1 MIOS_MIDI_TxBufferPut(0x59); // ProgramChange 89 MIOS_MIDI_TxBufferPut(0xC1); // Midichannel 2 MIOS_MIDI_TxBufferPut(0x1); // ProgramChange 1 EVENTUELL ÄNDERN WEGEN LOOPER AUF 2 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // High-Active State MIOS_MIDI_EndStream(); last_button = 2; break; case 1: MIOS_DOUT_PinSet(0x00, 0); // LED Clean Lead On MIOS_DOUT_PinSet(0x01, 0); // Other Channel LEDs off MIOS_DOUT_PinSet(0x02, 0); MIOS_DOUT_PinSet(0x03, 1); MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 16 MIOS_MIDI_TxBufferPut(0xA + shift); // ProgramChange 10 + shift Clean LEAD EQ MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 1 MIOS_MIDI_TxBufferPut(0x77); // ProgramChange 119 MIOS_MIDI_TxBufferPut(0xC1); // Midichannel 2 MIOS_MIDI_TxBufferPut(0x1); // ProgramChange 1 EVENTUELL ÄNDERN WEGEN LOOPER AUF 3 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // High-Active State MIOS_MIDI_EndStream(); last_button = 3; break; } // switch clean case 0x03: // Harmonizer Function Switch 1 MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xBF); // CC on channel 16 MIOS_MIDI_TxBufferPut(0x1); // CC #1 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // Velocity = 0x7f when // button pressed, else 0x00 MIOS_MIDI_EndStream(); break; case 0x04: // Tremolo Function Switch 2 MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xBF); // CC on channel 16 MIOS_MIDI_TxBufferPut(0x2); // CC #2 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // Velocity = 0x7f when // button pressed, else 0x00 MIOS_MIDI_EndStream(); break; case 0x05: // Tuner Function Switch 3 MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xBF); // CC on channel 16 MIOS_MIDI_TxBufferPut(0x3); // CC #3 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // Velocity = 0x7f when // button pressed, else 0x00 MIOS_MIDI_EndStream(); break; case 0x06: // External Switch 1 switches between Lead and Rhythm Sound for both channels ext1++; if(ext1 >1) {ext1 = 0} switch(ext1) { case 0: if (last_button == 0 || last_button == 1) { MIOS_DOUT_PinSet(0x00, 1); // LED Dirty Rhythm On MIOS_DOUT_PinSet(0x01, 0); // Other Channel LEDs off MIOS_DOUT_PinSet(0x02, 0); MIOS_DOUT_PinSet(0x03, 0); MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 16 MIOS_MIDI_TxBufferPut(0x1 + shift); // ProgramChange 1 + shift DIRTY RHYTHM EQ MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 1 MIOS_MIDI_TxBufferPut(0x59); // ProgramChange 89 MIOS_MIDI_TxBufferPut(0xC1); // Midichannel 2 MIOS_MIDI_TxBufferPut(0x0); // ProgramChange 0 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // High-Active State MIOS_MIDI_EndStream(); } // endif lastbutton if (last_button == 2 || last_button == 3) { MIOS_DOUT_PinSet(0x00, 0); // LED Clean Rhythm On MIOS_DOUT_PinSet(0x01, 0); // Other Channel LEDs off MIOS_DOUT_PinSet(0x02, 1); MIOS_DOUT_PinSet(0x03, 0); MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 16 MIOS_MIDI_TxBufferPut(0x4 + shift); // ProgramChange 4 + shift Clean RHYTHM EQ MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 1 MIOS_MIDI_TxBufferPut(0x59); // ProgramChange 89 MIOS_MIDI_TxBufferPut(0xC1); // Midichannel 2 MIOS_MIDI_TxBufferPut(0x1); // ProgramChange 1 EVENTUELL ÄNDERN WEGEN LOOPER AUF 2 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // High-Active State MIOS_MIDI_EndStream(); } // endif lastbutton break; case 1: if (last_button == 0 || last_button == 1) { MIOS_DOUT_PinSet(0x00, 0); // LED Dirty Lead On MIOS_DOUT_PinSet(0x01, 1); // Other Channel LEDs off MIOS_DOUT_PinSet(0x02, 0); MIOS_DOUT_PinSet(0x03, 0); MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 16 MIOS_MIDI_TxBufferPut(0x7 + shift); // ProgramChange 7 + shift DIRTY LEAD EQ MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 1 MIOS_MIDI_TxBufferPut(0x7E); // ProgramChange 126 MIOS_MIDI_TxBufferPut(0xC1); // Midichannel 2 MIOS_MIDI_TxBufferPut(0x0); // ProgramChange 0 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // High-Active State MIOS_MIDI_EndStream(); } // endif lastbutton if (last_button == 2 || last_button == 3) { MIOS_DOUT_PinSet(0x00, 0); // LED Clean Lead On MIOS_DOUT_PinSet(0x01, 0); // Other Channel LEDs off MIOS_DOUT_PinSet(0x02, 0); MIOS_DOUT_PinSet(0x03, 1); MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 16 MIOS_MIDI_TxBufferPut(0xA + shift); // ProgramChange 10 + shift Clean RHYTHM EQ MIOS_MIDI_TxBufferPut(0xC0); // Midichannel 1 MIOS_MIDI_TxBufferPut(0x77); // ProgramChange 119 MIOS_MIDI_TxBufferPut(0xC1); // Midichannel 2 MIOS_MIDI_TxBufferPut(0x1); // ProgramChange 1 EVENTUELL ÄNDERN WEGEN LOOPER AUF 2 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // High-Active State MIOS_MIDI_EndStream(); } // endif lastbutton break; } // switch ext1 case 0x07: // Externeal switch 2 switches Delay ON/OFF via CC #4 MIOS_MIDI_BeginStream(); MIOS_MIDI_TxBufferPut(0xBF); // CC on channel #16 MIOS_MIDI_TxBufferPut(0x4); // CC #4 MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // Velocity = 0x7f when // button pressed, else 0x00 MIOS_MIDI_EndStream(); break; } // switch pin} // void din notify toggleOk, this was a long post and I know it's not that polite to start here with a million questions etc... But I tried to do as much as I can without asking (by reading the forum, the wiki and stuff) and now this is the part that seems unclear to me..I tried to explain my code as precise as I can, so feel free to ask if you need something explained more in detail...Anyway, thanks to anyone who's able one or more questions! Sorry for my english...Well I owe you a beer or two...Thanks,JSF Quote Link to comment Share on other sites More sharing options...
stryd_one Posted April 15, 2007 Report Share Posted April 15, 2007 Hey mate :)1) No2) Its fine there.3) Yes4) That's for Midibox Link. You won't need those but they won't hurt.5) Yes6) Adding dec and hex is fine7) YesI didn't go over your code too heavily, most of it looks OK, I would suggest loading it up and going from there :) Don't be afraid :)One bit of advice with the switch statements, instead ofcase mblahblahblahcase nblahblahblahdocase mdosomething()case ndosomethingelse()oh and instead of case 1 and case 0, you can just use an if statement... It should make for cleaner code but I really don't think it will make much difference in this simple controller as it should have ample cycles available :) Quote Link to comment Share on other sites More sharing options...
jsflint Posted April 15, 2007 Author Report Share Posted April 15, 2007 Wow, that was fast!Thanks for your answers! But I did not quite get case mdosomething()case ndosomethingelse()What do you mean by dosomething()?Thanks,JSF Quote Link to comment Share on other sites More sharing options...
audiocommander Posted April 15, 2007 Report Share Posted April 15, 2007 What do you mean by dosomething()?stryd means, that the asm code generated by sdcc is smaller if you call functions from a switch case. but I don't think it makes any difference here – it may even get a bit more complicated for you, 'cause there's more to type. I don't think you really need to care about this level of optimisation for the purpose of your application; the PIC won't be overloaded with 8 knobs and 8 leds ;)(of course it can't hurt having heard about things like these...)cheers,Michael Quote Link to comment Share on other sites More sharing options...
jsflint Posted April 15, 2007 Author Report Share Posted April 15, 2007 Oh.. I got than one now... (had to look in an online C reference.. ;) ) but I think it's really a little bit to much for this small controller..But thanks for your help! (I will probably continue asking some questions when my midibox parts arrive so... be warned!!) Quote Link to comment Share on other sites More sharing options...
stryd_one Posted April 16, 2007 Report Share Posted April 16, 2007 but I think it's really a little bit to much for this small controller..stryd means, that the asm code generated by sdcc is smaller if you call functions from a switch case. Well, there is that too... but I was more concerned with the number of temp registers it'll generate.but I don't think it makes any difference here – it may even get a bit more complicated for you, 'cause there's more to type. I don't think you really need to care about this level of optimisation for the purpose of your application; the PIC won't be overloaded with 8 knobs and 8 leds ;)(of course it can't hurt having heard about things like these...)Don't forget the Too many switch cases crashes MIOS? thread :) The problem here was not in fact the number of cases... it was all the for loops inside them.Simple way to find out though: Compile it, and count how many r0x*** registers you can see in the output file. Quote Link to comment Share on other sites More sharing options...
audiocommander Posted April 16, 2007 Report Share Posted April 16, 2007 Simple way to find out though: Compile it, and count how many r0x*** registers you can see in the output file.hm, how may r0x*** registers may there be?Does that mean, if too much temp registers are needed, it won't fit into the available RAM?(Background: I have about 40 swich cases in a nested "super-"switch case and can see r0x0C right at the beginning of the function in the .asm file (_output). 13 r0x***es don't seem much for the incredible amount of C-Code I wrote there...sorry stryd, if this question is somehow dumb, but if you go into details, I wanna know it really detailed :-* ;)@jsflint: don't want to confuse you, sorry :) Quote Link to comment Share on other sites More sharing options...
jsflint Posted April 16, 2007 Author Report Share Posted April 16, 2007 Thanks for all your help... as you can see I have no idea about C at all but I'm willing to learn so I follow your 'expert' discussion...But at least I'm proud of myself 'cause I really looked at the C forum for a couple of hours and was able to write a little code... So thanks to all the midiboxers who wrote all the tutorials and stuff...I'll try to learn more about functions and incorporate them so that the code for my small app will at least look clean...Oh, one more question: as I won't include AINs, AOUTs and LCD etc, do I need to delete the parts from the skeleton or just leave them?Thanks,JSF Quote Link to comment Share on other sites More sharing options...
audiocommander Posted April 16, 2007 Report Share Posted April 16, 2007 as I won't include AINs, AOUTs and LCD etc, do I need to delete the parts from the skeleton or just leave them?just leave them ;)Cheers,Michael Quote Link to comment Share on other sites More sharing options...
jsflint Posted April 16, 2007 Author Report Share Posted April 16, 2007 Ok, I tried to compile it with Xcode on mac, but, as I've never done it before, I don't know if I've done it correct, just followed the instructions on the forum.. Where shall I look for the r0x entries? Quote Link to comment Share on other sites More sharing options...
stryd_one Posted April 16, 2007 Report Share Posted April 16, 2007 Thanks for all your help... as you can see I have no idea about C at all but I'm willing to learn so I follow your 'expert' discussion...Hahahah I would use the term expert very lightly in my case ;DBut at least I'm proud of myself 'cause I really looked at the C forum for a couple of hours and was able to write a little code... So thanks to all the midiboxers who wrote all the tutorials and stuff...I'll try to learn more about functions and incorporate them so that the code for my small app will at least look clean...You should be proud, that's very good work for a newbie!! :)Oh, one more question: as I won't include AINs, AOUTs and LCD etc, do I need to delete the parts from the skeleton or just leave them?Nah just leave em emptyOk, I tried to compile it with Xcode on mac, but, as I've never done it before, I don't know if I've done it correct, just followed the instructions on the forum.. Where shall I look for the r0x entries?audiocommander has written a tutorial for xcode on the wiki, I would definitely check that out...When you run the makefile, it will generate an 'output' directory, and there will be .asm files in there... at least that's it on a PC... :-\ Quote Link to comment Share on other sites More sharing options...
audiocommander Posted April 16, 2007 Report Share Posted April 16, 2007 SDCC generates ASM-files in the "_output" directory. So whenever there's a problem, you can find the ASM here: _output/myfilename.asmIn your case, you can upload it on the chip and see if it works. You might inspect the details only if you encounter any problems.Edit: beaten by stryd :P@stryd: have you seen my question about the number of rx0***'s ? Quote Link to comment Share on other sites More sharing options...
stryd_one Posted April 16, 2007 Report Share Posted April 16, 2007 @stryd: have you seen my question about the number of rx0***'s ?Yeh that's a slightly longer story, still typing :) Quote Link to comment Share on other sites More sharing options...
jsflint Posted April 16, 2007 Author Report Share Posted April 16, 2007 audiocommander... xcode still says permission denied when I try to compile the makefile target... i tried to change execute permissions for the bin folder with chmod but somehow it does not seem to work... any idea? Quote Link to comment Share on other sites More sharing options...
audiocommander Posted April 16, 2007 Report Share Posted April 16, 2007 xcode still says permission denied when I try to compile the makefile target.you don't need to go to the bin-folder for the makefile generator.There's just a perl script (tools/mkmk.pl) involved.So, you should make sure that these files are:- readable: yourproject/MAKEFILE.SPEC- executeable: yourproject/tools/mkmk.pldoes this help? Quote Link to comment Share on other sites More sharing options...
jsflint Posted April 16, 2007 Author Report Share Posted April 16, 2007 Hmmm.. obviously I did something wrong... somewhere... this is what I get when I try to compile the makefile target:/Users/jsflint/Desktop/midibox/build/midibox.build/Debug/Makefile.build/Script-84A65F450BD38FD20080FE2C.sh: line 6: ./mkmk.pl: Permission denied Quote Link to comment Share on other sites More sharing options...
audiocommander Posted April 16, 2007 Report Share Posted April 16, 2007 yeah, that's what I already wrote: go to the folder /tools/ (inside your project), search for mkmk.pl and set chmod permissions to be executeable.regards,Michael Quote Link to comment Share on other sites More sharing options...
jsflint Posted April 16, 2007 Author Report Share Posted April 16, 2007 Sorry, was in the wrong folder ??? ... now it works but I have some errors when compiling.. checking the forums first before I ask..Thanks Quote Link to comment Share on other sites More sharing options...
stryd_one Posted April 16, 2007 Report Share Posted April 16, 2007 hm, how may r0x*** registers may there be?Does that mean, if too much temp registers are needed, it won't fit into the available RAM?(Background: I have about 40 swich cases in a nested "super-"switch case and can see r0x0C right at the beginning of the function in the .asm file (_output). 13 r0x***es don't seem much for the incredible amount of C-Code I wrote there...sorry stryd, if this question is somehow dumb, but if you go into details, I wanna know it really detailed :-* ;)@jsflint: don't want to confuse you, sorry :)Detailed it is then... This kinda goes round in a circle before it gets to the answer.... :-\ Sorry...The r0x*** registers are used by SDCC as temporary variables within a function, the compiler decides where they are needed, and locates them in the Access Bank of ram on the PIC. The advantage of that, is that the access bank can be read or written, without the need for any additional instructions, whereas the remaining ram must be accessed either in banked or indirect mode. Banked operations require you to select the current memory bank prior to accessing the variable, you'll see those as BANKSEL in your ASM files (or SETBSR in TK's). Banksel is a macro which is substituted for the necessary command depending on PIC model - in our case I think BANKSEL MyBank becomes MOVLB MyBank. Note that it is a 2 word instruction (in order to carry enough data for the memory pointer). After that, you can read and write the variables only within that bank. If you go to a different bank, you need a new banksel. SDCC actually puts a banksel in every time, and the optimiser removes the unecessary ones.Indirect operations require you to load a memory pointer called the File Select Register or FSR. There are 3 of them, FSR0 FSR1 and FSR2, and they're a 14-bit pointer, so there is a low byte, and high byte of which only 6 bits are used. So you calculate the address to your variable, load it into FSRxH(5:0) and FSRxL, and the contents of that location are then available by reading or writing registers like INDFx and POSTDECx (which reads from the location and then decrements the address of the pointer).In order to access these variables like INDFx without needing a bank selection (which would obviously not work with other banked memory) they are also stored in the access bank. They are known as Special Function Registers or SFRs (not to be confused with FSR like I did hehehe). SFRs are registers used by the CPU and peripheral modules for controlling the PIC. Stuff like the timer registers, status bits, I/O ports (TRISx, PORTx etc) are all SFRs as well. The acces bank is actually split in two. All of these SFRs are stored in Access Bank High, which is located right at the top of the RAM. You can see it in the linker: ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED Table 5-2 in thee 4620 datasheet lists all the SFRs with a brief description. You probably know most of them already. Access Ram Low, which is at 0x000, is available for our applications. MIOS variables take up the first 16 bytes, and then 0x010 to 0x07F is free. You can see that memory described in the lkr as so: DATABANK NAME=miosvars START=0x000 END=0x00f ACCESSBANK NAME=accessram START=0x010 END=0x07F The MIOSVars are reserved by the wrapper am file : MIOS_VARIABLES udata 0x0000 _MIOS_BOX_CFG0 res 1 _MIOS_BOX_CFG1 res 1 _MIOS_BOX_STAT res 1 _MIOS_PARAMETER1 res 1 _MIOS_PARAMETER2 res 1 _MIOS_PARAMETER3 res 1 _TMP1 res 1 _TMP2 res 1 _TMP3 res 1 _TMP4 res 1 _TMP5 res 1 _IRQ_TMP1 res 1 _IRQ_TMP2 res 1 _IRQ_TMP3 res 1 _IRQ_TMP4 res 1 _IRQ_TMP5 res 1 And you can see them in the .map file: MIOS_VARIABLES udata 00000000 data 0x000010 Chances are, the very next line in your .map file will be this: .registers udata 0x000010 data 0x000038 And that's our friend, the r0x*** registers from SDCC. These registers were the result of this ASM file from sneakthief's seq: ; Internal registers .registers udata_ovr 0x010 r0x00 res 1 r0x01 res 1 r0x02 res 1 r0x03 res 1 r0x04 res 1 r0x05 res 1 r0x06 res 1 r0x07 res 1 r0x08 res 1 r0x09 res 1 r0x0A res 1 r0x0B res 1 r0x0C res 1 r0x0D res 1 r0x0E res 1 r0x0F res 1 r0x10 res 1 r0x11 res 1 r0x12 res 1 r0x13 res 1 r0x14 res 1 r0x15 res 1 r0x16 res 1 r0x17 res 1 r0x18 res 1 r0x19 res 1 r0x1A res 1 r0x1B res 1 r0x1C res 1 r0x1D res 1 r0x1E res 1 r0x1F res 1 r0x20 res 1 r0x21 res 1 r0x22 res 1 r0x23 res 1 r0x24 res 1 r0x25 res 1 r0x26 res 1 r0x27 res 1 r0x28 res 1 r0x29 res 1 r0x2A res 1 r0x2B res 1 r0x2C res 1 r0x2D res 1 r0x2E res 1 r0x2F res 1 r0x30 res 1 r0x31 res 1 r0x32 res 1 r0x33 res 1 r0x34 res 1 r0x35 res 1 r0x36 res 1 r0x37 res 1 You can see from the linker above that they can go up to END=0x07F, so in theory, we could have 0x6F (111) of them. Putting that theory into practice however, was not so successful in the case of sneakthief's seq. Because the variables are used as 'scratch space', they are often reused within a function. That app was using them as counters in for loops among ather things, and when that app got to r0x037 (it's last register) and tried to re-use r0x000 again, the thing went berserk and crashed the PIC.I suspect that this was actually a bug in SDCCs code, so maybe we can get away with it, maybe not... but it's the kind of thing that's often better off cleaned up anyway...Did that make any sense at all? :-\Edit: Trivia - the PICs with CAN and USB peripherals have too many SFRs, and some of them are located in the upper regions of banked RAM, not in access ram. I don't know why I mention that ;D Quote Link to comment Share on other sites More sharing options...
jsflint Posted April 16, 2007 Author Report Share Posted April 16, 2007 in case you're interested :P I managed to compile this code and I have 4 registers.... Quote Link to comment Share on other sites More sharing options...
stryd_one Posted April 16, 2007 Report Share Posted April 16, 2007 :D Yay!Musta been the for loops in sneak's seq... Lesson learned, thanks for checking it out for us jsflint, now we are well informed for the future. Quote Link to comment Share on other sites More sharing options...
audiocommander Posted April 16, 2007 Report Share Posted April 16, 2007 Did that make any sense at all? Absolutely! cheers for explaining this!r0x37 is indeed ...wooo, quite a number...As mentioned, in the kII Midi-Receive Function, I have mixed simple calls, if-statements and very long sub-switches (eg. [tt]switch(msgType) { case MIDI_CC: switch(MIDI_CC) { case CCBankselect: ...[/tt] )I counted roughly 40 to 50 cases alone for the CC case statement (sub-switch-routine), and I found just 13 r0x*** registers. that's good, eh'? 8)Great to know about that,thanks again, stryd :) Quote Link to comment Share on other sites More sharing options...
stryd_one Posted April 16, 2007 Report Share Posted April 16, 2007 I counted roughly 40 to 50 cases alone for the CC case statement (sub-switch-routine), and I found just 13 r0x*** registers. that's good, eh'? 8)That is good :)Glad I could make sense. Sorry jsflint, if I were you, all that would probably make me go "WTF" right now! Just ignore us ;D Quote Link to comment Share on other sites More sharing options...
jsflint Posted April 17, 2007 Author Report Share Posted April 17, 2007 If I'd ignore you both I'd probably still sit on a tree... ;)That's the way we learn isn't it? You tell something I don't understand, I look it up etc and then I know a little bit more... Quote Link to comment Share on other sites More sharing options...
stryd_one Posted April 17, 2007 Report Share Posted April 17, 2007 I think the problem is that we are still finding out about how and why SDCC works, and every time we answer one of our questions, we make some more! Welcome aboard the rollercoaster ;) 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.