📄 lin_api.c
字号:
{
/* No overrun or framing errors occurred, or this was an Event Triggered
* frame. Bitwise invert the calculated checksum to complete the checksum
* calculation. */
LIN_sum_code = ~LIN_sum_code;
/* Compare the calculated checksum with the received checksum. */
if (LIN_sum_code == LIN_data[(LIN_RX_count - 1)])
{
/* The checksums compare. */
if (LIN_frame_type == UNCONDITION_FRAME)
{
/* Check for a Diagnostic Response frame. */
if (LIN_ident == 0x3D)
{
;
}
else
{
/* This is not a Diagnostic Response frame. Load the received data into the signals
* associated with the frame. */
lin_make_signal_data(LIN_frame_name);
}
}
API_RX_END_FLG = 1; /* Set LIN_RX_END_FLG. */
/* Set the interface status and set the bus into the QUIET state. */
lin_set_ifc_status(LIN_ident_PB, LIN_IFC_COMPLETE);
lin_change_bus_status(QUIET_STATE);
}
else
{
/* The checksums did not compare. */
if (LIN_frame_type == UNCONDITION_FRAME)
{
/* This was an Unconditional frame. Set error status. */
#ifdef EXTENDED_ERROR_STATS
/* Increment the receive checksum error count. */
LIN_rcv_checksum_err++;
#endif /* EXTENDED_ERROR_STATS. */
LIN_frame_error_flag = 1; /* Frame error - retry the frame. */
API_RX_END_FLG = 1; /* Set LIN_RX_END_FLG. */
/* Set the interface status to error and set the bus to the QUIET state. */
lin_set_ifc_status(LIN_ident_PB, LIN_IFC_ERROR);
lin_change_bus_status(QUIET_STATE);
}
}
}
else
{
/* An overrun or framing error occurred. */
API_RX_END_FLG = 1; /* Set LIN_RX_END_FLG. */
/* Set the interface status to error and set the bus to the QUIET state. */
lin_set_ifc_status(LIN_ident_PB, LIN_IFC_ERROR);
lin_change_bus_status(QUIET_STATE);
}
}
#else /* End of Master node. Slave node receive code begins here. */
/* If the LIN bus is in the SYNC_RECEIVE state, the sync byte will
* be received and processed. If the sync byte is to be measured
* to allow adjustment of the Baud rate, the bus state will be in
* the IDENTIFY_RECEIVE state before the serial interrupt is
* enabled. */
if (LIN_bus_status == SYNC_RECEIVE_STATE)
{
/* The sync byte will not be measured to adjust the Baud rate. The
* function "lin_read_serial_data()" will return 1 if the sync
* byte was received in error (framing or overrun). */
if (lin_read_serial_data(&sync_code) != 0)
{
/* The sync byte was in error. Return the LIN bus to the QUIET state. */
lin_change_bus_status(QUIET_STATE);
}
else
{
/* The sync byte was received properly. */
if (sync_code == 0x55)
{
/* The sync byte is correct, put the bus in the IDENTIFY_RECEIVE
* state. */
lin_change_bus_status(IDENTIFY_RECEIVE_STATE);
}
else
{
/* The sync byte was in error. Return the LIN bus to the QUIET state. */
lin_change_bus_status(QUIET_STATE);
}
}
}
else if (LIN_bus_status == IDENTIFY_RECEIVE_STATE)
{
/* Read and process the message ID byte. The function "lin_read_serial_data()"
* will return 1 if the ID byte was received in error (framing or overrun). */
if (lin_read_serial_data(&LIN_ident_PB) != 0)
{
/* The ID byte was in error. Return the LIN bus to the QUIET state. */
lin_change_bus_status(QUIET_STATE) ;
}
else
{
LIN_ident = LIN_ident_PB & (unsigned char)0x3F; /* Strip off the parity bits. */
/* Remake the complete ID byte using the 6-bit ID code. If the two
* bytes match, the Protected ID checksum is valid and the Protected
* ID can be used. */
if (LIN_ident_PB == lin_make_protected_identifier(LIN_ident))
{
/* The Protected ID is valid. Clear the "frame_valid_flag". */
frame_valid_flag = 0;
/* Clear the frame error flag to prepare for data reception. */
LIN_frame_error_flag = 0;
/* If the ID is less than 0x3C, this is a normal LIN message frame
* either of type Unconditional or Event Triggered. */
if (LIN_ident < 0x3C)
{
/* This is a "normal" message frame. */
i = 0;
/* Search the "LIN_id_table[]" for a matching ID. The ID value 0xFE
* is an invalid value that indicates the end of the table. */
while (LIN_id_table[i].frame_id != 0xFE)
{
/* Check to see if this is a message ID that this Slave node processes. */
if (LIN_id_table[i].frame_id == LIN_ident)
{
/* The ID will be processed by this Slave node. Set the frame type from
* the value in "LIN_id_table[]". */
LIN_frame_type = LIN_id_table[i].frame_type;
/* The frame "name" (which is actually just the index value into "LIN_id_table[]")
* is the current value of "i". */
LIN_frame_name = (unsigned char)i;
/* Set the "frame_valid_flag" to indicate that this frame should be
* processed. */
frame_valid_flag = 1;
/* Initialize the LIN checksum byte according to the type specified for
* this ID. This should be "enhanced". */
lin_init_check_sum(LIN_id_table[LIN_frame_name].check_sum_type);
/* A valid frame ID has been found. Break out of the loop. */
break;
}
i++;
}
/* If the "frame_valid_flag" is set, this frame should be processed
* by this Slave node - either by transmitting the data bytes or by
* receiving them. */
if (frame_valid_flag == 1)
{
/* If the publisher configured for this frame ID is this slave node,
* go to transmit. */
if (LIN_id_table[LIN_frame_name].node_name == LIN_MY_NODE_NAME)
{
/* Place the bus in the QUIET state before calling the data transmit
* function to publish the data for this frame ID. The function
* "l_ifc_tx()" will check the frame type and, if the frame type is
* EVENT_TRIGGERED, data will be published only if the signal
* associated with the frame ID has been updated. */
l_ifc_tx(LIN);
}
else
{
/* This slave node does not publish the data for this message frame
* ID. Place the bus in the DATA_RECEIVE state to prepare to receive
* the message data bytes. */
lin_change_bus_status(DATA_RECEIVE_STATE);
}
}
else
{
/* This frame will not be processed by this slave device. Place the
* bus back in the quiet state to await the next BREAK. */
lin_change_bus_status(QUIET_STATE);
}
}
#if ((defined USE_POWER_CONTROL) || (defined ENABLE_DIAG))
else
{
/* If USE_POWER_CONTROL is defined, the Slave node must be able to receive
* the Go To Sleep command (PID 0x3C with NAD 0x00). If ENABLE_DIAG is
* defined, the Slave node must be able to respond to any of a number of
* diagnostic messages - all with PID's of 0x3C, 0x3D or 0x3E. Initialize
* the checksum as required for a "classic" LIN checksum. Diagnostic
* frames always use the "classic" checksum. The checksum must always be
* initialized here whether the Slave node will read or publish the data,
* and it will not matter if the checksum is cleared if the Slave node
* will not do either. */
LIN_sum_code = 0;
/* Initialize "LIN_frame_type". */
LIN_frame_type = UNCONDITION_FRAME;
switch (LIN_ident)
{
/* PID 0x3C is used for every function that would cause either ENABLE_DIAG
* or USE_POWER_CONTROL to be defined. */
case 0x3C:
{
/* This is a Master diagnostic request frame. The Slave node
* must read the data. */
LIN_frame_name = MASTER_DIAG_REQ; /* This references the Master request signal. */
lin_change_bus_status(DATA_RECEIVE_STATE);
LIN_DIAG_mode = 1;
break;
}
/* PID 0x3D is used only for those functions that would cause ENABLE_DIAG to
* be defined. The Slave node does not respond to the Go To Sleep command. */
default:
{
/* This is a reserved diagnostic frame (or a user defined diagnostic
* frame and user diagnostics are not implemented). The Slave node
* has nothing to do. Place the bus back in the quiet state to await
* the next BREAK. */
lin_change_bus_status(QUIET_STATE);
break;
}
}
}
#else /* USE_POWER_CONTROL or ENABLE_DIAG defined. */
else
{
/* This is a diagnostic frame (or a user defined diagnostic frame)
* and diagnostics are not implemented). The Slave node has nothing
* to do. Place the bus back in the quiet state to await the next BREAK. */
lin_change_bus_status(QUIET_STATE);
}
#endif /* USE_POWER_CONTROL or ENABLE_DIAG defined. */
}
else
{
/* The ID byte was in error. There is nothing for the Slave node to do.
* Return the LIN bus to the QUIET state. */
lin_change_bus_status(QUIET_STATE);
}
}
}
else if (LIN_bus_status == DATA_RECEIVE_STATE)
{
/* This byte is a data byte, perhaps the first. The function "lin_read_serial_data()"
* will return 1 if the data byte was received in error (framing or overrun).
* Otherwise, it will return 0 and write the byte into the appropriate byte of the
* "LIN_data[]" array. */
if (lin_read_serial_data(&LIN_data[LIN_RX_count]) != 0)
{
/* The data byte was in error. Return the LIN bus to the QUIET
* state, set the interface to the error state and set the receive
* end flag. Set the frame error flag, but continue trying to
* receive the message frame. */
LIN_frame_error_flag = 1;
}
/* The data byte is good. Note: "LIN_RX_count" is initialized to zero at the
* time the bus state is changed to the DATA_RECEIVE state.*/
if (LIN_RX_count == 0)
{
/* Set up the expected receive length. Add the count for the checksum
* byte to the message data length. */
LIN_rx_receive_length = LIN_id_table[LIN_frame_name].data_length + (unsigned char)1;
}
LIN_RX_count++; /* Increment the received byte count. */
if (LIN_rx_receive_length != LIN_RX_count)
{
/* This is not the last byte expected, add the value to the checksum
* being calculated. */
lin_make_check_sum(LIN_data[LIN_RX_count - 1]);
}
else
{
/* This is the last byte expected (checksum). Process the data. */
if (LIN_frame_error_flag == 0)
{
/* No overrun or framing errors occurred. This is the last byte
* expected. Process the data. Complete the calculation of the
* checksum by bitwise inverting the current value of the checksum. */
LIN_sum_code = ~LIN_sum_code;
/* If the calculated checksum is equal to the transmitted checksum (the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -