wackazong Posted September 29, 2008 Report Share Posted September 29, 2008 I need a function that is repeated with a frequency of about 4000Hz (4000 calls of the function per second). I implemented it in two ways: one just puts the function in void Tick(void) __wparam in the main.c sceleton, the other puts it in void Timer(void) __wparam, and initialises the timer with MIOS_Timer_Init(0x03, 50).The one which just uses Tick works beautifully, and the core stays responsive, while the other one does not work at all, only when I increase the second paramer of the init to 100. But also then the function is awfully slow. The core is also responsive then, but the function does not work as expected.I know that Timer uses an interrupt routine, but why doesnt this work with Timer when it works with Tick?This is the code that is called (Flash_Handler is called, and uses Interpolate32):///////////////////////////////////////////////////////////////////////////// // Interpolate ///////////////////////////////////////////////////////////////////////////// unsigned char KNOEPFLI_Interpolate32(unsigned char step, unsigned char value1, unsigned char value2) { unsigned char swap, diff; //send out value2 if step is the max value if( step == 32 ) { return value2; }; //send out value1 if step i 0 if( step == 0 ) { return value1; }; //invert the interpolation if value1 > value2 if( value1 > value2 ) { //swap the values swap = value2; value2 = value1; value1 = swap; //--step because we are counting from 0 to 32, not to 31 --step; //invert the step counter step = ~step; //clear the upper three bits step &= 0x1f; }; //get the difference diff = value2 - value1; //divide it through the total number of steps (>>5) and multiply it with step (gives an integer) then get the high byte, //shift the step counter three to the left to make it 8bit, store it in PRODL PRODL = step << 3; //store diff in PRODH PRODH = diff; //do the multiplication in assembler __asm movf _PRODL, W mulwf _PRODH, 0 __endasm; //add the lower value return value1 + PRODH; } ///////////////////////////////////////////////////////////////////////////// // Flash Handler ///////////////////////////////////////////////////////////////////////////// void KNOEPFLI_Flash_Handler() { unsigned char red, green, blue; if( knoepfli_led_status[knoepfli_led_counter].FLASH == 1 ) { red = KNOEPFLI_Interpolate32( knoepfli_led_flash_counter[knoepfli_led_counter], knoepfli_led_color_now_red[knoepfli_led_counter], knoepfli_led_color_flash_red[knoepfli_led_counter]); green = KNOEPFLI_Interpolate32( knoepfli_led_flash_counter[knoepfli_led_counter], knoepfli_led_color_now_green[knoepfli_led_counter], knoepfli_led_color_flash_green[knoepfli_led_counter]); blue = KNOEPFLI_Interpolate32( knoepfli_led_flash_counter[knoepfli_led_counter], knoepfli_led_color_now_blue[knoepfli_led_counter], knoepfli_led_color_flash_blue[knoepfli_led_counter]); //Send Brightness red MIOS_IIC_Start(); // start IIC MIOS_IIC_ByteSend( knoepfli_led_address_red[knoepfli_led_counter].DRIVER ); // send device address, bit #0 cleared to notify a write!!! MIOS_IIC_ByteSend( 0x02 + knoepfli_led_address_red[knoepfli_led_counter].LED ); // select brightness register of the corresponding led, the first one is 0xa2, no autoincrement MIOS_IIC_ByteSend( red ); // send brightness MIOS_IIC_Stop(); //Send Brightness green MIOS_IIC_Start(); // start IIC MIOS_IIC_ByteSend( knoepfli_led_address_green[knoepfli_led_counter].DRIVER ); // send device address, bit #0 cleared to notify a write!!! MIOS_IIC_ByteSend( 0x02 + knoepfli_led_address_green[knoepfli_led_counter].LED ); // select brightness register of the corresponding led, the first one is 0xa2, no autoincrement MIOS_IIC_ByteSend( green ); // send brightness MIOS_IIC_Stop(); //Send Brightness blue MIOS_IIC_Start(); // start IIC MIOS_IIC_ByteSend( knoepfli_led_address_blue[knoepfli_led_counter].DRIVER ); // send device address, bit #0 cleared to notify a write!!! MIOS_IIC_ByteSend( 0x02 + knoepfli_led_address_blue[knoepfli_led_counter].LED ); // select brightness register of the corresponding led, the first one is 0xa2, no autoincrement MIOS_IIC_ByteSend( blue ); // send brightness MIOS_IIC_Stop(); if( knoepfli_led_flash_counter[knoepfli_led_counter] == 0 ) { knoepfli_led_status[knoepfli_led_counter].FLASH = 0; } else { --knoepfli_led_flash_counter[knoepfli_led_counter]; }; }; //increase the counter for the next run of the routine ++knoepfli_led_counter; if( knoepfli_led_counter == KNOEPFLI_LED_NUMBER ) { knoepfli_led_counter = 0; }; } Quote Link to comment Share on other sites More sharing options...
audiocommander Posted September 29, 2008 Report Share Posted September 29, 2008 Hi,this should give an answer:Timer() would be a bad choice, because it interrupts the main task, and could therefore also interrupt a MIDI stream; this could result into sporadically sent invalid MIDI events.So, if timed transactions are required, the Timer should request a send, and Tick() should check for this request flag, clear it and send the events (similar to the approach used for DISPLAY_Tick())so: the right approach would be to set a flag at the Timer() notification and then process it (if enabled) within Tick()Regards,Michael Quote Link to comment Share on other sites More sharing options...
wackazong Posted September 29, 2008 Author Report Share Posted September 29, 2008 Wow, that sounds good. Thanks, I will try. 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.