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 */ |
41 | typedef 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 | ********************************************************/ |
51 | static FMSTR_U8 _FMSTR_SetScope_CFGMEM(FMSTR_BPTR msgBuffIO, FMSTR_SCOPE *scope); |
52 | static FMSTR_U8 _FMSTR_SetScope_CFGVAR(FMSTR_BPTR msgBuffIO, FMSTR_SCOPE *scope, FMSTR_U8 opLen); |
53 | |
54 | /*********************************** |
55 | * local variables |
56 | ***********************************/ |
57 | static FMSTR_SCOPE fmstr_scopeCfg[FMSTR_USE_SCOPE]; /* Container of all scopes configurations*/ |
58 | |
59 | /****************************************************************************** |
60 | * |
61 | * @brief Scope Initialization |
62 | * |
63 | ******************************************************************************/ |
64 | |
65 | FMSTR_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 | |
82 | static 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 | |
111 | static 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 | |
172 | FMSTR_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 | |
253 | FMSTR_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 | |