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

📄 smbus.c

📁 iic for avr very good
💻 C
📖 第 1 页 / 共 4 页
字号:
  return SMBerr_ReservedCommand;	//unused
}


unsigned char SMBR_Opt2(void)		// 0x3E
{

  return SMBerr_ReservedCommand;	//unused
}


unsigned char SMBR_Opt1(void)		// 0x3F
{

  return SMBerr_ReservedCommand;	//unused
}


unsigned char SMBR_invalid(void)	//This should never execute, if error is caught early!
{
  return SMBerr_UnsuptdCommand;
}



//typedef unsigned char (*ptr2funcUC_V)(void);

//Table of pointers to functions, indexed from the received SMBus Command byte.
ptr2funcUC_V SMB_ReadCmd[HIGHEST_SMB_CMD+1] =
{
  SMBR_MfrAccess,	//  0
  SMBR_RemCapAlm,	//  1
  SMBR_RemTimeAlm,	//  2
  SMBR_BattMode,  	//  3
  SMBR_AtRate,     	//  4
  SMBR_AtRateTTF,  	//  5
  SMBR_AtRateTTE,  	//  6
  SMBR_AtRateOK,   	//  7
  SMBR_Temperature,	//  8
  SMBR_Voltage,    	//  9
  SMBR_Current,    	// 10
  SMBR_AvgCurrent, 	// 11
  SMBR_MaxError,   	// 12
  SMBR_RelSOC,     	// 13
  SMBR_AbsSOC,     	// 14
  SMBR_RemCap,     	// 15
  SMBR_FullChgCap, 	// 16
  SMBR_RunTTE,     	// 17
  SMBR_AvgTTE,     	// 18
  SMBR_AvgTTF,     	// 19
  SMBR_ChgCurrent, 	// 20
  SMBR_ChgVoltage, 	// 21
  SMBR_BattStatus, 	// 22
  SMBR_CycleCount, 	// 23
  SMBR_DesignCap,  	// 24
  SMBR_DesignVolt, 	// 25
  SMBR_SpecInfo,   	// 26
  SMBR_MfrDate,    	// 27
  SMBR_SerialNo,   	// 28
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_MfrName,    	// 32
  SMBR_DeviceName, 	// 33
  SMBR_DeviceChem, 	// 34
  SMBR_MfrData,    	// 35
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_Opt5,       	// 0x2F
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_invalid,
  SMBR_Opt4,       	// 0x3C
  SMBR_Opt3,       	// 0x3D
  SMBR_Opt2,       	// 0x3E
  SMBR_Opt1       	// 0x3F
};



/* *************************************************************************
 *
 *   Individual handlers for SMBus WRITE-type commands
 *
 ************************************************************************* */


unsigned char SMBW_MfrAccess(void)	//  0
{
  unsigned char temp = TW_RxBuf[TW_RxBufIndex++];
  SMBvar_int[SMBV_MfrAccess] = temp | (TW_RxBuf[TW_RxBufIndex]<<8);
  SMBvariables[SMBV_BattStatus][lobyte] &= 0xF0;  //since this cmd is OK, clear Error bits per sbdat110, 4.3.2
  return 0;
}


unsigned char SMBW_RemCapAlm(void)	//  1
{
  unsigned char temp = TW_RxBuf[TW_RxBufIndex++];
  SMBvar_int[SMBV_RemCapAlm] = temp | (TW_RxBuf[TW_RxBufIndex]<<8);
  SMBvariables[SMBV_BattStatus][lobyte] &= 0xF0;  //since this cmd is OK, clear Error bits per sbdat110, 4.3.2
  return 0;
}


unsigned char SMBW_RemTimeAlm(void)	//  2
{
  unsigned char temp = TW_RxBuf[TW_RxBufIndex++];
  SMBvar_int[SMBV_RemTimeAlm] = temp | (TW_RxBuf[TW_RxBufIndex]<<8);
  SMBvariables[SMBV_BattStatus][lobyte] &= 0xF0;  //since this cmd is OK, clear Error bits per sbdat110, 4.3.2
  return 0;
}


