/*! Execute "Onboard Function Test" (NOT includes "START" and "END" command). @retval 1 The test is passed successfully. @retval -1 The test is failed. @retval 0 The test is aborted by kind of system error. @param[in] prms A pointer to a #AK8975PRMS structure. */ int16 FctShipmntTestProcess_Body(AK8975PRMS* prms) { int16 pf_total; //p/f flag for this subtest BYTE i2cData[16]; int16 hdata[3]; int16 asax; int16 asay; int16 asaz; //*********************************************** // Reset Test Result //*********************************************** pf_total = 1; //*********************************************** // Step1 //*********************************************** // Set to PowerDown mode if (AKD_SetMode(AK8975_MODE_POWERDOWN) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } // When the serial interface is SPI, // write "00011011" to I2CDIS register(to disable I2C,). if(CSPEC_SPI_USE == 1){ i2cData[0] = 0x1B; if (AKD_TxData(AK8975_REG_I2CDIS, i2cData, 1) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } } // Read values from WIA to ASTC. if (AKD_RxData(AK8975_REG_WIA, i2cData, 13) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } // TEST TEST_DATA(TLIMIT_NO_RST_WIA, TLIMIT_TN_RST_WIA, (int16)i2cData[0], TLIMIT_LO_RST_WIA, TLIMIT_HI_RST_WIA, &pf_total); TEST_DATA(TLIMIT_NO_RST_INFO, TLIMIT_TN_RST_INFO, (int16)i2cData[1], TLIMIT_LO_RST_INFO, TLIMIT_HI_RST_INFO, &pf_total); TEST_DATA(TLIMIT_NO_RST_ST1, TLIMIT_TN_RST_ST1, (int16)i2cData[2], TLIMIT_LO_RST_ST1, TLIMIT_HI_RST_ST1, &pf_total); TEST_DATA(TLIMIT_NO_RST_HXL, TLIMIT_TN_RST_HXL, (int16)i2cData[3], TLIMIT_LO_RST_HXL, TLIMIT_HI_RST_HXL, &pf_total); TEST_DATA(TLIMIT_NO_RST_HXH, TLIMIT_TN_RST_HXH, (int16)i2cData[4], TLIMIT_LO_RST_HXH, TLIMIT_HI_RST_HXH, &pf_total); TEST_DATA(TLIMIT_NO_RST_HYL, TLIMIT_TN_RST_HYL, (int16)i2cData[5], TLIMIT_LO_RST_HYL, TLIMIT_HI_RST_HYL, &pf_total); TEST_DATA(TLIMIT_NO_RST_HYH, TLIMIT_TN_RST_HYH, (int16)i2cData[6], TLIMIT_LO_RST_HYH, TLIMIT_HI_RST_HYH, &pf_total); TEST_DATA(TLIMIT_NO_RST_HZL, TLIMIT_TN_RST_HZL, (int16)i2cData[7], TLIMIT_LO_RST_HZL, TLIMIT_HI_RST_HZL, &pf_total); TEST_DATA(TLIMIT_NO_RST_HZH, TLIMIT_TN_RST_HZH, (int16)i2cData[8], TLIMIT_LO_RST_HZH, TLIMIT_HI_RST_HZH, &pf_total); TEST_DATA(TLIMIT_NO_RST_ST2, TLIMIT_TN_RST_ST2, (int16)i2cData[9], TLIMIT_LO_RST_ST2, TLIMIT_HI_RST_ST2, &pf_total); TEST_DATA(TLIMIT_NO_RST_CNTL, TLIMIT_TN_RST_CNTL, (int16)i2cData[10], TLIMIT_LO_RST_CNTL, TLIMIT_HI_RST_CNTL, &pf_total); // i2cData[11] is BLANK. TEST_DATA(TLIMIT_NO_RST_ASTC, TLIMIT_TN_RST_ASTC, (int16)i2cData[12], TLIMIT_LO_RST_ASTC, TLIMIT_HI_RST_ASTC, &pf_total); // Read values from I2CDIS. if (AKD_RxData(AK8975_REG_I2CDIS, i2cData, 1) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } if(CSPEC_SPI_USE == 1){ TEST_DATA(TLIMIT_NO_RST_I2CDIS, TLIMIT_TN_RST_I2CDIS, (int16)i2cData[0], TLIMIT_LO_RST_I2CDIS_USESPI, TLIMIT_HI_RST_I2CDIS_USESPI, &pf_total); }else{ TEST_DATA(TLIMIT_NO_RST_I2CDIS, TLIMIT_TN_RST_I2CDIS, (int16)i2cData[0], TLIMIT_LO_RST_I2CDIS_USEI2C, TLIMIT_HI_RST_I2CDIS_USEI2C, &pf_total); } // Set to FUSE ROM access mode if (AKD_SetMode(AK8975_MODE_FUSE_ACCESS) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } // Read values from ASAX to ASAZ if (AKD_RxData(AK8975_FUSE_ASAX, i2cData, 3) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } asax = (int16)i2cData[0]; asay = (int16)i2cData[1]; asaz = (int16)i2cData[2]; #ifdef NOASA if((asax==0)||(asay==0)||(asaz==0)){ asax = 128; asay = 128; asaz = 128; } #endif // TEST TEST_DATA(TLIMIT_NO_ASAX, TLIMIT_TN_ASAX, asax, TLIMIT_LO_ASAX, TLIMIT_HI_ASAX, &pf_total); TEST_DATA(TLIMIT_NO_ASAY, TLIMIT_TN_ASAY, asay, TLIMIT_LO_ASAY, TLIMIT_HI_ASAY, &pf_total); TEST_DATA(TLIMIT_NO_ASAZ, TLIMIT_TN_ASAZ, asaz, TLIMIT_LO_ASAZ, TLIMIT_HI_ASAZ, &pf_total); // Read values. CNTL if (AKD_RxData(AK8975_REG_CNTL, i2cData, 1) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } // Set to PowerDown mode if (AKD_SetMode(AK8975_MODE_POWERDOWN) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } // TEST TEST_DATA(TLIMIT_NO_WR_CNTL, TLIMIT_TN_WR_CNTL, (int16)i2cData[0], TLIMIT_LO_WR_CNTL, TLIMIT_HI_WR_CNTL, &pf_total); //*********************************************** // Step2 //*********************************************** // Set to SNG measurement pattern (Set CNTL register) if (AKD_SetMode(AK8975_MODE_SNG_MEASURE) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } // Wait for DRDY pin changes to HIGH. // Get measurement data from AK8975 // ST1 + (HXL + HXH) + (HYL + HYH) + (HZL + HZH) + ST2 // = 1 + (1 + 1) + (1 + 1) + (1 + 1) + 1 = 8 bytes if (AKD_GetMagneticData(i2cData) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } hdata[0] = (int16)((((uint16)(i2cData[2]))<<8)+(uint16)(i2cData[1])); hdata[1] = (int16)((((uint16)(i2cData[4]))<<8)+(uint16)(i2cData[3])); hdata[2] = (int16)((((uint16)(i2cData[6]))<<8)+(uint16)(i2cData[5])); // TEST TEST_DATA(TLIMIT_NO_SNG_ST1, TLIMIT_TN_SNG_ST1, (int16)i2cData[0], TLIMIT_LO_SNG_ST1, TLIMIT_HI_SNG_ST1, &pf_total); TEST_DATA(TLIMIT_NO_SNG_HX, TLIMIT_TN_SNG_HX, hdata[0], TLIMIT_LO_SNG_HX, TLIMIT_HI_SNG_HX, &pf_total); TEST_DATA(TLIMIT_NO_SNG_HY, TLIMIT_TN_SNG_HY, hdata[1], TLIMIT_LO_SNG_HY, TLIMIT_HI_SNG_HY, &pf_total); TEST_DATA(TLIMIT_NO_SNG_HZ, TLIMIT_TN_SNG_HZ, hdata[2], TLIMIT_LO_SNG_HZ, TLIMIT_HI_SNG_HZ, &pf_total); TEST_DATA(TLIMIT_NO_SNG_ST2, TLIMIT_TN_SNG_ST2, (int16)i2cData[7], TLIMIT_LO_SNG_ST2, TLIMIT_HI_SNG_ST2, &pf_total); // Generate magnetic field for self-test (Set ASTC register) i2cData[0] = 0x40; if (AKD_TxData(AK8975_REG_ASTC, i2cData, 1) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } // Set to Self-test mode (Set CNTL register) if (AKD_SetMode(AK8975_MODE_SELF_TEST) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } // Wait for DRDY pin changes to HIGH. // Get measurement data from AK8975 // ST1 + (HXL + HXH) + (HYL + HYH) + (HZL + HZH) + ST2 // = 1 + (1 + 1) + (1 + 1) + (1 + 1) + 1 = 8Byte if (AKD_GetMagneticData(i2cData) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } // TEST TEST_DATA(TLIMIT_NO_SLF_ST1, TLIMIT_TN_SLF_ST1, (int16)i2cData[0], TLIMIT_LO_SLF_ST1, TLIMIT_HI_SLF_ST1, &pf_total); hdata[0] = (int16)((((uint16)(i2cData[2]))<<8)+(uint16)(i2cData[1])); hdata[1] = (int16)((((uint16)(i2cData[4]))<<8)+(uint16)(i2cData[3])); hdata[2] = (int16)((((uint16)(i2cData[6]))<<8)+(uint16)(i2cData[5])); // TEST TEST_DATA( TLIMIT_NO_SLF_RVHX, TLIMIT_TN_SLF_RVHX, (hdata[0])*((asax - 128)*0.5f/128.0f + 1), TLIMIT_LO_SLF_RVHX, TLIMIT_HI_SLF_RVHX, &pf_total ); TEST_DATA( TLIMIT_NO_SLF_RVHY, TLIMIT_TN_SLF_RVHY, (hdata[1])*((asay - 128)*0.5f/128.0f + 1), TLIMIT_LO_SLF_RVHY, TLIMIT_HI_SLF_RVHY, &pf_total ); TEST_DATA( TLIMIT_NO_SLF_RVHZ, TLIMIT_TN_SLF_RVHZ, (hdata[2])*((asaz - 128)*0.5f/128.0f + 1), TLIMIT_LO_SLF_RVHZ, TLIMIT_HI_SLF_RVHZ, &pf_total ); // TEST TEST_DATA(TLIMIT_NO_SLF_ST2, TLIMIT_TN_SLF_ST2, (int16)i2cData[7], TLIMIT_LO_SLF_ST2, TLIMIT_HI_SLF_ST2, &pf_total); // Set to Normal mode for self-test. i2cData[0] = 0x00; if (AKD_TxData(AK8975_REG_ASTC, i2cData, 1) != AKD_SUCCESS) { DBGPRINT(DBG_LEVEL1, "%s:%d Error.\n", __FUNCTION__, __LINE__); return 0; } return pf_total; }
/*! Carry out self-test. @return If this function succeeds, the return value is #AKM_SUCCESS. Otherwise the return value is #AKM_FAIL. */ int16 AKFS_SelfTest(void) { BYTE i2cData[SENSOR_DATA_SIZE]; BYTE asa[3]; AKFLOAT hdata[3]; int16 ret; /* Set to FUSE ROM access mode */ if (AKD_SetMode(AK8975_MODE_FUSE_ACCESS) != AKD_SUCCESS) { AKMERROR; return AKM_FAIL; } /* Read values from ASAX to ASAZ */ if (AKD_RxData(AK8975_FUSE_ASAX, asa, 3) != AKD_SUCCESS) { AKMERROR; return AKM_FAIL; } /* Set to PowerDown mode */ if (AKD_SetMode(AK8975_MODE_POWERDOWN) != AKD_SUCCESS) { AKMERROR; return AKM_FAIL; } /* Set to self-test mode */ i2cData[0] = 0x40; if (AKD_TxData(AK8975_REG_ASTC, i2cData, 1) != AKD_SUCCESS) { AKMERROR; return AKM_FAIL; } /* Set to Self-test mode */ if (AKD_SetMode(AK8975_MODE_SELF_TEST) != AKD_SUCCESS) { AKMERROR; return AKM_FAIL; } /* Wait for DRDY pin changes to HIGH. Get measurement data from AK8975 */ if (AKD_GetMagneticData(i2cData) != AKD_SUCCESS) { AKMERROR; return AKM_FAIL; } hdata[0] = AK8975_HDATA_CONVERTER(i2cData[2], i2cData[1], asa[0]); hdata[1] = AK8975_HDATA_CONVERTER(i2cData[4], i2cData[3], asa[1]); hdata[2] = AK8975_HDATA_CONVERTER(i2cData[6], i2cData[5], asa[2]); /* Test */ ret = 1; if ((hdata[0] < AK8975_SELFTEST_MIN_X) || (AK8975_SELFTEST_MAX_X < hdata[0])) { ret = 0; } if ((hdata[1] < AK8975_SELFTEST_MIN_Y) || (AK8975_SELFTEST_MAX_Y < hdata[1])) { ret = 0; } if ((hdata[2] < AK8975_SELFTEST_MIN_Z) || (AK8975_SELFTEST_MAX_Z < hdata[2])) { ret = 0; } AKMDEBUG(DBG_LEVEL2, "Test(%s):%8.2f, %8.2f, %8.2f\n", (ret ? "Success" : "fail"), hdata[0], hdata[1], hdata[2]); if (ret) { return AKM_SUCCESS; } else { return AKM_FAIL; } }