⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lin_low_level.c

📁 针对日本瑞莎单片机r8c/23 开发的LIN网络通讯程序包括主节点和从节点
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************/
/*             Renesas Technology America, Inc. Legal Disclaimer              */
/******************************************************************************/
/* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY      */
/* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE        */
/* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR      */
/* PURPOSE.                                                                   */
/*                                                                            */
/* BY USING THE SOFTWARE HEREIN, YOU (AND YOUR COMPANY) AGREE TO BE BOUND BY  */
/* THE TERMS AND CONDITIONS OF RENESAS TECHNOLOGY AMERICA, INC.'S SOURCE CODE */
/* LICENSE AGREEMENT. PLEASE READ THIS AGREEMENT CAREFULLY. IF YOU (OR YOUR   */
/* COMPANY) DO NOT AGREE TO ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT,   */
/* DO NOT INSTALL OR USE THIS SOFTWARE AND ASSOCIATED DOCUMENTATION.          */
/*                                                                            */
/*  Copyright (c) 2003, 2004, 2005 and 2006 Renesas Technology America, Inc.  */
/******************************************************************************/
/**********************************************************************
   Title                      : lin_low_level.c

   Module Description         : This file contains the low level LIN function
                                routines.

   MCU Family                 : R8C

   Author                     : Bob Chamberlain

   Version                    : LIN API 2.0 Version 1.1
 
 *********************************************************************/

/**********************************************************************
 * Include header files
 *********************************************************************/
#include "lin_api.h"

/**********************************************************************
 * File level pragmas
 *********************************************************************/

/**********************************************************************
 * Constant and Macro Definitions using #define
 *********************************************************************/

/**********************************************************************
 * Enumerations, Structures and Typedefs
 *********************************************************************/

/**********************************************************************
 * Global and Const Variable Defining Definitions / Initializations
 *********************************************************************/
unsigned char LIN_node_status = DISCONNECT;
unsigned char LIN_bus_status  = QUIET_STATE;

#if (LIN_MASTER_NODE == LIN_MY_NODE_NAME)
   int LIN_slot_time = 0;
   unsigned char LIN_now_schedule = 0;
   unsigned char LIN_now_entry = 0;
   unsigned char LIN_change_schedule = 0xFF;
   unsigned char LIN_change_entry = 0;
   unsigned char LIN_retry_count;
   unsigned char LIN_schedule_stop_flag = 1;
#endif   /* Master node.  */
unsigned char LIN_frame_error_flag;
unsigned char LIN_TX_check_error;

unsigned char LIN_frame_type = 0;
unsigned char LIN_frame_name;
unsigned char LIN_ident;
unsigned char LIN_ident_PB;
unsigned char LIN_data[LIN_MAX_RESPONSE_LENGTH + 4];
unsigned char LIN_flags[4] = {0x00, 0x00, 0x00, 0x00};

const unsigned int LIN_bit_masks[17] = {
   0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
   0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
};

unsigned char LIN_sum_code;
unsigned char LIN_RX_count = 0;
unsigned char LIN_TX_count = 0;
unsigned char LIN_tx_send_length;
unsigned char LIN_rx_receive_length;
unsigned char LIN_ifc_status[2] = {0, 0};

unsigned char LIN_DIAG_mode;

#ifdef EXTENDED_ERROR_STATS
   unsigned char LIN_xmt_overrun_err = 0;
   unsigned char LIN_xmt_framing_err = 0;
   unsigned char LIN_xmt_checksum_err = 0;
   unsigned char LIN_xmt_readback_err = 0;
   unsigned char LIN_rcv_overrun_err = 0;
   unsigned char LIN_rcv_framing_err = 0;
   unsigned char LIN_rcv_checksum_err = 0;
#endif

/* This is the complete Go To Sleep command, to include the valid checksum as
 * the final byte.  */
#if ((LIN_MASTER_NODE == LIN_MY_NODE_NAME) && (defined USE_POWER_CONTROL))
   const unsigned char LIN_sleep_cmd[9] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
#endif

/* The following variables are required to implement the basic Node Configuration
 * commands.  */
#if ((LIN_MASTER_NODE == LIN_MY_NODE_NAME) && (defined BASIC_NODE_CONFIG))
   unsigned char LIN_diag_xfr_state = 0;
   unsigned char LIN_diag_xfr_status = 0;
   unsigned char LIN_diag_read_by_id = 0;
   unsigned char *LIN_diag_return_ptr;
