示例#1
0
bool_t GetData_AM2320(AM2320Data *data) {
	uint8 Cmd[2];
	uint8 Read[8];
	bool_t bOk = TRUE;
	int x;

	ZeroMemory(Cmd, sizeof(Cmd));
	ZeroMemory(Read, sizeof(Read));

	bOk &= bSMBusWrite(AM2320_ADDR, 0, 0, NULL);
	for (x = 0; x < 1600; x++) {;}
	if (bOk == FALSE) return FALSE;

	Cmd[0] = 0x00;
	Cmd[1] = 0x04;
	bOk = bSMBusWrite(AM2320_ADDR, 0x03, 2, Cmd);
	for (x = 0; x < 1600; x++) {;}
	if (bOk == FALSE) return FALSE;

	for (x = 0; x <= 5; x++) {
		bOk = bSMBusSequentialRead(AM2320_ADDR, 8, Read);
		if (bOk == TRUE) break;
	}
	if (bOk == FALSE) return FALSE;

	uint16 crc, calc_crc;
	crc = (Read[7] << 8) | Read[6];
	calc_crc = CRC16Calc(Read, 6);
	if (crc != calc_crc) return FALSE;
	data->Humidity = (Read[2] << 8) | Read[3];
	data->Temp = (Read[4] << 8) | Read[5];


	return TRUE;
}
示例#2
0
/** @ingroup MASTER
 * ACM1620 LCD モジュールに文字列を書き出す。
 * - この処理は、一定時間処理をブロックし、IO判定などTIMER_0起点の動作などに影響を及ぼします。
 * - 2つのパラメータを両方とも NULL にすると、画面クリアを行います。
 *
 * @param puUpperRow 上段に書き込む文字列
 * @param puLowerRow 下段に書き込む文字列
 * @return
 */
