951&961软件问题整理
951&961软件问题整理
TOC \o "1-1" \h \u HYPERLINK \l "_Toc75541659" 1. 各功能评估(以ac95n_ac96n-release_V1.0.3和TWS AC961 Wireless Charger V2.2) 20200910 xin PAGEREF _Toc75541659 \h 2
HYPERLINK \l "_Toc75541660" 2. 芯片资源评估 xin_20200815 PAGEREF _Toc75541660 \h 2
HYPERLINK \l "_Toc75541661" 3. 案子需求评估 xin_20200815 PAGEREF _Toc75541661 \h 3
HYPERLINK \l "_Toc75541662" 4. 芯片选型 xin_20200815 PAGEREF _Toc75541662 \h 3
HYPERLINK \l "_Toc75541663" 5. 软件开发平台 xin_20200815 PAGEREF _Toc75541663 \h 3
HYPERLINK \l "_Toc75541664" 6. 软件开发方式 xin_20200815 PAGEREF _Toc75541664 \h 4
HYPERLINK \l "_Toc75541665" 7. PCB设计 xin_20200815 PAGEREF _Toc75541665 \h 5
HYPERLINK \l "_Toc75541666" 8. 烧录配置 xin_20200817 PAGEREF _Toc75541666 \h 5
HYPERLINK \l "_Toc75541667" 9. 推灯方式 xin_20200817 PAGEREF _Toc75541667 \h 6
HYPERLINK \l "_Toc75541668" 10. 波特率及时钟设置 xin_20200817 PAGEREF _Toc75541668 \h 7
HYPERLINK \l "_Toc75541669" 11. 定时计数周期 xin_20200817 PAGEREF _Toc75541669 \h 7
HYPERLINK \l "_Toc75541670" 12. AC961外挂无线充注意事项 20200910 xin PAGEREF _Toc75541670 \h 8
HYPERLINK \l "_Toc75541671" 13. AC951部分功能说明和注意事项 20210625 FSW PAGEREF _Toc75541671 \h 9
- 各功能评估(以ac95n_ac96n-release_V1.0.3和TWS AC961 Wireless Charger V2.2) 20200910 xin
- 霍尔(必须要带霍尔开关)
默认SDK以霍尔来控制961的唤醒跟睡眠
暂不支持不带霍尔的案子,需要改动的功能(支持耳机提起开机、自动激活充电、维持充电脚输出电压而导致的功耗问题等),待完善 - 灯效(呼吸灯、跑马灯、控制间隔时间跟次数等功能)
只要芯片资源够,灯效都能加,951和带内置无线充的961,凡是要改灯效,要外挂握手芯片,软件去掉握手功能,才有空间加灯效 - 数码管(暂不支持)
需要去掉充电功能,外挂充电IC,原理图需要大改,961只能做纯粹检测跟显示功能而已 - NTC
新版原理图已添加,代码需要打补丁,对于内置握手内置无线充的工程,是不够放ntc的补丁的,需要去掉内置握手功能 - DUT
可以单独做一个程序用于产线测试用,进DUT模式,实际出货的机子,肯定没空间加DUT功能的
- 芯片资源评估 xin_20200815 AC951和AC961的资源奇缺,ROM只有3K,RAM只有128B(注意是字节)

以工程f96_ppm_wpr.cbp举例:(不带串口加密通信的)
公版不开打印,编译后ROM剩余空间38B,每个指令占用2B,只够写19个指令,随便写个函数都不够


对于其他工程也是这种情况,ROM的资源几乎是没剩多少
RAM资源留给应用开发的,只能定义一个u8的变量,没有多余的了
3. 案子需求评估 xin_20200815 充电仓3大功能,Lightning 握手,无线充,串口通信,最多只能3选其2
*如果选了2大功能,那UI的功能,基本没有空间修改,否则要删掉公版的流程,自己写一套(只能汇编写,随便写个灯的流程,熟练的话,至少一周时间,很有可能是盲调,没法看打印的哦)。
*如果要修改UI,要修改led和key的话,建议只选1个功能,即只有串口通信,那握手和无线充就只能外挂芯片。
- 至于外挂之后的整体成本,自行评估
芯片选型 xin_20200815 需要内置握手,优先选961,对于951的Lightning 握手兼容性差,无法处理(有些充电器会无法激活充电)
需要内置无线充,只能选961。
对于type-C接口,只需要串口通信,951和961都可
不带串口通信,951和961都可软件开发平台 xin_20200815 需要安装2个软件,请自行网上下载


