Displays user interactions with menus displayed on a console or a serial terminal.

Dependents:   EVAL-AD568x-AD569x EVAL-AD7124 EVAL-AD5592R EVAL-AD717x-AD411x ... more

Committer:
Kjansen
Date:
Fri Dec 03 18:07:28 2021 +0000
Revision:
5:052b9936f41f
Parent:
4:ced4fa6875ed
Child:
6:34034065d24b
Minor changes:
* Updated to code to have a global state of the console menu library.
* Added code to call the sub menu directly.
* Added function pointer check to the if statement.
* Added changes to store the error code from last menu action.
* Added macro and enum for representing colored text
* Added function to handle integer user input

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mahphalke 1:dcc17e5a913f 1 /*!
mahphalke 1:dcc17e5a913f 2 *****************************************************************************
mahphalke 1:dcc17e5a913f 3 @file: adi_console_menu.c
mahphalke 1:dcc17e5a913f 4
mahphalke 1:dcc17e5a913f 5 @brief: A simple console menu manager handler
mahphalke 1:dcc17e5a913f 6
mahphalke 1:dcc17e5a913f 7 @details: A way to define using arrays of structs a set of menus that can
mahphalke 1:dcc17e5a913f 8 be displayed to a user, easily, with all user interaction handled
mahphalke 1:dcc17e5a913f 9 by the library, leaving only the implementation of the menu actions
mahphalke 1:dcc17e5a913f 10 to be done by the library user.
mahphalke 1:dcc17e5a913f 11 -----------------------------------------------------------------------------
Kjansen 5:052b9936f41f 12 Copyright (c) 2019-2021 Analog Devices, Inc.
mahphalke 1:dcc17e5a913f 13 All rights reserved.
mahphalke 1:dcc17e5a913f 14
mahphalke 1:dcc17e5a913f 15 This software is proprietary to Analog Devices, Inc. and its licensors.
mahphalke 1:dcc17e5a913f 16 By using this software you agree to the terms of the associated
mahphalke 1:dcc17e5a913f 17 Analog Devices Software License Agreement.
mahphalke 1:dcc17e5a913f 18
mahphalke 1:dcc17e5a913f 19 *****************************************************************************/
mahphalke 1:dcc17e5a913f 20
Kjansen 5:052b9936f41f 21 /****************************************************************************/
Kjansen 5:052b9936f41f 22 /***************************** Include Files ********************************/
Kjansen 5:052b9936f41f 23 /****************************************************************************/
mahphalke 1:dcc17e5a913f 24 #include <stdio.h>
mahphalke 1:dcc17e5a913f 25 #include <stdlib.h>
mahphalke 1:dcc17e5a913f 26 #include <ctype.h>
mahphalke 1:dcc17e5a913f 27 #include <string.h>
mahphalke 1:dcc17e5a913f 28 #include <stdbool.h>
mahphalke 1:dcc17e5a913f 29 #include <assert.h>
mahphalke 1:dcc17e5a913f 30
mahphalke 1:dcc17e5a913f 31 #include "adi_console_menu.h"
Kjansen 5:052b9936f41f 32 #include "error.h"
mahphalke 1:dcc17e5a913f 33
Kjansen 5:052b9936f41f 34 /****************************************************************************/
Kjansen 5:052b9936f41f 35 /********************** Macros and Constants Definition *********************/
Kjansen 5:052b9936f41f 36 /****************************************************************************/
mahphalke 1:dcc17e5a913f 37 #define DIV_STRING "\t=================================================="
mahphalke 1:dcc17e5a913f 38
Kjansen 5:052b9936f41f 39 /******************************************************************************/
Kjansen 5:052b9936f41f 40 /*************************** Types Declarations *******************************/
Kjansen 5:052b9936f41f 41 /******************************************************************************/
Kjansen 5:052b9936f41f 42 // Saves the state of console menu library
Kjansen 5:052b9936f41f 43 console_menu_state adi_console_menu_state = {
Kjansen 5:052b9936f41f 44 .last_error_code = SUCCESS
Kjansen 5:052b9936f41f 45 };
Kjansen 5:052b9936f41f 46
Kjansen 5:052b9936f41f 47 /****************************************************************************/
Kjansen 5:052b9936f41f 48 /***************************** Function Definitions *************************/
Kjansen 5:052b9936f41f 49 /****************************************************************************/
mahphalke 1:dcc17e5a913f 50 /*!
mahphalke 1:dcc17e5a913f 51 * @brief displays the text of a console menu
mahphalke 1:dcc17e5a913f 52 *
mahphalke 1:dcc17e5a913f 53 * @details
mahphalke 1:dcc17e5a913f 54 */
mahphalke 1:dcc17e5a913f 55 static void adi_display_console_menu(const console_menu * menu)
mahphalke 1:dcc17e5a913f 56 {
mahphalke 1:dcc17e5a913f 57 adi_clear_console();
mahphalke 1:dcc17e5a913f 58
mahphalke 1:dcc17e5a913f 59 // call headerItem to allow display of other content
mahphalke 1:dcc17e5a913f 60 if (menu->headerItem != NULL) {
mahphalke 1:dcc17e5a913f 61 menu->headerItem();
mahphalke 1:dcc17e5a913f 62 printf(DIV_STRING EOL);
mahphalke 1:dcc17e5a913f 63 }
mahphalke 1:dcc17e5a913f 64
mahphalke 1:dcc17e5a913f 65 /*
mahphalke 1:dcc17e5a913f 66 * Display the menu title and menuItems
mahphalke 1:dcc17e5a913f 67 * The shortcutKey is used to display '[A]' before the dispayText
mahphalke 1:dcc17e5a913f 68 */
mahphalke 1:dcc17e5a913f 69 printf("\t%s" EOL "\t", menu->title);
mahphalke 1:dcc17e5a913f 70 // show an underline to distinguish title from item
mahphalke 1:dcc17e5a913f 71 for (uint8_t i = 0; i < strlen(menu->title); i++) {
mahphalke 1:dcc17e5a913f 72 putchar('-');
mahphalke 1:dcc17e5a913f 73 }
mahphalke 1:dcc17e5a913f 74 // Extend underline past end of string, and then new line
mahphalke 1:dcc17e5a913f 75 printf("--" EOL);
mahphalke 1:dcc17e5a913f 76
mahphalke 1:dcc17e5a913f 77 // If the shortcutKey is not unique, first found is used
mahphalke 1:dcc17e5a913f 78 for (uint8_t i = 0; i < menu->itemCount; i ++) {
mahphalke 1:dcc17e5a913f 79 if (menu->items[i].shortcutKey == '\00') {
mahphalke 1:dcc17e5a913f 80 // No shortcut key defined, but display item text if available
mahphalke 1:dcc17e5a913f 81 printf("\t%s" EOL, menu->items[i].text);
mahphalke 1:dcc17e5a913f 82 } else {
mahphalke 1:dcc17e5a913f 83 printf("\t[%c] %s" EOL, toupper(menu->items[i].shortcutKey),
mahphalke 1:dcc17e5a913f 84 menu->items[i].text);
mahphalke 1:dcc17e5a913f 85 }
mahphalke 1:dcc17e5a913f 86 }
mahphalke 1:dcc17e5a913f 87 if (menu->enableEscapeKey) {
mahphalke 1:dcc17e5a913f 88 printf(EOL "\t[ESC] Exit Menu" EOL);
mahphalke 1:dcc17e5a913f 89 }
mahphalke 1:dcc17e5a913f 90
mahphalke 1:dcc17e5a913f 91 printf(EOL "\tPlease make a selection." EOL);
mahphalke 1:dcc17e5a913f 92
mahphalke 1:dcc17e5a913f 93 // call footerItem to allow display of other content
mahphalke 1:dcc17e5a913f 94 if (menu->footerItem != NULL) {
mahphalke 1:dcc17e5a913f 95 printf(DIV_STRING EOL);
mahphalke 1:dcc17e5a913f 96 menu->footerItem();
mahphalke 1:dcc17e5a913f 97 }
mahphalke 1:dcc17e5a913f 98 }
mahphalke 1:dcc17e5a913f 99
mahphalke 1:dcc17e5a913f 100 /*!
mahphalke 1:dcc17e5a913f 101 * @brief Display a consoleMenu and handle User interaction
mahphalke 1:dcc17e5a913f 102 *
mahphalke 1:dcc17e5a913f 103 * @details This displays the menuItems defined by the console menu, and
Kjansen 5:052b9936f41f 104 * handles all user interaction for the menu.
Kjansen 5:052b9936f41f 105 *
Kjansen 5:052b9936f41f 106 * @note The function will return either the item selected or error code
Kjansen 5:052b9936f41f 107 * from the last action. One at a time. Either define the menu action
Kjansen 5:052b9936f41f 108 * or sub menu. If both are defined the function would return error.
Kjansen 5:052b9936f41f 109 * If both menu action and sub menu are defined NULL, then the
Kjansen 5:052b9936f41f 110 * function will return the item selected
mahphalke 1:dcc17e5a913f 111 */
mahphalke 1:dcc17e5a913f 112 int32_t adi_do_console_menu(const console_menu * menu)
mahphalke 1:dcc17e5a913f 113 {
mahphalke 1:dcc17e5a913f 114 int32_t itemSelected = MENU_ESCAPED;
mahphalke 1:dcc17e5a913f 115 bool enableKeyScan = true;
Kjansen 5:052b9936f41f 116 int32_t ret = MENU_DONE;
Kjansen 5:052b9936f41f 117
mahphalke 1:dcc17e5a913f 118 adi_display_console_menu(menu);
mahphalke 1:dcc17e5a913f 119
mahphalke 1:dcc17e5a913f 120 /*
mahphalke 1:dcc17e5a913f 121 * Loop waiting for valid user input. menuItem index is returned if
mahphalke 1:dcc17e5a913f 122 * user presses a valid menu option.
mahphalke 1:dcc17e5a913f 123 */
mahphalke 1:dcc17e5a913f 124 do {
mahphalke 1:dcc17e5a913f 125 char keyPressed = toupper(getchar());
mahphalke 1:dcc17e5a913f 126
mahphalke 1:dcc17e5a913f 127 if (menu->enableEscapeKey) {
mahphalke 1:dcc17e5a913f 128 if (keyPressed == ESCAPE_KEY_CODE) {
mahphalke 1:dcc17e5a913f 129 itemSelected = MENU_ESCAPED;
mahphalke 1:dcc17e5a913f 130 enableKeyScan = false;
mahphalke 1:dcc17e5a913f 131 break;
mahphalke 1:dcc17e5a913f 132 }
mahphalke 1:dcc17e5a913f 133 }
mahphalke 1:dcc17e5a913f 134
mahphalke 1:dcc17e5a913f 135 for (uint8_t i = 0; i < menu->itemCount; i ++) {
mahphalke 1:dcc17e5a913f 136 if (toupper(menu->items[i].shortcutKey) == keyPressed) {
mahphalke 1:dcc17e5a913f 137 itemSelected = i;
mahphalke 1:dcc17e5a913f 138
Kjansen 5:052b9936f41f 139 // If the menuAction function pointer is NULL and
Kjansen 5:052b9936f41f 140 // the sub console menu pointer is not NULL,
Kjansen 5:052b9936f41f 141 // call the sub console menu.
Kjansen 5:052b9936f41f 142 if (menu->items[i].action == NULL
Kjansen 5:052b9936f41f 143 && menu->items[i].submenu != NULL) {
Kjansen 5:052b9936f41f 144 ret = adi_do_console_menu(menu->items[i].submenu);
Kjansen 5:052b9936f41f 145 }
Kjansen 5:052b9936f41f 146 // If the menuAction function pointer is not NULL and sub console menu
Kjansen 5:052b9936f41f 147 // pointer is NULL, call the action.
Kjansen 5:052b9936f41f 148 else if (menu->items[i].action != NULL && menu->items[i].submenu == NULL) {
Kjansen 5:052b9936f41f 149 ret = menu->items[i].action(menu->items[i].id);
Kjansen 5:052b9936f41f 150 }
Kjansen 5:052b9936f41f 151 // If both are NULL, then return Not Supported action.
Kjansen 5:052b9936f41f 152 else if (menu->items[i].action != NULL && menu->items[i].submenu != NULL) {
Kjansen 5:052b9936f41f 153 ret = -ENOTSUP;
Kjansen 5:052b9936f41f 154 }
Kjansen 5:052b9936f41f 155
Kjansen 5:052b9936f41f 156 // Store the return value if it is negative.
Kjansen 5:052b9936f41f 157 if (ret < 0) {
Kjansen 5:052b9936f41f 158 adi_console_menu_state.last_error_code = ret;
Kjansen 5:052b9936f41f 159 ret = MENU_CONTINUE;
Kjansen 5:052b9936f41f 160 }
Kjansen 5:052b9936f41f 161
Kjansen 5:052b9936f41f 162 switch (ret) {
Kjansen 5:052b9936f41f 163 case MENU_DONE : {
Kjansen 5:052b9936f41f 164 enableKeyScan = false;
Kjansen 5:052b9936f41f 165 break;
Kjansen 5:052b9936f41f 166 }
Kjansen 5:052b9936f41f 167 case MENU_CONTINUE:
Kjansen 5:052b9936f41f 168 default: {
Kjansen 5:052b9936f41f 169 enableKeyScan = true;
Kjansen 5:052b9936f41f 170 adi_display_console_menu(menu);
Kjansen 5:052b9936f41f 171 break;
Kjansen 5:052b9936f41f 172 }
mahphalke 1:dcc17e5a913f 173 }
mahphalke 1:dcc17e5a913f 174 break;
mahphalke 1:dcc17e5a913f 175 }
mahphalke 1:dcc17e5a913f 176 }
Kjansen 5:052b9936f41f 177 // If both the action and sub menu are defined NULL, and the item selected
Kjansen 5:052b9936f41f 178 // is not MENU_ESCAPED, then break the loop to return selected item.
Kjansen 5:052b9936f41f 179 if(itemSelected != MENU_ESCAPED &&
Kjansen 5:052b9936f41f 180 menu->items[itemSelected].action == NULL &&
Kjansen 5:052b9936f41f 181 menu->items[itemSelected].submenu == NULL) {
Kjansen 5:052b9936f41f 182 break;
Kjansen 5:052b9936f41f 183 }
mahphalke 1:dcc17e5a913f 184 } while (enableKeyScan);
mahphalke 1:dcc17e5a913f 185
mahphalke 1:dcc17e5a913f 186 return (itemSelected);
mahphalke 1:dcc17e5a913f 187 }
mahphalke 1:dcc17e5a913f 188
mahphalke 1:dcc17e5a913f 189 /*!
mahphalke 1:dcc17e5a913f 190 * @brief Reads a decimal string from the user
mahphalke 1:dcc17e5a913f 191 *
mahphalke 1:dcc17e5a913f 192 * @param input_len max number of character to accept from the user
mahphalke 1:dcc17e5a913f 193 *
Kjansen 5:052b9936f41f 194 * @return The integer value entered
mahphalke 1:dcc17e5a913f 195 *
mahphalke 1:dcc17e5a913f 196 * @details Allows a user to type in number, echoing back to the user,
mahphalke 1:dcc17e5a913f 197 * up to input_len chars
mahphalke 1:dcc17e5a913f 198 *
mahphalke 1:dcc17e5a913f 199 * @note Only positive integer numbers are supported currently
mahphalke 1:dcc17e5a913f 200 */
mahphalke 1:dcc17e5a913f 201 int32_t adi_get_decimal_int(uint8_t input_len)
mahphalke 1:dcc17e5a913f 202 {
mahphalke 1:dcc17e5a913f 203 char buf[20] = {0};
mahphalke 1:dcc17e5a913f 204 uint8_t buf_index = 0;
mahphalke 1:dcc17e5a913f 205 char ch;
mahphalke 1:dcc17e5a913f 206 bool loop = true;
mahphalke 1:dcc17e5a913f 207
mahphalke 1:dcc17e5a913f 208 assert(input_len < 19);
mahphalke 1:dcc17e5a913f 209
mahphalke 1:dcc17e5a913f 210 do {
mahphalke 1:dcc17e5a913f 211 ch = getchar();
mahphalke 1:dcc17e5a913f 212 if (isdigit(ch) && buf_index < (input_len)) {
mahphalke 1:dcc17e5a913f 213 // echo and store it as buf not full
mahphalke 1:dcc17e5a913f 214 buf[buf_index++] = ch;
mahphalke 1:dcc17e5a913f 215 putchar(ch);
mahphalke 1:dcc17e5a913f 216 }
mahphalke 1:dcc17e5a913f 217 if ((ch == '\x7F') && (buf_index > 0)) {
mahphalke 1:dcc17e5a913f 218 //backspace and at least 1 char in buffer
mahphalke 1:dcc17e5a913f 219 buf[buf_index--] = '\x00';
mahphalke 1:dcc17e5a913f 220 putchar(ch);
mahphalke 1:dcc17e5a913f 221 }
mahphalke 1:dcc17e5a913f 222 if ((ch == '\x0D') || (ch == '\x0A')) {
mahphalke 1:dcc17e5a913f 223 // return key pressed, all done, null terminate string
mahphalke 1:dcc17e5a913f 224 buf[buf_index] = '\x00';
mahphalke 1:dcc17e5a913f 225 loop = false;
mahphalke 1:dcc17e5a913f 226 }
mahphalke 1:dcc17e5a913f 227 } while(loop);
mahphalke 1:dcc17e5a913f 228
mahphalke 1:dcc17e5a913f 229 return atoi(buf);
mahphalke 1:dcc17e5a913f 230 }
mahphalke 1:dcc17e5a913f 231
mahphalke 1:dcc17e5a913f 232 /*!
mahphalke 1:dcc17e5a913f 233 * @brief Reads a hexadecimal number from the user
mahphalke 1:dcc17e5a913f 234 *
mahphalke 1:dcc17e5a913f 235 * @param input_len max number of character to accept from the user
mahphalke 1:dcc17e5a913f 236 *
mahphalke 1:dcc17e5a913f 237 * @return The integer value entered
mahphalke 1:dcc17e5a913f 238 *
mahphalke 1:dcc17e5a913f 239 * @details Allows a user to type in a hexnumber, echoing back to the user,
mahphalke 1:dcc17e5a913f 240 * up to input_len chars
mahphalke 1:dcc17e5a913f 241 */
mahphalke 1:dcc17e5a913f 242 uint32_t adi_get_hex_integer(uint8_t input_len)
mahphalke 1:dcc17e5a913f 243 {
mahphalke 1:dcc17e5a913f 244 char buf[9] = {0};
mahphalke 1:dcc17e5a913f 245 uint8_t buf_index = 0;
mahphalke 1:dcc17e5a913f 246 char ch;
mahphalke 1:dcc17e5a913f 247 bool loop = true;
mahphalke 1:dcc17e5a913f 248
mahphalke 1:dcc17e5a913f 249 assert(input_len < 8);
mahphalke 1:dcc17e5a913f 250
mahphalke 1:dcc17e5a913f 251 do {
mahphalke 1:dcc17e5a913f 252 ch = getchar();
mahphalke 1:dcc17e5a913f 253 if (isxdigit(ch) && buf_index < (input_len)) {
mahphalke 1:dcc17e5a913f 254 // echo and store it as buf not full
mahphalke 1:dcc17e5a913f 255 buf[buf_index++] = ch;
mahphalke 1:dcc17e5a913f 256 putchar(ch);
mahphalke 1:dcc17e5a913f 257 }
mahphalke 1:dcc17e5a913f 258 if ((ch == '\x7F') && (buf_index > 0)) {
mahphalke 1:dcc17e5a913f 259 //backspace and at least 1 char in buffer
mahphalke 1:dcc17e5a913f 260 buf[buf_index--] = '\x00';
mahphalke 1:dcc17e5a913f 261 putchar(ch);
mahphalke 1:dcc17e5a913f 262 }
mahphalke 1:dcc17e5a913f 263 if ((ch == '\x0D') || (ch == '\x0A')) {
mahphalke 1:dcc17e5a913f 264 // return key pressed, all done, null terminate string
mahphalke 1:dcc17e5a913f 265 buf[buf_index] = '\x00';
mahphalke 1:dcc17e5a913f 266 loop = false;
mahphalke 1:dcc17e5a913f 267 }
mahphalke 1:dcc17e5a913f 268 } while(loop);
mahphalke 1:dcc17e5a913f 269
mahphalke 1:dcc17e5a913f 270 return strtol(buf, NULL, 16);
mahphalke 1:dcc17e5a913f 271 }
mahphalke 1:dcc17e5a913f 272
mahphalke 1:dcc17e5a913f 273 /*!
mahphalke 1:dcc17e5a913f 274 * @brief Reads a floating string from the user
mahphalke 1:dcc17e5a913f 275 *
mahphalke 1:dcc17e5a913f 276 * @param input_len max number of character to accept from the user
mahphalke 1:dcc17e5a913f 277 *
Kjansen 5:052b9936f41f 278 * @return The float value entered
mahphalke 1:dcc17e5a913f 279 *
mahphalke 1:dcc17e5a913f 280 * @details Allows a user to type in number, echoing back to the user,
mahphalke 1:dcc17e5a913f 281 * up to input_len chars
mahphalke 1:dcc17e5a913f 282 *
mahphalke 1:dcc17e5a913f 283 * @note Only positive floating point numbers are supported currently
mahphalke 1:dcc17e5a913f 284 */
mahphalke 1:dcc17e5a913f 285 float adi_get_decimal_float(uint8_t input_len)
mahphalke 1:dcc17e5a913f 286 {
mahphalke 1:dcc17e5a913f 287 char buf[20] = { 0 };
mahphalke 1:dcc17e5a913f 288 uint8_t buf_index = 0;
mahphalke 1:dcc17e5a913f 289 char ch;
mahphalke 1:dcc17e5a913f 290 bool loop = true;
mahphalke 1:dcc17e5a913f 291
mahphalke 1:dcc17e5a913f 292 assert(input_len < 19);
mahphalke 1:dcc17e5a913f 293
mahphalke 1:dcc17e5a913f 294 do {
mahphalke 1:dcc17e5a913f 295 ch = getchar();
mahphalke 1:dcc17e5a913f 296 if ((isdigit(ch) || (ch == '.')) && buf_index < (input_len)) {
mahphalke 1:dcc17e5a913f 297 // echo and store it as buf not full
mahphalke 1:dcc17e5a913f 298 buf[buf_index++] = ch;
mahphalke 1:dcc17e5a913f 299 putchar(ch);
mahphalke 1:dcc17e5a913f 300 }
mahphalke 1:dcc17e5a913f 301 if ((ch == '\x7F') && (buf_index > 0)) {
mahphalke 1:dcc17e5a913f 302 //backspace and at least 1 char in buffer
mahphalke 1:dcc17e5a913f 303 buf[buf_index--] = '\x00';
mahphalke 1:dcc17e5a913f 304 putchar(ch);
mahphalke 1:dcc17e5a913f 305 }
mahphalke 1:dcc17e5a913f 306 if ((ch == '\x0D') || (ch == '\x0A')) {
mahphalke 1:dcc17e5a913f 307 // return key pressed, all done, null terminate string
mahphalke 1:dcc17e5a913f 308 buf[buf_index] = '\x00';
mahphalke 1:dcc17e5a913f 309 loop = false;
mahphalke 1:dcc17e5a913f 310 }
mahphalke 1:dcc17e5a913f 311 } while (loop);
mahphalke 1:dcc17e5a913f 312
mahphalke 1:dcc17e5a913f 313 return atof(buf);
mahphalke 1:dcc17e5a913f 314 }
mahphalke 1:dcc17e5a913f 315
Kjansen 5:052b9936f41f 316 /**
Kjansen 5:052b9936f41f 317 * @brief Handles the input from the user by displaying
Kjansen 5:052b9936f41f 318 * the menu message and provides a set number of
Kjansen 5:052b9936f41f 319 * input attempts for the user.
Kjansen 5:052b9936f41f 320 * @param menu_prompt[in] - User specified prompt.
Kjansen 5:052b9936f41f 321 * @param min_val[in] - minimum input value.
Kjansen 5:052b9936f41f 322 * @param max_val[in] - maximum input value.
Kjansen 5:052b9936f41f 323 * @param input_val[in, out] - User provided input value.
Kjansen 5:052b9936f41f 324 * @param clear_lines[in] - lines to clear in case of
Kjansen 5:052b9936f41f 325 invalid input.
Kjansen 5:052b9936f41f 326 * @return SUCCESS in case success. otherwise FAILURE
Kjansen 5:052b9936f41f 327 */
Kjansen 5:052b9936f41f 328 int32_t adi_handle_user_input(const char* menu_prompt,
Kjansen 5:052b9936f41f 329 uint16_t min_val,
Kjansen 5:052b9936f41f 330 uint16_t max_val,
Kjansen 5:052b9936f41f 331 uint16_t *input_val,
Kjansen 5:052b9936f41f 332 uint8_t max_attempts,
Kjansen 5:052b9936f41f 333 uint8_t clear_lines)
Kjansen 5:052b9936f41f 334 {
Kjansen 5:052b9936f41f 335 uint8_t count = 0;
Kjansen 5:052b9936f41f 336
Kjansen 5:052b9936f41f 337 if (menu_prompt == NULL || input_val == NULL) {
Kjansen 5:052b9936f41f 338 return FAILURE;
Kjansen 5:052b9936f41f 339 }
Kjansen 5:052b9936f41f 340
Kjansen 5:052b9936f41f 341 do {
Kjansen 5:052b9936f41f 342 /* Gets the input from the user and allows
Kjansen 5:052b9936f41f 343 * reattempts in-case of incorrect input */
Kjansen 5:052b9936f41f 344 printf("%s (%d - %d): ", menu_prompt, min_val, max_val);
Kjansen 5:052b9936f41f 345 *input_val = (uint16_t)adi_get_decimal_int(5);
Kjansen 5:052b9936f41f 346
Kjansen 5:052b9936f41f 347 if ((*input_val >= min_val) && (*input_val <= max_val)) {
Kjansen 5:052b9936f41f 348 // break out of the loop in-case of a correct input
Kjansen 5:052b9936f41f 349 break;
Kjansen 5:052b9936f41f 350 } else {
Kjansen 5:052b9936f41f 351 if (count == max_attempts) {
Kjansen 5:052b9936f41f 352 printf(EOL "Maximum try limit exceeded" EOL);
Kjansen 5:052b9936f41f 353 adi_press_any_key_to_continue();
Kjansen 5:052b9936f41f 354 return FAILURE;
Kjansen 5:052b9936f41f 355 }
Kjansen 5:052b9936f41f 356
Kjansen 5:052b9936f41f 357 printf(EOL "Please enter a valid selection" EOL);
Kjansen 5:052b9936f41f 358 adi_press_any_key_to_continue();
Kjansen 5:052b9936f41f 359 /* Moves up the cursor by specified lines and
Kjansen 5:052b9936f41f 360 * clears the lines below it */
Kjansen 5:052b9936f41f 361 for (uint8_t i = 0; i < clear_lines; i++) {
Kjansen 5:052b9936f41f 362 printf(VT100_CLEAR_CURRENT_LINE);
Kjansen 5:052b9936f41f 363 printf(VT100_MOVE_UP_N_LINES, 1);
Kjansen 5:052b9936f41f 364 }
Kjansen 5:052b9936f41f 365 }
Kjansen 5:052b9936f41f 366 } while (++count <= max_attempts);
Kjansen 5:052b9936f41f 367
Kjansen 5:052b9936f41f 368 return SUCCESS;
Kjansen 5:052b9936f41f 369 }
mahphalke 1:dcc17e5a913f 370
mahphalke 1:dcc17e5a913f 371 /*!
mahphalke 1:dcc17e5a913f 372 * @brief Clears the console terminal
mahphalke 1:dcc17e5a913f 373 *
mahphalke 1:dcc17e5a913f 374 * @details Clears the console terminal using VT100 escape code, or can be changed to
mahphalke 1:dcc17e5a913f 375 * output blank lines if serial link doesn't support VT100.
mahphalke 1:dcc17e5a913f 376 */
mahphalke 1:dcc17e5a913f 377 void adi_clear_console(void)
mahphalke 1:dcc17e5a913f 378 {
mahphalke 1:dcc17e5a913f 379 /*
mahphalke 1:dcc17e5a913f 380 * clear console and move cursor to home location, followed by move to home location.
mahphalke 1:dcc17e5a913f 381 * Dedicated call to move home is because sometimes first move home doesn't work
mahphalke 1:dcc17e5a913f 382 * \r\n required to flush the uart buffer.
mahphalke 1:dcc17e5a913f 383 */
mahphalke 4:ced4fa6875ed 384 printf(VT100_CLEAR_CONSOLE VT100_MOVE_TO_HOME EOL);
mahphalke 1:dcc17e5a913f 385
mahphalke 1:dcc17e5a913f 386 /*
mahphalke 1:dcc17e5a913f 387 * if VT100 is not supported, this can be enabled instead, but menu display may not work well
mahphalke 1:dcc17e5a913f 388 */
mahphalke 1:dcc17e5a913f 389 // for (uint8_t = 0; i < 100; i++)
mahphalke 1:dcc17e5a913f 390 // printf("\r\n\r");
mahphalke 1:dcc17e5a913f 391 }
mahphalke 1:dcc17e5a913f 392
Kjansen 5:052b9936f41f 393 /*!
Kjansen 5:052b9936f41f 394 * @brief Clears the error code from the last menu
Kjansen 5:052b9936f41f 395 *
Kjansen 5:052b9936f41f 396 * @details
Kjansen 5:052b9936f41f 397 */
Kjansen 5:052b9936f41f 398 void adi_clear_last_menu_error(void)
Kjansen 5:052b9936f41f 399 {
Kjansen 5:052b9936f41f 400 adi_console_menu_state.last_error_code = SUCCESS;
Kjansen 5:052b9936f41f 401 }
Kjansen 5:052b9936f41f 402
Kjansen 5:052b9936f41f 403 /*!
Kjansen 5:052b9936f41f 404 * @brief Returns the error code from the last menu
Kjansen 5:052b9936f41f 405 *
Kjansen 5:052b9936f41f 406 * @return The error code value
Kjansen 5:052b9936f41f 407 */
Kjansen 5:052b9936f41f 408 int32_t adi_get_last_menu_error(void)
Kjansen 5:052b9936f41f 409 {
Kjansen 5:052b9936f41f 410 return adi_console_menu_state.last_error_code;
Kjansen 5:052b9936f41f 411 }
mahphalke 1:dcc17e5a913f 412
mahphalke 1:dcc17e5a913f 413 /*!
mahphalke 1:dcc17e5a913f 414 * @brief waits for any key to be pressed, and displays a prompt to the user
mahphalke 1:dcc17e5a913f 415 *
mahphalke 1:dcc17e5a913f 416 * @details
mahphalke 1:dcc17e5a913f 417 */
mahphalke 1:dcc17e5a913f 418 void adi_press_any_key_to_continue(void)
mahphalke 1:dcc17e5a913f 419 {
mahphalke 1:dcc17e5a913f 420 printf("\r\nPress any key to continue...\r\n");
mahphalke 1:dcc17e5a913f 421 getchar();
mahphalke 1:dcc17e5a913f 422 }