DE0でラジコンカー
   作ってみた

 石井 康寛(いしい やすひろ)
自己紹介
• 本業は組み込みファームウェア技術者
  (μITRON、組み込みLinux等)

• マイコンを使用した電子工作が好き
• Arduinoは去年から触りだしました
• 日本アンドロイドの会神戸支部・プロペラブに
  所属(私自身はあまり活動できてません)

• Twitter : @yishii
• Facebook : facebook.com/ishiiyasu
FPGA経験について


  • ほぼシロウトです。



• 年末年始にやったことを紹介したいと思います。
きっかけ
• たまたま梅田のカフェで鈴木さんと
 FPGAの話していたら、DE0ってボード
 と、本の事を教えてもらった。
FPGAボードで学ぶ
組み込みシステム 開
  発入門を見て
本の目次
•   第1章 FPGAの内部といろいろなFPGAボード

•   第2章 FPGAの回路設計を体験

•   第3章 もう少し進んだ回路設計

•   第4章 波形観測による回路デバッグ

•   第5章 FPGA内蔵CPUを試す

•   第6章 自作周辺回路の接続

•   第7章 いろいろな周辺回路を設計

•   第8章 メモリコントローラの設計

•   第9章 μClinuxの搭載
面白そう!!

• DE0と本かいました。
• DE0はTerasicの通販よりもDigikeyが
 安かったのでdigikeyにて購入。
とりあえず何か作ろう
     →Androidと繋ぐかなー




→ひとまずAndyShieldの
ArduinoをDE0に載せ替えてみよう
AndyShieldの構成


Arduino
               UART
                         BT
 ATMEGA328P
               GPIOとPWM
                    MotorDrv


  PCBはSeeed Studio Fusionにて作成
AndyShieldソフト構成

  制御アプリ

MemoryMapLib           UART/BT

  Arduino PF
                         ADK

GPIO PWM UART
                      Microbridge

MemoryMapLib → github.com/yishii
Android側-AndyLib




夜子まま氏が公開されているAndroid用の
BT接続クワガタロボット用アプリをその
    まま使用させていただく
本を読みつつ、することリストをまとめた(時系列)

• DE0にNiosII/e ソフトマクロCPUを載せる
• NiosIIに周辺機能 pio(GPIO)をつなぐ
• NiosIIに周辺機能UARTをつなぐ
• VerilogでPWMを作成してNiosIIに繋ぐ
• 上記機能をNiosII上のソフトから、Arduino
 API相当にて叩けるようにする

• AndyShieldのソフトをそのまま動かす
構成
                   Main control software

                       MemoryMapLib

                                  Arduino compatible layer



    NiosII Processor

             System Interconnect Fabric

    UART                   PWM
                                            GPIO(4)
    Core                   Core


                        7seg
                        Dec



                                      2ch driver
                                      TB6552F



 Bluetooth
SPP Module
NiosIIを載せる
SOPCビルダーで選ぶだけ。簡単。
GPIOを準備
選ぶだけ。簡単。
UARTをつなぐ
        通信速度や
    ストップビット長などは
    ロジックを小さくする為
     固定のタイプにした。


     これも選ぶだけ。