bool_t bDraw2LinesLcd_ACM1602(const char *puUpperRow,
		const char *puLowerRow) {
	bool_t bOk = TRUE;
	const uint8 *pu8data;
	const uint32 u32delay = 20000;

	// ディスプレーのクリア
	const uint8 au8data[] = { 0x01, 0x38, 0x0c, 0x06, 0x00 };
	pu8data = au8data;
	while (*pu8data) {
		bOk &= bSMBusWrite(0x50, 0x00, 1, (uint8*) pu8data);
		vWait(u32delay);

		pu8data++;
	}

	// 上段への書き込み
	if (puUpperRow) {
		uint8 u8data = 0x80; // 上段のアドレス指定
		int i = 0;

		bOk &= bSMBusWrite(0x50, 0x00, 1, &u8data);
		vWait(u32delay);

		pu8data = (uint8*) puUpperRow;

		while (*pu8data && i < 16) {
			bOk &= bSMBusWrite(0x50, 0x80, 1, (uint8*) pu8data);
			vWait(u32delay);

			pu8data++;
			i++;
		}
	}

	// 下段への書き込み
	if (puLowerRow) {
		uint8 u8data = 0xC0; // 下段のアドレス指定
		int i = 0;

		bOk &= bSMBusWrite(0x50, 0x00, 1, &u8data);
		vWait(u32delay);

		pu8data = (uint8*) puLowerRow;

		while (*pu8data && i < 16) {
			bOk &= bSMBusWrite(0x50, 0x80, 1, (uint8*) pu8data);
			vWait(u32delay);

			pu8data++;
			i++;
		}
	}

	return bOk;
}
示例#3
0
void vTSL2561_Init(tsObjData_TSL2561 *pData, tsSnsObj *pSnsObj) {
    vSnsObj_Init(pSnsObj);

    pSnsObj->pvData = (void*)pData;
    pSnsObj->pvProcessSnsObj = (void*)vProcessSnsObj_TSL2561;

    memset((void*)pData, 0, sizeof(tsObjData_TSL2561));

    uint8 opt = 0x03;
    bSMBusWrite(TSL2561_ADDRESS, CMD | 0x00, 1, &opt );
}
PUBLIC bool_t bNekotterreadResult( int16* ai16accel )
{
	bool_t	bOk = TRUE;
	int16	ai16result[3];
	uint8	au8data[2];
	int8	num;
	uint8	data;
	uint8	i, j;
	int16	ave;
	int16	sum[3] = { 0, 0, 0 };		//	サンプルの総和
	uint32	ssum[3] = { 0, 0, 0 };		//	サンプルの2乗和

	//	FIFOでたまった個数を読み込む
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_FIFO_STATUS, 0, NULL );
	bOk &= bSMBusSequentialRead( ADXL345_ADDRESS, 1, &data );

	num = (int8)(data&0x7f);
	for( i=0; i<num; i++ ){
		//	各軸の読み込み
		//	X軸
		bOk &= bGetAxis( ADXL345_IDX_X, au8data );
		ai16result[ADXL345_IDX_X] = (((au8data[1] << 8) | au8data[0]));
		//	Y軸
		bOk &= bGetAxis( ADXL345_IDX_Y, au8data );
		ai16result[ADXL345_IDX_Y] = (((au8data[1] << 8) | au8data[0]));
		//	Z軸
		bOk &= bGetAxis( ADXL345_IDX_Z, au8data );
		ai16result[ADXL345_IDX_Z] = (((au8data[1] << 8) | au8data[0]));

		//	総和と二乗和の計算
		for( j=0; j<3; j++ ){
			sum[j] += ai16result[j];
			ssum[j] += ai16result[j]*ai16result[j];
		}
		//vfPrintf(& sSerStream, "\n\r%2d:%d,%d,%d", i, ai16result[ADXL345_IDX_X], ai16result[ADXL345_IDX_Y], ai16result[ADXL345_IDX_Z]);
		//SERIAL_vFlush(E_AHI_UART_0);
	}

	for( i=0; i<3; i++ ){
	//	分散が評価値 分散の式を変形
		ave = sum[i]/num;
		ai16accel[i] = (int16)sqrt((double)(-1*(ave*ave)+(ssum[i]/num)));
	}

	//	ねこったーモードはじめ
	//	FIFOの設定をもう一度
	bOk &= bSetFIFO();
	//	終わり

    return bOk;
}
示例#5
0
/****************************************************************************
 *
 * NAME: u16TSL2561readResult
 *
 * DESCRIPTION:
 * Wrapper to read a measurement, followed by a conversion function to work
 * out the value in degrees Celcius.
 *
 * RETURNS:
 * int16: 0~10000 [1 := 5Lux], 100 means 500 Lux.
 *        0x8000, error
 *
 * NOTES:
 * the data conversion fomula is :
 *      ReadValue / 1.2 [LUX]
 *
 ****************************************************************************/
