LINFlexD外設(shè)簡介
YTM32微控制器的LINFlexD外設(shè)模塊,實(shí)現(xiàn)了LIN協(xié)議控制器的功能,可以支持LIN總線協(xié)議的主機(jī)和從機(jī)功能。如圖x所示。
圖x LINFlexD在LIN總線系統(tǒng)中的位置
LINFlexD 可以實(shí)現(xiàn)使用較少 CPU 介入的情況下,高效管理大量的 LIN 通信幀:
- 在主機(jī) Master 模式下,當(dāng)軟件觸發(fā)了通信過程(發(fā)送幀頭),LINFlexD 硬件可以自行繼續(xù)發(fā)送或者捕獲數(shù)據(jù)流(應(yīng)答數(shù)據(jù)),直至軟件重新啟動(dòng)下一個(gè)通信過程(主機(jī)啟動(dòng)),或者收到一個(gè)校驗(yàn)和(接收模式)。
- 在從機(jī) Slave 模式下,LINFlexD 中設(shè)計(jì)了一組幀頭過濾器(ID Filter),可以配置由硬件自動(dòng)匹配從總線上捕獲到的幀頭,僅當(dāng)識(shí)別到本機(jī)預(yù)設(shè)處理的幀頭,才啟動(dòng)數(shù)據(jù)通信過程(從機(jī)任務(wù))。
- LINFlexD 內(nèi)部還集成了一個(gè)8字節(jié)的緩沖區(qū),用于存放硬件自動(dòng)發(fā)送或者接收的數(shù)據(jù)段內(nèi)容。
- LINFlexD 硬件外設(shè)支持LIN v1.3、v2.0、v2.1、v2.2協(xié)議??梢栽谂渲脦^信息的
LINFlexD_BIDR[CCS]
寄存器位中指定將要發(fā)送或者接收的幀使用擴(kuò)展性校驗(yàn)和還是經(jīng)典款校驗(yàn)和。
LINFlexD 還支持 UART 模式,用于實(shí)現(xiàn)常規(guī)的 UART 通信。本文主要面向 LIN 通信引擎介紹,關(guān)于 UART 介紹,可見后續(xù)文章。
LINFlexD工作機(jī)制
初始化
手冊中對(duì) LINFlexD 的工作模式劃分為:初始化模式(Initialization)、常規(guī)工作模式(Normal)和休眠模式(Sleep)。在硬件復(fù)位后,LINFlexD 處于休眠模式以節(jié)約用電。若要配置 LINFlexD 開始工作,需要先通過軟件配置,切換至初始化模式,在初始化模式下進(jìn)行一些專屬的配置后,再切換至常規(guī)工作模式,才能順利啟動(dòng) LINFlexD 外設(shè)。這個(gè)初始化模式,相當(dāng)于為配置 LINFlexD 外設(shè)設(shè)計(jì)了一個(gè)同步鎖,或者說關(guān)鍵區(qū),使得在初始化階段配置 LINFlexD 外設(shè)的各項(xiàng)功能時(shí)都不會(huì)立刻生效,以避免產(chǎn)生不確定的不安全狀態(tài),最后退出初始化模式,硬件同步一并打開所有的配置功能,穩(wěn)當(dāng)。
- 初始化模式(Initializaiton,INIT)
軟件配置寄存器LINFlexD_LINCR1[INIT]=1
,切換至初始化模式。當(dāng)然,還可以通過配置LINFlexD_LINCR1[INIT]=0
,退出初始化模式(至Normal模式?)。
進(jìn)入初始化模式后,LINFlexD 引擎同 LIN 總線的傳輸將全部停掉(木頭人不許動(dòng)),并且推送總線上位高電平(隱形信號(hào))。如果在某個(gè)總線傳輸?shù)倪^程中進(jìn)入初始化模式,則該傳輸將被打斷并退出。所以說,在切入初始化狀態(tài)之前,軟件一定要先查一下 LINFlexD 的狀態(tài)標(biāo)志位,確保不會(huì)打斷正在進(jìn)行的傳輸,再進(jìn)入初始化模式。
在初始化模式下,可以對(duì) LINFlexD 外設(shè)進(jìn)行初始化配置:
- 配置通信波特率
- 啟用 LINFlexD 模式(停用UART模式)
- 選擇主機(jī)模式或者從機(jī)模式
- 配置校驗(yàn)和控制位
- 若是從機(jī)模式,還需要預(yù)先填寫好可以捕獲的ID的列表
- 常規(guī)工作模式(Normal Mode,NM)
在初始化模式中,配置寄存器LINFlexD_LINCR1[INIT]=0
,切換至常規(guī)工作模式。
在常規(guī)工作模式下,LINFlexD 可以執(zhí)行正常的收發(fā)通信。
- 休眠模式(Sleep Mode,SM)
配置軟件寄存器LINFlexD_LINCR1[SLEEP]=1
,切換至休眠模式。當(dāng)然,也可以通過配置LINFlexD_LINCR1[SLEEP]=0
,退出休眠模式(至Normal模式)。
進(jìn)入休眠模式后,LINFlexD引擎就暫停工作,等待喚醒事件到來后,自動(dòng)切回正常模式響應(yīng)外部的通信請求。
如果軟件在 LIN 總線上檢測到一個(gè) 150us 的喚醒脈沖,可以請求 LINFlexD 從休眠模式喚醒。
- 回環(huán)工作模式(Loop Back Mode)
通過配置寄存器LINFlexD_LINCR1[LPKM]=1
啟用回環(huán)模式?;丨h(huán)工作模式可用于自測試通信協(xié)議,當(dāng)啟動(dòng)回環(huán)模式后,芯片內(nèi)部的Tx和Rx引腳相連,通過Tx發(fā)送的信號(hào)會(huì)直接被反饋會(huì)接收通道(忽略Rx引腳的輸入)。如圖x所示。
圖x LINFlexD的回環(huán)模式
主機(jī)模式
通過配置寄存器LINFlexD_LINCR1[MME]=1
,設(shè)定本設(shè)備為主機(jī)模式工作。
- 發(fā)送幀頭
根據(jù)LIN協(xié)議的描述,LIN總線的上通信,都是由主機(jī)(具體是主機(jī)節(jié)點(diǎn)的主機(jī)任務(wù))發(fā)送幀頭開始的。當(dāng)發(fā)送幀頭時(shí),由軟件先寫入LINFlexD_BIDR
寄存器中的字段,包括:ID(6位的幀ID,硬件自動(dòng)補(bǔ)完校驗(yàn)位)、DFL(數(shù)據(jù)段長度)、DIR(幀通信的方向)及CCS(啟用經(jīng)典校驗(yàn)的控制位,后續(xù)硬件自動(dòng)生成校驗(yàn)字節(jié))。然后,設(shè)置寄存器LINFlexD_LINCR2[HTRQ]=1
,請求發(fā)送幀頭。在啟動(dòng)發(fā)送幀頭之后,在發(fā)送完成本幀之前,不要人為修改LINFlexD_BIDR
寄存器中的內(nèi)容,LINFlexD 從總線上捕獲到已經(jīng)發(fā)送幀的ID會(huì)被自動(dòng)復(fù)制到LINFlexD_BIDR
寄存器中。
- 發(fā)送數(shù)據(jù)
當(dāng)主機(jī)節(jié)點(diǎn)執(zhí)行發(fā)布任務(wù)時(shí)(發(fā)送數(shù)據(jù)到總線),主機(jī)節(jié)點(diǎn)上運(yùn)行的從任務(wù)(主機(jī)節(jié)點(diǎn)上的主任務(wù)僅發(fā)送幀頭)會(huì)繼續(xù)發(fā)送數(shù)據(jù)部分。因此,軟件需要在發(fā)起發(fā)送幀頭的請求之前,就將需要發(fā)送的數(shù)據(jù)準(zhǔn)備好,將數(shù)據(jù)存放至消息緩沖區(qū)LINFlexD_DATA[]
中,同時(shí),需要在LINFlexD_BIDR[DFL]
寄存器中指定將要發(fā)送字節(jié)數(shù)據(jù)的數(shù)量,硬件根據(jù)軟件在LINFlex_BIDR[CCS]
控制位的配置(這個(gè)數(shù)據(jù)位可能是總線上捕獲到的幀頭中的信息),自動(dòng)計(jì)算經(jīng)典校驗(yàn)和或是增強(qiáng)校驗(yàn)和。
當(dāng)應(yīng)答的數(shù)據(jù)發(fā)送成功后,會(huì)置位硬件標(biāo)志位LINFlexD_LINSR[DTF]
,但如果發(fā)送過程中出現(xiàn)錯(cuò)誤,標(biāo)志位LINFlexD_LINSR[DTF]
不會(huì)置位,LINFlexD_LINSR
寄存器的其它對(duì)應(yīng)標(biāo)志位會(huì)置位。
應(yīng)答數(shù)據(jù)的方向(發(fā)送?或是接收)由寄存器LINFlexD_BIDR[DIR]
設(shè)定,但哪怕是發(fā)送過程,將數(shù)據(jù)發(fā)送上總線后,也會(huì)監(jiān)聽總線,將總線上的數(shù)據(jù)捕獲下來并存入數(shù)據(jù)緩沖區(qū)中。
- 接收數(shù)據(jù)
當(dāng)主機(jī)節(jié)點(diǎn)從從機(jī)節(jié)點(diǎn)讀取數(shù)據(jù)時(shí),應(yīng)先發(fā)出一個(gè)幀頭(約定為讀操作的ID)。從機(jī)節(jié)點(diǎn)捕獲到幀頭之后,會(huì)向總線上發(fā)送應(yīng)答數(shù)據(jù),此時(shí)主機(jī)節(jié)點(diǎn)(的從機(jī)任務(wù))會(huì)從總線上捕獲數(shù)據(jù),并將數(shù)據(jù)內(nèi)容存放至數(shù)據(jù)緩沖區(qū)中,寄存器LINFlexD_LINSR
寄存器中對(duì)應(yīng)的標(biāo)志位也會(huì)置位。
當(dāng)應(yīng)答的數(shù)據(jù)接收成功后,會(huì)置位硬件標(biāo)志位LINFlexD_LINSR[DRF]
,但如果發(fā)送過程中出現(xiàn)錯(cuò)誤,標(biāo)志位LINFlexD_LINSR[DRF]
不會(huì)置位,LINFlexD_LINSR
寄存器的其它對(duì)應(yīng)標(biāo)志位會(huì)置位。
- 拋棄數(shù)據(jù)
若用戶需要拋棄發(fā)送幀頭之后捕獲到的應(yīng)答數(shù)據(jù),可預(yù)先設(shè)置寄存器LINFlexD_LINCR2[DDRQ]=1
。這對(duì)應(yīng)的是LIN通信中,實(shí)現(xiàn)“不應(yīng)答”的操作。
注意:哪怕是在主機(jī)模式中,也是分為主機(jī)任務(wù)和從機(jī)任務(wù)兩部分,主機(jī)任務(wù)僅負(fù)責(zé)發(fā)送幀頭,主機(jī)模式中的從機(jī)任務(wù)和下文描述的從機(jī)模式一致,都是通過 LINFlexD_BIDR
寄存器中捕獲的幀頭信息同自己的ID Filter進(jìn)行匹配,從而啟動(dòng)對(duì)應(yīng)的發(fā)送或接收數(shù)據(jù)的過程。
從機(jī)模式
通過配置寄存器LINFlexD_LINCR1[MME]=0
,設(shè)定本設(shè)備為從機(jī)模式工作。
- 發(fā)送應(yīng)答數(shù)據(jù)
當(dāng)從LIN總線上捕獲到主機(jī)任務(wù)發(fā)送的幀頭后,根據(jù)對(duì)ID的定義,若要求本節(jié)點(diǎn)提供應(yīng)答數(shù)據(jù),則硬件標(biāo)志位LINFlexD_LINSR[HRF]
寄存器會(huì)置位,并產(chǎn)生一個(gè)接收中斷。此時(shí),軟件需要盡快填寫將要發(fā)送的數(shù)據(jù)到數(shù)據(jù)緩沖區(qū)中:
- 讀
LINFlexD_BIDR
寄存器,判定接收到幀頭的ID - 向
LINFlexD_DATA
寄存器中填入將要發(fā)送的數(shù)據(jù) - 寫
LINFlexD_BIDR
寄存器,寫入CCS
(校驗(yàn)和計(jì)算方式)、DIR
(數(shù)據(jù)方向),以及DFL
(數(shù)據(jù)長度)寄存器。
設(shè)置寄存器LINFlexD_LINCR[DTRQ]
請求發(fā)送數(shù)據(jù)后,軟件才能清零LINFlexD_LINSR[HRF]
標(biāo)志位。為了確保LINFlexD_LINCR[DTRQ]
寄存器控制位能夠起作用,需要先保持LINFlexD_LINSR[HRF]
置位,這是為了防止LINFlexD_LINCR[DTRQ]
不會(huì)被意外地被置位,而必須跟在發(fā)送一個(gè)幀頭的操作之后進(jìn)行(增加了一個(gè)操作約束條件)。在接收數(shù)據(jù)過程中,LINFlexD_LINSR[RXBUSY]
寄存器保持置位,此時(shí)LINFlexD_BIDR[DIR]
和LINFlexD_LINCR[DTRQ]
位不能被軟件置位。
當(dāng)需要使用ID過濾器時(shí)(Identifier Filter),可配置LINFlexD_IFER
寄存器啟用過濾器功能。若命中其中一個(gè)過濾器時(shí),硬件會(huì)產(chǎn)生一個(gè)發(fā)送中斷,此時(shí),硬件可從寄存器LINFlexD_IFMI
中保存的指針從RAM從自動(dòng)搬運(yùn)數(shù)據(jù)內(nèi)容到LINFlexD_DATA
寄存器緩沖區(qū)中。
使用ID過濾器可以減少軟件從LINFlexD_BIDR
寄存器中讀ID、判定、配置數(shù)據(jù)長度和校驗(yàn)和類型的過程。
如果 LINFlexD 外設(shè)模塊中需要使用的過濾器不夠應(yīng)用中使用,還可以通過設(shè)置過濾器掩碼的方式,模糊匹配ID,以實(shí)現(xiàn)匹配更多ID的效果。
同主機(jī)模式相同,本機(jī)發(fā)送的數(shù)據(jù),也會(huì)被捕獲至本機(jī)的接收緩沖區(qū)中。
- 接收應(yīng)答數(shù)據(jù)
當(dāng)收到主機(jī)任務(wù)發(fā)送的幀頭后,若要求本節(jié)點(diǎn)接收應(yīng)答數(shù)據(jù),則硬件標(biāo)志位LINFlexD_LINSR[HRF]
寄存器會(huì)置位,并產(chǎn)生一個(gè)接收中斷。此時(shí),軟件需要盡快讀BIDR寄存器,從中讀幀ID進(jìn)行匹配,并寫入數(shù)據(jù)段長度(在收到第一個(gè)數(shù)據(jù)字節(jié)的停止位之前)。當(dāng)收到校驗(yàn)和之后,LINFlexD_LINSR[RMB]
寄存器位會(huì)置位,并會(huì)產(chǎn)生一個(gè)接收中斷,此時(shí),軟件可從LINFlexD_DATA
寄存器緩沖區(qū)中讀數(shù),讀數(shù)完成后,需要軟件清零LINFlex_LINSR[RMB]
寄存器位,以釋放接收數(shù)據(jù)緩沖區(qū)。
當(dāng)至少一個(gè)配置為接收的ID過濾器被激活命中,將在收到校驗(yàn)和之后,產(chǎn)生一個(gè)接收中斷。在接收到ID的時(shí)候不會(huì)產(chǎn)生中斷。
如果使用軟件方式過濾ID,當(dāng)HRF標(biāo)志位置位時(shí),若要拋棄數(shù)據(jù)(不應(yīng)答),可以通過寫LINFlexD_LINCR[DDRQ]
寄存器實(shí)現(xiàn)。若使用軟件過濾機(jī)制,軟件需要在接收到校驗(yàn)和之前設(shè)定校驗(yàn)的類型(配置LINFlexD_BIDR[CCS]
)。
錯(cuò)誤狀態(tài)標(biāo)志位
LINFlexD 硬件集成了協(xié)議棧的業(yè)務(wù)邏輯,但由于總線上是多設(shè)備仲裁運(yùn)行的環(huán)境,有時(shí)硬件總線的行為不是完全按照預(yù)期的情形運(yùn)作,時(shí)不時(shí)就會(huì)報(bào)錯(cuò)。LINFlexD 對(duì)處理不了的情況設(shè)計(jì)了對(duì)應(yīng)的監(jiān)測機(jī)制,對(duì)于硬件無法處理的情況,會(huì)盡量及時(shí)地報(bào)錯(cuò),上報(bào)給軟件,交由應(yīng)用邏輯裁決。
LINFlexD_LINESR
寄存器中包含了 LINFlexD 外設(shè)能夠檢測到的所有錯(cuò)誤標(biāo)志位,分別對(duì)應(yīng)檢測各自的錯(cuò)誤機(jī)制。LINFlexD_LINESR
寄存器的位定義,如圖x所示。
圖x LINFlexD_LINESR寄存器的位定義
- 總線拉低超時(shí)錯(cuò)誤(Stuck at Zero Timeout Error,SZF)
發(fā)生Stuck-at-zero超時(shí)錯(cuò)誤。大體上是描述LIN總線被意外地長時(shí)間拉低(顯式電平),后續(xù)無法傳輸數(shù)據(jù)的狀態(tài)。詳見下文超時(shí)錯(cuò)誤機(jī)制。
- 輸出比較標(biāo)志(Output Compare Flag,OCF)
輸出比較事件是LINFlexD在管理超時(shí)機(jī)制中產(chǎn)生的一個(gè)事件。
- 在主機(jī)模式下,當(dāng)
LINFlexD_LINTCSR[CNT]
中的計(jì)數(shù)值同LINFlexD_LINOCR[OC2]
寄存器的設(shè)定值相等時(shí),起OCF標(biāo)志位。 - 在從機(jī)模式下,當(dāng)
LINFlexD_LINTCSR[CNT]
中的計(jì)數(shù)值同LINFlexD_LINOCR[OC2]
或LINFlexD_LINOCR[OC1]
寄存器的設(shè)定值相等時(shí),起OCF標(biāo)志位。 - 當(dāng)在
LINFlexD_LINTCSR[MODE] = 0
(LIN模式)并且LINFlexD_LINTCSR[IOT] = 1
, 若OCF標(biāo)志位被置位,則LINFlexD進(jìn)入Idle狀態(tài)。 - 當(dāng)在
LINFlexD_LINTCSR[MODE] = 0
(LIN模式), OCF由處于初始化模式下的硬件外設(shè)自動(dòng)清零。 - 當(dāng)在
LINFlexD_LINTCSR[MODE] = 1
(輸出比較模式), OCF單純表示輸出比較的狀態(tài),同LIN的通信狀態(tài)無關(guān)。
- 位錯(cuò)誤(Bit Error,BEF)
位錯(cuò)誤可能發(fā)生在發(fā)送過程中(發(fā)送幀頭和發(fā)送應(yīng)答數(shù)據(jù)),當(dāng)從總線上讀回的值同發(fā)送的值不一致時(shí),會(huì)出現(xiàn)位錯(cuò)誤。檢測每個(gè)數(shù)據(jù)位的意義在于,確保收發(fā)器的延遲時(shí)間小于一個(gè)可以接受的容限(位時(shí)間的長度再減去6個(gè)功能時(shí)鐘周期),例如:
- 1個(gè)位時(shí)間 t_bittime = 20k bps = 50us
- 6個(gè)功能時(shí)鐘周期@80MHz = 75ns
- 則允許的收發(fā)器延遲時(shí)間 = t_bittime - 6 * t_ipg_baud_clk = 49.925us
這個(gè)49.925us將用于選型合適的LIN收發(fā)器。
在發(fā)送的間隔段中不檢測位錯(cuò)誤。
如果出現(xiàn)位錯(cuò)誤的情況,若此時(shí)已經(jīng)配置了LINFlexD_LINCR2[IOBE]=1
(Idle on Identifier Parity Error),LINFlexD的接收狀態(tài)機(jī)會(huì)立刻退出接收幀頭的狀態(tài)變成Idle。若是LINFlexD_LINCR2[IOBE]=0
,發(fā)送過程將繼續(xù),不管位錯(cuò)誤。如果配置了LINFlexD_LINIER[BEIE]=1
,則此時(shí)會(huì)產(chǎn)生中斷。一種極端的情況,如果不配置退出、不配置中斷,哪怕出現(xiàn)了位錯(cuò)誤,仍可堅(jiān)持完成發(fā)送過程。
- 校驗(yàn)和錯(cuò)誤(Checksum Error,CEF)
當(dāng)接收機(jī)收到數(shù)據(jù)幀及校驗(yàn)和字節(jié)后,會(huì)自動(dòng)計(jì)算校驗(yàn)和,當(dāng)計(jì)算結(jié)果同數(shù)據(jù)內(nèi)容不一致時(shí),會(huì)拋棄收到的數(shù)據(jù)包,同時(shí)會(huì)起一個(gè)CEF標(biāo)志位。如果預(yù)先配置寄存器LINFlexD_LINIER[CEIE]=1
,則對(duì)應(yīng)還可以產(chǎn)生一個(gè)中斷。
如果是LINFlexD發(fā)出的數(shù)據(jù)包,因LINFlexD在發(fā)送過程中會(huì)自動(dòng)計(jì)算校驗(yàn)和,所以若再用 LINFlexD 收到數(shù)據(jù)包仍會(huì)產(chǎn)生校驗(yàn)和錯(cuò)誤,那就要查看傳輸線路是否受到較大的干擾。如果發(fā)送方的校驗(yàn)和是人工計(jì)算的,那也要再確認(rèn)軟件計(jì)算校驗(yàn)和的方法是否正確。
- 幀頭錯(cuò)誤(Header Error)
從機(jī)任務(wù)在接收幀頭過程中發(fā)現(xiàn)的錯(cuò)誤,都算是幀頭錯(cuò)誤。這些錯(cuò)誤包括
(1)幀間隔段分隔符錯(cuò)誤(Break Delimiter Error, SDEF)
這個(gè)分隔符的長度應(yīng)至少為1位的時(shí)間,否則時(shí)間太短,接收方會(huì)丟棄當(dāng)前幀頭的同步段,進(jìn)而丟棄整個(gè)幀。如果LINFlexD_LINIER[HEIE]=1
,則此時(shí)會(huì)觸發(fā)一個(gè)中斷。
(2)同步段錯(cuò)誤(Sync Field Error,SFEF)
同步段錯(cuò)誤的情況在是否開啟自動(dòng)同步的配置(LINCR1[LASE]=1)時(shí)是不同的。
- 當(dāng)啟用自動(dòng)同步機(jī)制時(shí),SFEF標(biāo)志位標(biāo)識(shí)兩種情況:超出LIN規(guī)范(14%偏差)之外的同步段偏差錯(cuò)誤,或者測量同步段已經(jīng)溢出,分頻器打滿也除不下來。SFEF不會(huì)檢測同步段值的錯(cuò)誤(不是0x55)。
- 當(dāng)停用自動(dòng)同步機(jī)制時(shí),同步字段被當(dāng)做一個(gè)普通的字節(jié)被接收,此時(shí)會(huì)判定改值是否為
0x55
,如果不是這個(gè)值,則會(huì)報(bào)錯(cuò),后續(xù)的整個(gè)LIN幀都會(huì)被拋棄。
(3)ID校驗(yàn)錯(cuò)誤(Identifier Parity Error,IDPEF)
PID段中包含6個(gè)比特的ID和2個(gè)比特的校驗(yàn)碼,IDPEF檢測的就是這6個(gè)比特的ID和2個(gè)比特校驗(yàn)碼的一致性。在從機(jī)任務(wù)中,當(dāng)LINFlexD收到幀頭的PID段后,將6比特的ID值送至BIDR寄存器后,會(huì)由硬件自動(dòng)計(jì)算核驗(yàn)校驗(yàn)碼。如果出現(xiàn)不一致的情況,若此時(shí)已經(jīng)配置了LINFlexD_LINCR2[IOPE]=1
(Idle on Identifier Parity Error),LINFlexD的接收狀態(tài)機(jī)會(huì)立刻退出接收幀頭的狀態(tài)變成Idle。
- 幀錯(cuò)誤(Frame Error,F(xiàn)EF)
幀錯(cuò)誤標(biāo)識(shí)的是在當(dāng)前接收字節(jié)(LIN幀的同步段、ID段、數(shù)據(jù)段、校驗(yàn)和段)的停止位檢測到一個(gè)顯性信號(hào)(本應(yīng)為隱形信號(hào),拉高電平),此時(shí)LINFlexD會(huì)拋棄當(dāng)前接收到的幀,然后返回到Idle狀態(tài)。如果預(yù)先配置了LINFlexD_LINIER[FEIE]=1
,則會(huì)產(chǎn)生一個(gè)中斷。
當(dāng)出現(xiàn)幀錯(cuò)誤時(shí),導(dǎo)致錯(cuò)誤的字節(jié)數(shù)據(jù)仍會(huì)被送入數(shù)據(jù)緩沖區(qū)(畢竟已經(jīng)送進(jìn)去了),但LINFlexD_LINSR[DRF]
標(biāo)志位(數(shù)據(jù)接收完成標(biāo)志位)不會(huì)置位。
- 緩沖區(qū)溢出(Buffer Overrun,BOF)
當(dāng)收到一個(gè)新的數(shù)據(jù)時(shí),若標(biāo)志位LINFlexD_LINSR[RMB]=1
尚為清零(數(shù)據(jù)緩沖區(qū)滿,軟件可讀),則判定為緩沖區(qū)溢出,報(bào)錯(cuò)。此時(shí)還需通過寄存器LINFlexD_LINCR1[RBLM]
的配置值,確定如何處理新數(shù)據(jù):
- 若
LINFlexD_LINCR1[RBLM]=0
,則之前未被都走的數(shù)據(jù)包將會(huì)被新的數(shù)據(jù)包覆蓋,舊的數(shù)據(jù)包將被丟失。 - 若
LINFlexD_LINCR1[RBLM]=1
,則之前未被都走的數(shù)據(jù)包將會(huì)被保持,新的數(shù)據(jù)包將被丟失。在從機(jī)模式下,如果再未讀完數(shù)的情況下來了新的LIN幀,不僅僅是數(shù)據(jù),連帶幀ID也會(huì)被一同拋棄。
- 噪聲標(biāo)志(Noise Flag,NF)
當(dāng)接收器檢測到噪聲時(shí),起本標(biāo)志位。關(guān)于噪聲,是在檢測開始信號(hào)和間隔符信號(hào)時(shí),進(jìn)行連續(xù)3次隔點(diǎn)采樣,未能達(dá)到判決條件時(shí),即認(rèn)定為總線上有噪聲。
超時(shí)錯(cuò)誤(Timeout Error)
當(dāng)主機(jī)發(fā)送了幀頭后,如果在指定的時(shí)間段內(nèi)未收到應(yīng)答數(shù)據(jù),則會(huì)產(chǎn)生超時(shí)錯(cuò)誤。LINFlexD外設(shè)內(nèi)部設(shè)計(jì)了一個(gè)超時(shí)定時(shí)器(Timerout Counter),專門用于檢測同超時(shí)相關(guān)的檢測和響應(yīng)事件。
圖x LINFlexD的超時(shí)報(bào)錯(cuò)機(jī)制
- 應(yīng)答超時(shí)機(jī)制
- 主機(jī)模式:每當(dāng)發(fā)送或者接收到ID段(幀頭的最后一個(gè)字段)后,確切地說,是當(dāng)DFL被硬件寫入后,LINFlexD會(huì)自動(dòng)將寄存器
LINFlexD_LINOCR[OC2]
載入到LINFlex_LINTOCR[CNT]
寄存器,并啟動(dòng)內(nèi)部的定時(shí)器開始倒計(jì)數(shù),若在計(jì)數(shù)器計(jì)數(shù)清零之前未完成接收數(shù)據(jù),則產(chǎn)生超時(shí)事件。這相當(dāng)于是個(gè)看門狗。 - 從機(jī)模式:若使用ID過濾器過濾接收數(shù)據(jù)幀,同主機(jī)模式類似,當(dāng)匹配到消息ID,硬件寫入DFL寄存器時(shí),載入
LINFlexD_LINOCR[OC2]
寄存器的值到定時(shí)器,開始計(jì)數(shù)。若未使用ID過濾器,則在收到數(shù)據(jù)幀并由軟件進(jìn)行識(shí)別后,人工寫入DFL寄存器時(shí),硬件載入LINFlexD_LINOCR[OC2]
寄存器的值到定時(shí)器,啟動(dòng)定時(shí)器。
- 幀頭超時(shí)機(jī)制
- 主機(jī)模式:由于幀頭是由LINFlexD硬件自動(dòng)產(chǎn)生的,正常情況下不會(huì)出現(xiàn)超時(shí)。
- 從機(jī)模式:在收到幀間隔符后,硬件從寄存器
LINFlexD_LINOCR[OC1]
到LINFlexD_TOCR[HTO]
,啟動(dòng)定時(shí)器。
注意,這里的定時(shí)器也可以用來檢測其他的超時(shí)事件,但需要配置LINFlexD_LINTCSR[MODE]=0
,然后軟件向寄存器LINFlexD_LINTOCR
中寫入輸出比較值。
- 總線拉低超時(shí)錯(cuò)誤(Stuck at Zero Timeout Error)
如果顯性信號(hào)在總線上保持的時(shí)間超過了100個(gè)比特的時(shí)間,就會(huì)起標(biāo)志位LINFlexD_LINESR[SZF]
。人工清零標(biāo)志位后,如果顯性信號(hào)未消除并繼續(xù),那么接下來只要連續(xù)保持87個(gè)比特的時(shí)間,就會(huì)再次激活標(biāo)志位LINFlexD_LINESR[SZF]
。
ID過濾機(jī)制
在LIN協(xié)議中,消息的ID號(hào)并不是對(duì)應(yīng)節(jié)點(diǎn)的地址,而是標(biāo)識(shí)消息中攜帶的內(nèi)容(命令,或者消息類型)。發(fā)送器將消息廣播到LIN總線,所有的接收機(jī)都能收到,接收機(jī)通過識(shí)別消息的ID,接收機(jī)們決定是繼續(xù)收數(shù)據(jù),或是發(fā)送數(shù)據(jù)應(yīng)答(根據(jù)消息ID的含義做出反應(yīng)),如果接收機(jī)不識(shí)別消息(不做處理),就會(huì)拋棄它。
為了實(shí)現(xiàn)這樣的機(jī)制,LINFlexD外設(shè)設(shè)計(jì)了可配置的ID過濾器,以簡化原本需要軟件去匹配消息ID的工作,節(jié)約了CPU資源。LINFlexD中集成了16個(gè)過濾器,只有在初始化模式下才能配置他們,可以通過將LINFlexD_IFER[FACT]
寄存器中的對(duì)應(yīng)位置位,激活相應(yīng)的過濾器,然后在每個(gè)過濾器專屬的LINFlexD_IFCRn寄存器中配置各自過濾器的參數(shù)。
每個(gè)ID過濾器有兩種可選的工作模式(通過寄存器IFMR[IFM]):
- ID列表模式(Identifier List Mode)。若配置
LINFlexD_IFMR[IFM]=0
,則接收到LIN幀頭的消息ID必須按位同IFCR_n寄存器中的完全相同才能滿足匹配條件。 - ID掩碼模式(Identifier Mask Mode)。若配置
LINFlexD_IFMR[IFM]=1
,則IFCR_2n寄存器和IFCR_2n+1寄存器形成一個(gè)掩碼模式,IFCR_2n中的ID是一個(gè)模板ID,IFCR_2n+1中的ID是一個(gè)掩碼,當(dāng)收到LIN幀頭的消息ID后,先同掩碼做個(gè)與運(yùn)算,過濾掉不關(guān)心的位,然后再同模板ID進(jìn)行匹配。在ID掩碼模式下,LINFlexD_IFER[FACT]
寄存器中是否激活I(lǐng)FCR_2n+1,已經(jīng)不影響了,此時(shí)IFCR_2n+1總是被激活的。當(dāng)需要本接收機(jī)相應(yīng)的消息ID多于硬件ID過濾器支持的數(shù)量時(shí),就需要用ID掩碼模式擴(kuò)展能識(shí)別ID的范圍了。
無論在何種過濾器模式下,一旦編號(hào)為m的過濾器被匹配到,則值m+1將被硬件寫入到IFMI寄存器中,而IFMI=0就表示沒有當(dāng)前還發(fā)生任何匹配事件。此時(shí),軟件可以通過讀IFMI寄存器的值,識(shí)別是哪個(gè)過濾器被匹配到,進(jìn)而從中查看識(shí)別到的消息ID。當(dāng)完成一次匹配事件,LINFlexD硬件都會(huì)將匹配到的DFL、CCS和DIR寄存器的值,從IFCR寄存器復(fù)制到BIDR寄存器中(存放當(dāng)前的幀頭信息),此時(shí)至通信幀傳輸完成之前,BIDR寄存器都是只讀,不能被軟件寫入。此時(shí)LINFlexD_BIDR[DIR]
指示了應(yīng)答數(shù)據(jù)的傳輸方向(相對(duì)主機(jī)):
- 若
LINFlexD_BIDR[DIR]=1
,表示數(shù)據(jù)方向?yàn)榘l(fā)送,可以產(chǎn)生一個(gè)發(fā)送中斷(LINFlexD_LINIER[HRIE]=1
),此時(shí)軟件可以從IFMI寄存器中讀ID過濾器的索引編號(hào),然后向DATA緩沖區(qū)中填充將要發(fā)送的數(shù)據(jù),然后再配置LINFlexD_LINCR2[DTRG]=1
,啟動(dòng)傳輸。 - 若
LINFlexD_BIDR[DIR]=0
,表示數(shù)據(jù)方向?yàn)榻邮?,在接收?shù)據(jù)完畢后,包括校驗(yàn)和字節(jié),并驗(yàn)證校驗(yàn)和無誤后,可以產(chǎn)生一個(gè)接收中斷(LINFlexD_LINIER[DRIE]=1
),此時(shí),軟件可以從DATA緩沖區(qū)中讀出接收到的數(shù)據(jù)。
如果沒有匹配到任何過濾器(通過IFMI=0判定):
- 此時(shí)若已經(jīng)配置了
LINFlexD_LINCR1[BF]=1
,則仍可產(chǎn)生一個(gè)接收中斷。此時(shí)應(yīng)由軟件配置BIDR寄存器并啟動(dòng)傳輸(填充DATA數(shù)據(jù)緩沖區(qū)再配置LINFlexD_LINCR2[DTRQ]
),或放棄接收(配置LINFlexD_LINCR2[DDRQ]
)。 - 若已經(jīng)配置了
LINFlexD_LINCR1[BF]=0
,則接收機(jī)直接拋棄已經(jīng)收到的幀頭(包含消息ID),轉(zhuǎn)入Idle狀態(tài),等待接收下一個(gè)幀間隔段(開始信號(hào))。
注意,如果接收的消息ID同時(shí)匹配到了兩個(gè)過濾器,一個(gè)處于列表模式,另一個(gè)處于掩碼模式,則優(yōu)先匹配到處于列表模式的過濾器。如果同時(shí)匹配到兩個(gè)位于掩碼模式的過濾器,則優(yōu)先匹配到編號(hào)較小的過濾器。如果同時(shí)匹配到兩個(gè)處于列表模式的過濾器,好吧,能將同一個(gè)ID寫到兩個(gè)列表模式下的過濾器,一定是寫錯(cuò)了,但此時(shí)也會(huì)優(yōu)先匹配到編號(hào)較小的過濾器。
接收器檢測幀間隔段和幀間隔段分隔符
LINFlexD內(nèi)部檢測串行信號(hào)模式的方法非常有趣。接收器內(nèi)部設(shè)計(jì)了一個(gè)10比特的移位采樣寄存器,捕獲收到的串行信號(hào),LSB送入。移位寄存器中的比特位在平時(shí)是全0,當(dāng)其中的值變?yōu)?code>1110,然后在之后進(jìn)行隔點(diǎn)采樣(每兩個(gè)連續(xù)的點(diǎn)取一個(gè)樣本),連續(xù)3個(gè)樣本中,有2個(gè)為0,即可判定是一個(gè)開始信號(hào)(幀間隔符)。類似的,為了檢測幀間隔符分隔符,在繼續(xù)檢測到0001
的模式,然后再之后進(jìn)行隔點(diǎn)采樣,連續(xù)3個(gè)樣本中,有2個(gè)為1,即可判定是一個(gè)分隔符。如果只能檢測到兩個(gè)有效的樣本,噪聲標(biāo)志位(Noise Flag)將會(huì)被置位。
圖x 使用移位器檢測開始信號(hào)和分隔符模式
關(guān)于檢測模式的更細(xì)節(jié)的機(jī)制,可繼續(xù)參見手冊詳述,因同用戶使用關(guān)聯(lián)不大,此處不再贅述。
產(chǎn)生波特率
配置LIN總線的(發(fā)送和接收)波特率,主要設(shè)計(jì)兩個(gè)寄存器:LINFlexD_LINIBRR
和LINFlexD_LINFBRR
,分別對(duì)應(yīng)分頻因子的整數(shù)部分和小數(shù)部分。
- 當(dāng)
LINFlexD_UARTCR[ROSE]=1
(only for UART mode),baudrate = f_clksrc / ( OSR x LDIV ) - 當(dāng)
LINFlexD_UARTCR[ROSE]=0
(for LIN and UART mode),baudrate = f_clksrc / (16 x LDIV)
其中,f_clksrc
是 LINFlexD 的功能時(shí)鐘,在 SCU 外設(shè)模塊中分配時(shí)鐘源。LDIV
是一個(gè)無符號(hào)的定點(diǎn)數(shù),整數(shù)部分存放在20-bit的LINFlexD_LINIBRR
寄存器中,小數(shù)部分存放在4-bit的LINFlexD_LINFBRR
寄存器中。
當(dāng)停用過采樣功能,就不再使用LINFlexD_LINFBRR
寄存器(可清零),此時(shí)LDIV僅使用整數(shù)部分,配置至LINFlexD_LINIBRR
寄存器。
例如:
- When ROSE = 0 (for LIN and UART mode): LDIV = 468.75 d, ipg_baud_clk = 36 MHz, LINIBRR = 468 d, LINFBRR = 12, Baud rate = 36 MHz / (16 × 468.75) = 4.8 K bit/s
- When ROSE = 1 (only for UART mode): LDIV = 5 d, ipg_baud_clk = 80 MHz, LINIBRR = 5 d, OSR = 4, Baud rate = LIN_CLK / (OSR × LDIV) = 80 MHz / (4 × 5) = 4 M bit/s
自動(dòng)同步波特率機(jī)制
若要通過測量LIN通信幀的同步段,可以先隨便寫兩個(gè)波特率發(fā)生寄存器LINFlexD_LINIBRR
和LINFlexD_LINFBRR
,然后設(shè)定寄存器LINFlexD_LINCR1[LASE]=1
啟用自動(dòng)同步機(jī)制。
當(dāng)啟用自動(dòng)同步波特率機(jī)制后,在每個(gè)通信幀的同步間隔段間隔符之后,將會(huì)使用波特率時(shí)鐘源,在LINFlexD_RX
引腳上采樣連續(xù)5個(gè)下降沿的時(shí)間???
喚醒管理機(jī)制
處于休眠中的LIN總線可以由其中任何節(jié)點(diǎn)發(fā)起喚醒請求。節(jié)點(diǎn)將LIN總線信號(hào)強(qiáng)制拉低(保持顯性信號(hào))保持 250us 至 5ms,每個(gè)從機(jī)節(jié)點(diǎn)將會(huì)檢測到喚醒請求(一個(gè)長于 150us 的低電平脈沖),并在釋放顯性信號(hào)的上升沿開始 100ms 以內(nèi)準(zhǔn)備好監(jiān)聽來自總線的命令。主機(jī)在檢測到總線上的喚醒請求后也會(huì)醒過來,待從機(jī)準(zhǔn)備好之后,主機(jī)將發(fā)送幀頭以探查喚醒的源頭和原因。如果在收到喚醒請求后的 150ms 內(nèi),主機(jī)沒來得及發(fā)送幀頭,則原本喚醒總線的從機(jī)節(jié)點(diǎn)可以試著再次發(fā)起一個(gè)新的喚醒請求。
使用LINFlexD產(chǎn)生一個(gè)喚醒請求,可以通過向 DATA0 寄存器寫一個(gè)喚醒字符(0x0)并設(shè)定寄存器位LINFlexD_LINCR2[WURQ]
。當(dāng)寫WURQ寄存器位時(shí),DATA0中的數(shù)就已經(jīng)被送上總線了。
使用LINFlexD檢測LIN總線上的喚醒請求,可以有兩種方式:
- 當(dāng)AUTOWU=1,在休眠模式下,當(dāng)檢測到一個(gè)下降沿,
LINFlexD_LINCR1[SLEEP]
寄存器位由硬件清零(退出休眠模式),LINFlexD_LINCR1[WUF]
標(biāo)志位置位,如果此時(shí)LINFlexD_LINIER[WUIE]
=1,則可以產(chǎn)生一個(gè)中斷,此時(shí) LINFlexD 處于常規(guī)工作模式并準(zhǔn)備接收通信幀。 - 當(dāng)AUTOWU=0,當(dāng)檢測到一個(gè)下降沿,
LINFlexD_LINCR1[WUF]
標(biāo)志位置位,如果此時(shí)LINFlexD_LINIER[WUIE]=1
,則可以產(chǎn)生一個(gè)中斷,此時(shí)需要由軟件決定是否要清零LINFlexD_LINCR1[SLEEP]
寄存器位以返回常規(guī)工作模式。
圖x LIN的喚醒時(shí)序
軟件
YTMicro SDK中包含了LinFlexD的驅(qū)動(dòng)程序,并提供了lin_master
、lin_salve
、lin_slave_filter
等樣例工程。
-
微控制器
+關(guān)注
關(guān)注
48文章
7555瀏覽量
151429 -
通信協(xié)議
+關(guān)注
關(guān)注
28文章
884瀏覽量
40311 -
寄存器
+關(guān)注
關(guān)注
31文章
5343瀏覽量
120383 -
接收器
+關(guān)注
關(guān)注
14文章
2472瀏覽量
71917 -
DIR
+關(guān)注
關(guān)注
0文章
5瀏覽量
7333 -
LIN通信
+關(guān)注
關(guān)注
2文章
8瀏覽量
3793
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
評(píng)論