twi.cpp

説明を見る。
00001 #include <cdefBF53x.h>
00002 #include <ccblkfn.h>
00003 #include "twi.h"
00004 
00005 /** \file twi.cpp
00006  *  \brief TWIドライバファイル
00007  *
00008  * このファイルはADSP-BF537のTWI用ドライバのドライバファイルである。
00009  * 
00010  * 注意: Analog Devices Incおよびアナログ・デバイセズ株式会社は、
00011  * このプログラムの利用によって生じるいかなる問題にも責任を負わ
00012  * ない。
00013  */
00014  
00015 namespace twi{
00016 
00017 /** データ転送バッファ・アドレス
00018  * 
00019  * 次に送信するデータのアドレス、あるいは受信データを格納するバッファのアドレス。
00020  */
00021     unsigned char * dataPtr;
00022 
00023 /** Repeated Start後に使うバッファ・アドレス
00024  * 
00025  * 現在の転送の終了後にRepeated Startを行う場合は、次の転送を行うバッファの
00026  * アドレスをこの変数に格納する。
00027  */
00028     unsigned char * nextPtr;
00029     
00030 /** Repeated Start後のデバイス・アドレス
00031  * 
00032  * 現在の転送の終了後にRepeated Startを行う場合は、次の転送を行うTWIデバイスの
00033  * アドレスをこの変数に格納する。Repeated Startを行うか否かの判断にも使うので
00034  * Repeated Startを使わない場合は必ず0にセットする。
00035  */
00036     unsigned char nextAddress = 0;
00037     
00038 /** 転送済みバイト数
00039  * 
00040  * 進行中の送信、あるいは受信データ数を数える。
00041  */
00042     unsigned int transferedCount;
00043     
00044 /** 転送するバイト数
00045  * 
00046  * 進行中の送信、あるいは受信における総転送バイト数。
00047  */
00048     unsigned int countToBeTransfer;
00049     
00050 /** Repeated Start後の転送バイト数
00051  * 
00052  * 現在の転送の終了後にRepeated Startを行う場合は、
00053  * 次の転送での送信、あるいは受信における総転送バイト数。
00054  */
00055     unsigned int nextTransfer;
00056 
00057 /** 受信フラグ
00058  * 
00059  * 現在の転送が受信ならば真、送信ならば偽
00060  */
00061     bool rcv; 
00062 
00063 /** コールバック関数
00064  * 
00065  * 現在の転送が受信ならば真、送信ならば偽
00066  */
00067     void ( * userCallBack )(bool);
00068 
00069     void init( unsigned int sclkMHz )
00070     {
00071         *pTWI_CONTROL = TWI_ENA | (sclkMHz / 10);     // TWI内部クロックを10MHzに設定
00072         *pTWI_CLKDIV = CLKHI(50) | CLKLOW(50);        // Hihg/Low期間を250クロックに設定。およそ20kHzクロック
00073         *pTWI_FIFO_CTL = XMTFLUSH | RCVFLUSH;         // FIFOをフラッシュ
00074                 // 注意: 8bitデータ転送の場合、FIFOの設定は必ずXMTINTLEN=1, RCVINTLEN=0と
00075                 // すること。この場合、送信はFIFOが空なら割り込み、受信はFIFOが空で
00076                 // ないなら割り込みがかかる。この設定では送信FIFOのアンダーラン余裕が
00077                 // 減るが、repeated startの条件(最後の送信割り込みでDCNT=0のときMDIR反転)
00078                 // を満たすためには仕方がない。アンダーラン余裕は減ったといっても1byte送信
00079                 // 時間分の余裕はある。400kbpsのとき、これは20uSである。
00080         *pTWI_FIFO_CTL = XMTINTLEN;                   // 受信:1バイトでもデータがあれば割り込み。送信:バッファが空なら割り込み
00081         *pTWI_SLAVE_CTL = 0;                          // スレーブ機能をディセーブル
00082         *pSIC_IMASK |= IRQ_TWI;
00083     }
00084     
00085     void start( void )
00086     {
00087     }
00088        
00089     bool ISR( void )
00090     {
00091         unsigned int istat;
00092         
00093         if ( *pSIC_ISR & IRQ_TWI ){                         // TWI割り込みか
00094             istat = *pTWI_INT_STAT;                         // 割込み状況の取得
00095             if ( istat & XMTSERV ) {                        // 送信割り込みか
00096                 if ( countToBeTransfer == transferedCount ){// 全部送信したか
00097                     *pTWI_INT_MASK &= ~XMTSERV;             // 送信割り込み禁止
00098                     if ( nextAddress )                      // これはrepeated Startを使うか
00099                        *pTWI_MASTER_CTL |= MDIR;            // 転送方向を受信に
00100                 }
00101                 else {                                      // まだ送信が終わっていない
00102                     *pTWI_XMT_DATA8 = *(dataPtr++);         // 1バイト転送
00103                     transferedCount ++;                     // 転送バイト数更新
00104                 }
00105                 *pTWI_INT_STAT = XMTSERV;                   // 送信割り込みクリア
00106             }
00107             else if ( istat & RCVSERV ) {                   // 受信割り込みか
00108                 *(dataPtr++) = *pTWI_RCV_DATA8;             // 1バイト転送
00109                 *pTWI_INT_STAT = RCVSERV;                   // 受信割り込みクリア
00110                 transferedCount ++;                         // 転送バイト数更新
00111             }
00112             else if ( istat & MCOMP ){                      // データ転送完了か
00113                 *pTWI_INT_STAT = MCOMP;                     // 割込みクリア
00114                 *pTWI_INT_MASK &= ~(RCVSERV|XMTSERV|MCOMP); // 割り込みを禁止にする
00115                 if ( rcv ){                                 // 受信か
00116                     if ( *pTWI_FIFO_STAT & RCVSTAT ) {      // FIFOにデータが残っているか
00117                         *(dataPtr++) = *pTWI_RCV_DATA8;     // 最後の受信バイトを取得する
00118                         transferedCount ++;                 // 転送バイト数更新
00119                     }
00120                     if ( userCallBack )                     // 受信コールバックは必要か
00121                         userCallBack(true);                 // コールバック呼び出し
00122                 }
00123                 else{                                       // 送信終了
00124                     if ( nextAddress )                      // repoeated Startを使っているか
00125                         readAsync( nextAddress, nextPtr, nextTransfer, userCallBack );
00126                     else if ( userCallBack )                // 送信コールバックは必要か
00127                         userCallBack(false);                // コールバック呼び出し
00128                 }
00129             }
00130             ssync();
00131             return true;                                    // 割込み処理を行ったことを知らせる
00132         }                                                   // TWI割り込み処理終わり
00133         else
00134             return false;                                   // 割込み処理を行わなかった
00135     }
00136     
00137     void readAsync( 
00138                 unsigned char address,      // 通信相手のI2Cアドレス
00139                 unsigned char data[],       // 受信バッファ・アドレス
00140                 unsigned int count,         // 受信するデータ数
00141                 void ( * callback )( bool ) // 受信完了後呼び出すコールバック
00142                 )
00143     {
00144         rcv = true;                         // 受信
00145         nextAddress = 0;                    // Repeated Startを使わない。
00146         countToBeTransfer = count;          // 受信するデータ数
00147         dataPtr = (unsigned char *)data;    // バッファ・ポインタをセット
00148         userCallBack = callback;            // コールバック関数をセット
00149         *pTWI_INT_MASK = 0;                 // 割り込みを一時禁止
00150         *pTWI_MASTER_ADDR = address;        // 7bit アドレスを設定
00151         transferedCount = 0;                // 受信済みデータ数
00152         *pTWI_MASTER_CTL = MEN | MDIR | DCNT & ( count << 6 ); // マスターモード、受信、アドレス設定
00153         *pTWI_INT_MASK = RCVSERV | MCOMP;   // 割込みマスク設定
00154     } 
00155     
00156 /** writeAsyncの下請け関数
00157  * @param address 書き込みを行うデバイスの7bit TWIアドレス。
00158  * @param data 書き込むデータの配列
00159  * @param count 書きこみデータ数。単位はバイト。
00160  * @param callback 送信完了割り込み時に呼び出されるコールバック関数。NULLを指定すると何も呼び出されない。
00161  *
00162  * I2C送信の処理実体。 twi::writeAsyncと twi::writeReadAsyncは、
00163  * repeated Startに関する設定を行った後、残りの処理をこの関数に
00164  * 丸投げする。
00165  *
00166  * writeAsync関数は、I2Cデバイスアドレスを設定後、最初の1バイトを
00167  * FIFOに書き込んでから送信をイネーブルにする。
00168  */
00169         // 送信関数の下請け。
00170     void writeAsyncSub( 
00171                 unsigned char address,      // 通信相手のI2Cアドレス
00172                 const unsigned char data[], // 送信バッファ・アドレス
00173                 unsigned int count,         // 送信バイト数
00174                 void ( * callback )( bool ) // 送信完了後呼び出すコールバック
00175                 )
00176     {
00177         rcv = false;                        // 送信
00178         countToBeTransfer = count;          // 送信するデータ数
00179         dataPtr = (unsigned char *)data;    // バッファ・ポインタをセット
00180         userCallBack = callback;            // コールバック関数をセット
00181         *pTWI_INT_MASK = 0;                 // 割り込みを一時禁止
00182         *pTWI_MASTER_ADDR = address;        // 7bit アドレスを設定
00183         *pTWI_XMT_DATA8 = *(dataPtr++);     // 最初の1バイトを転送
00184         transferedCount = 1;                // 送信済みデータ数
00185   
00186         *pTWI_MASTER_CTL |= MEN | DCNT & ( count << 6 ); // マスターモード、送信、アドレス設定
00187         *pTWI_INT_MASK = XMTSERV | MCOMP;   // 割込みマスク設定
00188     }
00189                 
00190         // 送信関数。REPEATED STARTを行わない設定で送信を行う
00191     void writeAsync( 
00192                 unsigned char address,      // 通信相手のI2Cアドレス
00193                 const unsigned char data[], // 送信バッファ・アドレス
00194                 unsigned int count,         // 送信バイト数
00195                 void ( * callback )( bool ) // 送信完了後呼び出すコールバック
00196                 )
00197     {
00198         nextAddress = 0;                    // Repeated Startを使わない。
00199         *pTWI_MASTER_CTL = 0;               // Repeated Startを使わない
00200                                             // 主処理
00201         writeAsyncSub( address, data, count, callback );
00202     }
00203     
00204     void writeReadAsync( 
00205                 unsigned char wAddress,      // 通信相手のI2Cアドレス(受信)
00206                 const unsigned char wData[], // 送信バッファ・アドレス
00207                 unsigned int wCount,         // 送信バイト数
00208                 unsigned char rAddress,      // 通信相手のI2Cアドレス(受信)
00209                 const unsigned char rData[], // 受信バッファ・アドレス
00210                 unsigned int rCount,         // 受信バイト数
00211                 void ( * callback )( bool )  // 受信完了後呼び出すコールバック
00212                 )
00213     {
00214         nextTransfer = rCount;              // Repeated Start後の受信データ数
00215         nextPtr = (unsigned char *)rData;   // Repeated Start後の受信バッファ
00216         nextAddress = rAddress;             // Repeated Start後の受信デバイスアドレス
00217         *pTWI_MASTER_CTL = RSTART;          // Repeated Startを使う
00218                                             // 主処理
00219         writeAsyncSub( wAddress, wData, wCount, callback );
00220     }
00221 
00222 };
00223 
00224 

AudioFrameWorkに対してMon Apr 9 16:33:24 2007に生成されました。  doxygen 1.5.1-p1