I2CSensor.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. Unitemp - Universal temperature reader
  3. Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  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. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "I2CSensor.h"
  16. static uint8_t sensors_count = 0;
  17. void unitemp_i2c_acquire(const FuriHalI2cBusHandle* handle) {
  18. furi_hal_i2c_acquire(handle);
  19. LL_GPIO_SetPinPull(gpio_ext_pc1.port, gpio_ext_pc1.pin, LL_GPIO_PULL_UP);
  20. LL_GPIO_SetPinPull(gpio_ext_pc0.port, gpio_ext_pc0.pin, LL_GPIO_PULL_UP);
  21. }
  22. bool unitemp_i2c_isDeviceReady(I2CSensor* i2c_sensor) {
  23. unitemp_i2c_acquire(i2c_sensor->i2c);
  24. bool status = furi_hal_i2c_is_device_ready(i2c_sensor->i2c, i2c_sensor->currentI2CAdr, 10);
  25. furi_hal_i2c_release(i2c_sensor->i2c);
  26. return status;
  27. }
  28. uint8_t unitemp_i2c_readReg(I2CSensor* i2c_sensor, uint8_t reg) {
  29. //Блокировка шины
  30. unitemp_i2c_acquire(i2c_sensor->i2c);
  31. uint8_t buff[1] = {0};
  32. furi_hal_i2c_read_mem(i2c_sensor->i2c, i2c_sensor->currentI2CAdr, reg, buff, 1, 10);
  33. furi_hal_i2c_release(i2c_sensor->i2c);
  34. return buff[0];
  35. }
  36. bool unitemp_i2c_readArray(I2CSensor* i2c_sensor, uint8_t len, uint8_t* data) {
  37. unitemp_i2c_acquire(i2c_sensor->i2c);
  38. bool status = furi_hal_i2c_rx(i2c_sensor->i2c, i2c_sensor->currentI2CAdr, data, len, 10);
  39. furi_hal_i2c_release(i2c_sensor->i2c);
  40. return status;
  41. }
  42. bool unitemp_i2c_readRegArray(I2CSensor* i2c_sensor, uint8_t startReg, uint8_t len, uint8_t* data) {
  43. unitemp_i2c_acquire(i2c_sensor->i2c);
  44. bool status =
  45. furi_hal_i2c_read_mem(i2c_sensor->i2c, i2c_sensor->currentI2CAdr, startReg, data, len, 10);
  46. furi_hal_i2c_release(i2c_sensor->i2c);
  47. return status;
  48. }
  49. bool unitemp_i2c_writeReg(I2CSensor* i2c_sensor, uint8_t reg, uint8_t value) {
  50. //Блокировка шины
  51. unitemp_i2c_acquire(i2c_sensor->i2c);
  52. uint8_t buff[1] = {value};
  53. bool status =
  54. furi_hal_i2c_write_mem(i2c_sensor->i2c, i2c_sensor->currentI2CAdr, reg, buff, 1, 10);
  55. furi_hal_i2c_release(i2c_sensor->i2c);
  56. return status;
  57. }
  58. bool unitemp_i2c_writeArray(I2CSensor* i2c_sensor, uint8_t len, uint8_t* data) {
  59. unitemp_i2c_acquire(i2c_sensor->i2c);
  60. bool status = furi_hal_i2c_tx(i2c_sensor->i2c, i2c_sensor->currentI2CAdr, data, len, 10);
  61. furi_hal_i2c_release(i2c_sensor->i2c);
  62. return status;
  63. }
  64. bool unitemp_i2c_writeRegArray(I2CSensor* i2c_sensor, uint8_t startReg, uint8_t len, uint8_t* data) {
  65. //Блокировка шины
  66. unitemp_i2c_acquire(i2c_sensor->i2c);
  67. bool status = furi_hal_i2c_write_mem(
  68. i2c_sensor->i2c, i2c_sensor->currentI2CAdr, startReg, data, len, 10);
  69. furi_hal_i2c_release(i2c_sensor->i2c);
  70. return status;
  71. }
  72. bool unitemp_I2C_sensor_alloc(Sensor* sensor, char* args) {
  73. bool status = false;
  74. I2CSensor* instance = malloc(sizeof(I2CSensor));
  75. if(instance == NULL) {
  76. FURI_LOG_E(APP_NAME, "Sensor %s instance allocation error", sensor->name);
  77. return false;
  78. }
  79. instance->i2c = &furi_hal_i2c_handle_external;
  80. sensor->instance = instance;
  81. //Указание функций инициализации, деинициализации и обновления данных, а так же адреса на шине I2C
  82. status = sensor->type->allocator(sensor, args);
  83. int i2c_addr;
  84. sscanf(args, "%X", &i2c_addr);
  85. //Установка адреса шины I2C
  86. if(i2c_addr >= instance->minI2CAdr && i2c_addr <= instance->maxI2CAdr) {
  87. instance->currentI2CAdr = i2c_addr;
  88. } else {
  89. instance->currentI2CAdr = instance->minI2CAdr;
  90. }
  91. //Блокировка портов GPIO
  92. sensors_count++;
  93. unitemp_gpio_lock(unitemp_gpio_getFromInt(15), &I2C);
  94. unitemp_gpio_lock(unitemp_gpio_getFromInt(16), &I2C);
  95. return status;
  96. }
  97. bool unitemp_I2C_sensor_free(Sensor* sensor) {
  98. bool status = sensor->type->mem_releaser(sensor);
  99. free(sensor->instance);
  100. if(--sensors_count == 0) {
  101. unitemp_gpio_unlock(unitemp_gpio_getFromInt(15));
  102. unitemp_gpio_unlock(unitemp_gpio_getFromInt(16));
  103. }
  104. return status;
  105. }
  106. UnitempStatus unitemp_I2C_sensor_update(Sensor* sensor) {
  107. if(sensor->status != UT_SENSORSTATUS_OK) {
  108. sensor->type->initializer(sensor);
  109. }
  110. return sensor->type->updater(sensor);
  111. }