- 软件开发方式 xin_20200815 只能汇编开发方式,没有汇编基础的,请自行学习
参考AC951_AC961_指令集介绍.pdf,阅读指令集功能,才能看懂SDK的代码流程
ROM空闲的情况下,可以打开打印。
仅限于一个字符的打印,是无法打印字符串的
SDK可以打印变量的值,一般情况下是无法打开的,绝对爆空间,得先去掉一些功能
只能看这种打印,对代码的流程的
PCB设计 xin_20200815 请严格按照公版原理图的IO定义进行设计,没有多余的代码空间去写映射的!!!!
一定要优先考虑,把rom节省下来,留做UI的修改。切记切记!!烧录配置 xin_20200817 AC951 、AC961是OTP芯片,只能烧录一次,代码空间很紧张,百分百没有重烧的机会
烧录前请再三确认

- 推灯方式 xin_20200817 SDK默认是全占空比的推灯方式,亮度靠外围电阻调节,共阴极接法
PWM占空比修改: duty的占空比是反向设置,0xFF对应灭,0x00对应全亮
极性修改:
灯的亮灭周期控制:3个灯是独立控制的,之间没有互闪、同时亮灭的效果
红灯默认是慢闪,每个灯的闪烁频率可创建宏,独立控制,但是没法动态修改,因为宏是固定的
想动态修改,除非ram够,可将宏改成变量定义,默认SDK是没有ram了
波特率及时钟设置 xin_20200817 芯片是省晶振方式,烧录器会校准芯片的时钟源,其他的时钟都是依赖烧录器的校准值去算的。
开发板的芯片,如若打印乱码等,请用烧录器烧录之后再使用
打印串口波特率默认115200,是固定的,没有修改的地方定时计数周期 xin_20200817 SDK为了避免有乘除的操作,没法做整数倍的计数周期,都是2的倍数计数周期
如:100ms -> 128ms; 300ms -> 256ms; 500ms -> 512ms
关盖无充电,定时关机时间修改
240 * 512 == 122880 == 120s 约为2分钟,由于代码计数周期不是整数倍,加上执行效率较慢,会导致几分钟的计时,通常会出现几s的误差的。很难避免的
- AC961外挂无线充注意事项 20200910 xinAC961配合无线充使用时不能使用开关充电(单独外挂无线充芯片也不行),
如果在“f96_ppm_enc.cbp”的工程上使用了外挂无线充芯片,那么必须将工程替换为线性充电!修改方法是:关闭工程配置中开关充电的宏,PMU库替换为线性充电的库使用!

