一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

SEI異步通訊—多摩川協(xié)議支持

先楫半導(dǎo)體HPMicro ? 2024-06-14 08:17 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

賈工 先楫資深 FAE

12年產(chǎn)品研發(fā)經(jīng)驗(yàn),具有變頻器、伺服等工業(yè)產(chǎn)品開(kāi)發(fā)經(jīng)驗(yàn),也負(fù)責(zé)過(guò)激光投影顯示系統(tǒng)開(kāi)發(fā)、AI應(yīng)用開(kāi)發(fā)、PYQT、Linux驅(qū)動(dòng)開(kāi)發(fā)等工作。

1、SEI簡(jiǎn)介

SEI(Serial Encoder Interface)串行編碼器接口,是先楫半導(dǎo)體創(chuàng)新性設(shè)計(jì)的一個(gè)針對(duì)串行絕對(duì)值編碼器通信的外設(shè)。SEI支持同步通信模式與異步通信模式,既能做主機(jī)——從編碼器獲取數(shù)據(jù),又能做從機(jī)——將位置信息以主機(jī)需要的串行協(xié)議發(fā)出。在電機(jī)類應(yīng)用中極大的降低了編碼器相關(guān)開(kāi)發(fā)任務(wù)的難度,同時(shí)以硬件編解碼的方式降低了CPU負(fù)載率,讓CPU有更多算力處理其他任務(wù)。

先楫半導(dǎo)體SDK 1.5.0提供了諸多SEI應(yīng)用的實(shí)例,包括BISS-C、Endat、Hiperface、Nikon、SSI、Tamagawa等串行協(xié)議的主站、從站配置源碼,開(kāi)發(fā)者在sample實(shí)例的基礎(chǔ)上,簡(jiǎn)單的進(jìn)行修改即可應(yīng)用到項(xiàng)目中。

本文以Tamagawa協(xié)議為例,對(duì)SEI在異步通信中用法進(jìn)行講解,同時(shí)對(duì)slave例程進(jìn)行修改,增加對(duì)Tamagawa協(xié)議中EEPROM指令的支持,使讀者對(duì)SEI的用法有進(jìn)一步的認(rèn)識(shí)與了解。

本文中,命令指協(xié)議中主站向從站發(fā)送的命令,從站需要根據(jù)命令內(nèi)容進(jìn)行回復(fù)或執(zhí)行某些操作;指令指SEI引擎執(zhí)行的動(dòng)作。

1.1SEI關(guān)鍵概念

1.1.1數(shù)據(jù)寄存器

數(shù)據(jù)寄存器是SEI收發(fā)數(shù)據(jù)的數(shù)據(jù)存放單元。在通信的接收過(guò)程中,接收到的數(shù)據(jù)會(huì)被存放于數(shù)據(jù)寄存器中;在通信的發(fā)送過(guò)程中,需要向外發(fā)送的數(shù)據(jù)同樣存放在數(shù)據(jù)寄存器中。


SEI共有9組數(shù)據(jù)寄存器,每個(gè)寄存器寬度為32bit。當(dāng)以字節(jié)(8bit)為單位進(jìn)行收發(fā)時(shí),可以只使用數(shù)據(jù)寄存器的bit0~bit7,也可以使用bit0~bit32(或bit0~bit23),此時(shí)SEI引擎會(huì)自動(dòng)將數(shù)據(jù)每8bit為一個(gè)單位,增加起始位、奇偶校驗(yàn)位、結(jié)束位等進(jìn)行收發(fā)。例如有一個(gè)24bit的編碼器單圈位置數(shù)據(jù),接收時(shí)雖然每8bit接收1包,但連續(xù)收到的3包數(shù)據(jù)會(huì)放到同一個(gè)數(shù)據(jù)寄存器內(nèi);發(fā)送時(shí),用戶在數(shù)據(jù)寄存器的bit0~bit23填入數(shù)據(jù),SEI引擎會(huì)自動(dòng)拆包,將bit0~bit7、bit8~bit15、bit16~bit23分別增加起始位、奇偶校驗(yàn)位、結(jié)束位對(duì)外發(fā)出。


數(shù)據(jù)寄存器0用于忽略接收到的數(shù)據(jù)——某些開(kāi)發(fā)者不關(guān)心的數(shù)據(jù)可以使用數(shù)據(jù)數(shù)據(jù)寄存器0進(jìn)行接收;其概念與linux系統(tǒng)下黑洞文件類似。


數(shù)據(jù)寄存器2~數(shù)據(jù)寄存器9為通用數(shù)據(jù)寄存器??梢怨ぷ髟?種模式下:

1)數(shù)據(jù)模式:僅用于存儲(chǔ)數(shù)據(jù);

2)檢查模式:可設(shè)定期待值,例如用戶期待接收到0x17,當(dāng)接收到的寫入該數(shù)據(jù)寄存器的值不為0x17時(shí),可產(chǎn)生傳輸錯(cuò)誤提示;

3)CRC模式:用于收發(fā)數(shù)據(jù)過(guò)程中實(shí)時(shí)計(jì)算CRC值,可通過(guò)設(shè)置CRC多項(xiàng)式與CRC初始值來(lái)設(shè)計(jì)CRC算法,當(dāng)接收數(shù)據(jù)的CRC計(jì)算結(jié)果與實(shí)時(shí)計(jì)算結(jié)果不符時(shí),可產(chǎn)生錯(cuò)誤傳輸提示。

1.1.2命令寄存器

用于接收串行編碼器協(xié)議中的命令數(shù)據(jù)。例如Tamagawa協(xié)議中CF(Control Field)字段為命令,其含義如下圖:

828eea60-29e3-11ef-a655-92fbcf53809c.png82b59b10-29e3-11ef-a655-92fbcf53809c.png82da1602-29e3-11ef-a655-92fbcf53809c.png

可以看到,CF字段內(nèi)的cc0~cc3決定了通信的內(nèi)容,根據(jù)該字段的不同,主機(jī)可以從編碼器中讀取單圈位置數(shù)據(jù)、多圈位置數(shù)據(jù)、報(bào)警信息、操作EEPROM等。

1.1.3命令匹配表

命令寄存器接收到命令后,SEI引擎接收J(rèn)UMP跳轉(zhuǎn)指令,會(huì)根據(jù)命令內(nèi)容在命令匹配表內(nèi)進(jìn)行檢索。找到符合命令的表項(xiàng)后,則跳轉(zhuǎn)至該命令匹配表指向的指令開(kāi)始執(zhí)行。SEI共支持8張命令匹配表,SEI引擎會(huì)以順序方式對(duì)每張命令匹配表的命令進(jìn)行對(duì)比,如果命令匹配表0~命令匹配表6都匹配失敗,則無(wú)條件執(zhí)行命令匹配表7的預(yù)設(shè)指令(回復(fù)/不回復(fù))。

