やりとりする方法はいくつかありますが、比較的易しい、並列入力(Parallel in)を使ったデータ転送を取り上げます。まとまった値を一度に転送することができ、プログラムとしても理解しやすいですが、8ビット値以外は扱えません。
以上を踏まえて、フルスクラッチで7セグLEDドライバーを作ってみましょう。プロジェクトを新規作成して、シンボルウィザードを使ってカスタムコンポーネントを追加します。出力端子のプロパティ画面の「Bit Range」を「7:0」にすると8本のワイヤを並列に扱うことができるようになります。
7seg.v
`include "cypress.v"
module pa_out (
input clock,
output[7:0] led_out
);
cy_psoc3_dp #(.cy_dpconfig(
{
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM0: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM1: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM2: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM3: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM4: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM5: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM6: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM7: */
8'hFF, 8'h00, /*CFG9: */
8'hFF, 8'hFF, /*CFG11-10: */
`SC_CMPB_A1_D1, `SC_CMPA_A1_D1, `SC_CI_B_ARITH,
`SC_CI_A_ARITH, `SC_C1_MASK_DSBL, `SC_C0_MASK_DSBL,
`SC_A_MASK_DSBL, `SC_DEF_SI_0, `SC_SI_B_DEFSI,
`SC_SI_A_DEFSI, /*CFG13-12: */
`SC_A0_SRC_ACC, `SC_SHIFT_SL, `SC_PI_DYN_DS,
1'h0, `SC_FIFO1_BUS, `SC_FIFO0_BUS,
`SC_MSB_DSBL, `SC_MSB_BIT0, `SC_MSB_NOCHN,
`SC_FB_NOCHN, `SC_CMP1_NOCHN,
`SC_CMP0_NOCHN, /*CFG15-14: */
10'h00, `SC_FIFO_CLK__DP,`SC_FIFO_CAP_AX,
`SC_FIFO_LEVEL,`SC_FIFO__SYNC,`SC_EXTCRC_DSBL,
`SC_WRK16CAT_DSBL /*CFG17-16: */
}
)) dp(
.clk(clock),
.cs_addr(3'b000),
.po(led_out)
);
endmodule
あとはC言語から対象コンポーネントのA0レジスタを直接制御すればデータパスに値を設置することができます。しかしながら、都度「CY_SET_REG8(led_out_dp__A0_REG, v)」のようにレジスタ書き込みマクロをプログラムに逐次記述してしまうと、設計者以外にはそれが何のことであるかがさっぱり伝わりません。なので、API(生成されるアプリソースファイルのひな形)を用意することで、その問題に対応することにしましょう。
プロジェクト「Components」タブにある、カスタムコンポーネントを右クリックして「Add Component Item」を選び、一覧から「API Header File」を選んでテンプレートファイルを作成します。
テンプレートファイル用マクロには「CY_MAJOR_VERSION」などいくつかの組み込みパラメーターがありますが、基本的に「`$INSTANCE_NAME`」をAPIの名称に含ませると考えましょう。
この例では、7セグLEDの数値に応じたa~gランプの定義と、値を設置するAPIのひな形を登録しています。どのピンがどのランプにつながるかはメーカーにより異なってくるため、こちらはプログラム側で定義することにしています。
トップデザインはこのようになります。出力ピンの設定で「Mapping→Display as bus」にチェックを入れることで、コンポーネントと接続することができるようになります。
こちらは余談ですが、「Component Catalog」にある「Off-Chip」ライブラリーを使うと、簡単な回路図をデザインとして埋め込むことができます。これはプログラムを使用する人にとって見やすくするためのもので、コンパイルやマイコンの実行結果には一切影響しません。
こちらはソフトウェアサンプルです。一定回数ごとにLED点灯の配置を変更し、10回ごとにドットLEDを明滅させています。SEG_LA~SEG_LGの値はお使いの7セグLEDのピン配置に応じて値を変えてください。