TWIペリフェラルを使ってI2Cプロトコルを制御する
Revisión | a0ae539bc1a6519b5a343da00029cbccaa921eaa (tree) |
---|---|
Tiempo | 2012-09-09 09:22:32 |
Autor | takemasa <suikan@user...> |
Commiter | takemasa |
I2Cの応答時間確保のため、プロトコル実行中の優先順位を引き上げた。また、正常終了時のリターン値にバグがある点を修正した。
@@ -18,7 +18,7 @@ | ||
18 | 18 | #include <ccblkfn.h> |
19 | 19 | |
20 | 20 | |
21 | -// #define I2C_DEBUG | |
21 | +#define I2C_DEBUG | |
22 | 22 | |
23 | 23 | #ifdef I2C_DEBUG |
24 | 24 | #define I2C_SYSLOG(level,msg) syslog( level, msg ) |
@@ -100,7 +100,8 @@ int i2c_master_write_read( int peripheral, int slave, unsigned char write_data[] | ||
100 | 100 | struct I2C_MASTER_CONTROL_TYPE *twi; |
101 | 101 | BOOL read, write, rstart, quit; |
102 | 102 | unsigned char *wptr, *rptr; |
103 | - enum I2C_STATE state; /**< I2Cペリフェラルハンドラの内部状態 */ | |
103 | + enum I2C_STATE state; /**< I2Cペリフェラルハンドラの内部状態 */ | |
104 | + PRI old_priority; // タスクの優先順位を保存しておくための変数 | |
104 | 105 | |
105 | 106 | // 可読性向上のため、TWI管理構造体のポインタを設定する。 |
106 | 107 | twi = &i2c_control[peripheral]; |
@@ -138,6 +139,10 @@ int i2c_master_write_read( int peripheral, int slave, unsigned char write_data[] | ||
138 | 139 | // これでスレッドセーフにできる |
139 | 140 | wai_sem(twi->blocking); |
140 | 141 | |
142 | + // タスクの優先順位を一旦引き上げる。これは、TWIのレスポンスを保証するためである | |
143 | + get_pri( TSK_SELF, &old_priority ); | |
144 | + chg_pri( TSK_SELF, TMAX_TPRI ); | |
145 | + | |
141 | 146 | // SPIスレーブデバイスのアドレスを設定(7bit) |
142 | 147 | *twi->master_addr = slave; |
143 | 148 |
@@ -188,7 +193,7 @@ int i2c_master_write_read( int peripheral, int slave, unsigned char write_data[] | ||
188 | 193 | else if ( ( twi->intr_state & MCOMP ) && rstart) // MCOMP かつ RSTARTなら受信へ |
189 | 194 | state = I2C_RCV_ENTRY; |
190 | 195 | else if ( twi->intr_state & MCOMP ){ // RSTARTがないMCOMPなら終了 |
191 | - twi->intr_state = ~MCOMP; | |
196 | + twi->intr_state &= ~MCOMP; | |
192 | 197 | state = I2C_EXIT; |
193 | 198 | } |
194 | 199 | else // それ以外は送信割り込み |
@@ -215,7 +220,7 @@ int i2c_master_write_read( int peripheral, int slave, unsigned char write_data[] | ||
215 | 220 | if ( twi->intr_state & MERR) // エラーならすぐ終了 |
216 | 221 | state = I2C_EXIT; |
217 | 222 | else if ( twi->intr_state & MCOMP ){ // 終了ならエラークリア |
218 | - twi->intr_state = ~MCOMP; | |
223 | + twi->intr_state &= ~MCOMP; | |
219 | 224 | state = I2C_EXIT; |
220 | 225 | } |
221 | 226 | else // それ以外は受信割り込み |
@@ -234,6 +239,9 @@ int i2c_master_write_read( int peripheral, int slave, unsigned char write_data[] | ||
234 | 239 | } |
235 | 240 | } while ( !quit ); |
236 | 241 | |
242 | + // タスクの優先順位を元に戻す | |
243 | + chg_pri( TSK_SELF, old_priority); | |
244 | + | |
237 | 245 | // 排他区間の終了 |
238 | 246 | sig_sem(twi->blocking); |
239 | 247 |