view src/cs/drivers/drv_app/fchg/bsim_etm_cmd.c @ 281:a75eefbf8be4

Phone boot with PWON: weed out short button presses Every standard end user phone has a design provision, most naturally implemented in firmware, whereby the PWON button effects a boot only if it is held down long enough - short presses of this PWON button are detected, assumed to be spurious and cause the fw to power back off instead of proceeding with boot. The present change introduces this standard function in FreeCalypso.
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 24 Sep 2021 02:03:08 +0000
parents aec644728174
children
line wrap: on
line source

/*
 * In this module we are going to implement our handling of
 * ETM_BSIM command packets sent from a development host.
 */

#include "fchg/fchg_env.h"
#include "fchg/fchg_func_i.h"
#include "fchg/bsim_func_i.h"
#include "fchg/bsim_etm_cmd.h"
#include "rv/rv_general.h"
#include "rvf/rvf_api.h"
#include "rvm/rvm_use_id_list.h"
#include "etm/etm.h"
#include "etm/etm_api.h"

static void bsim_cmd_query(T_ETM_PKT *resp)
{
	etm_pkt_put8(resp, pwr_ctrl->state);
	etm_pkt_put8(resp,
	pwr_ctrl->batt.percent_thresh[pwr_ctrl->curr_disch_thresh].remain_capa);
	etm_pkt_put8(resp, pwr_ctrl->bsim.start_enable);
	resp->status = BSIM_STAT_OK;
}

static void bsim_cmd_discharge(T_ETM_PKT *resp, UINT8 set_percent)
{
	UINT16 i;

	switch (pwr_ctrl->state) {
	case FCHG_STATE_NO_EXT_PWR:
	case FCHG_STATE_PWR_PLUG_TIMER:
	case FCHG_STATE_READY_TO_CHARGE:
	case FCHG_STATE_READY_TO_RECHARGE:
	case FCHG_STATE_RECHARGE_TIMER:
	case FCHG_STATE_NO_CHARGING:
		break;
	default:
		resp->status = BSIM_ERR_WRONG_STATE;
		return;
	}
	for (i = 0; i < pwr_ctrl->nb_percent_thresh; i++) {
		if (pwr_ctrl->batt.percent_thresh[i].remain_capa ==
		    set_percent)
			break;
	}
	if (i >= pwr_ctrl->nb_percent_thresh) {
		resp->status = BSIM_ERR_INV_PERCENT;
		return;
	}
	if (i <= pwr_ctrl->curr_disch_thresh) {
		resp->status = BSIM_ERR_INV_DISCHARGE;
		return;
	}
	pwr_ctrl->curr_disch_thresh = i;
	if (pwr_ctrl->event_handler)
		pwr_ctrl->event_handler(FCHG_EVENT_DISCHARGE);
	resp->status = BSIM_STAT_OK;
}

static void bsim_cmd_chg_start(T_ETM_PKT *resp)
{
	switch (pwr_ctrl->state) {
	case FCHG_STATE_READY_TO_CHARGE:
	case FCHG_STATE_READY_TO_RECHARGE:
		break;
	default:
		resp->status = BSIM_ERR_WRONG_STATE;
		return;
	}
	rvf_send_trace("BSIM: simulated charging start", 30, NULL_PARAM,
			RV_TRACE_LEVEL_DEBUG_MEDIUM, FCHG_USE_ID);
	pwr_ctrl->state = FCHG_STATE_I2V_CAL_1;
	resp->status = BSIM_STAT_OK;
}

static void bsim_cmd_chg_ci2cv(T_ETM_PKT *resp)
{
	if (pwr_ctrl->state != FCHG_STATE_CI_CHARGING) {
		resp->status = BSIM_ERR_WRONG_STATE;
		return;
	}
	rvf_send_trace("BSIM: simulated charging CI->CV", 31, NULL_PARAM,
			RV_TRACE_LEVEL_DEBUG_MEDIUM, FCHG_USE_ID);
	pwr_ctrl->state = FCHG_STATE_CV_CHARGING;
	resp->status = BSIM_STAT_OK;
}

static void bsim_cmd_chg_complete(T_ETM_PKT *resp)
{
	if (pwr_ctrl->state != FCHG_STATE_CV_CHARGING) {
		resp->status = BSIM_ERR_WRONG_STATE;
		return;
	}
	rvf_send_trace("BSIM: simulated charging complete", 33, NULL_PARAM,
			RV_TRACE_LEVEL_DEBUG_MEDIUM, FCHG_USE_ID);
	pwr_init_discharge();
	pwr_ctrl->state = FCHG_STATE_READY_TO_RECHARGE;
	if (pwr_ctrl->event_handler)
		pwr_ctrl->event_handler(FCHG_EVENT_CHARGING_COMPLETE);
	resp->status = BSIM_STAT_OK;
}

static void bsim_cmd_set_ichg(T_ETM_PKT *resp, UINT16 ichg)
{
	pwr_ctrl->ci_ichg = ichg;
	pwr_ctrl->ichg_average = ichg;
	resp->status = BSIM_STAT_OK;
}

static void bsim_cmd_start_enable(T_ETM_PKT *resp, UINT8 setting)
{
	pwr_ctrl->bsim.start_enable = setting;
	resp->status = BSIM_STAT_OK;
}

void bsim_process_etm(T_ETM_DATA_READY *msg)
{
	T_ETM_PKT *resp;
	uint8 fid;

	resp = (T_ETM_PKT *) etm_malloc(sizeof(T_ETM_PKT));
	if (!resp) {
		rvf_send_trace(
		    "Unable to respond to ETM_BSIM: etm_malloc() failed", 50,
			NULL_PARAM, RV_TRACE_LEVEL_ERROR, FCHG_USE_ID);
		return;
	}
	/* init response packet */
	resp->mid = ETM_BSIM;
	resp->size = 0;
	resp->index = 0;
	/* start processing command */
	fid = msg->data[0];
	etm_pkt_put8(resp, fid);
	/* command dispatch */
	switch (fid) {
	case BSIM_CMD_QUERY:
		bsim_cmd_query(resp);
		break;
	case BSIM_CMD_DISCHARGE:
		bsim_cmd_discharge(resp, etm_get8(msg->data + 1));
		break;
	case BSIM_CMD_CHG_START:
		bsim_cmd_chg_start(resp);
		break;
	case BSIM_CMD_CHG_CI2CV:
		bsim_cmd_chg_ci2cv(resp);
		break;
	case BSIM_CMD_CHG_COMPLETE:
		bsim_cmd_chg_complete(resp);
		break;
	case BSIM_CMD_SET_ICHG:
		bsim_cmd_set_ichg(resp, etm_get16(msg->data + 1));
		break;
	case BSIM_CMD_START_ENABLE:
		bsim_cmd_start_enable(resp, etm_get8(msg->data + 1));
		break;
	default:
		resp->status = BSIM_ERR_BAD_CMD;
	}
	etm_pkt_send(resp);
	etm_free(resp);
}