/* ========================================================  加速度センサ関係 ・データ更新完了でデータを吸い上げ手レジスタを更新、CPUに割り込み ・フラグが立っていれば歩数カウント ・加速度センサ割り込みからタスクを登録して下さい。(I2Cの競合回避などがあるので) ======================================================== */ #ifndef _WIN32 #pragma SFR #pragma NOP #pragma HALT #pragma STOP #pragma ROT // rorb, rolb, rorw, rolw #pragma MUL #pragma BCD #endif #include "config.h" #ifndef _WIN32 #pragma interrupt INTP23 intp23_ACC_ready RB3 // 加速度センサ、データ準備完了 #endif #include "incs.h" #ifndef _WIN32 #include #endif // ======================================================== // レジスタ名 #define ACC_REG_WHOAMI 0x0F #define ACC_REG_CTRL1 0x20 #define ACC_REG_CTRL5 0x24 #define ACC_REG_X 0x28 // ビット位置 #define ACC_bP_PM0 5 #define ACC_bP_DR0 3 // ビット設定値 #define ACC_BITS_PM_PDN 0 #define ACC_BITS_PM_NORM 1 #define ACC_BITS_PM_LP0R5 2 #define ACC_BITS_PM_LP1 3 #define ACC_BITS_PM_LP2 4 #define ACC_BITS_PM_LP5 5 #define ACC_BITS_PM_LP10 6 #define ACC_BITS_DR_50Hz 0 #define ACC_BITS_DR_100Hz 1 #define ACC_BITS_DR_400Hz 2 #define ACC_BITS_DR_1000Hz 3 #define ACC_BITS_ALL_AXIS_ON 7 #define VREG_BITMASK_ACC_CONF_ACQ ( 1 << 0 ) #define VREG_BITMASK_ACC_CONF_HOSU ( 1 << 1 ) // ======================================================== task_status tsk_soft_int( ); /* ========================================================  ・割り込みを確認してデータを吸い上げ、レジスタに書き出します ・本当であればコールバック関数を登録しておけばいいじゃんとなるのですが、 I2Cが使用中だったら?とか考えると私ではそこまでできないのです。 ・自動歩数計とかでも結局 ======================================================== */ task_status_immed tski_cbk_accero( ) { // (疑似)isrから登録されます static u8 err_count; u8 acc_dat_buff[6]; // 加速度センサデータレジスタへの反映 if( iic_mcu_read( IIC_SLA_ACCEL, ( ACC_REG_X | 0x80 ), 6, acc_dat_buff ) != ERR_SUCCESS ) { err_count ++; if( err_count < 8 ) { // リトライ return( ERR_CONTINUE ); } else { // 加速度センサが異常になったので止める vreg_ctr[ VREG_C_ACC_CONFIG ] &= ~( VREG_BITMASK_ACC_CONF_HOSU | VREG_BITMASK_ACC_CONF_ACQ ); tski_acc_hosu_set(); vreg_ctr[ VREG_C_STATUS_1 ] |= REG_BIT_ACCERO_ERR; return ( ERR_FINISED ); // タスクの削除は必要 } } else { memcpy( &vreg_ctr[VREG_C_ACC_XL], acc_dat_buff, 6 ); err_count = 0; // 正常時パス // // 加速度更新&割り込み if( (( vreg_ctr[VREG_C_ACC_CONFIG] & VREG_BITMASK_ACC_CONF_ACQ ) != 0 ) && ( system_status.pwr_state == ON ) ) { set_irq( VREG_C_IRQ1, REG_BIT_ACC_DAT_RDY ); // ゴミデータのカラ読み if( ACC_VALID ) { u8 temp[6]; iic_mcu_read( IIC_SLA_ACCEL, ( ACC_REG_X | 0x80 ), 6, temp ); } } if(( system_status.pwr_state != ON_CHECK ) &&( system_status.pwr_state != OFF ) #ifndef _DBG_PEDO_AUTO_ENABLE_ &&( ( vreg_ctr[VREG_C_ACC_CONFIG] & VREG_BITMASK_ACC_CONF_HOSU ) != 0 ) #endif ) { pedometer(); // 歩数計 } } return ( ERR_FINISED ); } /*=======================================================  加速度センサ透過アクセス リード ========================================================*/ task_status_immed tski_acc_read( ) { vreg_ctr[VREG_C_ACC_W_BUF] = iic_mcu_read_a_byte( IIC_SLA_ACCEL, vreg_ctr[VREG_C_ACC_R_ADRS] ); // vreg_ctr[ VREG_C_ACC_R_BUF ] = iic_mcu_read_a_byte( IIC_SLA_ACCEL, vreg_ctr[VREG_C_ACC_R_ADRS] ); vreg_ctr[VREG_C_IRQ1] |= REG_BIT_ACC_ACK; if( ( vreg_ctr[VREG_C_IRQ_MASK1] & REG_BIT_ACC_ACK ) == 0 ) { IRQ0_ast; } return ( ERR_FINISED ); } /*=========================================================  加速度センサ透過アクセス ライト ========================================================*/ task_status_immed tski_acc_write( ) { iic_mcu_write_a_byte( IIC_SLA_ACCEL, vreg_ctr[VREG_C_ACC_W_ADRS], vreg_ctr[VREG_C_ACC_W_BUF] ); vreg_ctr[VREG_C_IRQ1] |= REG_BIT_ACC_ACK; if( ( vreg_ctr[VREG_C_IRQ_MASK1] & REG_BIT_ACC_ACK ) == 0 ) { IRQ0_ast; } return ( ERR_FINISED ); } /*=========================================================  加速度センサの設定 ========================================================*/ task_status_immed tski_acc_hosu_set( ) { // iic_mcu_read_a_byte( IIC_SLA_ACCEL, ACC_REG_WHOAMI ); // スタックが足りないので展開… // if( iic_mcu_result == ERR_NOSLAVE ) { u8 dummy; if( iic_mcu_read( IIC_SLA_ACCEL, ACC_REG_WHOAMI, 1, &dummy ) == ERR_NOSLAVE ) { vreg_ctr[ VREG_C_STATUS_1 ] |= REG_BIT_ACCERO_ERR; return ( ERR_FINISED ); // とりあえず、タスクは削除しなくてはならない // おしまい }else{ vreg_ctr[ VREG_C_STATUS_1 ] &= ~REG_BIT_ACCERO_ERR; } } { u8 str_send_buf[4]; str_send_buf[1] = 0x00; // ctrl2 HPF:normal, filterd, HPF for IRQ : dis/dis, HPF coeff:norm /* if( system_status.model == MODEL_TS_BOARD ) { // TS Final SoC str_send_buf[2] = 0x02; // 3 IRQ pol :Active HI, Drive:Pushpull, } else { // 実機&派生種、白箱 str_send_buf[2] = 0x10; // 3 IRQ pol :Active HI, Drive:Pushpull, } */ if( system_status.model == MODEL_TS_BOARD ) { str_send_buf[2] = bits8(0,0,0,0, 0,0,1,0); // ピン不足のため、ちゃんと分ける } else { str_send_buf[2] = bits8(0,0,0,1, 0,0,0,0); } str_send_buf[3] = 0x80; // ctrl3 block update:enable, MSB first, scale: +-2G(default), selftest: dis if( ( vreg_ctr[VREG_C_ACC_CONFIG] & ( VREG_BITMASK_ACC_CONF_HOSU | VREG_BITMASK_ACC_CONF_ACQ ) ) == 0 ) { PMK23 = 1; // 完全停止 str_send_buf[0] = ( ACC_BITS_PM_PDN << ACC_bP_PM0 | 0 << ACC_bP_DR0 | ACC_BITS_ALL_AXIS_ON ); } else { PMK23 = 0; // 100Hz 自動取り込み str_send_buf[0] = ( ACC_BITS_PM_NORM << ACC_bP_PM0 | ACC_BITS_DR_100Hz << ACC_bP_DR0 | ACC_BITS_ALL_AXIS_ON ); } iic_mcu_write( IIC_SLA_ACCEL, ( ACC_REG_CTRL1 | 0x80 ), 4, str_send_buf ); } // カラ読み if( ACC_VALID ) { if( system_status.pwr_state == ON ) { u8 temp[6]; iic_mcu_read( IIC_SLA_ACCEL, ( ACC_REG_X | 0x80 ), 6, temp ); } } return ( ERR_FINISED ); } /* ======================================================== 加速度センサ割り込み I2Cが使用中かもしれないので、読み出しタスクの登録を行うのみ ======================================================== */ __interrupt void intp23_ACC_ready( ) { EI(); if( ( vreg_ctr[VREG_C_ACC_CONFIG] & 0x03 ) != 0x00 ) { if( ( system_status.pwr_state == ON ) || ( system_status.pwr_state == SLEEP ) ) { if( ACC_VALID ) { renge_task_immed_add( tski_cbk_accero ); } } } }