1
0
mirror of https://github.com/elua/elua.git synced 2025-01-08 20:56:17 +08:00

Bugfixes in common_tmr.c

Fixed the following bugs:
Disabling the timer interrupt with a period of 0 for a virtual timer did
not clear the vtmr_int_periodic_flag, so the timer is still reset
regulary when reaching the old interval. The fix adds clearing of the
flag when tmr.set_match_int is called with a period of 0.

The check afainst the maximum value in tmr.set_match_int was wrong, this
has been fixed. The input value is scaled to the timer ticks before the
check is made.
This commit is contained in:
Thomas Hornschuh 2017-03-30 01:21:56 +02:00
parent d0a6375202
commit 55b90c0c55

View File

@ -79,6 +79,10 @@ static void vtmr_reset_timer( unsigned vid )
unsigned id = VTMR_GET_ID( vid );
vtmr_reset_idx = ( s8 )id;
// TH: Ensure that Interrupts are enabled before timer is reset, otherwise eLua will hang forever....
platform_cpu_set_global_interrupts(PLATFORM_CPU_ENABLE);
// End TH
while( vtmr_reset_idx != -1 );
}
@ -102,15 +106,24 @@ static int vtmr_set_match_int( unsigned vid, timer_data_type period_us, int type
unsigned id = VTMR_GET_ID( vid );
u8 msk = 1 << ( id & 0x07 );
if( period_us > VTMR_MAX_PERIOD )
return PLATFORM_TIMER_INT_TOO_LONG;
if( period_us == 0 )
{
vtmr_int_enabled[ id >> 3 ] &= ( u8 )~msk;
vtmr_int_flag[ id >> 3 ] &= ( u8 )~msk;
//TH: Bugfix: period_flag should also be cleared, so counter will not be reset anymore
// So clearing the match interrupt resets the timer to its initial state
vtmr_int_periodic_flag[ id >> 3 ] &= ( u8 )~msk;
//End TH
return PLATFORM_TIMER_INT_OK;
}
if( ( final = ( ( u64 )period_us * VTMR_FREQ_HZ ) / 1000000 ) == 0 )
final = ( u64 )((period_us * VTMR_FREQ_HZ ) / 1000000); // TH
// TH: To get the implementation correctly working, the converted input value need to be compared
// Of course this is more a theoretical problem, because the time is way to long to be of pratical use...
if( final > VTMR_MAX_PERIOD )
return PLATFORM_TIMER_INT_TOO_LONG;
if( final == 0 )
return PLATFORM_TIMER_INT_TOO_SHORT;
vtmr_period_limit[ id ] = final;
if( type == PLATFORM_TIMER_INT_ONESHOT )