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