本實驗室設計了一張板子作多用途使用, 這張板子上有多項新的嘗試
這是本實驗室第一張使用埋孔工藝的板子, 也是第一張整合無線通訊的板子
並且帶有過壓過流和靜電保護, 有實際長時間上線工作, 使用 NUC131 作為主控 MCU
首先發放線路:
wt-25-fixed.pdf
電源部份可以用 Micro USB 給電, 也可以外接 DC 電源座供電, 經過保險絲進入兩組電源
可以短路 J10 讓輸入電源直入系統, 或是選用升壓或降壓晶片再送入系統
選配降壓用 RT7257D, MCU 並不需要這麼多電流, 這是留給 PWM 送給外部設備使用
選配升壓用 MC34063, 這是一個古董方案, 有多家廠商有實做相似產品, 但據說它有個大問題
那就是容易超壓, 容易幹死負載, 現代設計一般不會用這顆, 但它有個優點:耐壓 40V
可以升很高的電壓, 可應用範圍較大, 所以才裝這顆
選定供電後接著是過壓保護 (OverVoltage Protection, OVP), 一共有兩組
這三條供電選一條進系統, 本來只要一組 OVP 即可
但升壓電路我有其他用途, 加上 MC34063 有超壓風險, 所以多一組獨立的 OVP 給它
OVP 需要在供電超過設定的範圍時切斷供電, 因此它有兩個需求
一是耐高壓, 不然自己先炸掉了怎麼保護後方? 另一是具備量測電壓能力
它要知道現在是幾伏特, 要有個電壓參考元件, 簡單的就用稽納二極體 (Zener diode)
但問題是這東西反應比較慢, 所以還要搞個延遲啟動, 然後只把稽納二極體當成電壓比較參考
臥槽, 這整組搞下來零件佔用面積怕是要和整個系統一樣大了, 而且這是類比電路
我沒有本事搞, 所以上網找了一些方案, 最後找到這顆 ETA7014
這個方案只要兩個電阻配置保護電壓, 而且是 SOT23 封裝, 非常小
可以承受 2A 電流, 對於小型系統來說剛剛好, 而且價格便宜, 我找代購從掏寶撈回來
算上服務費運費平均一顆只要 4 元台幣, 超便宜, 這樣我就不用傷腦筋擺平 OVP 問題
這次主控 MCU 選用腳比較少的 NUC131, 現在 IC 都漲價了, 查看以前購買紀錄
這顆現在價格和以前 WT-18 用的那顆 64 隻腳的舊價格相同, 這算漲了不少啊
選這顆主要是為了 CAN bus, 要搞長距離傳輸用, 雖然 485 也可以長距離傳
但要擺平資料碰撞問題, 比較麻煩, CAN 硬體本身就有這些功能, 用起來比較省心
缺點就是一次最多 8-byte, 很少, 傳大量資料必須拆分
本板對外通訊有多種選項, 有線的部份有 CAN 和 UART, 無線的部份有紅外線和 nRF24L01
UART 有兩組, 一組 UART2 連接其他週邊使用, 有過一個轉 3.3V 的準位轉換器
另一組接電腦用, 加一顆 USB serial, 方案選的是 CH340E, 這顆非常屌, 除了封裝很小外
它只需要一顆電容給內部整流用, 沒有其他外部元件, 整合度拉滿, 無敵了XD
而且有良好的 linux 驅動支持, 連續運轉數個月沒遇到問題, 露天對岸賣家出一顆不用 20 元台幣
紅外線就用 GPIO 和中斷刻成, 收發都有做, 收的部份用處理過載波輸出方波的三腳接收器
發的部份就一般 IR LED, 我本地線路是用 FET, 但實際測試後發現 GPIO open drain 即可
所以程式和電路給的是修改過的版本, 照片上會看紅外線接收附近有短路線是正常的
這次無線通訊新增 nRF24L01, 2.4G 收發器, 網上有一堆模組可買, 不過就是要疊在板上
想節省空間就嘗試版載, 選這顆除了因為便宜, 而且門檻較低, 原廠雙面板就能做
它應該沒有太精密的要求, 所以我搞一個試試, 這零件很難買啊
輸出到天線那三顆電感都是特規, 而且要過高頻信號, 要找到那種電感值的料不容易
我在網上看到有人剩少量, 全買下來, 目前手邊庫存大概夠我裝個數十組
電感的 PCB 零件圖給它畫個夾在 0603 和 0402 之間的尺寸, 這樣兩種規格都能上
PCB 天線圖就打開原廠提供的圖一對一照抄XD
這信號品質應該不會一樣, 但測過至少能動, 有達到最低要求標準XD
由於大家線路都抄來抄去, 應該不會差太多, 買現成模組回來殺肉裝上試過也能動
只不過市售模組若是小型的會用上 0402 零件, 那個拆下來很容易失蹤...
這張板有兩種輸入界面, 有六個按鈕和兩個旋轉編碼器
旋轉編碼器用 GPIO 中斷刻成, 兩個電阻拉高, 旋轉時內部金屬片會接地
和旋轉有關的主要有 3 隻腳 A, B, C, C 接地, 當往左轉時 A 會先接地
繼續轉則 B 會接地, 反方向轉則換成 B 先接地, 然後 A 才接地
這編碼器可以偵測往哪個方向轉了幾格, 但無法知道當前旋鈕轉到哪個方向
所以這種編碼器的旋鈕正常不會有刻度, 不過沒有刻度的旋鈕還不好找, 所以我只好裝有刻度的
這張板上有儲存空間, SPI flash 或是 SD 卡二選一, 由於系統預設電壓是 5V
需過一個 3.3V 準位轉換器, 這儲存設備不是規劃來本地儲存資料用, 而是刷 bios 用XD
本地儲存當然可以用, 只是目前我沒有任何計畫有這樣使用, 只有儲存設備需要準位轉換
nRF24L01 雖然是 3.3V SPI 設備但 IO 可以撐 5V, 所以就不過準位轉換直入
這項計畫有一部份是 UI 需求, 使用七段顯示器作為狀態表示, 驅動顯示使用對岸的 TM1637
這顆也是超級便宜, 露天的對岸賣家賣一顆 6 元台幣, 做成模組含顯示一組 30 元台幣有找
不過這晶片廠商看起來感覺是新創公司, 它全系列 IC 有多種通訊方式, 沒有統一
而且有疑似專利迴避的操作, 例如這顆通訊長得像 i2c, 但卻是低位先傳
因此無法使用標準 i2c 硬體去控制, 只能 GPIO 慢慢拉, 須另外刻一個控制程式
雖然控制比較麻煩, 但它功能不錯, 可以輸出七段顯示器, 還可以接受輸入, 執行鍵盤掃描
晶片直接接七段顯示器和按鈕, 沒有額外零件, 也是整合度拉滿的一個方案
七段顯示器我選的是深圳彩麗電子的白光七段顯示器, 這種特殊色的產品一般要訂製
這家有標準品, 露天只有一家有賣, 而且那家集貨週期較長, 通常要兩週......
但白色真的香, 所以還是耐心等待, 目前電路可以支持 2-4 位數七段顯示器
彩麗的 3-4 位數的接腳定義相同, 2 位數的差很多, 不過還是可以用
上圖為四位數和兩位數的接腳定義, 可以把接腳定義向右對齊比較一下, 只須注意正負
四位數的 8, 9 兩腳對到兩位數的 7, 8 兩腳, 這兩腳都是共陽腳, 可以共用
但四位數的 6 腳是共陽腳, 向右對齊後接到兩位數的第 5 腳, 那是負極接腳, 不相容
以我原先畫的線路只能跳線轉接到 TM1637 的 LED 負極接腳 SEG5
如上圖箭頭指出這樣, 七段顯示器右下腳拗彎, 從旁邊拉線把 SEG5 接過來即可
文章開頭附的修改過的電路圖增加 R44, R45 這兩個配置, 如果上件時七段顯示器向右對齊
就可以透過那兩電阻選看是要接四位還是兩位的七段顯示器, 三位數和四位數只差一腳可以共用
我本地線路是沒有畫這兩電阻, 本來只支援 3-4 位數, 後來比較了 2 位數的接腳才改上
然後程式部份顯示數據要換, 因為 bit 分佈不同
選用七段顯示器有一個原因是想做時鐘, 所以板上有畫一顆高精度 RTC:DS3231
可是最後發現其實不需要, 有 CAN bus, 透過有線廣播時間即可, 不需要自己算
另外這顆我找了兩個賣家都缺貨, 目前只能從現成模組殺肉
目前找到比較穩定有貨的是 Raspberry Pi 高精度 RTC 模組, 這個一片一百元台幣上下
TM1637 可以支持 6 位數七段顯示器和兩組鍵盤掃描, 我把四位數給七段顯示器
一位數分給 8 個 LED 燈, 可以作為狀態顯示, 然後一組鍵盤掃描接 5 個按鈕
剩下還有一些簡單輸入, 一個按鈕和 LED 直入 MCU 做更新韌體用, 8 個 PWM 接腳輸出
整張板的設計就這樣
設計完成後就找廠商生產, 這是本實驗室第一次設計有埋孔的板子, 埋孔的意思就是表面看不到的孔
例如這張是四層板, 裡面有的孔只連接第 2 和第 3 層, 表面沒孔, 這種工藝就是埋孔
這是昂貴的工藝, 我在別家 MCU 級模組板看到這種工藝以為這只是加點錢就有, 結果...文末報價!XD
搜尋了一下這工藝, 它和一般四層板一樣有核心板, 板厚由核心板決定, 核心板兩面鋪上膠片絕緣
然後再疊上銅箔, 所以一般的情況第 1,2 層會離得很近, 大概數十個 um, 第 3,4 層也是如此
2,3 層間是核心板比較厚, 不過也有廠商提供客製化改層間厚, 那個可能會加收錢或是只接大單
多層板這裡有影片介紹:内功震爆6层板PCB,了解多层板结构
可以看到他的四層板和六層板層間配置是不一樣的, 四層板是雙面板外貼兩張超薄單面板
而六層板則是三張超薄雙面板加兩個絕緣層夾起來, 由於每層間距不相同, 如果信號需要靠近地的就要注意
設計時軟體看上去只是在下一層, 但現實出來其實隔很遠, 這樣就會出問題
如果是全通孔的板子可以多層加工以後夾起來再一次鑽孔然後電鍍, 可是埋孔工藝就不行
要每層分開鑽孔和電鍍, 變得非常麻煩, 這應該是多收很多錢且時間拉更長的原因
做出來的樣子:
上圖下方紅框處的電路板 layout 內容放在上圖上半, KiCAD 的孔標示只有 net 名稱的是通孔
例如 IC 第 35 隻腳拉出去的 PWM1_1 的通孔就只有標示 net 名稱 PWM1_1
四周其他的都是埋孔, 在 net 名稱上方會標示從哪一層通到那一層, 例如 PWM1_1 右下方的 PWM3
它就是個第三層通到第四層的埋孔, pad 上有兩個顏色環:藍色和棕色, 這是那兩層銅箔標示的顏色
而 PWM3 孔下方的埋孔 PWM1_0 標示 1-4, 雖然孔類型是埋孔, 但 1-4 就是從最上層通最下層
實際上它是個通孔, 所以可以看到上圖下方紅框範圍內有兩個孔, 即是當通孔處理
而紅框範圍內其他的孔就沒有孔的外觀, 被填平了, 所以拿起電路板如果看到這種畫了 pad 卻沒孔的
它就有可能是高級的埋孔工藝, 要小心操作這種板, 因為它是很貴的XD
KiCAD 在出 gerber 時各種孔的鑽孔檔會分開出, 若是雙面板目前的開發版本會出 PTH 和 NPTH
即是有電鍍可通電的孔和沒電鍍的純鑽孔, 以前版本只有有電鍍通孔
所以我用電鍍通孔然後配置其 pad 尺寸等於鑽孔尺寸, 這樣就能做出沒電鍍的純鑽孔
現在不能用這套路了, 它會報錯, 所以以前做的元件圖要改, 而做到有埋孔的四層板以後鑽孔檔就複雜了
它會把所有指定層到另一層的孔都分開出, 例如所有孔從第 1 層到第 2 層的一個檔, 1-3 層的一個檔
把你在電路板上畫的所有孔進行分類, 每個孔都有起始層到目的層, 起始和目的相同的放一個檔
我的板子產出這些檔:
wt-25-front-in1.drl ← 1-2 層的孔
wt-25-front-in2.drl ← 1-3 層的孔
wt-25-in1-back.drl ← 2-4 層的孔
wt-25-in2-back.drl ← 3-4 層的孔
wt-25-NPTH.drl ← 無電鍍通孔
wt-25-PTH.drl ← 有電鍍通孔
發給廠商後因為他們要每層間分別處理, 他們做出工作檔後發給我確認, 他們軟體會輸出成每層鑽孔
例如 1-2 層的孔和 1-3 層的孔以及通孔都會經過第二層, 所以第二層的鑽孔圖必須包含前述三檔案的孔
要進行整併, 而用戶要確認, 確認方法就是用 KiCAD 的 gerber viewer, 把所有檔案讀入
然後開關圖層進行確認, 廠商要確認他們沒有塞錯順序, 如果你同意了最後出來錯了, 那你要背鍋XD
而我的板子做出來後測試都符合設計, 這證明了 KiCAD 可以設計有埋孔的電路板
用戶只要有錢就可以做XD
完成後拿到第一個先測 OVP, 這顆 OVP 有點限制, 它要輸入電壓大於 3.7V 才會開始送電
如上圖, 只給 3.6V 的話只會出 1.6V, 然後電源供應器再往上轉一點就會和輸入電壓相同
接著我們繼續轉, 轉到限制電壓就會輸出 0V, 然後繼續轉到電源供應器上限
如上圖, 擋住高壓, 沒有爆炸, 電壓下降到限制範圍內會恢復供電
接著測 MCU, 先發放源碼:
wt25-src.zip
這次實做兩種 loader, 新唐用的 loader 原理可參考前篇:在 ubuntu 上開發 nuvoton Mini58
首先示範和以前一樣的 uart loader, 放程式進去 flash 的方法相同, 差在 config 有修改
以及需要用按鈕才可更新, 原理前篇已經說明就不再重複, 這裡只記流程:
先改 OpenOCD, 在 src/flash/nor/numicro.c 裡加入這行:
{"NUC131LD2AE", 0x10013100, NUMICRO_BANKS_NUC100(64*1024)},
這樣才能識別這顆 MCU, 接著編譯源碼並燒錄
export PATH=$PATH:/XXX/gcc-arm-none-eabi-4.8.3-2014q1/bin
make
make uart-loader
gcc host-src/update.c -o update
# 到 OpenOCD 目錄
sudo ./bin/openocd -f interface/stlink-v2.cfg -f target/numicro.cfg -s share/openocd/scripts
telnet localhost 4444
接著輸入以下命令:
> reset init
> numicro chip_erase
> numicro write_isp 0x300000 0xFFFFFB3B
> flash write_image erase wt25_uart-loader.bin 0x100000
> reset
完成後電路圖上的 D1 LED 就會開始閃爍, 此時可以透過 uart 發送韌體
接著把預編好的韌體擼進去, 輸入:
./update /dev/ttyUSB0 bin/wt25_evk.bin
完成後就可以看到韌體開始工作, 接著如果要再更新韌體, 須透過按鈕進入 loader
按下電路圖上的 SW5 刷機鈕, 如下圖箭頭指處, 按下後 D1 那顆 LED 會開始閃, 然後輸入命令即可再刷
第二次刷命令相同:
./update /dev/ttyUSB0 bin/wt25_evk.bin
透過 UART 更新的 loader 和以前幾乎一樣, 更新工具也一樣, 只把 flash 尺寸改一下
這次新增另一種 loader: CAN loader, 由於需要配置板子, 我們留到後面說明
接著簡單說明一下源碼組織, 這次源碼是所有和 WT-25 有關聯且可公開的設備全壓成一包
所以內容比較多, 可以打開 makefile 這檔案, 搜尋 # APPs 這串字
這串字開始就是各種應用的 target, 除了兩個 loader 有獨立的 obj 目錄外
其他的應用都共用一個 obj 目錄, 所以同一時間只能編一個 target, 且換 target 時最好先清除
雖然對於週邊的控制我盡量讓它可以重複使用, 正常應該不管哪個 target 編出 object 檔是相同的
但我沒有仔細檢查和測試, 不保證有沒有沒注意到的洞, 畢竟是業餘計畫嘛, 隨便搞搞XD
所以最好經常清除重編, 反正沒幾個檔, 現代處理器一下子就可以編完
各個 target 用到的源碼檔案都寫在該 target 附近, 長得像 xxx_SRC, 應該很容易查找關聯檔案
各應用的主程式命名為 main-xxx.c, UI 段若有的話則命名為 ui-xxx.c
本文將介紹 3 個 target, 直接用 target 名稱做代號: uart2can, uart2conn, evk
第一個說明的是 uart2can, 這最簡單, 如其名, 就是 uart 轉 CAN bus
透過 uart 發送和接受 CAN 資料, 由於功能很少不需要所有零件都上, 這裡附上等效電路:
wt-25_uart2can.pdf
只要把這電路圖裡的零件裝上, 剩下都空著, 裝起來的樣子:
看起來非常空虛XD 接著編譯, 命令:
make uart2can
完成後可以得到 wt25_uart2can.bin, 接著按下刷機鈕然透過 uart 發過去
刷機後接著到源碼 host-src 目錄下下命令:
make
這會做出一個名為 uart-tool 的工具, 接著下命令運行:
$ ./uart-tool /dev/ttyUSB0
2023/12/31 15:45:49 uart rx thread start
setup uart...
接著可以輸入命令, 這是一個互動的程式, 因為 CAN 可以不斷收和發
不能像以往 uart 工具一個命令發出去等回應再發下一個, 因此做成互動程式, 輸入 exit 結束程序
在 uart.c 裡會開一個 thread 去專收 uart 回來的訊息, 所有訊息在 _uart_proc() 裡處理
而程式主迴圈接收使用者從 STDIN 輸入, 在 cmd.c 裡, cmd_loop() 處理所有使用者輸入
當使用者沒輸入時會 timeout, 這時程式會利用空檔去處理週期性的事件
可參考函數 cmd_handle_can_pkt(), 有多處在調用, 有空就檢查
當使用者輸入命令後按下 enter, 輸入的字串會交給 cmd_run() 處理, 所有指令都寫在這裡
這只是一個土砲的處理工具, 沒法像 shell 可以自動完成和使用歷史命令, 這太麻煩
業餘計畫嘛, 隨便搞搞!XD
這最基本款硬體是用來收發 CAN 資料, 若要發資料用這命令:
can-send 7ff 0 1 0
可參考源碼:
sscanf(buf+8, "%x %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx",
&cmsg.id, &cmsg.is_ext, &cmsg.dlc, d, d+1, d+2, d+3, d+4, d+5, d+6, d+7);
意思就是第一個參數 7ff 代表 id, 格式是 %x 即是 hex 數字, 剩下的全是 hex 表示的 byte
後面依序為:是否為延伸 id (目前不支援都填 0), dlc 資料長度, 第 1 個 byte, 第 2 個 byte...
當收到 CAN 訊息時會印出
2023/12/31 12:00:00 R 7ff (1) 00
參考源碼: cmd_handle_can_pkt() 印時間, id, ext (空格), (dlc), 資料
這工具很難用!XD 其實這比較像是範例程式, 應該是用戶把需求寫成程式然後上線使用
這也是我目前的用法, 而不是當工具來使, 要當工具就要有 UI......嗯...聽起來就很麻煩
等我有需要再說, 目前就這樣湊合著用XD 以上就是第一個 target 的主要功能
接著是第二個 target: uart2conn 等效電路:wt-25_uart2conn.pdf
裝起來的樣子:
uart2can 的功能再加上這種通訊, 有紅外線收發, nrf24l01 收發, Serial Flash 讀寫等
編譯命令:
make uart2conn
完成後可以得到 wt25_uart2conn.bin, 接著按下刷機鈕然透過 uart 發過去
接著一樣用 uart-tool 進行操作, 首先是紅外線發射, 在 uart-tool 裡下命令:
cir-send 02 20 80 00 3d bd
依序把要發的 byte 以 hex 方式表示, 空格隔開, 最多 10 個
可以配置發射參數 cir-set-tx, 源碼裡有一個範例:
cir-set-tx 342 171 21 21 21 64 21 39
數字改填整數, 這會對應到 WT-25 韌體裡的 cir-tx.c 最上方那堆配置
unsigned int g_cirtx_pre = 342; /* Preamble count */
unsigned int g_cirtx_prend = 171; /* Preamble End count */
unsigned int g_cirtx_p1_b0 = 21; /* Pulse ON for Bit 0 count */
unsigned int g_cirtx_p1_b1 = 21; /* Pulse ON for Bit 1 count */
unsigned int g_cirtx_p0_b0 = 21; /* Pulse OFF for Bit 0 count */
unsigned int g_cirtx_p0_b1 = 64; /* Pulse OFF for Bit 1 count */
unsigned int g_cirtx_stop = 21; /* End of message count */
unsigned int g_cirtx_max_bit = 8 * MAX_TX_LEN;
這會配置各 bit 的長度, 單位是幾個 38K 的 clock
接收也可以改配置, 但只能改 bit0 和 bit1 的臨界值, 對應到 WT-25 韌體裡的 cir-rx.c
單位是幾個 20us, 因為接收器內含載波偵測, 我們沒法改接收的載波頻率, 只能算時間
輸入命令後:
cir-set-tx 342 171 21 21 21 64 21 39
set cir tx OK
cir-send 02 20 80 00 81 bd
cirtx: OK
cirrx: 02 20 80 00 01
由於收發靠得很近, 發出去的也會收到, 用戶須自行排除重複問題
如上命令, 由於我們在配置裡限制了只能 39-bit, 所以收到只有 5 byte
且最後一個 byte 開頭的 bit 被捨棄了沒有發
接著測試 nrf24l01, 最簡單的命令是這樣下:
nrf-setup
nrf-set-en 1
這兩行完成後 nrf24l01 會進入接收模式, 此時若下 nrf-send 命令會發送資料
完成後立刻切回接收模式, nrf-setup 實際上是執行四個命令:
設置發送位址為 1, 2, 3, 4, 5
設置接收位址為 1, 2, 3, 4, 5
設置收發資料長度為 5 byte
設置使用 RF 第 0 通道
這個一個一個做成指令太囉唆, 直接寫死, 有修改需求的用戶請自己改源碼XD
這會映射到 WT-25 韌體裡的 nrf24l01.c:
nrf24l01_set_tx_addr()
nrf24l01_set_rx_addr()
nrf24l01_set_data_len()
nrf24l01_set_rf_ch()
有需要的用戶自行比對一下, 附上運行範例, 自行理解XD
$ ./uart-tool /dev/ttyUSB0
2023/12/30 19:31:00 uart rx thread start
setup uart...
nrf-setup
set tx addr: 0
set rx addr: 0
set payload: 0
set channel: 0
nrf-set-en 1
set rx: 0
nrf-send 1 2 3 4 5
nrf send data: 0
nrfrx: 55 aa 00 25 ff
最後是 Serial Flash 功能, 這功能沒有做在 uart-tool 裡, 理由是用不到
如前面說, 這是刷 bios 用, 刷的時候要熱風槍幹, 肯定不會拿去做其他事
所以用單獨程式下命令即可, 關聯的程式在 host-src 目錄下的 sfprog.c 和 sfread.c
預設晶片是 W25Q128, 這是海思專案要用的, 編譯方法:
gcc sfread.c -o sfread
gcc sfprog.c -o sfprog
運行範例: 把 sfprog.c 這檔案放進 flash 裡位址 0 的地方
$ ./sfprog /dev/ttyUSB0 sfprog.c 0
I(main):write to flash address 0x0
I(main):open uart...
I(main):setup uart...
I(main):open sfprog.c ...
Chip ID = 000147
stat = 42
erasing 0x0, wait... (stat = 40)
erasing 0x1000, wait... (stat = 40)
erasing 0x2000, wait... (stat = 40)
erasing 0x3000, wait... (stat = 40)
programming 0x3900 ...
I(main):reach file end, exit
接著我們把它讀出來, 從 flash 位址 0 的地方讀出 16 個 1K 大小的區塊:
$ ./sfread /dev/ttyUSB0 x.c 0 16
I(main):open uart...
I(main):setup uart...
I(main):open x.c ...
Chip ID = 000147
reading addr 3c00 ...
比較寫入和讀出檔案:
$ cmp sfprog.c x.c
cmp: EOF on sfprog.c after byte 14677, line 634
可以看到檔案 14677 以後不同, 這是因為要擦除再寫入, 讀出以 1K 為單位
所以多出來的部份就全是 0xFF, 14677 位元以前都是相同的, 表示寫入成功
sfread / sfprog 其實是 uart to spi 工具, 所以可以客製每個命令
以 sfprog 來說, 起始位址若設成 -1 則會執行全片擦除, 有塞一些我覺得會用的功能
可以客製代表全部手刻, 所以會有相容性問題, 這個用戶要自己想辦法XD
目前遇到有些 flash 需要第七隻腳拉高才能寫, 可能要一坨錫把 7 和 8 兩腳幹一起
或是用夾子夾住, 需要一些小動作, 請用戶自行人體感覺一下XD
以上就是第二個 target 的主要功能
接著是最後一個 target: evk
如其名, 評估板, 幾乎全料上, 只有選配的升降壓以及外部觸發部份沒上, 裝起來正面的樣子:
反面:
編譯命令:
make evk
完成後可以得到 wt25_evk.bin, 可以按下刷機鈕然透過 uart 發過去, 但我們要 demo 另一功能
那就是前面提到的第二個 loader: CAN loader
可以透過 CAN bus 更新韌體, 實做了一個類 ISO-15765-2 的傳輸程式
寫在 canmf_rx.c 的 canmf_rx_proc()
因為 loader 程式只有 4K, uart 已經用掉一些, 我只能到處刪減, 最後搞到非常接近 4K
沒有和真正的 ISO-15765-2 設備通信過不知道這樣寫對不對, 內容就和以前說過的一樣
把以前文章直接貼上:
ISO 15765-2 制定單幀以及多幀傳輸, 共有四種資料幀
當走 ISO 15765-2 時, DLC 一律填 8, 不管裡面有多少有效資料
有效資料數量寫在 8-byte 資料中, 所以會佔用 1~2 byte 來挪作 header 用
若是單幀傳輸, 最多 7 個 byte, 資料長度寫在第一個 byte, 後面放資料
若是多幀傳輸, 第一幀前兩 byte 挪作 header, 共 16-bit, 前 4-bit 填 0x1 表示第一幀
後面 12-bit 則是資料長度, 所以最多可傳 4095 bytes
第一幀傳完後對方回流控幀 (flow control frame), 告訴發送端它的狀況
可以是繼續發送, 或是要求等待, 或是接收端緩衝炸了停止傳輸等
若是繼續發送, 接著發送端就開始塞資料, 這時傳的是連續幀 (consecutive frame)
連續幀只佔用一個 byte header, 前 4-bit 填 0x3 表示連續幀, 後 4-bit 是傳輸序號
從 0x0-0xF 不斷循環, 若接收端發現數字沒有連續就是掉資料了
以上這些都有做, 只是最大長度限制為 520 bytes, 然後所有的 timeout 都是 0.5 秒
如果 0.5 秒後沒有再收到資料且資料沒收完, 就清除緩衝重來
編譯命令:
make can-loader
結果:
text data bss dec hex filename
4072 16 2064 6152 1808 wt25_can-loader.elf
只差 8 個 byte 就滿啦! 不能再塞了, 接著一樣用 ST Link v2 配 OpenOCD 燒進去
流程和 uart loader 相同, 完成後發韌體過去就要換方法, 如其名, 叫 CAN loader
肯定得從 CAN bus 發, 由於電腦大多沒有 CAN bus, 所以我需要一張 WT-25 作為轉發 CAN 的界面
就用前面的第一個 target:uart2can 來示範, 如下圖:
電腦接 uart2can, 然後 uart2can 的 CAN 接一條 30 公尺網路線, 網線另一端接給 evk 的 CAN
evk 接充電器, 此時 evk 閃黃燈運行在 can-loader, 然後電腦運行 uart-tool, 下命令:
$ ./uart-tool /dev/ttyUSB0
set-can-id 700 777
fw-update 777 ../wt25_evk.bin
go-app 777
先說明以上三命令功能, set-can-id 是配置這設備收韌體的 CAN ID, 確保我們不會擼錯設備
命令的意思是從 0x700 改成 0x777, 當 flash 被清空了以後程式預設 id 是 0x700
這命令會將 id 寫進 NUC131 裡的 flash, 要斷電重開才會更新, 記得下完命令後斷電重開
接著 fw-update 就把韌體透過 CAN 發過去, 須指定對象 id 以及韌體檔名
最後用戶自己確認過程有沒有問題, 看起來沒問題就下 go-app, 這會遠程讓 loader 切進 APROM
執行我們發送的韌體, 執行結果如下:
$ ./uart-tool /dev/ttyUSB0 2023/12/30 18:08:35 uart rx thread start setup uart... set-can-id 700 777 set device id from 700 to 777... please power-off then power-on device after set can id 2023/12/30 18:09:58 R 778 (2) 03 00 fw-update 777 ../wt25_evk.bin set update target id : 777 sending firmware... send block 0 OK (size=512) INFO block 0 is override by loader, unable to verify send block 1 OK (size=512) block 1 verify OK send block 2 OK (size=512) block 2 verify OK send block 3 OK (size=512) block 3 verify OK send block 4 OK (size=512) block 4 verify OK send block 5 OK (size=512) block 5 verify OK send block 6 OK (size=512) block 6 verify OK send block 7 OK (size=512) block 7 verify OK send block 8 OK (size=512) block 8 verify OK send block 9 OK (size=512) block 9 verify OK send block 10 OK (size=512) block 10 verify OK send block 11 OK (size=512) block 11 verify OK send block 12 OK (size=512) block 12 verify OK send block 13 OK (size=512) block 13 verify OK send block 14 OK (size=512) block 14 verify OK send block 15 OK (size=512) block 15 verify OK send block 16 OK (size=512) block 16 verify OK send block 17 OK (size=512) block 17 verify OK send block 18 OK (size=512) block 18 verify OK send block 19 OK (size=144) block 19 verify OK read end go-app 777 set device id 777 to run app... 2023/12/30 18:11:08 R 778 (2) 02 00
結果:
透過 30 公尺網線遠程佈署韌體成功
can loader 可以配置保存 id 用來識別設備, 若用戶配置了以後忘記了, 可以接上 uart0 到電腦
打開 uart0 配置 baudrate 為 460800, 然後按下 update 鍵切進 can-loader
切入後會印出當前 ID
由於是遠程佈署, 還是做了簡易的校驗, 就把每個 byte 加起來, 加到溢位多的捨棄
最後得到一個 byte 作為校驗值, 程式空間有限, 隨便算算!XD
如上面執行結果, 裡面有一行說明:
INFO block 0 is override by loader, unable to verify
由於新唐的 LDROM 運作策略會取代第一個 block, 所以無法直接讀取驗證
如果硬要讀應該可以用 flash_read() 去撈, 但這樣就要多個不同的判斷式
然後程式空間就超過 4K, 我懶得再想辦法裁剪這 loader 了, 索性不驗了, 我賭它成功XD
evk 和前兩 target 最大的不同就是加上七段顯示器以及旋鈕按鈕, 可以做使用者界面 (UI) 使用
我做了個簡單的功能:顯示時間, 接收和發送 nrf24l01 訊息
上圖的 0000 就是顯示時間 00:00, 時間寫死在程式裡, 只是示範用
接著測試, 把 uart2conn 這 target 配置好 nrf24l01 進入接收狀態後放旁邊
順時鐘旋轉 SW2 一步, 會變這樣:
最上面那排 LED 切到左邊第二個點亮, 表示顯示第二項目, 第二項目為接收訊息
顯示 0 表示收到 0 個訊息, 接著用 uart2conn 下命令 nrf-send 任意發 5 個 byte
它就會加一, 表示收到一個訊息
接著再順時鐘旋轉 SW2 一步, 會變這樣:
最上面那排 LED 切到左邊第三個點亮, 表示顯示第三項目, 第三項目為發送訊息
顯示 0 表示成功發送 0 個訊息, 按下 SW1 會發送一個訊息, 若發送成功會加一, 我們按一下 SW1
它就會加一, 表示成功發送一個訊息, 要成功才會加, 發送失敗不會加, 應該是有沒有收到 ACK
我們可以用行動電源接上 evk 然後每走一步就按一下, 看看可以多遠, 目前測試五公尺內可以穿牆
也就是隔著兩面甚至三面牆, 只要在五公尺內都能收, 五公尺以後就必須要無遮擋才能收
目前我的空間只能測到十公尺, 無遮擋十公尺內都可以收發, 以上就是 evk 的功能測試
evk 是帶 UI 的, 也就是要給人操作的, 人身上可能會有靜電, 那會有啥問題?
看老廝解說!
打火机内的万V高压装置去电一个好的笔记本,会发生什么
网友看我用打火石点电脑,也尝试了一次,结局令人唏嘘
防護好的和不好的就如兩影片示範XD 沒搞好一發幹進去, 直接幹死 CPU, 非常給力XD
測靜電一般用靜電槍打, 那玩具蠻貴的, 網上有報價十幾萬, 所以我找老廝的方案來用
把一個打火槍給拆了
關鍵元件:
它有接地線, 要和它共地幹起來才會最爽(?)XD 如果沒有共地, 實驗發現不一定會跳靜電
所以這兩根線都必須引出, 我把它組裝一下
裡面線要加強絕緣, 不然會在裡面跳電, 這性能挺好的
組裝完成的樣子:
然後測試一下:
會跳, 能用!
接著測試我的 WT-25
看起來是可以喔, 不過有點缺陷, 幹到右邊旋鈕時有時會 reset, 不過 MCU 沒死
不確定是我設計沒問題, 還是歪打正著?XD 反正設備是不會死的, 這樣應該就能放心上線使用了
電的時候只電按鈕和 CAN, 怎麼不電其他的? 這要看應用情境, 一般是電有防護的地方
如果拿靜電槍往 MCU 幹下去還是有可能會死的, 但這樣叫偷襲, 不講武德XD
防護本來就是有限防護, 當有裝外殼的情況正常你應該碰不到 MCU, 測這項目就不合理
以上就是本板設計和測試的全部內容了, 那麼做這樣 30 張有埋孔四層板線寬 6mil 的電路板
究竟要花多少錢呢?
答案是三萬元台幣含稅!
每張攤下來一張一千, 如果我知道這行情, 我會每個專案都開一張雙面板, 這樣加起來可能還沒有一萬...
這張板去年開始規劃, 去年底準備好送廠, 看到報價時我以為多看了一位數, 結果沒有喔, 就是五位數
下巴都掉下來了, 不過當時快過年, 要是再改將會花上大量時間, 而且可能會卡到過年後, 只好硬上
本來是想先做簡單的練習, 然後再做複雜的, 做完這一票, 我應該不會再開這種板了XD
最多四層全通孔, 不要再搞埋孔了, 夭壽!
板子年初回來, 因為項目很多, 這程式拖了很久, 改來改去, 總算搶在年底壓線發出XD
雖然文章後續還會在改, 但程式都驗過了, 不過對於 uart-tool 我還是覺得看起來蠻亂的
這個還想再修改, 但還拿不定主意, 再想想, 沒想到就算了
此專案還有兩個支線計畫還卡著, 所以年底壓線發出的不是全部關聯計畫, 另外兩個比較麻煩還要再等
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。