bsp.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*****************************************************************************
  2. * Product: Board Support Package (BSP) for the Calculator example
  3. * Last updated for version 6.9.0
  4. * Last updated on 2020-06-24
  5. *
  6. * Q u a n t u m L e a P s
  7. * ------------------------
  8. * Modern Embedded Software
  9. *
  10. * Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
  11. *
  12. * This program is open source software: you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License as published
  14. * by the Free Software Foundation, either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * Alternatively, this program may be distributed and modified under the
  18. * terms of Quantum Leaps commercial licenses, which expressly supersede
  19. * the GNU General Public License and are specifically designed for
  20. * licensees interested in retaining the proprietary status of their code.
  21. *
  22. * This program is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. * GNU General Public License for more details.
  26. *
  27. * You should have received a copy of the GNU General Public License
  28. * along with this program. If not, see <www.gnu.org/licenses/>.
  29. *
  30. * Contact information:
  31. * <www.state-machine.com/licensing>
  32. * <info@state-machine.com>
  33. *****************************************************************************/
  34. #include "qpc.h"
  35. #include "bsp.h"
  36. #include "safe_std.h" /* portable "safe" <stdio.h>/<string.h> facilities */
  37. #include <stdlib.h> /* for exit() */
  38. #define DISP_WIDTH 15
  39. /* helper macros to "stringify" values */
  40. #define VAL(x) #x
  41. #define STRINGIFY(x) VAL(x)
  42. static char l_display[DISP_WIDTH + 1]; /* the calculator display */
  43. static int l_len; /* number of displayed characters */
  44. /*..........................................................................*/
  45. void BSP_clear(void) {
  46. memset(l_display, ' ', DISP_WIDTH - 1);
  47. l_display[DISP_WIDTH - 1] = '0';
  48. l_display[DISP_WIDTH] = '\0';
  49. l_len = 0;
  50. }
  51. /*..........................................................................*/
  52. void BSP_insert(int keyId) {
  53. if (l_len == 0) {
  54. l_display[DISP_WIDTH - 1] = (char)keyId;
  55. ++l_len;
  56. }
  57. else if (l_len < (DISP_WIDTH - 1)) {
  58. MEMMOVE_S(&l_display[0], DISP_WIDTH, &l_display[1], DISP_WIDTH - 1);
  59. l_display[DISP_WIDTH - 1] = (char)keyId;
  60. ++l_len;
  61. }
  62. }
  63. /*..........................................................................*/
  64. void BSP_negate(void) {
  65. BSP_clear();
  66. l_display[DISP_WIDTH - 2] = '-';
  67. }
  68. /*..........................................................................*/
  69. void BSP_display(void) {
  70. PRINTF_S("\n[%" STRINGIFY(DISP_WIDTH) "s] ", l_display);
  71. }
  72. /*..........................................................................*/
  73. void BSP_exit(void) {
  74. PRINTF_S("\n%s\n", "Bye! Bye!");
  75. fflush(stdout);
  76. QF_onCleanup();
  77. exit(0);
  78. }
  79. /*..........................................................................*/
  80. double BSP_get_value(void) {
  81. return strtod(l_display, (char **)0);
  82. }
  83. /*..........................................................................*/
  84. int BSP_eval(double operand1, int oper, double operand2) {
  85. int ok = 1;
  86. double result = 0.0;
  87. switch (oper) {
  88. case KEY_PLUS: {
  89. result = operand1 + operand2;
  90. break;
  91. }
  92. case KEY_MINUS: {
  93. result = operand1 - operand2;
  94. break;
  95. }
  96. case KEY_MULT: {
  97. result = operand1 * operand2;
  98. break;
  99. }
  100. case KEY_DIVIDE: {
  101. if ((operand2 < -1e-30) || (1e-30 < operand2)) {
  102. result = operand1 / operand2;
  103. }
  104. else {
  105. /* error: divide by zero */
  106. STRNCPY_S(l_display, DISP_WIDTH, " Error 0 ");
  107. ok = 0;
  108. }
  109. break;
  110. }
  111. }
  112. if (ok) {
  113. if ((-0.000001 < result) && (result < 0.000001)) {
  114. result = 0.0;
  115. }
  116. if ((-99999999.0 < result) && (result < 99999999.0)) {
  117. SNPRINTF_S(l_display, DISP_WIDTH, "%10.7g", result);
  118. }
  119. else {
  120. /* error: out of range */
  121. STRNCPY_S(l_display, DISP_WIDTH, " Error 1 ");
  122. ok = 0;
  123. }
  124. }
  125. return ok;
  126. }
  127. /*..........................................................................*/
  128. void BSP_message(char const *msg) {
  129. PRINTF_S("%s", msg);
  130. }
  131. /*..........................................................................*/
  132. void QF_onStartup(void) {
  133. QF_consoleSetup();
  134. }
  135. /*..........................................................................*/
  136. void QF_onCleanup(void) {
  137. QF_consoleCleanup();
  138. }
  139. /*..........................................................................*/
  140. void QF_onClockTick(void) {
  141. }
  142. /*..........................................................................*/
  143. /* this function is used by the QP embedded systems-friendly assertions */
  144. Q_NORETURN Q_onAssert(char const * const module, int_t const loc) {
  145. FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc);
  146. QF_onCleanup();
  147. exit(-1);
  148. }