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

📄 comm_lin.c

📁 PIC Kit serial source code.
💻 C
📖 第 1 页 / 共 3 页
字号:
   if(RCSTAbits.OERR == 1)                   // OVERRUN ERROR ?
      COMM_LIN_OERR_FLAG = 1;
   comm_data_2 = RCREG;                      // RETRIEVE DATA BYTE

#ifdef __DEBUG_LIN_AUX1
   LIN_AUX1_PORT = 1;
#endif

   //=======================================================
   //--- BREAK ?!?
   //=======================================================
   Nop();
   if((comm_data_2==0) && (COMM_LIN_FERR_FLAG))
   {
      COMM_LIN_FERR_FLAG = 0;                // FERR EXPECTED ON BREAK
      
      COMM_LIN_2_FLAG = 1;                   // FLAG INDICATES HARD ABAUD ERROR, ELSE, IGNORED
   

      //--- POST EVENT MARKER
      if(COMM_CB_LIN_EVENT_EN_BREAK_RX_FLAG)
         comm_post_event(COMM_TAG_LIN_EVENT_BREAK_RX);
            
      //--- SETUP OP FLAGS
      COMM_LIN_SEQ_BRK_FLAG = 1;
      COMM_LIN_SEQ_SYN_FLAG = 0;
      COMM_LIN_SEQ_ID_FLAG = 0;
      COMM_LIN_RX_SP_FLAG = 0;
      COMM_LIN_TX_SP_FLAG = 0;
      COMM_LIN_RX_SP_FLAG = 0;
      
      //------------------------------------------
      //--- AUTOBAUD ENABLED ?
      //------------------------------------------
      if((COMM_CB_LIN_AUTOBAUD_FLAG) && (COMM_LIN_ABAUD_DISABLE_FLAG==0))
      {

         //-----------------------------
         //--- WAIT BREAK COMPLETE
         //    (ERR IF TIMEOUT)
         //-----------------------------
         timer3_set(COMM_LIN_WAIT_BREAK_T3);
         COMM_LIN_ABERR_FLAG = 1;               // PRESET ERROR FLAG
         while(PIR2bits.TMR3IF == 0)
         {
            if(LIN_RX_PORT)                     // SYNC COMPLETE ?
            {
               COMM_LIN_ABERR_FLAG = 0;         // SYNC COMPLETE, RESET ERROR FLAG !
               break;
            }
         }
         
         //---------------------------------------
         //--- BREAK TERMINATED W/O TIMEOUT
         //    ENGAGE AUTOBAUD
         //---------------------------------------
         Nop();

         if(COMM_LIN_ABERR_FLAG == 0)
         {     
            
            //-----------------------------
            //--- ENGAGE AUTOBAUD
            //-----------------------------
            BAUDCONbits.ABDEN = 1;

            //-----------------------------
            //--- WAIT ABAUD COMPLETE ...
            //    (ERR IF TIMEOUT)
            //-----------------------------
            COMM_LIN_COUNT = 0;
            COMM_LIN_3_FLAG = 1;
            COMM_LIN_ABERR_FLAG = 1;
            timer3_set(COMM_LIN_WAIT_AB_T3);
            while(PIR2bits.TMR3IF == 0)
            {
               if(COMM_LIN_3_FLAG == 0)
               {
                  if(LIN_RX_PORT == 1)
                  {
                     if(COMM_LIN_COUNT == 5)
                     {
                        Nop();
                        BAUDCONbits.ABDEN = 0;
                        comm_data_2 = RCREG;
                        COMM_LIN_ABERR_FLAG = 0;
                        break;
                     }
                     COMM_LIN_3_FLAG = 1;
                  }
               }
               else
               {
                  if(LIN_RX_PORT == 0)
                  {
                     COMM_LIN_3_FLAG = 0;
                     COMM_LIN_COUNT++;
                  }
               }
            }
            
            //---
            if(BAUDCONbits.ABDEN)
            {
               BAUDCONbits.ABDEN = 0;           // SAFETY NET CLEAN UP ON TIMEOUT
               COMM_LIN_2_FLAG = 1;             // HARD ERROR
            }
                  
            //-----------------------------
            //--- AUTOBAUD OVERFLOW ?
            //-----------------------------
            if(BAUDCONbits.ABDOVF)
            {
               BAUDCONbits.ABDEN = 0;
               BAUDCONbits.ABDOVF = 0;
               COMM_LIN_ABERR_FLAG = 1;
            }

            //-----------------------------------------
            //--- IF STATUS 'OK' SO FAR
            //    CHECK BAUD 'CHANGE' TO BE WITHIN LIMITS
            //    BAUD_CODE LIMITS: +/-12.5%
            //       CORRESPONDS TO BAUD: +14%/-11%
            //    OPTION:
            //    BAUD_CODE LIMITS: +/-25.0%
            //       CORRESPONDS TO BAUD: +33%/-20%
            //-----------------------------------------
            if(COMM_LIN_ABERR_FLAG == 0)
            {
               comm_macro_count_1_W.lo = SPBRG;
               comm_macro_count_1_W.hi = SPBRGH;
               comm_macro_count_2_W.lo = COMM_CB_LIN_BRG_LO_REG;
               comm_macro_count_2_W.hi = COMM_CB_LIN_BRG_HI_REG;
               if(comm_macro_count_1_W._w > comm_macro_count_2_W._w)
                  comm_macro_count_1_W._w = comm_macro_count_1_W._w - comm_macro_count_2_W._w;
               else
                  comm_macro_count_1_W._w = comm_macro_count_2_W._w - comm_macro_count_1_W._w;
               comm_macro_count_2_W._w >>= 3;
               if(comm_macro_count_1_W._w > comm_macro_count_2_W._w)
                  COMM_LIN_ABERR_FLAG = 1;
               COMM_LIN_2_FLAG = 0;
            }
         } //--- END: BREAK OK
         
         //----------------------------------------------------
         //--- IF AUTOBAUD ERROR, RE-LOAD DEFAULT BAUD
         //----------------------------------------------------
         if(COMM_LIN_ABERR_FLAG)
         {
            SPBRG = COMM_CB_LIN_BRG_LO_REG;
            SPBRGH = COMM_CB_LIN_BRG_HI_REG;
            if(COMM_LIN_2_FLAG == 0)
               COMM_LIN_ABERR_FLAG = 0;
         }
         else
         {
            COMM_LIN_SEQ_SYN_FLAG = 1;
         }
         
         if(COMM_CB_LIN_EVENT_EN_AUTOBAUD_FLAG)
            comm_post_event_2b(COMM_TAG_LIN_EVENT_AUTOBAUD, SPBRG, SPBRGH);

      } //--- END AUTOBAUD
   } //--- END BREAK DETECTION
   

   //=======================================================
   //--- DATA
   //=======================================================
   else
   {
      Nop();
      COMM_LIN_ABAUD_DISABLE_FLAG = 0;

      //---
      COMM_LIN_DATA_FLAG = 1;

      //--------------------------------
      //--- EXPECTING 'SYNC' BYTE ?
      //--------------------------------
      if(not COMM_LIN_SEQ_SYN_FLAG)
      {
         //if(comm_data_2 == 0x55)
            COMM_LIN_SEQ_SYN_FLAG = 1;

      } //--- END 'SYNC' BYTE

      //--------------------------------
      //--- EXPECTING 'DATA' BYTE !
      //--------------------------------
      else
      {
         //------------------------------------------         
         //--- POST 'DATA RX' EVENT TAG(S)
         //------------------------------------------         
         comm_post_event_1b(COMM_TAG_GEN_DATA, comm_data_2);
         if(COMM_CB_LIN_EVENT_EN_DATA_RX_FLAG)
            comm_post_event_1b(COMM_TAG_LIN_EVENT_BYTE_RX, comm_data_2);

         //-----------------------------
         //--- DATA: 'FRAME ID' ?
         //-----------------------------
         if(not COMM_LIN_SEQ_ID_FLAG)
         {
            COMM_LIN_SEQ_ID_FLAG = 1;

            //--------------------------
            //--- SLAVE MODE ?
            //--------------------------
            COMM_LIN_TX_SP_FLAG = 0;
            COMM_LIN_RX_SP_FLAG = 0;

            if(COMM_CB_LIN_SLAVE_FLAG)
            {
               if(comm_lin_parity(comm_data_2) != comm_data_2)
               {
                  if(COMM_CB_LIN_EVENT_EN_IDPARITY_ERR_FLAG)
                  {
                     comm_post_event_1b(COMM_TAG_LIN_EVENT_IDPARITY_ERR, \
                        comm_data_2);
                  }
               }
               if(comm_lin_sp_iddef_search(comm_data_2))
               {
                  //--- INIT CHECKSUM
                  COMM_LIN_SP_CHECKSUM = 0;
                  if((COMM_LIN_SP_IDDEF_ENHANCED_CS_FLAG) && (COMM_LIN_SP_ID<0x3C))
                     COMM_LIN_SP_CHECKSUM = comm_data_2;                  
                  
                  if(COMM_LIN_SP_IDDEF_PUBLISH_FLAG)
                  {
                     COMM_LIN_TX_SP_FLAG = 1;
                     comm_lin_tx_isr();
                  }
                  else
                  {
                     COMM_LIN_RX_SP_FLAG = 1;
                  }
               } //--- END: SEARCH SLAVE PROFILE FOR GIVEN ID
            } //--- END: SLAVE MODE
         } //--- END: EXPECTING FRAME ID
         
         //--------------------------
         //--- DATA: 
         //--------------------------
         else
         {
            //--------------------------
            //--- SLAVE MODE ?
            //--------------------------
            if(COMM_CB_LIN_SLAVE_FLAG)
            {
               if(COMM_LIN_RX_SP_FLAG)
               {
                  if(COMM_LIN_SP_NBYTES)
                  {
                     COMM_LIN_SP_CHECKSUM += comm_data_2;
                     cbuf3_data[COMM_LIN_SP_INDEX_DATA] = comm_data_2;
                     COMM_LIN_SP_INDEX_DATA++;
                     COMM_LIN_SP_NBYTES--;
                  } //--- END: RX_SP ACTIVE, NBYTES!=0
                  else
                  {
                     if(not COMM_LIN_SP_IDDEF_CHKSUMDATA_FLAG)
                     {
                        //--- CHECKSUM GOOD
                        if(comm_data_2 == ~COMM_LIN_SP_CHECKSUM)
                        {
                           Nop();
                        }
                        //--- CHECKSUM BAD
                        else
                        {
                           if(COMM_CB_LIN_EVENT_EN_CHECKSUM_ERR_FLAG)
                              comm_post_event_1b(COMM_TAG_LIN_EVENT_CHECKSUM_ERR, COMM_LIN_SP_ID);
                        }
                     } 
                     COMM_LIN_RX_SP_FLAG = 0;
                  } //--- END: RX_SP ACTIVE, NBYTES==0
               } //--- END: RX_SP ACTIVE
            } //--- END: RX DATA AFTER ID IN SLAVE MODE
         } //--- END: RX DATA AFTER FRAME ID
      } //--- END: RX DATA (NOT SYNC BYTE)
   } //--- END: RX DATA (NOT AUTOBAUD or BREAK)

