SENtral Simple Serial Host interface for PNI Sensor Corp SENtral-A2 motion coprocessor. For use with the RM3100RTI Arduino shield module on top of an STM4 serial mbed board. Will work with an PNI RM3100RTI module or M&M motion modules. Interaction with unit using built in USB serial serial port set for 115200 baud. Send '?' char for menu. Presently requires SENtral firmware to either be loaded in the RM3100RTI Arduino shield SD Card or preloaded in the RM3100RTI or M&M module's EEPROM. Firmware is typically preloaded on the module's EEPROM by PNI. PNI Sensor, 2019 www.pnicorp.com

Dependencies:   mbed SDFileSystemVSG

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers em7186.cpp Source File

em7186.cpp

00001 /**
00002 * @file         em7186.c
00003 *
00004 * @brief        Sample interface for the em7186.
00005 *
00006 * @authors      David Vincent, Joe Miller
00007 * @date         05/12/2016
00008 * @copyright    (C) 2015, 2016 PNI Corp
00009 *
00010 * @copyright    Disclosure to third parties or reproduction in any form
00011 *               whatsoever, without prior written consent, is strictly forbidden
00012 *
00013 */
00014 #include "em7186.h"
00015 
00016 
00017 float   em7186_sensor_scale[128];
00018 u32     timestampNonWake;
00019 u32     timestampWake;
00020 u8      printData = 1; // a switch to enable/disable display data (vs logData)
00021 u8      logData = 0;   // a switch to enable/disable log data to SD Card 
00022 u8      sensorEnabled[64];
00023 u8      haveSensorInfo = 0;
00024 u16     magMaxRate = 0;
00025 u16     accelMaxRate = 0;
00026 u16     gyroMaxRate = 0;
00027 u32     timestamp;
00028 u16     timestampPtr[2];
00029 
00030 SensorDescriptor sensorInformation[128];
00031 SensorConfiguration sensorConfiguration[127];
00032 
00033 
00034 ParamInfo sensorInfoParamList[128] =
00035 {
00036     { 0, 16 },
00037     { 1, 16 },
00038     { 2, 16 },
00039     { 3, 16 },
00040     { 4, 16 },
00041     { 5, 16 },
00042     { 6, 16 },
00043     { 7, 16 },
00044     { 8, 16 },
00045     { 9, 16 },
00046     { 10, 16 },
00047     { 11, 16 },
00048     { 12, 16 },
00049     { 13, 16 },
00050     { 14, 16 },
00051     { 15, 16 },
00052     { 16, 16 },
00053     { 17, 16 },
00054     { 18, 16 },
00055     { 19, 16 },
00056     { 20, 16 },
00057     { 21, 16 },
00058     { 22, 16 },
00059     { 23, 16 },
00060     { 24, 16 },
00061     { 25, 16 },
00062     { 26, 16 },
00063     { 27, 16 },
00064     { 28, 16 },
00065     { 29, 16 },
00066     { 30, 16 },
00067     { 31, 16 },
00068     { 32, 16 },
00069     { 33, 16 },
00070     { 34, 16 },
00071     { 35, 16 },
00072     { 36, 16 },
00073     { 37, 16 },
00074     { 38, 16 },
00075     { 39, 16 },
00076     { 40, 16 },
00077     { 41, 16 },
00078     { 42, 16 },
00079     { 43, 16 },
00080     { 44, 16 },
00081     { 45, 16 },
00082     { 46, 16 },
00083     { 47, 16 },
00084     { 48, 16 },
00085     { 49, 16 },
00086     { 50, 16 },
00087     { 51, 16 },
00088     { 52, 16 },
00089     { 53, 16 },
00090     { 54, 16 },
00091     { 55, 16 },
00092     { 56, 16 },
00093     { 57, 16 },
00094     { 58, 16 },
00095     { 59, 16 },
00096     { 60, 16 },
00097     { 61, 16 },
00098     { 62, 16 },
00099     { 63, 16 },
00100     { 64, 16 },
00101     { 65, 16 },
00102     { 66, 16 },
00103     { 67, 16 },
00104     { 68, 16 },
00105     { 69, 16 },
00106     { 70, 16 },
00107     { 71, 16 },
00108     { 72, 16 },
00109     { 73, 16 },
00110     { 74, 16 },
00111     { 75, 16 },
00112     { 76, 16 },
00113     { 77, 16 },
00114     { 78, 16 },
00115     { 79, 16 },
00116     { 80, 16 },
00117     { 81, 16 },
00118     { 82, 16 },
00119     { 83, 16 },
00120     { 84, 16 },
00121     { 85, 16 },
00122     { 86, 16 },
00123     { 87, 16 },
00124     { 88, 16 },
00125     { 89, 16 },
00126     { 90, 16 },
00127     { 91, 16 },
00128     { 92, 16 },
00129     { 93, 16 },
00130     { 94, 16 },
00131     { 95, 16 },
00132     { 96, 16 },
00133     { 97, 16 },
00134     { 98, 16 },
00135     { 99, 16 },
00136     { 100, 16 },
00137     { 101, 16 },
00138     { 102, 16 },
00139     { 103, 16 },
00140     { 104, 16 },
00141     { 105, 16 },
00142     { 106, 16 },
00143     { 107, 16 },
00144     { 108, 16 },
00145     { 109, 16 },
00146     { 110, 16 },
00147     { 111, 16 },
00148     { 112, 16 },
00149     { 113, 16 },
00150     { 114, 16 },
00151     { 115, 16 },
00152     { 116, 16 },
00153     { 117, 16 },
00154     { 118, 16 },
00155     { 119, 16 },
00156     { 120, 16 },
00157     { 121, 16 },
00158     { 122, 16 },
00159     { 123, 16 },
00160     { 124, 16 },
00161     { 125, 16 },
00162     { 126, 16 },
00163     { 127, 16 },
00164 };
00165 
00166 
00167 u32 em7186_i2c_init()
00168 {
00169     u8 buffer[1];
00170     em7186_i2c_read(PRODUCT_ID_REG, buffer, 1);
00171     
00172     switch(buffer[0])
00173     {
00174         case PRODUCT_ID_7180:
00175             printf("SENtral found\n\r");
00176             break;   
00177         case PRODUCT_ID_7184:
00178             printf("SENtral-A found\n\r");        
00179             break;   
00180         case PRODUCT_ID_7186:
00181             printf("SENtral-A2 found\n\r");        
00182             break;   
00183         default:
00184             printf("SENtral NOT FOUND, ID returned = %u\n\r",buffer[0]);
00185             return 0;
00186   
00187      }  
00188     return 1;
00189 }
00190 
00191 void firmwareTransfer(char srcDestCode)
00192 {
00193     switch (srcDestCode) {
00194 //        case 'r':
00195 //            if (displayText) printf("begin Upload of firmware to  SENtral RAM\n\r");
00196 //            SENtral_InterruptPin.disable_irq();
00197 //            if (!) {
00198 //                if (displayText) printf("Error uploading SENtral firmware to RAM\n\r");
00199 //            }
00200 //            SENtral_InterruptPin.enable_irq();
00201 //            break;
00202 //            
00203 //        case 'e':
00204 //            if (displayText) printf("begin Upload of firmware to PNI Module EEPROM\n\r");
00205 //            SENtral_InterruptPin.disable_irq();
00206 //            if (!) {
00207 //                if (displayText) printf("Error uploading SENtral firmware to EEPROM\n\r");
00208 //            }
00209 //            SENtral_InterruptPin.enable_irq();
00210 //            break;
00211 //            
00212 //        case 's':
00213 //            if (displayText) printf("begin Upload of firmware to SDCard\n\r");
00214 //            SENtral_InterruptPin.disable_irq();
00215 //            if (!) {
00216 //                if (displayText) printf("Error uploading SENtral firmware to SDCard\n\r");
00217 //            }
00218 //            SENtral_InterruptPin.enable_irq();
00219 //            break;
00220             
00221         case 'R':
00222             if (displayText) printf("Transfering firmware from SDCard to SENtral RAM\n\r");
00223             SENtral_InterruptPin.disable_irq();
00224             if (!em7186_firmware_Transfer2RAM(fw)) {
00225                 if (displayText) printf("Error transfering SENtral firmware to RAM\n\r");
00226                 break;
00227             }
00228             // Enable CPU
00229             em7186_i2c_write_value(CHIP_CONTROL_REG, CHIP_CONTROL_CPU_RUN);        
00230             em7186_set_scale_factors();
00231             SENtral_InterruptPin.enable_irq();
00232             break;
00233             
00234         case 'E':
00235             if (displayText) printf("Transfering firmware from SDCard to PNI Module EEPROM\n\r");
00236             SENtral_InterruptPin.disable_irq();
00237             if (!em7186_firmware_Transfer2EE(fw)) {
00238                 if (displayText) printf("Error transfering SENtral firmware to EEPROM\n\r");
00239             }
00240             break;
00241 
00242         default:
00243             serialCommandMode = 0;
00244 
00245     }
00246 
00247 
00248 }
00249 
00250 
00251 
00252 
00253 u32 em7186_i2c_write_value(u8 registerAddress, u8 value)
00254 {
00255     u32 status = em7186_i2c_write(registerAddress, &value, 1);
00256     return status;
00257 }
00258 
00259 
00260 //=========================================================================
00261 // Helper functions
00262 //=========================================================================
00263 u8  get_3_axis_sensor_data(SensorData3Axis *data, float scale, u8* buffer)
00264 {
00265     SensorData3AxisRaw rawData;
00266     memcpy(&rawData, &buffer[1], sizeof(rawData));
00267     data->x = (float)rawData.x * scale;
00268     data->y = (float)rawData.y * scale;
00269     data->z = (float)rawData.z * scale;
00270     data->extra = rawData.status;
00271 
00272     return 1;
00273 }
00274 u8  get_3_axis_uncal_sensor_data(SensorData6Axis *data, float scale, u8* buffer)
00275 {
00276     SensorData3AxisUncalRaw rawData;
00277     memcpy(&rawData, &buffer[1], sizeof(rawData));
00278     data->x = (float)rawData.x * scale;
00279     data->y = (float)rawData.y * scale;
00280     data->z = (float)rawData.z * scale;
00281     data->x_bias = (float)rawData.x_bias * scale;
00282     data->y_bias = (float)rawData.y_bias * scale;
00283     data->z_bias = (float)rawData.z_bias * scale;
00284     data->extra = rawData.status;
00285 
00286     return 1;
00287 }
00288 u8  get_rotation_vector(SensorData4Axis *rv, float quaternionScale, u8* buffer)
00289 {
00290     RotationVectorRaw rawData;
00291     memcpy(&rawData, &buffer[1], sizeof(rawData));
00292     rv->x = (float)rawData.x * quaternionScale;
00293     rv->y = (float)rawData.y * quaternionScale;
00294     rv->z = (float)rawData.z * quaternionScale;
00295     rv->w = (float)rawData.w * quaternionScale;
00296     rv->extra = (float)rawData.accuracy * ((float)M_PI / powf(2.0f, 14.0f));
00297 
00298     return 1;
00299 }
00300 
00301 //=========================================================================
00302 // Core functions
00303 //=========================================================================
00304 u32 em7186_firmware_Transfer2RAM(const u8 *firmwareName)
00305 {
00306    
00307     // reset Sentral
00308     em7186_i2c_write_value(RESET_REQ_REG, 1);
00309     em7186_i2c_write_value(CHIP_CONTROL_REG, CHIP_CONTROL_HOST_UPLOAD);
00310 
00311     ///////////////////////////////////////////////////////////////////////////
00312     // Load firmware from file
00313     ///////////////////////////////////////////////////////////////////////////
00314     // Open firmware file
00315     FILE *fw_h = fopen(firmwareName, "rb");
00316     if (!fw_h)
00317     {
00318         if (displayText) printf("ERROR: Unable to open file\n\r");
00319         return 0;
00320     }
00321     
00322     if (displayText) printf("Firmware file found\n\r");
00323 
00324     // Read the firmware header
00325     struct fwHeader
00326     {
00327         u8 imageSignatureLsb;
00328         u8 imageSignatureMsb;
00329         u16 flags;
00330         u32 crc;
00331         u32 reserved;
00332         u16 imageLength;
00333         u16 reserved2;
00334     } fwHeader;
00335     int hsize = fread(&fwHeader, 1, FIRMWARE_HEADER_SIZE, fw_h);
00336     if ( hsize != FIRMWARE_HEADER_SIZE)
00337     {
00338         if (displayText) printf("ERROR: File smaller than expected header size %d\n\r", hsize);
00339         fclose(fw_h);
00340         return 0;
00341     }
00342 
00343     // Validate firmware
00344     if (fwHeader.imageSignatureLsb != IMAGE_SIGNATURE_LSB || fwHeader.imageSignatureMsb != IMAGE_SIGNATURE_MSG)
00345     {
00346         if (displayText) printf("ERROR: Firmware version doesn't match\n\r");
00347         fclose(fw_h);
00348         return 0;
00349     }
00350 
00351     // TODO: ensure that firmware version matches rom version
00352 
00353     // Read the firmware image
00354     u8 *fw = (u8 *)malloc(fwHeader.imageLength);
00355     u32 firmwareSize = fread(fw, 1, fwHeader.imageLength, fw_h);
00356     fclose(fw_h);
00357     if (firmwareSize != fwHeader.imageLength || firmwareSize % 4)
00358     {
00359         if (displayText) printf("ERROR: Firmware size must break on 4 byte boundary\n\r");
00360         free(fw);
00361         return 0;
00362     }
00363 
00364     ///////////////////////////////////////////////////////////////////////////
00365     // Upload firmware to RAM
00366     ///////////////////////////////////////////////////////////////////////////
00367     // TODO: set upload address if needed. (zero by default)
00368 
00369     if (displayText) printf("Uploading Firmware to SENtral RAM...\n\r");
00370 
00371     s32 bytesWritten = 0,
00372         bytesRemaining = firmwareSize;
00373     u8 bytesToWrite, i,
00374         buf[MAX_I2C_WRITE],
00375         maxI2cWrite = MAX_I2C_WRITE;
00376 
00377     while (bytesRemaining > 0)
00378     {
00379         if (bytesRemaining < MAX_I2C_WRITE)      
00380             bytesToWrite = bytesRemaining;
00381         else
00382             bytesToWrite = maxI2cWrite;
00383 
00384         // Reverse byte order per word
00385         for (i = 0; i < bytesToWrite; i += 4)
00386         {
00387             buf[i + 0] = fw[bytesWritten + i + 3];
00388             buf[i + 1] = fw[bytesWritten + i + 2];
00389             buf[i + 2] = fw[bytesWritten + i + 1];
00390             buf[i + 3] = fw[bytesWritten + i + 0];
00391         }
00392 
00393         if (!em7186_i2c_write(SR_UPLOAD_DATA_REG, buf, bytesToWrite))
00394         {
00395             if (displayText) printf("ERROR: Problem writing to sentral\n\r");
00396             free(fw);
00397             return 0;
00398         }
00399 
00400         bytesRemaining -= bytesToWrite;
00401         bytesWritten += bytesToWrite;
00402     }
00403 
00404     free(fw);
00405 
00406     if (displayText) printf("Firmware Uploaded......");
00407 
00408     // Read and verify CRC
00409     u32 hostCRC = 0;
00410     em7186_i2c_read(HOST_CRC_REG, (u8*)&hostCRC, 4);
00411     u32 fwHeaderCRC = fwHeader.crc;//((u32*)fwHeader)[1];
00412     if (hostCRC != fwHeaderCRC)
00413     {
00414         if (displayText) printf("ERROR: CRC doesn't match\n\r");
00415         return 0;
00416     }
00417     
00418     if (displayText) printf(" CRC Match!!\n\r");
00419     return 1;
00420 }
00421 
00422 
00423 
00424 
00425 u32 em7186_firmware_Transfer2EE(const u8 *firmwareName)
00426 {
00427     u8  buffer[16];
00428     u8  trys = 1;
00429     u16 count;
00430     // Open firmware file
00431     FILE *fw_h = fopen(firmwareName, "rb");
00432     if (!fw_h) {
00433         if (displayText) printf("ERROR: Unable to open file\n\r");
00434         return 0;
00435     }
00436 
00437     if (displayText) printf("Firmware file found\n\r");
00438 
00439     // Read the firmware header
00440     struct fwHeader {
00441         u8 imageSignatureLsb;
00442         u8 imageSignatureMsb;
00443         u16 flags;
00444         u32 crc;
00445         u32 reserved;
00446         u16 imageLength;
00447         u16 reserved2;
00448     } fwHeader;
00449 
00450     int hsize = fread(&fwHeader, 1, FIRMWARE_HEADER_SIZE, fw_h);
00451     if ( hsize != FIRMWARE_HEADER_SIZE) {
00452         if (displayText) printf("ERROR: File smaller than expected header size %d\n\r", hsize);
00453         fclose(fw_h);
00454         return 0;
00455     }
00456 
00457     // Validate firmware
00458     if (fwHeader.imageSignatureLsb != IMAGE_SIGNATURE_LSB || fwHeader.imageSignatureMsb != IMAGE_SIGNATURE_MSG) {
00459         if (displayText) printf("ERROR: Firmware version doesn't match\n\r");
00460         fclose(fw_h);
00461         return 0;
00462     }
00463 
00464     // Read the firmware image From the SD Card
00465     u8 *fw = (u8 *)malloc(fwHeader.imageLength);
00466     u32 firmwareSize = fread(fw, 1, fwHeader.imageLength, fw_h);
00467     fclose(fw_h);
00468     if (firmwareSize != fwHeader.imageLength || firmwareSize % 4) {
00469         if (displayText) printf("ERROR: Firmware size must break on 4 byte boundary\n\r");
00470         free(fw);
00471         return 0;
00472     }
00473     if (displayText) printf("Firmware size = %u\n\r",firmwareSize);
00474 
00475 
00476    u8 headerBytes[FIRMWARE_HEADER_SIZE];
00477    memcpy(headerBytes,(u8*)&fwHeader,FIRMWARE_HEADER_SIZE); // create a bytewise copy of fwHeader
00478 
00479 
00480     ///////////////////////////////////////////////////////////////////////////
00481     // Upload firmware to EEPROM
00482     ///////////////////////////////////////////////////////////////////////////
00483 
00484     do {
00485         // request SENtral passthrough mode
00486         em7186_i2c_write_value(PASS_THROUGH_CFG_REG, 1);
00487         em7186_i2c_read(PASS_THROUGH_RDY_REG, buffer, 1);
00488     } while((buffer[0] != 1) && (++trys < 20));
00489 
00490 
00491     if (trys <20) {
00492 
00493         // Reverse byte order per word
00494 
00495 
00496         if (displayText) printf("SENtral confirmed passthrough mode after %u try(s)\n\r",trys);
00497 
00498 
00499         // write header portion to EEPROM from SDCard
00500         //key: EE_Write(u8 I2C_Addr, u16 EE_MemAddr, u8*buffer, u16 length)
00501         u32 status = EE_Write(0xA0, 0, (u8*)&fwHeader, FIRMWARE_HEADER_SIZE);
00502         if (displayText) printf("Header Sent to EEPROM......\n\r",firmwareSize);
00503         wait_ms(5);
00504         EE_Read(0xA0, 0, buffer, FIRMWARE_HEADER_SIZE);
00505         status = 0;
00506 
00507         // Readback EEPROM to verify header write
00508         for (count = 0; count<FIRMWARE_HEADER_SIZE; count++) {
00509             if (headerBytes[count] != buffer[count]) {
00510                 status = 1;  // 1 = fail
00511                 if (displayText) printf("Failed Header readback from EEPROM at %u, value=%u\n\r",count,headerBytes[count]);
00512                 break;
00513             }
00514         }
00515 
00516         if (!status) {
00517            u32 bytesWritten = 0;
00518             u32 bytesRemaining = firmwareSize;
00519             u8 bytesToWrite,
00520                maxI2cWrite = 16; // kind of small but ensures page alignment
00521 
00522             while (bytesRemaining > 0) {
00523                 if (bytesRemaining < maxI2cWrite)
00524                     bytesToWrite = bytesRemaining;
00525                 else
00526                     bytesToWrite = maxI2cWrite;
00527 
00528                 if (!EE_Write(0xA0, (bytesWritten+FIRMWARE_HEADER_SIZE), &fw[bytesWritten], bytesToWrite)) {
00529                     if (displayText) printf("\n\rCould not write to EEPROM\n\r");
00530                     free(fw);
00531                     wait_ms(5);
00532                     em7186_i2c_write_value(PASS_THROUGH_CFG_REG, 0);
00533                     return 0;
00534                 }
00535                 bytesWritten += bytesToWrite;
00536                 bytesRemaining -= bytesToWrite;
00537                 if (displayText) printf("\r%u",bytesWritten);
00538                 wait_ms(5);
00539             }
00540 
00541             if (displayText) printf("\n\rFirmware Transfered from SDCard to EEPROM.  Now Verifying.....\n\r");
00542 
00543             u32 bytesRead = 0;
00544             bytesRemaining = firmwareSize;
00545             u8 bytesToRead,
00546                maxI2cRead = 16;
00547             status = 0; 
00548             
00549             while ((bytesRemaining > 0) && (status == 0)) {
00550                 if (bytesRemaining < maxI2cRead)
00551                     bytesToRead = bytesRemaining;
00552                 else
00553                     bytesToRead = maxI2cRead;
00554                     
00555                 if (!EE_Read(0xA0, (bytesRead+FIRMWARE_HEADER_SIZE), buffer, bytesToRead)) {
00556                     if (displayText) printf("\n\rCould not Read EEPROM\n\r");
00557                     free(fw);
00558                     wait_ms(5);
00559                     em7186_i2c_write_value(PASS_THROUGH_CFG_REG, 0);
00560                     return 0;
00561                 }
00562 
00563                 for (count = 0; count<bytesToRead; count++) {
00564                     if (fw[bytesRead+count] != buffer[count]) {
00565                         status = 1;  // 1 = fail
00566                         if (displayText) printf("Failed firmware readback from EEPROM at %u, value=%u\n\r",bytesRead+FIRMWARE_HEADER_SIZE+count,buffer[count]);
00567                         wait_ms(5);
00568                         em7186_i2c_write_value(PASS_THROUGH_CFG_REG, 0);
00569                         return 0;
00570                     }
00571                 }
00572                 bytesRead += bytesToRead;
00573                 bytesRemaining -= bytesToRead;
00574                 if (displayText) printf("\r%u",bytesRead);
00575                 wait_ms(1);
00576             }
00577             if(status == 0)
00578             {
00579                 if (displayText) printf("\n\rVerify EEPROM **** SUCCESSFUL *****\n\r");
00580             }
00581         } else {
00582             if (displayText) printf("\r\nCould not write to EEPROM (Header)\n\r");
00583             wait_ms(5);
00584             em7186_i2c_write_value(PASS_THROUGH_CFG_REG, 0);
00585             return 0;
00586         }
00587 
00588         free(fw);
00589 
00590     } else {
00591         if (displayText) printf("Could not confirm SENtral Passthrough mode\n\r");
00592         return 0;
00593     }
00594 
00595     em7186_i2c_write_value(PASS_THROUGH_CFG_REG, 0); // turn off passthrough mode
00596 
00597     return 1;
00598 }
00599 
00600 
00601 
00602 
00603 
00604 u32 em7186_param_read(u8 *values, u8 page, ParamInfo *paramList, u8 numParams)
00605 {
00606     
00607     u8 i, paramAck, pageSelectValue;
00608     u16 valIndex = 0;
00609     for (i = 0; i < numParams; i++)
00610     {
00611         pageSelectValue = page | (paramList[i].size << 4);
00612         em7186_i2c_write_value(PARAM_PAGE_SELECT_REG, pageSelectValue);
00613         em7186_i2c_write_value(PARAM_REQUEST_REG, paramList[i].paramNo);
00614         do
00615         {
00616             em7186_i2c_read(PARAM_ACK_REG, &paramAck, 1);
00617             if (paramAck == 0x80)
00618             {
00619                 em7186_i2c_write_value(PARAM_REQUEST_REG, 0);
00620                 em7186_i2c_write_value(PARAM_PAGE_SELECT_REG, 0);
00621                 
00622 
00623                 return 0;
00624             }
00625         } while (paramAck != paramList[i].paramNo);
00626         em7186_i2c_read(PARAM_SAVE_REG, &values[valIndex], paramList[i].size);
00627 //      printf("%u ", values[valIndex]);
00628         valIndex += paramList[i].size;
00629     }
00630     em7186_i2c_write_value(PARAM_REQUEST_REG, 0);
00631     em7186_i2c_write_value(PARAM_PAGE_SELECT_REG, 0);
00632     
00633 
00634     return 1;
00635 }
00636 u32 em7186_param_write(u8 *values, u8 page, ParamInfo *paramList, u8 numParams)
00637 {
00638     
00639 
00640     u8 i, paramAck, paramNum, pageSelectValue;
00641     u16 valIndex = 0;
00642     for (i = 0; i < numParams; i++)
00643     {
00644         pageSelectValue = page | (paramList[i].size << 4);
00645         em7186_i2c_write_value(PARAM_PAGE_SELECT_REG, pageSelectValue);
00646 
00647         em7186_i2c_write(PARAM_LOAD_REG, &values[valIndex], (u16)paramList[i].size);
00648 
00649         paramNum = paramList[i].paramNo | 0x80;
00650         em7186_i2c_write_value(PARAM_REQUEST_REG, paramNum);
00651         do
00652         {
00653             em7186_i2c_read(PARAM_ACK_REG, &paramAck, 1);
00654             if (paramAck == 0x80)
00655             {
00656                 em7186_i2c_write_value(PARAM_REQUEST_REG, 0);
00657                 em7186_i2c_write_value(PARAM_PAGE_SELECT_REG, 0);
00658                 
00659 
00660                 return 0;
00661             }
00662         } while (paramAck != paramNum);
00663 
00664         valIndex += paramList[i].size;
00665     }
00666 
00667     em7186_i2c_write_value(PARAM_REQUEST_REG, 0);
00668     em7186_i2c_write_value(PARAM_PAGE_SELECT_REG, 0);
00669     
00670 
00671     return 1;
00672 }
00673 u32 em7186_read_fifo(u8 *buffer)
00674 {
00675     // Check number of bytes available
00676     u16 bytesAvailable, bytesRead = 0;
00677 
00678     em7186_i2c_read(BYTES_REMANING_REG, (u8*)&bytesAvailable, 2);
00679 
00680 
00681     //printf("FIFO bytesAvailable:%u\n\r",bytesAvailable);
00682 
00683     
00684 
00685 #define CONTINUOUS_FIFO_READ
00686 #ifdef CONTINUOUS_FIFO_READ
00687     bytesRead = em7186_i2c_read(0, buffer, bytesAvailable);
00688 #else
00689     u16 i, bytesToRead;
00690     while (bytesAvailable > 0)
00691     {
00692         // Break on 50 byte fifo register block
00693         bytesToRead = bytesRead % 50 + I2C_MAX_READ > 50 ? 50 - bytesRead % 50 : I2C_MAX_READ;
00694         // Make sure we don't read more than is available in the fifo
00695         bytesToRead = min(bytesAvailable, bytesToRead);
00696         if (!em7186_i2c_read(bytesRead % 50, &buffer[bytesRead], bytesToRead))
00697         {
00698             
00699             return 0;
00700         }
00701         bytesAvailable -= bytesToRead;
00702         bytesRead += bytesToRead;
00703     }
00704 #endif
00705     
00706     //printf("FIFO bytesRead:%u\n\r",bytesRead);
00707 
00708     return bytesRead;
00709 }
00710 u32 em7186_parse_next_fifo_block(u8* buffer, u32 size)
00711 {
00712     u8 sensorId = buffer[0];
00713     
00714 //    if (sensorId < SENSOR_TYPE_ACCELEROMETER_WAKE ||
00715 //        sensorId == SENSOR_TYPE_DEBUG ||
00716 //        sensorId == SENSOR_TYPE_TIMESTAMP ||
00717 //        sensorId == SENSOR_TYPE_TIMESTAMP_OVERFLOW ||
00718 //        sensorId == SENSOR_TYPE_META ||
00719 //        sensorId == SENSOR_TYPE_RAW_GYRO ||
00720 //        sensorId == SENSOR_TYPE_RAW_MAG ||
00721 //        sensorId == SENSOR_TYPE_RAW_ACCEL
00722 //        )
00723 //    {
00724 //     }
00725 //    else
00726 //    {
00727 //        timestamp = timestampWake;
00728 //        timestampPtr = (u16*)&timestampWake;
00729 //    }
00730 
00731     switch(sensorId)
00732     {
00733         case 0:
00734         {
00735             //printf("Padding: %d\n\r", size);
00736             return size;
00737         }
00738         case SENSOR_TYPE_ACCELEROMETER:
00739         case SENSOR_TYPE_ACCELEROMETER_WAKE:
00740         case SENSOR_TYPE_MAGNETIC_FIELD:
00741         case SENSOR_TYPE_MAGNETIC_FIELD_WAKE:
00742         case SENSOR_TYPE_GYROSCOPE:
00743         case SENSOR_TYPE_GYROSCOPE_WAKE:
00744         case SENSOR_TYPE_GRAVITY:
00745         case SENSOR_TYPE_GRAVITY_WAKE:
00746         case SENSOR_TYPE_LINEAR_ACCELERATION:
00747         case SENSOR_TYPE_LINEAR_ACCELERATION_WAKE:
00748         case SENSOR_TYPE_ORIENTATION:
00749         case SENSOR_TYPE_ORIENTATION_WAKE:
00750         {
00751             SensorData3Axis sensorData;
00752             get_3_axis_sensor_data(&sensorData, em7186_sensor_scale[sensorId], buffer);
00753             if (printData) printf("%u %s: %f, %f, %f, %f\n\r", timestamp,em7186_sensor_name[sensorId], sensorData.x, sensorData.y, sensorData.z, sensorData.extra);
00754             if (logData) fprintf(flog,"%u,%u,%f,%f,%f,%f\n", timestamp,sensorId, sensorData.x, sensorData.y, sensorData.z, sensorData.extra);
00755             
00756             return 8;
00757         }
00758         case SENSOR_TYPE_LIGHT:
00759         case SENSOR_TYPE_LIGHT_WAKE:
00760         case SENSOR_TYPE_PROXIMITY:
00761         case SENSOR_TYPE_PROXIMITY_WAKE:
00762         case SENSOR_TYPE_RELATIVE_HUMIDITY:
00763         case SENSOR_TYPE_RELATIVE_HUMIDITY_WAKE:
00764         case SENSOR_TYPE_ACTIVITY:
00765         case SENSOR_TYPE_ACTIVITY_WAKE:
00766         {
00767             float sensorData = (float)((buffer[2] << 8) + buffer[1]) * em7186_sensor_scale[sensorId];
00768             if (printData) printf("%u %s: %fLux\n\r", timestamp,em7186_sensor_name[sensorId], sensorData);
00769             if (logData) fprintf(flog,"%u,%u,%u,%f\n",timestamp, sensorId, sensorData);
00770             return 3;
00771         }
00772         case SENSOR_TYPE_PRESSURE:
00773         case SENSOR_TYPE_PRESSURE_WAKE:
00774         {
00775             float pressure = (float)((buffer[3] << 16) + (buffer[2] << 8) + buffer[1]) * em7186_sensor_scale[sensorId];
00776             if (printData) printf("%u %s: %fPa\n\r", timestamp, em7186_sensor_name[sensorId], pressure);
00777             if (logData) fprintf(flog,"%u,%u,%f\n",timestamp,sensorId,pressure);
00778             return 4;
00779         }
00780         case SENSOR_TYPE_TEMPERATURE:
00781         case SENSOR_TYPE_TEMPERATURE_WAKE:
00782         case SENSOR_TYPE_AMBIENT_TEMPERATURE:
00783         case SENSOR_TYPE_AMBIENT_TEMPERATURE_WAKE:
00784         {
00785             s16 *sensorData = (s16*)&buffer[1];
00786             float temp = (float)(sensorData[0]) * em7186_sensor_scale[sensorId];
00787             if (printData) printf("%u %s: %fC\n\r", timestamp, em7186_sensor_name[sensorId], temp);
00788             if (logData) fprintf(flog,"%u,%u,%f\n",timestamp,sensorId, temp);
00789             return 3;
00790         }
00791         case SENSOR_TYPE_ROTATION_VECTOR:
00792         case SENSOR_TYPE_ROTATION_VECTOR_WAKE:
00793         case SENSOR_TYPE_GAME_ROTATION_VECTOR:
00794         case SENSOR_TYPE_GAME_ROTATION_VECTOR_WAKE:
00795         case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
00796         case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR_WAKE:
00797         case SENSOR_TYPE_PDR:
00798         case SENSOR_TYPE_PDR_WAKE:
00799         case 60:
00800         {
00801             SensorData4Axis rotationVector;
00802             get_rotation_vector(&rotationVector, em7186_sensor_scale[sensorId], buffer);
00803             if (printData) printf("%u %s: %f, %f, %f, %f, %f\n\r", timestamp, em7186_sensor_name[sensorId], rotationVector.x, rotationVector.y, rotationVector.z, rotationVector.w, rotationVector.extra);
00804             if (logData) fprintf(flog,"%u,%u,%f,%f,%f,%f,%f\n", timestamp,sensorId, rotationVector.x, rotationVector.y, rotationVector.z, rotationVector.w, rotationVector.extra);
00805             return 11;
00806         }
00807         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
00808         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED_WAKE:
00809         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
00810         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED_WAKE:
00811         {
00812             SensorData6Axis sensorDataUncal;
00813             get_3_axis_uncal_sensor_data(&sensorDataUncal, em7186_sensor_scale[sensorId], buffer);
00814             if (printData) printf("%u %s: %f, %f, %f, %f, %f, %f, %f\n\r", timestamp, em7186_sensor_name[sensorId], sensorDataUncal.x, sensorDataUncal.y, sensorDataUncal.z, sensorDataUncal.x_bias, sensorDataUncal.y_bias, sensorDataUncal.z_bias, sensorDataUncal.extra);
00815             if (logData) fprintf(flog,"%u,%u,%f,%f,%f,%f,%f,%f,%f\n", timestamp,sensorId, sensorDataUncal.x, sensorDataUncal.y, sensorDataUncal.z, sensorDataUncal.x_bias, sensorDataUncal.y_bias, sensorDataUncal.z_bias, sensorDataUncal.extra);
00816             return 14;
00817         }
00818         case SENSOR_TYPE_STEP_COUNTER:
00819         case SENSOR_TYPE_STEP_COUNTER_WAKE:
00820         {
00821             u16 sensorData = (buffer[2] << 8) + buffer[1];
00822             if (printData) printf("%u %s: %u\n\r", timestamp, em7186_sensor_name[sensorId], sensorData);
00823             if (logData) fprintf(flog,"%u,%u,%u\n", timestamp,sensorId, sensorData);
00824            return 3;
00825         }
00826         case SENSOR_TYPE_HEART_RATE:       
00827         case SENSOR_TYPE_HEART_RATE_WAKE:
00828         {
00829             u8 sensorData = buffer[1];
00830     
00831     // Heart Rate
00832             if (printData) printf("%u %s: %u\n\r", timestamp, em7186_sensor_name[sensorId], sensorData);
00833             if (logData) fprintf(flog,"%u,%u,%u\n",timestamp,sensorId, sensorData);
00834             return 3;
00835         }
00836         case SENSOR_TYPE_CAR_MAG_DATA:
00837         case SENSOR_TYPE_CAR_MAG_DATA_WAKE:
00838         {
00839             // u8 SensorId, float[3] RawMagData, u8 Status, u8 expansion data 
00840             float RawMagData[3];
00841             memcpy(RawMagData, &buffer[1], sizeof(RawMagData));
00842     
00843             if (printData) printf("%u Car Detect Mag Data = %3.3f,%3.3f,%3.3f\n\r", timestamp, RawMagData[0], RawMagData[1], RawMagData[2]);
00844             if (logData) fprintf(flog,"%u,%u,%f,%f,%f\n", timestamp,sensorId, RawMagData[0], RawMagData[1], RawMagData[2]);
00845 
00846             return 15;
00847         }
00848     
00849         case SENSOR_TYPE_SIGNIFICANT_MOTION:
00850         case SENSOR_TYPE_SIGNIFICANT_MOTION_WAKE:
00851         case SENSOR_TYPE_STEP_DETECTOR:
00852         case SENSOR_TYPE_STEP_DETECTOR_WAKE:
00853         case SENSOR_TYPE_TILT_DETECTOR:
00854         case SENSOR_TYPE_TILT_DETECTOR_WAKE:
00855         case SENSOR_TYPE_PICK_UP_GESTURE:
00856         case SENSOR_TYPE_PICK_UP_GESTURE_WAKE:
00857         case SENSOR_TYPE_WAKE_GESTURE:
00858         case SENSOR_TYPE_WAKE_GESTURE_WAKE:
00859         {
00860            if (printData) printf("%u %s\n\r", timestamp, em7186_sensor_name[sensorId]);
00861            if (logData) fprintf(flog,"%u,%u\n", timestamp,sensorId);
00862              return 1;
00863         }
00864         case SENSOR_TYPE_TIMESTAMP:
00865         case SENSOR_TYPE_TIMESTAMP_WAKE:
00866         {
00867             u16* uPacket = (u16*)&buffer[1];
00868             timestampPtr[0] = uPacket[0];
00869             timestamp = *(u32*)timestampPtr;
00870             return 3;
00871         }
00872         case SENSOR_TYPE_TIMESTAMP_OVERFLOW:
00873         case SENSOR_TYPE_TIMESTAMP_OVERFLOW_WAKE:
00874         {
00875             u16* uPacket = (u16*)&buffer[1];
00876             timestampPtr[1] = uPacket[0];
00877             timestampPtr[0] = 0;
00878             timestamp = *(u32*)timestampPtr;
00879             return 3;
00880         }
00881         case SENSOR_TYPE_META:
00882         case SENSOR_TYPE_META_WAKE: 
00883         {
00884             if (reportMetaData) 
00885             {
00886                 if (printData) 
00887                 {
00888                     if (sensorId == SENSOR_TYPE_META_WAKE)
00889                     {
00890                         printf("%u WAKEUP %s:, %s/%u, %u\n\r", timestamp, em7186_meta_event_name[buffer[1]], em7186_sensor_name[buffer[2]],buffer[2], buffer[3]);
00891                     }
00892                     else 
00893                     {
00894                         printf("%u %s: %s/%u, %u\n\r", timestamp, em7186_meta_event_name[buffer[1]], em7186_sensor_name[buffer[2]], buffer[2], buffer[3]);
00895                         // special hook for sample script
00896                         if (buffer[2] == 14)
00897                         {
00898                             if (buffer[3] == 0 ) {
00899                                 green_LED = 1;
00900                                 printf("PASS **** The RM3100 Magnetometer ASIC and sensors are operating properly\n\r");
00901                             } else {
00902                                 green_LED = 1;
00903                                 wait(0.1);
00904                                 green_LED = 0;
00905                                 printf("FAIL **** The RM3100 Magnetometer ASIC and sensors fail code = %u\n\r",buffer[3]);
00906                             }
00907                         }                
00908                     }
00909                 }
00910                 if (logData) fprintf(flog,"%u,%u,%u,%u,%u\n",timestamp,sensorId, buffer[1],buffer[2],buffer[3]);
00911             }
00912             return 4;
00913         }
00914         case SENSOR_TYPE_RAW_ACCEL:
00915         case SENSOR_TYPE_RAW_GYRO:
00916         {
00917             SensorData3Axis sensorData;
00918             float* fPacket = (float*)&buffer[7];
00919             sensorData.x = 256 * (s8)buffer[2] + buffer[1]; //s16 will convert to float here
00920             sensorData.y = 256 * (s8)buffer[4] + buffer[3];
00921             sensorData.z = 256 * (s8)buffer[6] + buffer[5];
00922             sensorData.extra = fPacket[0];
00923             if (printData) printf("%u %s: %3.0f, %3.0f, %3.0f, %3.1f\n\r", timestamp, em7186_sensor_name[sensorId], sensorData.x, sensorData.y, sensorData.z, sensorData.extra);
00924             if (logData) fprintf(flog,"%u,%u,%f,%f,%f,%f\n", timestamp,sensorId, sensorData.x, sensorData.y, sensorData.z, sensorData.extra);
00925             return 11;
00926         }
00927         case SENSOR_TYPE_RAW_MAG:  //jm modified to s32 for RM3100
00928         {
00929             SensorData3Axis sensorData;
00930             //s32* sPacket = (s32*)&buffer[1];
00931             float* fPacket = (float*)&buffer[1];
00932             //sensorData.x = sPacket[0];    //s32 will convert to float here
00933             //sensorData.y = sPacket[1];
00934             //sensorData.z = sPacket[2];
00935             sensorData.x = (float)(buffer[1] + 256 * (buffer[2] + 256 * (buffer[3] + 256 * (buffer[4]))));  //s32 will convert to float here
00936             sensorData.y = buffer[5] + 256 * (buffer[6] + 256 * (buffer[7] + 256 * (buffer[8])));
00937             sensorData.z = buffer[9] + 256 * (buffer[10] + 256 * (buffer[11] + 256 * (buffer[12])));
00938             sensorData.extra = fPacket[3];
00939             if (printData) printf("%u %s: %f, %f, %f\n\r", timestamp, em7186_sensor_name[sensorId], sensorData.x, sensorData.y, sensorData.z);
00940             if (logData) fprintf(flog,"%u,%u,%f,%f,%f\n", timestamp,sensorId, sensorData.x, sensorData.y, sensorData.z);
00941             return 17;
00942         }
00943         case SENSOR_TYPE_DEBUG:
00944         {
00945             u8 packetSize = buffer[1] & 0x3F;
00946             u8 i;
00947             for (i = 0; i < packetSize; i++)
00948             {
00949                 if (printData) printf("%c", (u8)buffer[2 + i]);
00950             }
00951             return 14;
00952         }
00953         default:
00954         {
00955             // Parsing error or unkown sensor type. Clear out the rest of the 
00956             // buffer and start clean on the next read.
00957             if (printData) printf("%u Other: 0x%x: %d bytes skipped\n\r", timestamp, buffer[0], size);
00958             break;
00959         }
00960     
00961     } // end switch(sensorId) 
00962     
00963     return 0;
00964 }
00965 u32 em7186_parse_fifo(u8* buffer, u32 size)
00966 {
00967     u32 index = 0;
00968     u32 bytesUsed;
00969     u32 bytesRemaining = size;
00970 
00971     //if (displayText) printf("FIFO #Bytes to parse:%u\n\r",bytesRemaining);
00972 
00973 
00974     if (size == 0) return size;
00975 
00976     do {
00977         bytesUsed = em7186_parse_next_fifo_block(&buffer[index], bytesRemaining);
00978         index += bytesUsed;
00979         bytesRemaining -= bytesUsed;
00980     } while (bytesUsed > 0 && bytesRemaining > 0);
00981 
00982     return size - bytesRemaining;
00983 }
00984 u32 em7186_set_sensor_rate(u8 sensorId, u16 rate)
00985 {
00986 #ifdef BHI160
00987     u8 paramPage = PARAM_PAGE_SENSOR_INFO;
00988     ParamInfo param[] = { sensorId + 64, 2 };
00989 #else
00990     u8 paramPage = PARAM_PAGE_SENSOR_CONF;
00991     ParamInfo param[] = { sensorId, 2 };
00992 #endif
00993     return em7186_param_write((u8*)&rate, paramPage, param, 1);
00994 }
00995 
00996 
00997 u32 em7186_set_sensor_delay(u8 sensorId, u16 delay)
00998 {
00999 #ifdef BHI160
01000     u8 paramPage = PARAM_PAGE_SENSOR_INFO;
01001     ParamInfo param[] = { sensorId + 64, 2 };
01002 #else
01003     u8 paramPage = PARAM_PAGE_SENSOR_CONF;
01004     ParamInfo param[] = { sensorId, 2 };
01005 #endif
01006     u16 config[2];
01007 
01008     em7186_param_read((u8*)config, paramPage, param, 1);
01009     config[1] = delay;
01010     return em7186_param_write((u8*)config, paramPage, param, 1);
01011 }
01012 u32 em7186_set_meta_event(u8 eventId, u8 enable, u8 enableInt)
01013 {
01014     unsigned long metaEventBits;
01015     ParamInfo param[] = { 1, 8 };
01016 
01017     em7186_param_read((u8*)&metaEventBits, PARAM_PAGE_SYSTEM, param, 1);
01018     unsigned long bitMask = !(0x03 << ((eventId - 1) * 2));
01019     unsigned long setting = ((enable ? 0x02 : 0x00) | (enableInt ? 0x01 : 0x00)) << ((eventId - 1) * 2);
01020     metaEventBits = (metaEventBits & bitMask) | setting;
01021     em7186_param_write((u8*)&metaEventBits, PARAM_PAGE_SYSTEM, param, 1);
01022 
01023     return 1;
01024 }
01025 u8  em7186_set_scale_factors()
01026 {
01027     // Fixed range
01028     em7186_sensor_scale[SENSOR_TYPE_ORIENTATION_WAKE] =
01029         em7186_sensor_scale[SENSOR_TYPE_ORIENTATION] =
01030         360.0f / powf(2.0f, 15.0f); // Fixed
01031 
01032     em7186_sensor_scale[SENSOR_TYPE_ROTATION_VECTOR] =
01033         em7186_sensor_scale[SENSOR_TYPE_ROTATION_VECTOR_WAKE] =
01034         em7186_sensor_scale[SENSOR_TYPE_GAME_ROTATION_VECTOR] =
01035         em7186_sensor_scale[SENSOR_TYPE_GAME_ROTATION_VECTOR_WAKE] =
01036         em7186_sensor_scale[SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR] =
01037         em7186_sensor_scale[SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR_WAKE] =
01038         em7186_sensor_scale[SENSOR_TYPE_PDR] =
01039         em7186_sensor_scale[SENSOR_TYPE_PDR_WAKE] =
01040         em7186_sensor_scale[60] =
01041         1.0f / powf(2.0f, 14.0f);  // Fixed
01042     
01043 
01044 
01045     // Can change during system operation (if desired)
01046     float accelDynamicRange = 4.0f; // g
01047     float magDynamicRange = 1000.0f; // uT 
01048     float gyroDynamicRange = 2000.0f; // d/s
01049 
01050     // Change depending on dynamic range
01051     em7186_sensor_scale[SENSOR_TYPE_ACCELEROMETER] =
01052         em7186_sensor_scale[SENSOR_TYPE_ACCELEROMETER_WAKE] =
01053         em7186_sensor_scale[SENSOR_TYPE_GRAVITY] =
01054         em7186_sensor_scale[SENSOR_TYPE_GRAVITY_WAKE] =
01055         em7186_sensor_scale[SENSOR_TYPE_LINEAR_ACCELERATION] =
01056         em7186_sensor_scale[SENSOR_TYPE_LINEAR_ACCELERATION_WAKE] =
01057         9.81f * accelDynamicRange / powf(2.0f, 15.0f);
01058 
01059     em7186_sensor_scale[SENSOR_TYPE_MAGNETIC_FIELD] =
01060         em7186_sensor_scale[SENSOR_TYPE_MAGNETIC_FIELD_WAKE] =
01061         em7186_sensor_scale[SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED] =
01062         em7186_sensor_scale[SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED_WAKE] =
01063         magDynamicRange / powf(2.0f, 15.0f);
01064 
01065     em7186_sensor_scale[SENSOR_TYPE_GYROSCOPE] =
01066         em7186_sensor_scale[SENSOR_TYPE_GYROSCOPE_WAKE] =
01067         em7186_sensor_scale[SENSOR_TYPE_GYROSCOPE_UNCALIBRATED] =
01068         em7186_sensor_scale[SENSOR_TYPE_GYROSCOPE_UNCALIBRATED_WAKE] =
01069         (3.1415927f / 180.0f) * gyroDynamicRange / powf(2.0f, 15.0f);
01070 
01071     // Could change depending on dynamic range of physical sensor
01072     em7186_sensor_scale[SENSOR_TYPE_PRESSURE] =
01073         em7186_sensor_scale[SENSOR_TYPE_PRESSURE_WAKE] =
01074         1.0f / 128.0f;              // Subject to change
01075 
01076     em7186_sensor_scale[SENSOR_TYPE_LIGHT] =
01077         em7186_sensor_scale[SENSOR_TYPE_LIGHT_WAKE] =
01078         10000.0f / powf(2.0f, 16.0f);    // Subject to change
01079 
01080     em7186_sensor_scale[SENSOR_TYPE_PROXIMITY] =
01081         em7186_sensor_scale[SENSOR_TYPE_PROXIMITY_WAKE] =
01082         100.0f / powf(2.0f, 16.0f); // Subject to change
01083 
01084     em7186_sensor_scale[SENSOR_TYPE_RELATIVE_HUMIDITY] =
01085         em7186_sensor_scale[SENSOR_TYPE_RELATIVE_HUMIDITY_WAKE] =
01086         100.0f / powf(2.0f, 16.0f);  // Subject to change
01087 
01088     em7186_sensor_scale[SENSOR_TYPE_TEMPERATURE] =
01089         em7186_sensor_scale[SENSOR_TYPE_TEMPERATURE_WAKE] =
01090         em7186_sensor_scale[SENSOR_TYPE_AMBIENT_TEMPERATURE] =
01091         em7186_sensor_scale[SENSOR_TYPE_AMBIENT_TEMPERATURE_WAKE] =
01092         150.0f / powf(2.0f, 15.0f); // Subject to change
01093 
01094     em7186_sensor_scale[SENSOR_TYPE_ACTIVITY] =
01095         em7186_sensor_scale[SENSOR_TYPE_ACTIVITY_WAKE] =
01096         1.0f;
01097 
01098     return 1;
01099 }
01100 
01101 /*
01102 // Warm start parameter transfer. The parameter list and flags are presently going
01103 //   through a major revision therefore, these functions are now on hold
01104 
01105 u32 em7186_warm_start_load(const char *filename)
01106 {
01107     FILE *fin;
01108     fin = fopen(filename, "rb");
01109     if (!fin) return 0;
01110     WarmStartParams warmStartParams;
01111     fread(&warmStartParams, 1, sizeof(warmStartParams), fin);
01112     fclose(fin);
01113 
01114     em7186_param_write((u8*)&warmStartParams, PARAM_PAGE_WARM_START, warmStartList, sizeof(warmStartList) / sizeof(warmStartList[0]));
01115 
01116     return 1;
01117 }
01118 u32 em7186_warm_start_save(const char *filename)
01119 {
01120     WarmStartParams warmStartParams;
01121     em7186_param_read((u8*)&warmStartParams, PARAM_PAGE_WARM_START, warmStartList, sizeof(warmStartList) / sizeof(warmStartList[0]));
01122 
01123     FILE *fout;
01124     fout = fopen(filename, "wb");
01125     if (!fout) return 0;
01126     fwrite(&warmStartParams, 1, sizeof(warmStartParams), fout);
01127     fclose(fout);
01128     if (displayText) printf("Warm start parmeters Saved to warmstart.dat\n\r");
01129     return 1;
01130 }*/
01131 
01132 
01133 
01134 //=========================================================================
01135 // Additional Control Functions
01136 //=========================================================================
01137 u32 em7186_ap_suspend(u8 suspend)
01138 {
01139     u32 status = 0;
01140 
01141     if (suspend) status = em7186_i2c_write_value(HOST_INTERFACE_CTRL_REG, HOST_INTERFACE_CTRL_AP_SUSPEND);
01142     else status = em7186_i2c_write_value(HOST_INTERFACE_CTRL_REG, 0);
01143 
01144     return status;
01145 }
01146 
01147 u32 em7186_flush_sensor(u8 sensorId)
01148 {
01149     return em7186_i2c_write_value(FIFO_FLUSH_REG, sensorId);
01150 }
01151 
01152 void disableSensors()
01153 {
01154    u8 i;
01155     for ( i = 0; i<64 ;i++)
01156     {
01157         if (sensorEnabled[i] == TRUE)
01158         {
01159             em7186_set_sensor_rate(sensorEnabled[i+1], 0);
01160             sensorEnabled[i] = FALSE;
01161         }
01162     }        
01163 }
01164 
01165 u32 em7186_set_fifo_watermarks(u16 minRemainingWakeFifo, u16 minRemainingNonWakeFifo)
01166 {
01167     // if min remaining values are non-zero the watermark will be set that many bytes from the end of the fifo.
01168     // if a zero value is used the watermark is disabled.
01169     u16 config[4];
01170     ParamInfo param[1] = { { PARAM_FIFO_CONTROL, 8 } };
01171     
01172     em7186_param_read((u8*)config, PARAM_PAGE_SYSTEM, param, 1);
01173     config[0] = minRemainingWakeFifo ? config[1] - minRemainingWakeFifo : 0;
01174     config[2] = minRemainingNonWakeFifo ? config[3] - minRemainingNonWakeFifo : 0;
01175     return em7186_param_write((u8*)config, PARAM_PAGE_SYSTEM, param, 1);
01176 }
01177 
01178 u32 em7186_enable_raw_sensors(u8 enableMag, u8 enableAccel, u8 enableGyro)
01179 {
01180     u8 value = 0x00;
01181     if (enableMag) value |= 0x04;
01182     if (enableAccel) value |= 0x01;
01183     if (enableGyro) value |= 0x02;
01184 
01185     ParamInfo param[1] = { { 127, 1 } };
01186     
01187     em7186_param_write(&value, PARAM_PAGE_WARM_START, param, 1);
01188 
01189     return 1;
01190 }
01191 
01192 void resetCpu()
01193 {
01194     disableSensors();
01195     em7186_i2c_write_value(0xB6, 63);
01196 }
01197 
01198 u32 paramListSize(ParamInfo *paramList, u8 numParams)
01199 {
01200     u8 i;
01201     u32 size = 0;
01202     for (i = 0; i < numParams; i++)
01203     {
01204         size += paramList[i].size;
01205     }
01206     return size;
01207 }
01208 
01209 void displaySavedParams(u8 *values, ParamInfo *paramList, u8 numParams)
01210 {
01211     u8 i;
01212     u16 valueIndex = 0;
01213     for (i = 0; i < numParams; i++)
01214     {
01215         float* floatVals = (float*)&values[valueIndex];
01216         u32* hexVals = (u32*)&values[valueIndex];
01217 
01218         if (paramList[i].size >= 4)
01219         {
01220             printf("%d 1: %f, %08x\n\r", paramList[i].paramNo, floatVals[0], hexVals[0]);
01221         }
01222         if (paramList[i].size >= 8)
01223         {
01224             printf("%d 2: %f, %08x\n\r", paramList[i].paramNo, floatVals[1], hexVals[1]);
01225         }
01226         if (paramList[i].size == 1)
01227         {
01228             u8* hexVals = (u8*)&values[valueIndex];
01229             printf("%d 1: %d\n\r", paramList[i].paramNo, hexVals[0]);
01230         }
01231         valueIndex += paramList[i].size;
01232     }
01233 }
01234 
01235 void displayParams(u8 paramPage, ParamInfo *paramList, u8 numParams)
01236 {
01237     u32 size = paramListSize(paramList, numParams);
01238     u8 *values = (u8 *)malloc(size);
01239     em7186_param_read(values, paramPage, paramList, numParams);
01240     displaySavedParams(values, paramList, numParams);
01241     free(values);
01242 }
01243 
01244 /*
01245 // Warm start parameter transfer. The parameter list and flags are presently going
01246 //   through a major revision therefore, these functions are now on hold
01247 
01248 void warmStart()
01249 {
01250     // Save warm start params
01251     em7186_warm_start_save(warmStartFile);
01252 
01253     if (displayText) printf("\n\r\n\r-------------------- CPU Reset -------------------------------------\n\r");
01254     // Reset the cpu
01255     resetCpu();
01256 
01257     if (displayText) printf("\n\r\n\r---------------- Parameters after reset ----------------------------\n\r");
01258     // Read the warmstart params after reset
01259     displayParams(2, warmStartList, sizeof(warmStartList) / sizeof(warmStartList[0]));
01260 
01261     if (displayText) printf("\n\r\n\r---------------- Parameters after upload----------------------------\n\r");
01262     // Load warmstart parameters
01263     em7186_warm_start_load(warmStartFile);
01264 
01265     // Read the warmstart params after warmstart
01266     displayParams(2, warmStartList, sizeof(warmStartList) / sizeof(warmStartList[0]));
01267 }*/
01268 
01269 char* strBits(void const * const ptr, u8 numBytes, char* str)
01270 {
01271     u8 *bytes = (u8*)ptr;
01272     u8 i, j;
01273     for (i = 0; i < numBytes; i++)
01274     {
01275         for (j = 0; j < 8; j++)
01276         {
01277             str[i * 8 + (7 - j)] = bytes[(numBytes - 1) - i] & (1 << j) ? '1' : '0';
01278         }
01279     }
01280     str[numBytes * 8] = '\0';
01281     return str;
01282 }
01283 
01284 void displayStatusRegisters()
01285 {
01286     u8 buf[4];
01287     char str[17];
01288     printf("\n------------ Displaying Status Registers -----------\n\r");
01289     em7186_i2c_read(HOST_STATUS_REG, buf, 3);
01290     printf("Host Status:       % 5u, %s\n\r", buf[0], strBits(&buf[0], sizeof(buf[0]), str));
01291     printf("Interrupt Status:  % 5u, %s\n\r", buf[1], strBits(&buf[1], sizeof(buf[0]), str));
01292     printf("Chip Status:       % 5u, %s\n\r", buf[2], strBits(&buf[2], sizeof(buf[0]), str));
01293     em7186_i2c_read(ERR_REG, buf, 4);
01294     printf("Error Register:    % 5u, %s\n\r", buf[0], strBits(&buf[0], sizeof(buf[0]), str));
01295     printf("Interrupt State:   % 5u, %s\n\r", buf[1], strBits(&buf[1], sizeof(buf[0]), str));
01296     printf("Debug Value:       % 5u, %s\n\r", buf[2], strBits(&buf[2], sizeof(buf[0]), str));
01297     printf("Debug State:       % 5u, %s\n\r", buf[3], strBits(&buf[3], sizeof(buf[0]), str));
01298     em7186_i2c_read(BYTES_REMANING_REG, buf, 2);
01299     u16* v = (u16*)&buf;
01300     printf("Bytes Remaining:   % 5u, %s\n\n\r", v[0], strBits(&v[0], sizeof(v[0]), str));
01301 }
01302 
01303 void displaySensorStatusBits(u8 id, const SensorStatus *status)
01304 {
01305     printf("|% 4u |      % 4u | % 4u |   % 4u |      % 4u | % 4u |  % 4u |\n\r", 
01306         id, status->dataAvailable, status->i2cNack, status->deviceIdError, 
01307         status->transientError, status->dataLost, status->powerMode);
01308 }
01309 
01310 void displaySensorStatus()
01311 {
01312     SensorStatus sensorStatus[32];
01313     ParamInfo param[] = { PARAM_SENSOR_STATUS_BANK_0, 32 };
01314     em7186_param_read((u8*)sensorStatus, PARAM_PAGE_SYSTEM, param, 1);
01315     printf("+------------------------------------------------------------+\n\r");
01316     printf("|                       SENSOR STATUS                        |\n\r");
01317     printf("+-----+-----------+------+--------+-----------+------+-------+\n\r");
01318     printf("| ID  | Data      | I2C  | DEVICE | Transient | Data | Power |\n\r");
01319     printf("|     | Available | NACK | ID ERR | Error     | Lost | Mode  |\n\r");
01320     printf("+-----+-----------+------+--------+-----------+------+-------+\n\r");
01321     u8 i;
01322     for (i = 0; i < 32; i++)
01323     {
01324         displaySensorStatusBits(i + 1, &sensorStatus[i]);
01325     }
01326     param[0].paramNo = PARAM_SENSOR_STATUS_BANK_0 + 4;
01327     em7186_param_read((u8*)sensorStatus, PARAM_PAGE_SYSTEM, param, 1);
01328     for (i = 0; i < 16; i++)
01329     {
01330         displaySensorStatusBits(i + 65, &sensorStatus[i]);
01331     }
01332     printf("+-----+-----------+------+--------+-----------+------+-------+\n\r");
01333 
01334 }
01335 
01336 void getPhysicalSensorStatus()
01337 {
01338     ParamInfo param[] = { PARAM_PHYSICAL_SENSOR_STATUS, 15 };
01339     em7186_param_read((u8*)&physicalSensorStatus, PARAM_PAGE_SYSTEM, param, 1);
01340 }
01341 
01342 void displayPhysicalSensorStatus()
01343 {
01344     getPhysicalSensorStatus();
01345     printf("+----------------------------------------------------------------------------------------+\n\r");
01346     printf("|                                  PHYSICAL SENSOR STATUS                                |\n\r");
01347     printf("+--------+--------+---------+-----+-----------+------+--------+-----------+------+-------+\n\r");
01348     printf("| Sensor | Sample | Dynamic | ID  | Data      | I2C  | DEVICE | Transient | Data | Power |\n\r");
01349     printf("|        | Rate   | Range   |     | Available | NACK | ID ERR | Error     | Lost | Mode  |\n\r");
01350     printf("+--------+--------+---------+-----+-----------+------+--------+-----------+------+-------+\n\r");
01351 
01352     printf("| Accel  |   % 4u |    % 4u ", physicalSensorStatus.accel.sampleRate, physicalSensorStatus.accel.dynamicRange);
01353     displaySensorStatusBits(1, &physicalSensorStatus.accel.status);
01354 
01355     printf("| Gyro   |   % 4u |    % 4u ", physicalSensorStatus.gyro.sampleRate, physicalSensorStatus.gyro.dynamicRange);
01356     displaySensorStatusBits(2, &physicalSensorStatus.gyro.status);
01357 
01358     printf("| Mag    |   % 4u |    % 4u ", physicalSensorStatus.mag.sampleRate, physicalSensorStatus.mag.dynamicRange);
01359     displaySensorStatusBits(3, &physicalSensorStatus.mag.status);
01360     printf("+--------+--------+---------+-----+-----------+------+--------+-----------+------+-------+\n\r");
01361 }
01362 void displayPhysicalSensorInformation()
01363 {
01364     typedef struct
01365     {
01366         u8 sensorType;
01367         u8 driverId;
01368         u8 driverVersion;
01369         u8 current;
01370         u16 currentDynamicRange;
01371         u8 flags;
01372         u8 reserved;
01373         u16 currentRate;
01374         u8 numAxes;
01375         u8 orientationMatrix[5];
01376     } PhysicalSensorInformation;
01377  
01378     PhysicalSensorInformation s;
01379 
01380     u64 physicalSensorPresent = 0;
01381     ParamInfo param = { 32, 4 };
01382     em7186_param_read((u8*)&physicalSensorPresent, PARAM_PAGE_SYSTEM, &param, 1);
01383     
01384     u32 i;
01385     param.size = 16;
01386 
01387     printf("\n+----------------------------------+--------+---------+-------+---------+------------+------+\n\r");
01388     printf("| Sensor                           | Driver | Driver  | Power | Current | Current    | Num  |\n\r");
01389     printf("|                                  | ID     | Version |       | Range   | Rate       | Axes |\n\r");
01390     printf("+----------------------------------+--------+---------+-------+---------+------------+------+\n\r");
01391     for (i = 0; i < 64; i++)
01392     {
01393         if (physicalSensorPresent & (1LL << i))
01394         {
01395             param.paramNo = i+32;
01396             em7186_param_read((u8*)&s, PARAM_PAGE_SYSTEM, &param, 1);
01397             printf("| %-32s |   % 4u |    % 4u |  % 4u |    % 4u |       % 4u | % 4u |\n\r",
01398                 em7186_sensor_name[s.sensorType], s.driverId, s.driverVersion, s.current, s.currentDynamicRange, s.currentRate, s.numAxes);
01399         }
01400     }
01401     printf("+----------------------------------+--------+---------+-------+---------+------------+------+\n\r");
01402 }
01403 
01404 void getSensorInformation()
01405 {
01406     em7186_param_read((u8*)sensorInformation, PARAM_PAGE_SENSOR_INFO, sensorInfoParamList, sizeof(sensorInfoParamList) / sizeof(sensorInfoParamList[0]));
01407     haveSensorInfo = 1;
01408 
01409     magMaxRate = sensorInformation[SENSOR_TYPE_MAGNETIC_FIELD].maxRate;
01410     accelMaxRate = sensorInformation[SENSOR_TYPE_ACCELEROMETER].maxRate;
01411     gyroMaxRate = sensorInformation[SENSOR_TYPE_GYROSCOPE].maxRate;
01412 }
01413 
01414 void getSensorConfiguration()
01415 {
01416     u8 i;
01417     ParamInfo param[1] = { 0, 8 };
01418     for (i = 1; i<sizeof(sensorInformation) / sizeof(sensorInformation[0]); i++)
01419     { 
01420         if (sensorInformation[i].sensorId > 0)
01421         {
01422             param[0].paramNo = sensorInformation[i].sensorId;
01423             em7186_param_read((u8*)&sensorConfiguration[i], PARAM_PAGE_SENSOR_CONF, param, 1);
01424         }
01425     }
01426 }
01427 
01428 void displaySensorConfiguration()
01429 {
01430     if (!haveSensorInfo) { getSensorInformation(); };
01431     getSensorConfiguration();
01432     printf("+-------------------------------------------------------------------------+\n\r");
01433     printf("|                          Sensor Configuration                           |\n\r");
01434     printf("+----------------------------------+-------+-------+-------------+--------+\n\r");
01435     printf("| Sensor                           | Rate  | Delay | Sensitivity | Range  |\n\r");
01436     printf("+----------------------------------+-------+-------+-------------+--------+\n\r");
01437     u8 i;
01438     for (i = 0; i < sizeof(sensorInformation) / sizeof(sensorInformation[0]); i++)
01439     {
01440         if (sensorInformation[i].sensorId > 0)
01441         {
01442             printf("| %-32s | % 5u | % 5u | % 11u | % 6u |\n\r",
01443                 em7186_sensor_name[sensorInformation[i].sensorId],
01444                 sensorConfiguration[i].sampleRate,
01445                 sensorConfiguration[i].maxReportLatency, 
01446                 sensorConfiguration[i].changeSensitivity, 
01447                 sensorConfiguration[i].dynamicRange);
01448         }
01449     }
01450     printf("+----------------------------------+-------+-------+-------------+--------+\n\r");
01451 }
01452 
01453 void displaySensorInformation()
01454 {
01455     if (!haveSensorInfo) { getSensorInformation(); };
01456     printf("+------------------------------------------------------------------------------------------+\n\r");
01457     printf("|                                  Sensor Information                                      |\n\r");
01458     printf("+----------------------------------------+---------+-------+-------+-----+----------+------+\n\r");
01459     printf("| ID  |Sensor                            | Driver  | Power | Range | Res | Rate     | Size |\n\r");
01460     printf("+-----|----------------------------------+---------+-------+-------+-----+----------+------+\n\r");
01461     u8 i;
01462     for (i = 0; i < sizeof(sensorInfoParamList) / sizeof(sensorInfoParamList[0]); i++)
01463     {
01464         if (sensorInformation[i].sensorId > 0)
01465         {
01466             printf("|%3u  | %-32s | % 3u.%-3u |  % 4u | % 5u | % 3u | %-3u-% 4u |  % 3u |\n\r",
01467                 i,
01468                 em7186_sensor_name[sensorInformation[i].sensorId], sensorInformation[i].driverId, 
01469                 sensorInformation[i].driverVersion, sensorInformation[i].power,
01470                 sensorInformation[i].maxRange, sensorInformation[i].resolution, 
01471                 sensorInformation[i].minRate, sensorInformation[i].maxRate,
01472                 sensorInformation[i].eventSize);
01473         }
01474     }
01475     printf("+-----|----------------------------------+---------+-------+-------+-----+----------+------+\n\r");
01476 }
01477 
01478 
01479 void read_BuildVersion(void) {
01480 
01481     ParamInfo param; // elements:   {u8 paramNo; u8 size;}
01482 
01483     printf("\n\r\n\rSENtral Firmware build version information from PramIO Page 9\n\r");
01484 
01485     struct pni_version {
01486         u8 major;
01487         u8 minor;
01488         u8 patch;
01489         u8 other;
01490         u32 build;
01491     };
01492 
01493     struct pni_version pni_ver;
01494 
01495 
01496     param.paramNo = 1;
01497     param.size = 8;
01498     em7186_param_read((u8 *)&pni_ver, 9, &param, 1);
01499 
01500     printf("  major = %u\n\r", pni_ver.major);
01501     printf("  minor = %u\n\r", pni_ver.minor);
01502     printf("  patch = %u\n\r", pni_ver.patch);
01503     printf("  other = %u\n\r", pni_ver.other);
01504     printf("  build = %u\n\r", pni_ver.build);
01505 
01506 
01507 }