/* ======================================================== 簡易I2C(内蔵ペリフェラル使用)通信 de JHL 藤田@開技 '09 Feb - $Id$ ======================================================== */ #ifndef _WIN32 #pragma sfr #pragma di #pragma ei #pragma nop #pragma inline // memcpy()をインライン展開する(の方が小さい!) #endif #include "incs.h" #include "i2c_mcu.h" #include "loader.h" #include "util_funcs.h" #include "i2c_mcu_sub.h" #include "pm.h" /// やりたくなかった…CODECのレジスタ名をひくため // ======================================================== // ワークアラウンド用 static void iic_mcu_simple_dummy_write(); static i2c_err iic_mcu_codec_write_low( u8 adrs, u8 dat ); // i2c_mcu.c にいる extern void iic_mcu_send_re_st( ); extern void iic_mcu_send_sp( ); extern i2c_err iic_mcu_send_a_byte( u8 ); extern i2c_err iic_mcu_call_slave( u8 slave ); /* yamaha codecから不用意に割り込みが入ることがあるが、タスクが登録されて 実際に読み出すときには書き戻した後なので何事もなかったように動くはず */ /********************************************//** コーデックに 『1バイト』 ライト iic_mcu_write_a_byte CODEC不具合ワークアラウンド ***********************************************/ i2c_err iic_mcu_write_a_byte_codec( u8 adrs, u8 dat ) { u8 pm_reg_original; u8 rv; // ヤマハcodecワークアラウンド SPIとの共用レジスタの中身を取得 if(( rv = iic_mcu_read( IIC_SLA_CODEC, CODEC_REG_PM, 1, &pm_reg_original )) != I2C_ERR_OK ) { return( rv ); } // phase1 ここまで // 書き込み! if( ( rv = iic_mcu_codec_write_low( adrs, dat ) ) != I2C_ERR_OK ) { return( rv ); } // ヤマハcodecワークアラウンド if( dat != 0 ) // 書き込むのが0だったらチェックもしない { // 共有レジスタが 0x00 に書き換わっているようなら書き戻す u8 pm_reg_after; if(( rv = iic_mcu_read( IIC_SLA_CODEC, CODEC_REG_PM, 1, &pm_reg_after )) != I2C_ERR_OK ) { return( rv ); } if( ( pm_reg_after & 0x7C ) != 0x00 ) { return( I2C_ERR_OK ); } // else { return iic_mcu_codec_write_low( CODEC_REG_PM, pm_reg_original ); // リトライなどは無し } return( I2C_ERR_OK ); } static i2c_err iic_mcu_codec_write_low( u8 adrs, u8 dat ) { IICMK10 = 1; // DMA用のISRに飛ばさないためにマスク if( iic_mcu_call_slave( IIC_SLA_CODEC ) != I2C_ERR_OK ) { iic_mcu_busy = false; return ( I2C_ERR_NOSLAVE ); } iic_mcu_send_a_byte( adrs ); iic_mcu_send_a_byte( dat ); // TIワークアラウンド // re-stでダミーライト { iic_mcu_send_re_st( ); iic_mcu_send_a_byte( IIC_SLA_CODEC ); // ダミーライト iic_mcu_send_a_byte( 0x20 ); // ゴミを書いても問題ないアドレス iic_mcu_send_a_byte( 0xAA ); // 何でもよい } iic_mcu_send_sp( ); iic_mcu_busy = false; return( I2C_ERR_OK ); }