2016年12月22日 星期四

用 cc2540 進行 BLE 通信



BLE, Bluetooth low energy, 一個在藍芽 4.0 時推出的低功耗版本規範
它不相容於標準藍芽, 是一個獨立的規範, 使用相同的頻段但頻寬不同
本篇將利用德州儀器的 cc2540 實作一個裝置, 可以用 BLE 通信
我們將關注在 cc2540 對 cc2540 連接的應用, 和手機對連暫時不考慮
也不會提太多 BLE 規格的東西, 因為我也不是很清楚 (被巴)XD



這玩具最早應該是 zigbee, 由 Chipcon 設計生產的 cc2430
這顆 SoC 單一晶片即可進行 zigbee 傳輸, 而且功耗極低
zigbee 和 BLE 最大的不同是可以組網, BLE 傳承自 BT 的一對一連線
而 zigbee 則可以一對一, 一對多, 還可以轉發
也就是 A 和 C 要通信, 但是 A 看不到 C, 於是 A 可以發給 B, 再由 B 發給 C
依據裝置設定的角色而定, 最新的協議甚至可以跑 IPv6
而且通信採用 Direct Sequence Spread Spectrum (DSSS)
DSSS 把信號展開, 讓每個頻段信號強度跟背景雜訊差不多, 難以被察覺
以前唸書時這東西可是被看好可以取代藍芽, 和 WiMAX 取代 3G 一樣
結果......都死了XD
先搶先贏, 先有佈署可以相容就能拿到單子, 藍芽和 3G 就像既得利益者一樣XD
這些技術最後就留在企業對企業的服務中, 沒法人手一個融入大眾生活中

而 Chipcon 後來被德州儀器買下, 而且德州儀器還同時加入了 zigbee 和藍芽聯盟
印象中看過文章說後來德州儀器的 CC 系列 zigbee 和 BLE 是接腳相容的
可以同一板子直接換料變成另一種協議, 這讓系統廠有後路可退
發現壓寶 zigbee 輸了還可以花小錢全部變 BLE, 聽起來真不錯XD
不過我認為這樣替換是在前幾年規格大戰時期或許有機會用到
現在的話應該已經打完了, 不過嚴格說起來沒有誰輸誰贏
想想應用, 如果是要在大草原上部署大量感測器回傳資料
肯定是用 zigbee 這種可以組成網路的, 若用 BLE 資料就回不來了
或是要多花錢做個 BLE 中繼, 那還不如用原本的 zigbee
所以 BLE 應該沒有機會跑到外面去撒野(?)
而 zigbee 因為可組網的特性, 往往連線後你並沒法知道和你連的裝置在哪
以前 cc2430 時代有個好玩的應用:室內定位, 透過讀取已知裝置的 RSSI
來判斷和裝置之間的概略距離, 有三個裝置就可以定位
不過這功能在 cc2530 以後被取消了, 原因不明
若要我猜可能是組網以後讀取到的 RSSI 是發資料給你的那個節點
它可能是轉發, 不一定是發出這資料的源頭, 這樣自然是沒法評估距離
zigbee 後來也打智慧家庭, 但是因為大多數手機不含 zigbee, 如果要使用
用戶得再買一個收發端, 這裡 BLE 就佔盡先機, 它早已經存在於多數手機中
而且配對時我一定可以知道我正在和誰連, 裝置要進廣播模式, 然後手機配對
zigbee 也有一個單純點對點的配對連線, 叫 RF4CE
幾年前搞 zigbee 時有個 PM 拿了包玩具給我, 德州儀器的 CC2533DK-RF4CE-BA
哇靠, 原廠 EVK 耶, 離開學校後就沒玩過這種高級品
不過這東西我並沒有玩, 因為實在不知道這有什麼應用能做
後來那 PM 也沒再看到, 不知道是調走還是離職
這包就一直放在我這裡, 放到那霧面遙控器都變得黏踢踢了
留著無用丟了可惜還沒有人可以退還也不知有誰需要XD
在 BLE 還沒出來時它沒能攻佔市場入主手持裝置, 現在的話應該是沒機會了
所以現況看起來, 我認為是沿著房子一線畫開, 屋外的就是 zigbee, 屋內的就是 BLE
BLE 沒法出門撒野, zigbee 也沒法進到屋內搶位置, 一切維持原樣沒輸沒贏
當然, 變種產品一定有, 像是展覽上看過藍芽轉發器
stackoverflow 有人貼含 zigbee 的手機
TazTag unveils first Android phone with NFC and ZigBee
但這都是少數, 大多數產品不會這樣做

