Naknet blog

Nothing to believe, nothing else to believe.

NOVAC RadioMate NV-UR001

買いました

http://www.novac.co.jp/products/hardware/nv-radio/nv-ur001/index.html
買いました。

が、

音が割れる…orz

しかも、

http://www.driver.novac.co.jp/driver/ur001/ur001_faq.html (一番下)

Q.ラジオを録音する際、録音音量の調整を行い音量を下げて録音を行っているのですが、会話などの

  音声については問題ないのですが、音楽などの低音域でビリビリと音が割れてしまうのですが・・・

A.本製品の特徴として『Radio Mate』(機器側)では瞬時に適正な音量になるように調整し、会話も音楽もほぼ同じ音量にななるように

  設計されております。

  そのため、『低い音の聞き取りにくい音でも自動で聞き取りやすく増強してしまう』というマイナス面もあり、音楽などの低音域が

  強くなってしまうため音が割れてしまうことがあります。ご了承ください。

…ああん?

音楽などの低音域で

嘘です

どんな音だろうが割れます

うぜーー。

そこで

回路を解析しました。

調べたところ、構成は
[AM/FMチューナーIC]->[イコライザ]->[A/D内蔵マイコン]
という風になっているようでした。

で、オシロで信号を調べたところ、チューナーを出たところでは別に割れてはいない。
ところが、A/Dに入る手前で見ると、振幅が大きくなるところで3.3Vに張りついている。つまり飽和してるわけですね。
要はイコライザのgainが高すぎるのが悪いわけです。

回路

そこで、イコライザ(基板裏)付近の回路を起こしてみました。

NV-UR001_mini

上が元の回路、下が改造後の回路です。

元々は低域強調か何かのために、OpAmpを使用したイコライザの回路になっているみたいですね。
ここのgainが高すぎるために、Ampが飽和し、音が割れてしまっています。

本当は入力を半固定VRで分圧して調整できるようにすればいいんですが、本体のサイズが小さく、VRを入れる余裕はなさそうな上に、パターンカットをやらなければならなくなりそうだったので、やめました。

そこで、次善の策として、イコライザ部分を単なる非反転増幅回路に改造することにしました。

本当はここの回路定数を調べて、元の回路と同じ増幅曲線を実現できればいいんですが、あいにくチップキャパシタには容量の表記がないため、諦めました。

定数は、

  • C9,C13 -> RC9,RC13=120k
  • C18,C19 -> RC18,RC19=220k

にしました。
この値なのは、あり合わせのチップ抵抗を使ったからです。若干gainが足りない感じなので、C9,C13は60~80kくらいでもいいかもしれません。

また、元の回路では少し余計にバイアスが乗っているようだったので、VccとGNDのちょうど真ん中に入力を吊るように、

  • R9,R15 -> 120k
  • R10,R16 -> 120k

としました。

以上の改造で、音割れもなく快適に聞けるようになりました。

続きを読む>>
comments (2) | trackbacks (0)

TOPPERS/ASPのサンプルプログラムが動かない件

国産組み込み向けリアルタイムOSとして、TOPPERSというものがあります。先日、秋月のH8/3069F LANボードを購入したのですが、付属のH8/OSがいかにも古く、また後継のものも既にSHシリーズに開発がシフトしているようだったので、TOPPERS/ASP 1.6.0の導入を検討しました。

以下は、うちの環境でサンプルプログラム(sample1)が動作するようになるまでの過程です。

開発環境

まず開発環境の構築です。せっかくならば開発環境も(対応する範囲で)最新のものにしたいと思い、まずはCygwinで構築を試みました。
一応gccもbinutilsもnewlibもビルド+インストールはできたのですが、色々と問題が発生してしまいました。

まず第一の問題は、コンフィギュレータ(cfg)です。ビルドが面倒だったので、公式サイトからバイナリを落としてきたのですが、うちのCygwin-1.7.9-1では起動しませんでした。

そこでソースからビルドしたのですが、まず、簡易パッケージに含まれていたcfgは、boostの最新バージョンに対応していません(native_file_string()がおかしい云々)。そこで公式サイトから別途ダウンロードしたものを使用したのですが、使用したboostのバージョン(1.48.0)が、公式で動作確認が取れているものより新しかったため、問題が発生しました。それは、boost::filesystemのpathが、パスの区切り文字をご丁寧に '/' ではなく '\' と認識するため、cfgが変なエスケープシーケンスを含んだC言語のソースコードを生成します。この結果、コンパイルが通らなくなるというものです。これに対しては、cfgを頑張って修正するか、出力されたファイル cfg1_out.c をsedで修正するくらいしか方法がありません。

次に、Makefileで最適化(-O2)が行われていたため、genoffsetが認識できない.Sが出力されてエラーが出てしまいました。
この対策としては、../configureした後にMakefileを手動で編集し、COPTSに-O2としている箇所を-O0とすれば回避できます。しかし、このようにするとmakeoffset.cだけではなくすべてのファイルで最適化が無効になってしまうため、makeoffset.cだけを特別扱いするような別の対策が必要と考えられます。

