coffee.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "coffee.h"
  2. #include "math.h"
  3. #include <furi.h>
  4. #include <stdio.h>
  5. #define EEPROM_I2C_ADDR (0x50 << 1)
  6. uint8_t data_buffer[4];
  7. uint8_t address_54_buffer[4];
  8. uint8_t address_44_buffer[4];
  9. bool write_buffer(uint8_t *buffer, size_t buffer_size, uint8_t start_address){
  10. furi_hal_i2c_acquire(&furi_hal_i2c_handle_external);
  11. bool result = false;
  12. if(furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, EEPROM_I2C_ADDR, (uint32_t) 1000)){
  13. FURI_LOG_E("COFFEE", "WRITE READY");
  14. for (size_t i = 0; i < buffer_size; i++){
  15. result = false;
  16. while(!result){
  17. result = furi_hal_i2c_write_reg_8(&furi_hal_i2c_handle_external, EEPROM_I2C_ADDR, start_address + i, buffer[i], (uint32_t) 2000);
  18. FURI_LOG_E("COFFEE", "Write %.2X, byte %d/%d at address %.2X, result %d", buffer[i], i + 1, buffer_size, start_address + i, result);
  19. }
  20. }
  21. }
  22. else{
  23. FURI_LOG_D("COFFEE", "VIRGIN: EEPROM not ready %x (8-bit)", EEPROM_I2C_ADDR);
  24. }
  25. furi_hal_i2c_release(&furi_hal_i2c_handle_external);
  26. return result;
  27. }
  28. void write_dump(uint8_t* buffer, size_t size){
  29. write_buffer(buffer, size, 0x00);
  30. }
  31. void write_credit(float value){
  32. calc_credit(value, address_44_buffer);
  33. memcpy(address_54_buffer, address_44_buffer, 4 * sizeof(uint8_t));
  34. address_54_buffer[1] -= 0x40;
  35. write_buffer(address_44_buffer, sizeof(address_44_buffer), 0x44);
  36. write_buffer(address_54_buffer, sizeof(address_54_buffer), 0x54);
  37. }
  38. void dump(uint8_t* out){
  39. FuriString* dump_str = furi_string_alloc();
  40. furi_hal_i2c_acquire(&furi_hal_i2c_handle_external);
  41. if(furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, EEPROM_I2C_ADDR, (uint32_t) 1000)){
  42. uint8_t temp[1];
  43. FURI_LOG_E("COFFEE_eeprom", "Start dump");
  44. for (size_t i=0; i<256; i++){
  45. furi_hal_i2c_read_reg_8(&furi_hal_i2c_handle_external, EEPROM_I2C_ADDR, 0x00 + i, (uint8_t *) temp, (uint32_t) 500);
  46. furi_string_cat_printf(dump_str, "%.2X", temp[0]);
  47. out[i] = temp[0];
  48. }
  49. FURI_LOG_E("COFFEE_eeprom", furi_string_get_cstr(dump_str));
  50. FURI_LOG_E("COFFEE_eeprom", "End dump");
  51. }else{
  52. FURI_LOG_D("COFFEE", "DUMP: EEPROM not ready %x (8-bit)", EEPROM_I2C_ADDR);
  53. }
  54. furi_hal_i2c_release(&furi_hal_i2c_handle_external);
  55. }
  56. float read_credit(){
  57. memset(data_buffer, 0, sizeof(data_buffer)); //reset array
  58. furi_hal_i2c_acquire(&furi_hal_i2c_handle_external);
  59. bool is_ready = false;
  60. is_ready = furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, EEPROM_I2C_ADDR, (uint32_t) 1000);
  61. if(is_ready){
  62. furi_hal_i2c_read_mem(&furi_hal_i2c_handle_external, EEPROM_I2C_ADDR, 0x44, data_buffer, sizeof(data_buffer), (uint32_t) 1000);
  63. int credit = 0;
  64. int exponent = 14;
  65. int hi, lo = 0;
  66. for (size_t i = 0; i < sizeof(data_buffer); i++)
  67. { //iterate 2 bit at times
  68. hi = 0;
  69. lo = 0;
  70. for (int j = 3; j >= 0; j--) {
  71. int k = (data_buffer[i] % 16) >> j; // right shift
  72. if (k & 1){
  73. if(j>=2)
  74. hi += pow(2, j-2);
  75. else
  76. lo += pow(2, j);
  77. }
  78. }
  79. credit += hi * pow(2, exponent) + lo * pow(2, exponent-8);
  80. exponent -= 2;
  81. }
  82. furi_hal_i2c_release(&furi_hal_i2c_handle_external);
  83. return credit / 100.00;
  84. }
  85. else{
  86. furi_hal_i2c_release(&furi_hal_i2c_handle_external);
  87. FURI_LOG_D("COFFEE", "READ CREDIT: EEPROM not ready %x (8-bit)", EEPROM_I2C_ADDR);
  88. return -1.0;
  89. }
  90. }
  91. void calc_credit(float value, uint8_t* result){
  92. //credit
  93. uint8_t coeff[8];
  94. uint16_t n = value * 100;
  95. for (size_t i = 0; i < 8; i++) {
  96. coeff[i] = n % 4;
  97. n /= 4;
  98. }
  99. uint8_t credit[4];
  100. for (size_t i = 0; i < 4; i++) {
  101. uint8_t bit3 = (coeff[7 - i] >> 1) & 1;
  102. uint8_t bit2 = coeff[7 - i] & 1;
  103. uint8_t bit1 = (coeff[3 - i] >> 1) & 1;
  104. uint8_t bit0 = coeff[3 - i] & 1;
  105. credit[i] = (bit3 << 3) | (bit2 << 2) | (bit1 << 1) | bit0;
  106. }
  107. //checksum
  108. uint8_t exponents[] = {12, 8, 4, 0};
  109. uint16_t numerator = value * 100;
  110. uint8_t sub_factor = 0;
  111. for (size_t i = 0; i < 4; i++) {
  112. sub_factor += numerator / (1 << exponents[i]);
  113. numerator = numerator % (1 << exponents[i]);
  114. }
  115. uint8_t subbed = 187 - sub_factor;
  116. uint8_t checksum[4];
  117. for (size_t i = 0; i < 4; i++) {
  118. checksum[3 - i] = (subbed % 4) * 4;
  119. subbed /= 4;
  120. }
  121. //concatnate
  122. for (size_t i = 0; i < 4; i++) {
  123. result[i] = (checksum[i] << 4) | credit[i];
  124. }
  125. }