• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

TWIペリフェラルを使ってI2Cプロトコルを制御する


Commit MetaInfo

Revisão970a68376e9e8b99dbb8b954d0f8c5ea49d7fe69 (tree)
Hora2012-08-01 06:53:00
Autortakemasa <suikan@sour...>
Commitertakemasa

Mensagem de Log

ソース入力完了

Mudança Sumário

Diff

--- a/i2c-test/i2c_subsystem.c
+++ b/i2c-test/i2c_subsystem.c
@@ -16,14 +16,19 @@
1616 #define I2CNUM 0
1717
1818 /**
19+ * \brief I2C ペリフェラルのタイムアウト時間(mSec)
20+ */
21+#define I2C_TIMEOUT 100
22+
23+/**
1924 * \brief TWIペリフェラルの管理用ステート型。内部ステートマシンの状態値。
2025 */
2126 enum I2C_STATE {
22- I2C_XMIT_ENTRY,
27+ I2C_XMT_ENTRY,
2328 I2C_XMTRCV_ENTRY,
24- I2C_XMT_WIT_WAIT,
25- I2C_XMIT_INT,
26- I2C_XMIT_NEXT_BYTE,
29+ I2C_XMT_WAIT,
30+ I2C_XMT_INT,
31+ I2C_XMT_NEXT_BYTE,
2732 I2C_RCV_ENTRY,
2833 I2C_RCV_WAIT,
2934 I2C_RCV_INT,
@@ -38,7 +43,7 @@ enum I2C_STATE {
3843 struct I2C_MASTER_CONTROL_TYPE {
3944 ID signal; /**< データの送受信が全部終わったときに割り込みハンドラからタスクに知らせるためのセマフォ */
4045 ID blocking; /**< I2Cペリフェラルへの排他アクセスのためのセマフォ */
41- unsigned short int_state; /**< TWIペリフェラルの割り込みステータスのコピー **/
46+ unsigned short intr_state; /**< TWIペリフェラルの割り込みステータスのコピー **/
4247 enum I2C_STATE state; /**< I2Cペリフェラルハンドラの内部状態 */
4348 volatile uint16_t * clkdiv ;
4449 volatile uint16_t * control ;
@@ -77,11 +82,19 @@ int i2c_master_read( int peripheral, int slave, unsigned char read_data[], int r
7782 int i2c_master_write_read( int peripheral, int slave, unsigned char write_data[], int write_count, unsigned char read_data[], int read_count)
7883 {
7984 struct I2C_MASTER_CONTROL_TYPE *twi;
80- BOOL read, write;
85+ BOOL read, write, rstart;
86+ unsigned char *wptr, *rptr;
8187
8288 // 可読性向上のため、TWI管理構造体のポインタを設定する。
8389 twi = &i2c_control[peripheral];
8490
91+ // 送受信ポインタ.とかくこの世は生きにくい
92+ wptr = write_data;
93+ rptr = read_data;
94+
95+ // この代入は必要ないが、警告がうるさいので
96+ rstart= FALSE;
97+
8598 // 読み書きの有無の確認
8699 // バッファがNULLだったり長さが0のパラメタは転送に使わない
87100 write = ( write_data != NULL ) && ( write_count != 0 );
@@ -91,28 +104,86 @@ int i2c_master_write_read( int peripheral, int slave, unsigned char write_data[]
91104 if ( read && write )
92105 twi->state = I2C_XMTRCV_ENTRY;
93106 else if ( write && ! read )
94- twi->state = I2C_XMIT_ENTRY;
107+ twi->state = I2C_XMT_ENTRY;
95108 else if ( ! write && read )
96109 twi->state = I2C_RCV_ENTRY;
97110 else
98111 return I2C_ERR_WRONGPARAM;
99112
113+ if ( write_count > 254 || read_count > 254 )
114+ return I2C_ERR_TOOLONGBUFFER;
115+
100116
101117 // peripheral 引数で指定されたi2cペリフェラルを排他的に使うためのPV処理。
102118 // これでスレッドセーフにできる
103119 wai_sem(twi->blocking);
104120
105- twi->master_addr =
106- // TODO
121+ // SPIスレーブデバイスのアドレスを設定(7bit)
122+ *twi->master_addr = peripheral;
123+
107124 // TWIステートマシン
108125 do {
109126 switch (twi->state)
110127 {
111- case I2C_XMIT_ENTRY :
128+ case I2C_XMT_ENTRY :
129+ rstart = FALSE;
130+ *twi->master_ctl = ( write_count<<6 ) | MEN; // no rstart, transmit, no fast mode;
131+ twi->state = I2C_XMT_WAIT;
132+ break;
133+ case I2C_XMTRCV_ENTRY :
134+ rstart = TRUE;
135+ *twi->master_ctl = ( write_count<<6 ) | RSTART | MEN; // rstart, transmit, no fast mode;
136+ twi->state = I2C_XMT_WAIT;
137+ break;
138+ case I2C_RCV_ENTRY :
139+ rstart = FALSE;
140+ *twi->master_ctl = ( write_count<<6 ) | MDIR | MEN; // no rstart, receive, no fast mode;
141+ twi->state = I2C_RCV_WAIT;
142+ break;
143+ case I2C_XMT_WAIT :
144+ // 割り込みハンドラが送信割り込みを通知するまで待つ
145+ if ( E_OK == twai_sem(twi->signal, I2C_TIMEOUT))
146+ {
147+ twi->intr_state = I2C_ERR_TIMEOUT;
148+ twi->state = I2C_EXIT;
149+ }
150+ else
151+ twi->state = I2C_XMT_INT;
152+ break;
153+ case I2C_XMT_INT :
154+ if ( twi->intr_state & MERR ) // エラーならすぐ終了
155+ twi->state = I2C_EXIT;
156+ else if ( ( twi->intr_state & MCOMP ) && rstart) // MCOMP かつ RSTARTなら受信へ
157+ twi->state = I2C_RCV_ENTRY;
158+ else if ( twi->intr_state & MCOMP ) // RSTARTがないMCOMPなら終了
159+ twi->state = I2C_EXIT;
160+ else // それ以外は送信割り込み
161+ twi->state = I2C_XMT_NEXT_BYTE;
162+ break;
163+ case I2C_XMT_NEXT_BYTE :
164+ twi->xmt_data8 = *(wptr++); // 1バイト送信
165+ twi->state = I2C_XMT_WAIT; // 次の送信待
166+ break;
167+ case I2C_RCV_WAIT :
168+ // 割り込みハンドラが受信割り込みを通知するまで待つ
169+ if ( E_OK == twai_sem(twi->signal, I2C_TIMEOUT))
170+ {
171+ twi->intr_state = I2C_ERR_TIMEOUT;
172+ twi->state = I2C_EXIT;
173+ }
174+ else
175+ twi->state = I2C_RCV_INT;
176+ break;
177+ case I2C_RCV_INT :
178+ if ( twi->intr_state & (MERR | MCOMP )) // エラーか終了ならすぐ終了
179+ twi->state = I2C_EXIT;
180+ else // それ以外は送信割り込み
181+ twi->state = I2C_RCV_NEXT_BYTE;
182+ break;
183+ case I2C_RCV_NEXT_BYTE :
184+ *(wptr++) = twi->rcv_data8; // 1バイト受信
185+ twi->state = I2C_RCV_WAIT; // 次の受信待
112186 break;
113-
114- // 割り込みハンドラが送受処理を完了するまで待つ
115- wai_sem(twi->signal);
116187 }
117188 } while ( twi->state != I2C_EXIT );
118189
@@ -120,7 +191,7 @@ int i2c_master_write_read( int peripheral, int slave, unsigned char write_data[]
120191 sig_sem(twi->blocking);
121192
122193 // 割り込みステータスを返す。正常終了なら0
123- return twi->int_state;
194+ return twi->intr_state;
124195 }
125196
126197 /**
@@ -137,7 +208,7 @@ void i2c0_master_handler(void)
137208
138209 // TWIペリフェラルの割り込みステータスを取得し、コピーを保存する。
139210 // コピーを保存するのは、このあと割り込みクリアで消えるからである。
140- twi->int_state = *twi->int_stat;
211+ twi->intr_state = *twi->int_stat;
141212
142213 // 割り込みクリア。すべての割り込み要素をクリアしてしまう。ステータスはコピーしているのでタスクで処理する。
143214 *twi->int_stat = 0xFF;
--- a/i2c-test/i2c_subsystem.h
+++ b/i2c-test/i2c_subsystem.h
@@ -39,7 +39,9 @@
3939 */
4040 /*@{*/
4141
42-#define I2C_ERR_WRONGPARAM 0x40000000
42+#define I2C_ERR_WRONGPARAM 0x4000
43+#define I2C_ERR_TOOLONGBUFFER 0x2000
44+#define I2C_ERR_TIMEOUT 0x1000
4345
4446 /**
4547 * \brief i2cマスターモードの割り込みサービスルーチン