2009年5月アーカイブ

 今日はコード圧縮の続き。やっている途中で LCD の初期化に失敗する理由がわかった。時間待ちの関数の中の for のダミーループが最適化で無くなっていた orz。for で使う変数を volatile 宣言し、時定数を調整するとオリジナルのソースで問題なく表示できるようになった。本当はオシロを引っ張り出してきて波形を見ながら調整したほうが良いのだが、仕事じゃないし、良いことにしよう (^^;

 IO レジスタのアクセスに構造体を使うのをやめてコードの圧縮も完了。H8 はメモリ間接のアドレッシングで論理演算が出来ないらしく、結構手間取る。ソースはかなり見づらくなったが、1bit 操作するだけで 16byte も使われてはかなわない。
 結局 1K 弱のコードから 100byte 程度削った。

 切のいいところまでやってしまって、今日も 30分の時間オーバー。

 明日は表示部を仮fix 予定。次はいよいよカウンターを使ってパルス間の周期測定だ。

-----
 こういうことをするのなら、アセンブラを使いたいところだが、H8 のアセンブラは未経験。手を広げすぎてプロジェクト自体が収束しなくては本末転倒。

 今日はコード圧縮。40分ほどかけて IOレジスタへの構造体アクセスを外したあと、動かしてみると、動かない (^^;。調べて行くと、どうやら LCD の初期化に失敗している模様。

 やめるにやめられなくなり、時間を延長して調べて行くと、初期化の一番最初のタイミングが早すぎる模様。このままやっていくとエンドレスになりそうなので 40分ほどオーバーしたところ作業中止。

 せっかく変更したコードをほとんど戻してしまった。やっぱり不具合はひとつずつつぶし、変更は一歩一歩確実にいくべきだったか。
 昨日作ったソースを見直してから動かしてみると...、動かない (; ;)。見直しをかけると、CGRAM に送るデータをコマンド(RS=0)として送っていた。そこを直すと無事動いた。フォントもこちらでイメージしたとおり。

 と、ここで不具合発見。自前のプログラムから直で LCD をアクセスするとうまく表示されない。一度 H8OS を使って LCD 表示をしてからだとうまくいく。初期化ルーチンに問題があるのか...。

 それはそれとして、今日の残り時間はコードを短くする検討に入る。
 ネットをあちこち回って調べると、皆さん色々とやっておられる。ソースは「 PIC24Fの紹介と実験」から拝借。データとフォントパターンの関係については、「 LCDのCGRAMに書き込んでみた・・・」のを参考にさせていただいた。

 コンパイルすると、「4byte ほど bss に fit できない」とリンカーがエラーを出してくる。H8OS+3664 だと開発に使える RAM は 1.25KB しかないのだが、もう一杯になってしまったか。ちょっとやりくりしてとりあえずメモリに収める。今日はここで時間切れ。
 マップファイルをちょっと見ると構造体を使った I/O のアクセスはかなりコード効率が悪いみたいだ。いろいろやる価値はありそうだ。
 H8/OS のサポートする LCD アクセスはターミナル型で、任意の位置にアクセスできないので使えない。

 で、「キャラクタ液晶SC1602をテキストRAM形式で扱う」のソースを拝借しようと思ったのだが、こちらは、SC1602 -CPU 間の制御線が2線。せっかく3線つないだので、最下位のアクセスレイヤーは「H8/3694F 液晶パネルを使ってみる」からソースを拝借。
 ポートの割り当てだけをアサインしなおして実行すると...、動かない。よく見るとオリジナルはデータと制御線を別ポートに割り当ててあるせいか、データアクセス時に未使用の bit まで変化させている。今回の回路ではひとつのポートをデータと制御線で使っているのでそのせいで動かなかった。
 そこのところを修正して動かすと...、動いた、んだけど、2行全部に表示させたはずが1行しか表示されない。あれこれ調べること30分、何のことはない、大元で2行表示させたつもりが1行分しかデータを更新していなかった orz。貴重な時間を 30分ほどドブに捨ててしまった。

-----
 今日はドブに捨てた分の30分が時間オーバー。明日は CG-RAM アクセスルーチンのコーディング。
002.JPG 昨日で配線は終わったので、今日は LCD 表示のテストプログラムを作るところから。といっても、H8/OSのサンプルプログラムをチョコチョコといじくるだけ。のはずだったが、ポートの設定を自前でしなくてはならないので、オリジナルの H8/3067 のデータシートをダウンロードしたり、H8/3664 の設定レジスタを調べたりと時間がかかる。LCD をつないだポート(P56)は 3664N では出力に設定しないでくださいとあって焦ったが、I2C コントローラーとかぶっているだけみたいなので、ままよとプログラムを動かしてみる。

 プログラムを CPU に転送するのがうまくいかず、10回近くかかったが、正常に転送されたあとは一発で動いた。

 今日はここで時間切れ。
-----

 忘れていたが、H8/OS のページにある RAM 転送プログラムは速い PC ではうまく動かない。
 さて、どうしたものかとソースを見ると -w オプションで wait を入れられるじゃありませんか。
 これで次からは大丈夫だ。

----
 ソースはこんな感じ

#include    "../h8os/syscall.h"
#include    "../h8os/reg3664.h"
int main()            /*  C1-19 C1-18 C2-03 C1:17 C1:16 C1:15 C1:14    */
{                /*  RS:55 RW:54  E:56 D7:53 D6:52 D5:51 D5:50    */
    unsigned char    lcdport[] = {0x20, 0x10, 0x40, 0x08, 0x04, 0x02, 0x01};
   
    PMR5 = 0x00;
    PCR5 = 0x7F;

    lcd_setup(2, 16, &PDR5, lcdport);
    lcd_clear();
    write_mode(LCD);
        /*    1234567890123456    */
    write_string("CPU is H8/3664\n");
    write_string("H8OS is ready!");
}

 昨日、ネットをフラフラしているとこんなページを発見。分解能 1rpm のタコメータは初めて見た。

 すごいのは、CPU が AVR の 20pin で、LED のダイナミック駆動までしていること。CPU の ROM は 2KB でプログラムはアセンブラで書いてある。

 気合入ってるなぁ。

-----
 参考にしたいけど、AVR のアセンブラでは無理。H8 から AVR に乗り換えるのも、環境(soft+hard) 整備に必要なお金と時間を考えるとありえない。趣味で一個だけ作るのだから量産時のコストダウンメリットもないし(^^;
 
 LCD 周りの配線をして、導通・短絡チェック。

 明日はいよいよ LCD に字が出るか?

とりあえず H8OS 上で動く、シリアルポートから文字列を返すだけのプログラムを組んで動作確認をする。

#include    "../h8os/syscall.h"

int main()
{
//    sio_speed(57600,16000000);
    write_mode(SIO);
    write_string("CPU is HD64F3664\n");
    write_string("H8/OS is ready!!\n");
}
 まずは、3664 の RAM にプログラムの転送ではまる。H8OS のコマンドインタープリターにコマンドがあるもんだと思ったらない。FDT から書き込むのかと思ったら違う (FLASH development toolkit だから当たり前か (^^;)、ドキュメントを良く見ると、RAM 転送ツールを使うと書いてあって、HP を良く見るとそういう名前のツールがある。それを使って、RAM に転送は成功。

 RAM 上のプログラムをコマンドインタープリターから実行すると動かない。.mot ファイルを良く見ると、なぜか ROM のある 0100 からデータがある。マップファイルを良く見ると BSS 領域の初期値。なぜ?
 よくよく調べると、リンカのスクリプトファイルで 'rodata' となっているラベルが 'rodata.str1.1'となっている。'str1.1'ってなに?
 とりあえずスクリプトファイルの rodata の後ろに rodata.str1.1 を追加してコンパイルすると。ROM 領域のデータは消えた。str1.1 か。 1.2 とかも出てくるんだろうか?

.text :    {
    *(.text)
    *(.strings)
    *(.rodata)
    *(.rodata.str1.1)   <---- 追加
        _etext = . ;
    }  > ram

 再度実行するが、まだ動かない。

 念のためにと、シリアルポートのボーレート設定をコメントアウトして再挑戦。やっと動く。

H8/OS >exec f9c0CPU is HD64F3664
H8/OS is ready!!

 executed.
 なんで sio_speed がうまくいかないのかわからないが、今日はここで時間切れ。というか 30分ほどオーバー。

----
 今日見つけたページ
 
GNU リンカ LD の使い方
 予定を変更して、
  1. 旧メインマシン(現iTunesサーバー)に VNC サーバーをインストール
  2. 旧メインマシンから現メインマシンへファイル共有できるようにする
  3. H8OS の API を使って、単にシリアルポートからメッセージを出力するだけのプログラムを動作させる
 を目標に作業開始。

 1 はほどなく終わったが、2 がうまくいかない 現 ->旧のファイル共有は出来たのだが...。あきらめて 3 に取り掛かり、.mot ファイルが出来上がったところでタイムアップ。

----
 明日は今日作った .mot ファイルの動作確認から

P4:H8OS 稼動

| | トラックバック(0)
 さて、今日はいよいよ H8OSをインストール。

 最初に半田付けの接続チェックをして....全部 OK....、メインマシンのシリアルポートにつなごうとすると...、シリアルポートがない!!! VGAのポートをシリアルと勘違いしていた orz。それではと、iTunes サーバーに使っている元メインマシンにつなごうとすると...、オス対オス?そうかメインマシンの VGA コネクターがメスなのでパソコン側のシリアルポートがメスだと勘違いした。RS-232C のストレートケーブル(メスーメス)を探してきて、パソコンに接続。ルネサスのページから FDT をダウンロードして CPU との接続を試みるが...、失敗。あれこれ調べると...、ストレートケーブルを本体に接続していない orz。
 ケーブルを接続すると FDT と CPU のコネクションはあっさり成功。H8OS のダウンロードも問題なく成功。
 手探りで H8OS コマンドインタープリターの通信速度 57600bps を見つけて、H8OS の動作確認完了。

 ポカミスがいくつかあったが、割とすんなり終了。ちょっと物足りなかったりしないでもない (^^;
-----
 明日からは LCD 周りを配線して、H8 OS の API  経由で LCD にアクセスして接続確認。
 小さな万力を出して、線を何本も引っ張り出し、電源と RS-232C をつないだところで1時間経ってしまった orz。
 H8/OS のインストールは明日だ。

-----
 回路図の誤り発見 VCC が 5V ではなかった (^^;
 昨日作った回路図をプリントアウトして、半年振りに半田ごてを引っ張り出す。

 ジャンク箱から引っ張り出した AKI-H8/3048 開発キットから LCD のヘッダピンを外し、AKI?H8/3664Fのソケットと一緒に蛇の目基盤に半田付けし、CPU モジュールにヘッダピンを半田付けしたところで time up。

 明日は電源と RS-232C をつないで、H8/OS を ROM に書き込み、動作確認まで行きたい。
回路図-1 LCD-1-1.PNG LCD 関連、シリアル、電源、リセットを一応全部接続 。明日、一度見直してから半田付けに入ろう。
2009/05/21 更新・VCC を変更  VCC に 5V に安定化前の電圧を入れていた。LCD を壊すところだった。
 このぐらいの規模だと、今までは手書きのメモで済ませていたのだが、誤配線が多いのと回路図が残らないので、今回回路図 CAD で図面を残してみた。

 AKI3664 の パラの 26pin コネクタと SC1602 のライブラリを作って、RS232C のコネクタをつないだところで終わり。

 回路図の完成までに2-3日かかるかなぁ。
 昨日作った LCD表示プログラムを H8/OS 上のコマンドインタープリターで動くようにあれこれやってみる。
 この環境は何年か前に使ったことがあるのだが、そのときは H8/OS のページにあるLinux 上で動くコンパイラを使ったので割とすんなり行ったのだが、今回は GDL と一緒にインストールした Windows 版の gcc をコマンドラインから使うのでいろいろうまくいかない。

 H8/OS のサンプルプログラムの Makefile と リンカスクリプトを使ったがそのままではコンパイルできない。    

 あれこれやって、結局
   Makefile は    h8300-hms-* -> h8300-elf-*
 ram3664.x は OUTPUT_FORMAT("coff-h8300") ->OUTPUT_FORMAT("elf32-h8300")

 ぐらいでそれらしいヘキサ (*.MOT)ファイルを吐くようになった。

 ちなみにコードサイズ自体は 0x324 byte 。H8/OS + コマンドインタープリター環境ではユーザーの使える RAM サイズは 1.5KByte 程度なので、当分はなんとかなるだろう。

----
 このあとの工程は、
  H/W 作成
  H8/OS をインストールさせてコマンドインタープリタの動作確認
  H8/OS の API を使って LCD 接続確認
  自作 LCD アクセスルーチンのテスト・デバッグ
  パルス幅検出部のコーディング
  車両エミュレーターの作成
  車両エミュレータを使ってのテスト
  全体のコーディング
  車両エミュレータを使ってのテスト
  実車両を使って実パルスを測定
  パルス入力部分の設計・実装
  実車両に積んでテスト

    ....ずいぶんあるなぁ。一日一時間ずつやってるんだけど、何ヶ月かかるか...。
  

  

 
  ちょっとしたデータを LCD に表示する簡単なプログラムを作っる。そのあと、GCC Developer Lite で Windows にインストールした gcc を、コマンドラインから使ってコンパイル。

 オブジェクトが巨大になってしまったが、C の標準ライブラリを読み込んでいるらしい。

 今日はここで時間切れ。

 明日は、gcc のオプションと格闘せねば。

----
 今日のサンプルプログラム
   キャラクタ液晶SC1602をテキストRAM形式で扱う
 前回手に入れた 3664.Hこちらのページのコードをコンパイルすると微妙にエラーになる。調べてみると、ルネサスで無償評価版のコンパイラを公開していて、H8/Tiny で使う分には実質制限無し。こちらをインストールして iodefine.h を入手してやってみるが微妙にあわない。

 面倒くさいので、ヘッダにコードを合わせた。

----
 引っかかるのは

IO.PCR5.BYTE

 の 'BYTE'。

 gcc のヘッダならいらないのだろうか?

----
 LCD アクセスの最下位レイヤーはコンパイルまで終わった。

P4:部品調達

| | トラックバック(0)
 街に出たついでに地元の部品屋でこまごまとした部品を調達。梅沢が六時半まで開いているのはありがたい。

買ったのは
  • D-SUB 6pin オス
  • D-SUB のカバー
  • 電源のコネクター
  • 4.7μFの電解コンデンサー(電解コンデンサーは E6 らしく 3.6μがなかった)
  • 50kΩのボリューム
  • 10kΩの半固定抵抗(LCD コントラスト調整用)
で 500円弱。

 555も欲しかったのだが、一個 199円とお高かったので延期。探せば家の中にあるはず。
 3664 のヘッダファイルが欲しかったので、コンパイラをセットアップ。

 以前使ったことがあるこちらのページの gcc を CentOS5.1 にインストール。H8 Tiny 用のパッチを当てて再コンパイルしようとするとエラーになる。CentOS の gcc が 4 のせいだろうか?別なマシンを立ち上げて古い Linux を立ち上げるか、Cnet OS は Xen の上で動いているので古い Linux をゲスト OS として入れるか...。
 それはそれとして、3664 のヘッダファイルが欲しいの探していたら GCC Developer Lite なるものを見つけた。Windows 上で gcc が使えるらしい。H8/SH/AVR などもサポート。インストールもすんなり終了。
 今日はここで時間切れ。

 H3664.h は無事入手。
 部屋の中を探して秋月の CPU ボード(メインクロックがセラミック発振子だった)と、LCD を発見。

 LCD 周りの回路設計をして(信号線7本だけだが...)、参考になるソースを集めていじり始める。

 コードを書いているうちはいいのだが、実機デバッグになると、また...。まだ先の話だ。
 CPU (H8/3664)のドキュメントを見て、カウンターの動作を確認。

 20bit 必要なので、16bit の W と 8bit の V をシリアルにつなげて使うつもりだったが、V にインプットキャプチャーがない (; ;)。仕方ないから上位 2bit は W のオーバーフロー割り込みを使ってソフトでカウントしよう。キャプチャーもソフトになるので読み込み時には W がオーバーフローしていないことの確認も必要だ。

 部屋中引っ掻き回して 秋月H8/3664ボードと SC1602 の資料を見つけた。秋月ボードの BSch3V のライブラリはないだろうか。SC1602 の資料を見ると、オリジナルフォントを設定できるようだ。回転数のバーグラフ表示をしたいので、是非使いたい。コードを見つけたので参考にさせてもらおう。
発振器 7-400Hz.PNG 水魚堂さんの HP から BSch3V の最新版をダウンロードしてマシンにインストールし、回路図を入力。BSch3V は以前にも使ったことがあるのだが、マシンを入れ替えたので新しくインストール。こういうことを考えると、仮想マシンって魅力的だよなぁ、真面目に考えてみるか?

 データシートの回路図をほぼ丸写しして、30分ちょっとで完成。

 この程度は、さらっとメモに書いてチャチャと作ってしまっても良いのだが、それをやると、
  • 変更が面倒(配線を追って、回路図を起こさなくてはならない)
  • 作ったモノの再利用が出来ない(スペックがどこにも残らない)
  • 回路図エディターがいつまでも使えない
 ので、わざわざ回路図エディターに入力。

 ちなみにブログに残すのは、回路図を行方不明にしないため (^^;
----
 555 は探せばどこかにあるはずなのだが、見つけたらブレッドボードで組んでみよう。

 
 回転数計測の基本的な部分 が固まったので、車両エミュレータの設計を開始。プログラムを書くのに飽きてきたので目先を変えねば (^^;
-----
 今回のプロジェクトでは完成した装置は車(ステラ)に搭載することになるが、実環境でプログラムの「テスト->修正->プログラム書き換え->テスト」を繰り返すのは大変なので車の代わりになるものを作ることにする(車内にノートパソコンを持ち込んでデバッグするのは、それはそれでカッコよさそうだが...)。

 エミュレートに必要な信号は 20Hz-400Hz の矩形波だけなので、実態はタダの発振器 (^^;

 昔さんざん遊んだ CMOS のゲートを組み合わせたもので作ることを考えたが、手持ちに CMOS のゲート IC がなかったので、555 を使った回路を考える。

 ネットで見つけたこちらのページを見てパラメータを検討。こういう情報がネットを少し探せば見つかるとは、いい世の中になったものだ。手持ちの古いトラ技はあきらめて処分しようか...。

 C=3.6μF,Ra = 1kΩ ,Rb=0-50kΩ で 400Hz-7Hz ぐらいまでいけそう。Rb = 0  だと C の放電電流が大きくなりすぎて IC が壊れないか不安があるが、データシートを見る限り、モノステートの回路では Rb = 0 なので問題なかろう。

 今日はここで時間切れ。明日は回路図を起こそう。
 パルス計測が 16bitに収まらないので、パラメータをちょこっといじくって、関係する部分を unsigned short から unsigned long へ。たったそれだけに一時間近くかかってしまった。

 結局カウンターのクロックは 4MHz、600rpm のときのカウント値が 200,000(2puls/cycle)で、カウンターは 18bit になってしまったが、1rpm 単位で 10986rpm まで計測できる。

 せっかくなので 9999rpm まで計測できる仕様に変更しよう。

-----
 コメントのネストが出来なくてあせる。コンパイラを gcc から g++ に変更
-----
 途中 core dump で止まる。cygwin の gdb がなかったので追加インストール。すると今度は core がない。よく見ると、stackdump。
 ねっとでざっと見てもわからなかったので、あきらめて、gdb 無しで直す。
 相変わらず、ツールに遊ばれている。

 一昨日までに書いたソースを Cygwin + gcc でコンパイルしてテストデータを入れてシュミレーション。

 一回転2パルス、カウンタークロック 1MHz だと 600rpm で 50,000カウントで 16bit カウンタ(H8-3664 のカウンタ W)にはちょうど良いのだが、分解能 1rpm が5530rpm までしか確保できない。

 回転数の高いところでジリジリと上がって行くところが見られなくては価値が半減なので、ここは何とかしたい。

 タイマV と組み合わせて 24bit にして、クロックを少し上げるか。
 Cygwin をインストールして、今まで書いたソースをコンパイル。

 Cygwin はデフォルトだと、gcc も vi もインストールされない...。

 コンパイルエラーを直すうちに、非常に根本的なロジックのミスを発見。計算は 32bit でできても H8 のカウンタWは 16bit しかなかった。

 4気筒の場合、点火パルスは1回転あたり二発でるそうなので、コメントの方を書き換える。

 明日は、リダイレクトでデータを喰わせて、計算結果の確認だ。
 パルス幅から回転数を求めるコードを書き直し。数十行の短いコードになった。LCD表示部分もとりあえず書いた。H8OS の標準出力を使った簡単なもの。

 次は makefile を書いて、cygwin の gcc でコンパイルして、テストデータを食わせて動作確認して...、もう飽きてきた orz。
 ちょっと時間があったので、パルスの周期からテーブルを参照して回転数を得るルーチンを書き、テーブルを作ろうとしたら、テーブルの作りかたを間違っていたことに気づく。

 何を間違ったか、パルス幅の差分のカウント数でテーブルを作っていた。

 パルス幅でテーブルを作ると 1MHz のクロックで充分 1rpm 単位で測定できる。計算式を良く見ると、テーブルなど使わずに整数( ong int (32bit))で 1rpm まで計算できることが判明。

 書いたコードは無駄になったが、短いコードでより性能が良くなったので良しとしよう orz。

----
 新しい仕様
  ・表示更新周期は 200ms
  ・回転数分解能 は 1rpm
  ・測定範囲は 600rpm-8000rpm
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 頭の中でアレをあーして、コレをこーして..、と考えているうちに、発作的にパルス幅を測定する関数を書いてしまった。一年以上Cのコードを書いていなかったが、思いのほかスラスラ書けた。ま、エラーがどれだけあるかはこれからの楽しみだが。

 ハードに手をつける前に、机上デバッグ+エミュレーションを進めよう。