lin_commontl_api.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
7  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
10  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
14  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
16  * THE POSSIBILITY OF SUCH DAMAGE.
17  */
33 #include "lin_commontl_api.h"
34 #include "lin_commontl_proto.h"
35 #if (SUPPORT_TRANSPORT_LAYER == 1U)
36 
37 /*******************************************************************************
38  * Variables
39  ******************************************************************************/
40 
41 /*******************************************************************************
42  * Code
43  ******************************************************************************/
44 /*FUNCTION**********************************************************************
45  *
46  * Function Name : ld_init
47  * Description : Initialize or reinitialize the raw and cooked layers on the interface iii.
48  * All the transport layer buffers will be initialized.
49  *
50  * Implements : ld_init_Activity
51  *END**************************************************************************/
52 void ld_init(l_ifc_handle iii)
53 {
54  DEV_ASSERT((l_u8)iii < LIN_NUM_OF_IFCS);
55  lin_transport_layer_queue_t * tl_queue;
56  static lin_product_id_t product_id_data[LIN_NUM_OF_IFCS];
57  lin_tl_descriptor_t * tl_desc_ptr = &g_lin_tl_descriptor_array[iii];
59  l_u8 max_queue_size;
60 
61  /* Calculate max_queue_size from max_message_length */
62  if (length <= 6U)
63  {
64  max_queue_size = 1U;
65  }
66  else
67  {
68  if (((length - 5U) % 6U) == 0U)
69  {
70  max_queue_size = (l_u8)(((length - 5U) / 6U) + 1U);
71  }
72  else
73  {
74  max_queue_size = (l_u8)(((length - 5U) / 6U) + 2U);
75  }
76  }
77 
78  /* Initial global variables */
81 
82  tl_desc_ptr->product_id_ptr = &product_id_data[iii];
83  tl_desc_ptr->tl_tx_queue.queue_max_size = max_queue_size;
84  tl_desc_ptr->tl_rx_queue.queue_max_size = max_queue_size;
85 
86  /* Initialize transmit queue */
87  /* Get TL tx queue */
88  tl_queue = &(tl_desc_ptr->tl_tx_queue);
89  tl_queue->queue_header = 0;
90  tl_queue->queue_tail = 0;
91  tl_queue->queue_status = LD_QUEUE_EMPTY;
92  tl_queue->queue_current_size = 0;
93  /* Initialize receive queue */
94  /* Get TL rx queue */
95  tl_queue = &(tl_desc_ptr->tl_rx_queue);
96  tl_queue->queue_header = 0;
97  tl_queue->queue_tail = 0;
98  tl_queue->queue_status = LD_NO_DATA;
99  tl_queue->queue_current_size = 0;
100  /* Initialize transmit message */
101  tl_desc_ptr->rx_msg_status = LD_COMPLETED;
102  tl_desc_ptr->rx_msg_size = 0;
103  /* Initialize receive message */
104  tl_desc_ptr->tx_msg_status = LD_COMPLETED;
105  tl_desc_ptr->tx_msg_size = 0;
106 
107  tl_desc_ptr->last_cfg_result = LD_SUCCESS;
108  tl_desc_ptr->last_RSID = 0;
109  tl_desc_ptr->ld_error_code = 0;
110 
111  tl_desc_ptr->frame_counter = 0;
112  tl_desc_ptr->num_of_pdu = 0;
113  tl_desc_ptr->slave_resp_cnt = 0;
114 
116  tl_desc_ptr->check_timeout = 0;
117 
118  tl_desc_ptr->diag_state = LD_DIAG_IDLE;
119  tl_desc_ptr->service_status = LD_SERVICE_IDLE;
120  tl_desc_ptr->diag_interleave_state = DIAG_NOT_START;
121  tl_desc_ptr->interleave_timeout_counter = 0;
122  tl_desc_ptr->FF_pdu_received = false;
123  tl_desc_ptr->ld_return_data = false;
124 }
125 
126 /*FUNCTION**********************************************************************
127  *
128  * Function Name : ld_put_raw
129  * Description : Queue the transmission of 8 bytes of data in one frame.
130  * The data is sent in the next suitable frame.
131  *
132  * Implements : ld_put_raw_Activity
133  *END**************************************************************************/
134 void ld_put_raw(l_ifc_handle iii,
135  const l_u8 * const data)
136 {
137  DEV_ASSERT((l_u8)iii < LIN_NUM_OF_IFCS);
138  DEV_ASSERT(data != NULL);
139  lin_transport_layer_queue_t * tl_queue;
140  lin_tl_descriptor_t * tl_desc_ptr = &g_lin_tl_descriptor_array[iii];
141 
142 #if (SUPPORT_SLAVE_MODE == 1U)
143  const lin_protocol_user_config_t * prot_user_config_ptr = &g_lin_protocol_user_cfg_array[iii];
144  const lin_node_attribute_t * node_attr_ptr;
145  if ((prot_user_config_ptr->function == (bool)LIN_SLAVE) && (prot_user_config_ptr->protocol_version == LIN_PROTOCOL_21))
146  {
148  tl_desc_ptr->check_timeout = node_attr_ptr->N_As_timeout;
150  }
151 #endif /* End (SUPPORT_SLAVE_MODE == 1U) */
152 
153  /* Get transmit queue */
154  tl_queue = &(tl_desc_ptr->tl_tx_queue);
155  tl_desc_ptr->tx_msg_size++;
156  tl_desc_ptr->slave_resp_cnt++;
157  tl_put_raw(iii, data, tl_queue, TRANSMITTING);
158 }
159 
160 /*FUNCTION**********************************************************************
161  *
162  * Function Name : ld_get_raw
163  * Description : Copy the oldest received diagnostic frame data to the memory
164  * specified by data.
165  *
166  * Implements : ld_get_raw_Activity
167  *END**************************************************************************/
168 void ld_get_raw(l_ifc_handle iii,
169  l_u8 * const data)
170 {
171  DEV_ASSERT((l_u8)iii < LIN_NUM_OF_IFCS);
172  DEV_ASSERT(data != NULL);
174 
175  tl_get_raw(iii, data, tl_queue, RECEIVING);
176 }
177 
178 /*FUNCTION**********************************************************************
179  *
180  * Function Name : ld_raw_tx_status
181  * Description : Get the status of the raw frame transmission function
182  *
183  * Implements : ld_raw_tx_status_Activity
184  *END**************************************************************************/
185 l_u8 ld_raw_tx_status(l_ifc_handle iii)
186 {
187 
188  DEV_ASSERT((l_u8)iii < LIN_NUM_OF_IFCS);
189 
191 }
192 
193 /*FUNCTION**********************************************************************
194  *
195  * Function Name : ld_raw_rx_status
196  * Description : Get the status of the raw frame receive function.
197  *
198  * Implements : ld_raw_rx_status_Activity
199  *END**************************************************************************/
200 l_u8 ld_raw_rx_status(l_ifc_handle iii)
201 {
202  DEV_ASSERT((l_u8)iii < LIN_NUM_OF_IFCS);
203 
205 }
206 
207 /*FUNCTION**********************************************************************
208  *
209  * Function Name : ld_send_message
210  * Description : Pack the information specified by data and length into one or multiple diagnostic frames.
211  *
212  * Implements : ld_send_message_Activity
213  *END**************************************************************************/
214 void ld_send_message(l_ifc_handle iii,
215  l_u16 length,
216  l_u8 NAD,
217  const l_u8 * const data)
218 {
219  DEV_ASSERT((l_u8)iii < LIN_NUM_OF_IFCS);
220  DEV_ASSERT(data != NULL);
221 
222  const lin_transport_layer_queue_t * tl_queue;
223  lin_tl_descriptor_t * tl_desc_ptr = &g_lin_tl_descriptor_array[iii];
224  const lin_protocol_user_config_t * prot_user_config_ptr = &g_lin_protocol_user_cfg_array[iii];
225 
226  lin_tl_pdu_data_t pdu;
227  l_u8 i;
228  l_u8 message_size;
229  l_u16 data_index = 0U;
230  l_u16 tmp_length = length;
231  l_u16 frame_counter = 0U;
232 
233 
234  /* Get transmit queue */
235  tl_queue = &(tl_desc_ptr->tl_tx_queue);
236  /* check message status in queue */
237  if (LD_COMPLETED == tl_desc_ptr->tx_msg_status)
238  {
239  /* calculate number of PDU message_size for this message */
240  if (length <= 6U)
241  {
242  message_size = 1U;
243  }
244  else
245  {
246  if (((length - 5U) % 6U) == 0U)
247  {
248  message_size = (l_u8)(((length - 5U) / 6U) + 1U);
249  }
250  else
251  {
252  message_size = (l_u8)(((length - 5U) / 6U) + 2U);
253  }
254  }
255 
256  /* Check if the message can be put into queue */
257  if (message_size <= (tl_queue->queue_max_size - tl_queue->queue_current_size))
258  {
259  /* update information of message in queue */
260  tl_desc_ptr->tx_msg_status = LD_IN_PROGRESS;
261  tl_desc_ptr->service_status = LD_SERVICE_BUSY;
262 
263  /* package data */
264  if (length <= 6U)
265  {
266  /* package single frame */
267  /* ____________________________________________ */
268  /* | NAD | PCI | SID | D1 | D2 | D3 | D4 | D5 | */
269  /* |_____|_____|_____|____|____|____|____|____| */
270  if ((bool)LIN_MASTER == prot_user_config_ptr->function)
271  {
272  pdu[0] = NAD;
273  }
274  #if (SUPPORT_SLAVE_MODE == 1U)
275  else
276  {
278  }
279  #endif /* End (SUPPORT_SLAVE_MODE == 1U) */
280  pdu[1] = (l_u8)length;
281  pdu[2] = data[0]; /* SID / RSID */
282  for (i = 1U; i < length; i++)
283  {
284  pdu[i + 2U] = data[i]; /* used data */
285  }
286 
287  for (i = (l_u8)length; i < 6U; i++)
288  {
289  pdu[i + 2U] = 0xFFU; /* unused data */
290  }
291 
292  ld_put_raw(iii, pdu);
293  }
294  else
295  {
296  /* package first frame */
297  /* ____________________________________________ */
298  /* | NAD | PCI | LEN |SID | D2 | D3 | D4 | D5 | */
299  /* |_____|_____|_____|____|____|____|____|____| */
300  if ((bool)LIN_MASTER == prot_user_config_ptr->function)
301  {
302  pdu[0] = NAD;
303  }
304  #if (SUPPORT_SLAVE_MODE == 1U)
305  else
306  {
308  }
309  #endif /* End (SUPPORT_SLAVE_MODE == 1U) */
310  pdu[1] = (l_u8)(((length / 256U) & 0x0FU) | 0x10U); /* PCI */
311  pdu[2] = (l_u8)(length % 256U); /* length */
312  pdu[3] = data[0]; /* SID / RSID */
313  for (i = 1U; i < 5U; i++)
314  {
315  /* data */
316  pdu[i + 3U] = data[i];
317  }
318 
319  data_index += 5U;
320  tmp_length -= 5U;
321  ld_put_raw(iii, pdu);
322 
323  /* package consecutive frame */
324  /* ___________________________________________ */
325  /* | NAD | PCI | D1 | D2 | D3 | D4 | D5 | D6 | */
326  /* |_____|_____|____|____|____|____|____|____| */
327  message_size--;
328  if ((bool)LIN_MASTER == prot_user_config_ptr->function)
329  {
330  pdu[0] = NAD;
331  }
332  #if (SUPPORT_SLAVE_MODE == 1U)
333  else
334  {
336  }
337  #endif /* End (SUPPORT_SLAVE_MODE == 1U) */
338  while (message_size > 0U)
339  {
340  frame_counter++;
341  pdu[1] = (l_u8)(0x20U | (frame_counter & 0x0FU));
342  if (tmp_length < 6U)
343  {
344  /* last PDU */
345  /* used data */
346  for (i = 0U; i < tmp_length; i++)
347  {
348  pdu[i + 2U] = data[data_index];
349  data_index++;
350  }
351 
352  /* unused data */
353  for (i = (l_u8)tmp_length; i < 6U; i++)
354  {
355  pdu[i + 2U] = 0xFFU;
356  }
357  }
358  else
359  {
360  for (i = 2U; i < 8U; i++)
361  {
362  pdu[i] = data[data_index];
363  data_index++;
364  }
365 
366  tmp_length -= 6U;
367  } /* end of (tmp < 6) */
368 
369  message_size--;
370  ld_put_raw(iii, pdu);
371  } /* end of (message > 0) */
372  } /* end of (length < 6) */
373  } /* end of check message size */
374  } /* end of (LD_COMPLETED == tl_conf->tl_message_status) */
375 } /* end of ld_send_message */
376 
377 /*FUNCTION**********************************************************************
378  *
379  * Function Name : ld_receive_message
380  * Description : Prepare the LIN diagnostic module to receive one message
381  * and store it in the buffer pointed to by data.
382  *
383  * Implements : ld_receive_message_Activity
384  *END**************************************************************************/
385 void ld_receive_message(l_ifc_handle iii,
386  l_u16 * const length,
387  l_u8 * const NAD,
388  l_u8 * const data)
389 {
390  DEV_ASSERT((l_u8)iii < LIN_NUM_OF_IFCS);
391  DEV_ASSERT(data != NULL);
392  DEV_ASSERT(NAD != NULL);
393  DEV_ASSERT(length != NULL);
394  lin_tl_descriptor_t * tl_desc_ptr = &g_lin_tl_descriptor_array[iii];
395 
396  if((tl_desc_ptr->rx_msg_status == LD_COMPLETED) && (*length != 0U))
397  {
398  /* set status of receive message */
399  tl_desc_ptr->rx_msg_status = LD_IN_PROGRESS;
400 
401  /* Prepare to receive diagnostic frame */
402  tl_desc_ptr->receive_message_ptr = data;
403  tl_desc_ptr->receive_message_length_ptr = length;
404  tl_desc_ptr->receive_NAD_ptr = NAD;
405  }
406 }
407 
408 /*FUNCTION**********************************************************************
409  *
410  * Function Name : ld_tx_status
411  * Description : Get the status of the last made call to ld_send_message.
412  *
413  * Implements : ld_tx_status_Activity
414  *END**************************************************************************/
415 l_u8 ld_tx_status(l_ifc_handle iii)
416 {
417  DEV_ASSERT((l_u8)iii < LIN_NUM_OF_IFCS);
418 
419  const lin_tl_descriptor_t * tl_desc_ptr = &g_lin_tl_descriptor_array[iii];
420 
421  return (l_u8)(tl_desc_ptr->tx_msg_status);
422 }
423 
424 /*FUNCTION**********************************************************************
425  *
426  * Function Name : ld_rx_status
427  * Description : Get the status of the last made call to ld_receive_message.
428  *
429  * Implements : ld_rx_status_Activity
430  *END**************************************************************************/
431 l_u8 ld_rx_status(l_ifc_handle iii)
432 {
433  DEV_ASSERT((l_u8)iii < LIN_NUM_OF_IFCS);
434  const lin_tl_descriptor_t * tl_desc_ptr = &g_lin_tl_descriptor_array[iii];
435  const lin_protocol_user_config_t * prot_user_config_ptr = &g_lin_protocol_user_cfg_array[iii];
436 
437  l_u8 ret_val = (l_u8)tl_desc_ptr->rx_msg_status;
438  /* For protocol 2.0 and J2602, return LD_FAILED for LD_WRONG_SN */
439  if ((tl_desc_ptr->rx_msg_status == LD_WRONG_SN) && (prot_user_config_ptr->protocol_version != LIN_PROTOCOL_21))
440  {
441  ret_val = (l_u8)LD_FAILED;
442  }
443 
444  return ret_val;
445 }
446 
447 #if (SUPPORT_DIAG_SERVICE != 1U)
448 /* This function is use when user not use diag service */
449 void lin_diag_service_callback(l_ifc_handle iii,
450  l_u8 sid)
451 {
452  UNUSED(iii);
453  UNUSED(sid);
454 }
455 
456 #endif /* End (SUPPORT_DIAG_SERVICE != 1)*/
457 #endif /* End (SUPPORT_TRANSPORT_LAYER == 1U) */
458 /*******************************************************************************
459  * EOF
460  ******************************************************************************/
l_u8 num_of_pdu
Definition: lin.h:486
l_u16 rx_msg_size
Definition: lin.h:473
l_u8 ld_error_code
Definition: lin.h:481
lin_product_id_t * product_id_ptr
Definition: lin.h:485
l_ifc_slave_handle slave_ifc_handle
Definition: lin.h:527
bool FF_pdu_received
Definition: lin.h:495
l_u8 ld_raw_rx_status(l_ifc_handle iii)
Get the status of the raw frame receive function.
void ld_init(l_ifc_handle iii)
Initialize or reinitialize the raw and cooked layers.
l_u8 ld_rx_status(l_ifc_handle iii)
Get the status of the last made call to ld_send_message.
#define LIN_SLAVE
Mode of LIN node (master or slave)
Definition: lin.h:167
l_u16 * receive_message_length_ptr
Definition: lin.h:500
lin_tl_pdu_data_t * tl_pdu_ptr
Definition: lin.h:444
void ld_receive_message(l_ifc_handle iii, l_u16 *const length, l_u8 *const NAD, l_u8 *const data)
Prepare the LIN diagnostic module to receive one message and store it in the buffer pointed to by dat...
void lin_diag_service_callback(l_ifc_handle iii, l_u8 sid)
const lin_node_attribute_t g_lin_node_attribute_array[LIN_NUM_OF_SLAVE_IFCS]
#define DEV_ASSERT(x)
Definition: devassert.h:77
l_u16 interleave_timeout_counter
Definition: lin.h:490
lin_tl_descriptor_t g_lin_tl_descriptor_array[LIN_NUM_OF_IFCS]
Definition: lin.c:49
l_u16 tx_msg_size
Definition: lin.h:477
l_u16 check_timeout
Definition: lin.h:484
lin_tl_pdu_data_t * tl_tx_queue_data_ptr
Definition: lin.h:531
Configuration structure Implements : lin_protocol_user_config_t_Class.
Definition: lin.h:510
lin_message_status_t rx_msg_status
Definition: lin.h:472
diag_interleaved_state_t diag_interleave_state
Definition: lin.h:489
lin_message_timeout_type_t check_timeout_type
Definition: lin.h:483
void ld_send_message(l_ifc_handle iii, l_u16 length, l_u8 NAD, const l_u8 *const data)
Pack the information specified by data and length into one or multiple diagnostic frames...
l_u8 * receive_NAD_ptr
Definition: lin.h:499
#define LIN_MASTER
Definition: lin.h:168
Product id structure Implements : lin_product_id_t_Class.
Definition: lin_types.h:57
Definition: lin.h:401
void ld_get_raw(l_ifc_handle iii, l_u8 *const data)
Copy the oldest received diagnostic frame data to the memory specified by data.
l_u8 ld_tx_status(l_ifc_handle iii)
Get the status of the last made call to ld_send_message.
void tl_put_raw(l_ifc_handle iii, const l_u8 *const data, lin_transport_layer_queue_t *queue, l_u8 direction)
Transport layer queue Implements : lin_transport_layer_queue_t_Class.
Definition: lin.h:437
l_u8 * configured_NAD_ptr
Definition: lin.h:191
const lin_protocol_user_config_t g_lin_protocol_user_cfg_array[LIN_NUM_OF_IFCS]
ld_queue_status_t queue_status
Definition: lin.h:441
unsigned char l_u8
Unsigned 8 bit integer Implements : l_u8_Class.
Definition: lin_types.h:30
lin_transport_layer_queue_t tl_tx_queue
Definition: lin.h:467
l_u8 ld_raw_tx_status(l_ifc_handle iii)
Get the status of the raw frame transmission function.
void ld_put_raw(l_ifc_handle iii, const l_u8 *const data)
Queue the transmission of 8 bytes of data in one frame.
lin_diagnostic_state_t diag_state
Definition: lin.h:488
l_u16 N_As_timeout
Definition: lin.h:204
lin_transport_layer_queue_t tl_rx_queue
Definition: lin.h:468
l_u8 frame_counter
Definition: lin.h:487
void tl_get_raw(l_ifc_handle iii, l_u8 *const data, lin_transport_layer_queue_t *queue, l_u8 direction)
lin_protocol_handle_t protocol_version
Definition: lin.h:512
lin_tl_pdu_data_t * tl_rx_queue_data_ptr
Definition: lin.h:532
lin_message_status_t tx_msg_status
Definition: lin.h:476
l_u8 slave_resp_cnt
Definition: lin.h:491
lin_service_status_t service_status
Definition: lin.h:492
Attributes of LIN node Implements : lin_node_attribute_t_Class.
Definition: lin.h:189
l_u8 lin_tl_pdu_data_t[8]
PDU data. Implements : lin_tl_pdu_data_t_Class.
Definition: lin.h:99
#define TRANSMITTING
l_u8 last_RSID
Definition: lin.h:480
bool ld_return_data
Definition: lin.h:494
l_u8 * receive_message_ptr
Definition: lin.h:498
unsigned short int l_u16
Unsigned 16 bit integer Implements : l_u16_Class.
Definition: lin_types.h:36
#define RECEIVING
Transport layer description Implements : lin_tl_descriptor_t_Class.
Definition: lin.h:464
lin_last_cfg_result_t last_cfg_result
Definition: lin.h:479