/* ========================================================  加速度センサ関係 ・データ更新完了でデータを吸い上げ手レジスタを更新、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_REG_FLG_BURST_ACCESS 0x80 // ビット位置 #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 ) // ======================================================== #define ACC_RAW_DATA_SIZE 6 // ======================================================== task_status tsk_soft_int( ); extern void DI_wt_chk(); /* ========================================================  ・割り込みを確認してデータを吸い上げ、レジスタに書き出します ・本当であればコールバック関数を登録しておけばいいじゃんとなるのですが、 I2Cが使用中だったら?とか考えると私ではそこまでできないのです。 ・自動歩数計とかでも結局 ======================================================== */ task_status_immed tski_cbk_accero( ) { // (疑似)isrから登録されます static u8 err_count; u8 acc_dat_buff[ ACC_RAW_DATA_SIZE ]; // 加速度センサデータレジスタへの反映 if( iic_mcu_read( IIC_SLA_ACCEL, ( ACC_REG_X | ACC_REG_FLG_BURST_ACCESS ), ACC_RAW_DATA_SIZE, 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_setup(); vreg_ctr[ VREG_C_STATUS_1 ] |= REG_BIT_ACCERO_ERR; return ( ERR_FINISED ); // タスクの削除は必要 } } else { memcpy( &vreg_ctr[VREG_C_ACC_XL], acc_dat_buff, ACC_RAW_DATA_SIZE ); 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[ACC_RAW_DATA_SIZE]; iic_mcu_read( IIC_SLA_ACCEL, ( ACC_REG_X | ACC_REG_FLG_BURST_ACCESS ), ACC_RAW_DATA_SIZE, temp ); } } if(( system_status.pwr_state == ON ) ||( system_status.pwr_state == SLEEP ) ) { 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] ); set_irq( VREG_C_IRQ1, REG_BIT_ACC_ACK ); 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] ); set_irq( VREG_C_IRQ1, REG_BIT_ACC_ACK ); return ( ERR_FINISED ); } /*=========================================================  加速度センサの設定 ========================================================*/ task_status_immed tski_acc_setup( ) { // 加速度 on/off設定する { u8 str_send_buf[4]; str_send_buf[1] = 0x00; // ctrl2 HPF:normal, filterd, HPF for IRQ : dis/dis, HPF coeff:norm // ピン不足のため、TSとそれ以外(回路違い)を区別して設定 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 { u8 acc_setting_sent = ( vreg_ctr[VREG_C_ACC_CONFIG] & ( VREG_BITMASK_ACC_CONF_HOSU | VREG_BITMASK_ACC_CONF_ACQ )); do{ EI(); if( acc_setting_sent == 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 ); } // 実書き込み兼、通信できたかフラグ更新 if( iic_mcu_write( IIC_SLA_ACCEL, ( ACC_REG_CTRL1 | ACC_REG_FLG_BURST_ACCESS ), 4, str_send_buf ) == I2C_ERR_NOSLAVE ) { vreg_ctr[ VREG_C_STATUS_1 ] |= REG_BIT_ACCERO_ERR; }else{ vreg_ctr[ VREG_C_STATUS_1 ] &= ~REG_BIT_ACCERO_ERR; } // カラ読み。前回のゴミを読み捨て if( ACC_VALID ) { if( system_status.pwr_state == ON ) { u8 temp[ACC_RAW_DATA_SIZE]; iic_mcu_read( IIC_SLA_ACCEL, ( ACC_REG_X | ACC_REG_FLG_BURST_ACCESS ), 6, temp ); } } // センサに書きにいっている最中にSoCがまた書き換えてしまうかもしれない DI_wt_chk(); }while( acc_setting_sent != ( vreg_ctr[VREG_C_ACC_CONFIG] & ( VREG_BITMASK_ACC_CONF_HOSU | VREG_BITMASK_ACC_CONF_ACQ )) ); } } // DI状態のまま帰る 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 ); } } } }