stm32的swd接口的燒寫協(xié)議是否公開的呢?
按照Arm的手冊,每次轉換發(fā)送方都需要一個TNR但是我觀察JLINK的波形卻沒有那個該死的TNR。
本文引用地址:http://2s4d.com/article/201611/318148.htm手冊中說異步SWD需要,同步不需要-或者相反,但是我沒有找到關于同步異步的描述。
姑且不管他,反正目前忽略掉TNR就能夠讀到該死IDR。
另外JLINK的復位時序很奇怪,大致是
70clk High,0xe79e(注意,SWD是LSB First),
70clk High,0xedb6(這里很奇怪,找不到描述),
70clkHigh,16clk Low,0xa5,
注意這里按照協(xié)議應該是TNR位-但是沒有實際觀測到這個位,
0b100(ACK-OK),0xba01477……
實際測試,不額外增加那個奇怪的0xedb6也能夠照常讀出IDR。
另外要注意,設備端的數(shù)據最哈哦在CLK的下降沿讀取,或者上升沿過后延時1/2bit后讀取。
如果想要深究,可以去sourceforge.net去下載SWD Lib,以及openOCD,兩者對照著來會很方便。
利用好bitband寫程序會很舒服,尤其是處理SWD的位流,一個int32指針跳起來很爽,并且是LSB First的結構。
完全沒有任何障礙的。
另外發(fā)現(xiàn)在讀IDR后,其他的讀寫命令的ACK后面,SWDIO會有兩個bits的緩慢上升波形,
并且在clk的下降沿被Target拉底,按照格式硬套的話,這兩個位應該忽略掉。
目前還沒發(fā)現(xiàn)對于這兩個位的說法。
有的時候能夠看到當JLink讀取信息的最后會把本該由Target發(fā)送的parity拉低,忽略掉。
還有需要注意的是,似乎除了讀IDR,CTRL,ABOUT這三個寄存器外,其他的寄存器讀取都有一個數(shù)據幀的延遲。
比如你發(fā)起第一個讀取貞,讀到的數(shù)據沒有意義。
第二個讀取幀,讀到的是第一次的地址對應的數(shù)據,依次類推。
硬件上,SWDIO的上拉要足夠強,不然上升沿可能不夠陡峭,我現(xiàn)在用的是2.2k,還湊合。
看到SWD LIB的源碼里面是按照8位讀寫,32位讀寫的方式來做的。
也就是說,只要控制好SWCLK,并且能夠保證不丟掉任何SWDIO位信息,用SPI也可以模擬出SWD的時序。
這部分參考了SourceForge的LibSwd項目,該項目是開源的,寫的很嚴謹,代碼風格也很好,強烈大家下來看看。
原始代碼是四個函數(shù),讀,寫,8,32.我歸結到兩個函數(shù),用了bitband結構所以入口就簡單了一些,緩沖區(qū)和位數(shù)即可
int iLibSwdMosi(unsigned int* pBits,unsigned int iLen){unsigned int i;for(i=0;i
看到return(0)你想到了什么?
嘿嘿,本來我是采用定時器來控制clk的,這樣就需要考慮程序運行出錯的返回代碼。
后來發(fā)現(xiàn)這樣很傻,就該成死等了。
這樣就不需要返回異常信息了,但是為了保持形式上的統(tǒng)一,函數(shù)還是帶有返回值的樣子。hoho
這里是延時函數(shù),大寫的量是宏定義
int iLibSwdDelay(unsigned int iDly){unsigned int i,k;for(i=0;i
這里是切換到SWD模式并且讀取IDR的函數(shù)。
int iLibSwdSwitch2SWD(void){unsigned int i;for(i=0;i
如果成功讀取會返回一個指針,這個指針對應的緩沖區(qū)是預先申請好的,由于程序沒有改完,所以這里還不太好看。大家自己發(fā)揮吧。
上面用/**/屏蔽部分就是我說的JLINK波形中很奇怪的地方,屏蔽和不屏蔽在讀取IDR時好像沒什么分別。
不知道JLINK用來做什么的。有知道的么?
有時候為了區(qū)別是Host還是Target送出的bit,可以在時序上做一點修整。
Target總是在Clk的上升沿送出數(shù)據,Host可以在上升沿前面一點送出數(shù)據,
這樣就可以通過示波器來區(qū)別到底是Target還是Host發(fā)送的0
另外,手冊中有提到,在每個數(shù)據幀后面附加幾個額外的clk周期。
JLink的波形上也的確有這樣的體現(xiàn)。不過似乎不是總出現(xiàn)。
暫時沒發(fā)現(xiàn)這塊的影響,可能是通用性的考慮吧
評論