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

📄 i2c.c

📁 I2C library for LPC21xx processor
💻 C
📖 第 1 页 / 共 3 页
字号:
   VICIntEnable  |= 0x00004000;       //-- Enable Int 0
   OSSemPost(gpSemI2Cop);             //-- Set sem on(I2C is free)
#elif defined(__TNKERNEL_)
   VICIntEnable  |= 0x00004000;       //-- Enable Int 0
   tn_sem_signal(&gSemI2Cop);         //-- Set sem on(I2C is free)
#endif

   return rc;
}

//---------------------------------------------------------------------------
int lm75_get_temp(int * ret_val)
{
   int rc;

#if defined(__UCOS_)
   INT8U err;

   OSSemPend(gpSemI2Cop,0,&err);  //-- Wait until I2C released(sem on)
   VICIntEnClear = 0x00004000;  //-- Disable Int 0 - from I/O extender PCA9555
#elif defined(__TNKERNEL_)
   tn_sem_acquire(&gSemI2Cop,TN_WAIT_INFINITE); //-- Wait until I2C released(sem on)
   VICIntEnClear |= 0x00004000;  //-- Disable Int 0 - from I/O extender PCA9555
#endif

   rc = lm75_read16(0,LM75_REG_TEMP,ret_val);

#if defined(__UCOS_)
   VICIntEnable  |= 0x00004000;       //-- Enable Int 0
   OSSemPost(gpSemI2Cop);             //-- Set sem on(I2C is free)
#elif defined(__TNKERNEL_)
   VICIntEnable  |= 0x00004000;       //-- Enable Int 0
   tn_sem_signal(&gSemI2Cop);         //-- Set sem on(I2C is free)
#endif

   return rc;
}

//===========================================================================
//================ I/O Extender PCA9555  ==================================
//===========================================================================

//----------------------------------------------------------------------------
int pca9555_write(int Mode, int val)
{

 //  I2C_Write(Mode,val);

   int ctrl;
   int rc;

   ctrl = 0x42; //--- 0100 001 0

   //--- wr START + CONTROL
   rc = i2c_lpc_ctrl(ctrl);  //-- Now WR (RD/WI = 0)
   if(rc != I2C_NO_ERR)
      return rc;
   //--- wr Mode
   i2c_lpc_wr_byte(Mode);
   //--- wr Port 0
   i2c_lpc_wr_byte(val & 0x000000FF);
   //--- wr Port 1
   i2c_lpc_wr_byte((val>>8) & 0x000000FF);

   i2c_lpc_stop();

   return I2C_NO_ERR;
}

//----------------------------------------------------------------------------
int pca9555_read(int Mode, int * ret_val)
{
   int ctrl;
   int rc;
   int rd_val;
   unsigned char buf[4];


   ctrl = 0x42; //--- 0100 001 0

   //--- wr START + CONTROL
   rc = i2c_lpc_ctrl(ctrl); //-- Now WR (RD/WI = 0)
   if(rc != I2C_NO_ERR)
      return rc;
   //--- wr Mode
   i2c_lpc_wr_byte(Mode);

   //--- wr START + CONTROL
   rc = i2c_lpc_ctrl(ctrl | 0x01); //-- Now RD (RD/WI = 1)
   if(rc != I2C_NO_ERR)
      return rc;

   rc = i2c_lpc_rx_to_buf(&buf[0],2);
   if(rc != I2C_NO_ERR)
      return rc;

   i2c_lpc_stop();                 //-- Set STOP condition

   rd_val = (buf[1]<<8)& 0x0000FF00; //-- Port1
   rd_val |= buf[0];  //-- Port 0

   *ret_val = rd_val;

   return I2C_NO_ERR;
}

//===========================================================================
//================ Real Time Clock DS1307  ==================================
//===========================================================================

//----------------------------------------------------------------------------
char ds1307_toBCD(char bin_val)
{
//-- this function converts an 8 bit binary value
//-- to an 8 bit BCD value. Input range from 0 to 99.

   char temp;
   char retval;

   temp = bin_val;
   retval = 0;

   for(;;)
   {  // get tens digit by multiple subtraction of 10 from bin_val
      if(temp >= 10)
      {
         temp -= 10;
         retval += 0x10; // increment tens digit
      }
      else  // get ones digit by adding remainder
      {
         retval += temp; // adjusted result
         break;
      }
   }
   return retval;
}

