mt2503 如何读取external ADC value?
时间:10-02
整理:3721RD
点击:
[DESCRIPTION]
如何读取external ADC value?
[SOLUTION]
1. ADC工作原理介绍
(1) AUX task或者自定义task给BMT task发送读取channel request MSG_ID_BMT_ADC_ADD_ITEM_REQ
(2) BMT task收到此消息,add item:adc_sche_add_item;
(3) 系统进行对应channel ADC数据的读取;
(4) Read complete, BMT发送msg MSG_ID_BMT_ADC_MEASURE_DONE_CONF给aux task或自定义task;
(5) Aux task或者自定义task收到此消息,从aux_read_result获取读取的ADC值。
2. 添加步骤
(1) drv tool ADC Setting:
注:external ADC,请在adc.cmp中自定义名称
(2) Get ADC channel you want to read,Create object
类似如下:
(3) 添加给aux_task_main发送msg MSG_ID_READ_ALL_CHANNEL_REQ aux_read_all_channel,aux task必须定期收到此msg,否则ADC schedule run不起来。
添加到此,通过aux_read_result就可以读取到external ADC value了。
3. 添加的注意事项
(1) 以上举例,以在aux task添加为前提。
(2) 建议自定义task与bmt task交互,读取adc值。
(3) 若是在aux task里添加,建议用自定义宏隔开,以防破坏原有的流程。
kal_uint8 adc_sche_get_channel(adc_channel_type type)
{
kal_uint8 VBAT, VISENSE, VCHARGER, VBATTEMP;
#if defined(PMIC_FIXED_3_ADC_CH)
VBAT = PMIC_ADC_VBAT_CH_NUM;
VISENSE = PMIC_ADC_VISENSE_CH_NUM;
VCHARGER = PMIC_ADC_VCHARGER_CH_NUM;
#if defined(PMIC_FIXED_4_ADC_CH)
VBATTEMP = PMU_ADC_VBATTEMP_CH_NUM;
#else
VBATTEMP = ADC_VBATTMP;
#endif
#else
VBAT = ADC_VBAT;
VISENSE = ADC_VISENSE;
VCHARGER = ADC_VCHARGER;
VBATTEMP = ADC_VBATTMP;
#endif //#if defined(PMIC_FIXED_3_ADC_CH)
switch(type)
{
case vbat_adc_channel:
return ((kal_uint8)VBAT);
case visense_adc_channel:
return ((kal_uint8)VISENSE);
case vbattmp_adc_channel:
return ((kal_uint8)VBATTEMP);
case aux_adc_channel:
return ((kal_uint8)ADC_ACCESSORYID);
case vcharger_adc_channel:
return ((kal_uint8)VCHARGER);
case PCBtmp_adc_channel:
return ((kal_uint8)ADC_PCBTMP);
case chr_usb_adc_channel:
return ((kal_uint8)ADC_CHR_USB);
case otg_vbus_adc_channel:
return ((kal_uint8)ADC_OTG_VBUS);
case rftmp_adc_channel:
return ((kal_uint8)ADC_RFTMP);
case xp_adc_channel:
return 12;
case yp_adc_channel:
return 13;
case ym_adc_channel:
return 14;
case xm_adc_channel:
return 15;
default:
ASSERT(0);
return 100;
}
}
我这边使用AUXIN4已经读取external ADC成功了。具体实现如下:
ADC工作原理介绍:
在读取ADC 各channel值之前需要向MOD_AUX发送MSG_ID_READ_ALL_ADC_CHANNEL_REQ消息,
我测试时是通过进工模(拨号界面输入*#66*#)实现的,如下:
void l4cuem_get_adc_all_channel_start_req(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
uem_adc_on = 1;
uem_send_msg_to_aux(MSG_ID_READ_ALL_ADC_CHANNEL_REQ);
}
( 1 ) AUX task 或者自定义 task 给 BMT TASK 发送读取 channel
request:MSG_ID_BMT_ADC_ADD_ITEM_REQ
( 2 ) BMT task 收到此消息, add item:bmt_adc_sche_add_item() , 调用
DclSADC_Control(ptr->adc_handle, ADC_CMD_START_MEASURE, NULL)
{
case ADC_CMD_START_MEASURE:
{
DCL_UINT32 sche_id;
sche_id = DclSADC_GetScheId(handle);
if(sche_id == MAX_DCL_ADC_SCHE_ID) //not find correct sche_id //Modem_ONLY
load only allow RFTMP to access
return STATUS_OK;
adc_sche_add_item(sche_id,
dcl_adc_sche_id[sche_id].complete_cb,
dcl_adc_sche_id[sche_id].measure_cb);
return STATUS_OK;
}
...
}
( 3 )系统进行对应 channel ADC 数据的读取
(4)Read complete, 在回调函数 adc_sche_task_complete_callback 中 BMT向前task module发
送消息:
MSG_ID_BMT_ADC_MEASURE_DONE_CONF 给AUX task或自定义task;
( 5 ) AUX task 或者自定义 task 收到此消息,
aux_task_main()
{
case MSG_ID_BMT_ADC_MEASURE_DONE_CONF:
//TODO :从 aux_read_result 获取读取的 ADC 值。
DRV_BuildPrimitive(aux_ilm,
MOD_AUX,
MOD_UEM,
MSG_ID_ADC_ALL_CHANNEL_CONF,
adc_all_channel_result);
}
void uemaux_all_channel_conf_hdlr(local_para_struct *local_para_ptr,
peer_buff_struct *peer_buff_ptr)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
adc_all_channel_struct *ach = (adc_all_channel_struct*) local_para_ptr;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (uem_adc_on == 1)
{
// 获取各 channel ADC 值
l4cuem_get_adc_all_channel_ind(ach->vbat, ach->bat_temp, ach->vaux, ach-
>charge_current, ach->vcharger);
uem_start_timer(ADC_EVENT_TIMER, uem_get_adc_all_channel_timeout_hdlr,
1000); /* 1 Sec */
}
}
添加给 aux task main 发送 msg MSG_ID_READ_ALL_CHANNEL_REQ aux_read_all_channel,
aux task 必须定期收到此 msg ,否则 ADC schedule run 不起来。
我的 code 改动:
( 1 )在 drvtool 中选择 ADC4 的 ADC_var 为 ADC_ACCESSORYID (当然你也可以选择其他,只要
不冲突即可),最终在 code
custom\codegen\BSJ03D_11C_BB\adc_var.c 中生成:
const unsigned char ADC_ACCESSORYID = 4;
( 2 )
void aux_task_main( task_entry_struct * task_entry_ptr )
{
kal_int32 vauxin4_value=0;
DCL_HANDLE adc_handle_vauxin4;
adc_handle_vauxin4 = aux_open_and_create(DCL_AUX_ADC_CHANNEL);
...
case MSG_ID_READ_ALL_ADC_CHANNEL_REQ:
vauxin4_value = 0;
aux_read_adc_channel(adc_handle_vauxin4);
break;
case MSG_ID_BMT_ADC_MEASURE_DONE_CONF:
else if (mea_done_ptr->adc_handle == adc_handle_vauxin4) //lxg added
{
adc_measure_count++;
vauxin4_value = (kal_int32)mea_done_ptr->volt;
//aux_remove_adc_channel(vbattemp_adc_logic_id);
aux_remove_adc_channel(adc_handle_vauxin4);
}
...
if(adc_measure_count==6) //5 改为 6
#else
if(adc_measure_count==5) //4 改为 5
#endif
{
adc_measure_count=0;
adc_all_channel_result =
(adc_all_channel_struct*)construct_local_para(sizeof(adc_all_channel_struct),
TD_CTRL);
adc_all_channel_result->vbat = vbat_value;
adc_all_channel_result->vcharger = vcharger_value;
adc_all_channel_result->vaux = vaux_value;
adc_all_channel_result->vauxin4 = vauxin4_value;//lxg added
...
// 添加 log 打印
kal_pROMpt_trace(MOD_AUX,"[LXG] aux_task_main() \
vbat=%d,charge_current=%d,vcharger=%d,vbattemp=%d,vauxin4=%d", \
adc_all_channel_result->vbat,adc_all_channel_result-
>charge_current,adc_all_channel_result->vcharger, \
adc_all_channel_result->bat_temp,adc_all_channel_result->vauxin4);
DRV_BuildPrimitive(aux_ilm,
MOD_AUX,
MOD_UEM,
MSG_ID_ADC_ALL_CHANNEL_CONF,
adc_all_channel_result);
}
}
( 3 )在 auxmain.c 文件的 aux_open_and_create() 函数中将 u1EvaluateCount 改为 10
,即读取 10 次值取平均然后回调 adc_sche_task_complete_callback 。
adc_create_object.u1EvaluateCount = 10;
( 4 ) hal\peripheral\src\adcsche.c
kal_uint8 adc_sche_get_channel(adc_channel_type type)
{
case aux_adc_channel:
return ((kal_uint8)ADC_ACCESSORYID);
}
typedef enum {
vbat_adc_channel=0,
visense_adc_channel,
vbattmp_adc_channel,
battype_adc_channel,
vcharger_adc_channel,
pcbtmp_adc_channel,
aux_adc_channel, //6
chr_usb_adc_channel,
otg_vbus_adc_channel,
rftmp_adc_channel
} adc_channel_type;
( 5 )注意: AUXIN4 这个通道 Input range [V] : 0 ~ AV DD28
我从 log 中打印出的 :
[LXG] aux_task_main() vbat=3769360,charge_current=-
12076,vcharger=196938,vbattemp=25098,vauxin4=2786724
最大值是 2786724 ,误差在 +/- 50mV 以内,所以是正常的。
之所以之前读不到 AUXIN4 的值是因为在读取 ADC 各 channel 值之前没有向 MOD_AUX 发送
MSG_ID_READ_ALL_ADC_CHANNEL_REQ 消息。
要有触发机制,才会去测量的,谢谢!
如何读取external ADC value?
[SOLUTION]
1. ADC工作原理介绍
(1) AUX task或者自定义task给BMT task发送读取channel request MSG_ID_BMT_ADC_ADD_ITEM_REQ
(2) BMT task收到此消息,add item:adc_sche_add_item;
(3) 系统进行对应channel ADC数据的读取;
(4) Read complete, BMT发送msg MSG_ID_BMT_ADC_MEASURE_DONE_CONF给aux task或自定义task;
(5) Aux task或者自定义task收到此消息,从aux_read_result获取读取的ADC值。
2. 添加步骤
(1) drv tool ADC Setting:
注:external ADC,请在adc.cmp中自定义名称
(2) Get ADC channel you want to read,Create object
类似如下:
(3) 添加给aux_task_main发送msg MSG_ID_READ_ALL_CHANNEL_REQ aux_read_all_channel,aux task必须定期收到此msg,否则ADC schedule run不起来。
添加到此,通过aux_read_result就可以读取到external ADC value了。
3. 添加的注意事项
(1) 以上举例,以在aux task添加为前提。
(2) 建议自定义task与bmt task交互,读取adc值。
(3) 若是在aux task里添加,建议用自定义宏隔开,以防破坏原有的流程。
kal_uint8 adc_sche_get_channel(adc_channel_type type)
{
kal_uint8 VBAT, VISENSE, VCHARGER, VBATTEMP;
#if defined(PMIC_FIXED_3_ADC_CH)
VBAT = PMIC_ADC_VBAT_CH_NUM;
VISENSE = PMIC_ADC_VISENSE_CH_NUM;
VCHARGER = PMIC_ADC_VCHARGER_CH_NUM;
#if defined(PMIC_FIXED_4_ADC_CH)
VBATTEMP = PMU_ADC_VBATTEMP_CH_NUM;
#else
VBATTEMP = ADC_VBATTMP;
#endif
#else
VBAT = ADC_VBAT;
VISENSE = ADC_VISENSE;
VCHARGER = ADC_VCHARGER;
VBATTEMP = ADC_VBATTMP;
#endif //#if defined(PMIC_FIXED_3_ADC_CH)
switch(type)
{
case vbat_adc_channel:
return ((kal_uint8)VBAT);
case visense_adc_channel:
return ((kal_uint8)VISENSE);
case vbattmp_adc_channel:
return ((kal_uint8)VBATTEMP);
case aux_adc_channel:
return ((kal_uint8)ADC_ACCESSORYID);
case vcharger_adc_channel:
return ((kal_uint8)VCHARGER);
case PCBtmp_adc_channel:
return ((kal_uint8)ADC_PCBTMP);
case chr_usb_adc_channel:
return ((kal_uint8)ADC_CHR_USB);
case otg_vbus_adc_channel:
return ((kal_uint8)ADC_OTG_VBUS);
case rftmp_adc_channel:
return ((kal_uint8)ADC_RFTMP);
case xp_adc_channel:
return 12;
case yp_adc_channel:
return 13;
case ym_adc_channel:
return 14;
case xm_adc_channel:
return 15;
default:
ASSERT(0);
return 100;
}
}
我这边使用AUXIN4已经读取external ADC成功了。具体实现如下:
ADC工作原理介绍:
在读取ADC 各channel值之前需要向MOD_AUX发送MSG_ID_READ_ALL_ADC_CHANNEL_REQ消息,
我测试时是通过进工模(拨号界面输入*#66*#)实现的,如下:
void l4cuem_get_adc_all_channel_start_req(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
uem_adc_on = 1;
uem_send_msg_to_aux(MSG_ID_READ_ALL_ADC_CHANNEL_REQ);
}
( 1 ) AUX task 或者自定义 task 给 BMT TASK 发送读取 channel
request:MSG_ID_BMT_ADC_ADD_ITEM_REQ
( 2 ) BMT task 收到此消息, add item:bmt_adc_sche_add_item() , 调用
DclSADC_Control(ptr->adc_handle, ADC_CMD_START_MEASURE, NULL)
{
case ADC_CMD_START_MEASURE:
{
DCL_UINT32 sche_id;
sche_id = DclSADC_GetScheId(handle);
if(sche_id == MAX_DCL_ADC_SCHE_ID) //not find correct sche_id //Modem_ONLY
load only allow RFTMP to access
return STATUS_OK;
adc_sche_add_item(sche_id,
dcl_adc_sche_id[sche_id].complete_cb,
dcl_adc_sche_id[sche_id].measure_cb);
return STATUS_OK;
}
...
}
( 3 )系统进行对应 channel ADC 数据的读取
(4)Read complete, 在回调函数 adc_sche_task_complete_callback 中 BMT向前task module发
送消息:
MSG_ID_BMT_ADC_MEASURE_DONE_CONF 给AUX task或自定义task;
( 5 ) AUX task 或者自定义 task 收到此消息,
aux_task_main()
{
case MSG_ID_BMT_ADC_MEASURE_DONE_CONF:
//TODO :从 aux_read_result 获取读取的 ADC 值。
DRV_BuildPrimitive(aux_ilm,
MOD_AUX,
MOD_UEM,
MSG_ID_ADC_ALL_CHANNEL_CONF,
adc_all_channel_result);
}
void uemaux_all_channel_conf_hdlr(local_para_struct *local_para_ptr,
peer_buff_struct *peer_buff_ptr)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
adc_all_channel_struct *ach = (adc_all_channel_struct*) local_para_ptr;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (uem_adc_on == 1)
{
// 获取各 channel ADC 值
l4cuem_get_adc_all_channel_ind(ach->vbat, ach->bat_temp, ach->vaux, ach-
>charge_current, ach->vcharger);
uem_start_timer(ADC_EVENT_TIMER, uem_get_adc_all_channel_timeout_hdlr,
1000); /* 1 Sec */
}
}
添加给 aux task main 发送 msg MSG_ID_READ_ALL_CHANNEL_REQ aux_read_all_channel,
aux task 必须定期收到此 msg ,否则 ADC schedule run 不起来。
我的 code 改动:
( 1 )在 drvtool 中选择 ADC4 的 ADC_var 为 ADC_ACCESSORYID (当然你也可以选择其他,只要
不冲突即可),最终在 code
custom\codegen\BSJ03D_11C_BB\adc_var.c 中生成:
const unsigned char ADC_ACCESSORYID = 4;
( 2 )
void aux_task_main( task_entry_struct * task_entry_ptr )
{
kal_int32 vauxin4_value=0;
DCL_HANDLE adc_handle_vauxin4;
adc_handle_vauxin4 = aux_open_and_create(DCL_AUX_ADC_CHANNEL);
...
case MSG_ID_READ_ALL_ADC_CHANNEL_REQ:
vauxin4_value = 0;
aux_read_adc_channel(adc_handle_vauxin4);
break;
case MSG_ID_BMT_ADC_MEASURE_DONE_CONF:
else if (mea_done_ptr->adc_handle == adc_handle_vauxin4) //lxg added
{
adc_measure_count++;
vauxin4_value = (kal_int32)mea_done_ptr->volt;
//aux_remove_adc_channel(vbattemp_adc_logic_id);
aux_remove_adc_channel(adc_handle_vauxin4);
}
...
if(adc_measure_count==6) //5 改为 6
#else
if(adc_measure_count==5) //4 改为 5
#endif
{
adc_measure_count=0;
adc_all_channel_result =
(adc_all_channel_struct*)construct_local_para(sizeof(adc_all_channel_struct),
TD_CTRL);
adc_all_channel_result->vbat = vbat_value;
adc_all_channel_result->vcharger = vcharger_value;
adc_all_channel_result->vaux = vaux_value;
adc_all_channel_result->vauxin4 = vauxin4_value;//lxg added
...
// 添加 log 打印
kal_pROMpt_trace(MOD_AUX,"[LXG] aux_task_main() \
vbat=%d,charge_current=%d,vcharger=%d,vbattemp=%d,vauxin4=%d", \
adc_all_channel_result->vbat,adc_all_channel_result-
>charge_current,adc_all_channel_result->vcharger, \
adc_all_channel_result->bat_temp,adc_all_channel_result->vauxin4);
DRV_BuildPrimitive(aux_ilm,
MOD_AUX,
MOD_UEM,
MSG_ID_ADC_ALL_CHANNEL_CONF,
adc_all_channel_result);
}
}
( 3 )在 auxmain.c 文件的 aux_open_and_create() 函数中将 u1EvaluateCount 改为 10
,即读取 10 次值取平均然后回调 adc_sche_task_complete_callback 。
adc_create_object.u1EvaluateCount = 10;
( 4 ) hal\peripheral\src\adcsche.c
kal_uint8 adc_sche_get_channel(adc_channel_type type)
{
case aux_adc_channel:
return ((kal_uint8)ADC_ACCESSORYID);
}
typedef enum {
vbat_adc_channel=0,
visense_adc_channel,
vbattmp_adc_channel,
battype_adc_channel,
vcharger_adc_channel,
pcbtmp_adc_channel,
aux_adc_channel, //6
chr_usb_adc_channel,
otg_vbus_adc_channel,
rftmp_adc_channel
} adc_channel_type;
( 5 )注意: AUXIN4 这个通道 Input range [V] : 0 ~ AV DD28
我从 log 中打印出的 :
[LXG] aux_task_main() vbat=3769360,charge_current=-
12076,vcharger=196938,vbattemp=25098,vauxin4=2786724
最大值是 2786724 ,误差在 +/- 50mV 以内,所以是正常的。
之所以之前读不到 AUXIN4 的值是因为在读取 ADC 各 channel 值之前没有向 MOD_AUX 发送
MSG_ID_READ_ALL_ADC_CHANNEL_REQ 消息。
要有触发机制,才会去测量的,谢谢!
最新需要用到这个,谢谢!