coffee.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. furi_string_free(dump_str);
  52. }else{
  53. FURI_LOG_D("COFFEE", "DUMP: EEPROM not ready %x (8-bit)", EEPROM_I2C_ADDR);
  54. }
  55. furi_hal_i2c_release(&furi_hal_i2c_handle_external);
  56. }
  57. float read_credit(){
  58. memset(data_buffer, 0, sizeof(data_buffer)); //reset array
  59. furi_hal_i2c_acquire(&furi_hal_i2c_handle_external);
  60. bool is_ready = false;
  61. is_ready = furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, EEPROM_I2C_ADDR, (uint32_t) 1000);
  62. if(is_ready){
  63. furi_hal_i2c_read_mem(&furi_hal_i2c_handle_external, EEPROM_I2C_ADDR, 0x44, data_buffer, sizeof(data_buffer), (uint32_t) 1000);
  64. int credit = 0;
  65. int exponent = 14;
  66. int hi, lo = 0;
  67. for (size_t i = 0; i < sizeof(data_buffer); i++)
  68. { //iterate 2 bit at times
  69. hi = 0;
  70. lo = 0;
  71. for (int j = 3; j >= 0; j--) {
  72. int k = (data_buffer[i] % 16) >> j; // right shift
  73. if (k & 1){
  74. if(j>=2)
  75. hi += pow(2, j-2);
  76. else
  77. lo += pow(2, j);
  78. }
  79. }
  80. credit += hi * pow(2, exponent) + lo * pow(2, exponent-8);
  81. exponent -= 2;
  82. }
  83. furi_hal_i2c_release(&furi_hal_i2c_handle_external);
  84. return credit / 100.00;
  85. }
  86. else{
  87. furi_hal_i2c_release(&furi_hal_i2c_handle_external);
  88. FURI_LOG_D("COFFEE", "READ CREDIT: EEPROM not ready %x (8-bit)", EEPROM_I2C_ADDR);
  89. return -1.0;
  90. }
  91. }
  92. void calc_credit(float value, uint8_t* result){
  93. //credit
  94. uint8_t coeff[8];
  95. uint16_t n = value * 100;
  96. for (size_t i = 0; i < 8; i++) {
  97. coeff[i] = n % 4;
  98. n /= 4;
  99. }
  100. uint8_t credit[4];
  101. for (size_t i = 0; i < 4; i++) {
  102. uint8_t bit3 = (coeff[7 - i] >> 1) & 1;
  103. uint8_t bit2 = coeff[7 - i] & 1;
  104. uint8_t bit1 = (coeff[3 - i] >> 1) & 1;
  105. uint8_t bit0 = coeff[3 - i] & 1;
  106. credit[i] = (bit3 << 3) | (bit2 << 2) | (bit1 << 1) | bit0;
  107. }
  108. //checksum
  109. uint8_t exponents[] = {12, 8, 4, 0};
  110. uint16_t numerator = value * 100;
  111. uint8_t sub_factor = 0;
  112. for (size_t i = 0; i < 4; i++) {
  113. sub_factor += numerator / (1 << exponents[i]);
  114. numerator = numerator % (1 << exponents[i]);
  115. }
  116. uint8_t subbed = 187 - sub_factor;
  117. uint8_t checksum[4];
  118. for (size_t i = 0; i < 4; i++) {
  119. checksum[3 - i] = (subbed % 4) * 4;
  120. subbed /= 4;
  121. }
  122. //concatnate
  123. for (size_t i = 0; i < 4; i++) {
  124. result[i] = (checksum[i] << 4) | credit[i];
  125. }
  126. }