1.1.4指令

SEI引擎共支持8種指令,分為停止、等待、接收、發(fā)送、跳轉(zhuǎn)5大類指令,根據(jù)是否有超時(shí)保護(hù)拓展為8種指令。例如接收指令可分為時(shí)限內(nèi)接收與無(wú)限時(shí)接收,時(shí)限內(nèi)接收在規(guī)定的時(shí)間內(nèi)未收到數(shù)據(jù)會(huì)進(jìn)行報(bào)錯(cuò)處理,無(wú)限時(shí)接收則會(huì)永遠(yuǎn)等待下去。其它時(shí)限內(nèi)發(fā)送與無(wú)限時(shí)發(fā)送等概念,請(qǐng)讀者自行理解。SEI共支持預(yù)設(shè)64條指令。

1.1.5狀態(tài)機(jī)

SEI狀態(tài)機(jī)包括4個(gè)狀態(tài),狀態(tài)的切換只能以0-->1-->2-->3-->0的順序進(jìn)行,每種狀態(tài)的切換條件可由開(kāi)發(fā)者自行定義,例如設(shè)置執(zhí)行完第10條指令后狀態(tài)機(jī)從狀態(tài)0切換到狀態(tài)1。狀態(tài)切換可向外發(fā)送事件信號(hào),開(kāi)發(fā)者可將該信號(hào)拉到其它外設(shè)進(jìn)行觸發(fā),實(shí)現(xiàn)硬件同步;或簡(jiǎn)單的產(chǎn)生一次中斷或DMA事件,使用中斷或DMA進(jìn)行一定的數(shù)據(jù)處理工作。

理解SEI工作的關(guān)鍵就在于以上5個(gè)概念的掌握。其它更多的技術(shù)細(xì)節(jié)需要讀者自行查閱UM手冊(cè)進(jìn)行理解。下面就以這5個(gè)概念對(duì)SEI工作的流程進(jìn)行直觀的舉例描述:

1)從機(jī)開(kāi)始以指令0“接收”狀態(tài)等待主機(jī)發(fā)送CF字段,若接收到數(shù)據(jù),將接收到的指令保存到指令寄存器;

2)例如收到了DATA ID3指令,接收到指令后檢查指令匹配表;

3)順序檢查8張指令匹配表進(jìn)行指令匹配,例如匹配到了指令表1,該指令表內(nèi)描述“收到DATA ID3后執(zhí)行預(yù)設(shè)的64條指令中的指令10”;

4)SEI引擎執(zhí)行指令10,指令10內(nèi)容為“時(shí)限內(nèi)發(fā)送,CF,CF存放于指令寄存器”;

5)SEI引擎執(zhí)行指令11,指令11內(nèi)容為“時(shí)限內(nèi)發(fā)送,SF,SF存放于數(shù)據(jù)寄存器2”;

6)SEI引擎執(zhí)行指令12,指令12內(nèi)容為“時(shí)限內(nèi)發(fā)送,ABS0~ABS2,ABS存放于數(shù)據(jù)寄存器3”;

7)SEI引擎執(zhí)行指令13,指令13內(nèi)容為“時(shí)限內(nèi)發(fā)送,ENID,ENID存放于數(shù)據(jù)寄存器4”;

8)SEI引擎執(zhí)行指令14,指令14內(nèi)容為“時(shí)限內(nèi)發(fā)送,ABM,ABM存放于數(shù)據(jù)寄存器5”;

9)SEI引擎執(zhí)行指令15,指令15內(nèi)容為“時(shí)限內(nèi)發(fā)送,ALC,ALC存放于數(shù)據(jù)寄存器6”;

10)SEI引擎執(zhí)行指令16,指令16內(nèi)容為“時(shí)限內(nèi)發(fā)送,CRC,CRC存放于數(shù)據(jù)寄存器9”;

11)SEI引擎執(zhí)行指令17,指令17內(nèi)容為“結(jié)束,跳轉(zhuǎn)回指令0”;

12)SEI引擎執(zhí)行指令0,指令0內(nèi)容為“接收,等待主機(jī)發(fā)送CF字段,若接收到數(shù)據(jù),將接收到的指令保存到指令寄存器”。

可以看到,通過(guò)以上工作流程的描述,SEI就依靠硬件自動(dòng)完成了數(shù)據(jù)的發(fā)送,響應(yīng)了主機(jī)讀數(shù)據(jù)的需求。CPU只要在合適的時(shí)間點(diǎn)將數(shù)據(jù)更新到數(shù)據(jù)寄存器即可。

2 多摩川協(xié)議簡(jiǎn)介

多摩川編碼器在工業(yè)控制領(lǐng)域廣泛應(yīng)用,本節(jié)簡(jiǎn)單介紹Tamagawa編碼器協(xié)議。

注意,協(xié)議整體架構(gòu)是固定的,但具體到每款編碼器,根據(jù)編碼器精度不同、多圈數(shù)據(jù)位數(shù)不同,協(xié)議的數(shù)據(jù)內(nèi)容需要進(jìn)行微調(diào)。

多摩川編碼器支持向主站提供單圈位置信息、多圈位置信息、報(bào)警信息、復(fù)位操作、EEPROM讀寫操作等,不同操作指令的下發(fā)位于CF字段內(nèi)。下面分別介紹協(xié)議內(nèi)不同指令的具體格式。

具體的,多摩川協(xié)議以2.5M固定波特率進(jìn)行數(shù)通信,數(shù)據(jù)格式8、N、1。

2.1數(shù)據(jù)讀取指令格式

82f7c49a-29e3-11ef-a655-92fbcf53809c.png

數(shù)據(jù)讀取過(guò)程:

1)主機(jī)下發(fā)CF,CF內(nèi)的cc0~cc3為ID0~ID3時(shí),代表讀取編碼器信息;

2)從機(jī)回復(fù)CF,響應(yīng)主機(jī);

3)從機(jī)回復(fù)SF,發(fā)送編碼器狀態(tài)信息(具體有什么狀態(tài)Flag請(qǐng)讀者自行學(xué)習(xí)多摩川編碼器Datasheet);