//----------------------------------------------------------------------------
char ds1307_fromBCD(char bcd_val)
{
   return ((bcd_val >> 4) & 0x0F)*10 + (bcd_val & 0x0F);
}

//----------------------------------------------------------------------------
int ds1307_set(DATETIMEINFO * dti)
{
   int i;
   char buf[8];
#if defined(__UCOS_)
   INT8U err;
#endif

   buf[0] = dti->second;    // Seconds
   buf[1] = dti->minute;    // Minutes
   buf[2] = dti->hour;      // Hours
   buf[3] = 1;             // Day of week not supported! -> Always 1
   buf[4] = dti->day;      // Date
   buf[5] = dti->month;     // Month
   buf[6] = dti->year;      // Year
   buf[7] = 0;             // Control  = 00h (SQWE disable)

  //-- convert to BCD
   for(i=0; i<7; i++)
   {
      buf[i] = ds1307_toBCD(buf[i]);
   }
   //-- Set control bits
   buf[0] &= 0x7f;    //-- Seconds  bit 7(CH)    = 0 (clock enabled)
   buf[2] &= 0xbf;    //-- Hours    bit 6(12/24) = 0(24-hour mode)

#if defined(__UCOS_)
   OSSemPend(gpSemI2Cop,0,&err);  //-- Wait until I2C released(sem on)
   VICIntEnClear = 0x00004000;  //-- Disable Int 0 - from I/O extender PCA9555
#elif defined(__TNKERNEL_)
   tn_sem_acquire(&gSemI2Cop,TN_WAIT_INFINITE); //-- Wait until I2C released(sem on)
   VICIntEnClear |= 0x00004000;  //-- Disable Int 0 - from I/O extender PCA9555
#endif

   i2c_lpc_init(I2C_SPEED_100);
   i = ds1307_wr_regs(buf);
   i2c_lpc_init(I2C_SPEED_400);

#if defined(__UCOS_)
   VICIntEnable  |= 0x00004000;       //-- Enable Int 0
   OSSemPost(gpSemI2Cop);             //-- Set sem on(I2C is free)
#elif defined(__TNKERNEL_)
   VICIntEnable  |= 0x00004000;       //-- Enable Int 0
   tn_sem_signal(&gSemI2Cop);         //-- Set sem on(I2C is free)
#endif

   return i;
}

//----------------------------------------------------------------------------
int ds1307_get(DATETIMEINFO * dti)
{
   int rc;
   char buf[8];

#if defined(__UCOS_)
   INT8U err;

   OSSemPend(gpSemI2Cop,0,&err);  //-- Wait until I2C released(sem on)
   VICIntEnClear = 0x00004000;  //-- Disable Int 0 - from I/O extender PCA9555
#elif defined(__TNKERNEL_)
   tn_sem_acquire(&gSemI2Cop,TN_WAIT_INFINITE); //-- Wait until I2C released(sem on)
   VICIntEnClear |= 0x00004000;  //-- Disable Int 0 - from I/O extender PCA9555
#endif

   i2c_lpc_init(I2C_SPEED_100);
   rc = ds1307_rd_regs(buf);
   i2c_lpc_init(I2C_SPEED_400);

#if defined(__UCOS_)
   VICIntEnable  |= 0x00004000;       //-- Enable Int 0
   OSSemPost(gpSemI2Cop);             //-- Set sem on(I2C is free)
#elif defined(__TNKERNEL_)
   VICIntEnable  |= 0x00004000;       //-- Enable Int 0
   tn_sem_signal(&gSemI2Cop);         //-- Set sem on(I2C is free)
#endif

   if(rc != I2C_NO_ERR)
      return rc;

   //-- Mask off the unused bits
   buf[0] &= 0x7F; // Seconds
   buf[1] &= 0x7F; // Minutes
   buf[2] &= 0x3F; // Hours
   buf[3] &= 0x07; // Day of week not supported! -> Always 1
   buf[4] &= 0x3F; // Date (day of month)
   buf[5] &= 0x1F; // Month
                   // Year - not need

   //-- Convert from BCD

   dti->second  = ds1307_fromBCD(buf[0]); // Seconds
   dti->minute  = ds1307_fromBCD(buf[1]); // Minutes
   dti->hour    = ds1307_fromBCD(buf[2]); // Hours
   dti->day     = ds1307_fromBCD(buf[4]); // Date
   dti->month   = ds1307_fromBCD(buf[5]); // Month
   dti->year    = ds1307_fromBCD(buf[6]); // Year

   return I2C_NO_ERR;
}

