HMC58X3 Library
Fork of HMC58X3 by
Revision 4:8eb12adc8368, committed 2013-11-09
- Comitter:
- tyftyftyf
- Date:
- Sat Nov 09 08:51:00 2013 +0000
- Parent:
- 3:1e0e0c47287a
- Child:
- 5:ea869bfe993b
- Commit message:
- Implemented async mode
Changed in this revision
HMC58X3.cpp | Show annotated file Show diff for this revision Revisions of this file |
HMC58X3.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/HMC58X3.cpp Tue Nov 05 11:30:31 2013 +0000 +++ b/HMC58X3.cpp Sat Nov 09 08:51:00 2013 +0000 @@ -31,14 +31,13 @@ //#define DEBUG (1) #include "mbed.h" +#include "MODI2C.h" #include "HMC58X3.h" +#include "rtos.h" #include <new> //#include <DebugUtils.h> #define DEBUG_PRINT - - - /*! Counts/milli-gauss per gain for the self test bias current. */ @@ -61,29 +60,35 @@ //HMC58X3::HMC58X3(PinName sda, PinName scl): i2c(sda, scl) -HMC58X3::HMC58X3(I2C i2c_):i2c(i2c_) +HMC58X3::HMC58X3():i2c(I2C_SDA,I2C_SCL),_thread(&HMC58X3::samplingthread_stub, this, osPriorityAboveNormal),sem(0) { //this->i2c= i2c_; x_scale=1.0F; y_scale=1.0F; z_scale=1.0F; + HMC58X3_R_IDA = 10; } +void HMC58X3::samplingthread_stub(void const *p) { + HMC58X3 *instance = (HMC58X3*)p; + instance->samplingthread(); +} void HMC58X3::init(bool setmode) { // note that we don't initialize Wire here. // You'll have to do that in setup() in your Arduino program - wait_ms(10); // you need to wait at least 5ms after power on to initialize + Thread::wait(10); // you need to wait at least 5ms after power on to initialize + if (setmode) { setMode(0); } - - - writeReg(HMC58X3_R_CONFA, 0x70); // 8 samples averaged, 75Hz frequency, no artificial bias. + writeReg(HMC58X3_R_CONFA, 0x18); // 4 samples averaged, 75Hz frequency, no artificial bias. + writeReg(HMC58X3_R_CONFB, 0xA0); + writeReg(HMC58X3_R_MODE, 0x00); } @@ -95,7 +100,7 @@ } writeReg(HMC58X3_R_MODE, mode); - wait_ms(100); + Thread::wait(100); } /* @@ -273,14 +278,21 @@ writeReg(HMC58X3_R_CONFB, gain << 5); } +MemoryPool<short, 16> mpool; + +uint32_t writeregfin(uint32_t in) +{ + short *tmp = (short *)in; + mpool.free(tmp); + return 0; +} void HMC58X3::writeReg(unsigned char reg, unsigned char val) { - i2c.start(); - i2c.write(HMC58X3_ADDR<<1); - i2c.write(reg); // send register address - i2c.write(val); // send value to write - i2c.stop(); //end transmission + unsigned char *tmp = (unsigned char *)mpool.alloc(); + tmp[0]=reg; + tmp[1]=val; + i2c.write(I2C_ADDRESS, (char*)tmp, 2, &writeregfin, (void*)tmp); } @@ -304,29 +316,68 @@ *z = ((float) zr) / z_scale; } +uint32_t magn_readfin(uint32_t param){ + HMC58X3* ins = (HMC58X3*)param; + ins->sem.release(); + return 0; +} + +void HMC58X3::start_sampling(){ + _thread.signal_set(0x1); +} + +bool magn_valid = false; + +void HMC58X3::samplingthread() +{ + char tmp[2]; + tmp[0]=HMC58X3_R_MODE; + tmp[1]=1; + char magn_data[6]; + Timer magntimer; + + char cmd[2]; + cmd[0] = 0x03; + + Thread::signal_wait(0x1); + magntimer.start(); + + for (;;) { + i2c.write(0x3D, (char*)tmp, 2); + + i2c.write(0x3D, cmd, 1, true); // set the pointer to the start of x + + magntimer.reset(); + + i2c.read_nb(0x3D, (char*)magn_data, 6, &magn_readfin, this, false); + + sem.wait(); + + // read out the 3 values, 2 bytes each. + cache_x = int16_t(((unsigned char)magn_data[0] << 8) | (unsigned char)magn_data[1]); +#ifdef ISHMC5843 + cache_y = int16_t(((unsigned char)magn_data[1*2] << 8) | (unsigned char)magn_data[1*2+1]); + cache_z = int16_t(((unsigned char)magn_data[2*2] << 8) | (unsigned char)magn_data[2*2+1]); +#else // the Z registers comes before the Y registers in the HMC5883L + cache_z = int16_t(((unsigned char)magn_data[1*2] << 8) | (unsigned char)magn_data[1*2+1]); + cache_y = int16_t(((unsigned char)magn_data[2*2] << 8) | (unsigned char)magn_data[2*2+1]); +#endif + // the HMC58X3 will automatically wrap around on the next request. + + magn_valid = true; + + int time = ((6800-magntimer.read_us())/1000); + if (time >= 0) + Thread::wait(time); + } + +} void HMC58X3::getRaw(int16_t *x,int16_t *y,int16_t *z) { - - char cmd[2]; - char data[6]; - cmd[0] = 0x03; - - i2c.write(HMC58X3_ADDR<<1, cmd, 1, true); // set the pointer to the start of x - i2c.read((HMC58X3_ADDR<<1)+1, data, 6, false); - - // read out the 3 values, 2 bytes each. - *x = int16_t(((unsigned char)data[0] << 8) | (unsigned char)data[1]); -#ifdef ISHMC5843 - *y = int16_t(((unsigned char)data[1*2] << 8) | (unsigned char)data[1*2+1]); - *z = int16_t(((unsigned char)data[2*2] << 8) | (unsigned char)data[2*2+1]); -#else // the Z registers comes before the Y registers in the HMC5883L - *z = int16_t(((unsigned char)data[1*2] << 8) | (unsigned char)data[1*2+1]); - *y = int16_t(((unsigned char)data[2*2] << 8) | (unsigned char)data[2*2+1]); -#endif - // the HMC58X3 will automatically wrap around on the next request - - + *x = cache_x; + *y = cache_y; + *z = cache_z; } @@ -344,17 +395,9 @@ */ void HMC58X3::getID(char id[3]) { - i2c.start(); - i2c.write(HMC58X3_ADDR<<1); - i2c.write(HMC58X3_R_IDA); // Will start reading registers starting from Identification Register A. + i2c.write(I2C_ADDRESS, (char*)&HMC58X3_R_IDA, 1, true); + i2c.read(I2C_ADDRESS, id, 3); - i2c.start(); - i2c.write((HMC58X3_ADDR<<1)+1); - id[0] = i2c.read(0); - id[1] = i2c.read(0); - id[2] = i2c.read(0); - - i2c.stop(); } // getID(). int HMC58X3::min (int a, int b)
--- a/HMC58X3.h Tue Nov 05 11:30:31 2013 +0000 +++ b/HMC58X3.h Sat Nov 09 08:51:00 2013 +0000 @@ -34,6 +34,11 @@ #ifndef HMC58X3_h #define HMC58X3_h +#ifndef I2C_SDA + #define I2C_SDA p28 + #define I2C_SCL p27 +#endif + #define HMC58X3_ADDR 0x1E // 7 bit address of the HMC58X3 used with the Wire library #define HMC_POS_BIAS 1 #define HMC_NEG_BIAS 2 @@ -75,7 +80,7 @@ #endif #define HMC58X3_R_STATUS 9 -#define HMC58X3_R_IDA 10 +//#define HMC58X3_R_IDA 10 #define HMC58X3_R_IDB 11 #define HMC58X3_R_IDC 12 @@ -84,7 +89,7 @@ public: - HMC58X3(I2C i2c_); + HMC58X3(); void init(bool setmode); void init(int address, bool setmode); void getValues(int16_t *x,int16_t *y,int16_t *z); @@ -98,11 +103,23 @@ void setDOR(unsigned char DOR); void setGain(unsigned char gain); void getID(char id[3]); + + int16_t cache_x, cache_y, cache_z; + + static void samplingthread_stub(void const *p); + + void samplingthread(); + void start_sampling(); static const int I2C_ADDRESS = 0x3D; + char HMC58X3_R_IDA; + MODI2C i2c; + + Thread _thread; + + Semaphore sem; private: - I2C i2c; void writeReg(unsigned char reg, unsigned char val); float x_scale,y_scale,z_scale,x_max,y_max,z_max; int min(int a, int b);