4)從機(jī)回復(fù)DF0~DF7,即數(shù)據(jù)字段。根據(jù)不同的指令I(lǐng)D,數(shù)據(jù)字段長(zhǎng)度不同,數(shù)據(jù)字段內(nèi)可包含ABS(單圈信息),ENID(固定0x17),ABM(多圈信息),ALMC(報(bào)警信息),不同ID回復(fù)內(nèi)容見(jiàn)下表。

82da1602-29e3-11ef-a655-92fbcf53809c.png

5)從機(jī)回復(fù)CRC,供主機(jī)進(jìn)行數(shù)據(jù)完整性校驗(yàn)。

時(shí)序要求如下,在收到CF后的0.5us時(shí)刻鎖存當(dāng)前位置信息:

833705f6-29e3-11ef-a655-92fbcf53809c.png

2.2EEPROM讀指令格式

83454cf6-29e3-11ef-a655-92fbcf53809c.png

多摩川編碼器為客戶提供了762字節(jié)的EEPROM空間,分為6頁(yè),每頁(yè)包含127個(gè)(0~126)字節(jié)。對(duì)地址127進(jìn)行寫操作可改變操作頁(yè)數(shù)。

1)主機(jī)發(fā)送CF,CF內(nèi)cc0~cc3字段解析為ID D;

2)主機(jī)發(fā)送ADF,代表要讀取當(dāng)前頁(yè)的第ADF個(gè)(0~126)字節(jié)的數(shù)據(jù);

3)主機(jī)發(fā)送CRC,供從機(jī)進(jìn)行數(shù)據(jù)完整性校驗(yàn);

4)從機(jī)回復(fù)CF、ADF;

5)從機(jī)回復(fù)EDF,即主機(jī)需要的數(shù)據(jù);

6)從機(jī)回復(fù)CRC,供主機(jī)進(jìn)行數(shù)據(jù)完整性校驗(yàn)。

2.3EEPROM寫指令格式

835eab06-29e3-11ef-a655-92fbcf53809c.png

1)主機(jī)發(fā)送CF,CF內(nèi)cc0~cc3字段解析為ID 6;

2)主機(jī)發(fā)送ADF,代表要寫入當(dāng)前頁(yè)的第ADF個(gè)(0~126)字節(jié);

3)主機(jī)發(fā)送EDF,代表要寫入的數(shù)據(jù);

4)主機(jī)發(fā)送CRC,供從機(jī)進(jìn)行數(shù)據(jù)完整性校驗(yàn);

5)從機(jī)回復(fù)CF、ADF、EDF、CRC,與主機(jī)下發(fā)內(nèi)容相同,代表寫入成功。

讀寫時(shí)序要求如下:

8362a6de-29e3-11ef-a655-92fbcf53809c.png

3多摩川從站例程介紹

打開(kāi)

sdk_env_v1.5.0\hpm_sdk\samples\drivers\sei\slave\tamagawa\src文件,獲取Tamagawa從站源碼。

/* [1] tranceiver config */

tranceiver_config.mode=sei_asynchronous_mode;

tranceiver_config.tri_sample= false;

tranceiver_config.src_clk_freq=clock_get_frequency(BOARD_MOTOR_CLK_NAME);

tranceiver_config.asynchronous_config.wait_len =0;

tranceiver_config.asynchronous_config.data_len =8;

tranceiver_config.asynchronous_config.parity_enable=false;

tranceiver_config.asynchronous_config.data_idle_high_z =false;

tranceiver_config.asynchronous_config.data_idle_state= sei_idle_high_state;

tranceiver_config.asynchronous_config.baudrate= 2500000;

sei_tranceiver_config_init(BOARD_SEI,BOARD_SEI_CTRL,&tranceiver_config);

設(shè)置SEI工作在異步模式,波特率為2.5M,數(shù)據(jù)格式為8、N、1。以及數(shù)據(jù)線的默認(rèn)狀態(tài)等,這一部分請(qǐng)讀者自行對(duì)照UM手冊(cè)SEI寄存器進(jìn)行解析。

/* [2] data register config */

/* cmd register : recv CF */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order= sei_bit_lsb_first;

data_format_config.word_order= sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI,SEI_SELECT_CMD,BOARD_SEI_CTRL,&data_format_config);

/* data register 4: send SF */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order= sei_bit_lsb_first;

data_format_config.word_order= sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_4, &data_format_config);

/* data register 5: send ABS0 ABS1 ABS2 */

data_format_config.mode=sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order=sei_bit_lsb_first;

data_format_config.word_order=sei_word_nonreverse;

data_format_config.word_len= 24;

data_format_config.last_bit= 23;

data_format_config.first_bit= 0;

data_format_config.max_bit= 23;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_5, &data_format_config);

/* data register 6: send ENID */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order=sei_bit_lsb_first;

data_format_config.word_order=sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_6, &data_format_config);

/* data register 7: send ABM0 ABM1 ABM2 */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order=sei_bit_lsb_first;

data_format_config.word_order=sei_word_nonreverse;

data_format_config.word_len= 24;

data_format_config.last_bit= 23;

data_format_config.first_bit= 0;

data_format_config.max_bit= 23;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_7, &data_format_config);

/* data register 8: send ALMC */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order=sei_bit_lsb_first;

data_format_config.word_order=sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_8, &data_format_config);

/* data register 9: send crc */

data_format_config.mode= sei_crc_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order=sei_bit_lsb_first;

data_format_config.word_order=sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.crc_invert= false;

data_format_config.crc_shift_mode= false;

data_format_config.crc_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

data_format_config.crc_init_value= 0;

data_format_config.crc_poly= 1;

sei_cmd_data_format_config_init

(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_9, &data_format_config);

設(shè)置數(shù)據(jù)寄存器,其中:

1)指令寄存器用于收發(fā)CF;

2)DATA4(數(shù)據(jù)寄存器4)用于發(fā)送SF;

3)DATA5(數(shù)據(jù)寄存器5)用于發(fā)送ABS;

4)DATA6(數(shù)據(jù)寄存器6)用于發(fā)送ENID;

5)DATA7(數(shù)據(jù)寄存器7)用于發(fā)送ABM;

6)DATA8(數(shù)據(jù)寄存器8)用于發(fā)送ALM;

7)DATA9(數(shù)據(jù)寄存器9)用于發(fā)送CRC;

/* [3] instructions */

instr_idx= 0;

/* instr0 : Recv CF */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_RECV_WDG, 0, SEI_DAT_0, SEI_DAT_1, 8);

/* instr1 : halt 1 bit for update */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_HALT, 0, SEI_DAT_0, SEI_DAT_0, 1);