#ifdef __DEBUG_LIN_AUX1
   LIN_AUX1_PORT = 0;
#endif

} //--- END: RX ISR (BREAK, AUTOBAUD or DATA
   

//==========================================================
//--- comm_lin_tx_isr()
//==========================================================
//    USART TX interrupt service (in LIN mode)
//    TX data has 2 sources (selected by bit flags)
//    SLAVE & SCRIPT SERVICE ... SLAVE has priority
//==========================================================
void comm_lin_tx_isr(void)
{
   TD_BYTE i;
   
   //-----------------------------------
   //--- SERVICE SCRIPT ?
   //-----------------------------------
   if  (COMM_LIN_TX_SVC_FLAG)
   {
      comm_lin_svc();
   }
   
   //-----------------------------------
   //--- SLAVE TX IN PROGRESS ?
   //-----------------------------------
   else if (COMM_LIN_TX_SP_FLAG)
   
   {
      if(COMM_LIN_SP_NBYTES)
      {
         i = cbuf3_data[COMM_LIN_SP_INDEX_DATA];
         COMM_LIN_SP_CHECKSUM += i;
         comm_lin_tx(i);
         COMM_LIN_SP_INDEX_DATA++;
         COMM_LIN_SP_NBYTES--;
      }
      else
      {
         if(not COMM_LIN_SP_IDDEF_CHKSUMDATA_FLAG)
            comm_lin_tx(~COMM_LIN_SP_CHECKSUM);
         COMM_LIN_TX_SP_FLAG = 0;
      }
   }
      
   //-----------------------------------
   //--- DONE !
   //-----------------------------------
   else
   {
      PIE1bits.TXIE = 0;
   }
}

