2023年08月14日17:17:44 更新
以 i2c 举例
void xxx_start_hw_detect_sequence(sns_sensor *const this)
{
/**-----------------Register and Open COM Port-------------------------*/
if (NULL == state->common.com_port_info.port_handle)
{
rv = state->scp_service->api->sns_scp_register_com_port(
&state->common.com_port_info.com_config,
&state->common.com_port_info.port_handle);
if (rv == SNS_RC_SUCCESS)
{
rv = state->scp_service->api->sns_scp_open(state->common.com_port_info.port_handle);
}
}
/**---------------------Register Power Rails --------------------------*/
if (sns_suid_lookup_get(&state->common.suid_lookup_data, "timer", NULL)
&& NULL == state->pwr_rail_service
&& rv == SNS_RC_SUCCESS)
{
rv = stk3a6x_register_power_rail(this);
/**---------------------Turn Power Rails ON----------------------------*/
state->common.rail_config.rail_vote = state->common.registry_rail_on_state;
if (rv == SNS_RC_SUCCESS)
{
rv = state->pwr_rail_service->api->sns_vote_power_rail_update(state->pwr_rail_service,
this,
&state->common.rail_config,
NULL);
}
/**-------------Create a Timer stream for Power Rail ON timeout.---------*/
if (rv == SNS_RC_SUCCESS)
{
stk3a6x_start_power_rail_timer(this,
sns_convert_ns_to_ticks(STK3A6X_OFF_TO_IDLE_MS * 1000 * 1000),
STK3A6X_POWER_RAIL_PENDING_INIT);
}
}
}
1:注册 COM Port
sns_scp_register_com_port
函数路径:
sns_sync_com_port_service.c
SNS_SECTION(".text.sns") sns_rc sns_scp_register_com_port(sns_com_port_config const *com_config,
sns_sync_com_port_handle **port_handle)
{
// 已经打开过了,就不在重复打开
if(NULL != *port_handle)
{
sns_scp_deregister_com_port(port_handle);
}
// 分配空间。
port_priv_handle = sns_malloc(SNS_HEAP_ISLAND, sizeof(sns_com_port_priv_handle));
// sensor 驱动传过去的 一些参数.主要是从 registery 读取出来的数据。
sns_memscpy(&port_priv_handle->com_config,
sizeof(sns_com_port_config),
com_config,
sizeof(sns_com_port_config));
// 只是赋值了 bus_info .其他的后续再来看下
port_priv_handle->bus_info.bus_type = com_config->bus_type;
port_priv_handle->bus_info.power_on = false;
port_priv_handle->bus_info.opened = false;
/** bus_info::bus_config shall be allocated by bus specific
* implementation.
*/
*port_handle = (sns_sync_com_port_handle *)port_priv_handle;
return SNS_RC_SUCCESS;
}
2: sns_scp_open
port_handle 是第一步分配的内存,并对 bus_type 进行了些赋值
SNS_SECTION(".text.sns") sns_rc sns_scp_open(sns_sync_com_port_handle *port_handle)
{
sns_com_port_priv_handle *priv_handle = (sns_com_port_priv_handle *)port_handle;
sns_bus_info *bus_info = &priv_handle->bus_info;
sns_rc return_code = SNS_RC_SUCCESS;
// 打开过,就不要在打开了
if(bus_info->opened == true)
{
return SNS_RC_SUCCESS;
}
//
return_code = scp_port_apis[bus_info->bus_type]->sns_scp_open(port_handle);
else
{
bus_info->opened = true;
bus_info->power_on = true;
}
return return_code;
}
看下这个 scp_port_apis[bus_info->bus_type]->sns_scp_open(port_handle);
跑到 sns_com_port_i2c.c
sns_open_i2c 函数中,最后还是通过这个函数
sns_open_i2c_internal来实现的 .
static sns_rc sns_open_i2c_internal(sns_sync_com_port_handle *port_handle)
{
sns_com_port_priv_handle *priv_handle = (sns_com_port_priv_handle *)port_handle;
sns_bus_info *bus_info = &priv_handle->bus_info;
sns_com_port_config *com_config = &priv_handle->com_config;
// malloc 空间
bus_info->bus_config = sns_malloc( SNS_HEAP_ISLAND, sizeof(sns_i2c_info) );
i2c_info = (sns_i2c_info *)bus_info->bus_config;
//以请求的 i2c 速度打开 clk 资源.
sns_result =
sns_i2c_setup_clk_resources(com_config->bus_type,
(i2c_instance)(com_config->bus_instance),
com_config->max_bus_speed_KHz,
NULL);
// clk 设置完成,接下来 open i2c.
result = i2c_open( (i2c_instance)(com_config->bus_instance),
&i2c_info->i2c_handle);
// i2c 上电
result = i2c_power_on( i2c_info->i2c_handle );
// log . 可以查看 哪个 sensor 上电成功.
SNS_PRINTF( LOW, sns_fw_printf, "i2c_open success. hndl:%p instance:%u type:%u addr:0x%x",
i2c_info->i2c_handle, com_config->bus_instance,
com_config->bus_type, com_config->slave_control );
return SNS_RC_SUCCESS;
}
i2c 协议的一些上电大概就是这个流程, 其他协议应该也差不多.
普通的 gpio 口怎么上电呢? 比如 有些 sensor vdd 时序是有上电时序要求的.
再来继续看 Register Power Rails
应该是 注册 vdd/vddio
把这段代码 贴过来,看下
// 注册了个 定时器
if (sns_suid_lookup_get(&state->common.suid_lookup_data, "timer", NULL)
&& NULL == state->pwr_rail_service
&& rv == SNS_RC_SUCCESS)
{
rv = stk3a6x_register_power_rail(this);
/**---------------------Turn Power Rails ON----------------------------*/
state->common.rail_config.rail_vote = state->common.registry_rail_on_state;
if (rv == SNS_RC_SUCCESS)
{
rv = state->pwr_rail_service->api->sns_vote_power_rail_update(state->pwr_rail_service,
this,
&state->common.rail_config,
NULL);
}
/**-------------Create a Timer stream for Power Rail ON timeout.---------*/
if (rv == SNS_RC_SUCCESS)
{
stk3a6x_start_power_rail_timer(this,
sns_convert_ns_to_ticks(STK3A6X_OFF_TO_IDLE_MS * 1000 * 1000),
STK3A6X_POWER_RAIL_PENDING_INIT);
}
}
看下 stk3a6x_register_power_rail
static sns_rc stk3a6x_register_power_rail(sns_sensor *const this)
{
/** OFF state.
* Must be used when there are no active Sensors Instances.
*/
state->common.rail_config.rail_vote = SNS_RAIL_OFF;
if (NULL == state->pwr_rail_service)
{
state->pwr_rail_service =
(sns_pwr_rail_service*)smgr->get_service(smgr, SNS_POWER_RAIL_SERVICE);
state->pwr_rail_service->api->sns_register_power_rails(state->pwr_rail_service,
&state->common.rail_config);
}
if (NULL == state->pwr_rail_service)
{
rv = SNS_RC_FAILED;
}
return rv;
}
rail_config 这些之类的 就是 json 设置的 这些
"num_rail":{ "type": "int", "ver": "0",
"data": " "
},
"rail_on_state":{ "type": "int", "ver": "0",
"data": "2"
},
"vddio_rail":{ "type": "str", "ver": "0",
"data": "/pmic/client/sensor_vddio"
},
ok ,我们看下这个注册函数.有解释的.
大概理解下:
为物理的 sensor 供电的. 一般有一个或者多个. 从这可以看出,这不就是 vdd/vddio 这一类的东西嘛
这些东西应该定义在 non-volatile registry 。 是的,我们设置了 json文件,最后解析在 persist 分区中。最后从 registry 取出我们设置的数据. 当然这个只能初始化一次,上电过程不可能多次上电.
/**
* Register power rails for a physical sensor.
*
* All physical sensors typically have one or more power rails
* that supply power to the sensor hardware. Power rail
* configuration for all sensors shall be defined in the
* non-volatile registry. After the sensor driver fetches rail
* information from the registry, it shall register all rails
* using this API. Rail registration must happen only once for
* any rail.
*
* @param[i] this Power rail service reference.
* @param[i] rail_config Rail config being registered.
*
* @return
* SNS_RC_INVALID_VALUE - input rail config is invalid
* SNS_RC_SUCCESS - rail registration successful
*/
sns_rc (*sns_register_power_rails)(sns_pwr_rail_service* this,
sns_rail_config const* rail_config);
我们大致看下 这个函数的实现
SNS_SECTION(".text.sns") sns_rc sns_register_power_rails(sns_pwr_rail_service *this,
sns_rail_config const* rail_config)
{
SNS_ISLAND_EXIT();
return sns_register_power_rails_internal(this,rail_config);
}
//
static sns_rc __attribute__ ((noinline))
sns_register_power_rails_internal(sns_pwr_rail_service *this,
sns_rail_config const* rail_config)
{
// 获取 锁
sns_osa_lock_acquire(pwr_rail_service.rail_mgr_lock);
else
{
// 有几路 供电.
for(i = 0; i< rail_config->num_of_rails; i++)
{
rc = sns_pwr_rail_init(&rail_config->rails[i]);
// if even a single rail init fails then return immediately.
if(rc != SNS_RC_SUCCESS)
{
break;
}
}
}
// 释放 锁
sns_osa_lock_release(pwr_rail_service.rail_mgr_lock);
return rc;
}
// 假设 只有 vdd 供电,简单点
// 现在 看下 sns_pwr_rail_init
static sns_rc __attribute__ ((noinline))
sns_pwr_rail_init(sns_rail_name const* rail)
{
// 这名字也不是随便取的,可以参照下这个函数
if(!sns_rail_name_is_valid(rail))
{
return SNS_RC_INVALID_VALUE;
}
// Init default state for rail.
pwr_rail_service.rails[pwr_rail_service.num_rails_initialized].state = SNS_RAIL_OFF;
// Copy Rail name.
sns_strlcpy(pwr_rail_service.rails[pwr_rail_service.num_rails_initialized].name.name,
rail->name,
RAIL_NAME_STRING_SIZE_MAX);
// Init client list for rail.
sns_isafe_list_init(&pwr_rail_service.rails[pwr_rail_service.num_rails_initialized].client_item_list);
// Get NPA handle for rail. Not to be done for dummy rail
if((0 != strncmp(DUMMY_SENSOR_VDD, pwr_rail_service.rails[pwr_rail_service.num_rails_initialized].name.name,
sizeof(DUMMY_SENSOR_VDD))) &&
(0 != strncmp(SNS_PWR_RAIL_VDD, pwr_rail_service.rails[pwr_rail_service.num_rails_initialized].name.name,
sizeof(SNS_PWR_RAIL_VDD))))
{
pwr_rail_service.rails[pwr_rail_service.num_rails_initialized].rail_npa_handle =
npa_create_sync_client(pwr_rail_service.rails[pwr_rail_service.num_rails_initialized].name.name,
"Sensors",
NPA_CLIENT_REQUIRED);
if (NULL == pwr_rail_service.rails[pwr_rail_service.num_rails_initialized].rail_npa_handle)
{
SNS_SPRINTF(ERROR, sns_fw_printf, "Could not initialize power rail: %s",
pwr_rail_service.rails[pwr_rail_service.num_rails_initialized].name.name);
}
}
else
{
pwr_rail_service.rails[pwr_rail_service.num_rails_initialized].rail_npa_handle = NULL;
}
// Increment number of initialized rails.
pwr_rail_service.num_rails_initialized++;
return SNS_RC_SUCCESS;
}
下班时间到了,只能到后续有时间在写了…
继续 2023年08月15日10:04:14 更新
/**
- Define a dummy rail for OEMs that use external rails for their sensors.
- Dummy rail config is required so island mode block/unblock logic still
- works for those OEMs.
*/
#define DUMMY_SENSOR_VDD “/pmic/client/dummy_vdd”
#define SNS_PWR_RAIL_VDD “/see/rail/eLDO”
不太清楚这两个有啥区别??
可以使用外部供电. 比如下面这样.
没有使用 dsp 的pmic ,用了AP 那边的 pmic, 在 linux kernel 对这个口进行输出高电平,这个 sensor 就能进行供电了。
OK ,注册完成。接下来应该就是上电。
继续回到 xxx_start_hw_detect_sequence
/**---------------------Turn Power Rails ON----------------------------*/
// json 中设置 的 rail_on_state 。 就是启动转态 LPM/NPM 这种
state->common.rail_config.rail_vote = state->common.registry_rail_on_state;
//
if (rv == SNS_RC_SUCCESS)
{
rv = state->pwr_rail_service->api->sns_vote_power_rail_update(state->pwr_rail_service,
this,
&state->common.rail_config,
NULL);
}
看下是 怎么 power on 的
重点是这个函数 sns_vote_power_rail_update
sns_pwr_rail_service.c
/**
* Vote for a power rail status change.
*
* Each physical sensor driver uses this API to turn it's
* sensors power rails ON when there is an active client
* request. It is also the driver's responsibility to vote for
* power rails OFF when all clients requests are disabled (i.e.
* there are no Sensors Instances present)
*/
/*
看注释的话:
1: 客户端上电请求
2: 下电请求,会有多个下电请求,用 投票方法决定哪个下电。 不知道上电需不需要?? 没太看懂
3: sensor instance 不会有这个动作发生。
*/
// 实际实现在这里.
static sns_rc __attribute__ ((noinline))
sns_vote_power_rail_update_internal(sns_pwr_rail_service *this,
struct sns_sensor const* sensor,
sns_rail_config const* rails_config,
sns_time* rail_on_timestamp)
{
for(i = 0; i < rails_config->num_of_rails; i++)
{
// 判断是否注册了。
rail_is_registered = sns_rail_is_registered(&rails_config->rails[i], &rail_index);
// 我们设置的状态是 SNS_RAIL_OFF . 这个是移除 pwr_rail_client
if(rails_config->rail_vote == SNS_RAIL_OFF)
{
sns_remove_pwr_rail_client(sensor, rail_index);
}
else
{
sns_add_pwr_rail_client(sensor, rails_config->rail_vote, rail_index);
}
// Update the power rail state. Not required for dummy rail
if(0 != strncmp(DUMMY_SENSOR_VDD, pwr_rail_service.rails[rail_index].name.name, sizeof(DUMMY_SENSOR_VDD)))
{
sns_update_power_rail_state(rail_index);
}
// 主要是为了获取硬件初始化的多长时间.
/** There can be more than one rail that a client wants to
* turn ON. Using max operation to get timestamp of rail that
* was turned ON most recently so that the client can know
* exactly how long it needs until HW is available. */
on_timestamp = SNS_MAX(on_timestamp, sns_get_rail_on_timestamp(rail_index));
}
return rc;
}
接下来最重要的就是: sns_update_power_rail_state
Parses client info for the rail and chooses best state.
static void __attribute__ ((noinline))
sns_update_power_rail_state(uint8_t rail_index)
{
for(;
NULL != sns_isafe_list_iter_curr(&iter);
sns_isafe_list_iter_advance(&iter))
{
item = (sns_client_item*)sns_isafe_list_iter_get_curr_data(&iter);
// Search for the highest vote in rail's client list.
new_state = SNS_MAX(new_state, item->vote);
if (SNS_RAIL_ON_LPM == item->vote)
{
lpm_client_count++;
}
}
// LPM > 1. 新的状态进行赋值 SNS_RAIL_ON_NPM .
if (MAX_LPM_CLIENTS_PER_RAIL < lpm_client_count)
{
new_state = SNS_RAIL_ON_NPM;
}
// 进去
if(new_state != pwr_rail_service.rails[rail_index].state)
{
/* state new_state action
* ----------------------------------------------------------------------
* OFF LPM/NPM change right away. Update on_timestamp.
* LPM NPM change right away. Update on_timestamp.
* NPM/LPM OFF change right away. Clear on_timestamp.
* NPM LPM change right away. No change to on_timestamp.
*/
// 没有跑进去,不管
if (SNS_VDDIO_PWR_RAIL_ALWAYS_ON == 0x1)
{
if ((new_state == SNS_RAIL_OFF)
&& (0 == strncmp(PMIC_NPA_GROUP_ID_SENSOR_VDDIO, pwr_rail_service.rails[rail_index].name.name, sizeof(PMIC_NPA_GROUP_ID_SENSOR_VDDIO))))
{
if (0== sns_isafe_list_iter_len(&iter))
{
new_state = SNS_RAIL_ON_LPM;
}
else
return;
}
}
if(0 == strncmp(SNS_PWR_RAIL_VDD, pwr_rail_service.rails[rail_index].name.name, sizeof(SNS_PWR_RAIL_VDD)))
{
#ifdef SNS_GPIO_FOR_EXTERNAL_LDO
sns_write_gpio(SNS_GPIO_FOR_EXTERNAL_LDO, 1, SNS_GPIO_DRIVE_STRENGTH_2_MILLI_AMP,
SNS_GPIO_PULL_TYPE_PULL_UP,(SNS_RAIL_OFF != new_state)?SNS_GPIO_STATE_HIGH:SNS_GPIO_STATE_LOW);
#endif
}
else
{
// 向 NPA 发送 power_on 请求.
pmic_rail_state = (new_state == SNS_RAIL_OFF) ?
PMIC_NPA_MODE_ID_SENSOR_POWER_OFF :
((new_state == SNS_RAIL_ON_LPM) ?
PMIC_NPA_MODE_ID_SENSOR_LPM :
PMIC_NPA_MODE_ID_SENSOR_POWER_ON);
if (NULL != pwr_rail_service.rails[rail_index].rail_npa_handle)
{
npa_issue_required_request(pwr_rail_service.rails[rail_index].rail_npa_handle,
pmic_rail_state);
SNS_SPRINTF(HIGH, sns_fw_printf, "sensor power rail: %s, state: %d",
(char*)pwr_rail_service.rails[rail_index].name.name,
pmic_rail_state);
}
}
pwr_rail_service.rails[rail_index].state = new_state; // 更新状态
}
}
new_state:是我们sensor 那边 传进去的状态
pwr_rail_service.rails[rail_index].state : 这个初始值 不太确定是多少,从哪里传过来的. 后面在去看下
这个不是很确定
转态发送了改变, 才会进行相应的动作.
从 log 中可以看到打印:
sensor power rail: /pmic/client/sensor_vdd, state: 2
sensor power rail: /pmic/client/sensor_vddio, state: 2
sensor power rail: /pmic/client/sensor_vdd_2, state: 2
sensor power rail: /pmic/client/sensor_vddio_2, state: 2
我们设置的 rail_on_state 是2, 没毛病。 这样就 power on 了.
这个是等待的时间。
个人认为是 等待 dsp 那边稳定后,再来读取 sensor id 。
/**-------------Create a Timer stream for Power Rail ON timeout.---------*/
if (rv == SNS_RC_SUCCESS)
{
stk3a6x_start_power_rail_timer(this,
sns_convert_ns_to_ticks(STK3A6X_OFF_TO_IDLE_MS * 1000 * 1000),
STK3A6X_POWER_RAIL_PENDING_INIT);
}
我们看下这个写法:
void stk3a6x_start_power_rail_timer(sns_sensor *const this,
sns_time timeout_ticks,
stk3a6x_power_rail_pending_state pwr_rail_pend_state)
{
req_payload.timeout_period = timeout_ticks;
if (NULL == state->timer_stream)
{
sns_service_manager *smgr = this->cb->get_service_manager(this);
sns_stream_service *stream_svc = (sns_stream_service*)smgr->get_service(smgr, SNS_STREAM_SERVICE);
sns_sensor_uid suid;
sns_suid_lookup_get(&state->common.suid_lookup_data, "timer", &suid);
stream_svc->api->create_sensor_stream(stream_svc, this, suid,
&state->timer_stream);
}
req_len = pb_encode_request(buffer, sizeof(buffer), &req_payload,
sns_timer_sensor_config_fields, NULL);
if (req_len > 0 && NULL != state->timer_stream)
{
sns_request timer_req =
{
.message_id = SNS_TIMER_MSGID_SNS_TIMER_SENSOR_CONFIG,
.request = buffer, .request_len = req_len
};
state->timer_stream->api->send_request(state->timer_stream, &timer_req);
state->power_rail_pend_state = pwr_rail_pend_state;
}
}
看到只是发了个 消息: SNS_TIMER_MSGID_SNS_TIMER_SENSOR_CONFIG
state->power_rail_pend_state = pwr_rail_pend_state; 这句是在发送之后进行赋值的,并没有发送出去.
进入 sns_timer_sensor.c
SNS_SECTION(".text.sns")
static sns_sensor_instance*
sns_timer_set_client_request(sns_sensor *const this,
sns_request const *curr_req,
sns_request const *new_req,
bool remove) {
else if( SNS_TIMER_MSGID_SNS_TIMER_SENSOR_CONFIG == new_req->message_id &&
sns_timer_get_decoded_req(new_req, &decoded_request, &decoded_payload) )
{
// 加入到 timer 链表当中去.
this->instance_api->set_client_config(timer_inst, &inst_req);
sns_isafe_list_item_init(&new_inst_state->periodic_entry, timer_inst);
rc = sns_timer_sensor_record_entry(state, timer_inst, true);
// Generate timer registration event
if(!pb_send_event(timer_inst, sns_timer_sensor_reg_event_fields,
&(new_inst_state->client_config), sns_get_system_time(),
SNS_TIMER_MSGID_SNS_TIMER_SENSOR_REG_EVENT, NULL))
{
SNS_PRINTF(ERROR, sns_fw_printf, "Timer registration event failure");
}
}
}
可以看到 最后发送 SNS_TIMER_MSGID_SNS_TIMER_SENSOR_REG_EVENT
这个可以看到, 没有什么用. sensor 当中没有对这个做处理
我们看下 timer 时间到了 怎么处理的
SNS_SECTION(".text.sns")
static sns_rc
sns_timer_inst_generate_event(sns_sensor_instance *const timer_inst,
sns_sensor *const timer_sensor,
sns_time system_time)
{
timer_event.timeout_time = sensor_state->ro_buffer.timeout_event.timestamp;
timer_event.requested_timeout_time = state->trigger_time;
// 发送 SNS_TIMER_MSGID_SNS_TIMER_SENSOR_EVENT message 的消息
if(!pb_send_event(timer_inst, sns_timer_sensor_event_fields, &timer_event,
system_time, SNS_TIMER_MSGID_SNS_TIMER_SENSOR_EVENT,
NULL))
{
}
#ifdef SNS_TIMER_ENABLE_DEBUG
SNS_PRINTF(LOW, sns_fw_printf, "Timer sent event for %x, tout %x, now %x",
(uint32_t)timer_inst, (uint32_t)state->trigger_time,
(uint32_t)system_time );
#endif
return SNS_RC_SUCCESS;
}
可以看到,时间到了,会发送 SNS_TIMER_MSGID_SNS_TIMER_SENSOR_EVENT 的消息。
接下来,我们在回到 sensor 的驱动中
sns_stk3a6x_sensor_island.c
sns_rc stk3a6x_sensor_notify_event(sns_sensor *const this)
{
// 处理 timer event
/**----------------------Handle a Timer Sensor event.-------------------*/
if (NULL != state->timer_stream)
{
event = state->timer_stream->api->peek_input(state->timer_stream);
while (NULL != event)
{
pb_istream_t stream = pb_istream_from_buffer((pb_byte_t*)event->event,event->event_len);
// timer 定时器,时间到了,发来的消息 SNS_TIMER_MSGID_SNS_TIMER_SENSOR_EVENT
if (SNS_TIMER_MSGID_SNS_TIMER_SENSOR_EVENT == event->message_id)
{
if (pb_decode(&stream, sns_timer_sensor_event_fields, &timer_event))
{
// 注册的时候设置的 STK3A6X_POWER_RAIL_PENDING_INIT
if (state->power_rail_pend_state == STK3A6X_POWER_RAIL_PENDING_INIT)
{
/**-------------------Read and Confirm WHO-AM-I------------------------*/
state->island_service->api->sensor_island_exit(state->island_service, this);
state->common.hw_is_present = stk3a6x_discover_hw(this);
if (state->common.hw_is_present)
{
stk3a6x_publish_available(this);
stk3a6x_update_sibling_sensors(this);
}
state->power_rail_pend_state = STK3A6X_POWER_RAIL_PENDING_NONE;
}
}
event = state->timer_stream->api->get_next_input(state->timer_stream);
}
/** Free up timer stream if not needed anymore */
if (state->power_rail_pend_state == STK3A6X_POWER_RAIL_PENDING_NONE)
{
sns_sensor_util_remove_sensor_stream(this, &state->timer_stream);
}
}
}
总结下这个函数:
stk3a6x_start_power_rail_timer(this,
sns_convert_ns_to_ticks(STK3A6X_OFF_TO_IDLE_MS * 1000 * 1000),
STK3A6X_POWER_RAIL_PENDING_INIT);
power rail 等 STK3A6X_OFF_TO_IDLE_MS 的时间 ,在来继续处理
init 完成后,接下来就是读取 id
bool stk3a6x_discover_hw(sns_sensor *const this)
{
/**-------------------Read and Confirm WHO-AM-I------------------------*/
rv = stk3a6x_get_who_am_i(state->scp_service, state->common.com_port_info.port_handle,
&buffer[0]);
STK3A6X_PRINTF(ERROR, this, "STK3A6X rv:%d,buffer[0]:0x%X",rv, buffer[0]);
if ((rv == SNS_RC_SUCCESS) && (stk3a6x_check_pid(buffer[0]) == true))
{
// Reset Sensor only if an inatance is not alreadly running
// 像是有什么故障,所以要 reset sensor
if (NULL == sns_sensor_util_get_shared_instance(this))
{
rv = stk3a6x_reset_device(state->scp_service, state->common.com_port_info.port_handle,
(STK3A6X_ALS_OC | STK3A6X_ALS_STRM | STK3A6X_PS_OC | STK3A6X_PS_STRM));
}
if (rv == SNS_RC_SUCCESS)
{
hw_is_present = true;
}
}
state->common.who_am_i = buffer[0];
/**------------------Power Down and Close COM Port--------------------*/
state->scp_service->api->sns_scp_update_bus_power(
state->common.com_port_info.port_handle,
false);
state->scp_service->api->sns_scp_close(state->common.com_port_info.port_handle);
state->scp_service->api->sns_scp_deregister_com_port(&state->common.com_port_info.port_handle);
/**----------------------Turn Power Rail OFF--------------------------*/
state->common.rail_config.rail_vote = SNS_RAIL_OFF;
state->pwr_rail_service->api->sns_vote_power_rail_update(state->pwr_rail_service,
this,
&state->common.rail_config,
NULL);
return hw_is_present;
}
关闭了 com port / power done . 不知道 等传输数据的时候,还要打开这些吗??
读取到了id ,找到了硬件,publish 属性上去…
if (state->common.hw_is_present)
{
stk3a6x_publish_available(this);
stk3a6x_update_sibling_sensors(this);
}
现在 有个 sensor vdd 上电时序有要求,改哪里呢?
蓝色是 vdd , 如果要增加蓝色 vdd 的低电平的时间,要怎么改??