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

📄 lin_api.c

📁 针对日本瑞莎单片机r8c/23 开发的LIN网络通讯程序包括主节点和从节点
💻 C
📖 第 1 页 / 共 5 页
字号:
      /* This is a request for an API flag.  Return the present setting of the flag.  */
      flg -= 252;
      ret_val = LIN_flags[flg];
   }
   else
   {
      /* This is a request for a signal flag.  */
      ret_val = 0x00;   /* Initialize the return value to 0.  */
      /* Return 1 if the signal status byte is greater than 0x00.  */
      if (*LIN_signal_table[flg].signal_address > 0x00)
      {
         ret_val = 0x01;
      }
   }
   return (ret_val);
}

/**********************************************************************
 *    Function Name: l_flg_clr()
 *      Description: Clears a system flag or signal status byte.
 *       Parameters: flg - possible values:
 *                      any valid signal name defined in "lin_dev.h"
 *                      LIN_TX_END_FLG (252)
 *                      LIN_RX_END_FLG (253)
 *                      LIN_AWAKE_FLG (254)
 *                      LIN_DIAG_RESP_FLG (255).
 *          Returns: Nothing.
 *  Ext. References: System flag referenced by "flg".
 *      Preemptible: Yes.
 *        Reentrant: Yes.
 *
 * Note: this function does not perform any limit checking to verify
 * the signal name values in "flg".  The user application programmer
 * should take precautions to insure that invalid parameters cannot be
 * passed.  The best method to use is to reference all flags by name.
 * In the case of signals, these are the names defined in "lin_dev.h".
 * It is virtually guaranteed that these name definitions correspond
 * directly with the values defined in "LIN_signal_table[]".
 *********************************************************************/
void l_flg_clr(l_flag_handle flg)
{
   /* If "flg" has the value 252, 253, 254 or 255, this request is to clear one of
    * the API flags LIN TX_END_FLG, LIN_END_FLG, LIN_AWAKE_FLG or LIN_DIAG_RESP_FLG.
    * Otherwise, the request is to clear one of the user signals defined in
    * "LIN_signal_table[]".  */
   if (flg > 251)
   {
      /* This is a request for an API flag.  Clear the flag.  */
      flg -= 252;
      LIN_flags[flg] = 0;
   }
   else
   {
      /* This is a request for a signal flag.  Clear the signal ststus byte.  */
      *LIN_signal_table[flg].signal_address = 0x00;
   }
   return;
}

/**********************************************************************
 *    Function Name: l_ifc_read_status()
 *      Description: Reads the LIN interface status word.
 *       Parameters: ifc_name - index number of the LIN interface - only
 *                   0 is allowed.
 *          Returns: Returns the status value.
 *  Ext. References: LIN_ifc_status[].
 *      Preemptible: No.
 *        Reentrant: No.
 *
 * Note: This routine assumes that each node implements a single LIN
 * interface, defined as interface 0 in "lin_dev.h" (the value of "LIN"
 * is set to 0 by default).  The API software should be modified to
 * allow multiple LIN interfaces to be implemented.
 *********************************************************************/
l_u16 l_ifc_read_status(l_ifc_handle ifc_name)
{
   unsigned char flag_state;
   union {
      unsigned int     d_int;
      unsigned char    d_byte[2];
   } buf;

   /* Clear the return value for the case that "ifc_name" is not LIN.  */
   buf.d_int = 0x0000;
   /* Do nothing if the specified interface is not interface 0.  */
   if (ifc_name == LIN)
   {
      flag_state = l_sys_irq_disable();   /* Disable the global interrupt.  */
      /* Read the current value of "LIN_ifc_status" into the buffer.  */
      buf.d_byte[0] = LIN_ifc_status[0];
      buf.d_byte[1] = LIN_ifc_status[1];
      /* Clear "LIN_ifc_status".  */
      LIN_ifc_status[0] = 0;
      LIN_ifc_status[1] = 0;
      l_sys_irq_restore(flag_state);      /* Restore the global interrupt.  */
   }
   return (buf.d_int);  /* Return the state of "LIN_ifc_status" prior to being cleared.  */
}

