一、動機
自從2002年擁有第一臺GBA開始到2006年買的NDS,除了在兩上掌機上開發程序之外,一直希望能擴展硬件做一個小車機器人。但由于當時軟硬件知識的匱乏以及動手能力有限,一直沒有進展。
最近無意搜到一款幾年前發布的開源硬件DS brut,這是我目前了解的第二個開源NDS擴展硬件。第一個是DSerial。當時差不多2009年左右非常想買一塊DSerial,可惜人在國內不方便國際郵購。如今這兩個產品都已售罄,而自己感覺DIY的能力應該可以自己做一個以DS brut為基礎的擴展,于是有了本篇博文。
二、背景
NDS硬件擴展主要有兩種方式:(1) slot 1接口擴展 (2) slot 2接口擴展。前者為NDS卡接口,后者為GBA卡接口。slot 1接口只有17根線,而GBA接口則有32根線。兩種方式擴展都有人做。
2.1、Slot 1接口擴展
Slot 1接口擴展主要有DS brut和DSerial。
通過查看DS brut和DSerial的電路圖,可以了解到以下幾個主要信息:
(1)DS brut用的atmega168 8位單片機,
(2)DSerial用的是51系列8位單片機,
(3)兩者都使用NDS的slot 1接口(NDS游戲卡接口),
(4)兩者都使用SPI接口實現單片機和NDS主機的通信,
(5)兩者都沒有使用slot 1接口中的D0至D5數據線作為數據交換(D6,D7為SPI總線上的數據線,即MISO, MOSI),
(6)兩者均使用slot 1接口的3.3V的VCC作為單片機電源,無需額外供電,
(7)兩者均使用CPU內部晶振作為時鐘來源,即都沒使用外部晶振。
2.2、Slot 2接口擴展
在youtube上還有一個人將NDS通過slot 2接口以最簡單的方式接上了Arduino,并實現通信,文章請點擊這里。該方案只使用3根信號線完成通信,方案比較簡單,但功能擴展也相對有限。
另一個擴展方案請點這里。該方案相對復雜,從標題來看,應該是從slot 2接口引出線后通過FTDI,即TTL串口轉USB聯接電腦進行通信。其實方案中只要用了TTL串口,和單片機或嵌入式板子通信就無障礙了,除了通信速率問題外。
三、方案設計
以上這些信息已基本給出NDS硬件擴展的大致方案。從容易性和擴展功能是否強大來看,Slot 2的三線擴展最容易,但功能最弱。DSerial的功能相對強大,但除了購買現成板子外,自己動手制做難度太大,而且51系列CPU開發難度相對Arduino更高。
3.1、基于DS brut的擴展
DS brut由于CPU采用Atmega168,并且提供了兼容Arduino的bootloader(從Lilypad版改良),因此單片機側的軟件開發將會非常容易,IDE和庫以及文檔也非常全面。再加上Atmega AVR系列單片機的最小系統非常簡單,幾乎只需要通電就行。因此,本方案將基于DS brut進行擴展,但不限制NDS卡帶的寬度,可以將單片機外接,因此可以比DS brut有更多的GPIO和其它接口。
以下是DS brut的擴展電路:
從圖1中看以清楚看到除了220歐的R1電阻,發光二極管LED1,以及電源濾波的C1(100nf),沒有別的電子元件。而其中R1和LED1對擴展來說不是必須,也可以去掉。因此,電路非常簡單,外行都可以DIY實現。
原始的DS brut為NDS卡大小,如圖2所示:
3.2、擴展卡制做
考慮到單獨開板的成本,硬件打算簡易DIY。采用現成的NDS卡,但只使用引腳部分,將引腳和上部電路(卡套蓋住部分)用美工刀切斷電路連接,然后分別從每個引腳焊接引線,并從卡的上部引出。如果引線后卡套蓋不住,可考慮將原卡電路板上的芯片去掉(用電烙鐵和吸錫器)。
3.3、Arduino部分制做
由于為了電路簡單,Arduino部分電源將直接引線到NDS Slot 1的3.3V VCC。CPU理論上可以采用Atmega 48/88/168/328 系列。DS brut采用了Atmega168。采用不同的CPU在后續燒寫Arduino前需要改一下Arduino IDE對應的board.txt文件,這主要是因為設置不同的CPU的Operating電壓(CPU的實際運行電壓)需要設置CPU內不同的fuse bit。要實現fuse bit的設置有兩個方法:(1)如果使用Arduino IDE進行bootloader和程序的燒寫,需要改寫Arduino安裝路徑下的board.txt文件,添加相應的profile。(2)如果使用avrdude進行命令行燒寫bootloadert和程序的燒寫則可在命令行添加fuse bit的參數。但不管采用這兩種方法的哪一種,fuse bit的設置參數都應是一致的。而具體設置可以參考Atmega48/88/168/328 的DataSheet文檔查到。
而傳統大部分Arduino開發板采用的是5V電源,本質上Atmega的大部分AVR單片機可支持1.8V至5.5V輸入(具體請參考官網,點這里)。不過輸入電壓和CPU的工作頻率是有一定相關性的,有一篇文章關于這個問題有較詳細的說明(請點這里)。Any way, 只要我們的Atmega單片機能夠用3.3V驅動就可以了。
這里有一篇文章清楚介紹了如何設置Atmega328的fuse bits以運行電壓在3.3V上工作,給出了具體實現過程:ATmega328 Fuse Bit Setting for 3.3V Vcc。
電壓問題解決后,接下來就是Arduino的bootloader。DS brut定制了一個bootloader。跟據其readme文件說明,應該相對于Arduino的bootloader只是更改了一下WatchDog部分代碼而以。另外DS brut是采用CPU內部晶振作為振蕩源,和Lilypad一樣。因此懷疑bootloader也是按Lilypad的版本改的,這部分我未驗證。
關于Arduino環境中boards.txt文件(路徑為:arduino版本號/hardware/arduino/boards.txt)的各個部分的解釋可以參考這個官方文檔:Bootloader Development。
avrdude不像Arduino先燒bootloader,然后通過bootloader用串口燒寫應用程序。avrdude是個全功能的AVR燒寫軟件,可以燒寫所有程序,包括bootloader,不過需要一個燒寫硬件,如STK500或Smart ISP programmer。兩種方式各有優缺點,具體可以跟據自己手上的現成硬件進行選擇。avrdude的使用可以參考這篇官方教程:AVR Tutorial。
燒寫bootloader的方式,DS brut給出的是采用avrdude。而本方案將采用更方便的Arduino對燒,即需要另一個Arduino成品燒寫無bootloader的Atmega單片機CPU。這篇From Arduino to a Microcontroller on a Breadboard 給出了具體方案,同時這篇文章也給出了如何用另一個Arduino上傳編譯好的程序到獨立的CPU的方法。當然如果你有ISP燒寫工具,也可以直接燒寫,可參考這篇文章:Minimal Arduino with ATmega8,兩篇文章都給出了修改Arduino IDE的boards.txt文件的相關信息。用Arduino給CPU燒寫bootloader和上傳程序的接線圖請見圖3和圖4。
3.4、Arduino和NDS通信設計
Arduino和NDS通信通過SPI接口完成。Arduino部分對SPI編程實現非常方便,IDE內部的有庫直接支持,直接使用即可。示例代碼可以參考DS brut的dsbrut_arduino.txt文件。
NDS部分則相對復雜一些,需要寫驅動代碼。當然DS brut也已經提供了,分別為uart, spi, brut部分。也可以參考源碼。NDS部分的編譯好的程序需要放到Slot 2接口的燒錄卡上運行,因為Slot 1已用來擴展。NDS部分的程序開發可采用DevkitPro。libnds等庫也都非常實用,可以快速開發實現功能。另外,如果NDS程序涉及到FAT文件讀寫別忘了打DLDI補丁就行。
NDS端的驅動部分代碼可以預先編譯成庫,并將頭文件和庫文件分別放到devkitARM對應的目錄里,方便以后使用。
另外DS brut提供了Demo Project。這個section的詳細內容需要到實現方案后再能詳述。至此先這樣。
四、應用
采用本方案實現NDS擴展,對于擴展出來的單片機端更新程序也方便,對于NDS端的開發和以往一樣。應用實例基本上所有單片機能做的這個方案都可以實現。另外還有以下幾個主要優點:
(1)NDS的主CPU為32位68MHz的ARM 9,處理能力比單片機更強,可以處理一些由單片機傳回來的較為復雜的數據和運算,
(2)NDS端的程序在Slot 2,可以使用大容量的SD卡作為數據存儲,
(3)NDS擁有WiFi,可以聯網,有更多開發的可能性,比如遠程控制,無線數據傳輸,
(4)NDS擁有兩個LCD,可以顯示很多信息,其中一個可觸摸,
可以實現以下幾個應用:
(1)把NDS當作電腦的游戲手柄,或電腦鍵盤
(2)帶LCD狀態顯示的智能小車,可無線遙控
(3)通過NDS控制各種外設,如用觸摸屏控制4*4*4,或8*8*8的LED立方顯示任意圖案
(4)太多了...
有空我將實現本方案,敬請期待!