/* instr2 : halt some bits for waiting */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_HALT, 0, SEI_DAT_0, SEI_DAT_0, 6);

/* instr3 : jump to cmd table instr_idx[0] */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_CMD_TABLE_INSTR_IDX0);

/* Data ID0 : 0x02 */

/*instr4 : sendCF */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8);

/* instr5 : send SF */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8);

/*instr6 :send ST(POS) */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_5, 24);

/*instr7 :CRC */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8);

/*instr8 :Jump back to initiate*/

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX);

/* Data ID1 : 0x8A */

/* Reference to instr0 ~ instr8 */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8);/* CF */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8);/* SF */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_7, 24);/* MT */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8); /* CRC */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX);

/* Data ID2 : 0x92 */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8);/* CF */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8); /* SF */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_6, 8);/* ENID:0x17 */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8);/* CRC */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX);

/* Data ID3 : 0x1A */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8);/* CF */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8); /* SF */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_5, 24);/* ST(POS) */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_6, 8);/* ENID:0x17 */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_7, 24);/* MT */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_8, 8);/* ALMC */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8);/* CRC */

sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX);

設(shè)置預(yù)設(shè)指令,其中:

1)指令0用于接收CF;

2)指令1用于延遲0.5us后鎖存位置信息;

3)指令2用于延遲3us滿足時(shí)序要求;

4)指令3用于跳轉(zhuǎn),查找指令匹配表進(jìn)行匹配;

5)指令4~指令表結(jié)束,根據(jù)不同的指令向主機(jī)發(fā)送主機(jī)查詢的信息。

/* [4] command table */

command_table_config.cmd_min_value= 0x02u;

command_table_config.cmd_max_value= 0x02u;

command_table_config.cmd_mask_value= 0xFFu;

command_table_config.instr_idx[0] = 4;

sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_0, &command_table_config);

command_table_config.cmd_min_value= 0x8Au;

command_table_config.cmd_max_value= 0x8Au;

command_table_config.cmd_mask_value= 0xFFu;

command_table_config.instr_idx[0] = 9;

sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_1, &command_table_config);

command_table_config.cmd_min_value= 0x92u;

command_table_config.cmd_max_value= 0x92u;

command_table_config.cmd_mask_value= 0xFFu;

command_table_config.instr_idx[0] = 14;

sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_2,&command_table_config);

command_table_config.cmd_min_value= 0x1Au;

command_table_config.cmd_max_value= 0x1Au;

command_table_config.cmd_mask_value= 0xFFu;

command_table_config.instr_idx[0] = 19;

sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_3,&command_table_config);

設(shè)置指令匹配表,

cmd_min_value、cmd_max_value、cmd_mask_value設(shè)置了指令匹配的模式,請(qǐng)參考UM手冊(cè)查詢具體的含義;instr_idx[0]設(shè)置了如果匹配成功,跳轉(zhuǎn)的目標(biāo)指令。

/* [5] state transition config */

/* latch0 */

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= false;

state_transition_config.instr_ptr_cfg= sei_state_tran_condition_fall_leave;

state_transition_config.instr_ptr_value= 1;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_0_1, &state_transition_config);

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= true;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_1_2,&state_transition_config);

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= true;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_2_3, &state_transition_config);

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= true;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_3_0, &state_transition_config);

state_transition_latch_config.enable= true;

state_transition_latch_config.output_select= SEI_CTRL_LATCH_TRAN_0_1;

state_transition_latch_config.delay= 0;

sei_state_transition_latch_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0,&state_transition_latch_config);

狀態(tài)機(jī)跳轉(zhuǎn)的配置代碼,此處只配置了狀態(tài)0到狀態(tài)1轉(zhuǎn)換的條件為“指令1執(zhí)行完成”,即接收到CF后0.5us的時(shí)間點(diǎn),進(jìn)行狀態(tài)轉(zhuǎn)換,同時(shí)向外生成事件(本例程內(nèi)產(chǎn)生了中斷,中斷內(nèi)對(duì)要發(fā)送的數(shù)據(jù)進(jìn)行了設(shè)置)。

/* [6] sample config*/

sample_config.pos_data_idx= SEI_DAT_5;

sample_config.rev_data_idx= SEI_DAT_7;

sample_config.pos_data_use_rx= false;

sample_config.rev_data_use_rx= false;

sample_config.sample_window= 0x5;

sample_config.sample_once= true;

sample_config.latch_select= SEI_LATCH_0;

sample_config.data_register_select= BIT5_MASK| BIT7_MASK; /* SEI_DAT_5, SEI_DAT_7 */

sei_sample_config_init(BOARD_SEI, BOARD_SEI_CTRL,&sample_config);

sei_set_sample_pos_override_value(BOARD_SEI, BOARD_SEI_CTRL, mock_pos);

sei_set_sample_rev_override_value(BOARD_SEI, BOARD_SEI_CTRL,mock_rev);

/* [7] interrupt config */

intc_m_enable_irq_with_priority(BOARD_SEI_IRQn, 1);

sei_set_irq_enable(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_latch0_event | sei_irq_wdog_event | sei_irq_trx_err_event,true);

采樣設(shè)置(讀取電機(jī)系統(tǒng)內(nèi)的位置信息)與中斷開(kāi)啟,狀態(tài)0到狀態(tài)1實(shí)現(xiàn)狀態(tài)轉(zhuǎn)換時(shí),出發(fā)了sei_irq_latch0_event中斷。

/* [8] enbale sync timer timestamp */

synt_enable_timestamp(HPM_SYNT, true);

/* [9] engine config */

printf("Started sei engine!\n");

engine_config.arming_mode= sei_arming_direct_exec;

engine_config.data_cdm_idx= 0;

engine_config.data_base_idx= 0;

engine_config.init_instr_idx= 0;

engine_config.wdg_enable= true;

engine_config.wdg_action= sei_wdg_exec_exception_instr;

engine_config.wdg_instr_idx= 0;

engine_config.wdg_time= 1000; /* 1000 bits time */

sei_engine_config_init(BOARD_SEI, BOARD_SEI_CTRL,&engine_config);

sei_set_engine_enable(BOARD_SEI, BOARD_SEI_CTRL, true);

看門狗的設(shè)置及使能SEI引擎,看門狗的配置含義請(qǐng)參考UM手冊(cè)。

voidisr_sei(void)

