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

initial attempt at timer int support on stm32

This commit is contained in:
James Snyder 2011-08-01 18:32:11 -05:00
parent 8f520abd16
commit 8b50aca945
3 changed files with 134 additions and 10 deletions

View File

@ -692,8 +692,10 @@ int platform_s_uart_set_flow_control( unsigned id, int type )
// ****************************************************************************
// Timers
u8 stm32_timer_int_periodic_flag[ NUM_PHYS_TIMER ];
// We leave out TIM6/TIM for now, as they are dedicated
static TIM_TypeDef * const timer[] = { TIM1, TIM2, TIM3, TIM4, TIM5 };
const TIM_TypeDef * const timer[] = { TIM1, TIM2, TIM3, TIM4, TIM5 };
#define TIM_GET_PRESCALE( id ) ( ( id ) == 0 || ( id ) == 5 ? ( PCLK2_DIV ) : ( PCLK1_DIV ) )
#define TIM_GET_BASE_CLK( id ) ( TIM_GET_PRESCALE( id ) == 1 ? ( HCLK / TIM_GET_PRESCALE( id ) ) : ( HCLK / ( TIM_GET_PRESCALE( id ) / 2 ) ) )
#define TIM_STARTUP_CLOCK 50000
@ -802,7 +804,44 @@ u32 platform_s_timer_op( unsigned id, int op, u32 data )
int platform_s_timer_set_match_int( unsigned id, u32 period_us, int type )
{
return PLATFORM_TIMER_INT_INVALID_ID;
TIM_TypeDef* base = ( TIM_TypeDef* )timer[ id ];
u32 freq;
timer_data_type final;
TIM_OCInitTypeDef TIM_OCInitStructure;
if( period_us == 0 )
{
TIM_ITConfig( base, TIM_IT_CC1, DISABLE );
base->CR1 = 0; // Why are we doing this?
base->CR2 = 0;
return PLATFORM_TIMER_INT_OK;
}
timer_set_clock( id, 1000000 );
freq = timer_get_clock( id );
final = ( ( u64 )period_us * freq ) / 1000000;
if( final == 0 )
return PLATFORM_TIMER_INT_TOO_SHORT;
if( final > 0xFFFF )
return PLATFORM_TIMER_INT_TOO_LONG;
TIM_Cmd( base, DISABLE );
TIM_OCStructInit( &TIM_OCInitStructure );
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = final;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init( base, &TIM_OCInitStructure );
TIM_OC1PreloadConfig( base, TIM_OCPreload_Disable );
stm32_timer_int_periodic_flag[ id ] = type;
TIM_SetCounter( base, 0 );
TIM_Cmd( base, ENABLE );
TIM_ITConfig( base, TIM_IT_CC1, ENABLE );
return PLATFORM_TIMER_INT_OK;
}
// ****************************************************************************

View File

@ -112,6 +112,7 @@
#define NUM_SPI 2
#define NUM_UART 5
#define NUM_TIMER 5
#define NUM_PHYS_TIMER 5
#define NUM_PWM 4
#define NUM_ADC 16
#define NUM_CAN 1

View File

