Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers protocol_timer.c Source File

protocol_timer.c

00001 /*
00002  * Copyright (c) 2014-2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 #include "nsconfig.h"
00018 #include "ns_types.h"
00019 #include "ns_trace.h"
00020 #include "eventOS_event.h"
00021 #include "eventOS_callback_timer.h"
00022 #include "NWK_INTERFACE/Include/protocol.h"
00023 #include "NWK_INTERFACE/Include/protocol_timer.h"
00024 #include "platform/arm_hal_interrupt.h"
00025 
00026 #define TRACE_GROUP "ctim"
00027 
00028 #define PROTOCOL_TIMER_INTERVAL 1000    // 50us units, so we use 50ms
00029 
00030 NS_LARGE protocol_timer_t protocol_timer[PROTOCOL_TIMER_MAX];
00031 int8_t protocol_timer_id = -1;
00032 bool protocol_tick_handle_busy = false;
00033 static uint16_t  protocol_tick_update = 0;
00034 int protocol_timer_init(void)
00035 {
00036     uint8_t i;
00037     protocol_timer_id = eventOS_callback_timer_register(protocol_timer_interrupt);
00038     for (i = 0; i < PROTOCOL_TIMER_MAX; i++) {
00039         protocol_timer[i].ticks = 0;
00040         protocol_timer[i].time_drifts =0;
00041     }
00042     if (protocol_timer_id >= 0) {
00043         eventOS_callback_timer_start(protocol_timer_id, PROTOCOL_TIMER_INTERVAL);
00044     }
00045     return protocol_timer_id;
00046 }
00047 
00048 // time is in milliseconds
00049 void protocol_timer_start(protocol_timer_id_t id, void (*passed_fptr)(uint16_t), uint32_t time)
00050 {
00051     //Check Overflow
00052     if (passed_fptr) {
00053         if (time > 0x12FFED) {
00054             time = 0xffff;
00055         }
00056         if (time >= 100) {
00057             time /= (1000 / 20);
00058             //time++;
00059         } else {
00060             time = 1;
00061         }
00062         platform_enter_critical();
00063         protocol_timer[id].ticks = (uint16_t) time;
00064 
00065         protocol_timer[id].orderedTime = (uint16_t) time;
00066         if (time > 1 && protocol_timer[id].time_drifts >= 50) {
00067             protocol_timer[id].ticks--;
00068             protocol_timer[id].time_drifts -= 50;
00069         }
00070         protocol_timer[id].fptr = passed_fptr;
00071         platform_exit_critical();
00072     } else {
00073         tr_debug("Do Not use Null pointer for fptr!!!\n");
00074     }
00075 }
00076 
00077 void protocol_timer_stop(protocol_timer_id_t id)
00078 {
00079     platform_enter_critical();
00080     protocol_timer[id].ticks = 0;
00081     protocol_timer[id].orderedTime = 0;
00082     platform_exit_critical();
00083 }
00084 
00085 
00086 
00087 void protocol_timer_sleep_balance(uint32_t time_in_ms)
00088 {
00089     uint8_t i;
00090     uint16_t ticks_module;
00091     uint16_t time_in50ms_ticks;
00092     uint16_t tick_update, tempTimer;
00093 
00094     ticks_module = (time_in_ms % 50);
00095     time_in50ms_ticks = (time_in_ms / 50);
00096     for (i = 0; i < PROTOCOL_TIMER_MAX; i++) {
00097         if (protocol_timer[i].ticks) {
00098 
00099             tick_update = time_in50ms_ticks;
00100             protocol_timer[i].time_drifts += ticks_module;
00101 
00102             if (protocol_timer[i].time_drifts >= 50) {
00103                 protocol_timer[i].time_drifts -= 50;
00104             }
00105 
00106             if (protocol_timer[i].ticks <= tick_update) {
00107                 tempTimer = (tick_update - protocol_timer[i].ticks);
00108                 tick_update = 1;
00109                 if (tempTimer >= protocol_timer[i].orderedTime) {
00110                     tick_update += (tempTimer / protocol_timer[i].orderedTime);
00111                     //time drift
00112                     protocol_timer[i].time_drifts += ((tempTimer % protocol_timer[i].orderedTime) *50);
00113                 }
00114 
00115                 protocol_timer[i].ticks = 0;
00116                 protocol_timer[i].orderedTime = 0;
00117                 protocol_timer[i].fptr(tick_update);
00118 
00119             } else {
00120                 protocol_timer[i].ticks -= tick_update;
00121             }
00122         }
00123     }
00124 
00125 }
00126 
00127 void protocol_timer_event_lock_free(void)
00128 {
00129     platform_enter_critical();
00130     protocol_tick_handle_busy = false;
00131     platform_exit_critical();
00132 }
00133 
00134 
00135 void protocol_timer_cb(uint16_t ticks)
00136 {
00137     uint8_t i;
00138     uint16_t tick_update, tempTimer;
00139     for (i = 0; i < PROTOCOL_TIMER_MAX; i++) {
00140         if (protocol_timer[i].ticks) {
00141             if (protocol_timer[i].ticks <= ticks) {
00142                 tempTimer = (ticks - protocol_timer[i].ticks);
00143 
00144                 tick_update = 1;
00145                 if (protocol_timer[i].time_drifts >= 50) {
00146                     tempTimer++;
00147                     protocol_timer[i].time_drifts -= 50;
00148                 }
00149 
00150                 if (tempTimer >= protocol_timer[i].orderedTime) {
00151                     tick_update += (tempTimer / protocol_timer[i].orderedTime);
00152                     protocol_timer[i].time_drifts += ((tempTimer % protocol_timer[i].orderedTime) *50);
00153                 }
00154 
00155                 protocol_timer[i].ticks = 0;
00156                 protocol_timer[i].orderedTime = 0;
00157                 protocol_timer[i].fptr(tick_update);
00158 
00159             } else {
00160                 protocol_timer[i].ticks -= ticks;
00161             }
00162         }
00163     }
00164 }
00165 
00166 void protocol_timer_interrupt(int8_t timer_id, uint16_t slots)
00167 {
00168     (void)timer_id;
00169     (void)slots;
00170     eventOS_callback_timer_start(protocol_timer_id, PROTOCOL_TIMER_INTERVAL);
00171     protocol_tick_update++;
00172 
00173     if (!protocol_tick_handle_busy) {
00174         /* This static stuff gets initialised once */
00175         static arm_event_storage_t event = {
00176             .data = {
00177                 .data_ptr = NULL,
00178                 .event_type = ARM_IN_PROTOCOL_TIMER_EVENT,
00179                 .event_id = 0,
00180                 .priority = ARM_LIB_HIGH_PRIORITY_EVENT
00181             }
00182         };
00183 
00184         /* Dynamic stuff */
00185         event.data.receiver = event.data.sender = protocol_read_tasklet_id();
00186         event.data.event_data = protocol_tick_update;
00187         protocol_tick_update = 0;
00188 
00189         /* Use user-allocated variant to avoid memory allocation failure */
00190         eventOS_event_send_user_allocated(&event);
00191         protocol_tick_handle_busy = true;
00192     }
00193 }