{

uint32_tdelta;

if(sei_get_irq_status(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_latch0_event)) {

sei_clear_irq_flag(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_latch0_event);

sample_latch_tm1= sei_get_latch_time(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0);

mock_pos++;

if(mock_pos> 0x00FFFFFF) {

mock_pos= 0;

mock_rev++;

if(mock_rev> 0x00FFFFFF) {

mock_rev= 0;

}

}

sei_set_sample_pos_override_value(BOARD_SEI, BOARD_SEI_CTRL, mock_pos);

sei_set_sample_rev_override_value(BOARD_SEI, BOARD_SEI_CTRL, mock_rev);

sei_set_data_value(BOARD_SEI, SEI_DAT_4, 0x00);

sei_set_data_value(BOARD_SEI, SEI_DAT_6, 0x17);

sei_set_data_value(BOARD_SEI, SEI_DAT_8, 0x00);

delta= (sample_latch_tm1> sample_latch_tm2) ? (sample_latch_tm1- sample_latch_tm2) : (sample_latch_tm1- sample_latch_tm2+ 0xFFFFFFFFu);

printf("CMD:%#x, SF:%#x, ST:%#x, ENID:%#x, MT:%#x, ALMC:%#x, CRC:%#x, sample_tm1:%u, sample_tm2:%u, sample_interval:%dus\n",

sei_get_command_value(BOARD_SEI, BOARD_SEI_CTRL),

sei_get_data_value(BOARD_SEI, SEI_DAT_4),

sei_get_data_value(BOARD_SEI, SEI_DAT_5),

sei_get_data_value(BOARD_SEI, SEI_DAT_6),

sei_get_data_value(BOARD_SEI, SEI_DAT_7),

sei_get_data_value(BOARD_SEI, SEI_DAT_8),

sei_get_data_value(BOARD_SEI, SEI_DAT_9),

sample_latch_tm1, sample_latch_tm2, delta/ (clock_get_frequency(BOARD_MOTOR_CLK_NAME) / 1000000));

sample_latch_tm2= sample_latch_tm1;

}

if(sei_get_irq_status(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_wdog_event)) {

sei_clear_irq_flag(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_wdog_event);

sei_set_command_rewind(BOARD_SEI, BOARD_SEI_CTRL);

}

if(sei_get_irq_status(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_trx_err_event)) {

sei_clear_irq_flag(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_trx_err_event);

printf("TRX Error!\n");

}

}

SEI中斷設(shè)置,當(dāng)sei_irq_latch0_event中斷發(fā)生時(shí),設(shè)置了向主機(jī)回復(fù)的數(shù)據(jù),滿足多摩川時(shí)序要求,即接收到CF后0.5us時(shí)間點(diǎn)進(jìn)行數(shù)據(jù)設(shè)置。

4 EEPROM指令支持

由于讀寫EEPROM的指令格式與讀取位置數(shù)據(jù)指令格式有區(qū)別,即接收CF后不進(jìn)行鎖存,需要繼續(xù)接收ADF、EDF等數(shù)據(jù),因此整個(gè)SEI指令處理流程上,指令的跳轉(zhuǎn)邏輯變得更復(fù)雜。下圖是在做EEPROM指令支持開(kāi)發(fā)過(guò)程中,繪制的流程圖。

8376968a-29e3-11ef-a655-92fbcf53809c.png

支持EEPROM指令的關(guān)鍵源碼如下:

uint32_teeprom_page= 0;

uint32_teeprom[6][127] = {0};

聲明eeprom地址頁(yè)信息變量與6頁(yè)共762字節(jié)的eeprom數(shù)據(jù)數(shù)組。

/* [2] data register config */

/* cmd register : recv CF */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order= sei_bit_lsb_first;

data_format_config.word_order= sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI,SEI_SELECT_CMD, BOARD_SEI_CTRL, &data_format_config);

/* cmd register : recv ADF */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order= sei_bit_lsb_first;

data_format_config.word_order= sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI,SEI_SELECT_DATA, SEI_DAT_2,&data_format_config);

/* cmd register : recv EDF */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order= sei_bit_lsb_first;

data_format_config.word_order= sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI,SEI_SELECT_DATA, SEI_DAT_3,&data_format_config);

/* data register 4: send SF */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order= sei_bit_lsb_first;

data_format_config.word_order= sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI,SEI_SELECT_DATA, SEI_DAT_4, &data_format_config);

/* data register 5: send ABS0 ABS1 ABS2 */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag=false;

data_format_config.bit_order=sei_bit_lsb_first;

data_format_config.word_order= sei_word_nonreverse;

data_format_config.word_len= 24;

data_format_config.last_bit= 23;

data_format_config.first_bit= 0;

data_format_config.max_bit= 23;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI,SEI_SELECT_DATA, SEI_DAT_5, &data_format_config);

/* data register 6: send ENID */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order= sei_bit_lsb_first;

data_format_config.word_order= sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI,SEI_SELECT_DATA, SEI_DAT_6, &data_format_config);

/* data register 7: send ABM0 ABM1 ABM2 */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order= sei_bit_lsb_first;

data_format_config.word_order= sei_word_nonreverse;

data_format_config.word_len= 24;

data_format_config.last_bit= 23;

data_format_config.first_bit= 0;

data_format_config.max_bit= 23;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI,SEI_SELECT_DATA, SEI_DAT_7,&data_format_config);

/* data register 8: send ALMC */

data_format_config.mode= sei_data_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order= sei_bit_lsb_first;

data_format_config.word_order= sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

sei_cmd_data_format_config_init

(BOARD_SEI,SEI_SELECT_DATA, SEI_DAT_8,&data_format_config);

/* data register 9: send crc */

data_format_config.mode= sei_crc_mode;

data_format_config.signed_flag= false;

data_format_config.bit_order= sei_bit_lsb_first;

data_format_config.word_order= sei_word_nonreverse;

data_format_config.word_len= 8;

data_format_config.crc_invert= false;

data_format_config.crc_shift_mode= false;

data_format_config.crc_len= 8;

data_format_config.last_bit= 7;

data_format_config.first_bit= 0;

data_format_config.max_bit= 7;

data_format_config.min_bit= 0;

data_format_config.crc_init_value= 0;

data_format_config.crc_poly= 1;

sei_cmd_data_format_config_init

(BOARD_SEI,SEI_SELECT_DATA, SEI_DAT_9, &data_format_config);

設(shè)置數(shù)據(jù)寄存器,其中:

1)指令寄存器用于收發(fā)CF

2)DATA2(數(shù)據(jù)寄存器2)用于收發(fā)ADF

3)DATA3(數(shù)據(jù)寄存器3)用于發(fā)送EDF

4)DATA4(數(shù)據(jù)寄存器4)用于發(fā)送SF

