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 + -
显示快捷键?