RTK5RX65Nにシリアル通信など追加

仕事が重なって、凄く忙しく、なかなか趣味のマイコン関係が進まない・・・

「RTK5RX65N」のLCD関係を進めているのだが、ドライバーテンプレートを
自分で作りたいので、デバッグ環境を何とかしたい、このボードには、「PMOD」と
呼ばれる汎用インターフェースがついていて、コネクタも最初から付いている、このコ
ネクタには、SCI9がアサインされているようなので、とりあえず、これでデバッグ
用のシリアル通信を繋げてみた。
最初は、USB経由のシリアル通信で行う事を考えたが、フラッシュの書き換えなどに
USBポートを優先したいのと、切り替えが面倒なので、あえて、別のポートを使った。

俺俺テンプレートドライバーでは、非常に簡潔にインターフェースを定義できるように
工夫してある。
ポートのマッピング、消費電力制御、割り込みなど、雑多な制御は、全てコンパイル時
に行う事が出来るようにしてあり、ポートのマッピングを別の経路に変更したい場合で
も可能なような仕組みを用意してある。
テンプレートの良い所は、内部で、プログラムによって、切り替えをしていないので、
その切り替え等によって生じるオーバーヘッドや余分なメモリを消費せず、最適化され
た状態になる点で、基本的に「#define」を使っていない(プロセッサシリーズの切り替
えでは使っている)ので、プログラムも読みやすくシンプルになっている。

    typedef utils::fixed_fifo<char, 512>  RECV_BUFF;
    typedef utils::fixed_fifo<char, 1024> SEND_BUFF;
    typedef device::sci_io<device::SCI9, RECV_BUFF, SEND_BUFF> SCI;
    SCI     sci_;

SCIの起動は、割り込みレベルと、ボーレートだけでOK!
※現在は、8ビット、1ストップビット固定になっているが、変える必要性を感じない。

    {  // SCI 設定
        static const uint8_t sci_level = 2;
        sci_.start(115200, sci_level);
    }

また、C言語の関数、「printf」が使えるように(C++では使わないが・・)stdio
経由の出力が可能な仕組みを用意してある。
printf では、POSIX の「write」関数に対して、文字列を出力する、この際のディスク
リプタ「stdout」は、通常固定になっているので、「syscalls.c」で実装してある、
「write」関数で、SCI の文字出力に繋げておけばOKとなる。
※「C」の関数から呼ぶ為、「extern "C"」にしてある。

extern "C" {

    void sci_putch(char ch)
    {
        sci_.putch(ch);
    }

    void sci_puts(const char* str)
    {
        sci_.puts(str);
    }

    char sci_getch(void)
    {
        return sci_.getch();
    }

    uint16_t sci_length()
    {
        return sci_.recv_length();
    }
}

※C++の「iostream」も使えるけど、このライブラリをインクルードすると、とてつも
なく多くのメモリを食うので、「common/format.hpp」を用意してあり、このテンプレート
クラスで、「boost::format.hpp」と同等な操作が出来る、このテンプレートは、他に依存
しないように利便性を追求してあり、IEEE754 浮動小数点フォーマットのバイナリーを
デコードできるよう独自の実装を行っている。
※安易に「sprintf」を呼ぶような事をしていない。

gcc 「__attribute__((weak));」は、外部で定義されていれば、その関数を呼ぶが、定義
が無い場合、そのソースに置かれた関数を呼ぶ仕組みで、POSIX 関係の関数を外部で定義
してオーバーライトする事が出来るようになっている、「syscalls.c」にも同様な仕組み
を用意してあり、シリアルの入出力と標準入出力を繋げる仕組みに使っている。

void sci_putch(char ch) __attribute__((weak));
void sci_putch(char ch) { }
char sci_getch(void) __attribute__((weak));
char sci_getch(void) { return 0; }

今回はここまでー、次は頑張ってLCDを動かす・・・