以上の修正によりsample1はなんとかビルドできました。しかし、これを苫小牧高専の簡易モニタ上で実行すると、"task1 is running (xxx)."という表示は出るのですが、キーを入力すると固まってしまうという現象が発生しました。

この現象は、調べてみると他の人も遭遇しているようでした。しかも全く別のCPUでも発生しているようで、全く原因不明でした。

調べた方によれば、文字入力があった後でmain_task()がdispatchされていないということらしく、カーネルのバグを疑いました。

OSの変更

ただ、単純に開発環境がいけないだけという可能性もあります。そもそも、単純にmakeするだけではだめで、色々とファイルの修正が必要になる(しかも汚い方法で…)時点でCygwinの限界を感じたため、新たにVM上にCentOS 6.0 (x86)をインストールしました。ここでx86_64ではgccがビルドできません。x86(i686)版でやる必要があります。そういうわけでOSを2回インストールした後、この上にgcc-3.4.6+binutils-2.16.1+newlib-1.19.0で開発環境を改めて構築しました。

付属の各種txtによれば、hms(Hitachi Micro System)形式ではなくelf(Executable and Linking Format)形式をターゲットに指定する(--target=h8300-elf)こともできるそうです。そこで最初はそちらで環境を構築することにしました。しかしながら、構築した環境でsample1をビルドし、RAMに転送して実行しようとしても、全く動きませんでした。おそらく別の個所の修正が必要になるんだと思いますが、面倒なのでh8300-hmsで環境を構築しなおしました。

Linux上ではboost::filesystemのパスの問題も起きず、修正もMakefileの-O2の部分だけでmake dependもmakeも通ります。というわけなのでこれから環境を構築される方はCygwinではなくネイティブのLinux OSを用いることをおすすめします。

それでも動かない

そこで改めてsample1をビルドして実行してみたのですが、やはりキー入力をすると固まってしまいます。タスク切り替えに問題があるのかとtest_task1を実行してみましたが、すべてpassします。同様にtest_sem1、test_sem2もpassします。

make cleanをしてからビルドなど色々やってみたのですが、解決しません。

warningが出ていた

何日かブランクを開けた後、ふと、make中に"warning: function called through a non-compatible type"が出ていることに気付きました。これはgcc-3.4から導入された機能で、別の型からキャストされて得た関数ポインタを経由して関数を呼ぼうとすると、問答無用で落ちるというものらしいです。

原因はこれでした。TOPPERSのカーネルでは、自動生成された割込みハンドラ(kernel_cfg.c内)でキャストした関数ポインタを使用して関数をコールしており、この部分でabortしていたのでした。生成された関数は、具体的には

void
_kernel_inthdr_53(void)
{
	i_begin_int(53);
	LOG_ISR_ENTER(53);
	((ISR)(sio_rx_isr))((intptr_t)(USER_PORTID));	// ← HERE
	LOG_ISR_LEAVE(53);
	i_end_int(53);
}

のようになっており、文字が入力され、受信され、割込みが発生するとこの関数内でabortしてしまいます。

対策としては、kernel/kernel.tfを次

818a819,821
> $             ///// gcc3.4 /////
>               $TAB$ISR fp;$NL$
> $             ///// /gcc3.4 /////
830c833,836
<
$TAB$((ISR)($ISR.ISR[order]$))((intptr_t)($ISR.EXINF[order]$));$NL$
---
> $             ///// gcc3.4 /////
>                       $TAB$fp = (ISR) ($ISR.ISR[order]$);$NL$
>                       $TAB$(*fp)((intptr_t)($ISR.EXINF[order]$));$NL$
> $             ///// /gcc3.4 /////

のように書き換え、コンパイラを欺くか、あるいはgcc-3.4以前を使用します。私は前者の方法を採りました。この修正により、生成されるソースコードは次

void
_kernel_inthdr_53(void)
{
    ISR fp;	// **
    i_begin_int(53);
    LOG_ISR_ENTER(53);
    fp = (ISR) (sio_rx_isr); // **
    (*fp)((intptr_t)(USER_PORTID));	// **
    LOG_ISR_LEAVE(53);
    i_end_int(53);
}

のようになります。注意点として、同様のkernel.tfはextension/ovrhdr/kernelとextension/mutex/kernelにもありますので、これらの拡張を使用する際にも同様の修正が必要になることが挙げられます。

これで無事に3系gccの最新版でsample1が動くようになりました。タスク切り替えもちゃんと動いています。

これだけで1週間は悩みました…。最初から動作確認が取れている環境でビルドしなかったのが悪いんですが、最新のコンパイラを使う際は気をつけようということで。

参考サイト

開発環境構築にあたって参考とさせて頂いたサイトです。

他にも「h8300-hms-gcc」などで検索すればたくさん出てきます。

comments (0) | trackbacks (0)
1/1