#endif

/**********************************************************************
 * Static Variables With File Level Scope
 *********************************************************************/

/**********************************************************************
 * ROM Const Variables With File Level Scope
 *********************************************************************/

/**********************************************************************
 * Function Prototypes for Private Functions with File Level Scope
 *********************************************************************/

/**********************************************************************
 * Function Definitions
 *********************************************************************/

/* The break timer is initialized only for Slave nodes.  */
#if (LIN_MASTER_NODE != LIN_MY_NODE_NAME)
/**********************************************************************
 *    Function Name: lin_init_timer()
 *      Description: Set up the LIN break timer.
 *       Parameters: None.
 *          Returns: Nothing.
 *  Ext. References: LIN_MASTER_NODE, LIN_break_count, LIN_break_prescale.
 *      Preemptible: Yes.
 *        Reentrant: Yes.
 *********************************************************************/
void lin_init_timer(void)
{
   BRK_TMR_RUN = 0;                    /* Stop the break timer.  */
   BRK_TMR_INT_CTL = 0x00;             /* Disable the break timer interrupt.  */
   BRK_TMR_INT_CFG &= BRK_INT_NONE;    /* Clear all break timer interrupt source enables.  */
   BRK_TMR_FLAGS |= BRK_CLR_ALL_FLGS;  /* Clear all break timer interrupt flags.  */
   /* Initialize the break timer mode control bits according to the hardware
    * being used.  */
   BRK_TMR_MODE_REG = BRK_TMR_SLV_MODE;
   BRK_TMR_IO_REG = BRK_TMR_SLV_IO;
   /* If AUTO_CALCULATION is defined, calculate the LIN break period based on the
    * system clock frequency and the LIN Baud rate.  */
   #ifdef AUTO_CALCULATION
      /* The following math calculations should be done by the preprocessor, since all
       * of the values are defined constants.  This may result in a rounding error, but
       * it will be insignificantly small.  */
      LIN_break_prescale = (unsigned char)((((1000000 * LIN_MY_FREQUENCY) + H_DIVISOR) / DIVISOR) - 1);
      LIN_break_count = (unsigned char)((11 * BIT_FACTOR) - 1);
   #endif   /* AUTO_CALCULATION.  */
   /* Set the break timer period.  */
   BRK_TMR_PRECNT_REG = LIN_break_prescale;
   BRK_TMR_CNT_REG = LIN_break_count;
   return;
}
#endif   /* Slave node.  */

/* The schedule timer is used only for Master nodes.  */
#if (LIN_MASTER_NODE == LIN_MY_NODE_NAME)
/**********************************************************************
 *    Function Name: lin_init_schedule_timer()
 *      Description: Set up the LIN Master schedule tick timer.
 *       Parameters: None.
 *          Returns: Nothing.
 *  Ext. References: None.
 *      Preemptible: Yes.
 *        Reentrant: Yes.
 *********************************************************************/
void lin_init_schedule_timer(void)
{
   #ifdef DEDICATED_SCHEDULE_TIMER
      SCH_TMR_INT_CFG = SCH_INT_DIS;   /* Disable the schedule timer interrupt.  */
      SCH_TMR_RUN = 0;                 /* Stop the LIN schedule timer.  */
      /* Initialize the schedule timer mode control bits.  */
      SCH_TMR_MODE_REG = SCH_TMR_MODE;
      SCH_TMR_IO_REG = SCH_TMR_IO_MODE;
      /* Set the timer prescaler count to the value needed to produce 100us ticks
       * from the prescaler.  Then set the timer count to the number of 100us
       * ticks needed to produce "LIN_TIME_BASE" millisecond ticks.  */
      SCH_TMR_PRECNT_REG = SCH_TMR_INIT_PRECNT;
      SCH_TMR_CNT_REG = SCH_TMR_INIT_CNT;
   #endif
   BRK_TMR_RUN = 0;                    /* Stop the break timer.  */
   BRK_TMR_INT_CTL = 0x00;             /* Disable the break timer interrupt.  */
   BRK_TMR_INT_CFG &= BRK_INT_NONE;    /* Clear all break timer interrupt source enables.  */
   BRK_TMR_FLAGS |= BRK_CLR_ALL_FLGS;  /* Clear all break timer interrupt flags.  */
   /* Initialize the break timer mode control bits according to the hardware
    * being used.  */
   BRK_TMR_MODE_REG = BRK_TMR_MST_MODE;
   BRK_TMR_IO_REG = BRK_TMR_MST_IO;
   /* If AUTO_CALCULATION is defined, calculate the LIN break period (used by
    * "lin_send_break()") based on the system clock frequency and the LIN Baud rate.  */
   #ifdef AUTO_CALCULATION
      /* The following math calculations should be done by the preprocessor, since all
       * of the values are defined constants.  This may result in a rounding error, but
       * it will be insignificantly small.  */
      LIN_break_prescale = (unsigned char)((((1000000 * LIN_MY_FREQUENCY) + H_DIVISOR) / DIVISOR) - 1);
      LIN_break_count = (unsigned char)((13 * BIT_FACTOR) - 1);
   #endif   /* AUTO_CALCULATION.  */
   /* Set the break timer period.  */
   BRK_TMR_PRECNT_REG = LIN_break_prescale;
   BRK_TMR_CNT_REG = LIN_break_count;
   return;
}
#endif   /* Master node.  */

