]> begriffs open source - cmsis-driver-validation/blob - Tools/SPI_Server/Board/MCBSTM32F400/vio_MCBSTM32F400.c
Updated Readme with ref to use Doxygen 1.9.2
[cmsis-driver-validation] / Tools / SPI_Server / Board / MCBSTM32F400 / vio_MCBSTM32F400.c
1 /*
2  * Copyright (c) 2020 Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * -----------------------------------------------------------------------------
19  *
20  * Project:     SPI Server
21  * Title:       Virtual I/O (VIO) implementation for 
22  *              Keil MCBSTM32F400 evaluation board
23  *
24  * -----------------------------------------------------------------------------
25  */
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdarg.h>
30 #include "cmsis_os2.h"
31 #include "cmsis_compiler.h"
32 #include "cmsis_vio.h"
33
34 #if !defined(CMSIS_VOUT)
35 #include "Board_LED.h"                  // ::Board Support:LED
36 #include "Board_GLCD.h"                 // ::Board Support:Graphic LCD
37 #include "GLCD_Config.h"
38
39 extern GLCD_FONT GLCD_Font_6x8;
40 extern GLCD_FONT GLCD_Font_16x24;
41 #endif
42 #if !defined(CMSIS_VIN)
43 #include "Board_Buttons.h"              // ::Board Support:Buttons
44 #endif
45
46 // VIO input, output definitions
47 #define VIO_PRINT_MAX_SIZE      64U     // maximum size of print memory
48 #define VIO_PRINT_MEM_NUM        4U     // number of print memories
49 #define VIO_VALUE_NUM            3U     // number of values
50 #define VIO_VALUE_XYZ_NUM        3U     // number of XYZ values
51 #define VIO_IPV4_ADDRESS_NUM     2U     // number of IPv4 addresses
52 #define VIO_IPV6_ADDRESS_NUM     2U     // number of IPv6 addresses
53
54 // VIO input, output variables
55 __USED uint32_t      vioSignalIn;
56 __USED uint32_t      vioSignalOut;
57 __USED char          vioPrintMem[VIO_PRINT_MEM_NUM][VIO_PRINT_MAX_SIZE];
58 __USED int32_t       vioValue   [VIO_VALUE_NUM];
59 __USED vioValueXYZ_t vioValueXYZ[VIO_VALUE_XYZ_NUM];
60 __USED vioAddrIPv4_t vioAddrIPv4[VIO_IPV4_ADDRESS_NUM];
61 __USED vioAddrIPv6_t vioAddrIPv6[VIO_IPV6_ADDRESS_NUM];
62
63 static uint32_t       cursor_x;         // GLCD cursor x (horizontal) position (in pixels)
64 static uint32_t       cursor_y;         // GLCD cursor y (vertical)   position (in pixels)
65 static osMutexId_t    mid_GLCD;         // Mutex ID of GLCD mutex
66
67 // Initialize test input, output.
68 void vioInit (void) {
69
70   vioSignalIn  = 0U;
71   vioSignalOut = 0U;
72
73   memset (vioPrintMem, 0, sizeof(vioPrintMem));
74   memset (vioValue,    0, sizeof(vioValue));
75   memset (vioValueXYZ, 0, sizeof(vioValueXYZ));
76   memset (vioAddrIPv4, 0, sizeof(vioAddrIPv4));
77   memset (vioAddrIPv6, 0, sizeof(vioAddrIPv6));
78
79 #if !defined(CMSIS_VOUT)
80   (void)LED_Initialize();
81
82   mid_GLCD = osMutexNew(NULL);          // Create GLCD mutex
83   if (mid_GLCD != NULL) {
84     (void)GLCD_Initialize();
85     (void)GLCD_SetBackgroundColor(GLCD_COLOR_BLUE);
86     (void)GLCD_SetForegroundColor(GLCD_COLOR_WHITE);
87     (void)GLCD_ClearScreen();
88   }
89 #endif
90
91 #if !defined(CMSIS_VIN)
92   (void)Buttons_Initialize();
93 #endif
94 }
95
96 // Print formated string to test terminal.
97 int32_t vioPrint (uint32_t level, const char *format, ...) {
98   va_list args;
99   int32_t ret;
100
101 #if !defined(CMSIS_VOUT)
102   uint16_t cursor_x, cursor_y;          // GLCD cursor position (in pixels)
103   uint8_t  font_w, font_h;
104   uint8_t  i;
105   char     ch;
106 #endif
107
108   if (level > vioLevelError) {
109     return (-1);
110   }
111
112   if (level > VIO_PRINT_MEM_NUM) {
113     return (-1);
114   }
115
116   va_start(args, format);
117
118   ret = vsnprintf((char *)vioPrintMem[level], sizeof(vioPrintMem[level]), format, args);
119
120   va_end(args);
121
122 #if !defined(CMSIS_VOUT)
123   if (mid_GLCD != NULL) {
124     osMutexAcquire(mid_GLCD, osWaitForever);
125     switch (level) {
126       case vioLevelNone:                // Normal text
127         font_w   = GLCD_Font_6x8.width;
128         font_h   = GLCD_Font_6x8.height;
129         cursor_x = 0U;                  // Normal text starting position
130         cursor_y = 0U;                  // 1st text row
131         (void)GLCD_SetFont            (&GLCD_Font_6x8);
132         (void)GLCD_SetForegroundColor (GLCD_COLOR_WHITE);
133         break;
134       case vioLevelHeading:             // Heading text
135         font_w   = GLCD_Font_16x24.width;
136         font_h   = GLCD_Font_16x24.height;
137         cursor_x = 0U;                  // Heading text starting position
138         cursor_y = font_h;              // 2nd text row
139         (void)GLCD_SetFont            (&GLCD_Font_16x24);
140         (void)GLCD_SetForegroundColor (GLCD_COLOR_GREEN);
141         break;
142       case vioLevelMessage:             // Message text
143         font_w   = GLCD_Font_16x24.width;
144         font_h   = GLCD_Font_16x24.height;
145         cursor_x = 0U;                  // Message text starting position
146         cursor_y = font_h * 5U;         // 6th text row
147         (void)GLCD_SetFont            (&GLCD_Font_16x24);
148         (void)GLCD_SetForegroundColor (GLCD_COLOR_WHITE);
149         break;
150       case vioLevelError:               // Error text
151         font_w   = GLCD_Font_16x24.width;
152         font_h   = GLCD_Font_16x24.height;
153         cursor_x = 0U;                  // Error text starting position
154         cursor_y = font_h * 9U;         // 10th text row
155         (void)GLCD_SetFont            (&GLCD_Font_16x24);
156         (void)GLCD_SetForegroundColor (GLCD_COLOR_RED);
157         break;
158     }
159
160     i = 0U;
161     while (vioPrintMem[level][i] != 0) {
162       ch = vioPrintMem[level][i];
163       i++;
164
165       switch (ch) {
166         case 0x0A:                      // Line Feed ('\n')
167           cursor_y += font_h;
168           if (cursor_y >= GLCD_HEIGHT) {
169             // If cursor is out of screen vertically then rollover to vertical 0 
170             cursor_y = 0U;
171           }
172           break;
173         case 0x0D:                      // Carriage Return ('\r')
174           // Move the cursor to horizontal 0
175           cursor_x = 0U;
176           break;
177         default:                        // Any other character
178           // Display current character at the cursor position
179           (void)GLCD_DrawChar(cursor_x, cursor_y, ch);
180           // Move the cursor to the next character on the right
181           cursor_x += font_w;
182           if (cursor_x >= GLCD_WIDTH) {
183             // If cursor is out of screen horizontally then rollover to horizontal 0
184             // and into new line
185             cursor_x  = 0U;
186             cursor_y += font_h;
187             if (cursor_y >= GLCD_HEIGHT) {
188               // If cursor is out of screen vertically then rollover to vertical 0
189               cursor_y = 0U;
190             }
191           }
192           break;
193       }
194     }
195
196     osMutexRelease(mid_GLCD);
197   }
198 #endif
199
200   return (ret);
201 }
202
203 // Set signal output.
204 void vioSetSignal (uint32_t mask, uint32_t signal) {
205
206   vioSignalOut &= ~mask;
207   vioSignalOut |=  mask & signal;
208
209 #if !defined(CMSIS_VOUT)
210   (void)LED_SetOut(mask & signal);
211 #endif
212 }
213
214 // Get signal input.
215 uint32_t vioGetSignal (uint32_t mask) {
216   uint32_t signal;
217
218 #if !defined(CMSIS_VIN)
219   vioSignalIn = Buttons_GetState();
220 #endif
221   signal = vioSignalIn;
222
223   return (signal & mask);
224 }
225
226 // Set value output.
227 void vioSetValue (uint32_t id, int32_t value) {
228   uint32_t index = id;
229
230   if (index >= VIO_VALUE_NUM) {
231     return;                             /* return in case of out-of-range index */
232   }
233
234   vioValue[index] = value;
235 }
236
237 // Get value input.
238 int32_t vioGetValue (uint32_t id) {
239   uint32_t index = id;
240   int32_t  value = 0;
241
242   if (index >= VIO_VALUE_NUM) {
243     return value;                       /* return default in case of out-of-range index */
244   }
245
246   value = vioValue[index];
247
248   return value;
249 }
250
251 // Set XYZ value output.
252 void vioSetXYZ (uint32_t id, vioValueXYZ_t valueXYZ) {
253   uint32_t index = id;
254
255   if (index >= VIO_VALUE_XYZ_NUM) {
256     return;                             /* return in case of out-of-range index */
257   }
258
259   vioValueXYZ[index] = valueXYZ;
260 }
261
262 // Get XYZ value input.
263 vioValueXYZ_t vioGetXYZ (uint32_t id) {
264   uint32_t index = id;
265   vioValueXYZ_t valueXYZ = {0, 0, 0};
266
267   if (index >= VIO_VALUE_XYZ_NUM) {
268     return valueXYZ;                    /* return default in case of out-of-range index */
269   }
270
271   valueXYZ = vioValueXYZ[index];
272
273   return valueXYZ;
274 }
275
276 // Set IPv4 address output.
277 void vioSetIPv4 (uint32_t id, vioAddrIPv4_t addrIPv4) {
278   uint32_t index = id;
279
280   if (index >= VIO_IPV4_ADDRESS_NUM) {
281     return;                             /* return in case of out-of-range index */
282   }
283
284   vioAddrIPv4[index] = addrIPv4;
285 }
286
287 // Get IPv4 address input.
288 vioAddrIPv4_t vioGetIPv4 (uint32_t id) {
289   uint32_t index = id;
290   vioAddrIPv4_t addrIPv4 = {0U, 0U, 0U, 0U};
291
292   if (index >= VIO_IPV4_ADDRESS_NUM) {
293     return addrIPv4;                    /* return default in case of out-of-range index */
294   }
295
296   addrIPv4 = vioAddrIPv4[index];
297
298   return addrIPv4;
299 }
300
301 // Set IPv6 address output.
302 void vioSetIPv6 (uint32_t id, vioAddrIPv6_t addrIPv6) {
303   uint32_t index = id;
304
305   if (index >= VIO_IPV6_ADDRESS_NUM) {
306     return;                             /* return in case of out-of-range index */
307   }
308
309   vioAddrIPv6[index] = addrIPv6;
310 }
311
312 // Get IPv6 address input.
313 vioAddrIPv6_t vioGetIPv6 (uint32_t id) {
314   uint32_t index = id;
315   vioAddrIPv6_t addrIPv6 = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,
316                             0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U};
317
318   if (index >= VIO_IPV6_ADDRESS_NUM) {
319     return addrIPv6;                    /* return default in case of out-of-range index */
320   }
321
322   addrIPv6 = vioAddrIPv6[index];
323
324   return addrIPv6;
325 }