blob: e431e467e1e23fefc6339e5af99d4564c0714185 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-13 AisinoChip first add to bsp
*/
#include "board.h"
#include <rtdevice.h>
#if defined(RT_USING_PM)
#define IWDT_SRC_CLK 32000
#define IWDT_CLK_PRESCALER IWDT_CLOCK_PRESCALER_32
#define IWDT_CLK (IWDT_SRC_CLK / (4<<IWDT_CLK_PRESCALER))
static IWDT_HandleTypeDef hiwdt;
static rt_tick_t get_pm_tick_from_os_tick(rt_tick_t tick)
{
return (rt_tick_t)(IWDT_CLK * tick / RT_TICK_PER_SECOND);
}
static rt_tick_t get_os_tick_from_pm_tick(rt_tick_t tick)
{
static rt_uint32_t os_tick_remain = 0;
rt_uint32_t ret;
ret = (tick * RT_TICK_PER_SECOND + os_tick_remain) / IWDT_CLK;
os_tick_remain += (tick * RT_TICK_PER_SECOND);
os_tick_remain %= IWDT_CLK;
return ret;
}
static void _pm_sleep(struct rt_pm *pm, rt_uint8_t mode)
{
RT_ASSERT(pm != RT_NULL);
switch(mode)
{
case PM_SLEEP_MODE_NONE:
break;
case PM_SLEEP_MODE_IDLE:
break;
case PM_SLEEP_MODE_LIGHT:
System_Enter_Sleep_Mode(SLEEPENTRY_WFI);
break;
case PM_SLEEP_MODE_DEEP:
System_Enter_Stop_Mode(STOPENTRY_WFI);
break;
case PM_SLEEP_MODE_STANDBY:
System_Enter_Standby_Mode();
break;
case PM_SLEEP_MODE_SHUTDOWN:
break;
default:
return;
}
}
static void _pm_run(struct rt_pm *pm, rt_uint8_t mode)
{
static rt_uint8_t prev_mode = 0;
RT_ASSERT(pm != RT_NULL);
if(prev_mode == mode)
{
return;
}
switch(mode)
{
case PM_RUN_MODE_HIGH_SPEED: /* 64Mhz */
case PM_RUN_MODE_NORMAL_SPEED: /* 64Mhz */
System_Clock_Init(64000000);
break;
case PM_RUN_MODE_MEDIUM_SPEED: /* 32Mhz */
System_Clock_Init(32000000);
break;
case PM_RUN_MODE_LOW_SPEED: /* 8Mhz */
System_Clock_Init(8000000);
break;
default:
return;
}
SysTick_Config(System_Get_SystemClock() / RT_TICK_PER_SECOND);
prev_mode = mode;
}
static void _pm_timer_start(struct rt_pm *pm, rt_uint32_t timeout)
{
int tick;
RT_ASSERT(pm != RT_NULL);
IWDT_HandleTypeDef *phiwdt = (IWDT_HandleTypeDef *)(pm->parent.user_data);
if(timeout != RT_TICK_MAX)
{
tick = get_pm_tick_from_os_tick(timeout);
phiwdt->Instance = IWDT;
phiwdt->Init.Prescaler = IWDT_CLK_PRESCALER;
phiwdt->Init.Reload = tick;
phiwdt->Init.Window = tick; /* window function disabled when window >= reload */
phiwdt->Init.Wakeup = tick - 1; /* wakeup function disabled when wakeup >= reload */
HAL_IWDT_Init(phiwdt);
}
}
static void _pm_timer_stop(struct rt_pm *pm)
{
RT_ASSERT(pm != RT_NULL);
IWDT_HandleTypeDef *phiwdt = (IWDT_HandleTypeDef *)(pm->parent.user_data);
phiwdt->Instance->CMDR = 0xFFFF;
}
static rt_tick_t _pm_timer_get_tick(struct rt_pm *pm)
{
rt_tick_t tick;
RT_ASSERT(pm != RT_NULL);
tick = 1;
return get_os_tick_from_pm_tick(tick);
}
static const struct rt_pm_ops _pm_ops =
{
_pm_sleep,
_pm_run,
_pm_timer_start,
_pm_timer_stop,
_pm_timer_get_tick
};
/**
* This function initialize the power manager
*/
int drv_pm_hw_init(void)
{
rt_uint8_t timer_mask = 0;
/* initialize timer mask */
timer_mask = (1UL << PM_SLEEP_MODE_DEEP) | (1UL << PM_SLEEP_MODE_STANDBY);
/* initialize system pm module */
rt_system_pm_init(&_pm_ops, timer_mask, &hiwdt);
return 0;
}
INIT_BOARD_EXPORT(drv_pm_hw_init);
#endif /* RT_USING_PM */
|