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

📄 comm_i2cs.c

📁 PIC Kit serial source code.
💻 C
📖 第 1 页 / 共 2 页
字号:
//===================================================================== 
//--- COPYRIGHT
//===================================================================== 
// Copyright 2006 Microchip Technology Inc.
// 
// Microchip Technology Inc. ("Microchip") licenses this software to
// you solely for use with Microchip products. The software is owned
// by Microchip and is protected under applicable copyright laws. All
// rights reserved.
// 
// SOFTWARE IS PROVIDED IN AN "AS IS." MICROCHIP EXPRESSLY DISCLAIMS ANY
// WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL MICROCHIP
// BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
// DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
// PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
// BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
// ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
// 
//===================================================================== 
//--- TITLE
//===================================================================== 
//    Filename:            i2cs.c
//    Microcontroller:     PIC18F2550
//    Compiled using:      C18 V3.00
//
//    Author:              Mark Enochson
//    Company:             Microchip Technology Inc.
//
//===================================================================== 
//--- DESCRIPTION
//===================================================================== 
//
//    I2C slave

//===================================================================== 
//--- HISTORY
//===================================================================== 
//
//    0001 - 08-01-06 - ME
//    - alpha release
//
//===================================================================== 

//==========================================================
//--- INCLUDES
//==========================================================
#include "project.h"
#include "cbuf.h"
#include "comm_gen.h"
#include "comm_i2cs.h"

//==========================================================
//--- DEFINITIONS / DECLARATIONS
//==========================================================
// none


//==========================================================
//--- comm_i2cs_init()
//
//    initialization
//==========================================================
TD_BYTE comm_i2cs_init(void)
{
   comm_varbs_clear();
   comm_i2cs_reset();
   return(0);
}

//==========================================================
//--- comm_i2cs_reset()
//
//    hardware "reset"
//==========================================================
void comm_i2cs_reset(void)
{
   SSPCON1 = 0;
   PIE1bits.SSPIE = 0;
   COMM_I2CS_FLAGS = 0;
   I2CS_SCK = 1;
   I2CS_SDA = 1;
   I2CS_SCK_TRIS = 1;
   I2CS_SDA_TRIS = 1;
   COMM_IO_4B_DIR = 1;
   COMM_IO_5B_DIR = 1;
   SSPADD = COMM_CB_I2CS_SLAVE_ADDR_REG;
   SSPCON2 = I2CS_SSPCON2_DFLT | (COMM_CB_I2CS_SLAVE_ADDR_MASK_REG & I2CS_SSPCON2_DFLT_MASK) ;
   SSPCON1 = I2CS_SSPCON1_DFLT;
   PIR1bits.SSPIF = 0;
   IPR1bits.SSPIP = 0;
   PIE1bits.SSPIE = 1;
   SSPCON1bits.SSPEN = 1;
   
/*
   //--------------------------------------
   //--- MODE 2 - SLAVE PROFILE
   //--------------------------------------
   cbuf3_put(0x20);  // slave
   cbuf3_put(0x16);
   cbuf3_put(0x00);
   cbuf3_put(0x00);
   
   cbuf3_put(0x40);  // register - read only
   cbuf3_put(0x21);
   cbuf3_put(0x02);  // byte count
   cbuf3_put(0x34);
   cbuf3_put(0x12);
   
   cbuf3_put(0x40);  // register rd/wr
   cbuf3_put(0x22);
   cbuf3_put(0x01);  // byte count
   cbuf3_put(0x56);

   cbuf3_put(0x20);  // slave
   cbuf3_put(0x18);
   cbuf3_put(0x00);
   cbuf3_put(0x00);

   cbuf3_put(0x48);  // register rd/wr, block
   cbuf3_put(0x00);  // addr=0
   cbuf3_put(0x04);  // byte count
   cbuf3_put(0x11);
   cbuf3_put(0x22);
   cbuf3_put(0x33);
   cbuf3_put(0x44);
   
   cbuf3_put(0x80);
*/
/*   
   //--------------------------------------
   //--- SCRIPT COMMAND
   //--------------------------------------
   cbuf1_put(0xC3);
   cbuf1_put(0x16);
   cbuf1_put(0x21);         
*/
/*
   cbuf1_put(0xC1);
   cbuf1_put(0x03);
   cbuf1_put(0x56);
   cbuf1_put(0x78);
   cbuf1_put(0x9A);
*/

}
 
