マイコン工作実験日記

Microcontroller を用いての工作、実験記録

SDカードへの通話録音

2009-01-29 23:22:30 | W-SIM
SDカードアクセスができるようになったので、通話音声を録音してみます。とりあえずは、相手側の音声だけを録音です。録音は常におこなうこととし、オフフックした時点でファイル(rec.wav)をオープンすることにしました。WAVファイルのヘッダを書いたら、あとは20ms毎に160バイトづつ書き込んでいくだけです。そしてオンフックされたらヘッダ部分のデータ長部分を更新してファイルをクローズさせます。以下、動作の様子。
> Off-Hook
-I- SD/MMC card initialization successful
-I- Card size: 1882 MB
-I- Block size: 1024 Bytes
DTMF: 1
DTMF: 7
DTMF: 7
ATDT177##0
CONNECT 120000
connected!!
PROGIND:1
On-Hook
ATH
SD_Stop
newname = rec118.wav
SD_Stop
DISC
OK

>
ファイルをクローズしたら、ファイル名を変更しています。今のところブートからの経過秒数をつかってrecXXX.wavという名前にすることにしています。上の例の場合には、以下に示すようにrec118.wavというファイルが作成されています。ホントはファイル名で日付/時刻も表現したいところですが、LFNが使えないのでこれで我慢です。
> fat
-I- SD/MMC card initialization successful
-I- Card size: 1882 MB
-I- Block size: 1024 Bytes

shows directory list...
---------------------
 6676127 2008/11/23 21:09:54 AT91SA~1.PDF
  461024 2008/12/10 18:58:04 AT91SA~2.PDF
  245178 2009/01/01 00:00:00 rec118.wav
     122 2009/01/25 13:59:44 sample.txt
---------------------

dumping sample.txt...
---------------------
This is a sample text file created on the Windows.
If you can read this message, it means you can
access the FAT file.
---------------------
>
Windows Media Playerで再生してみましたが、問題なく録音できているようです。とは言っても、改善すべき点もいくつかあります。
  1. カードの抜挿を検出していないので、オフフックする度にf_mount操作をおこなっている。抜挿を検出して無駄なf_mountを無くしたい。
  2. 相手側音声しか録音していないので、ほんとの会話録音にはなっていない。上り音声も録音すべき。ミックスするまでもなく、ステレオ形式で書き込んで簡単に対応してしまおうかと考えています。
  3. やっぱり、ファイルにタイムスタンプが無いのは淋しいなぁ
順次対処していくことにしましょう。

FatFsを動かす

2009-01-25 19:50:53 | Weblog
SDカードの読み取りができるようになったので、次の段階としてFatFsを動かすことにしました。SDカードに通話録音を保存できるようにしようという目論見です。先日、ヨドバシの電話機売り場を覗いてみて知ったのですが、最近の電話機にはSDカードに通話録音を保存できる機種があるのですね。さすがSDアソシエーションの中心的メンバーであるパナソニックですねぇ。ここまでは高機能ではなくても、通話をWAV形式でSDカードに保存するくらいのことは簡単にできそうですから、試してみようというわけです。

FatFsについては、TOPPERS用にも移植されていますが、SDカードではなくPCカードに挿すCFを対象としているので、そのまま使えるわけではありません。そこで、わたしは最新のR0.06を拾ってきて、diskio.cをSDカードのドライバに合わせて作成してやることにしました。メモリをケチってTiny-FatFsを選択しています。移植といっても初期化とR/Wのルーチンのインタフェースを合わせてやる程度の作業なので、簡単に動かすことができます。書き込みの際にファイルのタイムスタンプを付けるために、RTCとのインタフェースとしてget_fattime()が必要なのですが、いまのところRTC機能が無いので、とりあえずは常に2009/01/01 00:00:00を返すことにしておきます。

動作試験として、ディレクトリの表示と、ファイル内容の表示をやってみました。



いい感じです。次は、通話時音声の書き込みをやってみることにします。

SDカードへのアクセス -- その2

2009-01-23 23:18:58 | Weblog
MCI(Multimedai Card Interface)を使ってのSDカードへのアクセスの実験の続きです。ATMELの提供するソフトウェア・パッケージのコード(Basic SD Card)にちょっと手を入れたところ、初期化はすぐに動作の確認がとれました。トレースのレベルをデバッグ(5)に上げておくと、次のようにSDカードに対して発行しているコマンドを確認することができます。



