drv_fxos8700.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include <rtthread.h>
  2. #include <rtdevice.h>
  3. #define FXOS8700_DEV_NAME ("fxos8700")
  4. #define FXOS8700_I2C_DEV_NAME ("i2c2")
  5. #define FXOS8700_CHIP_ADDR (0x1E)
  6. #define DBG_TAG "drv.fxos8700"
  7. #define DBG_LVL DBG_LOG
  8. #include <rtdbg.h>
  9. #define CTRL_REG1 0x2A
  10. #define XYZ_DATA_CFG_REG 0x0E
  11. #define M_CTRL_REG1 0x5B
  12. #define F_SETUP_REG 0x09
  13. #define M_CTRL_REG2 0x5C
  14. #define OUT_X_MSB_REG 0x01
  15. #define OUT_X_LSB_REG 0x02
  16. #define OUT_Y_MSB_REG 0x03
  17. #define OUT_Y_LSB_REG 0x04
  18. #define OUT_Z_MSB_REG 0x05
  19. #define OUT_Z_LSB_REG 0x06
  20. #define F_MODE_DISABLED 0x00
  21. #define ASLP_RATE1_MASK 0x80
  22. #define ASLP_RATE0_MASK 0x40
  23. #define DR2_MASK 0x20
  24. #define DR1_MASK 0x10
  25. #define DR0_MASK 0x08
  26. #define LNOISE_MASK 0x04
  27. #define FREAD_MASK 0x02
  28. #define ACTIVE_MASK 0x01
  29. #define ASLP_RATE_MASK 0xC0
  30. #define DR_MASK 0x38
  31. #define M_HYB_AUTOINC_MASK 0x20
  32. #define M_MAXMIN_DIS_MASK 0x10
  33. #define M_MAXMIN_DIS_THS_MASK 0x08
  34. #define M_MAXMIN_RST_MASK 0x04
  35. #define M_RST_CNT1_MASK 0x02
  36. #define M_RST_CNT0_MASK 0x01
  37. #define M_ACAL_MASK 0x80
  38. #define M_RST_MASK 0x40
  39. #define M_OST_MASK 0x20
  40. #define M_OSR2_MASK 0x10
  41. #define M_OSR1_MASK 0x08
  42. #define M_OSR0_MASK 0x04
  43. #define M_HMS1_MASK 0x02
  44. #define M_HMS0_MASK 0x01
  45. #define M_OSR_MASK 0x1C
  46. #define M_HMS_MASK 0x03
  47. typedef struct
  48. {
  49. struct rt_device parent;
  50. struct rt_i2c_bus_device *bus;
  51. uint8_t i2c_addr;
  52. }fxos8700_t;
  53. static uint8_t fxos_read_reg(fxos8700_t *dev, uint8_t reg_addr)
  54. {
  55. uint8_t val;
  56. rt_i2c_master_send(dev->bus, dev->i2c_addr, RT_I2C_WR, &reg_addr, 1);
  57. rt_i2c_master_recv(dev->bus, dev->i2c_addr, RT_I2C_RD, &val, 1);
  58. return val;
  59. }
  60. static void fxos_write_reg(fxos8700_t *dev, uint8_t reg_addr, uint8_t val)
  61. {
  62. uint8_t buf[2];
  63. buf[0] = reg_addr;
  64. buf[1] = val;
  65. rt_i2c_master_send(dev->bus, dev->i2c_addr, RT_I2C_WR, buf, 2);
  66. }
  67. static rt_err_t fxos8700_open(rt_device_t dev, rt_uint16_t oflag)
  68. {
  69. int i;
  70. uint8_t val;
  71. fxos8700_t *fxos8700 = (fxos8700_t *)dev;
  72. for(i=0; i<5; i++)
  73. {
  74. val = fxos_read_reg(fxos8700, 0x0D);
  75. if(val == 0xC7)
  76. {
  77. LOG_D("fxos8700 found, id:0x%X", val);
  78. /* reset */
  79. // fxos_write_reg(instance, gChipAddr, CTRL_REG2, RST_MASK);
  80. /* wait for a bit */
  81. for (i = 0; i < 0xFFFF; i++)
  82. {
  83. __asm("NOP");
  84. }
  85. /* setup auto sleep with FFMT trigger */
  86. /* go to standby */
  87. val = fxos_read_reg(fxos8700, CTRL_REG1);
  88. fxos_write_reg(fxos8700, CTRL_REG1, val & (uint8_t)~ACTIVE_MASK);
  89. /* Disable the FIFO */
  90. fxos_write_reg(fxos8700, F_SETUP_REG, F_MODE_DISABLED);
  91. /* set up Mag OSR and Hybrid mode using M_CTRL_REG1, use default for Acc */
  92. fxos_write_reg(fxos8700, M_CTRL_REG1, (M_RST_MASK | M_OSR_MASK | M_HMS_MASK));
  93. /* Enable hyrid mode auto increment using M_CTRL_REG2 */
  94. fxos_write_reg(fxos8700, M_CTRL_REG2, (M_HYB_AUTOINC_MASK));
  95. fxos_write_reg(fxos8700, XYZ_DATA_CFG_REG, 0x02);
  96. val = fxos_read_reg(fxos8700, CTRL_REG1);
  97. fxos_write_reg(fxos8700, CTRL_REG1, val | LNOISE_MASK);
  98. fxos_write_reg(fxos8700, CTRL_REG1, val | ACTIVE_MASK | LNOISE_MASK);
  99. return RT_EOK;
  100. }
  101. else
  102. {
  103. LOG_D("fxos8700 cannot found, id:0x%X", val);
  104. }
  105. }
  106. return RT_ERROR;
  107. }
  108. static rt_ssize_t fxos8700_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  109. {
  110. fxos8700_t *fxos8700 = (fxos8700_t *)dev;
  111. uint8_t buf[12];
  112. buf[0] = OUT_X_MSB_REG;
  113. rt_i2c_master_send(fxos8700->bus, fxos8700->i2c_addr, RT_I2C_WR, buf, 1);
  114. rt_i2c_master_recv(fxos8700->bus, fxos8700->i2c_addr, RT_I2C_RD, buf, 12);
  115. int16_t iacc[3];
  116. iacc[0] = (int16_t)((((int16_t)buf[0] << 8) | buf[1]));
  117. iacc[1] = (int16_t)((((int16_t)buf[2] << 8) | buf[3]));
  118. iacc[2] = (int16_t)((((int16_t)buf[4] << 8) | buf[5]));
  119. float *out_buf = buffer;
  120. out_buf[0] = (float)iacc[0] / 4096;
  121. out_buf[1] = (float)iacc[1] / 4096;
  122. out_buf[2] = (float)iacc[2] / 4096;
  123. return 3*4;
  124. }
  125. int rt_hw_fxos8700_init(void)
  126. {
  127. static fxos8700_t fxos8700;
  128. struct rt_i2c_bus_device *bus;
  129. bus = rt_i2c_bus_device_find(FXOS8700_I2C_DEV_NAME);
  130. if (bus == RT_NULL)
  131. {
  132. return RT_ENOSYS;
  133. }
  134. fxos8700.parent.type = RT_Device_Class_Sensor;
  135. fxos8700.parent.rx_indicate = RT_NULL;
  136. fxos8700.parent.tx_complete = RT_NULL;
  137. fxos8700.parent.init = RT_NULL;
  138. fxos8700.parent.open = fxos8700_open;
  139. fxos8700.parent.close = RT_NULL;
  140. fxos8700.parent.read = fxos8700_read;
  141. fxos8700.parent.write = RT_NULL;
  142. fxos8700.parent.user_data = RT_NULL;
  143. fxos8700.bus = bus;
  144. fxos8700.i2c_addr = FXOS8700_CHIP_ADDR;
  145. rt_device_register(&fxos8700.parent, FXOS8700_DEV_NAME, RT_DEVICE_FLAG_RDWR);
  146. return RT_EOK;
  147. }
  148. INIT_DEVICE_EXPORT(rt_hw_fxos8700_init);