unsigned char SMBW_BattMode(void)  	//  3
{
  unsigned char tempH = TW_RxBuf[TW_RxBufIndex+1];
  unsigned char tempL;

  tempL = SMBvariables[SMBV_BattMode][lobyte] & 0xF0;

  if(tempH & 0x1C)
    return SMBerr_AccessDenied;		//attempt to write to reserved bits!


  if(~(tempL & INTERNAL_CHARGE_CONTROLLER))
  {
    tempH &= ~CHARGE_CONTROLLER_ENABLED;  //feature not present, don't let it get turned on.
  }


  if(tempH & PRIMARY_BATTERY)
  {
    ;	//let the Host do what it wants with this flag; we ignore it.
  }

  if(tempH & ALARM_MODE)
    SetAlarmMode;	//this DISABLES sending alarm msgs for 60 secs


  if(tempH & CHARGER_MODE)
  {
    ;	//Allow Host to enable us to send Master-mode Charger-Voltage/Current msgs to the Charger
  }


  if(tempH & CAPACITY_MODE)
  {
    ;	//Host must be allowed to control this bit (report in mAH or 10mWH)
  }


  SMBvar_int[SMBV_BattMode] = tempL | (tempH<<8);	//write the modified bits.

  return 0;
}



unsigned char SMBW_AtRate(void)     	//  4
{
  unsigned char temp = TW_RxBuf[TW_RxBufIndex++];
  SMBvar_int[SMBV_AtRate] = temp | (TW_RxBuf[TW_RxBufIndex++]<<8);
  SMBvariables[SMBV_BattStatus][lobyte] &= 0xF0;  //since this cmd is OK, clear Error bits per sbdat110, 4.3.2
  return 0;
}

unsigned char SMBW_Opt5(void)       	// 0x2F
{
  __disable_interrupt();
  MCUSR = 0x1F;                         //clear all reset sources before jumping to bootloader code.
//  __watchdog_reset;					//

  asm("jmp 0x9000");					// Byte adress

//  __watchdog_reset;						// reset watchdog
  return(1);							// to avoid compiler warning, should never be reached

//  return SMBerr_ReservedCommand; // <-- Compiler generates warning if return statement is missing.
}

unsigned char SMBW_Opt4(void)       	// 0x3C
{
  calibration_state_req = TW_RxBuf[TW_RxBufIndex++];
  calibration_state_req |= (unsigned int)TW_RxBuf[TW_RxBufIndex++] << 8; // Store request details.
  SetCalibRequest; // Set action flag so that main loop starts calibrating.
  return 0; // Return OK.
}

unsigned char SMBW_Opt3(void)       	// 0x3D
{
  return SMBerr_ReservedCommand;
}

unsigned char SMBW_Opt2(void)       	// 0x3E
{
  return SMBerr_ReservedCommand;
}

unsigned char SMBW_Opt1(void)       	// 0x3F
{
  return SMBerr_ReservedCommand;
}

unsigned char SMBW_Invalid(void)	//This should never execute, if error is caught early!
{
  return SMBerr_AccessDenied;
}



//Table of pointers to functions, indexed from the received SMBus Command byte.
ptr2funcUC_V SMB_WriteCmd[HIGHEST_SMB_CMD+1] =
{
  SMBW_MfrAccess,	//  0
  SMBW_RemCapAlm,	//  1
  SMBW_RemTimeAlm,	//  2
  SMBW_BattMode,  	//  3
  SMBW_AtRate,     	//  4
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,		//0x0F

  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,		//0x1F

  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Opt5,       	// 0x2F

  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Invalid,
  SMBW_Opt4,       	// 0x3C
  SMBW_Opt3,       	// 0x3D
  SMBW_Opt2,       	// 0x3E
  SMBW_Opt1       	// 0x3F
};






/* *************************************************************************
 *
 *   Utilities for SMBus commmunications
 *
 ************************************************************************* */



__flash unsigned char crctable[16] =  {0,0x07,0x0E,0x90, 0x1c,0x1b,0x12,0x15, 0x38,0x3F,0x36,0x31, 0x24,0x23,0x2A,0x2D};
__flash unsigned char crctable2[16] = {0,0x70,0xE0,0x90, 0xC1,0xB1,0x21,0x51, 0x83,0xF3,0x63,0x13, 0x42,0x32,0xA2,0xD2};

