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

📄 lin_api.c

📁 针对日本瑞莎单片机r8c/23 开发的LIN网络通讯程序包括主节点和从节点
💻 C
📖 第 1 页 / 共 5 页
字号:
      /* 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 + -