- AC951部分功能说明和注意事项 20210625 FSW
(1) 代码启动流程:_start->_startup->main
(2) IO口(以p06为例):
#define p0_dir 0x92 //IO方向
#define p0_out 0x93 //IO电平
#define p0_pu 0x94 //IO上拉
#define p0_pd 0x95 //IO下拉
#define p0_hd 0x96 //IO强驱
#define p0_die 0x97 //IO数字或模拟
#define p0_in 0x98 //IO输入电平检测
[p0_dir].6 = 0 //p06配置为输出
[p0_dir].6 = 1 //p06配置为输入
[p0_out].6 = 0 //p06配置为输出低
[p0_out].6 = 1 //p06配置为输出高
[p0_pu].6 = 0 //p06配置为上拉关闭
[p0_pu].6 = 1 //p06配置为上拉打开
[p0_pd].6 = 0 //p06配置为下拉关闭
[p0_pd].6 = 1 //p06配置为下拉打开
[p0_hd].6 = 0 //p06配置为强驱关闭
[p0_hd].6 = 1 //p06配置为强驱打开
[p0_die].6 = 0 //p06配置为模拟
[p0_die].6 = 1 //p06配置为数字
[p0_in].6 == 0 //判断p06输入电平是否为低
[p0_in].6 == 1 //判断p06输入电平是否为高
(3) ad检测:
adc_read_phy(ch,ana_ch)
ch:根据实际IO选择对应的AD通道,ADC_CH_ANA表示要测量内部电源
#define ADC_CH_P01 0
#define ADC_CH_P03 1
#define ADC_CH_P05 2
#define ADC_CH_P06 3
#define ADC_CH_P13 4
#define ADC_CH_P14 5
#define ADC_CH_P15 6
#define ADC_CH_ANA 7
ana_ch:普通IO的AD通道直接填写0,测量内部电源通道根据要测量的电源选择,例如测量电池电压(Vbat脚)选择ANA_VBAT
#define ANA_VBG 0
#define ANA_VCC 1
#define ANA_VEB 2
#define ANA_Vsense_OUT1 3
#define ANA_Vsense_OUT0 4
#define ANA_LINE_PROGI 5
#define ANA_BUCK_PROGI 6
#define ANA_VBAT 7
采集到的结果为左对齐的0~1023,存放在TR0(H)和TR1(L)中
(4) PWM输出:(PWM输出的两种状态:高阻态和IO输出态,有效时为输出态)
初始化:
.global pwm_led_init
pwm_led_init:
[iomc3].7 = 1
w = D_PWM_PRD %% [pwm_prd] = w
[pwm_con0].5 = 1
[pwm_con0].4 = 0
[pwm_con0].3 = 1
[pwm_con0].2 = 0
[pwm_con0].1 = 0
[pwm_con0].0 = 1
寄存器说明:
[pwm_con0].7 ---PND
[pwm_con0].6 ---CLR_PND
[pwm_con0].5 ---SSEL PWM模块时钟源: 0-->wclk;1-->src_clk
[pwm_con0].4 ---PSET PWM模块时钟分频系数
[pwm_con0].3 ---PSET PWM模块时钟分频系数
[pwm_con0].2 ---PSET PWM模块时钟分频系数
[pwm_con0].1 ---PSET PWM模块时钟分频系数
[pwm_con0].0 ---EN
PWM模块时钟分频系数:[2:1]: 00-->div1 01-->div4 10-->div16 11-->div64
[3]: 0-->x1 1-->x2
[4]: 0-->x1 1-->x256
占空比:
w = duty %% call set_pwmx
duty为需要输出的占空比,set_pwmx可选为set_pwm0、set_pwm1、set_pwm2
duty的占空比是反向设置,0xFF对应0%,0x00对应100%
IO配置(以pwm0为例):
#define set_pwm0_io [p1_dir].3 = 0 %% [p1_out].3 = 1 //有效状态输出高,非有效高阻
#define set_pwm0_io [p1_dir].3 = 0 %% [p1_out].3 = 1 %% [p1_pd].3 = 1 //有效状态输出高,非有效为低电平(因为有下拉)
#define set_pwm0_io [p1_dir].3 = 0 %% [p1_out].3 = 0 //有效状态输出低,非有效高阻
#define set_pwm0_io [p1_dir].3 = 0 %% [p1_out].3 = 0 %% [p1_pu].3 = 1 //有效状态输出低,非有效为高电平(因为有上拉)
(5) 睡眠和唤醒:可参看芯片介绍的寄存器配置
睡眠:
注意:
1、睡眠前可能需要关闭一些IO(具体看外围),否则可能耗电
睡眠前需要关闭内部电源分压,否则会耗电
vcc_div_en = 0
vbat_div_en = 0
vout_div_en = 0
唤醒后需要重新打开(测量电源电压时需要)
vout_div_en = 1
vcc_div_en = 1
vbat_div_en = 1
2、如果需要用到P12脚(不使用内部充电时可用),需要将vout_discharge配置为0:vout_discharge = 0
唤醒:
两路普通IO口唤醒(IO可选任意普通IO,但要注意上电时p06不能是低电平)
#define io_wkup_rise(ch,port,n) \ //普通IO上升沿唤醒;例如p07:io_wkup_rise(ch0, p0, 7)
input_map(ch,port,n) %% \
bs port ## _pd,n %% \ //如有外部下拉,不要开内部下拉(bc port ## _pd,n)
bc port ## _pu,n %% \
bs port ## die,n %% \
wkup##ch(0)
\#define io_wkup_fall(ch,port,n) \ //普通IO下降沿唤醒;例如p14:io_wkup_fall(ch1, p1, 4)
input_map(ch,port,n) %% \
bc port \#\# _pd,n %% \
bs port \#\# _pu,n %% \ //如有外部上拉,不要开内部上拉(bc port \#\# _pu,n)
bs port \#\# _die,n %% \
wkup_\#\#ch(1)
以上:ch:只有两个,ch0和ch1
两路固定IO唤醒,p10和p11(不使用内部充电时可用)
\#define voutx_wkup_set_rise(ch,n) \
bs p1_dir,n %% \
bs p1_pd,n %% \ //如有外部下拉,不要开内部下拉(bc port \#\# _pd,n)
bc p1_pu,n %% \
bs p1_die,n %% \
wkup_\#\#ch(0)
\#define voutx_wkup_set_fall(ch,n) \
bs p1_dir,n %% \
bc p1_pd,n %% \
bs p1_pu,n %% \//如有外部上拉,不要开内部上拉(bc port \#\# _pu,n)
bs p1_die,n %% \
wkup_\#\#ch(1)
p10 例:
wkup9_cpnd = 1
wkup9_vout0_sleep
wkup9_en = 1
voutx_wkup_set_rise(ch2, 0) //p10只能选ch2
p11 例:
wkup10_cpnd = 1
wkup10_vout1_sleep
wkup10_en = 1
voutx_wkup_set_rise(ch3, 1) //p11只能选ch3
注意:[wkup_flt]的低4位为4个ch的唤醒滤波使能(详见芯片介绍文档),没有开启唤醒功能的ch不能使能其对应的滤波使能,否则会耗电!
vcc唤醒(不使用内部充电时可用),两种唤醒方式:
1、比较唤醒,vcc接入电压大于电池电压唤醒
wkup6_cpnd = 1 %% wkup6_eie = 1 %% wkup6_sel1 = 1 %% wkup6_sel0 = 0
wkup6_inv = 0 //只能为0
2、跳变沿唤醒,出现指定的跳变沿时唤醒
wkup6_cpnd = 1 %% wkup6_eie = 1 %% wkup6_sel1 = 0 %% wkup6_sel0 = 1
wkup6_inv = 1 //下降沿唤醒
wkup6_inv = 0 //上升沿唤醒
(6) vcc状态检测(不使用内部充电时可用):
初始化检测:
bs 0x8f, 6 //clr wtd
sfr_rd_sel2 = 0 //bc 0xfc, 7
sfr_rd_sel1 = 1 //bs 0xda, 7
sfr_rd_sel0 = 1 //bs 0xda, 6
两种检测判断方式:
第一种,判断电平:
if(vcc_det_pg3 == 1) skip //btbn 0xe4, 2, 判断vcc的电平是否为高电平
第二种,判断vcc是否比电池电压大:
if(vcc_vbat_comp_pg3 == 1) skip //btbn 0xe4, 3, 判断vcc是否比电池电压大
例:
.global vcc_detect_read
vcc_detect_read:
bs 0x8f, 6 //clr wtd
sfr_rd_sel2 = 0 //bc 0xfc, 7
sfr_rd_sel1 = 1 //bs 0xda, 7
sfr_rd_sel0 = 1 //bs 0xda, 6
if(vcc_det_pg3 == 1) skip //btbn 0xe4, 2, 判断vcc的电平是否为高电平
// if(vcc_vbat_comp_pg3 == 1) skip //btbn 0xe4, 3, 判断vcc是否比电池电压大
goto __vcc_detect_offline
__vcc_detect_online:
ret
__vcc_detect_offline:
ret
(7) 看门狗溢出时间修改:
[wdt_con]的低4位[3:0]time:溢出时间为 2^ time 毫秒
注意事项:
1、P06上电之前不能拉低,否则会不开机
2、配置唤醒功能,唤醒前的电平必须与唤醒后的相反,否则会耗电,也就是sleep之前是高电平,需要配置为下降沿唤醒(不能是上升沿唤醒),sleep之前是低电平,需要配置为上升沿唤醒(不能是下降沿唤醒)。
3、[wkup_flt]的低4位为4个ch的唤醒滤波使能(详见芯片介绍文档),没有开启唤醒功能的ch不能使能其对应的滤波使能,否则会耗电!
4、不用到的IO口,sleep之前建议配置为输入模拟关上下拉,否则可能耗电(例如输入数字关上下拉,会有几十ua的耗电)