//==========================================================
//--- comm_i2cs_pro_get_regdef()
//    search profile for register definition
//    it is assumed that the SLAVE addr has been located
//    so the address of the regdef(s) is known
//    COMM_I2CS_PRO_REG_OK_FLAG = 1 (regdef found)
//    COMM_I2CS_PRO_REG_OK_FLAG = 0 (regdef not found)
//==========================================================
void comm_i2cs_pro_get_regdef(void)
{
   COMM_I2CS_TEMP = COMM_I2CS_PRO_SLAVE_REGS_INDEX;
   COMM_I2CS_PRO_REG_OK_FLAG = 0;
   while(!COMM_SB_I2CS_PROFILE_ERR_FLAG)
   {
      comm_i2cs_pro_get();
      if(COMM_I2CS_PRO_TAG != COMM_I2CS_PRO_TAG_REGDEF)
         break;
      if(COMM_I2CS_PRO_REG_SEQ_FLAG)
      {
         if((COMM_I2CS_CMND >= COMM_I2CS_PRO_REG) && 
            (COMM_I2CS_CMND < (COMM_I2CS_PRO_REG + COMM_I2CS_PRO_REG_BC)))
         {
            COMM_I2CS_PRO_REG = COMM_I2CS_CMND - COMM_I2CS_PRO_REG;
            COMM_I2CS_PRO_REG_BC -= COMM_I2CS_PRO_REG;
            COMM_I2CS_PRO_REG_INDEX += COMM_I2CS_PRO_REG;
            COMM_I2CS_PRO_REG = COMM_I2CS_CMND;
            COMM_I2CS_PRO_REG_OK_FLAG = 1;
            break;
         }
      }
      else
      {
         if(COMM_I2CS_PRO_REG == COMM_I2CS_CMND)
         {
            COMM_I2CS_PRO_REG_OK_FLAG = 1;
            break;
         }
      }
   }
}

//==========================================================
//--- comm_i2cs_pro_get_slave()
//    search profile for slave address: COMM_I2CS_ADDR
//    COMM_I2CS_PRO_OK_FLAG = 1 (slave addr found)
//    COMM_I2CS_PRO_OK_FLAG = 0 (slave addr not found)
//==========================================================
void comm_i2cs_pro_get_slave(void)
{
   COMM_I2CS_TEMP = 1;
   COMM_I2CS_PRO_SLAVE_OK_FLAG = 0;
   COMM_I2CS_PRO_REG_OK_FLAG = 0;
   do
   {
      comm_i2cs_pro_get();
      if(COMM_I2CS_PRO_TAG == COMM_I2CS_PRO_TAG_SLAVE)
      {
         if(COMM_I2CS_PRO_SLAVE_ADDR == COMM_I2CS_ADDR)
         {
            COMM_I2CS_PRO_SLAVE_OK_FLAG = 1;
            break;
         }
      }
   } while((COMM_I2CS_PRO_TAG != COMM_I2CS_PRO_TAG_END)&&(!COMM_SB_I2CS_PROFILE_ERR_FLAG));
}