PUBLIC uint32 u32TSL2561readResult( void )
{
    bool_t bOk = TRUE;
    uint32 u32result = 0x00;
    uint16 data[2];
    uint8 au8data[2];
    uint8 command;
    uint32 Lux;

    command = CMD | WORD | TSL2561_DATA0;
    bOk &= bSMBusWrite(TSL2561_ADDRESS, command, 0, NULL );
    bOk &= bSMBusSequentialRead(TSL2561_ADDRESS, 2, au8data);
    if (bOk == FALSE) {
        u32result = (uint16)SENSOR_TAG_DATA_ERROR;
    } else {
        data[0] = ((au8data[1] << 8) | au8data[0]);	//	読み込んだ数値を代入

        command = CMD | WORD | TSL2561_DATA1;
        bOk &= bSMBusWrite(TSL2561_ADDRESS, command, 0, NULL );
        bOk &= bSMBusSequentialRead(TSL2561_ADDRESS, 2, au8data);
        if (bOk == FALSE) {
            u32result = SENSOR_TAG_DATA_ERROR;
        }
        data[1] = ((au8data[1] << 8) | au8data[0]);	//	読み込んだ数値を代入

        //	TSL2561FN 照度の計算
        Lux = u32CalcLux(data);

        u32result = Lux;
    }
#ifdef SERIAL_DEBUG
    vfPrintf(&sDebugStream, "\n\rTSL2561 DATA %x", *((uint16*)au8data) );
#endif

    return u32result;
}
示例#6
0
static bool_t bInit2LinesLcd_AQM0802A() {
	bool_t bOk = TRUE;
	const uint8 *pu8data;
	const uint32 u32delay = 2000;
	const uint8 u8addr = 0x3E;

	// ディスプレーのクリア
	const uint8 au8data[] = { 0x38, 0x39, 0x14, 0x70, 0x56, 0x6c, 0x00 };
	pu8data = au8data;
	while (*pu8data) {
		bOk &= bSMBusWrite(u8addr, 0x00, 1, (uint8*) pu8data);
		vWait(u32delay);

		pu8data++;
	}

	return bOk;
}
示例#7
0
/** @ingroup MASTER
 * ACM1620 LCD モジュールに文字列を書き出す。
 * - この処理は、一定時間処理をブロックし、IO判定などTIMER_0起点の動作などに影響を及ぼします。
 * - 2つのパラメータを両方とも NULL にすると、画面クリアを行います。
 *
 * @param puUpperRow 上段に書き込む文字列
 * @param puLowerRow 下段に書き込む文字列
 * @return
 */
bool_t bDraw2LinesLcd_AQM0802A(const char *puUpperRow,
		const char *puLowerRow) {
	bool_t bOk = TRUE;
	const uint8 *pu8data;
	const uint32 u32delay = 2000;
	const uint8 u8addr = 0x3E;

	static bool_t bInit;

	// ディスプレーのクリア
	if (!bInit) {
		bOk &= bInit2LinesLcd_AQM0802A();
		vWait(400000);
		bInit = TRUE;
	}

	const uint8 au8data2[] = { 0x38, 0x0c, 0x01, 0x06, 0x00 };
	pu8data = au8data2;
	while (*pu8data) {
		bOk &= bSMBusWrite(u8addr, 0x00, 1, (uint8*) pu8data);
		vWait(u32delay);

		pu8data++;
	}

	// 上段への書き込み
	if (puUpperRow) {
		uint8 u8data = 0x80; // 上段のアドレス指定
		int i = 0;

		bOk &= bSMBusWrite(u8addr, 0x00, 1, &u8data);
		vWait(u32delay);

		pu8data = (uint8*) puUpperRow;

		while (*pu8data && i < 8) {
			bOk &= bSMBusWrite(u8addr, 0x40, 1, (uint8*) pu8data);
			vWait(u32delay);

			pu8data++;
			i++;
		}
	}

	// 下段への書き込み
	if (puLowerRow) {
		uint8 u8data = 0xC0; // 下段のアドレス指定
		int i = 0;

		bOk &= bSMBusWrite(u8addr, 0x00, 1, &u8data);
		vWait(u32delay);

		pu8data = (uint8*) puLowerRow;

		while (*pu8data && i < 8) {
			bOk &= bSMBusWrite(u8addr, 0x40, 1, (uint8*) pu8data);
			vWait(u32delay);

			pu8data++;
			i++;
		}
	}

	return bOk;
}
示例#8
0
/** @ingroup MASTER
 * I2C のコマンドを実行して、応答を返します。
 * 無線経由ので要求の場合は、応答は送信元へ無線パケットで戻されます。
 * アドレスが0xDBの場合は、要求は自身のモジュールで実行された上 UART に応答します。
 *
 * - 入力フォーマット
 *   - OCTET: ネットワークアドレス(宛先,0xDBは自身のモジュールで実行してUARTに出力)
 *   - OCTET: 0x88
 *   - OCTET: 要求番号
 *   - OCTET: コマンド (0x1: Write, 0x2: Read, 0x3: Write and Increment, 0x4: Write and Read)
 *   - OCTET: I2Cアドレス
 *   - OCTET: I2Cコマンド
 *   - OCTET: データサイズ (無い時は 0)
 *   - OCTET[N]: データ (データサイズが0のときは、本フィールドは無し)
 *
 * - 出力フォーマット
 *   - OCTET: ネットワークアドレス
 *   - OCTET: 0x89
 *   - OCTET: 要求番号、入力フォーマットの値がコピーされる
 *   - OCTET: コマンド (0x1: Write, 0x2: Read)
 *   - OCTET: 0:FAIL, 1:SUCCESS
 *   - OCTET: データサイズ (無い時は 0)
 *   - OCTET[N]: データ (データサイズが0のときは、本フィールドは無し)
 *
 * @param p 入力書式のバイト列
 * @param u16len バイト列長
 * @param u8AddrSrc 要求元のネットワークアドレス
 */
