1 /*
2  *  Copyright (c) 2016, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  * @brief
32  *   This file includes platform abstractions for miscellaneous behaviors.
33  */
34 
35 #ifndef OPENTHREAD_PLATFORM_MISC_H_
36 #define OPENTHREAD_PLATFORM_MISC_H_
37 
38 #include <stdint.h>
39 
40 #include <openthread/instance.h>
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /**
47  * @addtogroup plat-misc
48  *
49  * @brief
50  *   This module includes platform abstractions for miscellaneous behaviors.
51  *
52  * @{
53  */
54 
55 /**
56  * Performs a software reset on the platform, if supported.
57  *
58  * @param[in] aInstance  The OpenThread instance structure.
59  */
60 void otPlatReset(otInstance *aInstance);
61 
62 /**
63  * Performs a hardware reset on the platform to launch bootloader mode, if supported.
64  *
65  * Used when `OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE` is enabled.
66  *
67  * @param[in] aInstance  The OpenThread instance structure.
68  *
69  * @retval OT_ERROR_NONE         Reset to bootloader successfully.
70  * @retval OT_ERROR_BUSY         Failed due to another operation is ongoing.
71  * @retval OT_ERROR_NOT_CAPABLE  Not capable of resetting to bootloader.
72  */
73 otError otPlatResetToBootloader(otInstance *aInstance);
74 
75 /**
76  * Enumeration of possible reset reason codes.
77  *
78  * These are in the same order as the Spinel reset reason codes.
79  */
80 typedef enum
81 {
82     OT_PLAT_RESET_REASON_POWER_ON = 0,
83     OT_PLAT_RESET_REASON_EXTERNAL = 1,
84     OT_PLAT_RESET_REASON_SOFTWARE = 2,
85     OT_PLAT_RESET_REASON_FAULT    = 3,
86     OT_PLAT_RESET_REASON_CRASH    = 4,
87     OT_PLAT_RESET_REASON_ASSERT   = 5,
88     OT_PLAT_RESET_REASON_OTHER    = 6,
89     OT_PLAT_RESET_REASON_UNKNOWN  = 7,
90     OT_PLAT_RESET_REASON_WATCHDOG = 8,
91 
92     OT_PLAT_RESET_REASON_COUNT,
93 } otPlatResetReason;
94 
95 /**
96  * Returns the reason for the last platform reset.
97  *
98  * @param[in] aInstance  The OpenThread instance structure.
99  */
100 otPlatResetReason otPlatGetResetReason(otInstance *aInstance);
101 
102 /**
103  * Provides a platform specific implementation for assert.
104  *
105  * @param[in] aFilename    The name of the file where the assert occurred.
106  * @param[in] aLineNumber  The line number in the file where the assert occurred.
107  */
108 void otPlatAssertFail(const char *aFilename, int aLineNumber);
109 
110 /**
111  * Performs a platform specific operation to wake the host MCU.
112  * This is used only for NCP configurations.
113  */
114 void otPlatWakeHost(void);
115 
116 /**
117  * Enumeration of micro-controller's power states.
118  *
119  * These values are used for NCP configuration when `OPENTHREAD_CONFIG_NCP_ENABLE_MCU_POWER_STATE_CONTROL` is enabled.
120  *
121  * The power state specifies the desired power state of NCP's micro-controller (MCU) when the underlying platform's
122  * operating system enters idle mode (i.e., all active tasks/events are processed and the MCU can potentially enter a
123  * energy-saving power state).
124  *
125  * The power state primarily determines how the host should interact with the NCP and whether the host needs an
126  * external trigger (a "poke") to NCP before it can communicate with the NCP or not.
127  *
128  * After a reset, the MCU power state MUST be `OT_PLAT_POWER_STATE_ON`.
129  */
130 typedef enum
131 {
132     /**
133      * NCP's MCU stays on and active all the time.
134      *
135      * When the NCP's desired power state is set to `ON`, host can send messages to NCP without requiring any "poke" or
136      * external triggers.
137      *
138      * @note The `ON` power state only determines the MCU's power mode and is not related to radio's state.
139      */
140     OT_PLAT_MCU_POWER_STATE_ON = 0,
141 
142     /**
143      * NCP's MCU can enter low-power (energy-saving) state.
144      *
145      * When the NCP's desired power state is set to `LOW_POWER`, host is expected to "poke" the NCP (e.g., an external
146      * trigger like an interrupt) before it can communicate with the NCP (send a message to the NCP). The "poke"
147      * mechanism is determined by the platform code (based on NCP's interface to the host).
148      *
149      * While power state is set to `LOW_POWER`, NCP can still (at any time) send messages to host. Note that receiving
150      * a message from the NCP does NOT indicate that the NCP's power state has changed, i.e., host is expected to
151      * continue to "poke" when it wants to talk to the NCP until the power state is explicitly changed (by a successful
152      * call to `otPlatSetMcuPowerState()` changing the state to `ON`).
153      *
154      * @note The `LOW_POWER` power state only determines the MCU's power mode and is not related to radio's state
155      * (radio is managed by OpenThread core and device role, e.g., device being sleepy or not.
156      */
157     OT_PLAT_MCU_POWER_STATE_LOW_POWER = 1,
158 
159     /**
160      * NCP is fully off.
161      *
162      * An NCP hardware reset (via a RESET pin) is required to bring the NCP back to `SPINEL_MCU_POWER_STATE_ON`.
163      * RAM is not retained after reset.
164      */
165     OT_PLAT_MCU_POWER_STATE_OFF = 2,
166 } otPlatMcuPowerState;
167 
168 /**
169  * Sets the desired MCU power state.
170  *
171  * This is only applicable and used for NCP configuration when `OPENTHREAD_CONFIG_NCP_ENABLE_MCU_POWER_STATE_CONTROL`
172  * is enabled.
173  *
174  * @param[in] aInstance      A pointer to OpenThread instance.
175  * @param[in] aState         The new MCU power state.
176  *
177  * @retval OT_ERROR_NONE     The power state updated successfully.
178  * @retval OT_ERROR_FAILED   The given MCU power state is not supported by the platform.
179  */
180 otError otPlatSetMcuPowerState(otInstance *aInstance, otPlatMcuPowerState aState);
181 
182 /**
183  * Gets the current desired MCU power state.
184  *
185  * This is only applicable and used for NCP configuration when `OPENTHREAD_CONFIG_NCP_ENABLE_MCU_POWER_STATE_CONTROL`
186  * is enabled.
187  *
188  * After a reset, the power state MUST return `OT_PLAT_POWER_STATE_ON`. During operation, power state SHOULD only
189  * change through an explicit successful call to `otPlatSetMcuPowerState()`.
190  *
191  * @param[in] aInstance  A pointer to OpenThread instance.
192  *
193  * @returns The current power state.
194  */
195 otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *aInstance);
196 
197 /**
198  * Logs a crash dump using OpenThread logging APIs
199  *
200  * @note This API is an optional logging platform API. It's up to the platform layer to implement it.
201  *
202  * @retval OT_ERROR_NONE            Crash dump was logged successfully
203  * @retval OT_ERROR_NOT_CAPABLE     Platform is not capable of logging a crash dump
204  */
205 otError otPlatLogCrashDump(void);
206 
207 /**
208  * @}
209  */
210 
211 #ifdef __cplusplus
212 } // extern "C"
213 #endif
214 
215 #endif // OPENTHREAD_PLATFORM_MISC_H_
216