所以我們在考慮設計玩具時, 就要先知道這玩具有什麼需求, 然後為它找個合適的方案
沒錯, BLE 也是可以做感測網路, zigbee 也可以做隨身設備
但是通常這麼做只是在自找麻煩XD
我這次的計畫就是個標準的隨身裝置, 它其實是升級版的退伍計時器
不過這次不再主打 "退伍計時器", 我已經退伍很久加上教召兩次, 沒必要再做這題目了XD
這次的新玩具有其他的任務在, 不過因為時間因素先只驗證板上功能
把板子上有的主要元件都打通, 然後測試一陣子看有沒有問題, 再決定要怎麼玩
依據退伍計時器的使用體驗, 這類手持裝置和手機一樣都會長時間在口袋或是包包中
尤其在口袋中, 長時間體溫加熱, 拿出來量測的結果通常沒有任何意義
我看過的感測器幾乎沒有不受溫度影響的, 即使是 RTC 這種算時間的都會隨溫度改變
如果封閉在密閉空間突然拿出來要量外面的環境都要等一下
可是手持裝置又不可能掛在外面, 它很可能會受到碰撞或是遺失
另外量測時如果是量測像是箱子內的狀態, 手持裝置丟進去我就看不到狀態了
所以我會需要把裝置和感測器短距離分開, 中間用無線通訊
這是這次計畫的想法, 不過這次我並沒有做感測器, 只點彩色 LED 確認通信正常
我想先了解這玩具的限制, 然後再看看怎麼規劃, 當然, 也不排除之後會打掉重練

這次我做了兩張板子, WT-12 和 WT-13, 這是去年中就產出的板子


WT-12 板子的架構圖:

WT-13 只是 cc2540 透過 UART 接 atmega16u2 而已, 很精簡我就不畫方塊圖了
WT-12 是控制端 (BLE Central), 而 WT-13 是接收端 (BLE Peripheral)
兩張板子都透過 UART 連接兩顆 MCU, 兩張都是 cc2540 當主控, AVR 聽命令辦事
把 LCD 接在 cc2540 上就是看準它有 256K 超大容量可以塞字型
外接 AVR 的原因是為了做一些通信以及精密 GPIO 操作
cc2540 只有 SPI 和 UART 可以和週邊通信, cc2541 才有 I2C
cc2540 應該是來當 HCI 用的, 它有 USB device 可用
不過我能買到的模組只有 cc2540, cc2541 很少見, 沒輒, 只好硬上

cc2540 內包 MCU 是高速變種 8051, 不是傳統版的
前篇玩的 RTD2660 裡的 8051 有 64K 位址空間的限制, 這顆看起來似乎沒有
程式塞了一大堆也沒有要我自己去分頁, 編出來的 hex 檔也只有一個
可能指令集有改過可以完整存取 256K 而不用換頁
它每個指令需要的 clock 數可能也和傳統 8051 不同
前篇 用 AVR 控制 WS2812 LED 已經實驗過, 遇到判斷式會慢很多
所以可能不適合用 GPIO 去操作一些特殊時序的設備, 所以才外接 AVR

這玩具的開發過程不太順利, 吃了不少苦頭
首先是板上的 AVR, 這次很有種的採用 QFN 封裝的 AVR
WT-12 配的是 Arduino 用的 atmega328p

這是 QFN 封裝的 atmega328p, 它的封裝很陰險(?)
四個角都有沒有接腳卻有接地的金屬邊, 焊接時不小心就會和隔壁接腳短路
layout 時若是沒注意, 例如上圖右下往上第一隻腳, 往下拉線剛好經過金屬邊
很容易就焊接在一起, 然後就在那邊抓錯抓老半天!最後是用熱風槍烤上去
然後焊槍再補強

這是 WT-13 上的 atmega16u2

這種才比較像話嘛!這顆第一次上去就會動了, 沒有遇到問題
328p 沒事四角接地幹麻啊, 底下都有 ground pad 了還不夠嗎? 還是說有導角比較好看?
WT-13 開發上問題比較少, 零件少, atmega16u2 就買 Arduino 用的
這顆可能比較多人買, 就不用殺肉了

