📄 lin_api.c
字号:
/* If "LIN_change_schedule" is not equal to 0xFF, a change to a new schedule table
* has been commanded. Switch to this schedule table before sending a frame. */
if (LIN_change_schedule != 0xFF)
{
LIN_now_schedule = LIN_change_schedule;
/* Predecrement "LIN_now_entry" by 1 to make up for the increment that will
* take place before "LIN_now_entry" is actually used. */
LIN_now_entry = LIN_change_entry - (unsigned char)1;
LIN_change_schedule = 0xFF;
/* Make sure all flags that control the selection of the next frame to be sent
* are cleared to insure that the schedule change takes place as planned. */
LIN_frame_error_flag = 0;
LIN_retry_count = 0;
}
/* "LIN_slot_time" has been set to the delay time in ms that must elapse
* before the next frame is sent. Decrement "LIN_slot_time" by the value
* of "LIN_TIME_BASE" and return if the result is still greater than 0.
* This allows the implementation of a variable slot time in multiples of
* "LIN_TIME_BASE". */
LIN_slot_time -= LIN_TIME_BASE; /* Decrement the slot time. */
/* If the slot time delay has expired, send the next frame. */
if (LIN_slot_time <= 0)
{
/* The slot time has expired and a new frame will now be sent. */
#ifdef USE_POWER_CONTROL /* Implemented only if power control is used. */
if (LIN_schedule_stop_flag == 2)
{
/* A call as been made to "l_ifc_goto_sleep()" and the current slot time has
* expired. Complete the LIN Go-To-Sleep message and then shut down the
* schedule timer. */
lin_goto_sleep(); /* Send the Go-To-Sleep message frame. */
#ifdef DEDICATED_SCHEDULE_TIMER
SCH_TMR_RUN = 0; /* Stop the LIN schedule timer. */
#endif
LIN_schedule_stop_flag = 1; /* Halt Master schedule action. */
}
#endif /* USE_POWER_CONTROL. */
/* Process a new frame only if the current schedule table is not the NULL schedule
* table and only if the "LIN_schedule_stop_flag" is not set. */
if ((LIN_now_schedule != LIN_L_NULL_SCHEDULE) && (LIN_schedule_stop_flag == 0))
{
/* Set the bus state to QUIET (as it should already be). */
lin_change_bus_status(QUIET_STATE);
/* If the last frame had a transfer error and there are retries still permitted
* simply decrement the retry count and re-send the previous frame. */
if ((LIN_frame_error_flag == 1) && (LIN_retry_count > 0))
{
LIN_retry_count--;
}
else
{
/* Increment "LIN_now_entry" to point to the next slot in the schedule
* table. */
LIN_now_entry++;
/* If the max number of slots in the schedule table has been exceeded,
* wrap around to slot 1 of the table. */
if (LIN_now_entry > LIN_schedule_table[LIN_now_schedule].num_slots)
{
LIN_now_entry = 1;
}
/* This will be a new frame. Reset "LIN_retry_count" to the max to allow
* retries for this frame. */
LIN_retry_count = LIN_NUM_RETRIES;
}
/* Clear "LIN_frame_error_flag" before processing the new frame or repeating
* the previous one. */
LIN_frame_error_flag = 0;
ret = LIN_now_entry; /* Set up the return value. */
/* The schedule table and entry in this schedule table for the next frame are
* now known. Set a pointer to the "frame_type" field of the selected frame of
* the current schedule table. Each entry in the schedule table requires 4 bytes.
* "LIN_now_entry" is 1 based. The entries in a schedule table are 0 based. */
p = LIN_schedule_table[LIN_now_schedule].schedule_address + ((LIN_now_entry - 1) * 4);
/* Read the frame values into the global variables. */
LIN_frame_type = *p; /* Type of frame. */
LIN_frame_name = *(p + 1); /* Name of the frame ("enumerated"). */
LIN_slot_time = *((unsigned int *)(p + 2)); /* Delay time in ms until the next frame. */
/* If this was an Unconditional frame to begin with or if it was a Sporadic
* frame and there is a command to be sent, "LIN_frame_type" will now be set
* to UNCONDITION_FRAME. A frame will be sent only if the frame type is not
* SPORADIC_FRAME - meaning this was an Unconditional frame to begin with, it
* is an Event Triggered frame or it was a Sporadic frame that was switched
* to an Unconditional frame because there is a command to be sent. */
/* Generate the LIN protected ID byte. */
LIN_ident = LIN_id_table[LIN_frame_name].frame_id;
LIN_ident_PB = lin_make_protected_identifier(LIN_ident);
/* Initialize the global checksum byte. */
lin_init_check_sum(LIN_id_table[LIN_frame_name].check_sum_type);
/* Send the LIN break to start the message frame. */
lin_send_break();
}
else
{
/* This is the default NULL schedule table. The Master mode has no frames
* to send. The return value will be 0. Preset "LIN_slot_time" to get
* "instant" execution when an active schedule table eventually is set. */
LIN_slot_time = LIN_TIME_BASE;
}
}
else
{
/* The time slot has not expired. Return the value of the entry now
* being processed. */
ret = LIN_now_entry;
}
}
/* If "LIN_CORE_TIME_ENABLE" is defined, LIN core time measurements are being made.
* Turn off the "LIN_CORE_TIME" output pin. */
#ifdef LIN_CORE_TIME_ENABLE
LIN_CORE_TIME = 0;
#endif
return (ret);
}
#endif /* Master node. */
/* This function is implemented only if "ENABLE_ODD_SIGNAL_WIDTHS" is
* defined, which allows signal bit widths other than 8 or 16 bits. */
#ifdef ENABLE_ODD_SIGNAL_WIDTHS
/**********************************************************************
* Function Name: l_bool_rd()
* Description: Reads the current value of a Boolean signal.
* Parameters: signal_name - index value of the signal name to be read.
* Returns: 8-bit Boolean value.
* Ext. References: LIN_signal_table[].
* Preemptible: No.
* Reentrant: No.
*********************************************************************/
l_bool l_bool_rd(l_signal_handle signal_name)
{
unsigned char buf;
unsigned char *p;
unsigned char flag_state;
/* Set a pointer to the signal data byte. */
p = LIN_signal_table[signal_name].signal_address + 1;
flag_state = l_sys_irq_disable(); /* Disable the global interrupt. */
/* Load "buf" with the LS data byte of the signal, with all bits but the LSBit masked off. */
buf = *p-- & (unsigned char)0x01;
/* Clear the signal update byte. */
*p = 0x00;
l_sys_irq_restore(flag_state); /* Restore the global interrupt. */
/* Return the read value. The only possible return values are 0x01 and 0x00. */
return (buf);
}
#endif /* ENABLE_ODD_SIGNAL_WIDTHS. */
/**********************************************************************
* Function Name: l_u8_rd()
* Description: Reads the current value of an 8-bit signal.
* Parameters: signal_name - index value of the signal name to be read.
* Returns: 8-bit value.
* Ext. References: LIN_signal_table.
* Preemptible: No.
* Reentrant: No.
*********************************************************************/
l_u8 l_u8_rd(l_signal_handle signal_name)
{
unsigned char buf;
unsigned char flag_state;
int bit_size;
#ifdef ENABLE_ODD_SIGNAL_WIDTHS
union {
unsigned int d_int ;
unsigned char d_byte[2];
} mask;
#endif
#ifndef ENABLE_ODD_SIGNAL_WIDTHS
/* Only 8-bit signal widths are allowed. */
flag_state = l_sys_irq_disable(); /* Disable the global interrupt. */
/* Read the signal data byte into "buf". */
buf = *(LIN_signal_table[signal_name].signal_address + 1);
/* Clear the signal update status byte. */
*LIN_signal_table[signal_name].signal_address = 0x00;
l_sys_irq_restore(flag_state); /* Restore the global interrupt. */
#else /* Bit widths from 1 to 8 bits are allowed. */
bit_size = LIN_signal_table[signal_name].signal_bit; /* Read the signal data bit width. */
/* Limit the bit-width to 8 bits max. */
if (bit_size > 8)
{
bit_size = 8;
}
mask.d_int = LIN_bit_masks[bit_size]; /* Initialize the 16-bit mask. */
flag_state = l_sys_irq_disable(); /* Disable the global interrupt. */
/* Read the signal data byte into "buf", masking of some MSBits as required by "bit_size". */
buf = *(LIN_signal_table[signal_name].signal_address + 1) & mask.d_byte[0];
/* 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_ODD_SIGNAL_WIDTHS. */
/* Return "buf". An 8-bit value is always returned, but some of the MSBits may be masked
* off if "ENABLE_ODD_SIGNAL_WIDTHS" is defined. */
return (buf);
}
/**********************************************************************
* Function Name: l_u16_rd()
* Description: Reads the current value of an 16-bit signal.
* Parameters: signal_name - index value of the signal name to be read.
* Returns: 16-bit value.
* Ext. References: LIN_signal_table.
* Preemptible: No.
* Reentrant: No.
*********************************************************************/
l_u16 l_u16_rd(l_signal_handle signal_name)
{
unsigned char flag_state;
unsigned char *p;
int bit_size;
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
p = LIN_signal_table[signal_name].signal_address + 1;
#ifndef ENABLE_ODD_SIGNAL_WIDTHS
/* Only 16-bit signal widths are allowed. Read the 16-bit signal data value,
* bytewise, into "buf". */
flag_state = l_sys_irq_disable(); /* Disable the global interrupt. */
buf.d_byte[0] = *p++;
buf.d_byte[1] = *p;
/* Clear the signal update status byte. */
*LIN_signal_table[signal_name].signal_address = 0x00;
l_sys_irq_restore(flag_state); /* Restore the global interrupt. */
#else /* Bit widths from 1 to 16 bits are allowed. */
bit_size = LIN_signal_table[signal_name].signal_bit; /* Read the signal data bit width. */
if (bit_size > 16)
{
bit_size = 16;
}
mask.d_int = LIN_bit_masks[bit_size]; /* Initialize the 16-bit mask. */
/* Read the 16-bit signal data value, bytewise, into "buf", masking of some MSBits as required by "bit_size". */
flag_state = l_sys_irq_disable(); /* Disable the global interrupt. */
buf.d_byte[0] = (*p++ & mask.d_byte[0]);
buf.d_byte[1] = (*p & mask.d_byte[1]);
/* 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_ODD_SIGNAL_WIDTHS. */
/* Return "buf". A 16-bit value is always returned, but some of the MSBits may be masked
* off if "ENABLE_ODD_SIGNAL_WIDTHS" is defined. */
return (buf.d_int);
}
/* This function is implemented only if "ENABLE_ODD_SIGNAL_WIDTHS" is
* defined, which allows signal bit widths other than 8 or 16 bits. */
#ifdef ENABLE_ODD_SIGNAL_WIDTHS
/**********************************************************************
* Function Name: l_bool_wr()
* Description: Stores a new value for an 8-bit boolean 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_bool_wr(l_signal_handle signal_name, l_bool write_data)
{
union {
unsigned int d_int;
unsigned char d_byte[2];
} buf;
/* Load the write value (1 bit) into "buf" as an integer. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -