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