| 
									
										
										
										
											2016-11-15 12:10:02 +08:00
										 |  |  | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Licensed under the Apache License, Version 2.0 (the "License");
 | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License.
 | 
					
						
							|  |  |  | // You may obtain a copy of the License at
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software
 | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS,
 | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and
 | 
					
						
							|  |  |  | // limitations under the License.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  | #include <stdint.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <stdbool.h>
 | 
					
						
							| 
									
										
										
										
											2017-07-08 20:47:55 +02:00
										 |  |  | #include "freertos/FreeRTOS.h"
 | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  | #include "esp_attr.h"
 | 
					
						
							|  |  |  | #include "esp_freertos_hooks.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-22 23:06:52 +08:00
										 |  |  | #include "sdkconfig.h"
 | 
					
						
							|  |  |  | #include "esp_pm.h"
 | 
					
						
							|  |  |  | #include "pm_impl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  | //We use just a static array here because it's not expected many components will need
 | 
					
						
							|  |  |  | //an idle or tick hook.
 | 
					
						
							|  |  |  | #define MAX_HOOKS 8
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-16 11:47:38 +08:00
										 |  |  | static portMUX_TYPE hooks_spinlock = portMUX_INITIALIZER_UNLOCKED; | 
					
						
							| 
									
										
										
										
											2017-07-08 20:47:55 +02:00
										 |  |  | static esp_freertos_idle_cb_t idle_cb[portNUM_PROCESSORS][MAX_HOOKS]={0}; | 
					
						
							|  |  |  | static esp_freertos_tick_cb_t tick_cb[portNUM_PROCESSORS][MAX_HOOKS]={0}; | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | void IRAM_ATTR esp_vApplicationTickHook()  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int n; | 
					
						
							| 
									
										
										
										
											2017-07-08 20:47:55 +02:00
										 |  |  |     int core = xPortGetCoreID(); | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  |     for (n=0; n<MAX_HOOKS; n++) { | 
					
						
							| 
									
										
										
										
											2017-07-08 20:47:55 +02:00
										 |  |  |         if (tick_cb[core][n]!=NULL) { | 
					
						
							|  |  |  |             tick_cb[core][n](); | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void esp_vApplicationIdleHook()  | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-22 23:06:52 +08:00
										 |  |  |     bool can_go_idle=true; | 
					
						
							| 
									
										
										
										
											2017-07-08 20:47:55 +02:00
										 |  |  |     int core = xPortGetCoreID(); | 
					
						
							| 
									
										
										
										
											2017-09-22 23:06:52 +08:00
										 |  |  |     for (int n = 0; n < MAX_HOOKS; n++) { | 
					
						
							|  |  |  |         if (idle_cb[core][n] != NULL && !idle_cb[core][n]()) { | 
					
						
							|  |  |  |             can_go_idle = false; | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-09-22 23:06:52 +08:00
										 |  |  |     if (!can_go_idle) { | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-09-22 23:06:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_PM_ENABLE
 | 
					
						
							|  |  |  |     esp_pm_impl_idle_hook(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-04-12 18:18:45 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern void esp_vApplicationWaitiHook( void ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-22 23:06:52 +08:00
										 |  |  |     asm("waiti 0"); | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-13 18:27:53 +08:00
										 |  |  | esp_err_t esp_register_freertos_idle_hook_for_cpu(esp_freertos_idle_cb_t new_idle_cb, UBaseType_t cpuid) | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-13 18:27:53 +08:00
										 |  |  |     if(cpuid >= portNUM_PROCESSORS){ | 
					
						
							|  |  |  |         return ESP_ERR_INVALID_ARG; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-16 11:47:38 +08:00
										 |  |  |     portENTER_CRITICAL(&hooks_spinlock); | 
					
						
							| 
									
										
										
										
											2017-10-13 18:27:53 +08:00
										 |  |  |     for(int n = 0; n < MAX_HOOKS; n++){ | 
					
						
							|  |  |  |         if (idle_cb[cpuid][n]==NULL) { | 
					
						
							|  |  |  |             idle_cb[cpuid][n]=new_idle_cb; | 
					
						
							| 
									
										
										
										
											2017-10-16 11:47:38 +08:00
										 |  |  |             portEXIT_CRITICAL(&hooks_spinlock); | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  |             return ESP_OK; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-16 11:47:38 +08:00
										 |  |  |     portEXIT_CRITICAL(&hooks_spinlock); | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  |     return ESP_ERR_NO_MEM; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-13 18:27:53 +08:00
										 |  |  | esp_err_t esp_register_freertos_idle_hook(esp_freertos_idle_cb_t new_idle_cb) | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-13 18:27:53 +08:00
										 |  |  |     return esp_register_freertos_idle_hook_for_cpu(new_idle_cb, xPortGetCoreID()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t esp_register_freertos_tick_hook_for_cpu(esp_freertos_tick_cb_t new_tick_cb, UBaseType_t cpuid) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if(cpuid >= portNUM_PROCESSORS){ | 
					
						
							|  |  |  |         return ESP_ERR_INVALID_ARG; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-16 11:47:38 +08:00
										 |  |  |     portENTER_CRITICAL(&hooks_spinlock); | 
					
						
							| 
									
										
										
										
											2017-10-13 18:27:53 +08:00
										 |  |  |     for(int n = 0; n < MAX_HOOKS; n++){ | 
					
						
							|  |  |  |         if (tick_cb[cpuid][n]==NULL) { | 
					
						
							|  |  |  |             tick_cb[cpuid][n]=new_tick_cb; | 
					
						
							| 
									
										
										
										
											2017-10-16 11:47:38 +08:00
										 |  |  |             portEXIT_CRITICAL(&hooks_spinlock); | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  |             return ESP_OK; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-16 11:47:38 +08:00
										 |  |  |     portEXIT_CRITICAL(&hooks_spinlock); | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  |     return ESP_ERR_NO_MEM; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-13 18:27:53 +08:00
										 |  |  | esp_err_t esp_register_freertos_tick_hook(esp_freertos_tick_cb_t new_tick_cb)  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return esp_register_freertos_tick_hook_for_cpu(new_tick_cb, xPortGetCoreID()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 18:07:30 +08:00
										 |  |  | void esp_deregister_freertos_idle_hook_for_cpu(esp_freertos_idle_cb_t old_idle_cb, UBaseType_t cpuid) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     portENTER_CRITICAL(&hooks_spinlock); | 
					
						
							|  |  |  |     if(cpuid >= portNUM_PROCESSORS){ | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for(int n = 0; n < MAX_HOOKS; n++){ | 
					
						
							|  |  |  |         if(idle_cb[cpuid][n] == old_idle_cb) idle_cb[cpuid][n] = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     portEXIT_CRITICAL(&hooks_spinlock); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  | void esp_deregister_freertos_idle_hook(esp_freertos_idle_cb_t old_idle_cb) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-16 11:47:38 +08:00
										 |  |  |     portENTER_CRITICAL(&hooks_spinlock); | 
					
						
							| 
									
										
										
										
											2017-10-13 18:27:53 +08:00
										 |  |  |     for(int m = 0; m < portNUM_PROCESSORS; m++) { | 
					
						
							| 
									
										
										
										
											2017-10-09 18:07:30 +08:00
										 |  |  |         esp_deregister_freertos_idle_hook_for_cpu(old_idle_cb, m); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     portEXIT_CRITICAL(&hooks_spinlock); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void esp_deregister_freertos_tick_hook_for_cpu(esp_freertos_tick_cb_t old_tick_cb, UBaseType_t cpuid) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     portENTER_CRITICAL(&hooks_spinlock); | 
					
						
							|  |  |  |     if(cpuid >= portNUM_PROCESSORS){ | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for(int n = 0; n < MAX_HOOKS; n++){ | 
					
						
							|  |  |  |         if(tick_cb[cpuid][n] == old_tick_cb) tick_cb[cpuid][n] = NULL; | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-16 11:47:38 +08:00
										 |  |  |     portEXIT_CRITICAL(&hooks_spinlock); | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void esp_deregister_freertos_tick_hook(esp_freertos_tick_cb_t old_tick_cb) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-16 11:47:38 +08:00
										 |  |  |     portENTER_CRITICAL(&hooks_spinlock); | 
					
						
							| 
									
										
										
										
											2017-10-13 18:27:53 +08:00
										 |  |  |     for(int m = 0; m < portNUM_PROCESSORS; m++){ | 
					
						
							| 
									
										
										
										
											2017-10-09 18:07:30 +08:00
										 |  |  |         esp_deregister_freertos_tick_hook_for_cpu(old_tick_cb, m); | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-16 11:47:38 +08:00
										 |  |  |     portEXIT_CRITICAL(&hooks_spinlock); | 
					
						
							| 
									
										
										
										
											2016-11-11 19:20:54 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 |