QFN 封裝的 atmega328p 外面單獨買一顆要 100 多元台幣
買回來還是不能用的, 和兩個不同賣家買結果都一樣, 我搞了好久
似乎是 serial program 的 bit 沒設
板子也有問題, reset 線忘了拉......但是接上後還是沒法燒錄, 然後就暫時放棄
後來看到有人賣這東西

arduino pro mini, 市面上有 TQFP 和 QFN 版
一片才賣 70 圓有找, 用熱風槍拆下來後接上去就會動了, 還附贈電容和晶振呢
後來就學乖了, 單買晶片有困難的就買模組來殺, 比較便宜又可靠, 還附贈週邊零件
電子產品就是看量的, 量少的都比較吃虧

接著是 LCD, 原本我是希望 LCD 在背面, 我也檢查很多次, 但最後還是錯

方向反了...硬把它接回去, 所以下面幾張照片 LCD 下方有有奇怪的接線

這次還實驗加入電源 IC, 手機很早就可以邊充電邊使用, 所以也跟著做
用的是德州儀器的 BQ24032A, 可以隨時插上 AC 就進行充電
隨時移除 AC系統可以持續運轉不會斷電, 設計時以為它會給我定電壓輸出
結果實際輸出是電池當前電壓, 這樣當電壓低於 3.3 時我的系統無法預期會怎樣
只好割銅箔掛個 5V 升壓, 所以這玩具就變厚了...
這類電源管理 IC 有國產的, 弄到 EUTECH (德信) 的 EUP8020 評估板

功能相同, 不過不知道去哪弄這料, 我只要少量應該很難找

剩下的 MP3, SD 卡就和前篇都相同, 細節請參考:

讀取 SD 記憶卡

用 VS1003 播放 MP3

讀取 FAT32 檔案系統

VS1003 輸出段改回抄公板, 聽不出差異, 不過我覺得 "心理上" 感覺較好XD

RTC 升級為高精度的 ds3231, 這個超讚, 拿去別的計畫用過
一個月過去和電腦對時還是正確的, 誤差不到一秒, 這才叫時鐘嘛!
之前用那個 DS1307 一天就能差個幾秒鐘

由於這玩具是要裝盒的, 燒錄接腳不上料以節省空間, 所以這樣燒

還行, 認不到時就用手壓一下就可以了XD

德州儀器的 cc2540 開發時必須使用 IAR 來開發, 裡面包含大量的 binary
不可迴避只能在 windows 上運行, 不過我手邊機器只有兩台 atom 級的有裝 windows
所以這程式大多數的時間是在 ubuntu 上寫, 然後才丟過去編譯
因此我放出來的原始碼在 windows 下如果用文字編輯器打開可能會有亂七八糟的換行
然後 IAR 打開可能會有亂碼但可以編譯過, 這我不想管XD
我就是在 ubuntu 上做, 能正常編譯就好, 剩下的不關我的事XD
編寫時採人體編譯(?), 人體模擬, 移到 IAR 上都修改不多就會動
它這包程式很雜, 曾聽過有人抱怨德州儀器把軟體搞的太複雜, 這次確實的體驗到了
不過它應該是為了客戶, 因為不是所有的客戶都有足夠等級可以翻 code
前篇 RTD2660 原廠的源碼也有類似的現象, 把 macro 一轉再轉
就為了讓客戶可以在程式最上方改變幾個數字就改變特徵
對供應商來說客戶有問題只要叫他照抄, 然後叫他改幾個數字就能打發
而不用浪費時間解釋細節, 但是對於內容有興趣的用戶就得一翻再翻
不斷的用全文搜尋看這定義被塞去哪, 然後還要有足夠的快取可以記下它丟哪
這樣的程式非常難讀, 而且繞了一圈往往發現只是很簡單的功能
所以, 我花了些時間把它拆解, 追蹤, 然後打掉重寫
把分散在各處的檔案集中, 需要的抽出來, 其他全部扔掉
所以用這包去寫以後升級會不容易修改, 不過就算都用官方的也不會容易到哪去
因為官方包如果要升級要連 IAR 一起升, 到頭來還是得一個一個改, 沒差啦

這裡先發放源碼, 以及電路圖

電路圖:WT-12-fix.pdf
原始碼:WT12+13.zip