//==========================================================
//--- comm_i2cs_pro_get() - get next entity in profile
//    scan slave profile, return one TAG at a time
//    (profile assumed to be properly formed)
//==========================================================
void comm_i2cs_pro_get(void)
{
   COMM_I2CS_PRO_TAG = cbuf3_data[COMM_I2CS_TEMP];

   if(COMM_I2CS_PRO_TAG != COMM_I2CS_PRO_TAG_END)
   {
      COMM_I2CS_TEMP++;
      if(COMM_I2CS_PRO_TAG == COMM_I2CS_PRO_TAG_SLAVE)
      {
         COMM_I2CS_PRO_SLAVE_ADDR = cbuf3_data[COMM_I2CS_TEMP];
         COMM_I2CS_TEMP += 2;
         COMM_I2CS_PRO_SLAVE_REG_INDEX = COMM_I2CS_TEMP;
         COMM_I2CS_TEMP ++;
         COMM_I2CS_PRO_SLAVE_REGS_INDEX = COMM_I2CS_TEMP;
      }
      else if(COMM_I2CS_PRO_TAG_REGDEF == (COMM_I2CS_PRO_TAG & 0xF0))
      {
         COMM_I2CS_PRO_REG_FLAGS = COMM_I2CS_PRO_TAG & 0x0F;
         COMM_I2CS_PRO_TAG &= 0xF0;
         COMM_I2CS_PRO_REG = cbuf3_data[COMM_I2CS_TEMP];
         COMM_I2CS_TEMP ++;
         COMM_I2CS_PRO_REG_BC = cbuf3_data[COMM_I2CS_TEMP];
         COMM_I2CS_TEMP ++;
         COMM_I2CS_PRO_REG_INDEX = COMM_I2CS_TEMP;
         COMM_I2CS_TEMP += COMM_I2CS_PRO_REG_BC;
      }
      else
      {
         COMM_SB_I2CS_PROFILE_ERR_FLAG = 1;
      }
   }
}
 
