openMSP430を使ってみる[ハードウェア編]
※この記事は3部に分かれています。以下の記事も併せてどうぞ。
| Link |
|---|
| (1) openMSP430を使ってみる[導入・開発環境整備編] この記事は導入〜開発環境整備・デモプロジェクトの構成説明までの内容です |
| (2) openMSP430を使ってみる[ハードウェア編] ※この記事です |
| (3) openMSP430を使ってみる[ファームウェア編] ファームウェアのカスタマイズ・コンパイルとデバッガを利用したデバッグの方法を紹介します |
| デモプロジェクト: https://github.com/tmct-web/omsp430_demo_tmct この記事で使用しているデモプロジェクトはこのリンクからダウンロードしましょう |

RTLをカスタマイズする
プロジェクト自体が大きいので一体何から手を付ければ良いのか迷いますが、以下の順でカスタマイズすると良いでしょう。
- openMSP430_defines.v をカスタマイズ
- プログラムメモリ・データメモリの実装・接続
- 割り込み信号の接続
- ペリフェラルバスの接続
openMSP430_defines.v をカスタマイズ
まず openMSP430_defines.v を修正します。
openMSP430_defines.v は /rtl/omsp430 にあります。コピーして別の場所に配置したものを編集・使用した方が良いでしょう。デモプロジェクトでは /board 以下のフォルダにボード固有ファイルとして配置し、それを使用しています。
カスタマイズは openMSP430 のドキュメントや openMSP430_defines.v に詳しく記載されているのでそれを見ながら修正していきます。
大まかなカスタマイズポイントを以下に示します。
| Item | Details |
|---|---|
![]() |
プログラムメモリのサイズ 実装するプログラムメモリのサイズを選んでコメントアウトを外します。
|
![]() |
データメモリのサイズ 実装するデータメモリのサイズを選んでコメントアウトを外します。
|
![]() |
ハードウェア乗算器を実装する? コメントを外す: ハードウェア乗算器が実装されます。 コメント化: ハードウェア乗算機は実装されません。 乗算の際にハードウェア乗算器を使用することで乗算速度が非常に高速になりますが、よほど乗算を多用するようなプログラムを書かない限りほとんど恩恵はないでしょう。 |
![]() |
デバッグインターフェイスを実装する? コメントを外す: デバッグインターフェイスが実装されます。 コメント化: デバッグインターフェイスが実装されません。 CPUを介さずにメモリ空間にアクセスできる・ファームウェアを転送できるなど非常に利便性が高いため、実装することを強くお勧めします。 |
![]() |
ユーザーバージョン値 FPGA論理のレビジョン管理などに利用可能なバージョン値を設定することができます。 |
![]() |
Watch Dog Timerを実装する? コメントを外す: WDT機能が実装されます。 コメント化: WDT機能が実装されません。 WDT機能が実装されない場合、以下の機能も利用できなくなります。
|
![]() |
DMA機能を実装する? コメントを外す: DMA機能が実装されます。 コメント化: DMA機能が実装されません。 DMA利用時の信号タイミング仕様などは openMSP430 の仕様書に詳しい記載があります。 |
![]() |
NMIを使う? コメントを外す: NMI(Non Maskable Interrupt)機能が実装されます。 コメント化: NMI機能が実装されません。 |
![]() |
IRQのサポート数 IRQをサポートする数を選んでコメントを外します。 通常は IRQ_16 でうち 13本 のIRQを自由に扱うことができます。 これ以外の設定を行った場合、リンカースクリプトを大きく書き換える必要が生じます。 |
![]() |
入力を同期化する? NMI・CPU_EN・DBG_EN 信号 をCPUクロックで同期化するか選択します。 コメントを外すとその信号が同期化されます。 よくわからない場合は同期化しておけばよいでしょう。 |
![]() |
ペリフェラル領域のサイズ 周辺モジュールが利用するメモリ領域のサイズを選んでコメントを外します。 通常は 512Bytes です。 この設定を変更した場合、リンカースクリプトを大きく変更する必要があります。 |
![]() |
リセット解除後に停止状態を保持する? コメントを外す: リセット解除後にCPUは自動的に停止状態になります。 コメント化: リセット解除後、CPUはプログラムメモリ内のプログラムを実行し始めます。 デバッグ初期など、プログラムメモリが空っぽでデバッグインターフェイスから毎回プログラムを送って動作確認する場合はコメントを外しておくと便利です。 ※この設定があることを知らないと「リセットを解除しているのに動かない」とハマるので注意が必要です。 |
![]() |
デバッグインターフェイスのプロトコル デバッグインターフェイスを使用する場合、サポートするプロトコルを選択してコメントを外します。 ミニデバッガを使用するために UART を強く推奨します。 |
![]() |
デバッグインターフェイスのI2Cブロードキャスト サポート デバッグインターフェイスを有効にしてプロトコルにI2Cを選択した場合、ブロードキャストアドレスで openMSP430 を制御できるようにする場合はコメントを外します。 openMSP430 を複数実装してリセット・開始・停止など同時制御したい場合を除き、コメント状態にしておけばよいです。 |
![]() |
ハードウェアブレイクポイントの数 ハードウェアブレイクポイントを使用する場合、何個までサポートするか選択してコメントを外します。 |
![]() |
ハードウェアブレイクポイントのサポート範囲 コメントを外すと、CPUメモリ空間内で命令やデータアクセスが遅延するたびに、ハードウェアブレークポイントユニットがCPUを停止させることができます。 |
![]() |
カスタムメモリサイズ 各種メモリ領域の設定でカスタムサイズを使う設定を行ったときの、具体的なメモリサイズをここに設定します。 |
![]() |
ASIC向け? FPGA向けに論理合成するため、通常はコメントしたままにします。 |
基本的にどうにでも構成できますが、以下には注意が必要です。
- プログラムメモリやデータメモリの容量は好きなようにできます。
ただしあまり大きくするとFPGAのハードウェアリソースに収まらない可能性があるので、FPGAの中ではあくまで脇役であることを忘れずに。
- ペリフェラル領域のサイズやIRQの数をデフォルト値から変更した場合、リンカースクリプト(*.x)を大きく修正する必要があります。
特殊なケースなのでこの記事では触れません。
たぶんググっても断片的な情報しか出てこないので変更する場合は相応のスキルが要ります。
プログラムメモリ・データメモリの実装
プログラムメモリ と データメモリ は PMPM_SIZE と DMEM_SIZE で定義した容量と同じバイト数のメモリを実装します。
openMSP430 のデータバス幅は 16bit なのでワード数だと半分になることに注意が必要です。
たとえばプログラムメモリサイズを `define PMEM_SIZE_8_KB として 8kBytes と定義した場合、16bitのメモリを 4kWords (4096Words=8192Bytes) だけ確保します。
また、プログラムメモリの初期値は \firmware\output フォルダ内に生成される *.mif ファイル(または *.binファイル) を参照するよう設定することをお忘れなく。
なお、プログラムメモリ・データメモリ・ペリフェラル領域 の合計サイズは 64kBytes を超えてはなりません。
「たったの64キロバイト?」と思うかもしれませんが、大したインターフェイスもなくOSも載っていないマイコンにとって64キロバイトはかなり大きなメモリ量です。
Quartus でメガファンクション(IP)として実装した例を示します。
プログラムメモリの実装例
以下の例は 32kBytes を実装した例です。
デバッグインターフェイスからも内容の書き換えができるよう、プログラムメモリであってもRAMとして実装します。
| Item | Points |
|---|---|
![]() |
データバス幅は 16bits です。 たとえば openMSP430_defines.v に 32kBytes として定義した場合、容量としては 16384Words を設定します。 |
![]() |
データの出力バスは Unregistered(出力をラッチしない)設定とします。 また、Clock Enable入力・Byte Enable入力を有効にします。 |
![]() |
Write/Readが競合した場合の動作設定ですが、openMSP430 ではそんな状態にはならないので設定変更の必要はありません。 |
![]() |
プログラムメモリの初期値のファイルを設定します。 \firmware\output フォルダ内に生成される *.mif ファイル(または *.binファイル) を参照するよう設定します。 |
openMSP430 コアとの Verilog での接続例は以下です。
// openMSP430 core
openMSP430 m_cpu0
(
// output
.pmem_addr (pmem_addr), // Program Memory address
.pmem_cen (pmem_cen), // Program Memory chip enable (low active)
.pmem_din (pmem_data), // Program Memory data input (optional)
.pmem_wen (pmem_wen), // Program Memory write enable (low active) (optional)
.puc_rst (puc_rst), // Main system reset
//input
.dco_clk (cpu_clk), // Fast oscillator (fast clock)
.pmem_dout (pmem_q) // Program Memory data output
);
// Program memory
progmem m_progmem0
(
.address (pmem_addr),
.byteena (~pmem_wen[1:0]),
.clken (~pmem_cen),
.clock (cpu_clk),
.data (pmem_data[15:0]),
.wren (~(&pmem_wen[1:0])),
.q (pmem_q[15:0])
);
データメモリの実装例
以下の例は 8kBytes を実装した例です。
| Item | Points |
|---|---|
![]() |
データバス幅は 16bits です。 たとえば openMSP430_defines.v に 8kBytes で定義した場合、容量としては 4096Words に設定します。 |
![]() |
データの出力バスは Unregistered(出力をラッチしない)設定とします。 また、Clock Enable入力・Byte Enable入力を有効にします。 |
![]() |
Write/Readが競合した場合の動作設定ですが、openMSP430 ではそんな状態にはならないので設定変更の必要はありません。 |
![]() |
プログラムメモリの初期値のファイルを設定します。 初期値を設定してもスタートアップで初期化されるため、ブランクで構いません。 |
openMSP430 コアとの Verilog での接続例は以下です。
// openMSP430 core
openMSP430 m_cpu0
(
// output
.dmem_addr (dmem_addr), // Data Memory address
.dmem_cen (dmem_cen), // Data Memory chip enable (low active)
.dmem_din (dmem_data), // Data Memory data input
.dmem_wen (dmem_wen), // Data Memory write byte enable (low active)
//input
.dco_clk (cpu_clk), // Fast oscillator (fast clock)
.dmem_dout (dmem_q) // Data Memory data output
);
// Data memory
datamem m_datamem0
(
.address (dmem_addr),
.byteena (~dmem_wen[1:0]),
.clken (~dmem_cen),
.clock (cpu_clk),
.data (dmem_data[15:0]),
.wren (~(&dmem_wen[1:0])),
.q (dmem_q[15:0])
);
割り込み信号の接続
openMSP430 に対する割り込み入力は以下の2種類です。
いずれも Active High の信号で、High の間は割り込みが発生し続けることに注意してください。
- IRQ: マスク可能な割り込み
openMSP430_defines.v の `define IRQ_xx のコメントを外すことで使用可能になります。
ただし以下の3つはシステムで固定されているため自由に使用することはできません。
IRQ15: ハードウェアリセット
IRQ14: NMI
IRQ10: Watch Dog Timer - NMI: マスク不可能な割り込み
openMSP430_defines.v の `define NMI のコメントを外すことで使用可能になります。
openMSP430 コアとの Verilog での接続例を以下に示します。
ただし以下の例は `define IRQ_16 とした場合です。それ以外は irq_bus のビット数を定義に応じて増やす必要があります。
wire [13:0] irq_bus;
wire nmi;
wire irq_irq1;
wire irq_irq0;
// openMSP430 core
openMSP430 m_cpu0
(
//input
.irq (irq_bus), // Maskable interrupts (14, 30 or 62)
.nmi (nmi) // Non-maskable interrupt (asynchronous and non-glitchy)
);
// Interrupt request bus
assign irq_bus = {
1'b0, // Vector 13 (0xFFFA)
1'b0, // Vector 12 (0xFFF8)
1'b0, // Vector 11 (0xFFF6)
1'b0, // Vector 10 (0xFFF4) - Watchdog -
1'b0, // Vector 9 (0xFFF2)
1'b0, // Vector 8 (0xFFF0)
1'b0, // Vector 7 (0xFFEE)
1'b0, // Vector 6 (0xFFEC)
1'b0, // Vector 5 (0xFFEA)
1'b0, // Vector 4 (0xFFE8)
1'b0, // Vector 3 (0xFFE6)
1'b0, // Vector 2 (0xFFE4)
irq_irq1, // Vector 1 (0xFFE2)
irq_irq0 // Vector 0 (0xFFE0)
};
ペリフェラルバスの接続
ペリフェラルバス(周辺モジュール制御用バス)は一般的なCPUバスシステムとほぼ同じです。
ただし openMSP430 のコアはアドレスデコードまではやってくれないので、そこは自力で実装する必要があります。
自分に割り当てられたバス空間に対してReadアクセスされた場合、per_dout にデータを返すようにします。くれぐれも自分のバス空間でないのに per_dout を駆動してはなりません。
/rtl/omsp430/periph/template_periph_8b.v または /rtl/omsp430/periph/template_periph_16b.v が参考になるでしょう。
以下には例として openMSP430 コアと basic_uart_tmct 、 I2C マスタコア 、 basic_gpio を接続した例を示します。
wire puc_rst;
wire per_clk;
wire [13:0] per_addr;
wire [15:0] per_mosi;
wire [15:0] per_miso;
wire [15:0] per_miso_uart;
wire [15:0] per_miso_i2c;
wire [15:0] per_miso_gpio;
wire per_en;
wire [1:0] per_we;
// openMSP430 core
openMSP430 m_cpu0
(
// output
.mclk (per_clk), // Main system clock
.per_addr (per_addr), // Peripheral address
.per_din (per_mosi), // Peripheral data input
.per_en (per_en), // Peripheral enable (high active)
.per_we (per_we), // Peripheral write byte enable (high active)
.puc_rst (puc_rst), // Main system reset
//input
.per_dout (per_miso) // Peripheral data output
);
// Peripheral data bus (Master-In Slave-Out)
assign per_miso = per_miso_uart | per_miso_i2c | per_miso_gpio;
// Basic UART Register
regs_uart m_regs_uart0
(
.i_mclk (per_clk),
.i_per_addr (per_addr),
.i_per_din (per_mosi),
.i_per_en (per_en),
.i_per_we (per_we),
.i_puc_rst (puc_rst),
.o_per_dout (per_miso_uart)
);
// I2C master Register
regs_i2c m_regs_i2c0
(
.i_mclk (per_clk),
.i_per_addr (per_addr),
.i_per_din (per_mosi),
.i_per_en (per_en),
.i_per_we (per_we),
.i_puc_rst (puc_rst),
.o_per_dout (per_miso_i2c),
);
// Basic GPIO Register
regs_gpio m_regs_gpio0
(
.i_mclk (per_clk),
.i_per_addr (per_addr),
.i_per_din (per_mosi),
.i_per_en (per_en),
.i_per_we (per_we),
.i_puc_rst (puc_rst),
.o_per_dout (per_miso_gpio),
);
まとめ
openMSP430についてハードウェア・RTLのカスタマイズまでを紹介しました。
続きはこちらをどうぞ。
| Link |
|---|
| (1) openMSP430を使ってみる[導入・開発環境整備編] この記事は導入〜開発環境整備・デモプロジェクトの構成説明までの内容です |
| (2) openMSP430を使ってみる[ハードウェア編] ※この記事です |
| (3) openMSP430を使ってみる[ファームウェア編] ファームウェアのカスタマイズ・コンパイルとデバッガを利用したデバッグの方法を紹介します |
| デモプロジェクト: https://github.com/tmct-web/omsp430_demo_tmct この記事で使用しているデモプロジェクトはこのリンクからダウンロードしましょう |

