PWMを繋ぐ(1)
module PWM8(               →SOPCビルダーの周辺機能選択肢に
     input clk,
     input n_rst,
     input [7:0] value,       PWMが無い・・・ので、
     output pwmout);


      wire   [7:0]   counter;   8ビットPWMを作る
      wire   [7:0]   counter_d;
      wire   [7:0]   divider;
      wire   [7:0]   divider_d;


      DFF_8 DFF_8_dividerGen(
           .n_rst(n_rst),
           .clk(clk),
           .d(divider_d),
           .q(divider));


      DFF_8 DFF_8_counterGen(
           .n_rst(n_rst),
           .clk(divider[3]),
           .d(counter_d),
           .q(counter));


      assign divider_d = (n_rst == 1'b0) ? 8'h00 : divider + 8'h01;
      assign counter_d = (n_rst == 1'b0) ? 8'h00 : counter + 8'h01;
      assign pwmout = (n_rst == 1'b0) ? (1'b0) : ((counter <= value) ? (1'b1) : (1'b0));


endmodule
PWMを繋ぐ(2)
                                                PWMをAVALONバスファブリックの
module PWM8_avalon_busif(
        input clk,
        input reset_n,
                                                仕様に合わせたモジュールを作成
        input [1:0] address,
        input write,
        input [7:0] writedata,
        output [7:0] value1,
        output [7:0] value2,



                                                組み込みマイコンのSRAM繋ぐ時の
        output pwmout1,
        output pwmout2);


         wire [7:0] value1_in;



                                                バスっぽい感じ(と思った)
         wire [7:0] value2_in;


         wire write_posedge;
         wire write_1d;


         // generate write posedge


         DFF_1 DFF_1_write_1dgen(
                                                デバッグに役立つかもしれないので
                  .clk(clk),
                  .n_rst(reset_n),
                  .d(write),
                  .q(write_1d));
                                                出力値を7セグにつないでおいた。
         assign write_posedge = ((write == 1'b1) && (write_1d == 1'b0)) ? 1'b1 : 1'b0;


         // latch value1


         DFF_8 DFF_8_value1(
                  .clk(clk),
                  .n_rst(reset_n),
                  .d(value1_in),
                  .q(value1));
         assign value1_in = ((write_posedge == 1'b1) && (address == 2'b00)) ? writedata : value1;
SOPCビルダーでつながった
    なんかうれしい!!
NiosII側ソフトの作成
                         1.Arduino的なAPIで包む

//
// Arduino Modoki Core Module     void analogWrite(int ch,unsigned char value)
//                                {
// Author : Yasuhiro ISHII,2012      IOWR(PWM_AVALON_0_BASE,ch == 0 ? 0 : 1,value);
//                                }
#include "Nios2Arduino.h"
#include <unistd.h>               void digitalWrite(int port,int value)
#include <sys/alt_alarm.h>        {
                                     static unsigned char outdata;
                                     unsigned char d;
void arduinoMain(void)
{                                     d = 1 << port;
   setup();                           if(value){
   while(1){                             outdata |= d;
       loop();                        } else {
   }                                     outdata &= ~d;
}                                     }

int millis(void)                      IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE,outdata);
{                                 }
    return (alt_nticks());
}

void delayMs(int x)
{
   usleep( x * 1000 );
}
NiosII側ソフトの作成
   2.UARTをMemoryMapLibと繋ぐクラス作成
                unsigned char SerialStream::read(void)
                {
                    unsigned char ret = 0;


   UARTは            if(mBufferedStream->size() >= 1){
                    mBufferedStream->pop(ret);
                    }


ファイルI/Oっぽく      }
                    return(ret);


                int SerialStream::write(unsigned char* buff,int len)

リードライトできる       {

                }
                    fwrite(buff,len,1,fp);



 関数が用意されて       void SerialStream::flush(void)
                {
                    mBufferedStream->flush();
                }
    いた          void SerialStream::setInterface(int* s)
                {
                    fp = fopen(UART_0_NAME,"w+");
                    if(fp != NULL){
                         mConnected = true;
                    }
                }




 MemoryMapLib              NiosII UART/BT
AndyShield用の
   スケッチを動かす


• インクルードファイル追加程度
• ほぼそのまま動いた
ビルド・実行

• プログラムがCyclonIII上に生成したメモ
 リーに入らない・・・→SOPCビルダー
 にて、SDRAMを選択してつないだ
ハードの製作
DE0を固定するプラスチック部品はタミヤの工作
    セットとデジットにて購入したもの

DE0のコネ
クタから信
号を引き出
して直結し
   た
完成!

DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519