📄 lin_low_level.c
字号:
for (j = 0; j < signal_byte; j++)
{
*dptr++ = *p++;
}
}
}
#endif /* ENABLE_ODD_SIGNAL_WIDTHS. */
return;
}
/**********************************************************************
* Function Name: lin_make_signal_data()
* Description: Reads out the data in a received message frame and
* updates the signal values.
* Parameters: frame_name - index value of the frame just received.
* Returns: Nothing.
* Ext. References: LIN_frame_type, LIN_data[], LIN_id_table[], LIN_signal_table[].
* Preemptible: Yes.
* Reentrant: No.
*********************************************************************/
void lin_make_signal_data(unsigned char frame_name)
{
int i, j;
unsigned char *p, *fstp, *dptr;
unsigned char max_sig;
union {
unsigned int d_int;
unsigned char d_byte[2];
} buf;
union {
unsigned int d_int;
unsigned char d_byte[2];
} save;
unsigned char set_byte, set_bit, signal_name, offset, signal_byte, signal_bit;
unsigned char start_byte, signal_change;
#ifdef ENABLE_ODD_SIGNAL_WIDTHS
unsigned int mask_int;
#endif
start_byte = 0;
#ifndef ENABLE_ODD_SIGNAL_WIDTHS /* Limits scalar signal data size to 8 or 16 bits. */
/* Save the number of signals in the frame. */
max_sig = LIN_id_table[frame_name].num_sigs;
/* Set the pointer to point to the first signal in the frame table. */
fstp = LIN_id_table[frame_name].data_address;
/* Loop through all of the signals associated with a LIN message frame ID. */
for (i = 0; i < max_sig; i++)
{
/* Get the index number of a signal. */
signal_name = *fstp++;
/* Determine the bit offset of the signal data in the LIN data buffer. */
offset = *fstp++;
/* Get the number of bytes in the signal value. */
signal_byte = LIN_signal_table[signal_name].signal_byte;
set_byte = offset / (unsigned char)8;
/* Set a pointer to the first data byte of the signal value. */
p = LIN_signal_table[signal_name].signal_address + 1;
/* Set a pointer to the (initial) source byte in "LIN_data[]". */
dptr = (unsigned char *)&LIN_data[set_byte + start_byte];
signal_change = 0x00; /* Initialize "signal_change" to "no_change". */
/* Read the signal value from the LIN data buffer at the appropriate
* location. */
for (j = 0; j < signal_byte; j++)
{
/* If the new and old values are not equal, set "signal_change" to mark the
* signal as updated. */
if (*p != *dptr)
{
signal_change = 0x80;
}
*p++ = *dptr++;
}
/* Mark the signal as updated, if needed. If all data bytes were equal to the
* current state of the signal data, "signal_change" will still be 0x00 - no change. */
if (signal_change != 0x00)
{
*LIN_signal_table[signal_name].signal_address = signal_change;
}
}
#else /* Odd length signals allowed (signal size not evenly divisable by 8). */
/* Save the number of signals in the frame. */
max_sig = LIN_id_table[frame_name].num_sigs;
/* Set the pointer to point to the first signal in the frame table. */
fstp = LIN_id_table[frame_name].data_address;
/* Loop through all of the signals associated with a LIN message frame ID. */
for (i = 0; i < max_sig; i++)
{
/* Get the index number of a signal. */
signal_name = *fstp++;
/* Determine the bit offset of the signal data in the LIN data buffer. */
offset = *fstp++;
/* Get the number of bytes in the signal value - 1 or 2. */
signal_byte = LIN_signal_table[signal_name].signal_byte;
/* Get the number of bits in the signal value - 0 through 15. */
signal_bit = LIN_signal_table[signal_name].signal_bit;
/* "offset" is the number of bits (0 through 63) that lie "below" the
* LSB of this signal in the "LIN_data[]" array. "offset" must be
* divided up to produce "set_byte" number of bytes completely offset (0
* through 7) and "set_bit" number of bits offset in the last byte (also
* 0 through 7). */
set_byte = offset >> 3;
set_bit = offset & (unsigned char)0x07;
/* Set a pointer to the first data byte of the signal value. */
p = LIN_signal_table[signal_name].signal_address + 1;
/* Set a pointer to the (initial) destination byte in "LIN_data[]". */
dptr = (unsigned char *)&LIN_data[set_byte + start_byte];
signal_change = 0x00; /* Initialize "signal_change" to "no_change". */
/* If "signal_byte" is 1 or 2, the signal may be a scalar signal with a
* length of between 1 and 16 bits. A scalar signal may be packed into
* the "LIN_data[]" array starting at any given bit (0 to 63) within the
* array, but a scalar value may cross only a single byte boundary within
* the array. If "signal_byte" is 1 or 2, the signal may also be a byte
* array. However, a byte array may be stored only in byte locations
* within the "LIN_data[]" array, meaning that the starting bit must
* always be bit 0 of some byte. If "signal_byte" is 3 or greater (max
* of 8), the signal is a byte array. */
if (signal_byte < 3)
{
/* Set a mask for the bit size of the signal. */
mask_int = LIN_bit_masks[signal_bit];
/* Read the signal data into "buf.d_int" to allow it to be bit shifted as
* a complete value. */
buf.d_byte[0] = *dptr++;
buf.d_byte[1] = *dptr;
/* Shift the signal value toward the LSbit by "set_bit" number of positions.
* A LIN scalar value may be 1 to 16 bits in length, but the value may
* cross only a single byte boundary. This means the the 16-bit "buf.d_int"
* will always be able to hold any (valid) combination of signal length and
* bit shifts without losing any bits. */
buf.d_int >>= set_bit;
/* Mask off the unused MSBits. */
buf.d_int &= mask_int;
/* Load the LSByte of the read value into the signal data buffer. If the new
* and old values are not equal, set "signal_change" to mark the signal as updated. */
if (*p != buf.d_byte[0])
{
signal_change = 0x80;
}
*p++ = buf.d_byte[0];
/* If necessary, load the MSByte of the read value into the signal data buffer. */
if (signal_bit > 8)
{
/* If the new and old values are not equal, set "signal_change" to mark the
* signal as updated. */
if (*p != buf.d_byte[1])
{
signal_change = 0x80;
}
*p = buf.d_byte[1];
}
}
else
{
/* This is a byte array. Read the signal value from the LIN data buffer at
* the appropriate locations. */
for (j = 0; j < signal_byte; j++)
{
/* If the new and old values are not equal, set "signal_change" to mark the
* signal as updated. */
if (*p != *dptr)
{
signal_change = 0x80;
}
*p++ = *dptr++;
}
}
/* Mark the signal as updated, if needed. If all data bytes were equal to the
* current state of the signal data, "signal_change" will still be 0x00 - no change. */
if (signal_change != 0x00)
{
*LIN_signal_table[signal_name].signal_address = signal_change;
}
}
#endif /* ENABLE_ODD_SIGNAL_WIDTHS. */
return;
}
/**********************************************************************
* Function Name: lin_signal_write()
* Description: Copies a new signal value into "LIN_signal_table"
* if the signal value has changed. Marks the signal
* as changed or unchanged appropriately.
* Parameters: signal_name - index number assigned to the signal.
* bit_size - bit length of the signal.
* write_data - new signal value.
* Returns: Nothing.
* Ext. References: LIN_signal_table
* Preemptible: Yes.
* Reentrant: No.
*********************************************************************/
void lin_signal_write(unsigned char signal_name, unsigned char bit_size, unsigned int write_data)
{
unsigned char flag_state;
unsigned char *p;
union {
unsigned int d_int;
unsigned char d_byte[2];
} write_buf;
union {
unsigned int d_int;
unsigned char d_byte[2];
} buf;
#ifdef ENABLE_ODD_SIGNAL_WIDTHS
union {
unsigned int d_int;
unsigned char d_byte[2];
} mask;
#endif
#ifndef ENABLE_ODD_SIGNAL_WIDTHS /* Limits scalar signal data size to 8 or 16 bits. */
/* Load the pointer "p" to point to the first data byte of the current signal value. */
p = LIN_signal_table[signal_name].signal_address + 1;
/* Copy current signal value into "buf". */
if (bit_size <= 8)
{
buf.d_int = 0;
}
else
{
buf.d_byte[1] = *(p + 1);
}
buf.d_byte[0] = *p;
/* Copy new value into "write_buf". */
write_buf.d_int = write_data;
/* If the values are not equal, copy the new value into the signal data array
* and mark the signal as changed. */
if (buf.d_int != write_buf.d_int)
{
/* Not equal. */
flag_state = l_sys_irq_disable(); /* Disable the global interrupt. */
/* Copy the new value into the signal data array and mark the signal as changed. */
if (bit_size > 8)
{
*(p + 1) = write_buf.d_byte[1];
}
*p-- = write_buf.d_byte[0];
*p = 0x80; /* Mark the signal as being changed. */
l_sys_irq_restore(flag_state); /* Restore the global interrupt. */
}
#else /* Odd length signals allowed (signal size not evenly divisable by 8). */
/* Set a mask for the bit size of the signal. */
mask.d_int = LIN_bit_masks[bit_size];
/* Load the pointer "p" to point to the first data byte of the current signal value. */
p = LIN_signal_table[signal_name].signal_address + 1;
/* Copy current signal value into "buf". */
if (bit_size <= 8)
{
buf.d_int = 0;
}
else
{
buf.d_byte[1] = *(p + 1) & mask.d_byte[1];
}
buf.d_byte[0] = *p & mask.d_byte[0];
/* Copy new value into "write_buf". */
write_buf.d_int = write_data & mask.d_int;
/* If the values are not equal, copy the new value into the signal data array
* and mark the signal as changed. */
if (buf.d_int != write_buf.d_int)
{
/* Not equal. */
flag_state = l_sys_irq_disable(); /* Disable the global interrupt. */
/* Copy the new value into the signal data array and mark the signal as changed. */
if (bit_size > 8)
{
*(p + 1) = write_buf.d_byte[1];
}
*p-- = write_buf.d_byte[0];
*p = 0x80; /* Mark the signal as being changed. */
l_sys_irq_restore(flag_state); /* Restore the global interrupt. */
}
#endif /* ENABLE_ODD_SIGNAL_WIDTHS. */
return;
}
/**********************************************************************
*
* Modification Record
*
**********************************************************************
*
* Version 1.1 for R8C 16 Mar 2006 Bob Chamberlain
* 01.08.2007 RTA-CSS version 1.17. id0x8 fix done in lin_low_level.c by Bob C.
* 08.24.2007 RTA-CSS defines EVENT_TRIG_FRAME and SPORADIC_FRAME removed
* from LIN Starter Demo version.
*********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -