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;
};
}