ところが、続いてブロックの読み出しを試してみると、これがちゃんと動いてくれません。MCIのステータスとしては、読み出しコマンド(CMD18)が正常終了しているように見えるのですが、実際にはデータが読みこまれないのです。CMD18の代わりにCMD17を使って1ブロックだけ読んでみても、やはりデータが読み込まれません。ATMELが提供しているコードなので動かないわけはないと思われますが、念のためにコードを自分で追ってみても怪しげな部分は見つかりません。

ソフト的におかしいところがなければ、原因はハード側かもしれないと考え、データシートのErattaを確認してみるとMCIをPDCモードでDMAする場合のバグについての記述があります。提供されているコードはPDCを使ってDMAしているので、まさしくバグが発生する場合に該当するのですが、その対処は施されていないようです。さっそく、対処のための変更を入れてみたのですが、それでもまだちゃんとデータが読み込めません。PDCのレジスタを読み出してDMA転送先アドレス(MCI_RPR)と残りバイト数(MCI_RCR)を確認してみると、読み出しコマンド(CMD18)の実行後には変化していますので、PDCとしては正常にDMAができているかのように見えます。まったく不思議な症状に見えて、まるまる1日ハマリましたがようやくと原因がわかりました。

原因は読み出したデータを格納するバッファのアドレス境界でした。バッファはunsigned char[] でとっていましたが、この配列が16bit/2バイト境界に配置されていました。一方、MCIによる読み込み/書き込みは常に32bit/4バイト単位でおこなわれるようになっています。PDCによるDMAの際も32bit単位で行われるのであれば、バッファも4バイト境界にアラインする必要があるのではないかと考え、バッファの宣言に __attribute__((aligned(32))) を追加してやると、ちゃんと読み出せました!! 普通のメモリアクセスであれば、data abortのトラップがかかるようなアクセスでも、PDCによるDMAの場合には、DMA転送がカラ振りに終わるだけで例外は発生しないということのようです。

下図は、セクタ0を読み出してダンプしてみたところです。



SDカードへのアクセス -- その1

2009-01-20 23:15:51 | Weblog
32KBしかSRAMを積んでいないAT91SAM7A3ですが、スペクトラムの表示機能まで入れてもまだ、半分の16KBも使っていません。まだまだ、RAMには余裕があります。そこで、AT91SAM7A3の特色でもあるMCI (Multimedia Card Interface)を使ってSDカードへのアクセスを実験することにします。



まずはハードウェアの準備から。MCIでは6本の信号が用意されていますので、これを下図のようにSDカードソケットにつないでやります。最初はマイクロSDにしようかと思っていたのですが、ソケットの実物を見たら手ハンダする自信が失せたので、SDカードに変更しました。SDカード自体は9ピンですが、残りの3本はVCCとVSS 2本です。ソケットにはカード検出用とライトプロテクト用のピンも用意されていますので、必要であればこれらはGPIOにつなぐわけですが、今回は省略しています。



トラ技とかインタフェースの製作記事や解説記事ではSPIモードを使ってのSDカードへのアクセスはしばしば解説されているようですが、SDバスを使った場合については、あまり説明されていないように思われます。安価なマイコンではSPIしか使えないのが大きな理由でしょうが、SDカードの詳細技術仕様についてはライセンスが必要ということも、しばしば指摘されているようです。そこで、SD AssociationのHPを確認してみたところ、現在では物理層仕様の簡易版であればダウンロード可能であることを知りました。この仕様書にざっと目を通したところ、SDバスのビット幅の切り替え方やSDHCカードの場合のブロックアドレスの指定方法を理解することができました。このドキュメントはSD関連技術資料の一部でしかありませんが、SDカードをストレージとして使う我々アマチュアの用途には必用十分な情報が記載されていると言えます。

SDバスモードを使うことによる優位性は、上図のようにSPIモードは1ビットのシリアルでしか入出力ができないのに対し、SDバスではDAT[0]~DAT[3]を使って、一度に4ビット転送できることです。電源投入時はSDカードはDAT[0]だけを使う1ビット幅のモードで動作しているので、初期化手順の中でACMD6コマンドを投入して4ビット幅に切り替えてやるようです。