5)DATA5(數(shù)據(jù)寄存器5)用于發(fā)送ABS

6)DATA6(數(shù)據(jù)寄存器6)用于發(fā)送ENID

7)DATA7(數(shù)據(jù)寄存器7)用于發(fā)送ABM

8)DATA8(數(shù)據(jù)寄存器8)用于發(fā)送ALM

9)DATA9(數(shù)據(jù)寄存器9)用于發(fā)送CRC

/* [3] instructions */

instr_idx= 0;

/*00*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_RECV_WDG, 0, SEI_DAT_9, SEI_DAT_1, 8);/* Recv CF */

/* jump to cmd */

/*01*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_CMD_TABLE_INSTR_IDX0);/* jump to cmd table instr_idx[0] */

/*02*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_HALT, 0, SEI_DAT_0, SEI_DAT_0, 1); /* halt 1 bit for update */

/*03*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_HALT, 0, SEI_DAT_0, SEI_DAT_0, 6); /* halt some bits for waiting */

/*04*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_CMD_TABLE_INSTR_IDX6);

/* Data ID0 : 0x02 */

/*05*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8); /* CF */

/*06*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8);/* SF */

/*07*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_5, 24);/* ST(POS) */

/*08*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8);/* CRC */

/*09*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX);

/* Data ID1 : 0x8A */

/*10*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8); /* CF */

/*11*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8);/* SF */

/*12*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_7, 24);/* MT */

/*13*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8);/* CRC */

/*14*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX);

/* Data ID2 : 0x92 */

/*15*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8);/* CF */

/*16*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8);/* SF */

/*17*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_6, 8);/* ENID:0x17 */

/*18*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8);/* CRC */

/*19*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX);

/* Data ID3 : 0x1A */

/*20*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8); /* CF */

/*21*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8);/* SF */

/*22*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_5, 24);/* ST(POS) */

/*23*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_6, 8);/* ENID:0x17 */

/*24*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_7, 24);/* MT */

/*25*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_8, 8); /* ALMC */

/*26*/sei_set_instr(BOARD_SEI,instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8);/* CRC */

/*27*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX);

/* Data ID6 : 0x32 */ /*write to eeprom */

/*28*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_RECV_WDG, 0, SEI_DAT_9, SEI_DAT_2, 8); /* ADF */

/*29*/sei_set_instr(BOARD_SEI,instr_idx++, SEI_INSTR_OP_RECV_WDG, 0, SEI_DAT_9, SEI_DAT_3, 8); /* EDF */

/*30*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_RECV_WDG, 0, SEI_DAT_0, SEI_DAT_9, 8); /* CRC */

/*31*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_CMD_TABLE_INSTR_IDX6);

/* Data IDD : 0xEA */ /*read from eeprom */

/*32*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_RECV_WDG, 0, SEI_DAT_9, SEI_DAT_2, 8);/* ADF */

/*33*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_RECV_WDG, 0, SEI_DAT_0, SEI_DAT_9, 8);/* CRC */

/*34*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_CMD_TABLE_INSTR_IDX6);

/*response to write/read eeprom */

/*35*/sei_set_instr(BOARD_SEI,instr_idx++, SEI_INSTR_OP_HALT, 0, SEI_DAT_0, SEI_DAT_0, 1); /* halt 1 bit for update */

/*36*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_HALT, 0, SEI_DAT_0, SEI_DAT_0, 6); /* halt some bits for waiting */

/*37*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8);/* CF */

/*38*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_2, 8); /* ADF */

/*39*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_3, 8);/* EDF */

/*40*/sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8); /* CRC */

/*41*/sei_set_instr(BOARD_SEI,instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX);

以上代碼為根據(jù)流程圖編寫的新指令預(yù)設(shè)內(nèi)容。

/* [4] command table */

command_table_config.cmd_min_value= 0x02u;

command_table_config.cmd_max_value= 0x02u;

command_table_config.cmd_mask_value= 0xFFu;

command_table_config.instr_idx[0] = 2;

command_table_config.instr_idx[6] = 05;

sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_0,&command_table_config);

command_table_config.cmd_min_value= 0x8Au;

command_table_config.cmd_max_value= 0x8Au;

command_table_config.cmd_mask_value= 0xFFu;

command_table_config.instr_idx[0] = 2;

command_table_config.instr_idx[6] = 10;

sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_1,&command_table_config);

command_table_config.cmd_min_value= 0x92u;

command_table_config.cmd_max_value= 0x92u;

command_table_config.cmd_mask_value= 0xFFu;

command_table_config.instr_idx[0] = 2;

command_table_config.instr_idx[6] = 15;

sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_2,&command_table_config);

command_table_config.cmd_min_value= 0x1Au;

command_table_config.cmd_max_value= 0x1Au;

command_table_config.cmd_mask_value= 0xFFu;

command_table_config.instr_idx[0] = 2;

command_table_config.instr_idx[6] = 20;

sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_3,&command_table_config);

command_table_config.cmd_min_value= 0x32u;

command_table_config.cmd_max_value= 0x32u;

command_table_config.cmd_mask_value= 0xFFu;

command_table_config.instr_idx[0] = 28;

command_table_config.instr_idx[6] = 35;

sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL,SEI_CMD_TABLE_4,&command_table_config);

command_table_config.cmd_min_value= 0xEAu;

command_table_config.cmd_max_value= 0xEAu;

command_table_config.cmd_mask_value= 0xFFu;

command_table_config.instr_idx[0] = 32;

command_table_config.instr_idx[6] = 35;

sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_5,&command_table_config);

以上代碼為根據(jù)流程圖編寫的新指令匹配表。

/* [5] state transition config */

/* latch0 */

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= false;

state_transition_config.instr_ptr_cfg= sei_state_tran_condition_fall_leave;

state_transition_config.instr_ptr_value= 2;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_0_1, &state_transition_config);

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= true;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_1_2, &state_transition_config);

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= true;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_2_3, &state_transition_config);

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= true;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_3_0,&state_transition_config);

state_transition_latch_config.enable= true;

state_transition_latch_config.output_select= SEI_CTRL_LATCH_TRAN_0_1;

state_transition_latch_config.delay= 0;

sei_state_transition_latch_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0,&state_transition_latch_config);

/* [6] state transition config */

/* latch1 */

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= false;

state_transition_config.instr_ptr_cfg= sei_state_tran_condition_fall_leave;

