X-Git-Url: http://cloudbase.mooo.com/gitweb/irmp-demo.git/blobdiff_plain/b1a276a15faaf6b4b74769021857850e818156b7..refs/heads/master:/irmp-main.c diff --git a/irmp-main.c b/irmp-main.c index 51b2e1d..bc6623b 100644 --- a/irmp-main.c +++ b/irmp-main.c @@ -1,17 +1,24 @@ -/*--------------------------------------------------------------------------------------------------------------------------------------------------- - * irmp-main-stm32.c - demo main module to test IRMP decoder on STM32 +/*------------------------------------------------------------------------------ + * irmp-main.c - demo program to test the IRMP decoder on STM32F1 whith libopencm3 * + * Copyright (c) 2017 Leo C. + * + * This demo program is essentially a combination of some libopencm3 examples + * from https://github.com/libopencm3/libopencm3-examples + * and irmp-main-stm32.c from the IRMP distribution, which is * Copyright (c) 2009-2016 Frank Meyer - frank(at)fli4l.de * - * $Id: irmp-main-stm32.c,v 1.2 2016/01/12 21:15:16 fm Exp $ + * The program demonstrates the integration of IRMP in a libopencm3 environment, + * and how to use the libopencm3 api functions, or alternatively direct + * register access, using the macros defined by libopencm3. * - * This demo module is runnable on STM32 + * This demo runs on the Generic STM32F103C8T6 Development Board, aka bluepill. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - *--------------------------------------------------------------------------------------------------------------------------------------------------- + *------------------------------------------------------------------------------ */ #include "config.h" @@ -22,20 +29,33 @@ #include #include +/* The folloing macros can also be defined in the Makefile */ +/* If 0 or undefined, use direct register access where appropriate, + * else use the libopencm3 api functions everywhere. */ #ifndef USE_OPENCM3_API -#define USE_OPENCM3_API 1 +#define USE_OPENCM3_API 0 #endif +/* Toggle a pin on irmp timer isr entry and exit */ #ifndef DEBUG_IRMP_TIMER_INT #define DEBUG_IRMP_TIMER_INT 0 #endif +#if DEBUG_IRMP_TIMER_INT +#define DEBUG_LED_PORT GPIOB +#define DEBUG_LED_PIN GPIO0 +#define DEBUG_LED_PORT_RCC RCC_GPIOB +#endif + +/** + * Do all initialisations, that are not done by a specific module here. + */ static void setup_clock_and_gpios(void) { /* Clock setup */ /* Default clock is 8MHz HSI */ //rcc_clock_setup_in_hse_8mhz_out_24mhz(); - rcc_clock_setup_in_hse_8mhz_out_72mhz(); + //rcc_clock_setup_in_hse_8mhz_out_72mhz(); /* GPIO setup */ /* Only the on board led is configured here */ @@ -56,49 +76,57 @@ static void setup_clock_and_gpios(void) /* IRMP */ /*--------------------------------------------------------------------------*/ -#define TIM_IRMP_CR1 TIM_CR1(TIM_IRMP) -#define TIM_IRMP_DIER TIM_DIER(TIM_IRMP) -#define TIM_IRMP_SR TIM_SR(TIM_IRMP) -#define TIM_IRMP_ARR TIM_ARR(TIM_IRMP) -#define RCC_TIM_IRMP CONCAT(RCC_TIM, IRMP_TIMER) -#define NVIC_TIM_IRMP_IRQ CONCAT(CONCAT(NVIC_TIM, IRMP_TIMER), _IRQ) -#define IRMP_TIMER_ISR CONCAT(CONCAT(tim, IRMP_TIMER), _isr) +#define IRMP_TIMER_NUMBER 3 +#define IRMP_TIMER CONCAT(TIM, IRMP_TIMER_NUMBER) +#define IRMP_TIMER_CR1 TIM_CR1(IRMP_TIMER) +#define IRMP_TIMER_DIER TIM_DIER(IRMP_TIMER) +#define IRMP_TIMER_SR TIM_SR(IRMP_TIMER) +#define IRMP_TIMER_ARR TIM_ARR(IRMP_TIMER) +#define IRMP_TIMER_RCC CONCAT(RCC_TIM, IRMP_TIMER_NUMBER) +#define NVIC_IRMP_TIMER_IRQ CONCAT(CONCAT(NVIC_TIM, IRMP_TIMER_NUMBER), _IRQ) +#define IRMP_TIMER_ISR CONCAT(CONCAT(tim, IRMP_TIMER_NUMBER), _isr) + +/** Retrieve the actual input clock of a timer + +@param[in] timer_peripheral Unsigned int32. Timer register address base +@returns Unsigned int32. frequency value. +*/ uint32_t timer_internal_clock_get(uint32_t timer_peripheral) { uint32_t timer_frequency; - uint32_t ppre; /* Get preripheral bus frequency and prescaler mask */ - if (timer_peripheral == TIM1 || timer_peripheral == TIM8) { - /* Advanced timers TIM1 and TIM8 are on APB2 */ - ppre = RCC_CFGR_PPRE2; - timer_frequency = rcc_apb2_frequency; - } else { - /* Other timers are on APB1 */ - ppre = RCC_CFGR_PPRE1; + if ((timer_peripheral >= TIM2 && timer_peripheral <= TIM5) + || (timer_peripheral >= TIM12 && timer_peripheral <= TIM14)) + { timer_frequency = rcc_apb1_frequency; + } else { + timer_frequency = rcc_apb2_frequency; } /* Timer clock is doubled, if the APB prescaler is greater than 1 */ - if ((RCC_CFGR & ppre) != 0) + if (timer_frequency != rcc_ahb_frequency) timer_frequency *= 2; return timer_frequency; } +/** + * Intialize the irmp interrupt timer + */ void irmp_timer_init (void) { #if DEBUG_IRMP_TIMER_INT /* Output pin for debugging */ - rcc_periph_clock_enable(RCC_GPIOA); - gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, GPIO2); + rcc_periph_clock_enable(DEBUG_LED_PORT_RCC); + gpio_set_mode(DEBUG_LED_PORT, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, DEBUG_LED_PIN); #endif /* Enable timer clock. */ - rcc_periph_clock_enable(RCC_TIM_IRMP); - nvic_set_priority(NVIC_TIM_IRMP_IRQ, 4*16); - nvic_enable_irq(NVIC_TIM_IRMP_IRQ); + rcc_periph_clock_enable(IRMP_TIMER_RCC); + nvic_set_priority(NVIC_IRMP_TIMER_IRQ, 4*16); + nvic_enable_irq(NVIC_IRMP_TIMER_IRQ); #if USE_OPENCM3_API /* Using API functions: */ @@ -109,22 +137,22 @@ void irmp_timer_init (void) * (These are actually default values after reset, so this call * is strictly unnecessary, but demos the api for alternative settings) */ - timer_set_mode(TIM_IRMP, TIM_CR1_CKD_CK_INT, + timer_set_mode(IRMP_TIMER, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); - timer_set_period(TIM_IRMP, timer_internal_clock_get(TIM_IRMP) / F_INTERRUPTS); + timer_set_period(IRMP_TIMER, timer_internal_clock_get(IRMP_TIMER) / F_INTERRUPTS - 1); /* Enable Channel 1 compare interrupt to recalculate compare values */ - timer_enable_irq(TIM_IRMP, TIM_DIER_UIE); + timer_enable_irq(IRMP_TIMER, TIM_DIER_UIE); /* Counter enable. */ - timer_enable_counter(TIM_IRMP); + timer_enable_counter(IRMP_TIMER); #else /* Manually */ - TIM_IRMP_CR1 = TIM_CR1_CKD_CK_INT | TIM_CR1_CMS_EDGE | TIM_CR1_DIR_UP; - TIM_IRMP_ARR = timer_internal_clock_get(TIM_IRMP) / F_INTERRUPTS; + IRMP_TIMER_CR1 = TIM_CR1_CKD_CK_INT | TIM_CR1_CMS_EDGE | TIM_CR1_DIR_UP; + IRMP_TIMER_ARR = timer_internal_clock_get(IRMP_TIMER) / F_INTERRUPTS - 1; /* Enable Timer interrupt and timer */ - TIM_IRMP_DIER = TIM_DIER_UIE; - TIM_IRMP_CR1 |= TIM_CR1_CEN; + IRMP_TIMER_DIER = TIM_DIER_UIE; + IRMP_TIMER_CR1 |= TIM_CR1_CEN; #endif } @@ -134,15 +162,15 @@ void IRMP_TIMER_ISR(void) #if DEBUG_IRMP_TIMER_INT # if USE_OPENCM3_API /* Using API functions: */ - gpio_clear(GPIOA, GPIO2); + gpio_clear(DEBUG_LED_PORT, DEBUG_LED_PIN); /* Clear update interrupt flag. */ - timer_clear_flag(TIM_IRMP, TIM_SR_UIF); + timer_clear_flag(IRMP_TIMER, TIM_SR_UIF); # else /* Manually */ - GPIO_BRR(GPIOA) = GPIO2; + GPIO_BRR(DEBUG_LED_PORT) = DEBUG_LED_PIN; # endif #endif /* Clear update interrupt flag. */ - TIM_IRMP_SR = ~TIM_SR_UIF; + IRMP_TIMER_SR = ~TIM_SR_UIF; (void) irmp_ISR(); // call irmp ISR @@ -150,15 +178,20 @@ void IRMP_TIMER_ISR(void) #if DEBUG_IRMP_TIMER_INT # if USE_OPENCM3_API /* Using API functions: */ - gpio_set(GPIOA, GPIO2); + gpio_set(DEBUG_LED_PORT, DEBUG_LED_PIN); # else /* Manually */ - GPIO_BSRR(GPIOA) = GPIO2; + GPIO_BSRR(DEBUG_LED_PORT) = DEBUG_LED_PIN; # endif #endif } /*--------------------------------------------------------------------------*/ +/** Test if a IR protocol is supported + * + * Return true, if proto is valid protocol number and the protocol + * is enabled in irmpconfig.h + */ int irmp_protocol_is_supported(int proto) { #if IRMP_SUPPORT_SIRCS_PROTOCOL @@ -306,6 +339,10 @@ int irmp_protocol_is_supported(int proto) return 0; } +/** + * Print the names of all supported protocols, or the supported protocol + * numbers, if names are not enabled. + */ void print_supported_protocols(void) { printf("Supported IR protocols:"); @@ -323,6 +360,10 @@ void print_supported_protocols(void) /*--------------------------------------------------------------------------*/ +/** Let the board led do something + * + * The led should blink with 1 Hz + */ void led_blink(void) { static uint32_t ts; @@ -345,7 +386,7 @@ int main (void) " System frequency: %luHz\n" "IRMP timer input frequency (CK_INT): %luHz\n" " IRMP interrupt frequency: %uHz\n", - rcc_ahb_frequency, timer_internal_clock_get(TIM_IRMP), F_INTERRUPTS); + rcc_ahb_frequency, timer_internal_clock_get(IRMP_TIMER), F_INTERRUPTS); systick_setup(); irmp_timer_init(); // initialize timer for irmp