1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2012-06-02 Bernard the first version 9 * 2018-08-02 Tanek split run and sleep modes, support custom mode 10 */ 11 12 #ifndef __PM_H__ 13 #define __PM_H__ 14 15 #include <rtthread.h> 16 17 #ifndef PM_HAS_CUSTOM_CONFIG 18 19 /* All modes used for rt_pm_request() adn rt_pm_release() */ 20 enum 21 { 22 /* run modes */ 23 PM_RUN_MODE_NORMAL = 0, 24 25 /* sleep modes */ 26 PM_SLEEP_MODE_SLEEP, 27 PM_SLEEP_MODE_TIMER, 28 PM_SLEEP_MODE_SHUTDOWN, 29 }; 30 31 /* The name of all modes used in the msh command "pm_dump" */ 32 #define PM_MODE_NAMES \ 33 { \ 34 "Running Mode", \ 35 \ 36 "Sleep Mode", \ 37 "Timer Mode", \ 38 "Shutdown Mode", \ 39 } 40 41 /* run mode count : 1 */ 42 #define PM_RUN_MODE_COUNT 1 43 /* sleep mode count : 3 */ 44 #define PM_SLEEP_MODE_COUNT 3 45 46 /* support redefining default run mode */ 47 #ifndef PM_RUN_MODE_DEFAULT 48 #define PM_RUN_MODE_DEFAULT 0 49 #endif 50 51 /* support redefining default sleep mode */ 52 #ifndef PM_SLEEP_MODE_DEFAULT 53 #define PM_SLEEP_MODE_DEFAULT (PM_SLEEP_MODE_START) 54 #endif 55 56 /* support redefining the minimum tick into sleep mode */ 57 #ifndef PM_MIN_ENTER_SLEEP_TICK 58 #define PM_MIN_ENTER_SLEEP_TICK (1) 59 #endif 60 61 #else /* PM_HAS_CUSTOM_CONFIG */ 62 63 #include <pm_cfg.h> 64 65 #ifndef PM_RUN_MODE_COUNT 66 #error "You must defined PM_RUN_MODE_COUNT on pm_cfg.h" 67 #endif 68 69 #ifndef PM_SLEEP_MODE_COUNT 70 #error "You must defined PM_SLEEP_MODE_COUNT on pm_cfg.h" 71 #endif 72 73 #ifndef PM_MODE_DEFAULT 74 #error "You must defined PM_MODE_DEFAULT on pm_cfg.h" 75 #endif 76 77 #ifndef PM_MODE_NAMES 78 #error "You must defined PM_MODE_NAMES on pm_cfg.h" 79 #endif 80 81 #ifndef PM_RUN_MODE_DEFAULT 82 #error "You must defined PM_RUN_MODE_DEFAULT on pm_cfg.h" 83 #endif 84 85 /* The default sleep mode(PM_SLEEP_MODE_DEFAULT) are not required. 86 * If the default mode is defined, it is requested once in rt_system_pm_init() 87 */ 88 89 #endif /* PM_HAS_CUSTOM_CONFIG */ 90 91 /* run mode must start at 0 */ 92 #define PM_RUN_MODE_START 0 93 /* the values of the run modes and sleep mode must be consecutive */ 94 #define PM_SLEEP_MODE_START PM_RUN_MODE_COUNT 95 /* all mode count */ 96 #define PM_MODE_COUNT (PM_RUN_MODE_COUNT + PM_SLEEP_MODE_COUNT) 97 /* The last mode, will be request in rt_system_pm_init() */ 98 #define PM_MODE_MAX (PM_RUN_MODE_COUNT + PM_SLEEP_MODE_COUNT - 1) 99 100 #if PM_MODE_COUNT > 32 101 #error "The number of modes cannot exceed 32" 102 #endif 103 104 /** 105 * device control flag to request or release power 106 */ 107 #define RT_PM_DEVICE_CTRL_REQUEST 0x01 108 #define RT_PM_DEVICE_CTRL_RELEASE 0x02 109 110 struct rt_pm; 111 112 /** 113 * low power mode operations 114 */ 115 struct rt_pm_ops 116 { 117 void (*enter)(struct rt_pm *pm); 118 void (*exit)(struct rt_pm *pm); 119 120 #if PM_RUN_MODE_COUNT > 1 121 void (*frequency_change)(struct rt_pm *pm, rt_uint32_t frequency); 122 #endif 123 124 void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout); 125 void (*timer_stop)(struct rt_pm *pm); 126 rt_tick_t (*timer_get_tick)(struct rt_pm *pm); 127 }; 128 129 struct rt_device_pm_ops 130 { 131 #if PM_RUN_MODE_COUNT > 1 132 void (*frequency_change)(const struct rt_device* device); 133 #endif 134 135 void (*suspend)(const struct rt_device* device); 136 void (*resume) (const struct rt_device* device); 137 }; 138 139 struct rt_device_pm 140 { 141 const struct rt_device* device; 142 const struct rt_device_pm_ops* ops; 143 }; 144 145 /** 146 * power management 147 */ 148 struct rt_pm 149 { 150 struct rt_device parent; 151 152 /* modes */ 153 rt_uint8_t modes[PM_MODE_COUNT]; 154 rt_uint8_t current_mode; /* current pm mode */ 155 rt_uint8_t exit_count; 156 157 /* the list of device, which has PM feature */ 158 rt_uint8_t device_pm_number; 159 struct rt_device_pm* device_pm; 160 struct rt_semaphore device_lock; 161 162 /* if the mode has timer, the corresponding bit is 1*/ 163 rt_uint32_t timer_mask; 164 165 const struct rt_pm_ops *ops; 166 }; 167 168 void rt_pm_enter(void); 169 void rt_pm_exit(void); 170 171 void rt_pm_request(rt_ubase_t mode); 172 void rt_pm_release(rt_ubase_t mode); 173 174 void rt_pm_register_device(struct rt_device* device, const struct rt_device_pm_ops* ops); 175 void rt_pm_unregister_device(struct rt_device* device); 176 177 void rt_system_pm_init(const struct rt_pm_ops *ops, 178 rt_uint8_t timer_mask, 179 void *user_data); 180 181 #endif /* __PM_H__ */ 182