//==========================================================
//--- ISR
//==========================================================
void comm_i2cs_isr(void)
{
   if(PIR1bits.SSPIF == 0)
      return;
   PIR1bits.SSPIF = 0;
   
   //---------------------------------------------
   //--- BUFFER FULL (ADDR/DATA AVAIL)
   //---------------------------------------------
   if(SSPSTATbits.BF)
   {
      //--------------------------------
      //--- DATA RECEIVED
      //--------------------------------
      if(SSPSTATbits.D)
      {
         COMM_I2CS_DATA = SSPBUF;
         if(COMM_CB_I2CS_EVENTEN_DATA_RX_FLAG)
            comm_post_event_1b(COMM_TAG_I2CS_EVENT_DATA_RX, COMM_I2CS_DATA);

         //--- IF 1ST BYTE, SAVE AS "CMND"
         if(COMM_I2CS_ADDR_FLAG)
         {
            COMM_I2CS_CMND = COMM_I2CS_DATA;

            //--- IF MODE 2, CHECK FOR 'REGDEF' PROFILE
            if(COMM_CB_I2CS_MODE_REG == 2)
            {
               if(COMM_I2CS_PRO_SLAVE_OK_FLAG)
               {
                  comm_i2cs_pro_get_regdef();
                  cbuf3_data[COMM_I2CS_PRO_SLAVE_REG_INDEX] = COMM_I2CS_CMND;
               }
            }

            COMM_I2CS_ADDR_FLAG = 0;
         }
         else
         {
   
            //--- IF MODE 2, CHECK FOR 'REGDEF' PROFILE
            if(COMM_CB_I2CS_MODE_REG == 2)
            {
               if(COMM_I2CS_PRO_REG_OK_FLAG)
               {
                  if(COMM_I2CS_PRO_REG_WRDIS_FLAG == 0)
                  {
                     if(COMM_I2CS_PRO_REG_BC)
                     {
                        cbuf3_data[COMM_I2CS_PRO_REG_INDEX] = COMM_I2CS_DATA;
                        COMM_I2CS_PRO_REG_INDEX++;
                        COMM_I2CS_PRO_REG_BC--;
                     }
                  }
                  if(COMM_I2CS_PRO_REG_SEQ_FLAG)
                     cbuf3_data[COMM_I2CS_PRO_SLAVE_REG_INDEX]++;
               }
               //--- 'WRITE REG' EVENT
               if((COMM_I2CS_EVENT_PENDING_FLAG) && (COMM_CB_I2CS_EVENTEN_REGWRITE_FLAG))
               {
                  COMM_I2CS_EVENT_PENDING_FLAG = 0;
                  comm_post_event_2b(COMM_TAG_I2CS_EVENT_REG_WRITE, COMM_I2CS_ADDR, COMM_I2CS_CMND);
               }
            }
         }
         
         SSPCON1bits.CKP = 1;
      }
      
      //--------------------------------
      //--- ADDR RECEIVED
      //--------------------------------
      else
      {
         COMM_I2CS_ADDR = SSPBUF;
         COMM_I2CS_XSTARTED_FLAG = 1;
         if(COMM_CB_I2CS_EVENTEN_ADDR_RX_FLAG)
            comm_post_event_1b(COMM_TAG_I2CS_EVENT_ADDR, COMM_I2CS_ADDR);
         COMM_I2CS_ADDR &= 0xFE;
         COMM_I2CS_ADDR_FLAG = 1;

         //-----------------------------
         //--- IF MODE 2, 
         //    IS SLAVE ADDR IN PROFILE
         //-----------------------------
         if(COMM_CB_I2CS_MODE_REG == 2)
         {
            COMM_I2CS_EVENT_PENDING_FLAG = 1;
            comm_i2cs_pro_get_slave();
         }

         //-----------------------------
         //--- READ ?!
         //-----------------------------
         if(SSPSTATbits.R)
         {
            COMM_I2CS_READ_FLAG = 1;
            if(COMM_CB_I2CS_MODE_REG == 2)
            {
               if(COMM_I2CS_PRO_SLAVE_OK_FLAG)
               {
                  COMM_I2CS_CMND = cbuf3_data[COMM_I2CS_PRO_SLAVE_REG_INDEX];
                  comm_i2cs_pro_get_regdef();
               }
               if(COMM_I2CS_EVENT_PENDING_FLAG)
               {
                  COMM_I2CS_EVENT_PENDING_FLAG = 0;
                  if(COMM_CB_I2CS_EVENTEN_REGREAD_FLAG)
                     comm_post_event_2b(COMM_TAG_I2CS_EVENT_REG_READ, COMM_I2CS_ADDR, COMM_I2CS_CMND);
               }
            }
         }

         //-----------------------------
         //--- WRITE ?!
         //-----------------------------
         else
         {
            COMM_I2CS_READ_FLAG = 0;
            SSPCON1bits.CKP = 1;
         }
      }
   }

   //---------------------------------------------
   //--- READ ACTIVE ?
   //---------------------------------------------
   
   //-----------------------------------   
   //--- IF 'READ' ACTIVE & CLOCK HI ... 
   //    NACK RECEIVED - READ DONE
   //-----------------------------------   
   if(COMM_I2CS_READ_FLAG)
   {
      if(SSPCON1bits.CKP == 0)
      {
         if(COMM_I2CS_ADDR_FLAG == 0)
         {
            if(COMM_CB_I2CS_EVENTEN_ACK_RX_FLAG)
               comm_post_event(COMM_TAG_I2CS_EVENT_ACK_RX);
         }
      }
      else
      {
         COMM_I2CS_READ_FLAG = 0;
         if(COMM_CB_I2CS_EVENTEN_NACK_RX_FLAG)
            comm_post_event(COMM_TAG_I2CS_EVENT_NACK_RX);
         if(COMM_CB_I2CS_MODE_REG == 1)
            cbuf3_init();
      }
   }
   
   //-----------------------------------   
   //--- READ ACTIVE
   //-----------------------------------   
   if(COMM_I2CS_READ_FLAG)
   {
      
      //----------------------
      //--- MODE: 0
      //----------------------
      if(COMM_CB_I2CS_MODE_REG == 0)
      {
         if(COMM_I2CS_ADDR_FLAG)
            COMM_I2CS_DATA = COMM_CB_I2CS_DATA_0_DFLT_REG;
         else
            COMM_I2CS_DATA = COMM_CB_I2CS_DATA_N_DFLT_REG;
         comm_i2cs_data_send();

⌨️ 快捷键说明

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