官方軟體版本要對編譯器才能用, 用的是 cc254x-1.3.2 配 IAR EW8051 8.10.4
軟體哪裡來的不清楚 (轉臉), 這我幫不上忙
源碼中有四個目錄, 我的板子上有 cc2540 和 AVR 兩顆 MCU
因此要刷兩個韌體才能動, 源碼分別放在 cc2540 和 avr 目錄中
host-app 則是 LCD 字型的轉換工具, 後面會說明
doc 是文件, 包含一個 TI 的 BLE 說明, 還有一個對岸寫的教學
TI 的 BLE 說明如果沒做過 BLE 一定要看, 至少有個模糊的概念
我現在就是大概知道它做什麼, 細節不清楚但足夠做軟體

先看 cc2540 目錄, 底下有個 cc254x-1.3.2 目錄, 那是德州儀器官方軟體整理後的
剩下的目錄則是開發各階段的檔, 我做了兩張板, WT-12 和 WT-13
板號後面跟數字代表開發順序, 內容如下:

wt12_1-lcd-only:LCD 剛點起來
wt12_2-simple-peri:把原先德州儀器的 Simple Peripheral 關聯的檔案抽出
wt12_3-1serv-1char:重整 simple-peri, 砍到只剩一個 service 和一個 char
wt12_4-central:修改為 central 模式
wt12_5-cent-ui:central 模式加上 UI
wt12_6-all:整合完成

wt13_1-1serv-1char:把上面 wt12_3-1serv-1char 移除 LCD 後改為 WT-13 用
wt13_2-uart:加上 uart
wt13_3-all:整合完成

IAR 的專案檔 eww 和 ewp 檔都是 XML 檔, 我懶得找 IAR 中的設定界面
所以全部都是用 gedit 去開來改的, 這樣替換路徑比較快不用一個一個選
原先軟體開發時我發現 HAL 對 GPIO 常常不聽使喚
所以我把 Key, LED, LCD 的 HAL 全部移除, 使用 UART, SPI, LCD 時都用自己的

wt12_1-lcd-only:LCD 剛點起來
先移除藍芽 profile 以上的 task, 然後加上一個 task
裡面就只印一串字然後什麼也不做, 結果像這樣:


wt12_2-simple-peri:把原先德州儀器的 Simple Peripheral 關聯的檔案抽出
這個範例雖然叫做 "simple", 但其實寫得很複雜XD
專案目錄下只有 simpleBLEPeripheral.c
但是裡面寫的都是設定並註冊 simpleGATTprofile.c 裡的東西, 這檔案在別的地方
然後把一些用戶手機 UI 可以看到的東西留在 simpleBLEPeripheral.c
實際上工作的檔案是 simpleGATTprofile.c, simpleBLEPeripheral.c 只是被呼叫
雖然寫 "simple" 卻一次註冊了四個服務, 加上一堆 LCD 和 Key 的 HAL
誰會執行, 什麼時候執行, 第一次看絕對不可能知道, 整隻程式看起來就是群魔亂舞
彷彿在說 "你看我檔名取作 simple 就先研究我對吧? 看我怎麼羞辱你" 的樣子XD
執行結果如下:

雖然是原本的程式但還是有拔掉一些東西
所以印出來和原本的不同

wt12_3-1serv-1char:重整 simple-peri, 砍到只剩一個 service 和一個 char
這是我看懂了上面那個妖魔鬼怪以後修改的, 裡面會註冊兩個服務
一個應該是系統必須, 不用理它, 另一個是我的 cmd service, 裡面只有一個 char
app_init() 會設定藍芽, 細節每一行都有註解, 完成後呼叫 cmd_add_service()
cmd_add_service() 會註冊一個 callback, 當遠端有讀寫時就呼叫你
然後再註冊一個 table, 裡面會敘述有哪些服務和特徵 (char)
遠端有設備查詢特徵時, 系統會呼叫讀寫函數, 然後夾帶參數告數你遠端要哪個 char
程式就把數據塞一塞返回, 就這樣而已!
這程式可以用手機測試, 安裝 BLE Scanner: Read,Write,Notify
然後 WT-12 開機, 它就會進廣播, 手機配對後點選服務再點選特徵

在特徵欄點選箭頭指的 W 就可以寫入資料


選擇箭頭指的 byte array, 然後輸入 hex 串, 我這範例只收一個 byte


然後就可以看到 WT-12 上收到特徵值變更