@ -9,6 +9,10 @@
// Platform-specific headers
#include "stm32f10x.h"
#ifndef VTMR_TIMER_ID
#define VTMR_TIMER_ID ( -1 )
#endif
// ****************************************************************************
// Interrupt handlers
@ -128,6 +132,56 @@ void EXTI15_10_IRQHandler()
}
}
// ----------------------------------------------------------------------------
// Timer interrupt handlers
const TIM_TypeDef * const timer[] = { TIM1, TIM2, TIM3, TIM4, TIM5 };
extern u8 stm32_timer_int_periodic_flag[ NUM_PHYS_TIMER ];
static void tmr_int_handler( int id )
{
TIM_TypeDef *base = ( TIM_TypeDef* )timer[ id ];
TIM_ClearITPendingBit( base, TIM_IT_CC1 );
if( id == VTMR_TIMER_ID )
cmn_virtual_timer_cb();
else
cmn_int_handler( INT_TMR_MATCH, id );
if( stm32_timer_int_periodic_flag[ id ] != PLATFORM_TIMER_INT_CYCLIC )\
TIM_ITConfig( base, TIM_IT_CC1, DISABLE );
}
void TIM1_CC_IRQHandler(void)
{
tmr_int_handler( 0 );
}
void TIM2_IRQHandler(void)
{
tmr_int_handler( 1 );
}
void TIM3_IRQHandler(void)
{
tmr_int_handler( 2 );
}
void TIM4_IRQHandler(void)
{
tmr_int_handler( 3 );
}
void TIM5_IRQHandler(void)
{
tmr_int_handler( 4 );
}
void TIM8_CC_IRQHandler(void)
{
tmr_int_handler( 7 );
}
// ****************************************************************************
// GPIO helper functions
@ -234,19 +288,30 @@ static int int_gpio_negedge_get_flag( elua_int_resnum resnum, int clear )
// ****************************************************************************
// Interrupt: INT_TMR_MATCH
static int int_tmr_match_set_status( elua_int_resnum resnum, int status )
{
return PLATFORM_INT_NOT_HANDLED;
}
static int int_tmr_match_get_status( elua_int_resnum resnum )
{
return PLATFORM_INT_NOT_HANDLED;
TIM_TypeDef *base = ( TIM_TypeDef* )timer[ resnum ];
return ( base->DIER & TIM_IT_CC1 ) != 0;
}
static int int_tmr_match_set_status( elua_int_resnum resnum, int status )
{
int previous = int_tmr_match_get_status( resnum );
TIM_TypeDef *base = ( TIM_TypeDef* )timer[ resnum ];
TIM_ITConfig( base, TIM_IT_CC1, status == PLATFORM_CPU_ENABLE ? ENABLE : DISABLE );
return previous;
}
static int int_tmr_match_get_flag( elua_int_resnum resnum, int clear )
{
return PLATFORM_INT_NOT_HANDLED;
TIM_TypeDef *base = ( TIM_TypeDef* )timer[ resnum ];
int status = TIM_GetFlagStatus( base, TIM_FLAG_CC1 );
if( clear )
TIM_ClearFlag( base, TIM_FLAG_CC1 );
return status;
}
// ****************************************************************************
@ -287,6 +352,15 @@ static const u8 uart_irq_table[] = { USART1_IRQn, USART2_IRQn, USART3_IRQn, UART
// EXTI IRQ table
static const u8 exti_irq_table[] = { EXTI0_IRQn, EXTI1_IRQn, EXTI2_IRQn, EXTI3_IRQn, EXTI4_IRQn, EXTI9_5_IRQn, EXTI15_10_IRQn };
// EXTI IRQ table
#if defined( STM32F10X_LD )
static const u8 timer_irq_table[] = { TIM1_CC_IRQn, TIM2_IRQn, TIM3_IRQn };
#elseif defined( STM32F10X_MD )
static const u8 timer_irq_table[] = { TIM1_CC_IRQn, TIM2_IRQn, TIM3_IRQn, TIM4_IRQn };
#else
static const u8 timer_irq_table[] = { TIM1_CC_IRQn, TIM2_IRQn, TIM3_IRQn, TIM4_IRQn, TIM5_IRQn };
#endif
void platform_int_init()
{
NVIC_InitTypeDef nvic_init_structure;
@ -295,7 +369,8 @@ void platform_int_init()
// Enable all USART interrupts in the NVIC
nvic_init_structure.NVIC_IRQChannelPreemptionPriority = 0;
nvic_init_structure.NVIC_IRQChannelSubPriority = 0;
nvic_init_structure.NVIC_IRQChannelCmd = ENABLE;
nvic_init_structure.NVIC_IRQChannelCmd = ENABLE;
for( i = 0; i < sizeof( uart_irq_table ) / sizeof( u8 ); i ++ )
{
nvic_init_structure.NVIC_IRQChannel = uart_irq_table[ i ];
@ -309,6 +384,15 @@ void platform_int_init()
NVIC_Init( &nvic_init_structure );
}
#ifdef INT_TMR_MATCH
for( i = 0; i < sizeof( timer_irq_table ) / sizeof( u8 ); i ++ )
{
nvic_init_structure.NVIC_IRQChannel = timer_irq_table[ i ];
nvic_init_structure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init( &nvic_init_structure );
}
#endif
}
// ****************************************************************************