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 LED5_PIN  GET_PIN(D, 9)
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(GPIOD, GPIO_PIN_9);
43     }
44 
45 #if defined(BSP_USING_PWR)
46     /* All level of ITs can interrupt */
47     __set_BASEPRI(0U);
48 
49     lptim_stop();
50     rt_kprintf("system returns to normal!\n");
51 #endif
52 }
53 
lptim_control(uint8_t pre_value)54 static int lptim_control(uint8_t pre_value)
55 {
56     if(pre_value > 7)
57     {
58        pre_value = 7;
59     }
60     hlptim1.Instance->CFGR &= ~(7 << 9);      /* clear PRESC[2:0] */
61     hlptim1.Instance->CFGR |= pre_value << 9; /* set PRESC[2:0]  */
62     rt_kprintf("set lptim pre value [0x%x] success!\n", pre_value);
63 
64     return RT_EOK;
65 }
66 
lptim_start(void)67 int lptim_start(void)
68 {
69   /* ### Start counting in interrupt mode ############################# */
70     if (HAL_LPTIM_Counter_Start_IT(&hlptim1, 32767) != HAL_OK)
71     {
72         LOG_D("lptim1 start counting failed!\n");
73         return -RT_ERROR;
74     }
75 
76     LOG_D("lptim1 start counting success!\n");
77 
78     return RT_EOK;
79 }
80 
lptim_stop(void)81 int lptim_stop(void)
82 {
83    if (HAL_LPTIM_Counter_Stop_IT(&hlptim1) != HAL_OK)
84    {
85         LOG_D("lptim1 stop failed!\n");
86         return -RT_ERROR;
87    }
88 
89    LOG_D("lptim1 stop counting success!\n");
90 
91    return RT_EOK;
92 }
93 
lptim_init(void)94 int lptim_init(void)
95 {
96     rt_pin_mode(LED5_PIN, PIN_MODE_OUTPUT);
97 
98     hlptim1.Instance = LPTIM1;
99     hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
100     hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV8;
101     hlptim1.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING;
102     hlptim1.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
103     hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
104     hlptim1.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
105     hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
106     hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
107     hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
108     hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
109     if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
110     {
111         LOG_D("lptim init failed!\n");
112         return -RT_ERROR;
113     }
114     LOG_D("lptim init success!\n");
115 
116     return RT_EOK;
117 }
118 INIT_DEVICE_EXPORT(lptim_init);
119 
lptim_sample(int argc,char * argv[])120 static int lptim_sample(int argc, char *argv[])
121 {
122     if (argc > 1)
123     {
124         if (!strcmp(argv[1], "start"))
125         {
126            lptim_start();
127            return RT_EOK;
128         }
129         else if (!strcmp(argv[1], "stop"))
130         {
131             lptim_stop();
132             return RT_EOK;
133         }
134         else if (!strcmp(argv[1], "set"))
135         {
136             if (argc > 2)
137             {
138                lptim_control(atoi(argv[2]));
139                return RT_EOK;
140             }
141             else
142             {
143                 goto _exit;
144             }
145         }
146         else
147         {
148             goto _exit;
149         }
150     }
151 _exit:
152     {
153         rt_kprintf("Usage:\n");
154         rt_kprintf("lptim_sample start    - start lptim, the LED5 will start blink\n");
155         rt_kprintf("lptim_sample stop     - stop lptim, the LED5 will stop blink\n");
156         rt_kprintf("lptim_sample set      - set the lptim prescaler to change LED5 blink frquency, lptim_sample set [0 - 7]\n");
157     }
158 
159     return -RT_ERROR;
160 }
161 MSH_CMD_EXPORT(lptim_sample, low power timer sample);
162 
163 #endif
164