赞助论坛
  • 6490阅读
  • 0回复

关于SERVO的控制(转载) [复制链接]

楼层直达
wlttck  
发帖
7
精华
0
金币
23
威望
3
贡献
0
好评
1
注册
2008-04-27
楼主    wlttck 发表于: 2008-07-07 18:34:27 
现MP3-CD Player是用SONY的3颗芯片协同控制来实现对CDDA、CDROM、CD-R、CD-RW识别和资料的读取。这三颗芯片是:RF CXA2647N、Digital SERVO CXD3068Q、Motor Driver CXA2534Q,现在用的Loader是ks900或者是BBC1000。主控芯片如TI DSP 54xx或者是CL koala7410来控制。基本控制流程如下。 1、 POWER ON:初始化系统和控制脚pin;然后reset CXD3068Q,因为需要一段时间的初始化,所以程序如下。 SET_SERVO_STANDBY;设置CXA2534Q,让它处于STAND BY状态。 CLEAR_SERVO_XRST; 设置CXD3068 Reset Pin为0,即Reset CXD3068 DelayMS(10); SET_SERVO_XRST; 设置CXD3068 Reset Pin为1,结束CXD3068 Reset DelayMS(20); CLEAR_SERVO_LDON;让CXA2647N的二极管开始打雷射光。 2、 初始化CXD3068Q的参数:这一步比较的重要,一般有一些参数是必须在SERVO ON之前设置的。相关Functions 是SERVO2545_init()。 Command 参数 功能描述 0x3f0010设置3068Q的Master Clock和它的波形参数,设置为默认值 0x348c10用来设置GFS、FOK信号高低产生的控制;MSR的设置 0xABFA2808EFM播放方式的控制,默认是打开 0xAC3F同步保护窗口宽度的自动扩展功能,默认为关闭,3f是同步向前保护的时间间隔。 0x30设置Sled kick level为1倍速 SERVO_send_8X_command()$80060030:模式规范设置,详细请看$8X command 0x9b109000Normal Speed,打开寄存器A.SEQ,立体声输出(STERE) 0xb00000Traverse monitor count setting,用来侦侧从SENS输出来的traverse的状态 0xc20f3000Spindle servo coefficient setting GVLVS=0db;GMDS=-6db;GDCLV=0db;将VPCO设为输出模式 0xd0e00000CLV CTRL;设置bottom hold 和peak 的时钟频率;在SERVO_filter_setting()中,它发送一组参数设置命令{0x340080, 0x340504, 0x341120, 0x34400b, 0x34436a, 0x344447, 0x34457d}设置内部RAM参数,其参数表值存放在内置ROM中,在系统启动后,根据特定的产品设置不同的参数,由此参数映射到内置ROM参数功能表,然后将其对应的功能设置load到RAM,初始化每个Filter的功能。下面解释一下这组Filter参数: 0x340080:设置Sled input gain(K00); 0x340504:设置Sled output gain(K05); 0x341120:设置 Focus output gain(K11); 0x34400b:设置 Tracking Hold Filter Input Gain(K40); 0x34436a:设置 Tracking Hold Filter B-H(K43); 0x344447:设置 Tracking Hold Filter B-L(K44); 0x34457d:设置 Tracking Hold Filter Output Gain(K45)。而SERVO_avrg_ctl()函数,主要测量DC偏移量并对信号进行补偿。在            CXD3068Q初始化时,可能由于电气特性或外在因素影响,信号会在振幅方向上有个偏移(Offset),为了准确得到个信号,必须去掉这个偏移量。所以在SERVO_avrg_ctl()函数中,我们通过相继发送0x380800,0x382000,0x380010,0x388000分别侧到  RFDC,FE,TE,VC的均值,然后发送0x38148a命令补偿相应的信号。最后是Do_mute()函数,在初始化时,一般都是先Mute CXD3068Q。 1、 Servo Sled。这一步主要是大范围移动小车,也就是所谓的粗调或跟进伺服,而在第一次启动时,则需要将车头移到光盘的最里面(导入区),这是为了后面读TOC做准备的。下面详细说明相关代码():(1)相关functions: SERVO_sledin (); (2) 命令参数解释: SERVO_send_command(2, TOFF_SREV):从外向里移动小车直到光盘最里面 SERVO_send_command_no_latch(2,0x30):Read Sens for SSTP,设置Sens输出信号为SSTP; SERVO_SENS_LOW:读取Sens信号; SERVO_TRK_SLD_OFF:关闭TRACK 和 SLED SERVO; (3)概述:在Sled in 的过程中,首先我们应该发送一个TOFF_SREV命令,令小车移到光盘最里头,这时我们就要去判断小车是否sled成功,其标志就是Sens输出信号是否为低(初始化时为高),在这里则先设一个时间limit,通常为 12s,当在这个时间limit内,若sens输出为低时则说明Servo Sled 已经成功,反之则失败。最后发送SERVO_TRK_SLD_OFF关闭TRACK and SLED SERVO结束整个sled过程。其中需要注意的一点是,不同情况下的Sens输出的信号代表着不同的含义。这里我们应该设为SSTP,所以在读SENS 信号前必须发送0x30到相应的寄存器。 4.Servo Focus:Servo 的聚焦过程,其作用是将镭射光打在正确的区域,以便能够正确的读取光盘上的数据。 (1)相关functions或代码: SERVO_focus(),SERVO_fcsdwn(),SERVO_focus_20(), SERVO_focus_30(),SERVO_fcson(),SERVO_focus_40(), SERVO_focsok(),SERVO_focus_50(),SERVO_fcstry(), SERVO_fcserr(),SERVO_focus_60(),SERVO_fcsext()。 (2)命令参数解释: CLEAR_SERVO_LDON:打开镭射光; SERVO_FOCUS_DOWN:Focus Search Voltage Down ,驱动光头下移; SERVO_AUTO_FOCUS:Auto Focus,自动聚焦,包括0x03和0x08两个参数命令功能。 SERVO_CLV_A:自动CLVS/CLVP切换模式(播放); SERVO_ANTISHOCK_OFF:关闭anti shock; SERVO_TRK_SLD_ON:TRACK SERVO and SLED SERVO is on; SERVO_AUTOSEQ_CANCEL:focus cancel; (3)信号注释 FZC:聚焦过零信号,在光头在上下移动时,当焦点刚好落在信号面上时FZC为零,表示搜索到焦点(聚焦成功);否则为非零值。 FOK:聚焦OK信号,从激光头输出的RF经过聚焦OK比较器后产生的信号,当聚焦搜索完成,FOK就会由低变为高。 GFS:主轴伺服成功信号,当同步帧信号和基准时钟相匹配时,GFS信号则会变高。  (4)Focus Search波形图(CXD3068Q DataSheet Page 95): (5)概述:首先执行的是SERVO_focus()函数,它主要是在聚焦(focus)之前进行一些相应变量的初始化工作,比如说置focus成功的标志,重新聚焦的次数等,还有的是打开镭射光;接着是开始聚焦(focus),它包括聚焦搜索和聚焦伺服。首先是聚焦搜索,从Focus Search的波形图中可看出,通过相继发送命令$00->$02->$03->$08,然后根据FOK 和SENS pin输出的信号FOK 和FZC来判断focus是否成功。具体到程序角度来看,SERVO_fcsdwn()是发送一个0x02参数命令,使得光头下移(时间300ms);然后就是SERVO_focus_20()发送AUTO FOCUS参数命令0x4700,这个命令包括两个参数功能:0x03使得光头上升,到了一定的高度,也就是说镭射光打到了一块正确光盘区域(凹坑),则表示聚焦成功,此时就发送0x08参数命令过去,Fok 和FZC信号则会变高,SERVO_focus_30()就是通过侦侧FOK和FZC 信号来判断Focus是否成功;如果不成功的话则重新开始Try,如果成功的话,在一般情况下整个聚焦过程就结束了,但在实际情况中,由于SERVO或光盘的摇晃,震动等等,我们必须进行进一步的比较精细的聚焦调试判断过程,这一点我们可以从Focus Search波形图中FOK和FZC信号在Focus成功以后的变化看出,具体则由函数SERVO_fcson()来完成,根据FOK和FZC信号在 Focus serve on之后的变化曲线,可得出它们为高电位的时间远远大于低电位的时间(check_focus_ok()函数实现的功能),这样我们可以通过 check_focus_ok函数来判断是否聚焦成功,若返回不成功的话则跳转到SERVO_focus重新聚焦,如果成功的话,则表明聚焦搜索完成,开始聚焦伺服动作。这时将CLV设置为CLVS/CLVP自动切换(通常是在播放模式下的)、来启动主轴电机,关闭ANTI-SHOCK(这是因为在AGC Control时,必须把每个伺服Filter Gain设置成Normal模式和关闭Anit- shock线路)以及打开TRACK SERVO和SLED SERVO,既接通循迹伺服环路,控制激光束准确地照在光盘的信号轨迹上;由于发送了CLV_A命令,可能会造成对聚焦的破坏,所以我们得再次调用 check_focus_ok来判断是否聚焦成功;如果成功的话,接下来的就是主轴伺服过程。在主轴伺服过程中,在主轴电机启动后,当CLV达到一定速度时,便可从光盘上读取帧同步信号,经基准时钟信号比较后,输出GFS,若GFS在一段时间内(通常为10ms)为高,则表示主轴伺服工作正常。在SERVO_focus_40函数里我们就是通过判断GFS信号是否保持10ms为高电位。此时,整个SERVO FOCUS过程就完成了,在SERVO_focsok()函数中主要是做一些变量的初始化或赋值;而SERVO_focus_50()决定是STOP还是继续FOCUS后继工作:EF Balance Adjustment 和Focus Bias Adjustment。注意:在聚焦工作前,也就是在Focus Down前,是否要驱动电机转动,既发送SERVO_CLV_KICK。根据聚焦原理来看,是否驱动电机转动对聚焦过程没有影响, SERVO_CLV_KICK可做也可不做,因为在聚焦时,无论光盘有没有在转动,Focus Search要做的事就是使激光束焦点打在光盘信息纹迹上,光盘的转动只会增加聚焦的难度或者延长了聚焦的时间。5.EF Balance Adjustment:循迹伺服,当Focus Servo on时,光盘在做CLV转动,由于离心率等因素引起TE信号做曲线变化,从而影响聚焦,读碟。TE信号是由光敏二极管F,E将反射光信号转换成电信号,再经TE放大器输出的循迹误差信号。当激光束扫描光盘信息纹迹时,从光盘反射到光敏二极管E,F,由于物镜的反射偏差,导致激光束投射在E,F光敏二极管的区域对信息扫描轨迹的不对称分布,形成循迹误差信号TE,它的正负反映了主光束偏移信息纹迹的方向,大小反映偏移纹迹的程度,为了能够正确使激光束投射在信息纹迹中线,在E,F副光束区成一个对称的分布,我们必须将循迹误差信号TE放大后去驱动循迹线圈达到EF Balance(均衡)。 (1). 相关Functions: SERVO_EF_balance()、SERVO_efv_10()。 (2). 命令参数解释: SERVO_AGC_CANCEL(0x38148e):DC Offset Cancel Measrement and compensation,DC偏移的测量和补偿。 0x3814AA:置TBLM为1,通过内置TRK hold filter抽取掉TE信号中的低频信号。置TLC2为1来补偿从TRVSC寄存器来的TE和SE信号。 SERVO_TRK_SLD_OFF:关闭TRACK 和 SLED SERVO; (3)概述:在函数SERVO_EF_balance中,先发一个命令0x3814AA,它的作用是抽取TE信号中的低频部分,将其存放在TRVSC寄存器中,以此值来比较TE和SE信号,得出循迹误差信号,驱动循迹线圈带动物镜在水平方向上微动,达到准确跟踪信息纹迹的目的,完成循迹伺服补偿。在循迹补偿过程中,可能会出现两种情况需要补偿:一种是从光敏二极管E反射回来的光量大于从光敏二极管F反射回来的光量;另一种是E〈 F。当光头在最里面时,准确的说当光头停止在某个固定点时,只可能对一种误差情况进行补偿,为了调试能够在两钟情况下都可以补偿,则需发送TOFF_SFWD命令,令小车光头向外作微笑的移动,这移动的距离取决于延迟的时间,当小车向外移动,这两种需要补偿的情况都会出现,并自动完成了对其的补偿。接着就跳到函数 SERVO_efv_10(),在EF Balance Adjust完成之后,置标志servo_EF_balance_ok为1,由于上面小车作了向外移动,影响了给进伺服,我们有必要重新进行给进伺服,首先调用SERVO_AGC_CANCEL(0x38148e)删除DC中的分歧(Offset)且加以补偿,然后 SERVO_sledin和SERVO_fcson重新完成给进伺服。6.Focus Bias Adjustment:搜索并设置自动调节聚焦的偏移值, 通过对一段时间内凹坑/平台产生的抖晃值(jitter)进行统计,将其平均值作为光头的Jitter值,因为 Jitter值越小,实际检测到的信号就越接近标准信号,从而光头的性能就越好。 (1).相关Functions: SERVO_fbias()。 (2).命令参数解释: 0x3a4000:置FBON为1,便于读取FBIAS寄存器中的值; (3)概述:在SERVO_fbias()中,采用多次测量,求得Focus Bias平均值,以使Servo的抖晃(Jitter)最小。首先发送0x3a4000命令,打开FBIAS寄存器,便于从FBIAS寄存器读取 Jitter到Focus Servo Jilter中;接着会作两次搜索:向上(Up)和向下(Down)搜索,调用SERVO_fb_dtr()设置Focus Bias值,存到FBIAS寄存器中,然后SERVO_rfjsmp()从Focus Servo 寄存器中读取抖晃值(Jitter),当读取完毕后,SENS pin会输出高电位,既用SERVO_sense_fok和SERVO_sense_gfs来判断是否OK,重复此动作,得出一个最小Jitter值 Bias_a;然后进行向下搜索(动作同上),得到另一个最小Jitter值Bias_b;取其平均值后发送到FBIAS寄存器,便于Focus Servo读取调节聚焦效果。 7. Automatic Gain Control:进行聚焦自动增益(AGF)和循迹自动增益 (AGT)动作,可自动调节Jilter内部增益值,从而获取精确的Servo Loop Gain。AGC不仅可以知道转动装置和二极管敏感的变化,而且可获得不同DISC的不同增益(gain)。 (1).相关Functions: SERVO_agc()、SERVO_agc_10()、SERVO_ag_trk()、SERVO_agc_20()。 (2).命令参数解释: 0x38168e:打开聚焦自动增益调节控制位(位AGF=1); 0x38158e:打开循迹自动增益调节控制位(位AGT=1); (3)概述:首先我们进行聚焦自动增益(AGF)控制,在SERVO_agc()函数中,发送一个命令0x38168e,其作用是打开聚焦自动增益调节控制位,系统便开始自动调节,这时,我们可以通过侦侧SENS输出信号,当变高时则说明AGF完毕;这一步在SERVO_agc_10()中得到实现,此外,如果有异常发生(前面SERVO_sense_fok和SERVO_sense_gfs得知),就调用SERVO_AGC_CANCEL停止AGC,转到异常处理程序SERVO_emrchk。同样的原理,再进行循迹自动增益控制(AGT);在SERVO_ag_trk()中,发送一个命令0x38158e,打开循迹自动增益调节控制位(位 AGT=1);系统就自动进行循迹增益调节;同样的方法,在SERVO_agc_20()实现判断AGT是否完成,以及是否有异常发生并调用相应的异常处理 SERVO_emrchk函数。 8. 异常处理:当 Servo完成聚焦伺服,主轴伺服,循迹伺服后正常工作时,由于盘片的质量或者外界的影响造成Servo出现异常,比较常见的有聚焦不成功,主轴失控,循迹不正确等问题。这部分的工作主要是由Servo内部线路自动完成,而程序所需要做的是侦侧内部线路自动调节的结果,更改程序的运行流程导向。 1) 相关Functions: SERVO_emrchk()、SERVO_emr_10()、SERVO_emcsbq() SERVO_emr_20()、adjCDtime()、reset_emergency_flag() 2) 主要变量解释: servo_focus_drop:聚焦伺服是否成功的标志; servo_gfs_drop:主轴伺服是否成功的标志; servo_subq_drop:在读SUBQ过程是否出现异常; 3) 具体程序代码分析: u SERVO_emrchk():该函数是异常处理的主程序。当出现异常时,先将标志servo_focus_on 置为0,表示要重新Servo的各种伺服动作。如果此时是在读TOC的过程中,并且只是GFS信号有问题,而聚焦伺服完好,说明可能是主轴伺服失控,这时我们需要去判断CLK模式后聚焦伺服是否依然完好,首先发送SERVO_AUTOSEQ_CANCEL命令停止主轴转动,然后将小车拉到光盘内侧,关闭 Track Servo 和Sled Servo,将CLV模式设置为Brake,运行一段时间后停止,调用函数check_focus_ok()侦侧聚焦伺服是否完好。如果没有,则置聚焦伺服异常标志servo_focus_drop为1。如果系统在播放模式下,并且不在search过程中,这时我们需要记录当前光头所在的地址,并且需要调整该地址,因为在播放时出现异常,极可能光盘当前地址有异常,此时我们需要将光头向前挪几个frame,跳出该异常区域,具体程序由adjCDtime()来实现,调节好地址,将search_flag置为1,致使Servo进行Search动作。下面根据不同时刻下的异常发生进行相应的处理,主要有三种,分别是聚焦伺服,主轴伺服和读SUQ:当聚焦伺服出现异常时,由变量servo_focus_drop可得知。重新设置Fok的限制执行时间,初始化相关状态设置,调用SERVO_focus 重新从聚焦伺服开始调节。由servo_gfs_drop可得知是否出现主轴伺服异常。初始化相关时间变量和Servo设置参数,调用SERVO_emr_10进行相应的处理。否则则说明异常发生在TOC的读取过程中,此时则调用函数SERVO_emcsbq()来处理。 u SERVO_emr_10()该函数主要处理主轴伺服异常,即当servo_gfs_drop为1时。先是等待500ms后调用SERVO_fcson进行主轴伺服过程,而不需要重新从聚焦伺服开始整个过程。 u SERVO_emcsbq():当TOC读取过程中发生异常时,先要停止Focus Search 动作,初始化Servo的相关设置。对servo_sbqemr进行累加计数,判断是否异常处理次数是否超过2次,如果超过的话,说明前面2次都没有纠正该异常,重新设置各异常标志值,停止Servo运行,使系统进入Idle模式;如果没有超过2次,设置System时间,并将小车拉至光盘内侧后,调用函数 SERVO_emr_20进行相关的处理。 u SERVO_emr_20():判断小车在System时间内有没有将小车拉至光盘内侧,如果有,则开始重新整个Servo的伺服过程。首先初始化servo_subq_drop为0,当小车已经拉至光盘内侧后,我们要关闭Track Servo 和Sled Servo ,调用函数SERVO_focus()重新进行聚焦伺服等其它伺服过程。 u adjCDtime():该函数主要是用来调节地址信息的,在函数中的有三个引用参time, amount和direction。Time表示的是调节前的地址信息,amount表示的是需要移动的地址长度,direction表示的是移动的方向,1代表向前,0则为向后。返回值就是调节后的地址信息。 u reset_emergency_flag():重新设置各异常标志,并且包括相关的时间参数设置。