Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
RM3100.cpp
00001 /** 00002 * @file RM3100.cpp 00003 * 00004 * @brief Sample interface for RM3100. 00005 * 00006 * @authors Betty Zhang 00007 * @date 05/21/2018 00008 * @copyright (C) 2018 PNI Corp, Protonex LLC 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 "RM3100.h" 00015 #include "main.h" 00016 00017 void RM3100::ClearDrdyInt() 00018 { 00019 //Clear Interrupt first 00020 cs = 0; 00021 spi.write(RM3100_STATUS_REG); 00022 int status = spi.write(0x00); 00023 cs = 1; 00024 if (status & 0x80) 00025 { 00026 ReadRM3100(); 00027 status = 0; 00028 } 00029 } 00030 00031 void RM3100::RunCMM(int flag) 00032 { 00033 //Set current sample rate if it changes 00034 if (sample_rate != prev_rate) 00035 { 00036 SetSampleRateReg(sample_rate); 00037 prev_rate = sample_rate; 00038 } 00039 00040 if (flag) { 00041 //Set Cycle Count if it changes 00042 SetCycleCountReg(); 00043 00044 //Confirm new setting and update "gain" 00045 DisplayCycleCount(); 00046 } 00047 00048 RegCMM cmm_reg; 00049 cmm_reg.bits.LDM = 0; 00050 cmm_reg.bits.CMX = 1; 00051 cmm_reg.bits.CMY = 1; 00052 cmm_reg.bits.CMZ = 1; 00053 cmm_reg.bits.Drdm = 2; //0 on any axis, 2 Drdy after completion of XYZ 00054 cmm_reg.bits.Alarm = 0; 00055 00056 if (flag) { 00057 //Start CMM run 00058 cmm_reg.bits.Start = 1; 00059 cmm_reg.bits.CMX = 1; 00060 cmm_reg.bits.CMY = 1; 00061 cmm_reg.bits.CMZ = 1; 00062 } else { 00063 //Stop CMM run 00064 cmm_reg.bits.Start = 0; 00065 cmm_reg.bits.CMX = 0; 00066 cmm_reg.bits.CMY = 0; 00067 cmm_reg.bits.CMZ = 0; 00068 } 00069 00070 cs = 0; 00071 spi.write(RM3100_CMM_REG); 00072 spi.write(cmm_reg.reg); 00073 cs = 1; 00074 } 00075 00076 void RM3100::ChangeSampleRate(int flag) 00077 { 00078 if (flag > 0) 00079 sample_rate *= 2; //increase 2 times 00080 if (flag < 0) 00081 sample_rate /= 2; //decrease 2 times 00082 00083 if (sample_rate < 1) 00084 sample_rate = 1; //1hz 00085 else if (sample_rate > 600) 00086 sample_rate = 600; 00087 } 00088 00089 void RM3100::SetSampleRateReg(int rate) 00090 { 00091 int value; 00092 00093 sample_rate = rate; 00094 00095 if ((rate <= 600) && (rate >= 300)) 00096 value = 0x92; 00097 else if ((rate < 300) && (rate >= 150)) 00098 value = 0x93; 00099 else if ((rate < 150) && (rate >= 75)) 00100 value = 0x94; 00101 else if ((rate < 75) && (rate >= 37)) 00102 value = 0x95; 00103 else if ((rate < 37) && (rate >= 18)) 00104 value = 0x96; 00105 else if ((rate < 18) && (rate >= 9)) 00106 value = 0x97; 00107 else if ((rate < 9) && (rate >= 4)) 00108 value = 0x98; 00109 else if ((rate < 4) && (rate >= 3)) 00110 value = 0x99; 00111 else if ((rate < 3) && (rate >= 2)) 00112 value = 0x9A; 00113 else if ((rate < 2) && (rate >= 1)) 00114 value = 0x9B; //About 1Hz 00115 else 00116 value = 0x9C; //About 0.6Hz 00117 00118 cs = 0; 00119 //set sample rate 00120 spi.write(RM3100_TMRC_REG); 00121 spi.write(value); //about 1Hz 00122 cs = 1; 00123 } 00124 00125 int RM3100::GetSampleRate(int *tmrc_reg_val) 00126 { 00127 cs = 0; 00128 //set sample rate 00129 spi.write(RM3100_TMRC_REG | 0x80); //Read TMRC reg 00130 * tmrc_reg_val = spi.write(0); 00131 cs = 1; 00132 00133 return sample_rate; 00134 } 00135 00136 void RM3100::ReadRM3100() 00137 { 00138 int mag[9]; 00139 int count[3]; 00140 00141 __disable_irq(); // Disable Interrupts 00142 cs = 0; 00143 spi.write(RM3100_MX_REG); 00144 00145 comport.printf("Mag = 0x"); 00146 for (int i = 0; i < 9; i++) { 00147 mag[i] = spi.write(0x00); 00148 comport.printf("%x", mag[i]); 00149 if ((i < 8) && ((i+1) % 3) == 0) 00150 comport.printf(" 0x"); 00151 } 00152 cs = 1; 00153 00154 comport.printf(", "); 00155 //Process the 24-bit signed measurement in count 00156 int measurement = 0; 00157 int index = 0; 00158 for (int j = 0; j < 9; j += 3) { 00159 if (mag[j] & 0x80) 00160 measurement = 0xFF; 00161 measurement <<= 24; //left shift 24-bit 00162 measurement |= (mag[j+2] | (mag[j+1] | (mag[j] << 8)) << 8); 00163 comport.printf("%d ", measurement); 00164 count[index] = measurement; 00165 measurement = 0; 00166 index++; 00167 } 00168 00169 comport.printf(", "); 00170 //Convert to uT (microTesla) 00171 for (int k = 0; k < 3; k++) { 00172 comport.printf("%5.3fuT ", (float)count[k]/current_gain[k]); 00173 } 00174 00175 comport.printf("\n\r"); 00176 00177 __enable_irq(); // Enable Interrupts 00178 00179 } 00180 00181 void RM3100::SetDrdyIntFlag(u8 flag) 00182 { 00183 rm3100_service_flag = flag; 00184 if (flag) 00185 drdy.disable_irq(); 00186 else 00187 drdy.enable_irq(); 00188 } 00189 00190 u8 RM3100::GetDrdyIntFlag(void) 00191 { 00192 return rm3100_service_flag; 00193 } 00194 00195 void RM3100::ProcessDrdyInt() 00196 { 00197 SetDrdyIntFlag(1); 00198 } 00199 00200 void RM3100::DrdyCallBack(void) 00201 { 00202 // attach ProcessDrdyInt function of this RM3100 instance 00203 drdy.rise(callback(this, &RM3100::ProcessDrdyInt)); 00204 } 00205 00206 void RM3100::DisplayCycleCount() 00207 { 00208 int cc[6]; 00209 int c_count[3]; 00210 float maxrate; 00211 00212 //Read CC reg 00213 __disable_irq(); // Disable Interrupts 00214 cs = 0; 00215 int cc_reg = RM3100_CCXLSB_REG | 0x80; //"| 0x80" to read CC Reg 00216 spi.write(cc_reg); 00217 00218 comport.printf("CC = 0x"); 00219 for (int i = 0; i < 6; i++) { 00220 cc[i] = spi.write(0); 00221 comport.printf("%x", cc[i]); 00222 if ((i < 5) && ((i+1) % 2) == 0) 00223 comport.printf(" 0x"); 00224 } 00225 cs = 1; 00226 00227 comport.printf(", "); 00228 //Process the 16-bit unsigned cycle count 00229 int temp = 0; 00230 int index = 0; 00231 for (int j = 0; j < 6; j += 2) { 00232 if (cc[j] & 0x80) 00233 temp = 0xFF; 00234 temp <<= 8; //left shift 8-bit 00235 temp |= (cc[j+1] | (cc[j] << 8)); 00236 c_count[index++] = temp; //save CC values 00237 comport.printf("%d ", temp); 00238 temp = 0; 00239 } 00240 00241 //Calculate gain from CC, gain = 0.375 * cc; 00242 comport.printf(", Gain = "); 00243 for (int k = 0; k < 3; k++) { 00244 if (c_count[k]) 00245 current_gain[k] = c_count[k] * DEFAULTGAIN/DEFAULTCCOUNT; 00246 comport.printf("%d ", current_gain[k]); 00247 } 00248 00249 //Calculate max sample rate, assume CC same for 3 axes 00250 if (c_count[0] == 50) 00251 maxrate = 1600.0 / 3.0; 00252 else if (c_count[0] == 100) 00253 maxrate = 850.0 / 3.0; 00254 else if (c_count[0] == 200) 00255 maxrate = 440.0 / 3.0; 00256 else if (c_count[0] == 225) 00257 maxrate = 370.0 / 3.0; 00258 else if (c_count[0] == 250) 00259 maxrate = 350.0 / 3.0; 00260 else if (c_count[0] < 100) 00261 maxrate = (-15.0 * c_count[0] + 2350.0) / 3.0; 00262 else if (c_count[0] < 225) 00263 maxrate = (-14.0 * c_count[0]/5.0 + 1000.0) / 3.0; 00264 else if (c_count[0] < 250) 00265 maxrate = (-4.0 * c_count[0]/5.0 + 550.0) / 3.0; 00266 else if (c_count[0] <= 400) 00267 maxrate = (-4.0 * c_count[0] /5.0 + 550.0) / 3.0; 00268 00269 comport.printf("MaxRate = %3.2f Hz\n\r", maxrate); 00270 00271 __enable_irq(); // Enable Interrupts 00272 } 00273 00274 void RM3100::DisplayREVIDReg() 00275 { 00276 //Read REVID reg 00277 __disable_irq(); // Disable Interrupts 00278 cs = 0; 00279 int reg = RM3100_REVID_REG; 00280 spi.write(reg); 00281 int revid = spi.write(0); 00282 __enable_irq(); // Enable Interrupts 00283 cs = 1; 00284 00285 comport.printf("RM3100 REVID = %2D\n\r", revid); 00286 } 00287 00288 void RM3100::SelfTest() 00289 { 00290 comport.printf("SelfTest \n\r"); 00291 00292 RegBIST regbist; 00293 RegPOLL regpoll; 00294 00295 //Set BIST 00296 //bit#7 STE=1, bit#6#5#4 = 0, bit#3 BW1=1, bit#2 BW0=1, bit#1 BP1=1, bit#0 BP0=1 00297 regbist.bits.BP = 3; 00298 regbist.bits.BW = 3; 00299 regbist.bits.XYZOK = 0; 00300 regbist.bits.STE = 1; 00301 00302 //Set POLL reg 00303 regpoll.bits.LowNibble = 0; 00304 regpoll.bits.PMX = 1; 00305 regpoll.bits.PMY = 1; 00306 regpoll.bits.PMZ = 1; 00307 regpoll.bits.MSB = 0; 00308 00309 //Start Self Test 00310 __disable_irq(); // Disable Interrupts 00311 cs = 0; 00312 00313 //stop continuous mode 00314 spi.write(RM3100_CMM_REG); 00315 spi.write(0); 00316 cs = 1; 00317 00318 cs = 0; 00319 spi.write(RM3100_BIST_REG); 00320 spi.write(regbist.reg); 00321 comport.printf("bist val= 0x%X, poll val = 0x%X \n\r", regbist.reg, regpoll.reg); 00322 00323 cs = 1; 00324 00325 cs = 0; 00326 //POLL 1 measurement on XYZ 00327 spi.write(RM3100_POLL_REG); 00328 spi.write(regpoll.reg); 00329 cs = 1; 00330 00331 //Get result 00332 cs = 0; 00333 spi.write(RM3100_STATUS_REG | 0x80); 00334 int value = spi.write(0); 00335 comport.printf("Poll a measurement and Check status reg val = 0x%X \n\r", value); 00336 00337 cs = 1; 00338 00339 if (value) { 00340 //Read RM3100_BIST_REG; 00341 cs = 0; 00342 spi.write(RM3100_BIST_REG | 0x80); 00343 value = spi.write(0); 00344 cs = 1; 00345 00346 //Check result here 00347 comport.printf("Check BIST reg 0x%X\n\r", value); 00348 if (value & 0x70) 00349 comport.printf("Result = 0x%X Pass\n\r", value); 00350 else 00351 comport.printf("Result = 0x%X Fail\n\r", value); 00352 00353 } else 00354 comport.printf("Measurement not Ready\n\r"); 00355 00356 //It's important to Reset SeltTest reg 00357 cs = 0; 00358 spi.write(RM3100_BIST_REG); 00359 spi.write(0); 00360 cs = 1; 00361 00362 __enable_irq(); // Enable Interrupts 00363 00364 } 00365 00366 void RM3100::ChangeCycleCount(int flag) 00367 { 00368 for (int i = 0; i < 3; i++) 00369 { 00370 if (flag > 0) 00371 { 00372 current_ccount[i] += 10; 00373 } 00374 else if (flag < 0) 00375 { 00376 current_ccount[i] -= 10; 00377 } 00378 00379 if (current_ccount[i] < LOWERCYCLECOUNT) 00380 current_ccount[i] = LOWERCYCLECOUNT; 00381 00382 if (current_ccount[i] > UPPERCYCLECOUNT) 00383 current_ccount[i] = UPPERCYCLECOUNT; 00384 00385 } 00386 } 00387 00388 00389 //Set Cycle Count Reg 00390 void RM3100::SetCycleCountReg() 00391 { 00392 static int prev_ccount = DEFAULTCCOUNT; 00393 00394 //Check any changes on CC. Should check 3 axes, just X-axis as example 00395 if (prev_ccount != current_ccount[0]) { 00396 00397 prev_ccount = current_ccount[0]; 00398 00399 //Read CC reg 00400 __disable_irq(); // Disable Interrupts 00401 cs = 0; 00402 int cc_reg = RM3100_CCXLSB_REG; 00403 spi.write(cc_reg); 00404 00405 for (int i = 0; i < 3; i++) { 00406 spi.write((current_ccount[i] & 0xFF00)>>8); //MSB 00407 spi.write(current_ccount[i] & 0x00FF); //LSB 00408 } 00409 cs = 1; 00410 00411 __enable_irq(); // Enable Interrupts 00412 } 00413 } 00414 00415 00416 //constructor 00417 RM3100::RM3100(): rm3100_service_flag(0), //init to 0 00418 sample_rate(1), //init to 1 Hz 00419 prev_rate(1), //init to 1 Hz 00420 cs(SPI_CS), //init to SPI_CS 00421 drdy(D9), //init to D9 00422 spi(SPI_MOSI, SPI_MISO, SPI_SCK) //spi pins init 00423 { 00424 //Init to default 00425 for (int i = 0; i < 3; i++) 00426 { 00427 current_ccount[i] = DEFAULTCCOUNT; 00428 current_gain[i] = DEFAULTGAIN; 00429 } 00430 00431 };
Generated on Thu Jul 14 2022 03:31:09 by
1.7.2