//==========================================================         
//--- comm_lin_svc_tx()
//==========================================================         
//    transmit 'comm_data' byte
//==========================================================         
void comm_lin_svc_tx(void)
{
   COMM_LIN_TX_SVC_FLAG = 1;
   comm_lin_tx(comm_data);
}


//==========================================================
//--- comm_lin_tx()
//==========================================================
//    send/transmit data byte
//    enable TX
//    enable TX interrupt
//==========================================================
void comm_lin_tx(TD_BYTE data)
{
   TXREG = data;
   PIE1bits.TXIE = 1;
   if(COMM_CB_LIN_EVENT_EN_DATA_TX_FLAG)
      comm_post_event_1b(COMM_TAG_LIN_EVENT_BYTE_TX, comm_data);
}

//==========================================================
//--- comm_lin_parity()
//==========================================================
//    computes 2 parity bits associated with LIN FRAME ID
//    parity is computed on calling argument - 'data'
//    the 'result' is returned as the function value
//    where:
//    result[7:7] = 1 ^ (data[5] ^ data[4] ^ data[3] ^ data[1])
//    result[6:6] = 0 ^ (data[4] ^ data[2] ^ data[1] ^ data[0])
//    result[5:0] = data[5:0]
//==========================================================
TD_BYTE comm_lin_parity(TD_BYTE data)
{
   TD_BYTE mask;

   data &= 0x3F;
   
   mask = data & 0x17;
   if((mask==0x01) || (mask==0x02) || (mask==0x04) || (mask==0x07) || \
      (mask==0x10) || (mask==0x13) || (mask==0x15) || (mask==0x16))
      data |= 0x40;
   mask = data & 0x3A;
   if((mask==0x00) || (mask==0x0A) || (mask==0x12) || (mask==0x18) || \
      (mask==0x22) || (mask==0x28) || (mask==0x30) || (mask==0x3A))
      data |= 0x80;
      
   return(data);
}

⌨️ 快捷键说明

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