BEI ZHANG / Mbed 2 deprecated RM3100_SPI_SampleCode

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RM3100.cpp Source File

RM3100.cpp

Go to the documentation of this file.
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 };