<EPCD-055> <SMBus> <Local_SMBus> <F-Service_SMBus> ** Mount in "service_peripheral_table" * <F-OEM_SMBus> ** Just call SMBus_IRQ * <F-SMBus_IRQ> ** (Dummy)Test "REG_SMB_IF(SMBPF)", if have interrupt, ** (Dummy)-> Get value of "REG_SMB_ALRM_ADDR" "REG_SMB_RSA" "REG_SMB_ALRM_DATA[0]&[1]" ** Test "REG_SMB_STS[6]"(host notify protocol), if Alarm Recive, ** -> Write value "REG_SMB_ALRM_ADDR" "REG_SMB_ALRM_DATA[0]&[1]" to EC_RAM ** Send SxI_Queue * </F-SMBus_IRQ> </F-OEM_SMBus> </F-Service_SMBus> <SMBus_Function> F-SMBus_ReadWord F-SMBus_ReadByte F-SMBus_ReadBlock F-SMBus_WriteWord F-SMBus_WriteByte <F-SMBus_Transaction> ** Fill up REG_SMBus with arg "struct SMB_REQUEST_ST" ** Switch(Protocol) to Select Method ** At "DONE:" Lable -> ** Test if SMBSTS[5] or [7] is 1, goto "TRANS_OK:" ** If SMBSTS[5]==1(trans not finish due to low clock), check protocol then -> ** (clear SMBSTS except Alarm bit) goto "AGAIN:" finish trans. * <F-SMBus_Set_Timeout_30uS> ** At "AGAIN:" Lable -> ** If BLOCK_WRITE or BLOCK_READ, test transaction(Test SMBSTS[5]&[7]) for 125ms. ** If not finish in 125ms -> there's a trouble, reset SMBus host ** If SMBSTS[5] is 1, trans not finish due to slow clock, then goto "DONE:" ** If SMBSTS[7] is 1 , trans command done, then goto "DONE:" * </F-SMBus_Set_Timeout_30uS> </F-SMBus_Transaction> </SMBus_Function> </Local_SMBus> <ACPI_SMBus> <F-service_peripheral> ** ACPI Burst Mode * <F-OEM_Write_EC_Space> ** Switch "BANK_ID" * <F-Write_EC_BANK0> ** Write Data by Address, but with part of "Write to SMBus" * <F-OEM_ACPI_SMBus_Alloc> ** Alloc SMBus with ACPI, Set SMBus Interrpt pin Enable * </F-OEM_ACPI_SMBus_Alloc> <F-OEM_Write_SMBus_Memory> ** Write SMBus's REG by switch() once a time until write "EC_RAM_SMB_PRTCL". ** Use F-SMBus_Transaction sent to SMBus. * </F-OEM_Write_SMBus_Memory> </F-Write_EC_BANK0> </F-OEM_Write_EC_Space> </F-service_peripheral> </ACPI_SMBus> </SMBus>
<Smart_Batt> <F-Timer0_T2500usRoutines> ** Make timers : 5ms 10ms 100ms, (2500us = 2.5ms) ** Query BATT(in 10mS section) every 3200ms -> "OEM_BAT_Monitor_State()" * <F-Time_Tick_100mS> ** Initial SMBus0, IF !BATT1_IN & !BATT2_IN -> [Check IF SMBus0_INITED -> Reset()], Else -> always do nothing until BATT_IN ** IF BATT_IN -> SMBus0_INIT, Assert reset signal > 2.5s do the reset ** Else -> Check Battery every 10s ** For "batt_id = 0 ~ 1" ** IF !BATT_IN -> do nothing, ** Else IF (BATT.IS_INITED ||...) -> do nothing, batt monitor will act in T2500usRoutines, ** Else -> Init SMBus0_BattTimer[1,2] = 0; SMBus0_BattTimer[batt_id]++; ** Test SMBus0_BattTimer[batt_id], "batt_id=0" will enter, but "batt_id=1" will enter after 100*100ms * <SWITCH--F-OEM_Battery_Mode_Init> ** Switch SMBus to Battery, save Data to "REG_EC_BATT" struct ** (Read SMBus)(ERR return 0) Get DesignCapacity -> "REG_EC_BATT" ** (Read SMBus)(ERR return 0) Get ManufacturerName -> bat_info ** (Read SMBus)(ERR return 0) Get DeviceName -> bat_name ** Set info(TEMP_WARNING, TEMP_CRITICAL, MAX_I, CELL_S) to "REG_EC_BATT" ** (Read SMBus)(ERR return 0) Get DesignVoltage -> "REG_EC_BATT" ** (OK return 1, ELSE return ERR_CODE) * <CASE_0> ** Case 0: Battery is in degraged mode, Start to precharge * <F-OEM_BAT_Control> ** ASSUME => _BAT_Charging_Ctrl()=A(); _BAT_Discharging_Ctrl=B(); ** If (ECFW_UPDATED || BAT_CTRL_DISABLED || DC_POWER_TESTING || ECFW_FAILURE || NO BAT IN || NO BAT INIT) -> goto "STOP_CONTROL" ** At "STOP_CONTROL:" Lable -> A(FALSE);B(FALSE);return; ** If BAT_DEGRADED || (AC_IN & !BAT_LEARN_ENABLED) -> A(TRUE);B(FALSE); ** Else -> A(FALSE);B(TRUE); * <F-_BAT_Charging_Ctrl> ** (Dummy variable) -> charging_mA, charging_mV ** ctrl_flag = (!enabled || BAT_LEARN_ENABLED ? (TRUE -> 0, Charge_OFF -> return) : (FALSE -> batt_id)); ** If (FULLY_CHARGED || CHARGING_TIMEOUT || ctrl_flag[4,5,6] & (TIME_BATCHG_1Min==0)) -> batt_id=BATT2=1; ** switch(ctrl_flag & ACTIVE_BATT_MASK) ** Case 0: Dummy?? return; ** Case 1,2: If Battery is degraded ** (If Timeout goto "CHG_PAUSE") ** SETBITs "ctrl_flag",_BatteryCharging_mA=PreCharge_mA, _BatteryCharging_mV=PreCharge_mV, goto "CHG_ON"; ** Else ** If (TEMP over MAX || TEMP lower MIN || Battery Alarming || mA=0 || mV=0) -> goto "CHG_PAUSE"; ** If (BATT_TEMP <= temp_check) & (BATT_TEMP >= TEMP_MIN) ** If (mA <= PreCharge_mA) -> Test & Set if init PreCharge timer?, Else -> Test & Set if init Charge timer?; ** At "CHG_ON:" Lable: ** SMBus switch to Battery ** (Write SMBus) Set_BattCharger_mV, if ERR -> SET(ctrl_flag, mV_ERR), Else -> Clear(ctrl_flag, mV_ERR) ** (Write SMBus) Set_BattCharger_mA, if ERR -> SET(ctrl_flag, mA_ERR), Else -> Clear(ctrl_flag, mA_ERR) ** If (mV_ERR || mA_ERR) -> goto "CHG_PAUSE", Else -> "Battery_Charge_ON(batt_id);" ** At "CHG_PAUSE:" Lable : ** Else -> Charge_OFF; * </F-_BAT_Charging_Ctrl> <F-_BAT_Discharging_Ctrl> ** ctrl_flag = (!enabled || !FLAG_DISCHARGING || BAT_DEGRADED? (TRUE -> 0, Throttle_CPU_Disabled -> return) : (FALSE -> batt_id)); ** At "BATT1_ON:" "BATT2_ON:" Lable: ** Set -> itself FLAG_DISCHARGING, BATT_MODE, Clear -> another's FLAG_DISCHARGING, Send -> SxI_Queue; ** Set -> "OCP_mA, Max_mA, Batt_temp, Batt_temp_warn, Batt_temp_crit" From REG_EC; ** OCP(Over Current Protect), OCP_mA is native number, turn to positive -> OCP_mA=(~OCP_mA)+1 ** IF (Batt_temp < Batt_temp_warn) -> Send SxI_Queue(SxI_Temp_BAT_Normal), Clear flags of temp warning ** Else -> IF !DisChgTemp_Warning -> Set & Send SxI_Queue (Temp_Warning); ** Else -> IF (Batt_temp >= Batt_temp_crit) -> Set & Send SxI_Queue (Temp_Critical); ** Elee -> Clear Temp_Critical & Send SxI_Queue(Temp_Warning); ** IF (BATT_TEMP_ALARM || DisChgOCP || DisChgTemp_Critical || DisChgTemp_Warning) -> Throttle_CPU_Enabled; ** Else -> Throttle_CPU_Disabled; * </F-_BAT_Discharging_Ctrl> </F-OEM_BAT_Control> </CASE_0> <CASE_1> ** Case 1: Battery is ready, Start to monitor * <F-OEM_BAT_Refresh_Status> ** SMBus switch to Battery ** Read info >> by loop, once a time * <F-_BAT_Monitor_Status> ** Switch(state) ** Case 0: (Read SMBus) Get BatteryStatus -> "_BatteryStatus[batt_id]" ** if (OVER_TEMP, FULLY_CHARGED, FULLY_DISCHARGED) -> Set_EC_Flag, Else -> Clear_EC_Flag ** Case 1: (Read SMBus) Get Temperature -> "REG_EC_BATT[batt_id].TEMP" ** Case 2: (Read SMBus) Get ChargingCurrent -> "_BatteryCharging_mA[batt_id]" ** if NO ERR, (Read SMBus) Get ChargingVoltage -> "_BatteryCharging_mV[batt_id]" ** Case 3: (Read SMBus) Get AverageCurrent -> "REG_EC_BATT[batt_id].AVG_I" ** Case 4: (Read SMBus) Get Current -> "REG_EC_BATT[batt_id].I" ** Case 5: (Read SMBus) Get Voltage -> "REG_EC_BATT[batt_id].VOLT" ** Case 6: (Read SMBus) Get RemainingCapacity -> "REG_EC_BATT[batt_id].CAP" ** Case 7: (Read SMBus) Get FullChargeCapacity -> "REG_EC_BATT[batt_id].FULL_CAP" ** if AC_IN & BAT_LEARN_ENABLED -> OEM_Put_SxI_Queue(SxI_Battery_Status_Update) ** Case 8: (Read SMBus) Get RelativeStateOfCharge -> "REG_EC_BATT[batt_id].RSOC" ** Case 9,10,11: Dummy State, After 11, state = 0 ** IF ERR, return ERR, Else state++ -> next state * </F-_BAT_Monitor_Status> ** If OK, Set or Clear some FLAGs, >> * <F-OEM_BAT_Control> </F-OEM_BAT_Control> </F-OEM_BAT_Refresh_Status> </CASE_1> </SWITCH--F-OEM_Battery_Mode_Init> ** SMBus1 Init ** IF NOT in S0 -> SMBus1_Timer=0, IF SMBus1_INITED -> SMBus1_Reset(); ** Else (in S0) -> IF !SMBus1_INITED -> SMBus1_Disabled(); delay 100ms to SMBus1_Enabled(); ** Else -> IF !PWRSEQ_BUSY -> OEM_SMBus1_Device_Init(); * <F-OEM_SMBus1_Device_Init> ** (Read SMBus) External Temperature CPU, IF ERROR -> reset=TRUE; goto "VGA1"; ** Else -> Set Flag THERMAL_CPU_INITED <F-_Init_VGA> ** IF OK -> return TRUE, Else(ERROR) -> return FALSE; ** (Read SMBus) from THERMAL_VGA_ADDR, IF ERROR -> Try VGA_ADDR(0x9A, 0x9E); * </F-_Init_VGA> ** IF OK -> Set Flag THERMAL_VGA_INITED, Else -> reset=TRUE; ** IF reset -> SMBus1_Reset(); * </F-OEM_SMBus1_Device_Init> ** In time 4s part * <F-T4s> ** It will call "OEM_BAT_Control()" again for every 4s ** OEM_BAT_Control() -> Charge Function * </F-T4s> </F-Time_Tick_100mS> </F-Timer0_T2500usRoutines>