1/*
2 * Copyright (c) 2007-2015 Freescale Semiconductor, Inc.
3 * Copyright 2018-2020 NXP
4 *
5 * License: NXP LA_OPT_NXP_Software_License
6 *
7 * NXP Confidential. This software is owned or controlled by NXP and may
8 * only be used strictly in accordance with the applicable license terms.
9 * By expressly accepting such terms or by downloading, installing,
10 * activating and/or otherwise using the software, you are agreeing that
11 * you have read, and that you agree to comply with and are bound by,
12 * such license terms. If you do not agree to be bound by the applicable
13 * license terms, then you may not retain, install, activate or otherwise
14 * use the software. This code may only be used in a microprocessor,
15 * microcontroller, sensor or digital signal processor ("NXP Product")
16 * supplied directly or indirectly from NXP. See the full NXP Software
17 * License Agreement in license/LA_OPT_NXP_Software_License.pdf
18 *
19 * FreeMASTER Communication Driver - Oscilloscope implementation
20 */
21
22#include "freemaster.h"
23#include "freemaster_private.h"
24#include "freemaster_protocol.h"
25#include "freemaster_utils.h"
26
27#if FMSTR_USE_SCOPE > 0 && FMSTR_DISABLE == 0
28
29/********************************************************
30 * local macros definition
31 ********************************************************/
32/* Define Protocol operations*/
33#define FMSTR_SCOPE_PRTCLSET_OP_CFGMEM 0x01 /* Set number of recorder variables */
34#define FMSTR_SCOPE_PRTCLSET_OP_CFGVAR 0x02 /* Setup address and size of one scope variable */
35
36/********************************************************
37 * local types definition
38 ********************************************************/
39
40/* Scope instance definition */
41typedef struct
42{
43 FMSTR_U8 varCnt; /* number of active scope variables */
44 FMSTR_ADDR varAddr[FMSTR_MAX_SCOPE_VARS]; /* addresses of scope variables */
45 FMSTR_U8 varSize[FMSTR_MAX_SCOPE_VARS]; /* sizes of scope variables */
46} FMSTR_SCOPE;
47
48/********************************************************
49 * local static functions declarations
50 ********************************************************/
51static FMSTR_U8 _FMSTR_SetScope_CFGMEM(FMSTR_BPTR msgBuffIO, FMSTR_SCOPE *scope);
52static FMSTR_U8 _FMSTR_SetScope_CFGVAR(FMSTR_BPTR msgBuffIO, FMSTR_SCOPE *scope, FMSTR_U8 opLen);
53
54/***********************************
55 * local variables
56 ***********************************/
57static FMSTR_SCOPE fmstr_scopeCfg[FMSTR_USE_SCOPE]; /* Container of all scopes configurations*/
58
59/******************************************************************************
60 *
61 * @brief Scope Initialization
62 *
63 ******************************************************************************/
64
65FMSTR_BOOL FMSTR_InitScope(void)
66{
67 FMSTR_MemSet(fmstr_scopeCfg, 0, sizeof(fmstr_scopeCfg));
68 return FMSTR_TRUE;
69}
70
71/******************************************************************************
72 *
73 * @brief Handling FMSTR_CMD_SETSCOPE Memory configuration command
74 *
75 * @param msgBuffIO - original command (in) and response buffer (out)
76 * @param scope - pointer to scope configuration
77 *
78 * @return status of operation usable in protocol
79 *
80 ******************************************************************************/
81
82static FMSTR_U8 _FMSTR_SetScope_CFGMEM(FMSTR_BPTR msgBuffIO, FMSTR_SCOPE *scope)
83{
84 FMSTR_U8 varCnt;
85
86 /* Get the active variables count of Scope Instance */
87 (void)FMSTR_ValueFromBuffer8(&varCnt, msgBuffIO);
88
89 if (varCnt > (FMSTR_U8)FMSTR_MAX_SCOPE_VARS)
90 {
91 return FMSTR_STC_INVSIZE;
92 }
93
94 /* Initialize the scope configuration */
95 FMSTR_MemSet(scope, 0, sizeof(*scope));
96 scope->varCnt = varCnt;
97
98 return FMSTR_STS_OK;
99}
100
101/******************************************************************************
102 *
103 * @brief API: Set up the recorder variable configuration (internal version)
104 *
105 * @param recIx - index of recorder
106 * @param recCfg - pointer to recorder configuration
107 *
108 *
109 ******************************************************************************/
110
111static FMSTR_U8 _FMSTR_SetScope_CFGVAR(FMSTR_BPTR msgBuffIO, FMSTR_SCOPE *scope, FMSTR_U8 opLen)
112{
113 FMSTR_BPTR msgBuffIOStart = msgBuffIO;
114 FMSTR_U8 varIx;
115 FMSTR_ADDR addr;
116 FMSTR_U8 size;
117
118 /* Get the variable index */
119 msgBuffIO = FMSTR_ValueFromBuffer8(&varIx, msgBuffIO);
120 /* Get the variable address */
121 msgBuffIO = FMSTR_AddressFromBuffer(&addr, msgBuffIO);
122 /* Get the variable size */
123 msgBuffIO = FMSTR_ValueFromBuffer8(&size, msgBuffIO);
124
125 /* Decoded ULEBs should match the expected op_data length */
126 if (msgBuffIO != (msgBuffIOStart + opLen))
127 {
128 return FMSTR_STC_INVSIZE;
129 }
130
131 /* Check the variable index */
132 if (varIx >= scope->varCnt)
133 {
134 return FMSTR_STC_INVBUFF;
135 }
136
137 /* Valid numeric variable sizes only */
138 if ((size != 1U) && (size != 2U) && (size != 4U) && (size != 8U))
139 {
140 return FMSTR_STC_INVSIZE;
141 }
142
143 /* Check the TSA safety */
144#if FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY
145 if (FMSTR_CheckTsaSpace(addr, size, FMSTR_FALSE) == FMSTR_FALSE)
146 {
147 return FMSTR_STC_EACCESS;
148 }
149#endif /* FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY */
150
151 /* Store the variable configuration */
152 scope->varAddr[varIx] = addr;
153 scope->varSize[varIx] = size;
154
155 return FMSTR_STS_OK;
156}
157
158/******************************************************************************
159 *
160 * @brief Handling SETUPSCOPE command
161 *
162 * @param session - transport session
163 * @param msgBuffIO - original command (in) and response buffer (out)
164 * @param inputLen - Count of received bytes in input buffer
165 * @param retStatus - pointer to return status variable
166 *
167 * @return As all command handlers, the return value should be the buffer
168 * pointer where the response output finished (except checksum)
169 *
170 ******************************************************************************/
171
172FMSTR_BPTR FMSTR_SetScope(FMSTR_SESSION *session, FMSTR_BPTR msgBuffIO, FMSTR_SIZE inputLen, FMSTR_U8 *retStatus)
173{
174 FMSTR_SCOPE *scope;
175 FMSTR_BPTR response = msgBuffIO;
176 FMSTR_U8 responseCode = FMSTR_STS_OK;
177 FMSTR_U8 scopeIndex;
178
179 /* Get recerder index */
180 msgBuffIO = FMSTR_ValueFromBuffer8(&scopeIndex, msgBuffIO);
181 inputLen--;
182
183 if (scopeIndex >= (FMSTR_U8)FMSTR_USE_SCOPE)
184 {
185 *retStatus = FMSTR_STC_INSTERR;
186 return response;
187 }
188
189#if FMSTR_SESSION_COUNT > 1
190 /* Is feature locked by me */
191 if (FMSTR_IsFeatureOwned(session, FMSTR_FEATURE_SCOPE, scopeIndex) == FMSTR_FALSE)
192 {
193 *retStatus = FMSTR_STC_SERVBUSY;
194 return response;
195 }
196#endif
197
198 scope = &fmstr_scopeCfg[scopeIndex];
199
200 while (inputLen != 0U && (responseCode == FMSTR_STS_OK))
201 {
202 FMSTR_U8 opCode, opLen;
203
204 /* Get Operation Code and data length */
205 msgBuffIO = FMSTR_ValueFromBuffer8(&opCode, msgBuffIO);
206 msgBuffIO = FMSTR_ValueFromBuffer8(&opLen, msgBuffIO);
207
208 if ((opLen + 2U) > inputLen)
209 {
210 *retStatus = FMSTR_STC_INVSIZE;
211 return response;
212 }
213
214 switch (opCode)
215 {
216 /* Configure scope memory */
217 case FMSTR_SCOPE_PRTCLSET_OP_CFGMEM:
218 responseCode = _FMSTR_SetScope_CFGMEM(msgBuffIO, scope);
219 break;
220
221 /* Configure variable */
222 case FMSTR_SCOPE_PRTCLSET_OP_CFGVAR:
223 responseCode = _FMSTR_SetScope_CFGVAR(msgBuffIO, scope, opLen);
224 break;
225
226 default:
227 responseCode = FMSTR_STC_INVCMD;
228 break;
229 }
230
231 inputLen -= opLen + 2U;
232 msgBuffIO += opLen;
233 }
234
235 *retStatus = responseCode;
236 return response;
237}
238
239/******************************************************************************
240 *
241 * @brief Handling READSCOPE command
242 *
243 * @param session - transport session
244 * @param msgBuffIO - original command (in) and response buffer (out)
245 * @param retStatus - pointer to return status variable
246 * @param maxOutSize - Maximal size of output data
247 *
248 * @return As all command handlers, the return value should be the buffer
249 * pointer where the response output finished (except checksum)
250 *
251 ******************************************************************************/
252
253FMSTR_BPTR FMSTR_ReadScope(FMSTR_SESSION *session, FMSTR_BPTR msgBuffIO, FMSTR_U8 *retStatus, FMSTR_SIZE maxOutSize)
254{
255 FMSTR_U8 i;
256 FMSTR_U8 scopeIndex;
257 FMSTR_SCOPE *scope;
258 FMSTR_BPTR msgBuffIOStart = msgBuffIO;
259
260 /* Get recerder index */
261 (void)FMSTR_ValueFromBuffer8(&scopeIndex, msgBuffIO);
262
263 /* Check the index of scope if it fits to configuration */
264 if (scopeIndex >= (FMSTR_U8)FMSTR_USE_SCOPE)
265 {
266 *retStatus = FMSTR_STC_INSTERR;
267 return msgBuffIO;
268 }
269
270#if FMSTR_SESSION_COUNT > 1
271 /* Is feature locked by me */
272 if (FMSTR_IsFeatureOwned(session, FMSTR_FEATURE_SCOPE, scopeIndex) == FMSTR_FALSE)
273 {
274 *retStatus = FMSTR_STC_SERVBUSY;
275 return msgBuffIO;
276 }
277#endif
278
279 /* Get the scope */
280 scope = &fmstr_scopeCfg[scopeIndex];
281
282 /* Check if there are defined some variables */
283 if (scope->varCnt == 0U)
284 {
285 *retStatus = FMSTR_STC_NOTINIT;
286 return msgBuffIO;
287 }
288
289 /* Copy all variables into the output buffer */
290 for (i = 0U; i < scope->varCnt; i++)
291 {
292 /* Check the size of output buffer */
293 if (maxOutSize < scope->varSize[i])
294 {
295 *retStatus = FMSTR_STC_INVSIZE;
296 return msgBuffIOStart;
297 }
298 maxOutSize -= scope->varSize[i];
299
300 /* Copy variable */
301 msgBuffIO = FMSTR_CopyToBuffer(msgBuffIO, scope->varAddr[i], scope->varSize[i]);
302 }
303
304 *retStatus = FMSTR_STS_OK;
305
306 /* return end position */
307 return msgBuffIO;
308}
309
310#endif /* (FMSTR_USE_SCOPE) && !(FMSTR_DISABLE) */
311