Jump to content

This N°9

Programmer
  • Posts

    331
  • Joined

  • Last visited

Everything posted by This N°9

  1. ...hmm. don't know. didn't want to "underestimate" you.. but what's wrong with a shift? it's a native operation of the processor, therefore fast and there's a native operator in C? maybe you could use a byte-address to do what you want?: unsigned int i=0xffbb; unsigned char msb = *(&i);//msb==0xff now unsigned char lsb = *((&i)+1);//lsb==0xbb now this (could) also work (an array var is nothing else than a pointer), but they say it's "bad style": [s]unsigned int i=0xffbb; unsigned char msb = (&i)[0];//msb==0xff now unsigned char lsb = (&i)[1];//lsb==0xbb now[/s] [glow=red,2,300]correction: I think you need to typecast also:[/glow] unsigned int i=0xffbb; unsigned char msb = *((unsigned char *)&i);//msb==0xff now unsigned char lsb = *((unsigned char *)((&i)+1));//lsb==0xbb now or unsigned int i=0xffbb; unsigned char msb = ((unsigned char *)&i)[0];//msb==0xff now unsigned char lsb = ((unsigned char *)&i)[1];//lsb==0xbb now this look a bit weired, I didn't test if the syntax is correct, maybe it works. Anyway, it should be possible to address a byte inside any var and cast it as unsigned char.. dereferencing can be done with either * or array index.
  2. hello stryd_one, no, I don't think so.. because the linker error occurs also if I don't do anything with the const. so this post says everything necessary (the const / var is created outside of any function in main.c of the c-skelleton): check it out yourself, If you like regards, this
  3. ok, I will head for the asm code then. because I just want to know. you are right, but I can be quite picky sometimes.. regards, this
  4. why the hell you don't want to make a shift ??? ? there are shift operators in C++ ! check this: http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Companion/cxx_crib/shift.html or this: http://www.fredosaurus.com/notes-cpp/expressions/bitops.html and mind the operator precedence on writing expressions with multiple operators in it: http://www.cppreference.com/operator_precedence.html
  5. questions to TK concerning the "merger disable hack": you say: if I disable the forwarding on receiving a status-byte, this byte will not be forwarded. fact: every midi-message starts with a status byte (byte & 0x80 == 1). a sysex is the only message whos last byte is also a status byte. does the "disable code" block the forwarding of the stop-status-byte of the sysex too? and if so, does it look explicitly for THE stop-status-byte or just for any status byte? if it looks for ANY status byte to restart the merging, the hack would not work, because the merger would not forward the statusbyte of the next message, so this message would be lost. if it looks explicitly for the stop-byte of the sysex, the forwarding would not start again. only if the code would distinguish (between) the sysex-stop-byte and any other status-byte, the hack would work. why I want to know this: - I think that the forwarding by the merger is faster code than any code produced by the sdcc compiler? - If I do parsing on application level, every byte will be double-parsed, once by MIOS and once by my application I could check this in the MIOS-code myself, but I'm not fit in assembler, so it would take me quite time to find the place where it happens. maybe you (TK) can answer these questions directly by heart. by the way: thanks for your correction the origial version confused me, thats why I asked "so what would be an example application of the case described here?" another proposal: if I stop the merger with MIOS_MIDI_MergerSet on receiving "my" event, and start it again on any other event? if the mergin' happens after MPROC_NotifyReceivedByte, this should work (?)
  6. this thread missguided me a bit at first, so here's the result of my research and emails to TK: -MPROC_Notify_ReceivedByte receives EVERY byte of incoming MIDI-data (status bytes and data bytes). also the bytes later passed to MPROC_Notify_ReceivedEvent -MPROC_Notify_ReceivedEvent receives all channel-voice and channel-mode messages [glow=red,2,300]so this quote is completly wrong:[/glow] -channel specific (channel-voice, channel-mode) messages have alway evnt0 < 0xf0 -system messages (sysex, system-common, system-realtime) can be handled in MPROC_Notify_ReceivedByte and have always byte >= 0xf0 use this implementation of MPROC_Notify_ReceivedByte to forward all system-messages to the output: void MPROC_NotifyReceivedByte(unsigned char byte) __wparam{ //this function forwards all system messages to the output static unsigned char fx_status = 0; if(byte >= 0xf0){//system status byte MIOS_MIDI_TxBufferPut(byte); //determine status switch(byte){ case 0xf1://midi timecode case 0xf3://songselect fx_status = 1; break; case 0xf2://songposition pointer fx_status = 2; break; case 0xf0://sysex, forward until 0xf7 fx_status = 0xff; break; default://applies also on 0xf7! fx_status = 0; } } else if(fx_status){ MIOS_MIDI_TxBufferPut(byte); if(fx_status!=0xff) fx_status--; } } the above code is a "pimped" version of the code by TK: void MPROC_NotifyReceivedByte(unsigned char byte) __wparam { static char fx_status; // normal MIDI events are forwarded in MPROC_NotifyReceivedEvnt // this function handles sysex and realtime messages if( byte & 0x80 ) { // Status message if( byte >= 0xf0 ) MIOS_MIDI_TxBufferPut(byte); // transfer byte // determine status if( byte == 0xf0 ) { fx_status = 0xff; // forward until 0xf7 } else if( byte == 0xf7 ) { fx_status = 0; // f7 reached, no forward } else if( byte == 0xf1 || byte == 0xf3 ) { fx_status = 1; // expecting one additional byte } else if( byte == 0xf2 ) { fx_status = 2; // expecting two additional bytes } else { fx_status = 0; // expecting no additional byte } } else { // check if fx status active if( fx_status ) { // forward data byte MIOS_MIDI_TxBufferPut(byte); // decrement counter if required if( fx_status != 0xff ) --fx_status; } } } when you want to manipulate / parse the data, replace MIOS_MIDI_TxBufferPut(byte) with your code
  7. I was so free to pimp the code for forwarding system-messages a little: void MPROC_NotifyReceivedByte(unsigned char byte) __wparam{ //this function forwards all system messages to the output static unsigned char fx_status = 0; if(byte >= 0xf0){//system status byte MIOS_MIDI_TxBufferPut(byte); //determine status switch(byte){ case 0xf1://midi timecode case 0xf3://songselect fx_status = 1; break; case 0xf2://songposition pointer fx_status = 2; break; case 0xf0://sysex, forward until 0xf7 fx_status = 0xff; break; default://applies also on 0xf7! fx_status = 0; } } else if(fx_status){ MIOS_MIDI_TxBufferPut(byte); if(fx_status!=0xff) fx_status--; } } I beleive it's faster than the original code (and more compact-> easier to read -> less bugs): -less conditions, > 0xf0 is a status byte anyway -case instead of if-chain (I'am not sure if this really results in faster code, but for it is more natural to do it with case in this case I think so). I know it doesn't really matter that much, but I like aesthetic code ;D by the way: is there some official repository / place for code-snippets?
  8. so what would be an example application of the case described here?:
  9. this example does all the forwarding without midi-merger.. : http://ucapps.de/mios_c_forward_chn1.html is the midi-merger-ability a newer MIOS-feature?
  10. thanks for the input, this is a new approach.. like this I don't have to forward all the bytes myself (faster) I'm not sure I get what you mean, who(what) is IT? :) I think your code is exactly right: - on reception of the status byte we are IN the message, merger disable - complete message will be passed to recvEvnt - because the merger is off, the message will not be autom. be forwarded - MIOS enables merger (this is after the complete event has been received) if the merger is on or off while putting the bytes doesnt make a difference I think..
  11. its more than this, the wrapping is because of the overflow, but the error appears only if a const is created. consts are stored in the program code space (variables are stored in RAM / stack). so I suppose its a protection mechanism for the program code space. but I think the best solutions is just not creating overflows ;D
  12. I tried to reproduce the error. Its not the overflow: no error on compiling const unsigned int dummy = 20000000; but.. this causes a linker error: const unsigned int dummy = 30000000; gplink: lst.c:187: write_src: Assertion `data & 0x80000000' failed. well, it IS the overflow, combined with some kind of protection for fields in the code space (?) this one works, it's a field in the RAM: unsigned int dummy = 30000000; strange effect, but with no real relevance. I'am brand new to microcontrollers & quite new to c++, so I have to get used to the limitations :-) cheers
  13. ok, thats very true. I didnt see it. but anyway, the error occurs also with small numbers in int-range. and I can't pass a number this large to the timer function, because it requires an int. so I will have to count. I beleive its not wise to generally use defines, because it's not typed. In some contexts this could generate unnecessary promotions. this is from the sdcc-manual: Here are a few guidelines that will help the compiler generate more efcient code, some of the tips are specic to this compiler others are generally good programming practice. • Use the smallest data type to represent your data-value. If it is known in advance that the value is going to be less than 256 then use an ’unsigned char’ instead of a ’short’ or ’int’. Please note, that ANSI C requires both signed and unsigned chars to be promoted to ’signed int’ before doing any operation. This promotion can be ! omitted, if the result is the same. The effect of the promotion rules together with the sign-extension is often surprising: unsigned char uc = 0xfe; if (uc * uc < 0) /* this is true! */ { .... } uc * uc is evaluated as (int) uc * (int) uc = (int) 0xfe * (int) 0xfe = (int) 0xfc04 = -1024. Another one: (unsigned char) -12 / (signed char) -3 = ... No, the result is not 4: (int) (unsigned char) -12 / (int) (signed char) -3 = (int) (unsigned char) 0xf4 / (int) (signed char) 0xfd = (int) 0x00f4 / (int) 0xfffd = (int) 0x00f4 / (int) 0xfffd = (int) 244 / (int) -3 = (int) -81 = (int) 0xffaf; Don’t complain, that gcc gives you a different result. gcc uses 32 bit ints, while SDCC uses 16 bit ints. Therefore the results are different. From â€comp.lang.c FAQâ€: I think the multiplication would be optimized by the compiler anyway.
  14. hello all, what types of midi-events are passed to MPROC_NotifyReceivedEvnt ? there are one-byte(just status-byte, f.e. system realtime msgs), two byte (f.e. program change) and three byte(f.e. note on, note off) messages. (and sysex of course). which of these are catched my the MIOS-parser? ??? is it a problem to forward a one/two bytes msg. with a second/third 0 byte to the output? I would like to catch all channel-specific messages (evnt0 < 0xf0) and manipulate the channel. all others (incl. sysex) should just be sent to the output unchanged. thanks in advance, this
  15. hmm... It happens just for int-types, and only for some values.. maybe this is kind of a code-space protecting mechanism or so..
  16. hi there, I'am currently working with the c-MIOS-skeleton. I thought it would be wise to define all fields that will not be changed as const. In some sdcc howto I read, that there's an explicit directive __code that can be put instead of const, and that tutorial suggested this too. however the linker seems not to like that. the sdcc says: "gen.c:12715 symbol iTemp6 = [ chn_msg_mask ] is in code space" and the linker says: "gplink: lst.c:187: write_src: Assertion `data & 0x80000000' failed. make: *** [project.hex] Aborted" It seems that it concerns only fields that I pass to a function: MIOS_TIMER_Init(0x00,clear_request_period); unsigned int clear_request_period = 10000000*3;//this works const unsigned int clear_request_period = 10000000*3;//doesn't work thanks in advance, this (is my name)
  17. hi all, based on which criterias should I choose a timer prescaler? is there some performance advantage/disadvantage? in the documetation, this example is shown: // we want to setup the timer with a frequency of 500 Hz = 2 mS // prescaler 1:1 should be used // calculate the required number of clocks for this period: // clocks = period / 100 nS = 2 mS / 100 nS = 20000 // therefore: MIOS_TIMER_Init(0x00, 20000); // now the Timer() function is called every 2 mS! why not take a prescaler of 1:2 and set the period to 10000? this
×
×
  • Create New...