protofuse Posted September 28, 2009 Report Share Posted September 28, 2009 (edited) I'd like to make some led blinking. the most efficient way : doing that in the firmware (and not with an artificial note-on note-off message from the software interface to the device via midi......) I searched, I looked for that: http://www.midibox.o...index.php/topic,8456.msg60753.html#msg60753 1st question: can I mix asm and C naturally? I'm not sure. if yes, how I could put that in my code? 2nd question: how should I code that? I mean, should I use a particular value of a midi note on byte (velocity=xx) to make the led blinking? my matrix coding is: // we create a 1-dimensional array with 64 entries for led color storage for the clip matrix controller part // each entry consists of 1 byte coded like that: // 0x00 = OFF // 0x10 = RED // 0x20 = GREEN // 0x40 = BLUE // 0x30 = RED + GREEN = YELLOW // 0x60= GREEN + BLUE = CYAN // 0x50 = RED + BLUE = MAGENTA // 0x70 = WHITE // The meaning of the bytes can be found in the MIDI spec // (-> http://www.harmony-central.com/MIDI/Doc/table1.html) // (-> http://www.harmony-central.com/MIDI/Doc/table2.html) // (-> http://www.harmony-central.com/MIDI/Doc/table3.html) // // structure is matrix[COLUMN + 8*ROW]=COLOR static unsigned char matrix[64] = { 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, 0x50,0x10,0x10,0x10,0x10,0x10,0x10,0x10, 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10 }; it is the lookup table parsed every SRIO cycle. I could use another matrix as a kind of masking blinking state. if value is 0, the led is solid state if value is 1, the led is blinking (OFF/COLOR/OFF/COLOR etc etc) how could I do that? Edited November 10, 2009 by protofuse Quote Link to comment Share on other sites More sharing options...
audiocommander Posted September 28, 2009 Report Share Posted September 28, 2009 Hi protofuse,1st question: can I mix asm and C naturally? I'm not sure. if yes, how I could put that in my code?you can use plain asm code within your C code (though you cannot add C code to an asm-based project) :http://www.midibox.org/dokuwiki/doku.php?id=how_to_mix_c_and_asm2nd question: how should I code that? I mean, should I use a particular value of a midi note on byte (velocity=xx) to make the led blinking?the most useful tip in the thread you mentioned came from mess:if you want the timer to do this*first step is to initialise the timer, call MIOS_TIMER_Init(see http://www.ucapps.de/mios_fun.html for more info on how to use this function)*next put your blink code in USER_Timerdo you have experience with assembler coding?otherwise it would be easier to do this in Crefer to the MIOS C function reference to learn how to switch your pins on and off. It should be fairly simple :-)best,Michael Quote Link to comment Share on other sites More sharing options...
protofuse Posted September 29, 2009 Author Report Share Posted September 29, 2009 hello michael,no prob for switch on & off.I'll try to do that and post it if I succeed :) Quote Link to comment Share on other sites More sharing options...
protofuse Posted September 29, 2009 Author Report Share Posted September 29, 2009 I have little problem with- definition of LX_xxx- some "opcode" give error ( rgoto ...)- Symbol not previously defined (MIOS_DOUT_PinSet1) and for other calland, I don't know how I can use it with my code.I mean: I have a matrix[] that stores led state (off and colors)I think about another array: matrixBlinkState[] where 0=solid, 1=blinkingif matrix[x] != 0x00 && matrixBlinkState[x] == 0x01 =======> blinking!how could I do that using this timer, which, I suppose, makes the blinking rate ? Quote Link to comment Share on other sites More sharing options...
TK. Posted October 4, 2009 Report Share Posted October 4, 2009 It is neither required to use a timer, nor to program this in assembly code.Just use the SR_Service_Prepare() hook, which is called each mS before the shift registers are loaded.Inside this hook, use a counter (a global variable), whenever it reaches a certain value (e.g. 200 for a 200 mS delay), apply an inversion pattern on all DOUT bits which should flash.Step by step (in the hope that it's understandable):define a global variable somewhere in the header of your application:// 8bit variable (range: 0..255)unsigned char flash_ctr;[/code] And insert following code into the ServicePrepare hook: [code]void SR_Service_Prepare(void) __wparam{ if( ++flash_ctr >= 200 ) { flash_ctr = 0; MIOS_DOUT_SRSet(0, MIOS_DOUT_SRGet(0) ^ 0x01); }} This will: - read the 8bit value of the first shift register (#0) - XOR the value with 0x01 (means: first DOUT pin will be toggled) - write back the value into the first shift register - this will be done each 200 mS Examples for XOR patterns: 0x01: will toggle 1st LED 0x02: will toggle 2nd LED 0x04: will toggle 3rd LED 0x08: will toggle 4th LED 0x10: will toggle 5th LED 0x20: will toggle 6th LED 0x40: will toggle 7th LED 0x80: will toggle 8th LED To toggle multiple LEDs, just OR the values, e.g.: (0x01 | 0x80): will toggle the 1st and 8th LED The brackets are important!!! Or if you got practice, just write this into a single value without OR operation: 0x55: will toggle 1st, 3rd, 5th and 7th LED Ok, now you want to make the flash pattern variable and control it from another MIDI device. Define another global variable: unsigned char flash_pattern;[/code] (initialize it with 0x00 in the Init() hook) Modify the SR_Service_Prepare() hook the following way: [code]void SR_Service_Prepare(void) __wparam{ if( ++flash_ctr >= 200 ) { flash_ctr = 0; MIOS_DOUT_SRSet(0, MIOS_DOUT_SRGet(0) ^ flash_pattern); }} Thats all. Now you can set a specific bit of the 8bit pattern (e.g. from the MPROC_NotifyReceivedEvnt() hook when a certain MIDI event has been received) with: // it is assumed that dout_pin is in the range of 0..7 flash_pattern |= MIOS_HLP_GetBitORMask(dout_pin);[/code] and you can clear it with: [code] flash_pattern &= MIOS_HLP_GetBitANDMask(dout_pin); Next step: you want to flash more than 8 LEDs - it's time to use an array, e.g.: // prepared for all 128 DOUT pinsunsigned char flash_pattern[16];[/code] (initialize all array elements with 0x00 in the Init() hook) Modify the SR_Service_Prepare() hook the following way: [code]void SR_Service_Prepare(void) __wparam{ unsigned char sr; if( ++flash_ctr >= 200 ) { flash_ctr = 0; for(sr=0; sr<16; ++sr) MIOS_DOUT_SRSet(sr, MIOS_DOUT_SRGet(sr) ^ flash_pattern[sr]); }} Setting/clearing a specific bit will require following code: // it is assumed that dout_pin is in the range of 0..127 flash_pattern[dout_pin >> 3) |= MIOS_HLP_GetBitORMask(dout_pin);[/code] and you can clear it with: [code] flash_pattern[dout_pin >> 3] &= MIOS_HLP_GetBitANDMask(dout_pin);Have fun by doing some more experiments! :)Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
protofuse Posted October 4, 2009 Author Report Share Posted October 4, 2009 Thorsten...what a big and precise answer!I'll test it as soon as I had my AIN/Pots problem solved!I'll put it in the protodeck post.of course, I have to thank you a lot for me ... and for us! Quote Link to comment Share on other sites More sharing options...
protofuse Posted October 11, 2009 Author Report Share Posted October 11, 2009 Thorsten,I'm including this code before making my 1st test.Indeed, I'd like to control it with another midi device.I'm a little bit stuck cause I'm using RGB led.Could you help me?I'm using a lookup table:static unsigned char matrix[64] ; I feed it with MPROC_NotifyReceivedEvnt() function: void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam { int channelIndex = evnt0-0x90; int noteIndex = evnt1; unsigned char value = evnt2; matrix[8*(noteIndex - 1 - _NOTE_MATRIX_OFFSET)+channelIndex] = value; //-1 cause note begin at 1 and row at 0 } I read it with SR_Service_Prepare() void SR_Service_Prepare(void) __wparam { static unsigned int row; static unsigned int lastrow; unsigned int x; row = ++row & 0x07; // row cycling MIOS_DOUT_PinSet0(lastrow); // lastrow OFF MIOS_DOUT_PinSet1(row); // current row ON for (x = 0; x < 8; x++) { DisplayLED(x , matrix[x+row*8]); // displaying the led (x,row) } lastrow = row; } and the parsing function is DisplayLED: void DisplayLED(unsigned int column, unsigned char color) __wparam { color >>= 4; MIOS_DOUT_PinSet(column+8, color & 0x01); // RED color >>= 1; MIOS_DOUT_PinSet(column+8+8, color & 0x01); // GREEN color >>= 1; MIOS_DOUT_PinSet(column+8+8+8, color & 0x01); // BLUE }could you help me? Quote Link to comment Share on other sites More sharing options...
protofuse Posted October 12, 2009 Author Report Share Posted October 12, 2009 ok TK.I think I have the right code (I'm doing a pause at work, so I cannot test right now)I define these before Init()unsigned char matrixBlinkingState[64] ; unsigned char flash_ctr; I fill these matrixBlinkingState with 0x00 in Init() cause nothing blinks at the beginning unsigned int index; for (index = 0; index < 8; index++) { matrixBlinkingState[index] = 0x00 ; } DisplayLED hasn't been changed. ///////////////////////////////////////////////////////////////////////////// // This function is called by SR_Service_Prepare, decompose color component and UP the right rgb pins ///////////////////////////////////////////////////////////////////////////// void DisplayLED(unsigned int column, unsigned char color) __wparam { color >>= 4; MIOS_DOUT_PinSet(column+8, (unsigned char)(color & 0x01)); // RED color >>= 1; MIOS_DOUT_PinSet(column+8+8, (unsigned char)(color & 0x01)); // BLUE color >>= 1; MIOS_DOUT_PinSet(column+8+8+8, (unsigned char)(color & 0x01)); // GREEN } I put the counter incrementation outside of the for loop in order to keep it consistent... the if/test can really be improved I'll do it asap with bitmask etc as you did.. but I have to figure out how I can do that in my case. void SR_Service_Prepare(void) __wparam { static unsigned int row; static unsigned int lastrow; unsigned int x; row = ++row & 0x07; // row cycling MIOS_DOUT_PinSet0(lastrow); // lastrow OFF MIOS_DOUT_PinSet1(row); // current row ON for (x = 0; x < 8; x++) { if( flash_ctr >= 200 ) { flash_ctr = 0; if (matrixBlinkingState[x+row*8] == 0x00) DisplayLED(x , matrix[x+row*8]); // displaying the led (x,row) else DisplayLED(x , 0x00); // OFF this led cause it blinks } } lastrow = row; flash_ctr++; } I control blinking state with velocity: 0x7E means solid state, 0x7F means blink state. void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam { int channelIndex = evnt0-0x90; int noteIndex = evnt1; unsigned char value = evnt2; if (value != 0x7E || value != 0x7F) matrix[8*(noteIndex - 1 - _NOTE_MATRIX_OFFSET)+channelIndex] = value; //-1 cause note begin at 1 and row at 0 else if (value == 0x7F) // value = 0x7F means blinking state ON matrixBlinkingState[8*(noteIndex - 1 - _NOTE_MATRIX_OFFSET)+channelIndex] = 0x01; else (value == 0x7E) // value = 0x7E means blinking state OFF matrixBlinkingState[8*(noteIndex - 1 - _NOTE_MATRIX_OFFSET)+channelIndex] = 0x00; } 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.