1 /* 2 * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>. 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 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 * 32 * @file : task_sensor.c 33 * @date : Set 26, 2023 34 * @author : Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar> 35 * @version v1.0.0 36 */ 37 38 /********************** inclusions *******************************************/ 39 /* Project includes */ 40 #include "main.h" 41 42 /* Demo includes */ 43 #include "logger.h" 44 #include "dwt.h" 45 46 /* Application & Tasks includes */ 47 #include "board.h" 48 #include "app.h" 49 #include "task_sensor_attribute.h" 50 #include "task_menu_attribute.h" 51 #include "task_menu_interface.h" 52 53 /********************** macros and definitions *******************************/ 54 #define G_TASK_SEN_CNT_INIT 0ul 55 #define G_TASK_SEN_TICK_CNT_INI 0ul 56 #define G_TASK_SEN_INACTIVE_MAX_TICK 10000ul // 10 seconds 57 58 #define DEL_BTN_XX_MIN 0ul 59 #define DEL_BTN_XX_MED 10ul 60 #define DEL_BTN_XX_MAX 20ul 61 62 /********************** internal data declaration ****************************/ 63 const task_sensor_cfg_t task_sensor_cfg_list[] = { 64 {ID_BTN_ENT, BTN_ENT_PORT, BTN_ENT_PIN, BTN_ENT_PRESSED, DEL_BTN_XX_MAX, 65 EV_MEN_ENT_IDLE, EV_MEN_ENT_ACTIVE}, 66 {ID_BTN_NEX, BTN_NEX_PORT, BTN_NEX_PIN, BTN_NEX_PRESSED, DEL_BTN_XX_MAX, 67 EV_MEN_NEX_IDLE, EV_MEN_NEX_ACTIVE}, 68 {ID_BTN_ESC, BTN_ESC_PORT, BTN_ESC_PIN, BTN_ESC_PRESSED, DEL_BTN_XX_MAX, 69 EV_MEN_ESC_IDLE, EV_MEN_ESC_ACTIVE} 70 }; 71 72 #define SENSOR_CFG_QTY (sizeof(task_sensor_cfg_list)/sizeof(task_sensor_cfg_t)) 73 74 task_sensor_dta_t task_sensor_dta_list[] = { 75 {DEL_BTN_XX_MIN, ST_BTN_XX_UP, EV_BTN_XX_UP}, 76 {DEL_BTN_XX_MIN, ST_BTN_XX_UP, EV_BTN_XX_UP}, 77 {DEL_BTN_XX_MIN, ST_BTN_XX_UP, EV_BTN_XX_UP} 78 }; 79 80 #define SENSOR_DTA_QTY (sizeof(task_sensor_dta_list)/sizeof(task_sensor_dta_t)) 81 82 /********************** internal functions declaration ***********************/ 83 void task_sensor_statechart(void); 84 85 /********************** internal data definition *****************************/ 86 const char *p_task_sensor = "Task Sensor (Sensor Statechart)"; 87 const char *p_task_sensor_ = "Non-Blocking & Update By Time Code"; 88 89 uint32_t g_task_sensor_last_active_ticks; 90 91 /********************** external data declaration ****************************/ 92 uint32_t g_task_sensor_cnt; 93 volatile uint32_t g_task_sensor_tick_cnt; 94 95 /********************** external functions definition ************************/ 96 void task_sensor_init(void *parameters) 97 { 98 uint32_t index; 99 task_sensor_dta_t *p_task_sensor_dta; 100 task_sensor_st_t state; 101 task_sensor_ev_t event; 102 103 /* Print out: Task Initialized */ 104 LOGGER_INFO(" "); 105 LOGGER_INFO(" %s is running - %s", GET_NAME(task_sensor_init), p_task_sensor); 106 LOGGER_INFO(" %s is a %s", GET_NAME(task_sensor), p_task_sensor_); 107 108 /* Init & Print out: Task execution counter */ 109 g_task_sensor_cnt = G_TASK_SEN_CNT_INIT; 110 LOGGER_INFO(" %s = %lu", GET_NAME(g_task_sensor_cnt), g_task_sensor_cnt); 111 112 113 g_task_sensor_last_active_ticks = G_TASK_SEN_INACTIVE_MAX_TICK; 114 115 for (index = 0; SENSOR_DTA_QTY > index; index++) 116 { 117 /* Update Task Sensor Data Pointer */ 118 p_task_sensor_dta = &task_sensor_dta_list[index]; 119 120 /* Init & Print out: Index & Task execution FSM */ 121 state = ST_BTN_XX_UP; 122 p_task_sensor_dta->state = state; 123 124 event = EV_BTN_XX_UP; 125 p_task_sensor_dta->event = event; 126 127 LOGGER_INFO(" "); 128 LOGGER_INFO(" %s = %lu %s = %lu %s = %lu", 129 GET_NAME(index), index, 130 GET_NAME(state), (uint32_t)state, 131 GET_NAME(event), (uint32_t)event); 132 } 133 } 134 135 void task_sensor_update(void *parameters) 136 { 137 bool b_time_update_required = false; 138 139 if (0 < g_task_sensor_last_active_ticks) 140 { 141 g_task_sensor_last_active_ticks--; 142 143 if (1 == g_task_sensor_last_active_ticks) 144 { 145 g_task_sensor_last_active_ticks = 0; 146 put_event_task_menu(EV_MEN_INACTIVE_TIMEOUT); 147 } 148 } 149 150 /* Protect shared resource */ 151 __asm("CPSID i"); /* disable interrupts */ 152 if (G_TASK_SEN_TICK_CNT_INI < g_task_sensor_tick_cnt) 153 { 154 /* Update Tick Counter */ 155 g_task_sensor_tick_cnt--; 156 b_time_update_required = true; 157 } 158 __asm("CPSIE i"); /* enable interrupts */ 159 160 while (b_time_update_required) 161 { 162 /* Update Task Counter */ 163 g_task_sensor_cnt++; 164 165 /* Run Task Sensor Statechart */ 166 task_sensor_statechart(); 167 168 /* Protect shared resource */ 169 __asm("CPSID i"); /* disable interrupts */ 170 if (G_TASK_SEN_TICK_CNT_INI < g_task_sensor_tick_cnt) 171 { 172 /* Update Tick Counter */ 173 g_task_sensor_tick_cnt--; 174 b_time_update_required = true; 175 } 176 else 177 { 178 b_time_update_required = false; 179 } 180 __asm("CPSIE i"); /* enable interrupts */ 181 } 182 } 183 184 void task_sensor_statechart(void) 185 { 186 uint32_t index; 187 const task_sensor_cfg_t *p_task_sensor_cfg; 188 task_sensor_dta_t *p_task_sensor_dta; 189 190 for (index = 0; SENSOR_DTA_QTY > index; index++) 191 { 192 /* Update Task Sensor Configuration & Data Pointer */ 193 p_task_sensor_cfg = &task_sensor_cfg_list[index]; 194 p_task_sensor_dta = &task_sensor_dta_list[index]; 195 196 if (p_task_sensor_cfg->pressed == HAL_GPIO_ReadPin(p_task_sensor_cfg->gpio_port, p_task_sensor_cfg->pin)) 197 { 198 p_task_sensor_dta->event = EV_BTN_XX_DOWN; 199 } 200 else 201 { 202 p_task_sensor_dta->event = EV_BTN_XX_UP; 203 } 204 205 switch (p_task_sensor_dta->state) 206 { 207 case ST_BTN_XX_UP: 208 209 if (EV_BTN_XX_DOWN == p_task_sensor_dta->event) 210 { 211 p_task_sensor_dta->tick = p_task_sensor_cfg->tick_max; 212 p_task_sensor_dta->state = ST_BTN_XX_FALLING; 213 } 214 215 break; 216 217 case ST_BTN_XX_FALLING: 218 219 p_task_sensor_dta->tick--; 220 if (DEL_BTN_XX_MIN == p_task_sensor_dta->tick) 221 { 222 if (EV_BTN_XX_DOWN == p_task_sensor_dta->event) 223 { 224 put_event_task_menu(p_task_sensor_cfg->signal_down); 225 p_task_sensor_dta->state = ST_BTN_XX_DOWN; 226 g_task_sensor_last_active_ticks = G_TASK_SEN_INACTIVE_MAX_TICK; 227 } 228 else 229 { 230 p_task_sensor_dta->state = ST_BTN_XX_UP; 231 } 232 } 233 234 break; 235 236 case ST_BTN_XX_DOWN: 237 238 if (EV_BTN_XX_UP == p_task_sensor_dta->event) 239 { 240 p_task_sensor_dta->state = ST_BTN_XX_RISING; 241 p_task_sensor_dta->tick = p_task_sensor_cfg->tick_max; 242 } 243 244 break; 245 246 case ST_BTN_XX_RISING: 247 248 p_task_sensor_dta->tick--; 249 if (DEL_BTN_XX_MIN == p_task_sensor_dta->tick) 250 { 251 if (EV_BTN_XX_UP == p_task_sensor_dta->event) 252 { 253 put_event_task_menu(p_task_sensor_cfg->signal_up); 254 p_task_sensor_dta->state = ST_BTN_XX_UP; 255 g_task_sensor_last_active_ticks = G_TASK_SEN_INACTIVE_MAX_TICK; 256 } 257 else 258 { 259 p_task_sensor_dta->state = ST_BTN_XX_DOWN; 260 } 261 } 262 263 break; 264 265 default: 266 267 p_task_sensor_dta->tick = DEL_BTN_XX_MIN; 268 p_task_sensor_dta->state = ST_BTN_XX_UP; 269 p_task_sensor_dta->event = EV_BTN_XX_UP; 270 271 break; 272 } 273 } 274 } 275 276 /********************** end of file ******************************************/
