1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author          Notes
8  * 2020-06-19     thread-liu      first version
9  */
10 
11 #include <board.h>
12 
13 #ifdef BSP_USING_LPTIM
14 #include "drv_config.h"
15 #include <string.h>
16 #include <stdlib.h>
17 
18 //#define DRV_DEBUG
19 #define LOG_TAG             "drv.lptimer"
20 #include <drv_log.h>
21 
22 #define LED7_PIN  GET_PIN(H, 7)
23 LPTIM_HandleTypeDef hlptim1;
24 
25 extern int lptim_stop(void);
26 
LPTIM1_IRQHandler(void)27 void LPTIM1_IRQHandler(void)
28 {
29     /* enter interrupt */
30     rt_interrupt_enter();
31 
32     HAL_LPTIM_IRQHandler(&hlptim1);
33 
34     /* leave interrupt */
35     rt_interrupt_leave();
36 }
37 
HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef * hlptim)38 void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim)
39 {
40     if(hlptim->Instance == LPTIM1)
41     {
42         HAL_GPIO_TogglePin(GPIOH, GPIO_PIN_7);
43     }
44 
45     /* All level of ITs can interrupt */
46     __set_BASEPRI(0U);
47 
48     lptim_stop();
49     rt_kprintf("system returns to normal!\n");
50 }
51 
lptim_control(uint8_t pre_value)52 static int lptim_control(uint8_t pre_value)
53 {
54     if(pre_value > 7)
55     {
56        pre_value = 7;
57     }
58     hlptim1.Instance->CFGR &= ~(7 << 9);      /* clear PRESC[2:0] */
59     hlptim1.Instance->CFGR |= pre_value << 9; /* set PRESC[2:0]  */
60     rt_kprintf("set lptim pre value [0x%x] success!\n", pre_value);
61 
62     return RT_EOK;
63 }
64 
lptim_start(void)65 int lptim_start(void)
66 {
67   /* ### Start counting in interrupt mode ############################# */
68     if (HAL_LPTIM_Counter_Start_IT(&hlptim1, 32767) != HAL_OK)
69     {
70         LOG_D("lptim1 start counting failed!\n");
71         return -RT_ERROR;
72     }
73 
74     LOG_D("lptim1 start counting success!\n");
75 
76     return RT_EOK;
77 }
78 
lptim_stop(void)79 int lptim_stop(void)
80 {
81    if (HAL_LPTIM_Counter_Stop_IT(&hlptim1) != HAL_OK)
82    {
83         LOG_D("lptim1 stop failed!\n");
84         return -RT_ERROR;
85    }
86 
87    LOG_D("lptim1 stop counting success!\n");
88 
89    return RT_EOK;
90 }
91 
lptim_init(void)92 int lptim_init(void)
93 {
94     rt_pin_mode(LED7_PIN, PIN_MODE_OUTPUT);
95 
96     hlptim1.Instance = LPTIM1;
97     hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
98     hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV8;
99     hlptim1.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING;
100     hlptim1.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
101     hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
102     hlptim1.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
103     hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
104     hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
105     hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
106     hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
107     if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
108     {
109         LOG_D("lptim init failed!\n");
110         return -RT_ERROR;
111     }
112     LOG_D("lptim init success!\n");
113 
114     return RT_EOK;
115 }
116 INIT_DEVICE_EXPORT(lptim_init);
117 
lptim_sample(int argc,char * argv[])118 static int lptim_sample(int argc, char *argv[])
119 {
120     if (argc > 1)
121     {
122         if (!strcmp(argv[1], "start"))
123         {
124            lptim_start();
125            return RT_EOK;
126         }
127         else if (!strcmp(argv[1], "stop"))
128         {
129             lptim_stop();
130             return RT_EOK;
131         }
132         else if (!strcmp(argv[1], "set"))
133         {
134             if (argc > 2)
135             {
136                lptim_control(atoi(argv[2]));
137                return RT_EOK;
138             }
139             else
140             {
141                 goto _exit;
142             }
143         }
144         else
145         {
146             goto _exit;
147         }
148     }
149 _exit:
150     {
151         rt_kprintf("Usage:\n");
152         rt_kprintf("lptim_sample start    - start lptim, the LED7 will start blink\n");
153         rt_kprintf("lptim_sample stop     - stop lptim, the LED7 will stop blink\n");
154         rt_kprintf("lptim_sample set      - set the lptim prescaler to change LED7 blink frquency, lptim_sample set [0 - 7]\n");
155     }
156 
157     return -RT_ERROR;
158 }
159 MSH_CMD_EXPORT(lptim_sample, low power timer sample);
160 
161 #endif
162