1 /*------------------------------------------------------------------------------------------------*/
2 /* UNICENS V2.1.0-3491 */
3 /* Copyright (c) 2017 Microchip Technology Germany II GmbH & Co. KG. */
5 /* This program is free software: you can redistribute it and/or modify */
6 /* it under the terms of the GNU General Public License as published by */
7 /* the Free Software Foundation, either version 2 of the License, or */
8 /* (at your option) any later version. */
10 /* This program is distributed in the hope that it will be useful, */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
13 /* GNU General Public License for more details. */
15 /* You should have received a copy of the GNU General Public License */
16 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 /* You may also obtain this software under a propriety license from Microchip. */
19 /* Please contact Microchip for further information. */
20 /*------------------------------------------------------------------------------------------------*/
24 * \brief Implementation of the BackChannel Diagnosis.
26 * \cond UCS_INTERNAL_DOC
27 * \addtogroup G_BACKCHANNEL_DIAG
32 /*------------------------------------------------------------------------------------------------*/
34 /*------------------------------------------------------------------------------------------------*/
35 #include "ucs_inic_pb.h"
36 #include "ucs_bc_diag.h"
40 /*------------------------------------------------------------------------------------------------*/
41 /* Internal constants */
42 /*------------------------------------------------------------------------------------------------*/
43 #define BCD_NUM_STATES 7U /*!< \brief Number of state machine states */
44 #define BCD_NUM_EVENTS 12U /*!< \brief Number of state machine events */
46 #define BCD_TIMEOUT_COMMAND 100U /*!< \brief supervise EXC commands */
48 #define BCD_SIGNATURE_VERSION 1U /*!< \brief signature version used for BackChannel Diagnosis */
50 #define BCD_T_SEND 0x0100U
51 #define BCD_T_WAIT4DUT 0x1000U
52 #define BCD_T_SWITCH 0x0100U
53 #define BCD_T_BACK 0x2000U
54 #define BCD_TIMEOUT2 0x3000U
55 #define BCD_T_SIGNAL_ON 100U
56 #define BCD_T_LOCK 100U
57 #define BCD_T_LIGHT_PROGRESS 20U
58 #define BCD_AUTOBACK (true)
59 #define ADMIN_BASE_ADDR 0x0F00U
61 /*------------------------------------------------------------------------------------------------*/
62 /* Service parameters */
63 /*------------------------------------------------------------------------------------------------*/
64 /*! Priority of the BackChannel Diagnosis used by scheduler */
65 static const uint8_t BCD_SRV_PRIO = 248U; /* parasoft-suppress MISRA2004-8_7 "Value shall be part of the module, not part of a function." */
66 /*! Main event for the BackChannel Diagnosis */
67 static const Srv_Event_t BCD_EVENT_SERVICE = 1U;
70 /*------------------------------------------------------------------------------------------------*/
71 /* Internal enumerators */
72 /*------------------------------------------------------------------------------------------------*/
73 /*! \brief Possible events of the BackChannel Diagnosis state machine */
74 typedef enum Bcd_Events_
76 BCD_E_NIL = 0U, /*!< \brief NIL Event */
77 BCD_E_START = 1U, /*!< \brief API start command was called. */
78 BCD_E_DIAGMODE_END = 2U, /*!< \brief INIC.BCDiagEnd.Result successful. */
79 BCD_E_DIAG_MODE_STARTED = 3U, /*!< \brief INIC.BCDiag.Result successful. */
80 BCD_E_DIAG_MODE_FAILED = 4U, /*!< \brief INIC.BCDiag.Error received. */
81 BCD_E_TX_ENABLE_SUCCESS = 5U, /*!< \brief EXC.BCEnableTx successful */
82 BCD_E_TX_ENABLE_FAILED = 6U, /*!< \brief EXC.BCEnableTx failed. */
83 BCD_E_DIAG_RESULT_OK = 7U, /*!< \brief EXC.BCDIAG.Result Ok received. */
84 BCD_E_DIAG_RESULT_NOTOK = 8U, /*!< \brief EXC.BCDIAG.Result NotOk received. */
85 BCD_E_NET_OFF = 9U, /*!< \brief NetOff occurred. */
86 BCD_E_TIMEOUT = 10U, /*!< \brief Timeout occurred. */
87 BCD_E_ERROR = 11U /*!< \brief An unexpected error occurred. */
92 /*! \brief States of the BackChannel Diagnosis state machine */
93 typedef enum Bcd_State_
95 BCD_S_IDLE = 0U, /*!< \brief Idle state */
96 BCD_S_STARTED = 1U, /*!< \brief BackChannel Diagnosis started */
97 BCD_S_WAIT_ENABLED = 2U, /*!< \brief Wait for BCEnableTx.Result */
98 BCD_S_WAIT_SIG_PROP = 3U, /*!< \brief Wait for signal propagating through the following nodes */
99 BCD_S_WAIT_SIGNAL_ON = 4U, /*!< \brief Wait for t_SignalOn to expire. */
100 BCD_S_WAIT_RESULT = 5U, /*!< \brief Wait for ENC.BCDiag.Result */
101 BCD_S_END = 6U /*!< \brief BackChannel Diagnosis ends. */
105 /*------------------------------------------------------------------------------------------------*/
106 /* Internal prototypes */
107 /*------------------------------------------------------------------------------------------------*/
108 static void Bcd_Service(void *self);
110 static void Bcd_InicBcdStartCb(void *self, void *result_ptr);
111 static void Bcd_EnableTxResultCb(void *self, void *result_ptr);
112 static void Bcd_DiagnosisResultCb(void *self, void *result_ptr);
113 static void Bcd_InicBcdEndCb(void *self, void *result_ptr);
115 static void Bcd_OnTerminateEventCb(void *self, void *result_ptr);
116 static void Bcd_NetworkStatusCb(void *self, void *result_ptr);
118 static void Bcd_A_Start(void *self);
119 static void Bcd_A_EnableTx(void *self);
120 static void Bcd_A_DiagStart(void *self);
121 static void Bcd_A_NextSeg(void *self);
122 static void Bcd_A_StopDiag(void *self);
123 static void Bcd_A_Error(void *self);
124 static void Bcd_A_EndDiag(void *self);
125 static void Bcd_A_Timeout2(void *self);
126 static void Bcd_A_WaitLight(void *self);
129 static Ucs_Return_t Bcd_EnableTx(void *self, uint8_t port);
131 static void Bcd_TimerCb(void *self);
133 /*------------------------------------------------------------------------------------------------*/
134 /* State transition table (used by finite state machine) */
135 /*------------------------------------------------------------------------------------------------*/
136 /*! \brief State transition table */
137 static const Fsm_StateElem_t bcd_trans_tab[BCD_NUM_STATES][BCD_NUM_EVENTS] = /* parasoft-suppress MISRA2004-8_7 "Value shall be part of the module, not part of a function." */
139 { /* State BCD_S_IDLE */
140 /* BCD_E_NIL */ {NULL, BCD_S_IDLE },
141 /* BCD_E_START */ {Bcd_A_Start, BCD_S_STARTED },
142 /* BCD_E_DIAGMODE_END */ {NULL, BCD_S_IDLE },
143 /* BCD_E_DIAG_MODE_STARTED */ {NULL, BCD_S_IDLE },
144 /* BCD_E_DIAG_MODE_FAILED */ {NULL, BCD_S_IDLE },
145 /* BCD_E_TX_ENABLE_SUCCESS */ {NULL, BCD_S_IDLE },
146 /* BCD_E_TX_ENABLE_FAILED */ {NULL, BCD_S_IDLE },
147 /* BCD_E_DIAG_RESULT_OK */ {NULL, BCD_S_IDLE },
148 /* BCD_E_DIAG_RESULT_NOTOK */ {NULL, BCD_S_IDLE },
149 /* BCD_E_NET_OFF */ {NULL, BCD_S_IDLE },
150 /* BCD_E_TIMEOUT */ {NULL, BCD_S_IDLE },
151 /* BCD_E_ERROR */ {NULL, BCD_S_IDLE }
153 { /* State BCD_S_STARTED */
154 /* BCD_E_NIL */ {NULL, BCD_S_STARTED },
155 /* BCD_E_START */ {NULL, BCD_S_STARTED },
156 /* BCD_E_DIAGMODE_END */ {NULL, BCD_S_STARTED },
157 /* BCD_E_DIAG_MODE_STARTED */ {Bcd_A_EnableTx, BCD_S_WAIT_ENABLED },
158 /* BCD_E_DIAG_MODE_FAILED */ {NULL, BCD_S_STARTED },
159 /* BCD_E_TX_ENABLE_SUCCESS */ {NULL, BCD_S_STARTED },
160 /* BCD_E_TX_ENABLE_FAILED */ {NULL, BCD_S_STARTED },
161 /* BCD_E_DIAG_RESULT_OK */ {NULL, BCD_S_STARTED },
162 /* BCD_E_DIAG_RESULT_NOTOK */ {NULL, BCD_S_STARTED },
163 /* BCD_E_NET_OFF */ {NULL, BCD_S_STARTED },
164 /* BCD_E_TIMEOUT */ {Bcd_A_Timeout2, BCD_S_IDLE },
165 /* BCD_E_ERROR */ {Bcd_A_Error, BCD_S_IDLE }
167 { /* State BCD_S_WAIT_ENABLED */
168 /* BCD_E_NIL */ {NULL, BCD_S_WAIT_ENABLED },
169 /* BCD_E_START */ {NULL, BCD_S_WAIT_ENABLED },
170 /* BCD_E_DIAGMODE_END */ {NULL, BCD_S_WAIT_ENABLED },
171 /* BCD_E_DIAG_MODE_STARTED */ {NULL, BCD_S_WAIT_ENABLED },
172 /* BCD_E_DIAG_MODE_FAILED */ {NULL, BCD_S_WAIT_ENABLED },
173 /* BCD_E_TX_ENABLE_SUCCESS */ {Bcd_A_WaitLight, BCD_S_WAIT_SIG_PROP },
174 /* BCD_E_TX_ENABLE_FAILED */ {Bcd_A_Error, BCD_S_IDLE },
175 /* BCD_E_DIAG_RESULT_OK */ {NULL, BCD_S_WAIT_ENABLED },
176 /* BCD_E_DIAG_RESULT_NOTOK */ {NULL, BCD_S_WAIT_ENABLED },
177 /* BCD_E_NET_OFF */ {NULL, BCD_S_WAIT_ENABLED },
178 /* BCD_E_TIMEOUT */ {Bcd_A_Timeout2, BCD_S_IDLE },
179 /* BCD_E_ERROR */ {Bcd_A_Error, BCD_S_IDLE }
181 { /* State BCD_S_WAIT_SIG_PROP */
182 /* BCD_E_NIL */ {NULL, BCD_S_WAIT_SIG_PROP },
183 /* BCD_E_START */ {NULL, BCD_S_WAIT_SIG_PROP },
184 /* BCD_E_DIAGMODE_END */ {NULL, BCD_S_WAIT_SIG_PROP },
185 /* BCD_E_DIAG_MODE_STARTED */ {NULL, BCD_S_WAIT_SIG_PROP },
186 /* BCD_E_DIAG_MODE_FAILED */ {NULL, BCD_S_WAIT_SIG_PROP },
187 /* BCD_E_TX_ENABLE_SUCCESS */ {NULL, BCD_S_WAIT_SIG_PROP },
188 /* BCD_E_TX_ENABLE_FAILED */ {NULL, BCD_S_WAIT_SIG_PROP },
189 /* BCD_E_DIAG_RESULT_OK */ {NULL, BCD_S_WAIT_SIG_PROP },
190 /* BCD_E_DIAG_RESULT_NOTOK */ {NULL, BCD_S_WAIT_SIG_PROP },
191 /* BCD_E_NET_OFF */ {NULL, BCD_S_WAIT_SIG_PROP },
192 /* BCD_E_TIMEOUT */ {Bcd_A_DiagStart, BCD_S_WAIT_RESULT },
193 /* BCD_E_ERROR */ {Bcd_A_Error, BCD_S_IDLE }
195 { /* State BCD_S_WAIT_SIGNAL_ON */
196 /* BCD_E_NIL */ {NULL, BCD_S_WAIT_SIGNAL_ON },
197 /* BCD_E_START */ {NULL, BCD_S_WAIT_SIGNAL_ON },
198 /* BCD_E_DIAGMODE_END */ {NULL, BCD_S_WAIT_SIGNAL_ON },
199 /* BCD_E_DIAG_MODE_STARTED */ {NULL, BCD_S_WAIT_SIGNAL_ON },
200 /* BCD_E_DIAG_MODE_FAILED */ {NULL, BCD_S_WAIT_SIGNAL_ON },
201 /* BCD_E_TX_ENABLE_SUCCESS */ {NULL, BCD_S_WAIT_SIGNAL_ON },
202 /* BCD_E_TX_ENABLE_FAILED */ {NULL, BCD_S_WAIT_SIGNAL_ON },
203 /* BCD_E_DIAG_RESULT_OK */ {NULL, BCD_S_WAIT_SIGNAL_ON },
204 /* BCD_E_DIAG_RESULT_NOTOK */ {NULL, BCD_S_WAIT_SIGNAL_ON },
205 /* BCD_E_NET_OFF */ {NULL, BCD_S_WAIT_SIGNAL_ON },
206 /* BCD_E_TIMEOUT */ {Bcd_A_EnableTx, BCD_S_WAIT_ENABLED },
207 /* BCD_E_ERROR */ {Bcd_A_Error, BCD_S_IDLE }
209 { /* State BCD_S_WAIT_RESULT */
210 /* BCD_E_NIL */ {NULL, BCD_S_WAIT_RESULT },
211 /* BCD_E_START */ {NULL, BCD_S_WAIT_RESULT },
212 /* BCD_E_DIAGMODE_END */ {NULL, BCD_S_WAIT_RESULT },
213 /* BCD_E_DIAG_MODE_STARTED */ {NULL, BCD_S_WAIT_RESULT },
214 /* BCD_E_DIAG_MODE_FAILED */ {NULL, BCD_S_WAIT_RESULT },
215 /* BCD_E_TX_ENABLE_SUCCESS */ {NULL, BCD_S_WAIT_RESULT },
216 /* BCD_E_TX_ENABLE_FAILED */ {NULL, BCD_S_WAIT_RESULT },
217 /* BCD_E_DIAG_RESULT_OK */ {Bcd_A_NextSeg, BCD_S_WAIT_SIGNAL_ON },
218 /* BCD_E_DIAG_RESULT_NOTOK */ {Bcd_A_StopDiag, BCD_S_END },
219 /* BCD_E_NET_OFF */ {NULL, BCD_S_WAIT_RESULT },
220 /* BCD_E_TIMEOUT */ {Bcd_A_Timeout2, BCD_S_IDLE },
221 /* BCD_E_ERROR */ {Bcd_A_Error, BCD_S_IDLE }
223 { /* State BCD_S_END */
224 /* BCD_E_NIL */ {NULL, BCD_S_END },
225 /* BCD_E_START */ {NULL, BCD_S_END },
226 /* BCD_E_DIAGMODE_END */ {Bcd_A_EndDiag, BCD_S_IDLE },
227 /* BCD_E_DIAG_MODE_STARTED */ {NULL, BCD_S_END },
228 /* BCD_E_DIAG_MODE_FAILED */ {NULL, BCD_S_END },
229 /* BCD_E_TX_ENABLE_SUCCESS */ {NULL, BCD_S_END },
230 /* BCD_E_TX_ENABLE_FAILED */ {NULL, BCD_S_END },
231 /* BCD_E_DIAG_RESULT_OK */ {NULL, BCD_S_END },
232 /* BCD_E_DIAG_RESULT_NOTOK */ {NULL, BCD_S_END },
233 /* BCD_E_NET_OFF */ {NULL, BCD_S_END },
234 /* BCD_E_TIMEOUT */ {Bcd_A_Timeout2, BCD_S_IDLE },
235 /* BCD_E_ERROR */ {Bcd_A_Error, BCD_S_IDLE }
240 /*! \brief Constructor of class CBackChannelDiag.
241 * \param self Reference to CBackChannelDiag instance
242 * \param inic Reference to CInic instance
243 * \param base Reference to CBase instance
244 * \param exc Reference to CExc instance
246 /* \param init_ptr Report callback function*/
247 void Bcd_Ctor(CBackChannelDiag *self, CInic *inic, CBase *base, CExc *exc)
249 MISC_MEM_SET((void *)self, 0, sizeof(*self));
255 Fsm_Ctor(&self->fsm, self, &(bcd_trans_tab[0][0]), BCD_NUM_EVENTS, BCD_E_NIL);
258 Sobs_Ctor(&self->bcd_inic_bcd_start, self, &Bcd_InicBcdStartCb);
259 Sobs_Ctor(&self->bcd_inic_bcd_end, self, &Bcd_InicBcdEndCb);
260 Sobs_Ctor(&self->bcd_enabletx, self, &Bcd_EnableTxResultCb);
261 Sobs_Ctor(&self->bcd_diagnosis, self, &Bcd_DiagnosisResultCb);
264 /* register termination events */
265 Mobs_Ctor(&self->bcd_terminate, self, EH_M_TERMINATION_EVENTS, &Bcd_OnTerminateEventCb);
266 Eh_AddObsrvInternalEvent(&self->base->eh, &self->bcd_terminate);
268 /* Register NetOn and MPR events */
269 Obs_Ctor(&self->bcd_nwstatus, self, &Bcd_NetworkStatusCb);
270 Inic_AddObsrvNwStatus(self->inic, &self->bcd_nwstatus);
273 /* Initialize Node Discovery service */
274 Srv_Ctor(&self->service, BCD_SRV_PRIO, self, &Bcd_Service);
275 /* Add Node Discovery service to scheduler */
276 (void)Scd_AddService(&self->base->scd, &self->service);
281 /*! \brief Service function of the Node Discovery service.
282 * \param self Reference to Node Discovery object
284 static void Bcd_Service(void *self)
286 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
287 Srv_Event_t event_mask;
288 Srv_GetEvent(&self_->service, &event_mask);
289 if(BCD_EVENT_SERVICE == (event_mask & BCD_EVENT_SERVICE)) /* Is event pending? */
292 Srv_ClearEvent(&self_->service, BCD_EVENT_SERVICE);
293 TR_INFO((self_->base->ucs_user_ptr, "[BCD]", "FSM __ %d %d", 2U, self_->fsm.current_state, self_->fsm.event_occured));
294 result = Fsm_Service(&self_->fsm);
295 TR_ASSERT(self_->base->ucs_user_ptr, "[BCD]", (result != FSM_STATE_ERROR));
296 TR_INFO((self_->base->ucs_user_ptr, "[BCD]", "FSM -> %d", 1U, self_->fsm.current_state));
302 /**************************************************************************************************/
304 /**************************************************************************************************/
305 /*! \brief Program a node
307 * \param *self Reference to BackChannel Diagnosis object
308 * \param *report_fptr Reference to result callback used by BackChannel Diagnosis
310 void Bcd_Start(CBackChannelDiag *self, Ucs_Bcd_ReportCb_t report_fptr)
312 self->report_fptr = report_fptr;
314 Fsm_SetEvent(&self->fsm, BCD_E_START);
315 Srv_SetEvent(&self->service, BCD_EVENT_SERVICE);
317 TR_INFO((self->base->ucs_user_ptr, "[BCD]", "Bcd_Start", 0U));
323 /**************************************************************************************************/
325 /**************************************************************************************************/
326 static void Bcd_A_Start(void *self)
328 Ucs_Return_t ret_val;
329 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
331 /* send INIC.BCDiag.StartResult */
332 ret_val = Inic_BCDiagnosis(self_->inic, &self_->bcd_inic_bcd_start);
334 if (ret_val == UCS_RET_SUCCESS)
336 Tm_SetTimer(&self_->base->tm,
345 Fsm_SetEvent(&self_->fsm, BCD_E_ERROR);
346 Srv_SetEvent(&self_->service, BCD_EVENT_SERVICE);
349 self_->current_segment = 0U;
351 TR_ASSERT(self_->base->ucs_user_ptr, "[BCD]", ret_val == UCS_RET_SUCCESS);
352 MISC_UNUSED(ret_val);
355 static void Bcd_A_EnableTx(void *self)
357 Ucs_Return_t ret_val;
358 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
360 /* send ENC.EnableTx */
361 ret_val = Bcd_EnableTx(self, 0U);
363 if (ret_val == UCS_RET_SUCCESS)
365 Tm_SetTimer(&self_->base->tm,
374 Fsm_SetEvent(&self_->fsm, BCD_E_ERROR);
375 Srv_SetEvent(&self_->service, BCD_EVENT_SERVICE);
378 TR_ASSERT(self_->base->ucs_user_ptr, "[BCD]", ret_val == UCS_RET_SUCCESS);
379 MISC_UNUSED(ret_val);
382 /*! Starts the diagnosis command for one certain segment.
384 * \param *self The instance
386 static void Bcd_A_DiagStart(void *self)
388 Ucs_Return_t ret_val;
389 uint16_t t_send = BCD_T_SEND;
390 uint16_t t_wait4dut = BCD_T_WAIT4DUT;
391 uint16_t t_switch = BCD_T_SWITCH;
392 uint16_t t_back = BCD_T_BACK;
393 bool autoback = BCD_AUTOBACK;
395 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
397 ret_val = Exc_BCDiag_Start(self_->exc,
398 self_->current_segment,
399 ADMIN_BASE_ADDR + self_->current_segment,
405 &self_->bcd_diagnosis);
407 if (ret_val == UCS_RET_SUCCESS)
409 Tm_SetTimer(&self_->base->tm,
419 Fsm_SetEvent(&self_->fsm, BCD_E_ERROR);
420 Srv_SetEvent(&self_->service, BCD_EVENT_SERVICE);
424 MISC_UNUSED(ret_val);
428 static void Bcd_A_NextSeg(void *self)
430 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
432 self_->report_fptr(UCS_BCD_RES_SUCCESS,
433 (uint8_t)(self_->bcd_result.admin_addr - ADMIN_BASE_ADDR),
434 self_->base->ucs_user_ptr);
435 self_->current_segment += 1U; /* switch to next segment. */
437 Tm_SetTimer(&self_->base->tm,
445 static void Bcd_A_StopDiag(void *self)
447 Ucs_Return_t ret_val;
448 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
450 switch(self_->bcd_result.diag_result)
453 self_->report_fptr(UCS_BCD_RES_NO_RING_BREAK,
454 (uint8_t)(self_->bcd_result.admin_addr - ADMIN_BASE_ADDR),
455 self_->base->ucs_user_ptr);
459 self_->report_fptr(UCS_BCD_RES_RING_BREAK,
460 (uint8_t)(self_->bcd_result.admin_addr - ADMIN_BASE_ADDR),
461 self_->base->ucs_user_ptr);
465 self_->report_fptr(UCS_BCD_RES_TIMEOUT1,
466 (uint8_t)(self_->bcd_result.admin_addr - ADMIN_BASE_ADDR),
467 self_->base->ucs_user_ptr);
474 /* finish Back Channel Diagnosis Mode: send INIC.BCDiagEnd.StartResult */
475 ret_val = Inic_BCDiagEnd(self_->inic, &self_->bcd_inic_bcd_end);
477 if (ret_val == UCS_RET_SUCCESS)
479 Tm_SetTimer(&self_->base->tm,
488 Fsm_SetEvent(&self_->fsm, BCD_E_ERROR);
489 Srv_SetEvent(&self_->service, BCD_EVENT_SERVICE);
492 MISC_UNUSED(ret_val);
496 static void Bcd_A_EndDiag(void *self)
498 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
500 if (self_->report_fptr != NULL)
502 self_->report_fptr(UCS_BCD_RES_END, UCS_BCD_DUMMY_SEGMENT, self_->base->ucs_user_ptr);
506 static void Bcd_A_Timeout2(void *self)
508 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
510 if (self_->report_fptr != NULL)
512 self_->report_fptr(UCS_BCD_RES_TIMEOUT2, UCS_BCD_DUMMY_SEGMENT, self_->base->ucs_user_ptr);
516 static void Bcd_A_WaitLight(void *self)
518 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
520 Tm_SetTimer(&self_->base->tm,
524 BCD_T_LOCK + (BCD_T_LIGHT_PROGRESS * (self_->current_segment + 1U)),
531 /*! \brief An unecpected error occurred
533 * \param *self Reference to BackChannelDiagnosis object
535 static void Bcd_A_Error(void *self)
537 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
539 if (self_->report_fptr != NULL)
541 self_->report_fptr(UCS_BCD_RES_ERROR, UCS_BCD_DUMMY_SEGMENT, self_->base->ucs_user_ptr);
547 /**************************************************************************************************/
548 /* Callback functions */
549 /**************************************************************************************************/
551 /*! \brief Function is called on reception of the Welcome.Result messsage
552 * \param self Reference to BackChannelDiagnosis object
553 * \param result_ptr Pointer to the result of the Welcome message
555 static void Bcd_InicBcdStartCb(void *self, void *result_ptr)
557 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
558 Exc_StdResult_t *result_ptr_ = (Exc_StdResult_t *)result_ptr;
560 Tm_ClearTimer(&self_->base->tm, &self_->timer);
562 if (result_ptr_->result.code == UCS_RES_SUCCESS)
564 Fsm_SetEvent(&self_->fsm, BCD_E_DIAG_MODE_STARTED);
565 TR_INFO((self_->base->ucs_user_ptr, "[BCD]", "Bcd_InicBcdStartCb BCD_E_DIAG_MODE_STARTED", 0U));
571 Fsm_SetEvent(&self_->fsm, BCD_E_DIAG_MODE_FAILED);
572 TR_INFO((self_->base->ucs_user_ptr, "[BCD]", "Bcd_InicBcdStartCb Error (code) 0x%x", 1U, result_ptr_->result.code));
573 for (i=0U; i< result_ptr_->result.info_size; ++i)
575 TR_INFO((self_->base->ucs_user_ptr, "[BCD]", "Bcd_InicBcdStartCb Error (info) 0x%x", 1U, result_ptr_->result.info_ptr[i]));
579 Srv_SetEvent(&self_->service, BCD_EVENT_SERVICE);
584 /*! \brief Function is called on reception of the BCEnableTx.Result messsage
585 * \param self Reference to BackChannelDiagnosis object
586 * \param result_ptr Pointer to the result of the BCEnableTx message
588 static void Bcd_EnableTxResultCb(void *self, void *result_ptr)
590 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
591 Exc_StdResult_t *result_ptr_ = (Exc_StdResult_t *)result_ptr;
593 Tm_ClearTimer(&self_->base->tm, &self_->timer);
595 if (result_ptr_->result.code == UCS_RES_SUCCESS)
597 /* self_->signature_status = *(Exc_SignatureStatus_t *)(result_ptr_->data_info);*/
598 Fsm_SetEvent(&self_->fsm, BCD_E_TX_ENABLE_SUCCESS);
599 TR_INFO((self_->base->ucs_user_ptr, "[BCD]", "Bcd_EnableTxResultCb BCD_E_TX_ENABLE_SUCCESS", 0U));
603 Fsm_SetEvent(&self_->fsm, BCD_E_TX_ENABLE_FAILED);
604 TR_INFO((self_->base->ucs_user_ptr, "[ND]", "Bcd_EnableTxResultCb Error 0x%x", 1U, result_ptr_->result.code));
607 Srv_SetEvent(&self_->service, BCD_EVENT_SERVICE);
611 /*! \brief Function is called on reception of the ENC.BCDiag.Result messsage
612 * \param self Reference to BackChannelDiagnosis object
613 * \param result_ptr Pointer to the result of the BCDiag message
615 static void Bcd_DiagnosisResultCb(void *self, void *result_ptr)
617 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
618 Exc_StdResult_t *result_ptr_ = (Exc_StdResult_t *)result_ptr;
620 Tm_ClearTimer(&self_->base->tm, &self_->timer);
622 if (result_ptr_->result.code == UCS_RES_SUCCESS)
624 self_->bcd_result = *((Exc_BCDiagResult *)(result_ptr_->data_info));
625 switch (self_->bcd_result.diag_result)
628 /* node reported working segment */
629 Fsm_SetEvent(&self_->fsm, BCD_E_DIAG_RESULT_OK);
630 TR_INFO((self_->base->ucs_user_ptr, "[BCD]", "Bcd_DiagnosisResultCb DUT_SLAVE", 0U));
633 case DUT_MASTER: /* all segments are ok */
634 case DUT_NO_ANSWER: /* ring break found */
635 case DUT_TIMEOUT: /* no communication on back channel */
636 Fsm_SetEvent(&self_->fsm, BCD_E_DIAG_RESULT_NOTOK);
637 TR_INFO((self_->base->ucs_user_ptr, "[BCD]", "Bcd_DiagnosisResultCb others", 0U));
647 Fsm_SetEvent(&self_->fsm, BCD_E_ERROR);
648 TR_INFO((self_->base->ucs_user_ptr, "[ND]", "Bcd_DiagnosisResultCb Error 0x%x", 1U, result_ptr_->result.code));
651 Srv_SetEvent(&self_->service, BCD_EVENT_SERVICE);
655 /*! \brief Function is called on reception of the INIC.BCDiagEnd.Result messsage
656 * \param self Reference to BackChannel Diagnosis object
657 * \param result_ptr Pointer to the result of the Welcome message
659 static void Bcd_InicBcdEndCb(void *self, void *result_ptr)
661 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
662 Exc_StdResult_t *result_ptr_ = (Exc_StdResult_t *)result_ptr;
664 Tm_ClearTimer(&self_->base->tm, &self_->timer);
666 if (result_ptr_->result.code == UCS_RES_SUCCESS)
668 Fsm_SetEvent(&self_->fsm, BCD_E_DIAGMODE_END);
669 TR_INFO((self_->base->ucs_user_ptr, "[BCD]", "Bcd_InicBcdEndCb BCD_E_DIAGMODE_END", 0U));
673 Fsm_SetEvent(&self_->fsm, BCD_E_ERROR);
674 TR_INFO((self_->base->ucs_user_ptr, "[ND]", "Bcd_InicBcdEndCb Error 0x%x", 1U, result_ptr_->result.code));
677 Srv_SetEvent(&self_->service, BCD_EVENT_SERVICE);
681 /*! Function is called on severe internal errors
683 * \param *self Reference to Node Discovery object
684 * \param *result_ptr Reference to data
686 static void Bcd_OnTerminateEventCb(void *self, void *result_ptr)
688 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
690 MISC_UNUSED(result_ptr);
692 if (self_->fsm.current_state != BCD_S_IDLE)
694 Tm_ClearTimer(&self_->base->tm, &self_->timer);
695 if (self_->report_fptr != NULL)
697 self_->report_fptr(UCS_BCD_RES_ERROR, UCS_BCD_DUMMY_SEGMENT, self_->base->ucs_user_ptr);
703 /*! \brief Callback function for the INIC.NetworkStatus status and error messages
705 * \param *self Reference to Node Discovery object
706 * \param *result_ptr Pointer to the result of the INIC.NetworkStatus message
708 static void Bcd_NetworkStatusCb(void *self, void *result_ptr)
710 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
711 Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
713 if (result_ptr_->result.code == UCS_RES_SUCCESS)
715 TR_INFO((self_->base->ucs_user_ptr, "[BCD]", "Bcd_NetworkStatusCb 0x%x", 1U, result_ptr_->result.code));
716 /* check for NetOn/NetOff events */
717 if ( (self_->neton == true)
718 && ((((Inic_NetworkStatus_t *)(result_ptr_->data_info))->availability) == UCS_NW_NOT_AVAILABLE) )
720 self_->neton = false;
721 Fsm_SetEvent(&self_->fsm, BCD_E_NET_OFF);
722 Srv_SetEvent(&self_->service, BCD_EVENT_SERVICE);
724 /* check for NetOn/NetOff events */
725 else if ( (self_->neton == false)
726 && ((((Inic_NetworkStatus_t *)(result_ptr_->data_info))->availability) == UCS_NW_AVAILABLE) )
728 /* self_->neton = true;
729 self_->hello_neton_request = true;
730 Fsm_SetEvent(&self_->fsm, BCD_E_CHECK);*/
732 /* check for MPR event */
733 else if ( (((Inic_NetworkStatus_t *)(result_ptr_->data_info))->events & UCS_NETWORK_EVENT_NCE)
734 == UCS_NETWORK_EVENT_NCE)
736 /* self_->hello_mpr_request = true;
737 Fsm_SetEvent(&self_->fsm, BCD_E_CHECK);*/
744 /*! \brief Timer callback used for supervising INIC command timeouts.
745 * \param self Reference to Node Discovery object
747 static void Bcd_TimerCb(void *self)
749 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
751 Fsm_SetEvent(&self_->fsm, BCD_E_TIMEOUT);
752 TR_INFO((self_->base->ucs_user_ptr, "[BCD]", "Bcd_TimerCb BCD_E_TIMEOUT", 0U));
754 Srv_SetEvent(&self_->service, BCD_EVENT_SERVICE);
758 /**************************************************************************************************/
759 /* Helper functions */
760 /**************************************************************************************************/
761 static Ucs_Return_t Bcd_EnableTx(void *self, uint8_t port)
763 Ucs_Return_t ret_val;
764 CBackChannelDiag *self_ = (CBackChannelDiag *)self;
766 /* send INIC.BCDiag.StartResult */
767 ret_val = Exc_BCEnableTx_StartResult(self_->exc, port, &self_->bcd_enabletx);
769 TR_ASSERT(self_->base->ucs_user_ptr, "[BCD]", ret_val == UCS_RET_SUCCESS);
781 /*------------------------------------------------------------------------------------------------*/
783 /*------------------------------------------------------------------------------------------------*/