void vProcessI2CCommand(uint8 *p, uint16 u16len, uint8 u8AddrSrc) {
	//uint8 *p_end = p + u16len;
	uint8 au8OutBuf[256 + 32];
	uint8 *q = au8OutBuf;

	bool_t bOk = TRUE;
	uint8 n;
	static volatile uint16 x;

	// 入力データの解釈
	uint8 u8Addr = G_OCTET();
	(void) u8Addr;

	uint8 u8Command = G_OCTET();
	if (u8Command != SERCMD_ID_I2C_COMMAND) {
		return;
	}

	uint8 u8ReqNum = G_OCTET();
	uint8 u8I2C_Oper = G_OCTET();
	uint8 u8I2C_Addr = G_OCTET();
	uint8 u8I2C_Cmd = G_OCTET();
	uint8 u8DataSize = G_OCTET();

	uint8 *pu8data = p;
	//uint8 *pu8data_end = p + u8DataSize;

#if 0
	if (pu8data_end != p_end) {
		DBGOUT(1, "I2CCMD: incorrect data."LB);
		return;
	}
#endif

	// 出力用のバッファを用意しておく
	S_OCTET(sAppData.u8AppLogicalId);
	S_OCTET(SERCMD_ID_I2C_COMMAND_RESP);
	S_OCTET(u8ReqNum);
	S_OCTET(u8I2C_Oper);
	//ここで q[0] 成功失敗フラグ, q[1] データサイズ, q[2]... データ
	q[0] = FALSE;
	q[1] = 0;

	DBGOUT(1, "I2CCMD: req#=%d Oper=%d Addr=%02x Cmd=%02x Siz=%d"LB, u8ReqNum,
			u8I2C_Oper, u8I2C_Addr, u8I2C_Cmd, u8DataSize);

	switch (u8I2C_Oper) {
	case 1:
		bOk &= bSMBusWrite(u8I2C_Addr, u8I2C_Cmd, u8DataSize,
				u8DataSize == 0 ? NULL : pu8data);
		break;

	case 2:
		if (u8DataSize > 0) {
			bOk &= bSMBusSequentialRead(u8I2C_Addr, u8DataSize, &(q[2]));
			if (bOk)
				q[1] = u8DataSize;
		} else {
			bOk = FALSE;
		}
		break;

	case 3:
		for (n = 0; n < u8DataSize; n++) {
			bOk &= bSMBusWrite(u8I2C_Addr, u8I2C_Cmd + n, 1, &pu8data[n]);
			for (x = 0; x < 16000; x++)
				; //wait (e.g. for memory device)
		}
		break;

	case 4:
		if (u8DataSize > 0) {
			bOk &= bSMBusWrite(u8I2C_Addr, u8I2C_Cmd, 0, NULL );
			if (bOk)
				bOk &= bSMBusSequentialRead(u8I2C_Addr, u8DataSize, &(q[2]));
			if (bOk)
				q[1] = u8DataSize;
		} else {
			bOk = FALSE;
		}
		break;

#ifdef USE_I2C_ACM1620
	case 0x21: // ACM1620
		bDraw2LinesLcd_ACM1602((const char *) pu8data,
				(const char *) (pu8data + 16));
		break;
#endif

#ifdef USE_I2C_AQM0802A
	case 0x22: // ACM1620
		bDraw2LinesLcd_AQM0802A((const char *) pu8data,
				(const char *) (pu8data + 8));
		break;
#endif

	default:
		DBGOUT(1, "I2CCMD: unknown operation(%d)."LB, u8I2C_Oper);
		return;
	}

	q[0] = bOk; // 成功失敗フラグを書き込む
	q = q + 2 + q[1]; // ポインタ q を進める(データ末尾+1)

	if (u8AddrSrc == SERCMD_ADDR_TO_MODULE) {
		SerCmdAscii_Output_AdrCmd(&sSerStream, u8AddrSrc, au8OutBuf[1],
				au8OutBuf + 2, q - au8OutBuf - 2);
	} else {
		i16TransmitSerMsg(au8OutBuf, q - au8OutBuf, ToCoNet_u32GetSerial(),
				sAppData.u8AppLogicalId, u8AddrSrc, FALSE,
				sAppData.u8UartReqNum++);
	}
}
//	センサの設定を記述する関数
bool_t bADXL345_Setting( int16 i16mode, tsADXL345Param sParam, bool_t bLink )
{
	u16modeflag = (uint16)i16mode;
	u16modeflag = ((i16mode&SHAKE) != 0) ? SHAKE : u16modeflag;

	uint8 com;
	if( u16modeflag == NEKOTTER || u16modeflag == SHAKE ){
		switch(sParam.u16Duration){
//		case 1:
//			com = 0x14;		//	Low Power Mode, 1.56Hz Sampling frequency
//			break;
//		case 3:
//			com = 0x15;		//	Low Power Mode, 3.13Hz Sampling frequency
//			break;
		case 6:
			com = 0x16;		//	Low Power Mode, 6.25Hz Sampling frequency
			break;
		case 12:
			com = 0x17;		//	Low Power Mode, 12.5Hz Sampling frequency
			break;
		case 25:
			com = 0x18;		//	Low Power Mode, 25Hz Sampling frequency
			break;
		case 50:
			com = 0x19;		//	Low Power Mode, 50Hz Sampling frequency
			break;
		case 100:
			com = 0x1A;		//	Low Power Mode, 100Hz Sampling frequency
			break;
		case 200:
			com = 0x1B;		//	Low Power Mode, 200Hz Sampling frequency
			break;
		case 400:
			com = 0x0C;		//	400Hz Sampling frequency
			break;
//		case 800:
//			com = 0x0D;		//	800Hz Sampling frequency
//			break;
//		case 1600:
//			com = 0x0E;		//	1600Hz Sampling frequency
//			break;
//		case 3200:
//			com = 0x0F;		//	3200Hz Sampling frequency
//			break;
		default:
			com = 0x08;		//	Low Power Mode, 25Hz Sampling frequency
			break;
		}
	}else{
		com = 0x1A;		//	Low Power Mode, 100Hz Sampling frequency
	}
	bool_t bOk = bSMBusWrite(ADXL345_ADDRESS, ADXL345_BW_RATE, 1, &com );

	com = 0x0B;		//	Full Resolution Mode, +-16g
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_DATA_FORMAT, 1, &com );

	if(bLink){
		com = 0x08;		//	Start Measuring
	}else{
		com = 0x28;		//	Link(Active -> Inactive -> Active ...), Start Measuring
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_POWER_CTL, 1, &com );

	uint16 u16tempcom;
	//	タップを判別するための閾値
	if( (u16modeflag&S_TAP) || (u16modeflag&D_TAP) ){
		if( sParam.u16ThresholdTap != 0 ){
			u16tempcom = sParam.u16ThresholdTap*10/625;
			if( 0x00FF < u16tempcom ){
				com = 0xFF;
			}else{
				com = (uint8)u16tempcom;
			}
		}else{
			com = 0x32;			//	threshold of tap
		}
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_THRESH_TAP, 1, &com );

	//	タップを認識するための時間
	if( (u16modeflag&S_TAP) || (u16modeflag&D_TAP) ){
		if( sParam.u16Duration != 0 ){
			u16tempcom = sParam.u16Duration*10/625;
			if( 0x00FF < u16tempcom ){
				com = 0xFF;
			}else{
				com = (uint8)u16tempcom;
			}
		}else{
			com = 0x0F;
		}
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_DUR, 1, &com );

	//	次のタップまでの時間
	if( u16modeflag&D_TAP ){
		if( sParam.u16Latency != 0 ){
			u16tempcom = sParam.u16Latency*100/125;
			if( 0x00FF < u16tempcom ){
				com = 0xFF;
			}else{
				com = (uint8)u16tempcom;
			}
		}else{
			com = 0x50;
		}
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_LATENT, 1, &com );

	//	ダブルタップを認識するための時間
	if( u16modeflag&D_TAP ){
		if( sParam.u16Window != 0 ){
			u16tempcom = sParam.u16Window*100/125;
			if( 0x00FF < u16tempcom ){
				com = 0xFF;
			}else{
				com = (uint8)u16tempcom;
			}
		}else{
			com = 0xD9;			// Window Width
		}
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_WINDOW, 1, &com );

	//	タップを検知する軸の設定
	if( (u16modeflag&S_TAP) || (u16modeflag&D_TAP) ){
		com = 0x07;
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_TAP_AXES, 1, &com );

	//	自由落下を検知するための閾値
	if( (u16modeflag&FREEFALL) != 0 && u16modeflag < SHAKE ){
		if( sParam.u16ThresholdFreeFall != 0 ){
			u16tempcom = sParam.u16ThresholdFreeFall*10/625;
			if( 0x00FF < u16tempcom ){
				com = 0xFF;
			}else{
				com = (uint8)u16tempcom;
			}
		}else{
			com = 0x07;			// threshold of freefall
		}
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_THRESH_FF, 1, &com );

	//	自由落下を検知するための時間
	if( u16modeflag&FREEFALL ){
		if( sParam.u16TimeFreeFall != 0 ){
			u16tempcom = sParam.u16TimeFreeFall/5;
			if( 0x00FF < u16tempcom ){
				com = 0xFF;
			}else{
				com = (uint8)u16tempcom;
			}
		}else{
			com = 0x2D;			// time of freefall
		}
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_TIME_FF, 1, &com );

	//	動いていることを判断するための閾値
	if( u16modeflag&ACTIVE ){
		if( sParam.u16ThresholdActive != 0 ){
			u16tempcom = sParam.u16ThresholdActive*10/625;
			if( 0x00FF < u16tempcom ){
				com = 0xFF;
			}else{
				com = (uint8)u16tempcom;
			}
		}else{
			com = 0x15;
		}
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_THRESH_ACT, 1, &com );

	//	動いていないことを判断するための閾値
	if( u16modeflag&ACTIVE ){
		if( sParam.u16ThresholdInactive != 0 ){
			u16tempcom = sParam.u16ThresholdInactive*10/625;
			if( 0x00FF < u16tempcom ){
				com = 0xFF;
			}else{
				com = (uint8)u16tempcom;
			}
		} else {
			com = 0x14;
		}
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_THRESH_INACT, 1, &com );

	//	動いていないことを判断するための時間(s)
	if( u16modeflag&ACTIVE ){
		if( sParam.u16TimeInactive != 0 ){
			u16tempcom = sParam.u16TimeInactive;
			if( 0x00FF < u16tempcom ){
				com = 0xFF;
			}else{
				com = (uint8)u16tempcom;
			}
		} else {
			com = 0x02;
		}
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_TIME_INACT, 1, &com );

	//	動いている/いないことを判断するための軸
	if( u16modeflag&ACTIVE ){
		com = 0x77;
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_ACT_INACT_CTL, 1, &com );

	//	割り込みピンの設定
	if( u16modeflag > 0  && u16modeflag < 32){
		com = 0x10;		//	ACTIVEは別ピン
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_INT_MAP, 1, &com );

	//	有効にする割り込みの設定
	com = 0;
	if( (u16modeflag&SHAKE) != 0 ){
		com += 0x02;
	}else{
		if( u16modeflag&S_TAP ){
			com += 0x40;
		}
		if( u16modeflag&D_TAP ){
			com += 0x20;
		}
		if( u16modeflag&FREEFALL ){
			com += 0x04;
		}
		if( u16modeflag&ACTIVE ){
			com += 0x18;		//	INACTIVEも割り込みさせる
		}
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_INT_ENABLE, 1, &com );

	if( u16modeflag == NEKOTTER || u16modeflag == SHAKE ){
		com = 0xC0 | 0x20 | READ_FIFO;
	}else{
		com = 0x00;
	}
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_FIFO_CTL, 1, &com );

	if( u16modeflag == SHAKE ){
		if( sParam.u16ThresholdTap != 0 ){
			u16ThAccel = sParam.u16ThresholdTap;
		}
	}

	return bOk;
}
PUBLIC bool_t bShakereadResult( int16* ai16accel )
{
	static 	int16	ai16TmpAccel[3]={0, 0, 0};
	bool_t	bOk = TRUE;
	uint8	au8data[2];
	int16	max = 0x8000;
	uint8	num;				//	FIFOのデータ数
	uint8	i;
	int16	sum[32];
	uint8	count = 0;
	int16	x[33];
	int16	y[33];
	int16	z[33];

	//	FIFOでたまった個数を読み込む
	bOk &= bSMBusWrite(ADXL345_ADDRESS, ADXL345_FIFO_STATUS, 0, NULL );
	bOk &= bSMBusSequentialRead( ADXL345_ADDRESS, 1, &num );

	//	FIFOの中身を全部読む
	num = (num&0x7f);
	if( num == READ_FIFO ){
		//	各軸の読み込み
		for( i=0; i<num; i++ ){
			//	X軸
			bOk &= bGetAxis( ADXL345_IDX_X, au8data );
			x[i] = (((au8data[1] << 8) | au8data[0]));
		}
		for( i=0; i<num; i++ ){
			//	Y軸
			bOk &= bGetAxis( ADXL345_IDX_Y, au8data );
			y[i] = (((au8data[1] << 8) | au8data[0]));
		}
		for( i=0; i<num; i++ ){
			//	Z軸
			bOk &= bGetAxis( ADXL345_IDX_Z, au8data );
			z[i] = (((au8data[1] << 8) | au8data[0]));
		}
		//	FIFOの設定をもう一度
		bOk &= bSetFIFO();

		for( i=0; i<num; i++ ){
			x[i] = (x[i]<<2)/10;
			y[i] = (y[i]<<2)/10;
			z[i] = (z[i]<<2)/10;

			if( i == 0 ){
				sum[i] = ( x[i]-ai16TmpAccel[0] + y[i]-ai16TmpAccel[1] + z[i]-ai16TmpAccel[2] );
			}else{
				sum[i] = ( x[i]-x[i-1] + y[i]-y[i-1] + z[i]-z[i-1] );
			}

			if( sum[i] < 0 ){
				sum[i] *= -1;
			}

			max = sum[i]>max ? sum[i] : max;

			if( sum[i] > u16ThAccel ){
				count++;
			}
#if 0
			vfPrintf(& sSerStream, "\n\r%2d:%d,%d,%d %d", i, x[i], y[i], z[i], sum[i] );
			SERIAL_vFlush(E_AHI_UART_0);
		}
		vfPrintf( &sSerStream, "\n\r" );
#else
		}
#endif
		ai16accel[0] = max;
		ai16accel[1] = z[0];
		ai16accel[2] = count;
		ai16TmpAccel[0] = x[num-1];
		ai16TmpAccel[1] = y[num-1];
		ai16TmpAccel[2] = z[num-1];
	}else{