lin_interface.c
来自「芯科原厂所有c8051fxx程序的例子。」· C语言 代码 · 共 317 行
C
317 行
// Copyright (c) 2006 SILICON LABORATORIES, INC.
//
// FILE NAME : LIN_Interface.c
// TARGET MCU : C8051F52xA-53xA
// DESCRIPTION : Interface-level routines for Core LIN API
//
// This file implements interface-level Core LIN API routines.
//
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include <c8051F520.h>
#include "LIN.h"
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
//
// These variables are used globally in LIN_Interface.c:
//
// 1. status_std_ifc - Status variable defined by the LIN specification.
// It reports status information in the following format:
//
// a. status_std_ifc [15:8] - Last Frame PID: Contains the PID of the last
// frame detected on the bus and processed in the node.
//
// b. status_std_ifc [7] - 0
//
// c. status_std_ifc [6] - Save Configuration: Set when the Save
// Configuration Request has been successfully received. Only set in
// the slave node (i.e. always 0 in the master node).
//
// d. status_std_ifc [5] - Event-Triggered Frame Collision: Set as long as
// the collision resolving schedule is executing. Only set in the
// master node (i.e. always 0 in the slave node).
//
// e. status_std_ifc [4] - Bus Activity: Set if the node has detected
// activity on the bus.
//
// f. status_std_ifc [3] - Go to Sleep: Set in a slave node if a go to
// sleep command has been received. Set in a master node if a go to
// sleep command has been successfully transmitted on the bus.
//
// g. status_std_ifc [2] - Overrun: Set if two or more frames are processed
// since the last call to l_ifc_read_status ().
//
// h. status_std_ifc [1] - Successful Transfer: Set if a frame has been
// received or transmitted without an error.
//
// i. status_std_ifc [0] - Error in Response: Set if a frame error is
// detected in the frame response (e.g. checksum error, framing
// error, synch error, etc.). Not set in the event of a bus timeout.
//
// 2. rx_valid_data - This bit indicates whether the current received data is
// valid or invalid.
//
l_ifc_status status_std_ifc;
l_bool rx_valid_data;
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// l_ifc_init_std_ifc ()
//-----------------------------------------------------------------------------
//
// Initializes the interface (std_ifc).
//
l_bool l_ifc_init_std_ifc (void)
{
// Initialize the LIN bit rate.
LIN_Bit_Rate_Init ();
// Initialize status_std_ifc.
status_std_ifc = 0x0000;
#if (LIN_MODE == LIN_MASTER)
// Set the schedule to L_NULL_SCHEDULE.
l_sch_set_std_ifc(L_NULL_SCHEDULE, 0);
#endif // LIN_MODE == LIN_MASTER
return (1);
}
#if (LIN_MODE == LIN_MASTER)
//-----------------------------------------------------------------------------
// l_ifc_goto_sleep_std_ifc ()
//-----------------------------------------------------------------------------
//
// Requests all slave nodes on the interface std_ifc to enter
// sleep mode.
//
void l_ifc_goto_sleep_std_ifc (void)
{
// Use the diagnostic_master_request_schedule.
l_sch_set_std_ifc (diagnostic_master_request_schedule, 0);
}
#endif // LIN_MODE == LIN_MASTER
//-----------------------------------------------------------------------------
// l_ifc_wake_up_std_ifc ()
//-----------------------------------------------------------------------------
//
// Sends the wake-up signal to all nodes on interface std_ifc.
//
void l_ifc_wake_up_std_ifc (void)
{
// Call function in the driver to send the wakeup signal.
l_transmit_wake_up ();
}
//-----------------------------------------------------------------------------
// l_ifc_rx_std_ifc ()
//-----------------------------------------------------------------------------
//
// Handles received frames.
//
void l_ifc_rx_std_ifc (void)
{
l_u8 frame_id;
l_u8 frame_data[8];
// Get the frame ID received.
frame_id = l_read_frame_id ();
// Get the frame data.
l_read_frame_data (frame_data);
if ((frame_id == MASTER_REQUEST_FRAME_ID) || (frame_id == SLAVE_RESPONSE_FRAME_ID))
{
// Process the diagnostic frame if a diagnostic frame was received.
l_process_rx_diagnostic_data (frame_data);
// Update the status with valid data.
l_ifc_update_status_std_ifc (TRUE);
// Set rx_valid_data to true.
rx_valid_data = TRUE;
}
else
{
// Process the received frame data.
if (l_process_rx_frame_data (frame_id, frame_data))
{
// Update the status with valid data.
l_ifc_update_status_std_ifc (TRUE);
// Set rx_valid_data to true.
rx_valid_data = TRUE;
}
else
{
// Update the status with invalid data.
l_ifc_update_status_std_ifc (FALSE);
// Set rx_valid_data to false.
rx_valid_data = FALSE;
}
}
}
//-----------------------------------------------------------------------------
// l_ifc_tx_std_ifc ()
//-----------------------------------------------------------------------------
//
// Performs any operations necessary after the transmission of a frame.
//
void l_ifc_tx_std_ifc (void)
{
l_u8 frame_id;
l_u8 frame_data[8];
// Get the frame ID received.
frame_id = l_read_frame_id ();
// Get the frame data.
l_read_frame_data (frame_data);
if ((frame_id == MASTER_REQUEST_FRAME_ID) || (frame_id == SLAVE_RESPONSE_FRAME_ID))
{
// Handle diagnostic frames.
l_diagnostic_tx_complete (frame_data);
}
else
{
// Update signals after successful transmission.
l_tx_complete (frame_id, frame_data);
}
// Update the status with valid data.
l_ifc_update_status_std_ifc (TRUE);
}
//-----------------------------------------------------------------------------
// l_ifc_read_status_std_ifc ()
//-----------------------------------------------------------------------------
//
// Returns the status of interface std_ifc. The return value is a 16-bit value.
// The format of the return value is:
//
// [15 : 8] - Last frame PID.
// [7] - 0
// [6] - Save configuration
// [5] - Event-triggered frame collision
// [4] - Bus activity
// [3] - Go to sleep
// [2] - Overrun
// [1] - Successful transfer
// [0] - Error in response
//
l_u16 l_ifc_read_status_std_ifc (void)
{
l_u16 retval;
// Disable interrupts while getting status information.
l_disable_global_interrupts ();
retval = status_std_ifc;
// Clear status_std_ifc.
status_std_ifc = 0x0000;
// Restore interrupts to their previous state.
l_restore_global_interrupts ();
return (retval);
}
//-----------------------------------------------------------------------------
// l_ifc_update_status_std_ifc ()
//-----------------------------------------------------------------------------
//
// Updates status_std_ifc, which is returned when the application calls
// l_ifc_read_status ().
//
// Parameters:
//
// 1. frame_data_valid - If the software has determined that the frame data
// is invalid (i.e. the frame is an unconditional frame and there is a
// parity error in the first data byte which holds the PID), this should
// be set to FALSE. Otherwise, it is true.
//
void l_ifc_update_status_std_ifc (l_bool frame_data_valid)
{
l_frame * frame_ptr;
l_u8 status;
// Set overrun in status_std_ifc if it was not read between the current
// frame and the previous frame.
if ((status_std_ifc & ~COLLISION_RESOLUTION_SCHEDULE) != 0x0000)
status_std_ifc |= OVERRUN;
// Get the status of the last LIN transmission.
status = l_get_status ();
// If frame_data_valid is FALSE, a frame error has occurred.
if (frame_data_valid == FALSE)
{
status &= ~TX_SUCCESS;
status |= TX_FRAME_ERROR;
}
// Get the frame with ID frame_id.
frame_ptr = l_get_frame (l_read_frame_id ());
// If there was a transmission error on an event-triggered frame, set
// the EVENT_TRIGGERED_FRAME_COLLISION flag in status_std_ifc.
if (frame_ptr->frame_type == EVENT_TRIGGERED_FRAME)
{
#if (LIN_MODE == LIN_MASTER)
if (status & TX_FRAME_ERROR)
{
status_std_ifc |= EVENT_TRIGGERED_FRAME_COLLISION;
status_std_ifc |= BUS_ACTIVITY;
}
#endif
}
else
{
// If there was a framing error,
if (status & TX_FRAME_ERROR)
{
status_std_ifc |= ERROR_IN_RESPONSE;
status_std_ifc |= BUS_ACTIVITY;
}
}
if (status & TX_SUCCESS)
{
// Set SUCCESSFUL_TRANSFER is the last transfer completed succesfully.
status_std_ifc |= SUCCESSFUL_TRANSFER;
status_std_ifc |= BUS_ACTIVITY;
}
// Append the most recent Frame PID to status_std_ifc.
status_std_ifc &= 0x00FF;
status_std_ifc |= (l_u16) (l_get_frame_pid (l_read_frame_id ()) << 8);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?