/* This function is implemented only for LIN Master nodes.  LIN Slave nodes
 * are commanded into the sleep mode when this command is received and they
 * are supposed to go to sleep automatically after 4 seconds of bus silence.  */
#if (LIN_MASTER_NODE == LIN_MY_NODE_NAME)
#ifdef USE_POWER_CONTROL   /* Implemented only if power control is used.  */
/**********************************************************************
 *    Function Name: l_ifc_goto_sleep()
 *      Description: Send the LIN sleep command from a LIN Master node
 *                   and then put the Master node in the SLEEP state.
 *       Parameters: ifc_name - index number of the LIN interface - only
 *                   0 is allowed.
 *          Returns: Nothing.
 *  Ext. References: LIN_schedule_stop_flag.
 *      Preemptible: Yes.
 *        Reentrant: No.
 *
 * Note: This routine assumes that each node implements a single LIN
 * interface, defined as interface 0 in "lin_dev.h" (the value of "LIN"
 * is set to 0 by default).  The API software should be modified to
 * allow multiple LIN interfaces to be implemented.
 *********************************************************************/
void l_ifc_goto_sleep(l_ifc_handle ifc_name)
{
   /* Do nothing if the specified interface is not interface 0.  */
   if (ifc_name == LIN)
   {
      /* Set the "LIN_schedule_stop_flag" to 2.  When the current frame slot
       * has expired, the LIN Go-To-Sleep message will be sent and then the
       * Master schedule actions will be stopped.  */
      LIN_schedule_stop_flag = 2;
      #ifdef DEDICATED_SCHEDULE_TIMER
         /* If the LIN device is using a dedicated schedule timer, and this call
          * to the "l_ifc_goto_sleep()" function is being made because a previous
          * attempt failed, it will be necessary to restart the schedule timer to
          * allow the Go-To-Sleep message to repeat.  If the timer is already
          * running, the following command won't change anything anyway.  */
         SCH_TMR_RUN = 1;  /* Restart the LIN schedule timer.  */
      #endif
   }
}
#endif   /* USE_POWER_CONTROL.  */
#endif   /* Master node.  */

#ifdef USE_POWER_CONTROL   /* Implemented only if power control is used.  */
/**********************************************************************
 *    Function Name: l_ifc_wake_up()
 *      Description: Sends the wakeup signal on the LIN bus (logic 0 for
 *                   250us) and then takes the node out of the SLEEP state.
 *       Parameters: ifc_name - index number of the LIN interface - only
 *                   0 is allowed.
 *          Returns: Nothing.
 *  Ext. References: No direct external references.
 *      Preemptible: No.
 *        Reentrant: No.
 *
 * Note: This routine assumes that each node implements a single LIN
 * interface, defined as interface 0 in "lin_dev.h" (the value of "LIN"
 * is set to 0 by default).  The API software should be modified to
 * allow multiple LIN interfaces to be implemented.
 *********************************************************************/
void l_ifc_wake_up(l_ifc_handle ifc_name)
{
   unsigned char flag_state;

   /* Do nothing if the specified interface is not interface 0.  */
   if (ifc_name == LIN)
   {
      if (LIN_bus_status == QUIET_STATE)
      {
         flag_state = l_sys_irq_disable();   /* Disable the global interrupt.  */
         lin_change_bus_status(WAKEUP_SEND_STATE); /* Prepare the LIN bus to transmit.  */
         /* Wait until the transmit data register is empty.  */
         while (LIN_UART_TBUFE_FLG == 0);
         LIN_UART_TDAT = 0xF0;   /* Output 0xF0, which forces the bus low for 5 bit periods.  */
         /* Wait until the byte has been sent.  */
         while (LIN_UART_TXEND_FLG == 0);
         /* If the LIN interface is in the "sleep" state, bring it back up.  */
         if (LIN_node_status == SLEEP_STATE)
         {
            lin_change_node_status(WAKE_UP_STATE); /* Set the LIN interface into the "wakeup state".  */
         }
         else
         {
            lin_change_bus_status(QUIET_STATE);     /* Set the LIN bus to the inactive state.  */
         }
         l_sys_irq_restore(flag_state);   /* Restore the global interrupt.  */
      }
   }
}
#endif   /* USE_POWER_CONTROL.  */

