drv_qmc6310_v2.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /*Includes ----------------------------------------------*/
  2. #include "drv_iic_back.h"
  3. #include "nrf_delay.h"
  4. #include "drv_qmc6310_v2.h"
  5. #include "exception.h"
  6. #include "system.h"
  7. /*Private macro ------------------------------------------------*/
  8. /* vendor chip id*/
  9. #define QMC6310U_IIC_ADDR (0x1c<<1)
  10. #define QMC6310N_IIC_ADDR (0x3c<<1)
  11. #define QMC6310_CHIP_ID_REG 0x00
  12. /*data output register*/
  13. #define QMC6310_DATA_OUT_X_LSB_REG 0x01
  14. #define QMC6310_DATA_OUT_X_MSB_REG 0x02
  15. #define QMC6310_DATA_OUT_Y_LSB_REG 0x03
  16. #define QMC6310_DATA_OUT_Y_MSB_REG 0x04
  17. #define QMC6310_DATA_OUT_Z_LSB_REG 0x05
  18. #define QMC6310_DATA_OUT_Z_MSB_REG 0x06
  19. /*Status registers */
  20. #define QMC6310_STATUS_REG 0x09
  21. /* configuration registers */
  22. #define QMC6310_CTL_REG_ONE 0x0A /* Contrl register one */
  23. #define QMC6310_CTL_REG_TWO 0x0B /* Contrl register two */
  24. /* Magnetic Sensor Operating Mode MODE[1:0]*/
  25. #define QMC6310_SUSPEND_MODE 0x00
  26. #define QMC6310_NORMAL_MODE 0x01
  27. #define QMC6310_SINGLE_MODE 0x02
  28. #define QMC6310_H_PFM_MODE 0x03
  29. /*data output rate OSR2[2:0]*/
  30. #define OUTPUT_DATA_RATE_800HZ 0x00
  31. #define OUTPUT_DATA_RATE_400HZ 0x01
  32. #define OUTPUT_DATA_RATE_200HZ 0x02
  33. #define OUTPUT_DATA_RATE_100HZ 0x03
  34. /*oversample Ratio OSR[1]*/
  35. #define OVERSAMPLE_RATE_256 0x01
  36. #define OVERSAMPLE_RATE_128 0x00
  37. #define SET_RESET_ON 0x00
  38. #define SET_ONLY_ON 0x01
  39. #define SET_RESET_OFF 0x02
  40. #define QMC6310_DEFAULT_DELAY 200
  41. #define QMC6310_MAXHZ 0xC3
  42. #define QMC6310_200HZ 0x3D
  43. #define QMC6310_100HZ 0x39
  44. #define QMC6310_10HZ 0x31
  45. /*STRUCTION -----------------------------------------------------*/
  46. typedef struct drv_qmc6310
  47. {
  48. bool (*write)(uint8_t add,uint8_t reg,uint8_t* p,uint8_t len); //IIC - 写
  49. bool (*read)(uint8_t add,uint8_t reg,uint8_t* p,uint8_t len); //IIC - 读
  50. qmc_data_t cur_data; //当前QMC的数据
  51. drv_qmc_config_param_t cur_param; //当前QMC的配置
  52. } Drv_Qmc6310_t;
  53. /*Local Variable ----------------------------------------------*/
  54. static Drv_Qmc6310_t ob_qmc6310;
  55. static uint32_t iic_write_error_counter = 0; //iic写错误上报
  56. static uint32_t iic_read_error_counter = 0; //iic读错误上报
  57. /*Local Functions ----------------------------------------------*/
  58. static bool qmc6310_get_chipid(void)
  59. {
  60. bool ret;
  61. uint8_t chipid = 0xFF;
  62. ret = ob_qmc6310.read(QMC6310U_IIC_ADDR,QMC6310_CHIP_ID_REG,&chipid,1);
  63. if(ret == false)return false;
  64. return true;
  65. }
  66. static bool platform_read(uint8_t add,uint8_t reg,uint8_t* p,uint8_t len)
  67. {
  68. bool ierror;
  69. ierror = IIC_BACK_ReadBytes(add,reg,p,len);
  70. if(ierror != true)
  71. {
  72. iic_read_error_counter++;
  73. }
  74. return ierror;
  75. }
  76. static bool platform_write(uint8_t add,uint8_t reg,uint8_t* p,uint8_t len)
  77. {
  78. bool ierror;
  79. ierror = IIC_BACK_WriteBytes(add,reg,p,len);
  80. if(ierror != true)
  81. {
  82. iic_write_error_counter++;
  83. }
  84. return ierror;
  85. }
  86. static void drv_qmc_iic_error_report_process(void)
  87. {
  88. char buff[30]={0};
  89. if(iic_write_error_counter > 0)
  90. {
  91. sprintf(buff,"iic_write_err,%d\r\n",iic_write_error_counter);
  92. Except_TxError(EXCEPT_IIC_RW,(const char *)buff);
  93. }
  94. if(iic_read_error_counter > 0)
  95. {
  96. sprintf(buff,"iic_read_err,%d\r\n",iic_read_error_counter);
  97. Except_TxError(EXCEPT_IIC_RW,(const char *)buff);
  98. }
  99. iic_write_error_counter = 0;
  100. iic_read_error_counter = 0;
  101. }
  102. /*API ----------------------------------------------*/
  103. /**
  104. @brief 初始化QMC6310驱动
  105. @param 无
  106. @return 错误代码 - [out] -1失败,0成功
  107. */
  108. int drv_qmc6310_Init(void)
  109. {
  110. nrf_gpio_cfg(
  111. PIN_BACK_SENSE_POWER,
  112. NRF_GPIO_PIN_DIR_OUTPUT,
  113. NRF_GPIO_PIN_INPUT_DISCONNECT,
  114. NRF_GPIO_PIN_NOPULL,
  115. NRF_GPIO_PIN_H0H1,
  116. NRF_GPIO_PIN_NOSENSE);
  117. nrf_gpio_cfg_output(PIN_BACK_SCL);
  118. nrf_gpio_cfg_output(PIN_BACK_SDA);
  119. nrf_gpio_pin_write(PIN_BACK_SCL,0);
  120. nrf_gpio_pin_write(PIN_BACK_SDA,0);
  121. //供电
  122. nrf_gpio_pin_write(PIN_BACK_SENSE_POWER,0);
  123. nrf_delay_ms(5);
  124. nrf_gpio_pin_write(PIN_BACK_SENSE_POWER,1);
  125. nrf_delay_ms(5);
  126. //初始化IIC错误上报
  127. Process_Start(1000,"drv_qmc_iic_error_report_process",drv_qmc_iic_error_report_process);
  128. //初始化IIC
  129. IIC_BACK_Init();
  130. //初始化结构体
  131. memset(&ob_qmc6310, 0, sizeof(ob_qmc6310));
  132. ob_qmc6310.read = platform_read;
  133. ob_qmc6310.write = platform_write;
  134. ob_qmc6310.cur_param.mag_fs = QMC_MAG_FS_30GS;
  135. ob_qmc6310.cur_param.mag_odr = QMC_MAG_ODR_OFF;
  136. if(qmc6310_get_chipid())
  137. {
  138. return 0;
  139. }
  140. return -1;
  141. }
  142. /**
  143. @brief QMC6310断电
  144. @param 无
  145. @return 错误代码 - [out] -1失败,0成功
  146. */
  147. int drv_qmc6310_power_off(void)
  148. {
  149. nrf_gpio_cfg(
  150. PIN_BACK_SENSE_POWER,
  151. NRF_GPIO_PIN_DIR_OUTPUT,
  152. NRF_GPIO_PIN_INPUT_DISCONNECT,
  153. NRF_GPIO_PIN_NOPULL,
  154. NRF_GPIO_PIN_H0H1,
  155. NRF_GPIO_PIN_NOSENSE);
  156. nrf_gpio_cfg_output(PIN_BACK_SCL);
  157. nrf_gpio_cfg_output(PIN_BACK_SDA);
  158. nrf_gpio_pin_write(PIN_BACK_SCL,0);
  159. nrf_gpio_pin_write(PIN_BACK_SDA,0);
  160. //供电
  161. nrf_gpio_pin_write(PIN_BACK_SENSE_POWER,0);
  162. return 0;
  163. }
  164. /**
  165. @brief QMC6310上电(默认配置挂起)
  166. @param 无
  167. @return 错误代码 - [out] -1失败,0成功
  168. */
  169. int drv_qmc6310_power_on(void)
  170. {
  171. nrf_gpio_pin_write(PIN_BACK_SENSE_POWER,1);
  172. //初始化IIC
  173. IIC_BACK_Init();
  174. memset(&ob_qmc6310.cur_data,0,sizeof(ob_qmc6310.cur_data));
  175. ob_qmc6310.cur_param.mag_fs = QMC_MAG_FS_30GS;
  176. ob_qmc6310.cur_param.mag_odr = QMC_MAG_ODR_OFF;
  177. return 0;
  178. }
  179. /**
  180. @brief 设置MAG量程
  181. @param mag_fs - [in] MAG量程
  182. @return 错误代码 - [out] -1失败,0成功
  183. */
  184. int drv_qmc6310_set_mag_fs(QMC_MAG_FS_e mag_fs)
  185. {
  186. bool ret;
  187. uint8_t data;
  188. if(ob_qmc6310.cur_param.mag_fs != mag_fs)
  189. {
  190. switch(mag_fs)
  191. {
  192. case QMC_MAG_FS_30GS:
  193. data = QMC_MAG_FS_30GS;
  194. ret = ob_qmc6310.write(QMC6310U_IIC_ADDR,QMC6310_CTL_REG_TWO,&data,1);
  195. if(ret == false)return -1;
  196. data = 0xFF;
  197. ret = ob_qmc6310.read(QMC6310U_IIC_ADDR,QMC6310_CTL_REG_TWO,&data,1);
  198. if(ret == false || data != QMC_MAG_FS_30GS)return -1;
  199. ob_qmc6310.cur_param.mag_fs = QMC_MAG_FS_30GS;
  200. break;
  201. }
  202. }
  203. return 0;
  204. }
  205. /**
  206. @brief 获取配置MAG采样频率需要的步骤数量
  207. @return 错误代码 - [out] 配置MAG采样频率需要的步骤数量
  208. */
  209. int drv_qmc6310_get_mag_odr_flow(void)
  210. {
  211. return 4;
  212. }
  213. /**
  214. @brief 设置MAG采样频率
  215. @param mag_odr - [in] MAG采样频率
  216. @param flow - [in] 当前需要处理的步骤
  217. @return 错误代码 - [out] -1失败,0成功
  218. */
  219. int drv_qmc6310_set_mag_odr(QMC_MAG_ODR_e mag_odr, int flow)
  220. {
  221. int ret = -1;
  222. bool err;
  223. uint8_t data;
  224. if(flow <= 0 || flow >= 5)return -1;
  225. if(ob_qmc6310.cur_param.mag_odr != mag_odr)
  226. {
  227. switch(flow)
  228. {
  229. case 1:
  230. //define the sign for x y and z axis
  231. if(mag_odr != QMC_MAG_ODR_OFF)
  232. {
  233. data = 0x06;
  234. err = ob_qmc6310.write(QMC6310U_IIC_ADDR,0x29,&data,1);
  235. if(err == false)return -1;
  236. else ret = 0;
  237. }
  238. else
  239. {
  240. ret = 0;
  241. }
  242. break;
  243. case 2:
  244. //define the sign for x y and z axis
  245. if(mag_odr != QMC_MAG_ODR_OFF)
  246. {
  247. data = 0xFF;
  248. err = ob_qmc6310.read(QMC6310U_IIC_ADDR,0x29,&data,1);
  249. if(err == false || data != 0x06)return -1;
  250. else ret = 0;
  251. }
  252. else
  253. {
  254. ret = 0;
  255. }
  256. break;
  257. case 3:
  258. //set odr
  259. data = mag_odr;
  260. err = ob_qmc6310.write(QMC6310U_IIC_ADDR,QMC6310_CTL_REG_ONE,&data,1);
  261. if(err == false)return -1;
  262. else ret = 0;
  263. break;
  264. case 4:
  265. data = 0xFF;
  266. err = ob_qmc6310.read(QMC6310U_IIC_ADDR,QMC6310_CTL_REG_ONE,&data,1);
  267. if(err == false || data != mag_odr)return -1;
  268. else{
  269. ret = 0;
  270. ob_qmc6310.cur_param.mag_odr = mag_odr;
  271. }
  272. break;
  273. }
  274. }
  275. else
  276. {
  277. return 0;
  278. }
  279. return ret;
  280. }
  281. /**
  282. @brief 获取LSM配置参数
  283. @param param - [in] LSM配置参数
  284. @return 错误代码 - [out] -1失败,0成功
  285. */
  286. int drv_qmc6310_get_config_param(drv_qmc_config_param_t *p_param)
  287. {
  288. *p_param = ob_qmc6310.cur_param;
  289. return 0;
  290. }
  291. /**
  292. @brief 获取LSM的ACC数据
  293. @param p_data - [out] 返回的ACC三轴数据
  294. @return 错误代码 - [out] -1失败,0成功
  295. */
  296. int drv_qmc6310_get_mag_data(qmc_data_t *p_data)
  297. {
  298. bool ret;
  299. unsigned char mag_data[6];
  300. mag_data[0] = QMC6310_DATA_OUT_X_LSB_REG;
  301. ret = ob_qmc6310.read(QMC6310U_IIC_ADDR,QMC6310_DATA_OUT_X_LSB_REG,mag_data,6);
  302. if(ret == false)return -1;
  303. if(p_data != NULL)
  304. {
  305. p_data->mag[0] = (int16_t)(((mag_data[1]) << 8) | mag_data[0]);
  306. p_data->mag[1] = (int16_t)(((mag_data[3]) << 8) | mag_data[2]);
  307. p_data->mag[2] = (int16_t)(((mag_data[5]) << 8) | mag_data[4]);
  308. }
  309. return 0;
  310. }