state_transition_config.instr_ptr_value= 35;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_1, SEI_CTRL_LATCH_TRAN_0_1, &state_transition_config);

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= true;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL,SEI_LATCH_1, SEI_CTRL_LATCH_TRAN_1_2, &state_transition_config);

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= true;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_1, SEI_CTRL_LATCH_TRAN_2_3,&state_transition_config);

state_transition_config.disable_clk_check= true;

state_transition_config.disable_txd_check= true;

state_transition_config.disable_rxd_check= true;

state_transition_config.disable_timeout_check= true;

state_transition_config.disable_instr_ptr_check= true;

sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_1, SEI_CTRL_LATCH_TRAN_3_0, &state_transition_config);

state_transition_latch_config.enable= true;

state_transition_latch_config.output_select= SEI_CTRL_LATCH_TRAN_0_1;

state_transition_latch_config.delay= 0;

sei_state_transition_latch_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_1,&state_transition_latch_config);

鎖存器0配置為執(zhí)行完指令2(讀取位置信息CF的0.5us鎖存點(diǎn))后進(jìn)行位置鎖存;

鎖存器1配置為執(zhí)行完指令35(操作EEPROM指令CRC后0.5us鎖存點(diǎn))后進(jìn)行EEPROM操作;

voidisr_sei(void)

{

uint32_tdelta;

if(sei_get_irq_status(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_latch0_event)) {

sei_clear_irq_flag(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_latch0_event);

sei_set_data_rewind(BOARD_SEI,SEI_DAT_9);

sample_latch_tm1= sei_get_latch_time(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0);

mock_pos++;

if(mock_pos> 0x00FFFFFF) {

mock_pos= 0;

mock_rev++;

if(mock_rev> 0x00FFFFFF) {

mock_rev= 0;

}

}

sei_set_sample_pos_override_value(BOARD_SEI, BOARD_SEI_CTRL, mock_pos);

sei_set_sample_rev_override_value(BOARD_SEI, BOARD_SEI_CTRL, mock_rev);

sei_set_data_value(BOARD_SEI, SEI_DAT_4, 0x00);

sei_set_data_value(BOARD_SEI, SEI_DAT_6, 0x17);

sei_set_data_value(BOARD_SEI, SEI_DAT_8, 0x00);

delta= (sample_latch_tm1> sample_latch_tm2) ? (sample_latch_tm1- sample_latch_tm2) : (sample_latch_tm1- sample_latch_tm2+ 0xFFFFFFFFu);

printf("CMD:%#x, SF:%#x, ST:%#x, ENID:%#x,MT:%#x, ALMC:%#x, CRC:%#x,sample_tm1:%u,sample_tm2:%u, sample_interval:%dus\n",

sei_get_command_value(BOARD_SEI, BOARD_SEI_CTRL),

sei_get_data_value(BOARD_SEI, SEI_DAT_4),

sei_get_data_value(BOARD_SEI, SEI_DAT_5),

sei_get_data_value(BOARD_SEI, SEI_DAT_6),

sei_get_data_value(BOARD_SEI, SEI_DAT_7),

sei_get_data_value(BOARD_SEI, SEI_DAT_8),

sei_get_data_value(BOARD_SEI, SEI_DAT_9),

sample_latch_tm1, sample_latch_tm2, delta/ (clock_get_frequency(BOARD_MOTOR_CLK_NAME) / 1000000));

sample_latch_tm2= sample_latch_tm1;

}

elseif(sei_get_irq_status(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_latch1_event)) {

sei_clear_irq_flag(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_latch1_event);

uint32_tcmd= sei_get_command_value(BOARD_SEI, SEI_CTRL_1);

if(cmd== 0x32u) {

uint32_taddr= sei_get_data_value(BOARD_SEI, SEI_DAT_2);

uint32_tdata= sei_get_data_value(BOARD_SEI, SEI_DAT_3);

if(addr== 127) {

eeprom_page= data;

}else{

eeprom[eeprom_page][addr] = data;

}

}elseif(cmd== 0xEAu) {

uint32_taddr= sei_get_data_value(BOARD_SEI, SEI_DAT_2);

sei_set_data_value(BOARD_SEI, SEI_DAT_3, eeprom[eeprom_page][addr]);

}

}

if(sei_get_irq_status(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_wdog_event)) {

sei_clear_irq_flag(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_wdog_event);

sei_set_command_rewind(BOARD_SEI, BOARD_SEI_CTRL);

printf("WDG!\n");

}

if(sei_get_irq_status(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_trx_err_event)) {

sei_clear_irq_flag(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_trx_err_event);

printf("TRX Error!\n");

}

}

在中斷內(nèi),sei_irq_latch0_event分支處理位置鎖存信息;sei_irq_latch1_event根據(jù)收到的指令信息對(duì)eeprom數(shù)組和地址頁(yè)進(jìn)行操作,更新數(shù)據(jù)/設(shè)置回復(fù)數(shù)據(jù)。

5 小結(jié)

