logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

bme280.c (7452B)


  1. /* Copyright 2021 rate
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <stdint.h>
  17. #include "bme280.h"
  18. #include "i2c_master.h"
  19. #define BME280_ADDRESS (0x76<<1)
  20. #define BME280_REG_CALIB00 (0x88)
  21. #define BME280_REG_CALIB25 (0xA1)
  22. #define BME280_REG_CALIB26 (0xE1)
  23. #define BME280_REG_CTRL_HUM (0xF2)
  24. #define BME280_REG_CTRL_MEAS (0xF4)
  25. #define BME280_REG_CONFIG (0xF5)
  26. #define BME280_REG_PRESS_MSB (0xf7)
  27. #define I2C_BME280_TIMEOUT (20)
  28. /* BME280 configurator values */
  29. /* [2:0] Humidity oversampling
  30. * 000 Skipped
  31. * 001 oversampling x1
  32. * 010 oversampling x2
  33. * 011 oversampling x4
  34. * 100 oversampling x8
  35. * 101,others oversampling x16
  36. */
  37. #define BME280_CTRL_HUM_VAL (0x01)
  38. /* [7:5] Pressure oversampling
  39. * 000 Skipped
  40. * 001 oversampling x1
  41. * 010 oversampling x2
  42. * 011 oversampling x4
  43. * 100 oversampling x8
  44. * 101,others oversampling x16
  45. * [4:2] Temperature oversampling
  46. * 000 Skipped
  47. * 001 oversampling x1
  48. * 010 oversampling x2
  49. * 011 oversampling x4
  50. * 100 oversampling x8
  51. * 101,others oversampling x16
  52. * [1:0] Mode
  53. * 00 Sleep mode
  54. * 11 Normal mode
  55. */
  56. #define BME280_CTRL_MEAS_VAL (0x27)
  57. /* [7:5] t_standby[ms]
  58. * 000 0.5
  59. * 001 62.5
  60. * 010 125
  61. * 011 250
  62. * 100 500
  63. * 101 1000
  64. * 110 10
  65. * 111 20
  66. * [4:2] Filter corefficient
  67. * 000 Filter off
  68. * 001 2
  69. * 010 4
  70. * 011 8
  71. * 100,others 16
  72. * [0] SPI interface
  73. * 0 4-wire
  74. * 1 3-wire
  75. */
  76. #define BME280_CONFIG_VAL (0xA0)
  77. static void readTrim(void);
  78. static void readData(void);
  79. static int32_t calibration_T(int32_t adc_T);
  80. static uint32_t calibration_P(int32_t adc_P);
  81. static uint32_t calibration_H(int32_t adc_H);
  82. static uint32_t hum_raw,temp_raw,pres_raw;
  83. static uint16_t dig_T1;
  84. static int16_t dig_T2, dig_T3;
  85. static uint16_t dig_P1;
  86. static int16_t dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9;
  87. static uint8_t dig_H1, dig_H3;
  88. static int16_t dig_H2, dig_H4, dig_H5;
  89. static int8_t dig_H6;
  90. static int32_t t_fine;
  91. /* Private */
  92. static void readTrim(void) {
  93. uint8_t data[32];
  94. i2c_read_register(BME280_ADDRESS, BME280_REG_CALIB00, &data[0], 24, I2C_BME280_TIMEOUT);
  95. i2c_read_register(BME280_ADDRESS, BME280_REG_CALIB25, &data[25], 1, I2C_BME280_TIMEOUT);
  96. i2c_read_register(BME280_ADDRESS, BME280_REG_CALIB26, &data[25], 7, I2C_BME280_TIMEOUT);
  97. dig_T1 = (data[1] << 8) | data[0];
  98. dig_T2 = (data[3] << 8) | data[2];
  99. dig_T3 = (data[5] << 8) | data[4];
  100. dig_P1 = (data[7] << 8) | data[6];
  101. dig_P2 = (data[9] << 8) | data[8];
  102. dig_P3 = (data[11]<< 8) | data[10];
  103. dig_P4 = (data[13]<< 8) | data[12];
  104. dig_P5 = (data[15]<< 8) | data[14];
  105. dig_P6 = (data[17]<< 8) | data[16];
  106. dig_P7 = (data[19]<< 8) | data[18];
  107. dig_P8 = (data[21]<< 8) | data[20];
  108. dig_P9 = (data[23]<< 8) | data[22];
  109. dig_H1 = data[24];
  110. dig_H2 = (data[26]<< 8) | data[25];
  111. dig_H3 = data[27];
  112. dig_H4 = (data[28]<< 4) | (0x0F & data[29]);
  113. dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F);
  114. dig_H6 = data[31];
  115. return;
  116. }
  117. static void readData(void) {
  118. uint8_t data[8];
  119. i2c_read_register(BME280_ADDRESS, 0xF7, &data[0], 8, I2C_BME280_TIMEOUT);
  120. pres_raw = data[0];
  121. pres_raw = (pres_raw<<8) | data[1];
  122. pres_raw = (pres_raw<<4) | (data[2] >> 4);
  123. temp_raw = data[3];
  124. temp_raw = (temp_raw<<8) | data[4];
  125. temp_raw = (temp_raw<<4) | (data[5] >> 4);
  126. hum_raw = data[6];
  127. hum_raw = (hum_raw << 8) | data[7];
  128. return;
  129. }
  130. static int32_t calibration_T(int32_t adc_T) {
  131. int32_t var1, var2, T;
  132. var1 = ((((adc_T >> 3) - ((int32_t)dig_T1<<1))) * ((int32_t)dig_T2)) >> 11;
  133. var2 = (((((adc_T >> 4) - ((int32_t)dig_T1)) * ((adc_T>>4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14;
  134. t_fine = var1 + var2;
  135. T = (t_fine * 5 + 128) >> 8;
  136. return T;
  137. }
  138. static uint32_t calibration_P(int32_t adc_P) {
  139. int32_t var1, var2;
  140. uint32_t P;
  141. var1 = (((int32_t)t_fine)>>1) - (int32_t)64000;
  142. var2 = (((var1>>2) * (var1>>2)) >> 11) * ((int32_t)dig_P6);
  143. var2 = var2 + ((var1*((int32_t)dig_P5))<<1);
  144. var2 = (var2>>2)+(((int32_t)dig_P4)<<16);
  145. var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((int32_t)dig_P2) * var1)>>1))>>18;
  146. var1 = ((((32768+var1))*((int32_t)dig_P1))>>15);
  147. if (var1 == 0) {
  148. return 0;
  149. }
  150. P = (((uint32_t)(((int32_t)1048576)-adc_P)-(var2>>12)))*3125;
  151. if( P < 0x80000000 ) {
  152. P = (P << 1) / ((uint32_t) var1);
  153. } else {
  154. P = (P / (uint32_t)var1) * 2;
  155. }
  156. var1 = (((int32_t)dig_P9) * ((int32_t)(((P>>3) * (P>>3))>>13)))>>12;
  157. var2 = (((int32_t)(P>>2)) * ((int32_t)dig_P8))>>13;
  158. P = (uint32_t)((int32_t)P + ((var1 + var2 + dig_P7) >> 4));
  159. return P;
  160. }
  161. static uint32_t calibration_H(int32_t adc_H) {
  162. int32_t v_x1;
  163. v_x1 = (t_fine - ((int32_t)76800));
  164. v_x1 = (((((adc_H << 14) -(((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * v_x1)) +
  165. ((int32_t)16384)) >> 15) * (((((((v_x1 * ((int32_t)dig_H6)) >> 10) *
  166. (((v_x1 * ((int32_t)dig_H3)) >> 11) + ((int32_t) 32768))) >> 10) + (( int32_t)2097152)) *
  167. ((int32_t) dig_H2) + 8192) >> 14));
  168. v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((int32_t)dig_H1)) >> 4));
  169. v_x1 = (v_x1 < 0 ? 0 : v_x1);
  170. v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
  171. return (uint32_t)(v_x1 >> 12);
  172. }
  173. /* Public */
  174. void bme280_init(void) {
  175. uint8_t ctrl_hum_reg;
  176. uint8_t ctrl_meas_reg;
  177. uint8_t config_reg;
  178. ctrl_hum_reg = BME280_CTRL_HUM_VAL;
  179. ctrl_meas_reg = BME280_CTRL_MEAS_VAL;
  180. config_reg = BME280_CONFIG_VAL;
  181. i2c_init();
  182. i2c_write_register(BME280_ADDRESS, BME280_REG_CTRL_HUM, &ctrl_hum_reg, 1, I2C_BME280_TIMEOUT);
  183. i2c_write_register(BME280_ADDRESS, BME280_REG_CTRL_MEAS, &ctrl_meas_reg, 1, I2C_BME280_TIMEOUT);
  184. i2c_write_register(BME280_ADDRESS, BME280_REG_CONFIG, &config_reg, 1, I2C_BME280_TIMEOUT);
  185. readTrim();
  186. return;
  187. }
  188. void bme280_exec(void) {
  189. readData();
  190. return;
  191. }
  192. double bme280_getTemp(void) {
  193. double temp_act;
  194. int32_t temp_cal;
  195. temp_cal = calibration_T(temp_raw);
  196. temp_act = (double)temp_cal / 100.0;
  197. return temp_act;
  198. }
  199. double bme280_getPress(void) {
  200. double press_act;
  201. uint32_t press_cal;
  202. press_cal = calibration_P(pres_raw);
  203. press_act = (double)press_cal / 100.0;
  204. return press_act;
  205. }
  206. double bme280_getHum(void) {
  207. double hum_act;
  208. uint32_t hum_cal;
  209. hum_cal = calibration_H(hum_raw);
  210. hum_act = (double)hum_cal / 1024.0;
  211. return hum_act;
  212. }