Use latest version of conf.d/templates submodule.
[apps/agl-service-unicens.git] / ucs2-lib / src / ucs_i2c.c
1 /*------------------------------------------------------------------------------------------------*/
2 /* UNICENS V2.1.0-3491                                                                            */
3 /* Copyright (c) 2017 Microchip Technology Germany II GmbH & Co. KG.                              */
4 /*                                                                                                */
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.                                                            */
9 /*                                                                                                */
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.                                                   */
14 /*                                                                                                */
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/>.                          */
17 /*                                                                                                */
18 /* You may also obtain this software under a propriety license from Microchip.                    */
19 /* Please contact Microchip for further information.                                              */
20 /*------------------------------------------------------------------------------------------------*/
21
22 /*!
23  * \file
24  * \brief Implementation of the I2C Module.
25  *
26  * \cond UCS_INTERNAL_DOC
27  * \addtogroup G_I2C
28  * @{
29  */
30
31 /*------------------------------------------------------------------------------------------------*/
32 /* Includes                                                                                       */
33 /*------------------------------------------------------------------------------------------------*/
34 #include "ucs_i2c.h"
35 #include "ucs_misc.h"
36
37 /*------------------------------------------------------------------------------------------------*/
38 /* Internal prototypes                                                                            */
39 /*------------------------------------------------------------------------------------------------*/
40 static void I2c_PortCreateResCb(void *self, void *result_ptr);
41 static void I2c_PortWriteResCb(void *self, void *result_ptr);
42 static void I2c_PortReadResCb(void *self, void *result_ptr);
43 static void I2c_TriggerEventStatusCb(void *self, void *result_ptr);
44 static bool I2c_RxFilter4NsmCb(Msg_MostTel_t *tel_ptr, void *self);
45 static void I2c_PortCreate_Result(void *self, Msg_MostTel_t *msg_ptr);
46 static void I2c_PortRead_Result(void *self, Msg_MostTel_t *msg_ptr);
47 static void I2c_PortWrite_Result(void *self, Msg_MostTel_t *msg_ptr);
48 static void I2c_RxError(void *self, Msg_MostTel_t *msg_ptr, I2c_ErrResultCb_t res_cb_fptr);
49 static void I2c_NsmResultCb(void * self, Nsm_Result_t result);
50
51 /*------------------------------------------------------------------------------------------------*/
52 /* Implementation of class I2C                                                                    */
53 /*------------------------------------------------------------------------------------------------*/
54 /*------------------------------------------------------------------------------------------------*/
55 /* Initialization Methods                                                                         */
56 /*------------------------------------------------------------------------------------------------*/
57 /*! \brief Constructor of the I2C class.
58  *  \param self        Instance pointer
59  *  \param init_ptr    init data_ptr
60  */
61 void I2c_Ctor(CI2c * self, I2c_InitData_t * init_ptr)
62 {
63     MISC_MEM_SET(self, 0, sizeof(CI2c));
64
65     /* Set class instances */
66     self->inic_ptr = init_ptr->inic_ptr;
67     self->base_ptr = self->inic_ptr->base_ptr;
68     self->nsm_ptr  = init_ptr->nsm_ptr; 
69
70     self->curr_user_data.i2c_interrupt_report_fptr = init_ptr->i2c_interrupt_report_fptr;
71
72     /* Init GPIOTriggerEvent observer */
73     Obs_Ctor(&self->triggerevent_observer, self, &I2c_TriggerEventStatusCb);
74
75     /* Subscribe Observers */
76     Inic_AddObsrvGpioTriggerEvent(self->inic_ptr, &self->triggerevent_observer);
77
78     /* Set device id */
79     self->device_address = Inic_GetTargetAddress(self->inic_ptr);
80 }
81
82 /*------------------------------------------------------------------------------------------------*/
83 /* Service Functions                                                                              */
84 /*------------------------------------------------------------------------------------------------*/
85 /*! \brief  Creates an I2C Port with its associated parameter. 
86  *  \param  self                Reference to CI2c instance
87  *  \param  index               I2C Port instance
88  *  \param  speed               The speed grade of the I2C Port
89  *  \param  i2c_int_mask        The I2C interrupt pin mask on the GPIO Port.
90  *  \param  res_fptr            Required result callback function pointer.    
91  *  \return Possible return values are shown in the table below.
92  *           Value                       | Description 
93  *           --------------------------- | ------------------------------------
94  *           UCS_RET_SUCCESS             | No error
95  *           UCS_RET_ERR_PARAM           | At least one parameter is wrong
96  *           UCS_RET_ERR_BUFFER_OVERFLOW | No message buffer available
97  *           UCS_RET_ERR_API_LOCKED      | API is currently locked
98  */
99 Ucs_Return_t I2c_CreatePort(CI2c * self, uint8_t index, Ucs_I2c_Speed_t speed, uint8_t i2c_int_mask, Ucs_I2c_CreatePortResCb_t res_fptr)
100 {
101     Ucs_Return_t result = UCS_RET_ERR_PARAM;
102     uint8_t address     = 0x00U; /* Address will be ignored */
103     uint8_t mode        = 0x01U; /* Master Mode */
104
105     if ((NULL != self) && (NULL != res_fptr))
106     {
107         result = UCS_RET_ERR_API_LOCKED;
108         if (!Nsm_IsLocked(self->nsm_ptr))
109         {
110             I2c_Script_t * tmp_script = &self->curr_script;
111
112             /* Set Data */
113             tmp_script->cfg_data[0] = index;
114             tmp_script->cfg_data[1] = address;
115             tmp_script->cfg_data[2] = mode;
116             tmp_script->cfg_data[3] = (uint8_t)speed;
117
118             /* Set message id */
119             tmp_script->cfg_msg.FBlockId = FB_INIC;
120             tmp_script->cfg_msg.InstId   = 0U;
121             tmp_script->cfg_msg.FunktId  = INIC_FID_I2C_PORT_CREATE;
122             tmp_script->cfg_msg.OpCode   = (uint8_t)UCS_OP_STARTRESULT;
123             tmp_script->cfg_msg.DataLen  = 4U;
124             tmp_script->cfg_msg.DataPtr  = &tmp_script->cfg_data[0];
125           
126             /* Set script */
127             tmp_script->script.send_cmd = &tmp_script->cfg_msg;
128             tmp_script->script.pause    = 0U;
129
130             /* Transmit script */
131             result = Nsm_Run_Pv(self->nsm_ptr, &tmp_script->script, 1U, self, &I2c_RxFilter4NsmCb, &I2c_NsmResultCb);
132             if(result == UCS_RET_SUCCESS)
133             {
134                 self->curr_user_data.int_pin_mask = i2c_int_mask;
135                 self->curr_user_data.portcreate_res_cb = res_fptr;
136                 self->curr_res_cb = &I2c_PortCreateResCb;
137             }
138         }
139     }
140
141     return result;
142 }                                                
143
144 /*! \brief  Writes a block of bytes to an I2C device at a specified I2C address.
145  *  \param  self            Reference to CI2c instance
146  *  \param  port_handle     Port resource handle
147  *  \param  mode            The write transfer mode
148  *  \param  block_count     The number of blocks to be written to the I2C address.
149  *  \param  slave_address   The 7-bit I2C slave address of the peripheral to be read
150  *  \param  timeout         The timeout for the I2C Port write
151  *  \param  data_len        Number of bytes to be written to the addressed I2C peripheral
152  *  \param  data_ptr        Reference to the data to be written
153  *  \param  res_fptr        Required result callback function pointer.   
154  *  \return Possible return values are shown in the table below.
155  *           Value                       | Description 
156  *           --------------------------- | ------------------------------------
157  *           UCS_RET_SUCCESS             | No error
158  *           UCS_RET_ERR_PARAM           | At least one parameter is wrong
159  *           UCS_RET_ERR_BUFFER_OVERFLOW | No message buffer available
160  *           UCS_RET_ERR_API_LOCKED      | API is currently locked
161  */
162 Ucs_Return_t I2c_WritePort(CI2c * self, uint16_t port_handle, Ucs_I2c_TrMode_t mode, uint8_t block_count, uint8_t slave_address, uint16_t timeout, uint8_t data_len, uint8_t data_ptr[], Ucs_I2c_WritePortResCb_t res_fptr)
163 {
164     Ucs_Return_t result = UCS_RET_ERR_PARAM;
165
166     if ((NULL != self) && (NULL != res_fptr))
167     {
168         if ((0U < data_len) && (NULL != data_ptr))
169         {
170             result = UCS_RET_ERR_API_LOCKED;
171             if (!Nsm_IsLocked(self->nsm_ptr))
172             {
173                 bool is_ok = true;
174
175                 result = UCS_RET_ERR_PARAM;
176                 if ((UCS_I2C_BURST_MODE == mode) && (0U == block_count))
177                 {
178                     is_ok = false;
179                 }
180
181                 if (is_ok)
182                 {
183                     uint8_t i;
184                     I2c_Script_t * tmp_script = &self->curr_script;
185
186                     for (i = 0U; i < data_len; i++)
187                     {
188                         tmp_script->cfg_data[8U + i] = data_ptr[i];
189                     }
190
191                     /* Set Data */
192                     tmp_script->cfg_data[0] = MISC_HB(port_handle);
193                     tmp_script->cfg_data[1] = MISC_LB(port_handle);
194                     tmp_script->cfg_data[2] = (uint8_t)mode;
195                     tmp_script->cfg_data[3] = block_count;
196                     tmp_script->cfg_data[4] = slave_address;
197                     tmp_script->cfg_data[5] = (mode == UCS_I2C_BURST_MODE)  ? (data_len/block_count):data_len;
198                     tmp_script->cfg_data[6] = MISC_HB(timeout);
199                     tmp_script->cfg_data[7] = MISC_LB(timeout);
200
201                     /* Set message id */
202                     tmp_script->cfg_msg.FBlockId = FB_INIC;
203                     tmp_script->cfg_msg.InstId   = 0U;
204                     tmp_script->cfg_msg.FunktId  = INIC_FID_I2C_PORT_WRITE;
205                     tmp_script->cfg_msg.OpCode   = (uint8_t)UCS_OP_STARTRESULT;
206                     tmp_script->cfg_msg.DataLen  = data_len + 8U;
207                     tmp_script->cfg_msg.DataPtr  = &tmp_script->cfg_data[0];
208           
209                     /* Set script */
210                     tmp_script->script.send_cmd = &tmp_script->cfg_msg;
211                     tmp_script->script.pause    = 0U;
212
213                     /* Transmit script */
214                     result = Nsm_Run_Pv(self->nsm_ptr, &tmp_script->script, 1U, self, &I2c_RxFilter4NsmCb, &I2c_NsmResultCb);
215                     if(result == UCS_RET_SUCCESS)
216                     {
217                         self->curr_user_data.portwrite_res_cb = res_fptr;
218                         self->curr_res_cb = &I2c_PortWriteResCb;
219                     }
220                 }
221             }
222         }
223     }
224
225     return result;
226 }
227
228 /*! \brief  Reads a block of bytes from an I2C device at a specified I2C address. 
229  *  \param  self            Reference to CI2c instance
230  *  \param  port_handle     Port resource handle
231  *  \param  slave_address   The 7-bit I2C slave address of the peripheral to be read
232  *  \param  data_len        Number of bytes to be read from the address
233  *  \param  timeout         The timeout for the I2C Port read
234  *  \param  res_fptr        Required result callback function pointer.   
235  *  \return Possible return values are shown in the table below.
236  *           Value                       | Description 
237  *           --------------------------- | ------------------------------------
238  *           UCS_RET_SUCCESS             | No error
239  *           UCS_RET_ERR_PARAM           | At least one parameter is wrong
240  *           UCS_RET_ERR_BUFFER_OVERFLOW | No message buffer available
241  *           UCS_RET_ERR_API_LOCKED      | API is currently locked
242  */
243 Ucs_Return_t I2c_ReadPort(CI2c * self, uint16_t port_handle, uint8_t slave_address, uint8_t data_len, uint16_t timeout, Ucs_I2c_ReadPortResCb_t res_fptr)
244 {
245     Ucs_Return_t result = UCS_RET_ERR_PARAM;
246
247     if ((NULL != self) && (NULL != res_fptr))
248     {
249         result = UCS_RET_ERR_API_LOCKED;
250         if (!Nsm_IsLocked(self->nsm_ptr))
251         {
252             I2c_Script_t * tmp_script = &self->curr_script;
253         
254             /* Set Data */
255             tmp_script->cfg_data[0] = MISC_HB(port_handle);
256             tmp_script->cfg_data[1] = MISC_LB(port_handle);
257             tmp_script->cfg_data[2] = slave_address;
258             tmp_script->cfg_data[3] = data_len;
259             tmp_script->cfg_data[4] = MISC_HB(timeout);
260             tmp_script->cfg_data[5] = MISC_LB(timeout); 
261         
262             /* Set message id */
263             tmp_script->cfg_msg.FBlockId = FB_INIC;
264             tmp_script->cfg_msg.InstId   = 0U;
265             tmp_script->cfg_msg.FunktId  = INIC_FID_I2C_PORT_READ;
266             tmp_script->cfg_msg.OpCode   = (uint8_t)UCS_OP_STARTRESULT;
267             tmp_script->cfg_msg.DataLen  = 6U;
268             tmp_script->cfg_msg.DataPtr  = &tmp_script->cfg_data[0];
269         
270             /* Set script */
271             tmp_script->script.send_cmd = &tmp_script->cfg_msg;
272             tmp_script->script.pause    = 0U;
273         
274             /* Transmit script */
275             result = Nsm_Run_Pv(self->nsm_ptr, &tmp_script->script, 1U, self, &I2c_RxFilter4NsmCb, &I2c_NsmResultCb);
276             if(result == UCS_RET_SUCCESS)
277             {
278                 self->curr_user_data.portread_res_cb = res_fptr;
279                 self->curr_res_cb = &I2c_PortReadResCb;
280             }
281         }
282     }
283
284     return result;
285 }
286
287 /*------------------------------------------------------------------------------------------------*/
288 /* Private Methods                                                                                */
289 /*------------------------------------------------------------------------------------------------*/
290 /*! \brief  Handles the result of the I2CPortCreate.StartResultAck
291  *  \param  self            Instance pointer
292  *  \param  result_ptr      result pointer
293  */
294 static void I2c_PortCreateResCb(void *self, void *result_ptr)
295 {
296     CI2c *self_ = (CI2c *)self;
297     uint16_t i2c_port_handle;
298     Ucs_I2c_Result_t res;
299     Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
300
301     /* Init result */
302     MISC_MEM_SET(&res, 0, sizeof(Ucs_I2c_Result_t));
303
304     if (NULL != result_ptr_)
305     {
306         i2c_port_handle = 0U;
307         res.code = UCS_I2C_RES_ERR_CMD;
308         res.details.result_type = UCS_I2C_RESULT_TYPE_TGT;
309         res.details.inic_result = result_ptr_->result;
310         if (result_ptr_->data_info != NULL)
311         {
312             if(result_ptr_->result.code == UCS_RES_SUCCESS)
313             {
314                 res.code        = UCS_I2C_RES_SUCCESS;
315                 i2c_port_handle = *(uint16_t *)result_ptr_->data_info;
316             }
317             else if(result_ptr_->result.code == UCS_RES_ERR_TRANSMISSION)
318             {
319                 res.details.result_type = UCS_I2C_RESULT_TYPE_TX;
320                 res.details.tx_result   = *(Ucs_MsgTxStatus_t *)(result_ptr_->data_info);
321             }
322             else if (result_ptr_->result.code == UCS_RES_ERR_CONFIGURATION)
323             {
324                 res.code = UCS_I2C_RES_ERR_SYNC;
325             }
326         }
327
328         if (NULL != self_->curr_user_data.portcreate_res_cb)
329         {
330             self_->curr_user_data.portcreate_res_cb(self_->device_address, i2c_port_handle, res, self_->base_ptr->ucs_user_ptr);
331         }
332     }
333 }
334
335 /*! \brief  Handles the result of the I2CPortWrite.StartResultAck
336  *  \param  self            Instance pointer
337  *  \param  result_ptr      result pointer
338  */
339 static void I2c_PortWriteResCb(void *self, void *result_ptr)
340 {
341     CI2c *self_ = (CI2c *)self;
342     Inic_I2cWriteResStatus_t wr_res;
343     Ucs_I2c_Result_t res;
344     Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
345
346     /* Init result */
347     MISC_MEM_SET(&res, 0, sizeof(Ucs_I2c_Result_t));
348
349     if (NULL != result_ptr_)
350     {
351         wr_res.data_len = 0U;
352         wr_res.port_handle = 0U;
353         wr_res.slave_address = 0U;
354         res.code = UCS_I2C_RES_ERR_CMD;
355         res.details.result_type = UCS_I2C_RESULT_TYPE_TGT;
356         res.details.inic_result = result_ptr_->result;
357         if (result_ptr_->data_info != NULL)
358         {
359             if(result_ptr_->result.code == UCS_RES_SUCCESS)
360             {
361                 res.code = UCS_I2C_RES_SUCCESS;
362                 wr_res = *(Inic_I2cWriteResStatus_t *)result_ptr_->data_info;
363             }
364             else if(result_ptr_->result.code == UCS_RES_ERR_TRANSMISSION)
365             {
366                 res.details.result_type = UCS_I2C_RESULT_TYPE_TX;
367                 res.details.tx_result   = *(Ucs_MsgTxStatus_t *)(result_ptr_->data_info);
368             }
369             else if (result_ptr_->result.code == UCS_RES_ERR_CONFIGURATION)
370             {
371                 res.code = UCS_I2C_RES_ERR_SYNC;
372             }
373         }
374
375         if (NULL != self_->curr_user_data.portwrite_res_cb)
376         {
377             self_->curr_user_data.portwrite_res_cb(self_->device_address, wr_res.port_handle, wr_res.slave_address, wr_res.data_len, res, self_->base_ptr->ucs_user_ptr);
378         }
379     }
380 }
381
382 /*! \brief  Handles the result of the I2CPortRead.StartResultAck
383  *  \param  self            Instance pointer
384  *  \param  result_ptr      result pointer
385  */
386 static void I2c_PortReadResCb(void *self, void *result_ptr)
387 {
388     CI2c *self_ = (CI2c *)self;
389     Inic_I2cReadResStatus_t read_res;
390     Ucs_I2c_Result_t res;
391     Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
392
393     /* Init result */
394     MISC_MEM_SET(&res, 0, sizeof(Ucs_I2c_Result_t));
395
396     if (NULL != result_ptr_)
397     {
398         read_res.data_len = 0U;
399         read_res.data_ptr = NULL;
400         read_res.port_handle = 0U;
401         read_res.slave_address = 0U;
402         res.code = UCS_I2C_RES_ERR_CMD;
403         res.details.result_type = UCS_I2C_RESULT_TYPE_TGT;
404         res.details.inic_result = result_ptr_->result;
405         if (result_ptr_->data_info != NULL)
406         {
407             if(result_ptr_->result.code == UCS_RES_SUCCESS)
408             {
409                 res.code = UCS_I2C_RES_SUCCESS;
410                 read_res = *(Inic_I2cReadResStatus_t *)result_ptr_->data_info;
411             }
412             else if(result_ptr_->result.code == UCS_RES_ERR_TRANSMISSION)
413             {
414                 res.details.result_type = UCS_I2C_RESULT_TYPE_TX;
415                 res.details.tx_result = *(Ucs_MsgTxStatus_t *)(result_ptr_->data_info);
416             }
417             else if (result_ptr_->result.code == UCS_RES_ERR_CONFIGURATION)
418             {
419                 res.code = UCS_I2C_RES_ERR_SYNC;
420             }
421         }
422
423         if (NULL != self_->curr_user_data.portread_res_cb)
424         {
425             self_->curr_user_data.portread_res_cb(self_->device_address, read_res.port_handle, read_res.slave_address, read_res.data_len, read_res.data_ptr, res, self_->base_ptr->ucs_user_ptr);
426         }
427     }
428 }
429
430 /*! \brief  Handles the result of the GPIOPortTriggerEvent.Status
431  *  \param  self            Instance pointer
432  *  \param  result_ptr      result pointer
433  */
434 static void I2c_TriggerEventStatusCb(void *self, void *result_ptr)
435 {
436     CI2c *self_ = (CI2c *)self;
437     Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
438
439     if ((NULL != result_ptr_) && 
440         (NULL != self_->curr_user_data.i2c_interrupt_report_fptr))
441     {
442         Inic_GpioTriggerEventStatus_t status;
443         uint16_t int_mask = self_->curr_user_data.int_pin_mask;
444         status = *(Inic_GpioTriggerEventStatus_t *)result_ptr_->data_info;
445
446         if ((!status.is_first_report) && 
447             ((int_mask == (status.rising_edges & int_mask)) ||
448             (int_mask == (status.levels & int_mask)) ||
449             (int_mask == (status.falling_edges & int_mask))))
450         {
451             self_->curr_user_data.i2c_interrupt_report_fptr(self_->device_address, self_->base_ptr->ucs_user_ptr);
452         }
453     }
454 }
455
456 /*! \brief  Checks whether the incoming is our message and handles It if it's.
457  *  \param  tel_ptr          Reference to the message object.
458  *  \param  self             Reference to the user argument.
459  *  \return  Returns \c true to discard the message and free it to the pool if it's  our message. Otherwise, returns 
460  *           \c false.
461  */
462 static bool I2c_RxFilter4NsmCb(Msg_MostTel_t *tel_ptr, void *self)
463 {
464     CI2c *self_ = (CI2c *)self;
465     bool ret_val = true;
466
467     if ((tel_ptr != NULL) && (tel_ptr->id.function_id == self_->curr_script.script.send_cmd->FunktId))
468     {
469         if (tel_ptr->id.op_type == UCS_OP_RESULT)
470         {
471             switch(tel_ptr->id.function_id)
472             {
473             case INIC_FID_I2C_PORT_CREATE:
474                 I2c_PortCreate_Result(self_, tel_ptr);
475                 break;
476             case INIC_FID_I2C_PORT_READ:
477                 I2c_PortRead_Result(self_, tel_ptr);
478                 break;
479             case INIC_FID_I2C_PORT_WRITE:
480                 I2c_PortWrite_Result(self_, tel_ptr);
481                 break;
482             default:
483                 ret_val = false;
484                 break;
485             }
486         }
487         else if (tel_ptr->id.op_type == UCS_OP_ERROR)
488         {
489             I2c_ErrResultCb_t res_cb_fptr = self_->curr_res_cb;
490             I2c_RxError(self_, tel_ptr, res_cb_fptr);
491         }
492     }
493     else
494     {
495         ret_val = false;
496     }
497
498     return ret_val;
499 }
500
501 /*! \brief  Result callback function for NSM result. Whenever this function is called the NodeScripting has finished the
502  *  script's execution. This function handles transmission and sync error. Only these two kind of errors can occur.
503  *  \param  self     Reference to the called user instance.
504  *  \param  result   Result of the scripting operation.
505  */
506 static void I2c_NsmResultCb(void * self, Nsm_Result_t result)
507 {
508     CI2c *self_ = (CI2c *)self;
509
510     if (self_ != NULL)
511     {
512         Inic_StdResult_t res_data;
513         bool allow_report = false;
514
515         if ((result.code == UCS_NS_RES_ERROR) && (result.details.result_type == NS_RESULT_TYPE_TX))
516         {
517             res_data.data_info        = &result.details.tx_result;
518             res_data.result.code      = UCS_RES_ERR_TRANSMISSION;
519             res_data.result.info_ptr  = NULL;
520             res_data.result.info_size = 0U;
521             allow_report = true;
522         }
523         else if ((result.code == UCS_NS_RES_ERROR) && (result.details.result_type == NS_RESULT_TYPE_TGT_SYNC))
524         {
525             res_data.data_info        = &result.details.inic_result;
526             res_data.result.code      = result.details.inic_result.code;
527             res_data.result.info_ptr  = result.details.inic_result.info_ptr;
528             res_data.result.info_size = result.details.inic_result.info_size;
529             allow_report = true;
530         }
531         else if ((result.code == UCS_NS_RES_ERROR) && ((result.details.tx_result == UCS_MSG_STAT_OK) || 
532                  (result.details.inic_result.code == UCS_RES_SUCCESS)))
533         {
534             res_data.data_info        = NULL;
535             res_data.result.code      = UCS_RES_ERR_TIMEOUT;
536             res_data.result.info_ptr  = NULL;
537             res_data.result.info_size = 0U;
538
539             TR_ERROR((self_->base_ptr->ucs_user_ptr, "[I2C]", "TIMEOUT ERROR occurred for currently I2C command. No response received from target device with address 0x%X.", 1U, self_->device_address));
540         }
541
542         if ((self_->curr_res_cb != NULL) && (allow_report))
543         {
544             self_->curr_res_cb(self_, &res_data);
545         }
546     }
547 }
548
549 /*---------------------------------- GW Functions ----------------------------------*/ 
550
551 /*! \brief   Error Handler function for all I2C methods
552  *  \param   self      Reference to CI2c instance
553  *  \param   msg_ptr   Pointer to received message
554  *  \param   res_cb_fptr   Pointer to a specified error handler function
555  */
556 static void I2c_RxError(void *self, Msg_MostTel_t *msg_ptr, I2c_ErrResultCb_t res_cb_fptr)
557 {
558     CI2c *self_ = (CI2c *)self;
559     Inic_StdResult_t res_data;
560
561     res_data.data_info = NULL;
562     res_data.result = Inic_TranslateError(self_->inic_ptr,
563                                           &msg_ptr->tel.tel_data_ptr[0],
564                                           (msg_ptr->tel.tel_len));
565     if (res_cb_fptr != NULL)
566     {
567         res_cb_fptr(self_, &res_data);
568     }
569 }
570
571 /*! \brief   Handler function for I2CPortCreate.ResultAck
572  *  \details Element res_data.data_info points to the variable i2c_port_handle which holds the
573  *           I2C Port resource handle.
574  *  \param   self      Reference to CI2c instance
575  *  \param   msg_ptr   Pointer to received message
576  */
577 static void I2c_PortCreate_Result(void *self, Msg_MostTel_t *msg_ptr)
578 {
579     CI2c *self_ = (CI2c *)self;
580     uint16_t i2c_port_handle;
581     Inic_StdResult_t res_data;
582
583     MISC_DECODE_WORD(&i2c_port_handle, &(msg_ptr->tel.tel_data_ptr[0]));
584     res_data.data_info       = &i2c_port_handle;
585     res_data.result.code     = UCS_RES_SUCCESS;
586     res_data.result.info_ptr = NULL;
587
588     I2c_PortCreateResCb(self_, &res_data);
589 }
590
591 /*! \brief   Handler function for I2CPortRead.ResultAck
592  *  \details Element res_data.data_info points to a variable of type Inic_I2cReadResStatus_t which holds the
593  *          the results of the I2CPortRead.StartResultAck command.
594  *  \param   self      Reference to CI2c instance
595  *  \param   msg_ptr   Pointer to received message
596  */
597 static void I2c_PortRead_Result(void *self, Msg_MostTel_t *msg_ptr)
598 {
599     CI2c *self_ = (CI2c *)self;
600     Inic_I2cReadResStatus_t i2c_read_res;
601     Inic_StdResult_t res_data;
602
603     res_data.data_info       = &i2c_read_res;
604     res_data.result.code     = UCS_RES_SUCCESS;
605     res_data.result.info_ptr = NULL;
606
607     MISC_DECODE_WORD(&i2c_read_res.port_handle, &(msg_ptr->tel.tel_data_ptr[0]));
608     i2c_read_res.slave_address = msg_ptr->tel.tel_data_ptr[2];
609     i2c_read_res.data_len      = msg_ptr->tel.tel_data_ptr[3];
610     i2c_read_res.data_ptr      = &msg_ptr->tel.tel_data_ptr[4];
611
612     I2c_PortReadResCb(self_, &res_data);
613 }
614
615 /*! \brief   Handler function for I2CPortWrite.ResultAck
616  *  \details Element res_data.data_info points to a variable of type Inic_I2cWriteResStatus_t which holds the
617  *          the results of the I2CPortWrite.StartResultAck command.
618  *  \param   self      Reference to CI2c instance
619  *  \param   msg_ptr   Pointer to received message
620  */
621 static void I2c_PortWrite_Result(void *self, Msg_MostTel_t *msg_ptr)
622 {
623     CI2c *self_ = (CI2c *)self;
624     Inic_I2cWriteResStatus_t i2c_write_res;
625     Inic_StdResult_t res_data;
626
627     res_data.data_info       = &i2c_write_res;
628     res_data.result.code     = UCS_RES_SUCCESS;
629     res_data.result.info_ptr = NULL;
630
631     MISC_DECODE_WORD(&i2c_write_res.port_handle, &(msg_ptr->tel.tel_data_ptr[0]));
632     i2c_write_res.slave_address = msg_ptr->tel.tel_data_ptr[2];
633     i2c_write_res.data_len      = msg_ptr->tel.tel_data_ptr[3];
634
635     I2c_PortWriteResCb(self_, &res_data);
636 }
637
638 /*!
639  * @}
640  * \endcond
641  */
642
643 /*------------------------------------------------------------------------------------------------*/
644 /* End of file                                                                                    */
645 /*------------------------------------------------------------------------------------------------*/
646