SDカードのバスとプロトコルの仕様はわかったので、次はMCIを使ってSDカードにアクセスするためのドライバです。仕様書とAT91SAM7A3のデータシートを元に自分で書いてもいいのですが、今回はATMELが提供してくれているSoftware Packageに含まれているソースを流用することにしました。RTOS無しの環境で動作するコードになっていますが、ちゃんと割り込みを使って処理するコードになっており、構造も素直でわかりやすく書かれているので、ちょっと手を入れるだけですぐに使えそうだからです。

この続きは、また次回。

音声スペクトルを表示してみる

2009-01-17 18:40:09 | W-SIM
電話機ジャケットでの発着信はアッサリと動いてしまったので、少し機能拡張してみることにしました。LCDとしてVoIP GWと同じNokia 5110を使っていますので、まずは音声波形の表示機能を持ってきましたが、これだけでは進歩が無いのでこんどはスペクトル表示もやってみることにしました。(表示するのは相手側から受信した音声だけとします)



FFTした結果をグラフ表示してやればいいという程度の理屈はわかってはいたのですが、何しろFFTなんてやったことがありません。まずは、いつも参考にさせていただいているChaNさんのオーディオ・スペクトラム・モニタの説明を読んで、動画を見ると刺激をうけて自分もやる気がでてきました。秋月LCD用のソースコードはAVRのアセンブラで書いてありましたが、ハミング窓を通してからFFTをかけて、結果はログ・スケールで表示するのが良いことがわかったので、ARMでも同じ流れで処理してやれば良さそうです。

とは言っても、AVRのアセンブラをARMのアセンブラで書きなおすほどの根性も無いので、Cで書かれたFFTのサンプルを探してみました。DTMF検出の時と同じように整数演算命令で済む固定小数点で処理しているものが欲しいわけです。すると、酔漢さんが解説記事を書いておられるのを見つけました。わたしが知りたいと思っていたことが要領良く整理してあり、サンプルコードも提示されています。はい、そのまま使わせていただくことにしました。

音声の送受信はこれまでのジャケットと同じく、20ms単位でDMAしています。8000Hzサンプリングですので、160バイトに相当します。そこで、FFTは256点毎に行うこととし、160バイトを受信する毎にFFTをかける範囲をスライドしていくことにしました。FFTの結果は、4000Hzまでの範囲に相当する128ドット幅で表示したいところなのですが、残念ながらNokia 5110は横84ドットしかありません。周波数の低い方から84ドット分表示することにしたので、2645Hz以上の周波数成分は表示されていません。実際の処理としては、20ms毎にW-SIMからの受信タスク(wsim_recv_task)が256点のFFTを実行し、横84ドット分の波形ならびにスペクトルのビットマップを作成します。そして、LCD画面の更新要求がwsim_recv_taskからphone_taskに送られ、phone_taskがビットマップ情報をLCDに対してDMAすることで画面の更新が行われています。

上掲の写真は、シャッター速度が遅かったために画面が流れてしまい、その結果黒い帯状の表示になってしまっています。動画を見ていただいた方が雰囲気がわかると思います。



電話機ジャケットのタスク構成

2009-01-14 22:35:23 | W-SIM
現在の電話機ジャケットのタスク構成について記しておくことにします。コンソール・モニタには、psコマンドを用意してあるのですが、その出力は次のとおりです。全部で9つのタスクがありますが、logtaskはTOPPERS/JSPのシステムタスクですので、電話機ジャケットで新たに用意したタスクは8つということになります。



最初のpsコマンド出力が示すように、システムの起動時にはslic_recv_task, wsim_recv_task, wsim_xmit_taskの3つのタスクは起動されていませんが、受話器をオフフックするとslic_recv_taskが走り始めます。このタスクがSLICからのPCM音声を受信してDTMF信号の検出を行います。検出されたDTMF信号はデータキューを介してphone_taskに通知されます。

phone_taskは電話機としてのユーザ・インタフェースを実現しているタスクです。このタスクではSLICやW-SIMの状態変換に伴って発生したイベントを受理して、その時の電話機状態に応じた処理をおこないます。オフフックに伴って、ダイアルトーンを生成して、slic_recv_taskを起動するのも、phone_taskの役割です。