/* This function is implemented only for LIN Master nodes.  */
#if (LIN_MASTER_NODE == LIN_MY_NODE_NAME)
/**********************************************************************
 *    Function Name: l_sch_set()
 *      Description: Configures the Master node to use a different
 *                   schedule table.
 *       Parameters: ifc_name - index number of the LIN interface - only
 *                   0 is allowed.
 *                   schedule - index number of the schedule table to use.
 *                   entry - first entry in the new schedule table that
 *                   should be used.
 *          Returns: Nothing.
 *  Ext. References: LIN_change_schedule, LIN_change_entry.
 *      Preemptible: Yes.
 *        Reentrant: No.
 *
 * Note: This routine assumes that each node implements a single LIN
 * interface, defined as interface 0 in "lin_dev.h" (the value of "LIN"
 * is set to 0 by default).  The API software should be modified to
 * allow multiple LIN interfaces to be implemented.
 *********************************************************************/
void l_sch_set(l_ifc_handle ifc_name, l_schedule_handle schedule, l_u8 entry)
{
   /* Do nothing if the specified interface is not interface 0.  */
   if (ifc_name == LIN)
   {
      /* An "entry" value of both 0 and 1 means "start at the beginning".  Modify
       * "entry" such that 1 is the minimum value actually used.  */
      if (entry == 0)
      {
         entry = 1;
      }
      /* Load the requested values into "LIN_change_schedule" and "LIN_change_entry"
       * so they can be activated at the next opportunity.  */
      LIN_change_entry = entry;
      LIN_change_schedule = schedule;
   }
}
#endif   /* Master node.  */

/* This function is implemented only for LIN Master nodes.  */
#if (LIN_MASTER_NODE == LIN_MY_NODE_NAME)
/**********************************************************************
 *    Function Name: l_sch_tick()
 *      Description: Sends the next message frame on the current schedule
 *                   table.  This function is called only from the ISR
 *                   for the scheduler timer.
 *       Parameters: ifc_name - index number of the LIN interface - only
 *                   0 is allowed.
 *          Returns: Index number of entry just sent or 0 on error.
 *  Ext. References:
 *      Preemptible: No.
 *        Reentrant: No.
 *
 * Note: This routine assumes that each node implements a single LIN
 * interface, defined as interface 0 in "lin_dev.h" (the value of "LIN"
 * is set to 0 by default).  The API software should be modified to
 * allow multiple LIN interfaces to be implemented.
 *********************************************************************/
l_u8 l_sch_tick(l_ifc_handle ifc_name)
{
   unsigned char ret;
   unsigned char relational_frame_name;
   unsigned char signal_name;
   unsigned char LIN_master_request_frame;
   unsigned char *p;
   unsigned char i;
   unsigned char j;

   /* If "LIN_CORE_TIME_ENABLE" is defined, LIN core time measurements are being made.
    * Turn on the "LIN_CORE_TIME" output pin.  */
   #ifdef LIN_CORE_TIME_ENABLE
      LIN_CORE_TIME = 1;
   #endif
   ret = 0; /* Initialize the return value in case the NULL schedule table is active.  */
   /* Do nothing if the specified interface is not interface 0.  */
   if (ifc_name == LIN)
   {
      #ifdef DEDICATED_SCHEDULE_TIMER
         SCH_TMR_FLAG_REG &= SCH_CLR_FLG; /* Clear the schedule timer flag.  */
      #endif

⌨️ 快捷键说明

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