OSDN Git Service

First commitment for the BlackTank LPC1769.
[blacktank/blacktank.git] / i2s_subsystem.h
1 /**
2  * @file i2s_subsystem.h
3  * @brief I2S操作関数群
4  * @date 2011/02/19
5  * @author Takemasa Nakamura
6  * @details
7  * @ref i2s_init 関数を使ってI2Sペリフェラルを初期化し、
8  * 次に @ref i2s_dma_init 関数を使ってDMA機能を初期化する。
9  * 最後に @ref i2s_start 関数を呼ぶことで実際のI2S動作が始まる。
10  *
11  * I2Sはダブルバッファを使う。
12  * バッファのデータ転送が終わるたびにDMA割り込みが入る。
13  * この割り込みを処理するにはDMA割り込みが起きるたびに、
14  * @ref i2s_dma_intr_handler 関数を割り込みハンドラ内部から呼べばよい。
15  *
16  * @ref audio_task 関数は、オーディオ処理タスクの実態であり、
17  * TOPPERS/ASPのタスクにすること。
18  * この関数はSEM_I2SDMAセマフォを使って @ref i2s_dma_intr_handler と
19  * 同期するため、SEM_I2SDMAセマフォを用意しておかなければならない。
20  *
21  * @ref process_audio 関数は、audio_processing.c でユーザーが実装すべき
22  * オーディオ信号処理関数である。この関数は audio_task から呼び出される。
23  */
24
25 #ifndef I2S_SUBSYSTEM_H_
26 #define I2S_SUBSYSTEM_H_
27
28 #include <LPC17xx.h>
29 #include <kernel.h>
30 #include <t_syslog.h>
31 #include "audio_common.h"
32
33 /**
34  * @brief DMA用のリンクリストの構成要素型
35  * @details
36  * LP17xxの GPDMAはスキャッタ、ギャザーにも使用できるリンクリストを
37  * 構成できる。LLI型はそのリストの構成単位となるデータ型である。
38  * 基本的にLLIはLPC1768のユーザーズマニュアル、UM10360で記述されている
39  * DMA LLIそのままである。
40  * 詳しくはユーザーズマニュアル参照の事。
41  */
42 struct LLI {
43     int * SrcAddr;  /**< DMAのソース・バッファ・アドレス */
44     int * DstAddr;  /**< DMAのデスティネーション・バッファ・アドレス・ */
45     struct LLI * nextLLI;   /**< 次のLLI要素へのポインタ */
46     unsigned int Control;   /**< DMAコントロール・レジスタへのロード値 */
47 };
48
49 /**
50  * @brief I2S用データ
51  * @details DMA転送などに使うデータを一ヶ所にあつめたもの。
52  */
53 struct I2S_AUDIO_DATA {
54     /**
55      * @brief 送信DMA用のLLIリスト
56      * @details
57      * LLIチェーンは2要素をもち、全体でサーキュラーバッファを構成する。
58      * 初期化は @ref i2s_dma_init で行う。
59      */
60     struct LLI txI2SLLI[2];
61
62     /**
63      * @brief 受信DMA用のLLIリスト
64      * @details
65      * LLIチェーンは2要素をもち、全体でサーキュラーバッファを構成する。
66      * 初期化は @ref i2s_dma_init で行う。
67      */
68     struct LLI rxI2SLLI[2];
69
70     /**
71      * @brief I2S送信DMAのバッファ
72      * @details
73      * DMAを使ってI2Sポートから送信するためのデータバッファ。
74      * 二つのバッファを持つのは、ピンポン(ダブルバッファ)
75      * 制御を行うためである。
76      * DMA転送中にプログラムが次の送信データを書き込むためのバッファを
77      * 取得するには、
78      * @ref i2s_getTxBuf 関数を使う。
79      */
80     AUDIOSAMPLE txBuffer[2][AUDIOBUFSIZE];
81
82     /**
83      * @brief I2S受信DMAのバッファ
84      * @details
85      * DMAを使ってI2Sポートから受信するためのデータバッファ。
86      * 二つのバッファを持つのは、ピンポン(ダブルバッファ)
87      * 制御を行うためである。
88      * DMA転送中にプログラムが直前の受信データを読み込むための
89      * バッファを取得するには、 @ref i2s_getRxBuf 関数を使う。
90      */
91     AUDIOSAMPLE rxBuffer[2][AUDIOBUFSIZE];
92 };
93
94 /**
95  * @brief I2S 初期化ルーチン
96  * @details
97  * LPC1768のI2Sペリフェラルを初期化する。送受信とも
98  * @li スレーブ
99  * @li 32bit
100  * @li 4ワイアー
101  * である。DMA1をRXに、DMA2をTXに割り当てている。
102  *
103  * なお、このルーチンは初期化はするが、I2Sを起動しない。
104  * 起動はDMAの設定が終わった後に @ref i2s_start ルーチンを呼んで行う。
105  *
106  * @todo
107  * 現在の設定でも過不足なく動くが、TXのクロックをRXから分けるようにすれば、
108  * もっと少ないピン数で動作させることもできるはずである。
109  */
110 void i2s_init();
111
112 /**
113  * @brief DMA初期化
114  * @details
115  * I2Sに関連づけされたDMAを初期化する。
116  * 同時に、LLIを初期化して、ピンポンバッファをすぐに使えるような
117  * 状態にする。
118  * 受信DMAは各バッファの受信完了ごとにDMA割り込みをおこす。
119  * 送信では起こさない。
120  * プログラムはこれに同期してタスクと協調動作をする。
121  *
122  * DMA受信割り込みは @ref dma_intr_handler で処理を行う。
123  *
124  * @todo
125  * DMAの割り当ては決め打ちである。
126  * 適切なDMA管理機構を使用して衝突を避ける。
127  */
128 void i2s_dma_init();
129
130 /**
131  * @brief I2S 開始。DMA初期化後に行う
132  * @details
133  * @ref i2s_init ルーチンと @ref i2s_dma_init ルーチンによって準備を
134  * 終えた後、このルーチンを呼び出してi2sによる転送を始める。
135  */
136 void i2s_start();
137
138 /**
139  * @brief I2S DMA 割り込みハンドラの初期化を行う
140  * @details
141  * LPC1768のDMA割り込みステータスをチェックし、I2S DMA 受信TC割り込みが
142  * 発生していたら、その割り込みに対処する。
143  */
144 void i2s_dma_intr_handler();
145
146 AUDIOSAMPLE * i2s_getTxBuf();
147 AUDIOSAMPLE * i2s_getRxBuf();
148
149 #endif
150