phone_taskは検出されたDTMF信号を電話番号を指定する桁として順次蓄えていきますが、一定時間(3秒間)たっても次の桁がこないと、タイムアウトして蓄積された電話番号へ発呼するために、W-SIMに対してATDTコマンドを送出します。また、この時、slic_recv_taskを終了させます。



上図は通話中にpsを実行した場合の様子です。呼が接続されると、phone_taskはwsim_recv_taskとwsim_xmit_taskを起動します。wsim_recv_taskがW-SIMからのPCM信号を受信し、SLICへ送信するタスクです。wsim_xmit_taskは、逆にSLICからPCM信号を受信し、W-SIMへ送出します。

modem_taskはW-SIMのモデム信号やリザルト・メッセージを受信してphone_taskにイベントとして通知する処理をおこないます。main_taskは起動時の初期化処理をおこなった後は、SLICからの割り込み要求に応じた処理と、phone_taskへの状態変化通知を担当しています。

SLICとLCDをつなげた

2009-01-10 23:15:17 | W-SIM
電話機ジャケットボードにSLIC子基板とLCDをつなげました。当面の実験に必要なハードウェアはこんなところでしょうか。LCDとしてはモノクロのNokia 5110を再び使うことにしました。SIP GWの時に作成したルーチンを流用して、さっさと動かせますし。



ハードウェア全体の構成は下図のようになります。SIP GWからW-SIMとLCD, SIP TAからSLIC部分を切り出してくっつけたようなもんです。したがって、ソフトの方もそれらからコピペするだけで60%くらいはできてしまいます。実際のところ、もうすでに基本的な発着信は動いています。もう少し機能追加してから、ソフト周りも記事にしようと思います。


各部品やモジュールをMCUに直結しているだけの、誰でも作れる簡単ハードですね。AT91SAM7A3のUSARTには、DSR, DTR, RI, DCDといったモデム制御信号は無いので、W-SIMのDTR, DCD, INS(DSR)信号はGPIOを使うことで検出/制御しています。
SPIインタフェースとしてはSPI0とSPI1の2つをもっていますが、SLICとLCDはどちらもSPI1の方につないであり、CS信号で選択して利用するようにしています。SPI0のピンはMCIと兼用になっているので、こちらの方は後々SDカードをつなげるのに使うつもりでいます。

電話機ジャケットボード

2009-01-07 23:27:18 | W-SIM
製作中のW-SIM電話機ジャケットボードです。



AT91SAM7A3を使ったヘッダーボードがあれば、それを買ったと思うのですが、残念ながらみあたらないようなのでMCUを買って自分で配線することにしました。MCUは100ピンなので、ダイセンのピッチ変換基板を使っています。サイズの小さいアイテムラボの変換基板を使おうかとも思ったのですが、足のピンが3列並びになってしまうので配線しにくいかもしれないと思い、2列のダイセン基板を使うことにしました。

例によってユニバーサル基板を使っていますが、いつもの秋月基板(400円)に替えてアイテムラボのパワーメッシュ基板(1500円)を初めて使ってみました。この基板、お値段はちょっと高いですが、宣伝文句のように電源配線やパスコンの配線はとっても簡単です。とくに、MCU周りでは電源ライン関連でいくつもパスコンが必要となりますが、パワーメッシュのおかげて直近のGNDに1608サイズのチップコンデンサでつなげられるので、ラクチンでした。プルアップ抵抗も同様にして配線できますが、スペースを気にしなければ、チップ抵抗を使わずとも普通の抵抗器のリードをパワーメッシュのスルーホールに通して半田することもできます。

このように大変便利な反面、注意すべき点もいくつかあります。
  1. ショートに注意
    ハンダブリッジでVCC/GNDへの配線が簡単にできるわけですが、パターンを間違えれば即ショートです。実際には、GNDパターンの方にはシルクで目印が付いているので、わたしはVCC/GNDを間違えることはありませんでしたが、部品のリードのハンダ付けの際にGNDと接触させてしまったりしました。
  2. コネクタの取り付けに注意が必要
    これも結局はショートにつながる事ですが、コネクタ等の部品を取り付ける際に電源メッシュと接触したり、メッシューをショートさせたりしないように注意しなければなりません。今回は、USB Bコネクタの下にはカプトンテープを貼って絶縁しています。USBコネクタの取り付け足と、W-SIMコネクタの周囲ではパワーメッシュのスルーホールをドリルでけずることで局所的に電源パターンを無効化することで対処しています。
  3. こまめに配線確認
    なにしろ基板がチカチカと光るので、配線を追うのはちょっとツライです。ショートさせてしまうと、その場所を探すのも大変です。部品は少しづつ配置/配線しては、ショートさせていないか確認しながら作業した方が良さそうです。

当面必要な部品はすべて配置してあります。変換基板の右側にあるピンソケットで、SLIC評価ボードの子基板を受けます。ピンソケットと変換基板に囲まれているのは、2.048MHzの水晶発振器です。あとは、電源、W-SIMソケットとUSB関連の部品しかありません。ハードウェアとしては、とってもシンプルです。機会をみて、ブロック図でも描くことにします。

まだ配線の途中ですが、JTAGでフラッシュの書き込みができることは確認できたので一安心。電源とJTAG関連信号とリセットさえ配線すれば、フラッシュの書き込み確認がとれるので、いつもこれらから動作確認をすることにしています。次は、簡単にソフトを用意してUSBでのCDCによるアクセスの確認というのがいつもの手順です。


AT91SAM7A3

2009-01-04 19:17:53 | Weblog
せっかくの休みなので、次のW-SIMジャケットの配線を始めています。ある程度、動作が確認できた時点から実際の記事を書き始めたいと思います。

さて、今度のジャケットではTDMインタフェースに使うSSCがふたつ欲しいという理由からMCUとしてAT91SAM7A3を選択しました。これまで、AT91SAM7S256, AT91SAM7SE256, AT91SAM7X256と使ってきましたので、SAM7シリーズもこれで4種類目ということになります。このAT91SAM7A3ですが、他のSAM7シリーズとちょっと毛色が違っていておもしろいデバイスです。

  1. ペリフェラルの数が多い
    他のデバイスと比べてみるとこんな感じ。もちろん、ピンへの機能割り当ての都合上、全部が同時に使えるわけではありませんが、用途によっては便利そうです。
    DeviceADCUSARTSSCSPITIMERMCI
    AT91SAM7S25682113N/A
    AT91SAM7SE25682113N/A
    AT91SAM7X25682123N/A
    AT91SAM7A31632291

  2. SAM7シリーズで、唯一MCIが使える
    上図にも示したようにMCI(Multimedia Card Interface)を持っており、MMCやSDCをつなぐのに使える。SPIを使ってSDカードをつなぐ場合に比べて、高速アクセスが期待できます。

  3. バッテリーバックアップできるレジスタがある
    バックアップ用電源端子とシャットダウン制御機能があり、バックアップ状態を用意できる。

SAM7A1とSAM7A2にはEBI(外部バスインタフェース)があったのに、SAM7A3には無いというのもちょっと不思議な点です。

SDカードインタフェースは、近頃のLPC2000なんかではサポートしているデバイスも多いのですが、SAM7ではSAM7A3だけですので、是非とも実験してみたい気もします。ChaNさんの動画とかアクセス速度の計測結果を見てしまうと、自分もSDカードモードを使ってみたくなりますし。 というか、値段も安いしLPC23xxも使ってみたくなります。それにしても、ChaNさんの配線は芸術的ですよねぇ。

うるう秒を聞きそこねる

2009-01-01 19:13:43 | Weblog
明けましておめでとうございます。

今年は「うるう秒」の調整のため、ひかり電話の利用者は午前9時の時報が2回鳴るという珍しい事象を耳にすることができるということで、お雑煮に手をつける前に時報を確認することにしました。もちろん、昨年末に製作したSIP TAを使っての実験です。

8時59分40秒になって、117をダイアルしてみたのですが。。。話し中でつながりませんでした。。かなりの「人気」だったということでしょうか? 新年早々の企てが失敗に終わってしまって、かなりメゲました。気をとり直して、新たなW-SIMジャケットの製作もそろそろ開始しようかと思っています。