相信通過(guò)以上針對(duì)SEI的講解,及對(duì)多摩川協(xié)議、例程代碼的分析與修改,讀者對(duì)SEI有了更深的認(rèn)識(shí),希望開(kāi)發(fā)者可以用好SEI模塊,加速項(xiàng)目開(kāi)發(fā)與落地。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 編碼器
    +關(guān)注

    關(guān)注

    45

    文章

    3811

    瀏覽量

    138133
  • 異步通信
    +關(guān)注

    關(guān)注

    1

    文章

    58

    瀏覽量

    10352
  • 異步通訊
    +關(guān)注

    關(guān)注

    0

    文章

    12

    瀏覽量

    7543
  • 先楫半導(dǎo)體
    +關(guān)注

    關(guān)注

    11

    文章

    251

    瀏覽量

    2688
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    HPM5300系列SEI串行編碼器接口:如何設(shè)置通訊協(xié)議(上)

    01.串行編碼器接口SEI的應(yīng)用場(chǎng)景SEI串行編碼器接口是HPM單片機(jī)獨(dú)創(chuàng)的通信接口外設(shè),可以在同一個(gè)硬件接口上實(shí)現(xiàn)不同類型的串行通信協(xié)議的數(shù)據(jù)收發(fā)。是5300精確位置系統(tǒng)的一部分,可以與系統(tǒng)中的其它外設(shè)協(xié)同工作。主要應(yīng)用場(chǎng)景:
    的頭像 發(fā)表于 12-20 08:17 ?3187次閱讀
    HPM5300系列<b class='flag-5'>SEI</b>串行編碼器接口:如何設(shè)置<b class='flag-5'>通訊</b><b class='flag-5'>協(xié)議</b>(上)

    SEI實(shí)現(xiàn)BiSS-C從機(jī)協(xié)議,發(fā)送TIMEOUT期間CDM如何接收?

    SEI實(shí)現(xiàn)BiSS-C從機(jī)協(xié)議,發(fā)送TIMEOUT期間CDM如何接收?
    發(fā)表于 04-07 11:09

    MODBUS通訊協(xié)議---機(jī)通訊

    、 //************************************************************************************************************* //主題: Modbus協(xié)議--機(jī)
    發(fā)表于 11-11 17:25

    labview支持通訊協(xié)議有哪些?

    請(qǐng)問(wèn)現(xiàn)在想用labview和三菱的Q03UDE CPU基于以太網(wǎng)的通訊,三菱手冊(cè)里面說(shuō)該CUP支持 MC協(xié)議 和套間字通訊方式,請(qǐng)問(wèn)LABVIEW有自帶的這兩種
    發(fā)表于 08-07 14:36

    絕對(duì)式編碼器特點(diǎn)和應(yīng)用

    本文簡(jiǎn)要介紹日本多絕對(duì)式 編碼器 應(yīng)用特點(diǎn)和接口方法,其中重點(diǎn)介紹產(chǎn)品通信協(xié)議和硬件接口電路以及專用的接收芯片AU5561 應(yīng)用方法。
    發(fā)表于 06-16 15:45 ?73次下載
    <b class='flag-5'>多</b><b class='flag-5'>摩</b><b class='flag-5'>川</b>絕對(duì)式編碼器特點(diǎn)和應(yīng)用

    機(jī)器人通訊網(wǎng)絡(luò)的路由協(xié)議的研究

    本文是關(guān)于機(jī)器人通訊網(wǎng)絡(luò)的路由協(xié)議的研究
    發(fā)表于 11-03 18:44 ?33次下載

    存儲(chǔ)硬盤協(xié)議支持

    協(xié)議支持可謂是統(tǒng)一存儲(chǔ)率先受到人們關(guān)注的要素,一直以來(lái)專家都認(rèn)為對(duì)協(xié)議支持能夠給用戶帶來(lái)非
    發(fā)表于 08-02 14:23 ?986次閱讀
    存儲(chǔ)硬盤<b class='flag-5'>多</b><b class='flag-5'>協(xié)議</b><b class='flag-5'>支持</b>

    一主從Modbus通訊協(xié)議的無(wú)線通訊

    該方案可適用于3臺(tái)以上西門子PLC,S7-200或S7-200Smart之間實(shí)現(xiàn)一主從Modbus通訊協(xié)議的無(wú)線通訊
    發(fā)表于 06-04 09:50 ?1.1w次閱讀
    一主<b class='flag-5'>多</b>從Modbus<b class='flag-5'>通訊</b><b class='flag-5'>協(xié)議</b>的無(wú)線<b class='flag-5'>通訊</b>

    編碼器資料

    常用規(guī)格編碼器資料
    發(fā)表于 07-01 15:31 ?14次下載

    世強(qiáng)先進(jìn)與電阻制造商SEI簽署合作協(xié)議

    近日,世強(qiáng)先進(jìn)與SEI(世達(dá)柏科技)簽署合作協(xié)議,SEI授權(quán)世強(qiáng)先進(jìn)代理旗下電阻、電感、多層陶瓷電容等全線產(chǎn)品。
    的頭像 發(fā)表于 08-02 14:07 ?1806次閱讀

    HPM6200系列微控制器PLA實(shí)戰(zhàn)—

    電子發(fā)燒友網(wǎng)站提供《HPM6200系列微控制器PLA實(shí)戰(zhàn)—.pdf》資料免費(fèi)下載
    發(fā)表于 09-19 15:48 ?1次下載
    HPM6200系列微控制器PLA實(shí)戰(zhàn)—<b class='flag-5'>多</b><b class='flag-5'>摩</b><b class='flag-5'>川</b>

    編碼器助力自動(dòng)控制設(shè)備的智能革命

    在當(dāng)今科技飛速發(fā)展的時(shí)代,自動(dòng)控制設(shè)備正以令人矚目的速度改變著我們的生活和工作方式。從工業(yè)生產(chǎn)線上的精密機(jī)械到智能家居中的便捷設(shè)備,自動(dòng)控制技術(shù)無(wú)處不在。而在這場(chǎng)智能革命的背后,編碼器扮演著至關(guān)重要的角色,為自動(dòng)控制設(shè)備的
    的頭像 發(fā)表于 07-18 18:01 ?287次閱讀

    協(xié)議編碼器:助力數(shù)控機(jī)床行業(yè)邁向智能制造

    協(xié)議編碼器:助力數(shù)控機(jī)床行業(yè)邁向智能制造 在當(dāng)今制造業(yè)快速發(fā)展的浪潮中,智能制造已成為數(shù)控機(jī)床行業(yè)的核心發(fā)展方向。而編碼器作為數(shù)控機(jī)床中至關(guān)重要的檢測(cè)元件,對(duì)機(jī)床的精度、穩(wěn)定性和
    的頭像 發(fā)表于 07-18 17:11 ?301次閱讀

    編碼器:助力自動(dòng)化控制系統(tǒng)實(shí)現(xiàn)更精準(zhǔn)的運(yùn)動(dòng)控制

    在當(dāng)今高度自動(dòng)化的工業(yè)生產(chǎn)和先進(jìn)科技領(lǐng)域,精準(zhǔn)的運(yùn)動(dòng)控制是眾多設(shè)備和系統(tǒng)穩(wěn)定、高效運(yùn)行的關(guān)鍵。編碼器作為一種關(guān)鍵的測(cè)量和反饋裝置,正憑借其卓越的性能,在自動(dòng)化控制系統(tǒng)中發(fā)揮著至關(guān)重要的作用,助力實(shí)現(xiàn)更精準(zhǔn)的運(yùn)動(dòng)控制。
    的頭像 發(fā)表于 07-21 16:54 ?74次閱讀

    編碼器助力木工機(jī)械創(chuàng)新發(fā)展

    在木工機(jī)械領(lǐng)域,精度、效率和可靠性是衡量設(shè)備性能的關(guān)鍵指標(biāo)。隨著科技的不斷進(jìn)步,木工機(jī)械也在朝著更加智能化、精準(zhǔn)化的方向發(fā)展。而編碼器作為一種關(guān)鍵的測(cè)量和控制元件,正為木工機(jī)械的創(chuàng)新發(fā)展注入新的活力。
    的頭像 發(fā)表于 07-21 17:17 ?96次閱讀