//----------------------------------------------------------------------------
int ds1307_wr_regs(char * buf)  //---- Wr 8 control bytes to DS1307
{
   int rc;
   int num;
//---- Wr ----------
   //--- wr START + CONTROL
   rc = i2c_lpc_ctrl(0xd0);     //-- Now WR (RD/WI = 0); 0xd0 - ID of DS1307
   if(rc != I2C_NO_ERR)
      return rc;
   //--- wr ADDRESS
   i2c_lpc_wr_byte(0);
   //---  Write  data
   num = 8;
   while(num--)                 //-- transmit data until length>0
   {
      rc = *buf++; //---
      i2c_lpc_wr_byte(rc);
   }
   i2c_lpc_stop();
 //--------------------
   return I2C_NO_ERR;
}

//----------------------------------------------------------------------------
int ds1307_rd_regs(char * buf)  //---- Rd 8 control bytes from DS1307
{
   int rc;
//---- RD ------
   //--- wr START + CONTROL
   rc = i2c_lpc_ctrl(0xd0); //-- Now WR (RD/WI = 0)
   if(rc != I2C_NO_ERR)
      return rc;
   //--- wr ADDRESS
   i2c_lpc_wr_byte(0);

   //--- wr START + CONTROL again - for read start
   rc = i2c_lpc_ctrl(0xd0 | 0x01); //-- Now RD (RD/WI = 1)
   if(rc != I2C_NO_ERR)
      return rc;

   rc = i2c_lpc_rx_to_buf(buf,8);
   if(rc != I2C_NO_ERR)
      return rc;

   i2c_lpc_stop();     //---- Set STOP ---
//-------------------------------------
   return I2C_NO_ERR;
}

//----------------------------------------------------------------------------
int ds1307_wr_nvram(int addr,int num, char * buf,int * b_wr)
{
   int n_wr;
   int rc;

   addr += 0x08;
   n_wr = 0x3f - addr;
   if(n_wr <= 0)
      return I2C_ERR_WRONG_PARAM;

   n_wr = __min(n_wr,num);
   if(n_wr <= 0)
      return I2C_ERR_WRONG_PARAM;

 //---- Wr ----------
   //--- wr START + CONTROL
   rc = i2c_lpc_ctrl(0xd0); //-- Now WR (RD/WI = 0); 0xd0 - ID of DS1307
   if(rc != I2C_NO_ERR)
      return rc;
   //--- wr ADDRESS
   i2c_lpc_wr_byte(addr);
   //---  Write  data
   num = n_wr;
   while(num--)                 //-- transmit data until length>0
   {
      rc = *buf++; //---
      i2c_lpc_wr_byte(rc);
   }
   i2c_lpc_stop();
 //--------------------
   *b_wr = n_wr;
   return I2C_NO_ERR;
}

//----------------------------------------------------------------------------
int ds1307_rd_nvram(int addr,int num, char * buf,int * b_rd)
{
   int n_rd;
   int rc;

   addr += 0x08;
   n_rd = 0x3f - addr;
   if(n_rd <= 0)
      return I2C_ERR_WRONG_PARAM;

   n_rd = __min(n_rd,num);

   if(n_rd <= 0)
      return I2C_ERR_WRONG_PARAM;

   i2c_lpc_init(I2C_SPEED_100);

//---- RD ------
   //--- wr START + CONTROL
   rc = i2c_lpc_ctrl(0xd0); //-- Now WR (RD/WI = 0)
   if(rc != I2C_NO_ERR)
      return rc;
   //--- wr ADDRESS
   i2c_lpc_wr_byte(addr);

   //--- wr START + CONTROL again - for read start
   rc = i2c_lpc_ctrl(0xd0 | 0x01); //-- Now RD (RD/WI = 1)
   if(rc != I2C_NO_ERR)
      return rc;

   rc = i2c_lpc_rx_to_buf(buf,n_rd);
   if(rc != I2C_NO_ERR)
      return rc;

   i2c_lpc_stop();     //---- Set STOP ---

//--------------

   *b_rd = n_rd;
   return I2C_NO_ERR;
}

//---------------------------------------------------------------------------

⌨️ 快捷键说明

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