unsigned char FastCRC(unsigned char LastCRC, unsigned char newbyte)
{
  unsigned char index;

  index = newbyte;
  index ^= LastCRC;
  index >>= 4;
  LastCRC &= 0x0F;
  LastCRC ^= crctable2[index];

  index = LastCRC;
  index ^= newbyte;
  index &= 0x0F;
  LastCRC &= 0xF0;
  LastCRC ^= crctable[index];

  return(LastCRC);
}

/*  This version doesn't require crctable2[], but requires more shifts.
unsigned char SlowerCRC(unsigned char LastCRC, unsigned char newbyte)
{
  unsigned char index;

  index = newbyte;
  index ^= LastCRC;
  index >>= 4;
  LastCRC <<= 4;
  LastCRC ^= crctable[index];

  index = LastCRC >> 4;
  index ^= newbyte;
  index &= 0x0F;
  LastCRC <<= 4;
  LastCRC ^= crctable[index];

  return(LastCRC);
} */






//! \todo  This can be modified to load defaults from EEPROM rather than fixed values to the SMB variables.
// This sets power-up defaults.
void InitSMBvariables(void)
{
  SMBvar_int[SMBV_MfrAccess] = 0x4060;				// Mega406 ap-note, revision 0 code
  SMBvar_int[SMBV_RemCapAlm] = (PACK_DESIGNCAPTYP / 10);	// per sbdat110, 4.4.1
  SMBvar_int[SMBV_RemTimeAlm] = 0x000A;			// per sbdat110, 4.4.1
  SMBvar_int[SMBV_BattMode  ] = 0x0000;	//
  SMBvar_int[SMBV_AtRate    ] = 0x0000;	//

/* For testing with no calcs
  SMBvar_int[SMBV_AtRateTTF ] = 0x0000;	//
  SMBvar_int[SMBV_AtRateTTE ] = 0x0000;	//
  SMBvar_int[SMBV_AtRateOK  ] = 0x0000;	//

  SMBvar_int[SMBV_Temperature] = 0x0000;	//
  SMBvar_int[SMBV_Voltage    ] = 0x0000;	//
  SMBvar_int[SMBV_Current    ] = 0x0000;	//
  SMBvar_int[SMBV_AvgCurrent ] = 0x0000;	//
  SMBvar_int[SMBV_MaxError   ] = 0x0000;	//
  SMBvar_int[SMBV_RelSOC     ] = 0x0000;	//
  SMBvar_int[SMBV_AbsSOC     ] = 0x0000;	//
  SMBvar_int[SMBV_RemCap     ] = 0x0000;	//

  SMBvar_int[SMBV_FullChgCap] = 0x0000;	//
  SMBvar_int[SMBV_RunTTE    ] = 0x0000;	//
  SMBvar_int[SMBV_AvgTTE    ] = 0x0000;	//
  SMBvar_int[SMBV_AvgTTF    ] = 0x0000;	//
  SMBvar_int[SMBV_ChgCurrent] = 0x0000;	//
  SMBvar_int[SMBV_ChgVoltage] = 0x0000;	//
*/
  SMBvar_int[SMBV_BattStatus] = 0x0080;	//per sbdat110, 4.4.1
  SMBvar_int[SMBV_CycleCount] = 0x0000;	//per sbdat110, 4.4.1

/* For testing with no calcs
  SMBvar_int[SMBV_DesignCap ] = 0x0000;	//
  SMBvar_int[SMBV_DesignVolt] = 0x0000;	//
*/

  SMBvar_int[SMBV_SpecInfo  ] = 0x0031;	// no scaling of I or V; we support PEC, and we're V1.1
  SMBvar_int[SMBV_MfrDate   ] = ((2005-1980)<<9)+(8<<5)+(31);	//! \todo Fill in current year, month, day. Values are octal
  SMBvar_int[SMBV_SerialNo  ] = 12345;	// arbitrary...

  //Note that for the Block-Read variables, we copy those into a RAM buffer only as needed.
  // These are MfrName, DeviceName, DeviceChem, and MfrData.

  SetMaxTopAcc((long)6600*10727);   //! \todo for testing, initialized value before reaching fully charged, 6600mAh * 10727
//  RunningAcc = (long)1000*10727;    //for testing, to start at other point than 0, 1000 * 10727
}




/* Some important notes from the SMBus specs:

Insertion or removal of a Smart Battery may be detected when the 慡afety Signal

⌨️ 快捷键说明

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