wt12_4-central:修改為 central 模式
這是從上面 wt12_3-1serv-1char 那裡改來的, 不再從 SimpleBLECentral 去改
想也知道從 "simple" 改只是浪費時間XD
Central 模式是扮演連結的角色, 程式內容差很多, 設定檔也不同
專案目錄下 buildConfig.cfg 有修改:

// BLE Host Build Configurations

//-DHOST_CONFIG=BROADCASTER_CFG
//-DHOST_CONFIG=OBSERVER_CFG
//-DHOST_CONFIG=PERIPHERAL_CFG
-DHOST_CONFIG=CENTRAL_CFG
//-DHOST_CONFIG=BROADCASTER_CFG+OBSERVER_CFG
//-DHOST_CONFIG=PERIPHERAL_CFG+OBSERVER_CFG
//-DHOST_CONFIG=CENTRAL_CFG+BROADCASTER_CFG
//-DHOST_CONFIG=PERIPHERAL_CFG+CENTRAL_CFG

表示德州儀器方案設備要扮演什麼角色編譯時就定死了
如果要自由改變身份可能就要把它當成單純的 PHY 來用, 透過 HCI 可能可以
但方法怎麼做我不知道, 這要對藍芽規格有相當程度的熟悉才行
wt12_4-central 做的事情就是一開始延遲啟動
app_init() 呼叫 osal_set_event(g_app_task_id, APP_START_DEVICE);
這會等到系統開始調用 app_process_event() 時才會 "啟動" 設備
延後呼叫 GAPCentralRole_StartDevice, 這會註冊兩個函數
一個是 RSSI, 另一是事件:app_event_cb()
當系統有事件時會呼叫這個, 然後我把它寫成全自動的, 不用按鍵輸入, 這樣比較單純
一開始會搜尋裝置, 沒搜尋到就會設定狀態為 AS_IDLE
然後我註冊的 APP_LOOP 如果發現沒搜尋到
就會設定繼續搜尋, 直到找到有為止, 尋找條件是這行:
if (app_find_svc_uuid(0xFFF0, // WT-13 cmd service UUID
尋找我的 WT-13, WT-13 的程式就是 wt12_3-1serv-1char 改過去的
找到了就把它存起來, 然後接著一個一個去連線, 連線函數:
GAPCentralRole_EstablishLink(FALSE, FALSE, addrType, peerAddr);
連上以後系統會發 GAP_LINK_ESTABLISHED_EVENT 給我, 然後我就設定等一秒
為什麼要等? 沒為什麼, 要麼系統忙碌, 要麼協議限制, 都有可能
這是官方範例寫的, 如果不照做會發現異常, 所以就照做就對了
異常大概就是發了請求卻啥也沒回, 然後用有限狀態機去寫程式就會卡死在某個狀態
等完一秒後接著用 GATT_DiscPrimaryServiceByUUID 發請求尋找服務
找到了以後傳回 ATT_FIND_BY_TYPE_VALUE_RSP, 注意這是另一個註冊函數
接著用找到的服務 handler 去找特徵, 用 GATT_ReadUsingCharUUID
找 0xFFF1 這特徵, 這也是我們前面範例寫的
找到以後傳回 ATT_READ_BY_TYPE_RSP, 會再得到一個特徵的 handler
接著把狀態設為 ASS_FOUND, APP_LOOP 迴圈看到這狀態就會發出讀取請求
讀取用 GATT_ReadCharValue, 寫入用 GATT_WriteCharValue
由於 ASS_FOUND 到 APP_LOOP 看到會有延遲所以能動
不要再看到 ASS_FOUND 時立刻發讀寫, 會沒有回應, 要等半秒多, 我已經試過了
讀寫後會收到 ATT_READ_RSP 或 ATT_WRITE_RSP, 然後狀態設為 ASS_DONE
接著 APP_LOOP 看到這個狀態就用 GAPCentralRole_TerminateLink 中止連線
然後繼續嘗試下一個找到的設備, 若都連線完了, 就把搜尋清單重置, 然後重新搜尋
結果:


這種程式就是一個小型的 OS, 同時多個 task 運行, 處理事件後發出請求
然後處理完後結果會用事件發出, task 接收處理後再發請求, 不斷循環

wt12_5-cent-ui:central 模式加上 UI
這個範例只是調整上面那個範例, 把它獨立出去成一個 task:centapp
然後我的 app 註冊函數, 當 centapp 有重要事件時通知我
一些比較細節的事件像是搜尋服務, 搜尋特徵, 這些不要告訴我, 自己做掉
這樣我做 UI 時處理的狀態會比較少

wt12_6-all:整合完成
最後把所有功能加上去, 這個簡單範例又重新變成一條巨龍XD
結果:


WT-13 部份就不再說明了, 那都是 WT-12 做完確定後搬過去的, 只是改一些像是名稱的東西
然後增加彩色 LED 功能, 程式沿用前篇:用 AVR 控制 WS2812 LED

這兩張板子都有用 UART 通訊, 在 cc2540 上使用有些注意事項...
首先是 baudrate, 這是官方文件說明:

晶振是整數的頻率, 弄去 115200 這類 UART 一定會有 error
不過拉高時脈去除可以讓 error 變小, 和電腦通訊還行
這是 AVR 的 UART 說明:


它也是從外部晶振去除, 只是 AVR 時脈較低, 尤其跑 3.3V 時通常只能低於 12MHz
12MHz 還是在危險邊緣, 溫度變化時可能還是會出差錯, 跑 8MHz 會比較保險
這樣低的速度下去除, 產生的 error 會讓電腦識別不出來, 無法使用
所以 AVR 的 UART 要接電腦通常要接一個特別速度的晶振像是 11.0592MHz
不過如果是板上 cc2540 接 AVR, 雙方都是接整數晶振, 都是用整數除頻
那我們並不需要去管桌上型電腦常用的 115200, 只要雙方速度一致即可
所以我這裡設定的是 125000

cc2540:
BAUD_M = 0, BAUD_E = 12
(256 + 0) * 2^12 * 32000000 / 2^28 = 125000

AVR:
UBRR = 5
12000000 / (16 * (5 + 1)) = 125000

還沒完, cc2540 有個省電功能, 如果有定義 POWER_SAVING
它就會在休眠時把 UART 關掉...ffffuuuu
這個我查很久, 後來逐段檢測, 再用一些關鍵詞上網找才發現也有用戶在唉
這顆的硬體似乎沒法 UART 喚醒, 所以睡了, 就再也聽不到了
把 POWER_SAVING 移除即可, 不過這樣就會多吃電
所以我的玩具雖然是 BLE 但一點也不 Low Energy...都是德州儀器!XD

還有, 這顆 SoC 跑 BLE 似乎已經相當吃重了, 實驗發現如果 BLE 收到資料
然後我把資料餵給 AVR, AVR 執行後馬上回應, 一樣會收不到
cc2540 回去處理 BLE 資料似乎有關閉中斷的行為
解法是 AVR 收到後如果沒有做太多事情就要延遲一下, 不要急著回傳
硬塞可是會壞掉的

WT-12 的 LCD 和 OLED 一樣是 128x64, 由深圳晶聯訊生產

11 年來, 我們只做液晶模塊!XD
雖然做久不代表做好, 但這標語有一種 "專注, 精益求精" 的感覺, 還是給力的XD
不過這片面積較大, 原先 OLED 字型放大後感覺不好, 所以重做
這次換找另一家軟體:GLCD Font Creator 1.2.0.0
這是 windows 上的軟體, 但可以在 wine 上面跑, 可以直接把系統字型轉出
然後讓用戶調整轉出的字型, 最後生成像素陣列

不過生成的陣列是縱向排列, 我的 LCD, OLED 都是橫向排列的
所以寫個小程式把它轉過去, 也就是源碼包中的 host-app 下的東西
把上圖選取的文字複製到檔案, 最後一列的換行也要複製
然後執行

./glcdfont-conv ./24x40 24 40 > 24x40.txt

24 是每個字元寬, 40 是每個字元高, 把陣列重新排列, 這樣我原先的軟體就能用

目前 WT-12 裡 UI 部份的軟體寫的不是很好, 用一大堆狀態去判斷
不過這種和通訊相關的軟體就是這樣, 受限於晶片供應商的軟體架構
以及 MCU 受限制的資源, 不是很好搞, 目前還沒想到改進的方法
這一堆狀態判斷有一定的機率會卡死, 目前開發階段會遇到的卡死都解了
但不保證沒遇到的狀態會發生什麼事, 需要花時間想想
板上一次上兩顆 MCU 變成 (異質) 雙核心, 效能沒有雙倍
太快回應還會壞, 這也讓程式增加複雜度, 以後還是盡量避免做這種的板子 (逃避XD)

那個 LCD 跳線對於裝盒子不是很好, 可能會因為振動鬆脫
所以後來又做了一片, 直接反接, 然後拗到零件面



這樣按鈕就沒法使用, 改成拉線到左上角去, LCD 底下填少量熱溶膠固定, 先暫時這樣


背面貼 RTC 電池和 5V 升壓, 這裡有個怪現象, 如果升壓板用雙面膠緊貼電路板
電路板該區域都是接地銅箔且有防焊漆, 沒有任何接點, 不會短路, 但會影響 BLE
只要 BLE 開始連線, 就會重開機, 不知道為什麼, 只要把雙面膠換成泡綿膠
墊高 1mm 而已, 還不是厚的泡綿膠, 這樣問題就消失了
只能說這種 RF 的東西就是很難搞, 所以我不會想去碰 RF 的 layout
那個出了問題我永遠找不到原因

板上有兩個開關, 左邊的是電源, 右邊是背光

背光不自動控制, 全手動, 用戶自己決定, 這比較符合軍用需求, 非必要不開燈
整套系統大概就這樣了


和前代比, 退伍計時器的時間已經差了 50 分鐘了XD



BLE 方案還有另一家

這是 nRF51822, CPU 是 ARM Cortex M0, 性能更好, 但是沒模組版
沒模組版就沒法做自己的玩具, 所以這玩具的優先權非常低, 短期應該不會去碰
德州儀器也拿出更猛的 cc2650, 內包 Cortex M3 作為系統核心
註冊商標 SimpleLink™ Multistandard Wireless MCU
網上說明文件也有以前的範例 Simple Peripheral 等 Simple 系列
RF 的東西怎麼可能 Simple 啊臥槽!
寫 Multistandard Wireless 意思是可以支援多種 RF, 可以是 BLE 或是 zigbee !
而且 cc2650 本身就是雙核心, RF 部份由一顆 Cortex M0 負責
用戶將無可避免的需面對雙核心的平台
可以想見我在這個計畫遇到的問題很可能會重現
而且搭配德州儀器超麻煩的軟體平台, 除非什麼都不改抄公板照著做
不然應該又要被整了XD

6 則留言:

  1. 剛好小弟也在玩BLE。
    不過您真辛苦,做到23時。要是小弟已被家中母老虎叫回去罰做勞務了!

    回覆刪除
    回覆
    1. 母老虎XD 勞務還好, 至少不是跪主機板(?)XD
      沒那麼晚啦, 那是 demo 的時間不是工作時間
      我也沒認識妹子, 沒有人會管我XD

      刪除
  2. 51822可以去找gwell做的模組來用,一樣是郵票孔邊貼板子的。或者淘寶也不少了
    不過nordic的ble玩起來可能不盡興,他把ble相關的部份直接編譯好binary,出廠前就先燒進去了xd,要用就是直接照寫而已。
    然後他的uart用起來有點難過,第九bit竟然不能自己指定xd還有pwm也是timer加event task硬體模擬的,用起來不太舒服。不過他的event task硬體還有功能接腳隨便指定的特性還滿爽的,有些事情可以完全不叫醒cpu就用這些週邊電路自動做完了。
    後來他有出一片新的nrf52832,核心直接上m4,明眼人都知道這針對誰(?),上面抱怨的問題也修掉一些,和傳輸有關的週邊幾乎全納入dma的管轄這點反而讓我覺得他應該出個m0+dma的低階版本(51822也有dma,但是只有rf和spi從模式能享受到)

    回覆刪除
    回覆
    1. >出廠前就先燒進去了xd
      還有這樣的喔XD 可以只燒一部分該不會是 RTOS, 用戶只能裝 task 上去?
      我看這篇:https://read01.com/8a2L3a.html
      這樣看起來 event task 不太像硬體, 比較像是 RTOS 的 task
      聯發科的 LinkIt ONE 也是這樣做的, 用戶只能上傳 app (也就是 task)
      只不過聯發科的是要呼叫函數註冊自己的函數指標來接收事件 (同 TI 方案)
      而 51822 的看起來像是用固定名字的函數來接收事件
      如果真的是這樣那 51822 的會比較難玩, 更難預測會發生什麼事
      我在玩 LinkIt ONE 的 BLE 就是這樣玩輸的XD
      >明眼人都知道這針對誰(?)
      我大膽猜測 TI 下一顆 cc2750 會用 Cortex M7!XD
      >和傳輸有關的週邊幾乎全納入dma的管轄
      這不見得是好事情, 因為在 MCU 的應用中會有需要依據收到的 byte 做不同事情
      像是 pn532 的 i2c 就會在指定 byte 中告知這筆資料多長
      一定要一個一個 byte 去判讀
      uart 協議如果走換行分段的, 像是 AT command, 如果用 DMA 會惹麻煩
      要麼資料不完整, 要麼 buffer 還沒滿資料等老半天沒回來
      如果能讓用戶自己選會比較好, 但這種 API 會更雜亂

      刪除
    2. uart的部份,他說為了相容舊款ic,所以把有dma和沒有dma的兩種uart都裝了一組上去,應該可以避掉這個問題(?),可能兩組一起接收,無d專收短指令和開頭,收到特定開頭就暫時關掉自己的中斷讓有d去收到完發中斷再叫回來處理;或者其他更聰明的辦法。
      i2c也...裝了兩組xd

      預燒的那套library,nordic用的行銷(?)關鍵字是「softdevice」。不過我只是當他普通無線電在用(和他家的無線電ic nrf2401可以通訊),所以拿到一律洗掉這塊xd
      也因為已經洗掉了,所以確定他task event機制是有硬體在做,可以參考ppi章節(內部功能單元的te)和gpiote章節(外部訊號的te)

      記得他在研討會上有秀一招:ram放多個pwm參數,dma負責在收到要求的時候餵資料給pwm單元(52832才有專責pwm),外部接腳設定成觸發事件,內部task event來管控流程,做到按按鈕播放音效但是cpu全程放大假...還是給高手用就好了xd

      忘記說的是,升壓模組看到眼熟的貼紙w

      刪除
    3. >所以把有dma和沒有dma的兩種uart都裝了一組上去
      這種怪方案這輩子第一次看到XD
      有無 dma 這樣混用蠻危險的, 要是資料傳一半斷了就又要死當了XD
      不過這要看硬體, 如果都在同一張板上應該是可以這樣搞
      >task event機制是有硬體在做
      稍微搜尋一下 PPI 全名有找到專利:https://www.google.com/patents/US20140304439
      很快的看過去是可以理解大概在幹麻, 如果我沒有理解錯應該是:
      硬體週邊必須先定義一些事件
      類似設定中斷時我們可以要求週邊在某些情況時要通知我們
      例如:uart 的傳輸完成, 以及接收完成, 這個稱作事件
      而硬體週邊還必須先定義一些事件是接收的
      類似設定暫存器要求週邊做事情, 例如 uart 只要寫入資料暫存器就會觸發傳輸
      這個寫入的觸發就類似接收事件
      Nordic 他們家工程師發現當我們對 MCU 設定中斷觸發時
      有些時候我們往往只是收到後去觸發另一個硬體
      例如收到 uart 發送完成的中斷後
      我們下一步通常就只是再把資料放進資料暫存器觸發下一筆傳輸
      那麼何不讓這些事情自動發生呢?
      所以 PPI 做的事情就是把中斷源直接接去給觸發傳輸信號
      當然, 如果以 uart 來說沒有資料就觸發傳輸是沒有意義的
      所以這些週邊需要再多一些硬體來協助, 像是 GPIO 就做一個 toggle 功能
      這樣就不用把當前值讀出來然後反向, 而是直接硬體反向
      接著把 timer 發的中斷信號接過去, 它就可以自動 toggle
      這種硬體對於 timer, GPIO, PWM 等確實特別好用
      如果是用中斷去寫, 以 uart, i2c, spi 來說用示波器去看
      常常可以發現每筆資料中間間隔有時甚至比傳輸一個 byte 的時間還長
      因為跳進中斷需要時間, 如果還要喚醒 MCU 肯定更久
      不過 PPI 這種玩法如果遇到資料傳輸, 尤其是可變長度或即時內容判斷的
      應該是撈不到任何好處, 因為這類傳輸是沒法自動化的
      PPI 確實是一個事件處理器 (應該說轉發器), 但是是預先規劃好的硬體事件
      而不是我們軟體上可以任意定義的那種 "事件"
      雖然沒有我看到這個詞 "硬體 task event" 時想像中的好XD
      但對於 MCU 應用來說這確實有幫助
      >升壓模組看到眼熟的貼紙w
      就露天某賣家, 賣開發板和模組的XD

      刪除