/**********************************************************************
 *    Function Name: lin_init_serial_if()
 *      Description: Set up the serial port.
 *       Parameters: None.
 *          Returns: Nothing.
 *  Ext. References: LIN_brr_value, LIN_smr_value.
 *      Preemptible: Yes.
 *        Reentrant: No.
 *
 * Note: This function really only sets up the Baud rate generator, sets
 * the TxD pin function as a serial port output and clears the flags.
 *********************************************************************/
void lin_init_serial_if(void)
{
   #ifdef AUTO_CALCULATION
      unsigned long brate;
      unsigned int brr_value;
      unsigned char i;
   #endif

   /* Clear the LIN configuration for a clean start.  */
   LIN_CONTROL_REG = 0x00;
   BRK_TMR_FLAGS |= BRK_CLR_ALL_FLGS;  /* Clear all break timer interrupt flags.  */
   /* Clear the serial port configuration.  This will clear any error flags.  */
   LIN_UART_MODE_REG = 0x00;
   LIN_UART_OP_MODE = LIN_UART_OP_OFF;
   LIN_UART_RX_INT_CTL = 0x00;
   LIN_UART_TX_INT_CTL = 0x00;
   /* Set the serial port mode to assert TxD.  */
   LIN_UART_MODE_REG = LIN_UART_MODE;
   LIN_UART_MODE_REG2 = LIN_UART_MODE2;

   /* If AUTO_CALCULATION is defined, calculate the serial port Baud rate
    * divider value instead of using precalculated value.  */
   #ifdef AUTO_CALCULATION
      /* Try various prescaler values until the Baud rate divider is less than 256.  */
      for (i = 0; i <= 2; i++)
      {
         switch (i)
         {
            case 0:     /* Prescale divide by 1.  */
               brate = (unsigned long)3125000000;
               break;
            case 1:     /* Prescale divide by 8.  */
               brate = (unsigned long)390625000;
               break;
            case 2:     /* Prescale divide by 32.  */
               brate = (unsigned long)97656250;
               break;
         }
         /* Calculate the Baud rate generator divide value using integer
          * math.  This adds very little to the code size.  */
         brate += ((LIN_SPEED / 2) - 1); /* The right hand calculation should be done by the preprocessor.  */
         brate /= LIN_SPEED;
         brate *= LIN_MY_FREQUENCY;
         brate += 24999;
         brate /= 50000;
         brr_value = (unsigned int)(brate - 1);
         if (brr_value <= 255)
         {
            break;
         }
      }
      LIN_brr_value = (unsigned char)brr_value; /* Save the calculated divide value.  */
      LIN_smr_value = i;         /* Save the prescaler index value.  */
   #endif   /* AUTO_CALCULATION.  */
   /* Load the serial port control registers.  */
   LIN_UART_BRG_CKS |= LIN_smr_value;  /* Set the BRG prescaler select bits.  */
   LIN_UART_BRG = LIN_brr_value;       /* Set the BRG divide value.  */
   /* Set the basic LIN configuration.  */
   #if (LIN_MASTER_NODE == LIN_MY_NODE_NAME)
      LIN_CONTROL_REG = 0xC0;
   #else
      #ifdef SYNC_AUTO_MODE
         LIN_CONTROL_REG = 0xA0;
      #else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -