年をまたがってようやくとバグを修正できたので、メモしておきます。
大晦日から久しぶりにLPC810をさわって、FTDI EVE用ソフトの修正に着手。これまではSystickタイマーを使って10ms毎の割り込みを生成し、それを使って時計の計時とディレイタイミングの生成を行っていました。少しはLPC810の機能を使ってみようと思い、これをMRT(Multi Rate Timer)を使うように変更することにしました。MRTは4チャネルのカウンタを持っており、繰り返し割り込みあるいはワンショットの割り込みをチャネル毎に生成することができます。この機能を使って、チャネル0では1秒毎の計時用割り込みを、チャネル1ではディレイ用のワンショット割り込みを生成することにしたのです。
MRTでは各チャネル毎のSTATレジスタにより割り込み要求の確認とクリヤができますが、これとは別に全チャネルの割り込み要求の確認とクリアができるIRQ_FLAGが用意されています。2つのチャネルからの割り込みを検出したいので、IRQ_FLAGレジスタを使うことにして、タイマの初期化ルーチンと、割り込みハンドラを作成。ところがちゃんと動いてくれません。割り込みを許可すると動かなくなるようなので、割り込み処理に問題があるようでした。何しろ8ピン全部を使っているので、JTAGも使えず机上デバックで試行錯誤してみることに。するとSTATレジスタを使って割り込み確認とクリヤをおこなえばちゃんと動くことが確認できました。結局、IRQ_FLAGレジスタを参照するように割り込みハンドラを作ると動かないことが判明。そこでNXPからダウンロードしてきた
となっていました。あぁ。。。やられました。途中にあるReserved01の大きさが間違っています。ただしくは、
uint32_t Reserved0[45];
です。これが原因でIRQ_FLAGレジスタのアドレスが狂っていたのです。その結果、割り込みがかかりっぱなしになってしまっていたようです。
大晦日から久しぶりにLPC810をさわって、FTDI EVE用ソフトの修正に着手。これまではSystickタイマーを使って10ms毎の割り込みを生成し、それを使って時計の計時とディレイタイミングの生成を行っていました。少しはLPC810の機能を使ってみようと思い、これをMRT(Multi Rate Timer)を使うように変更することにしました。MRTは4チャネルのカウンタを持っており、繰り返し割り込みあるいはワンショットの割り込みをチャネル毎に生成することができます。この機能を使って、チャネル0では1秒毎の計時用割り込みを、チャネル1ではディレイ用のワンショット割り込みを生成することにしたのです。
MRTでは各チャネル毎のSTATレジスタにより割り込み要求の確認とクリヤができますが、これとは別に全チャネルの割り込み要求の確認とクリアができるIRQ_FLAGが用意されています。2つのチャネルからの割り込みを検出したいので、IRQ_FLAGレジスタを使うことにして、タイマの初期化ルーチンと、割り込みハンドラを作成。ところがちゃんと動いてくれません。割り込みを許可すると動かなくなるようなので、割り込み処理に問題があるようでした。何しろ8ピン全部を使っているので、JTAGも使えず机上デバックで試行錯誤してみることに。するとSTATレジスタを使って割り込み確認とクリヤをおこなえばちゃんと動くことが確認できました。結局、IRQ_FLAGレジスタを参照するように割り込みハンドラを作ると動かないことが判明。そこでNXPからダウンロードしてきた
LPC8xx.hでMRTのレジスタ定義を確認してみると、
typedef struct { __IO uint32_t INTVAL; __IO uint32_t TIMER; __IO uint32_t CTRL; __IO uint32_t STAT; } MRT_Channel_cfg_Type; typedef struct { MRT_Channel_cfg_Type Channel[4]; uint32_t Reserved0[1]; __IO uint32_t IDLE_CH; __IO uint32_t IRQ_FLAG; } LPC_MRT_TypeDef;
となっていました。あぁ。。。やられました。途中にあるReserved01の大きさが間違っています。ただしくは、
uint32_t Reserved0[45];
です。これが原因でIRQ_FLAGレジスタのアドレスが狂っていたのです。その結果、割り込みがかかりっぱなしになってしまっていたようです。