📄 lin_api.c
字号:
buf.d_byte[1] = 0x00;
buf.d_byte[0] = write_data & (unsigned char)0x01;
/* Write the LSBit into the signal data field. */
lin_signal_write(signal_name, 1, buf.d_int);
}
#endif /* ENABLE_ODD_SIGNAL_WIDTHS. */
/**********************************************************************
* Function Name: l_u8_wr()
* Description: Stores a new value for an 8-bit signal.
* Parameters: signal_name - index value of the signal name to be updated.
* write_data - new value to be stored.
* Returns: Nothing.
* Ext. References: LIN_signal_table.
* Preemptible: No.
* Reentrant: No.
*********************************************************************/
void l_u8_wr(l_signal_handle signal_name, l_u8 write_data)
{
union {
unsigned int d_int;
unsigned char d_byte[2];
} buf;
unsigned char bit_size;
/* Read the bit width of the signal and limit the value to 8 bits. */
bit_size = LIN_signal_table[signal_name].signal_bit;
if (bit_size > 8)
{
bit_size = 8;
}
/* Load the write value (8 bits) into "buf" as an integer. */
buf.d_byte[1] = 0x00;
buf.d_byte[0] = write_data;
/* Write the appropriate number of bits into the signal data field. */
lin_signal_write(signal_name, bit_size, buf.d_int);
}
/**********************************************************************
* Function Name: l_u16_wr()
* Description: Stores a new value for an 16-bit signal.
* Parameters: signal_name - index value of the signal name to be updated.
* write_data - new value to be stored.
* Returns: Nothing.
* Ext. References: LIN_signal_table.
* Preemptible: No.
* Reentrant: No.
*********************************************************************/
void l_u16_wr(l_signal_handle signal_name, l_u16 write_data)
{
unsigned char bit_size;
/* Read the bit width of the signal and limit the value to 16 bits. */
bit_size = LIN_signal_table[signal_name].signal_bit;
if (bit_size > 16)
{
bit_size = 16;
}
/* Write the appropriate number of bits into the signal data field. */
lin_signal_write(signal_name, bit_size, write_data);
}
/* The following function will be available only if ENABLE_BYTE_ARRAYS is
* defined in "lin_dev.h". */
#ifdef ENABLE_BYTE_ARRAYS
/**********************************************************************
* Function Name: l_bytes_rd()
* Description: Reads a new value for a multi-byte signal.
* Parameters: signal_name - index value of the signal name to be read.
* start - offset within signal data block.
* count - number of bytes to read.
* data - pointer to the location to store the read data.
* Returns: Nothing.
* Ext. References: LIN_signal_table.
* Preemptible: No.
* Reentrant: No.
*********************************************************************/
void l_bytes_rd(l_signal_handle signal_name, l_u8 start, l_u8 count, l_u8 *data)
{
unsigned char flag_state;
unsigned char *p;
unsigned char i;
unsigned char byte_size;
/* Read the signal size in bytes. */
byte_size = LIN_signal_table[signal_name].signal_byte;
/* "start" is the first byte of the signal data field that will be read. Byte 0
* of the signal data field is the signal status byte. However, the code below adds
* 1 to the value of "start" when setting the pointer to the signal data byte. Thus,
* "start" has a valid range of 0 to "byte_size" - 1. Since "start" is an unsigned
* value, the comparison below provides a full limit check. If the value of "start"
* is out of range, nothing is done and no error is indicated. This follows the LIN
* 2.0 specification. */
if (start < byte_size)
{
/* Limit "count" such that no attempt will be made to read beyond the end of the
* signal data field. */
if ((start + count) > byte_size)
{
count = byte_size - start;
}
/* Set pointer "p" to point to the first byte of the signal data field to be read. */
p = LIN_signal_table[signal_name].signal_address + (1 + start);
flag_state = l_sys_irq_disable(); /* Disable the global interrupt. */
/* Read "count" data bytes from the signal data field. */
for (i = 0; i < count; i++)
{
*data++ = *p++; /* Read the data byte from the signal data field. */
}
/* Clear the signal update status byte. */
*LIN_signal_table[signal_name].signal_address = 0x00;
l_sys_irq_restore(flag_state); /* Restore the global interrupt. */
}
}
#endif /* ENABLE_BYTE_ARRAYS. */
/* The following function will be available only if ENABLE_BYTE_ARRAYS is
* defined in "lin_dev.h". */
#ifdef ENABLE_BYTE_ARRAYS
/**********************************************************************
* Function Name: l_bytes_wr()
* Description: Stores a new value for a multi-byte signal.
* Parameters: signal_name - index value of the signal name to be updated.
* start - offset within signal data block.
* count - number of bytes to read.
* data - pointer to the location to read the update data from.
* Returns: Nothing.
* Ext. References: LIN_signal_table.
* Preemptible: No.
* Reentrant: No.
*********************************************************************/
void l_bytes_wr(l_signal_handle signal_name, l_u8 start, l_u8 count, l_u8 *data)
{
unsigned char flag_state;
unsigned char *p;
unsigned char *statp;
unsigned char i;
unsigned char byte_size;
unsigned char data_change;
/* Read the signal size in bytes. */
byte_size = LIN_signal_table[signal_name].signal_byte;
/* "start" is the first byte of the signal data field that will be written. Byte 0
* of the signal data field is the signal status byte. However, the code below adds
* 1 to the value of "start" when setting the pointer to the signal data byte. Thus,
* "start" has a valid range of 0 to "byte_size" - 1. Since "start" is an unsigned
* value, the comparison below provides a full limit check. If the value of "start"
* is out of range, nothing is done and no error is indicated. This follows the LIN
* 2.0 specification. */
if (start < byte_size)
{
/* Limit "count" such that no attempt will be made to write beyond the end of the
* signal data field. */
if((start + count) > byte_size)
{
count = byte_size - start;
}
/* Set pointer "p" to point to the first byte of the signal data field to be written. */
statp = LIN_signal_table[signal_name].signal_address;
p = statp + (start + 1);
data_change = 0; /* Initialize the changed data flag. */
flag_state = l_sys_irq_disable(); /* Disable the global interrupt. */
/* Store "count" write data bytes into the signal data field. */
for (i = 0; i < count; i++)
{
/* If the new data byte is different from the existing signal data byte,
* mark the signal as "changed". */
if (*p != *data)
{
/* Mark the signal as "changed". */
data_change = 1;
}
*p++ = *data++; /* Copy the data byte into the signal data field. */
}
if (data_change == 1)
{
*statp = 0x80;
}
l_sys_irq_restore(flag_state); /* Restore the global interrupt. */
}
}
#endif /* ENABLE_BYTE_ARRAYS. */
/**********************************************************************
* Function Name: l_ifc_rx()
* Description: Receives a message frame from the LIN bus. This
* function is called from the LIN serial port Tx/Rx
* ISR.
* Parameters: ifc_name - index number of the LIN interface - only
* 0 is allowed.
* Returns: Nothing.
* Ext. References:
* Preemptible: No.
* Reentrant: No.
*
* Note: This routine assumes that each node implements a single LIN
* interface, defined as interface 0 in "lin_dev.h" (the value of "LIN"
* is set to 0 by default). The API software should be modified to
* allow multiple LIN interfaces to be implemented.
*********************************************************************/
void l_ifc_rx(l_ifc_handle ifc_name)
{
unsigned char temp_frame_name;
unsigned char i;
unsigned char j;
unsigned char sync_code;
unsigned char frame_valid_flag;
/* If "LIN_CORE_TIME_ENABLE" is defined, LIN core time measurements are being made.
* Turn on the "LIN_CORE_TIME" output pin. */
#ifdef LIN_CORE_TIME_ENABLE
LIN_CORE_TIME = 1;
#endif
/* Do nothing if the specified interface is not interface 0. */
if (ifc_name == LIN)
{
#if ((LIN_MASTER_NODE != LIN_MY_NODE_NAME) && (defined USE_POWER_CONTROL))
/* If the sleep timer has been implemented for a Slave node, reset it here.
* This ISR is the most frequently "pinged" area of code that indicates
* LIN bus activity. */
LIN_sleep_timer = 0;
#endif /* Slave node and USE_POWER_CONTROL is defined. */
/* Determine of this is a transmit or a receive action based on the state of the
* LIN bus. */
if (LIN_bus_status == DATA_SEND_STATE)
{
/* Transmit action. Jump to transmit processing. */
l_ifc_tx(LIN);
}
else
{
/* Receive action. Continue receive processing. */
#if (LIN_MASTER_NODE == LIN_MY_NODE_NAME)
/* This is a LIN Master node. The receive interrupt must have been
* generated by a data byte or checksum byte sent by a Slave node
* publishing data. Read the byte from the serial port receive
* buffer. The return value is 0 on success; 1 for a framing error
* or overrun error. */
if (lin_read_serial_data(&LIN_data[LIN_RX_count]) != 0)
{
/* Receive error. Set "LIN_frame_error_flag" for Unconditional frames
* to repeat them. Do not repeat Event Triggered frames, and depend
* on the checksum to catch the errors. */
if (LIN_frame_type == UNCONDITION_FRAME)
{
LIN_frame_error_flag = 1; /* Frame error - retry the frame. */
}
}
/* Whether or not there was a receive error, make the best use of the data as
* possible. "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)
{
/* This is the first receive byte. Set the expected length of the data
* plus one byte for the checksum. */
LIN_rx_receive_length = LIN_id_table[LIN_frame_name].data_length + (unsigned char)1;
}
LIN_RX_count++; /* Increment the receive byte count. */
if (LIN_rx_receive_length != LIN_RX_count)
{
/* If this is not the last byte (checksum), add the received byte
* to the checksum. */
lin_make_check_sum(LIN_data[(LIN_RX_count - 1)]);
}
else
{
/* This is the last byte (checksum). If there was a framing or overrun error,
* for an Unconditional frame, "LIN_frame_error_flag" will be set. Simply ignore
* the received data and retry the frame. This flag will never be set for Event
* Triggered frames. */
if (LIN_frame_error_flag == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -