board.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * board.c
  3. *
  4. * Created on: Jun 15, 2019
  5. * Author: curiousmuch
  6. */
  7. #include <stdio.h>
  8. #include "freertos/FreeRTOS.h"
  9. #include "freertos/task.h"
  10. #include "driver/gpio.h"
  11. #include "driver/adc.h"
  12. #include "esp_adc_cal.h"
  13. #include "esp_log.h"
  14. #include "board.h"
  15. // Debugging IO Functions
  16. inline void IRAM_ATTR enable_debug_IO(uint32_t io_num)
  17. {
  18. gpio_set_level(io_num, 1);
  19. }
  20. inline void IRAM_ATTR disable_debug_IO(uint32_t io_num)
  21. {
  22. gpio_set_level(io_num, 0);
  23. }
  24. // Red LED Functions
  25. void enable_red_led(void)
  26. {
  27. gpio_set_level(RED_LED, 1);
  28. }
  29. void disable_red_led(void)
  30. {
  31. gpio_set_level(RED_LED, 0);
  32. }
  33. // Green LED Functions
  34. void enable_green_led(void)
  35. {
  36. gpio_set_level(GREEN_LED, 1);
  37. }
  38. void disable_green_led(void)
  39. {
  40. gpio_set_level(GREEN_LED, 0);
  41. }
  42. // ADC Functions
  43. #define DEFAULT_VREF 1100 // units in mV
  44. static esp_adc_cal_characteristics_t *adc_chars;
  45. #define ADC_CONSTANT (100) / (100 + 350)
  46. void enable_voltage_divider(void)
  47. {
  48. gpio_set_level(ENABLE_VOLTAGE_DIVIDER, 0);
  49. }
  50. void disable_voltage_divider(void)
  51. {
  52. // TODO: set to Hi-Z instead
  53. gpio_set_level(ENABLE_VOLTAGE_DIVIDER, 1);
  54. }
  55. static void check_efuse(void)
  56. {
  57. // check TP is burned into eFuse
  58. if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK)
  59. {
  60. ESP_LOGI("board", "eFuse two point: supported");
  61. }
  62. else
  63. {
  64. ESP_LOGW("board", "eFuse two point: NOT supported");
  65. }
  66. // check Vref is burned into eFuse
  67. if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK)
  68. {
  69. ESP_LOGI("board", "eFuse Vref: supported");
  70. }
  71. else
  72. {
  73. ESP_LOGW("board", "eFuse Vref: NOT supported");
  74. }
  75. }
  76. static void print_char_val_type(esp_adc_cal_value_t val_type)
  77. {
  78. if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
  79. ESP_LOGI("board", "characterized using two point value");
  80. } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
  81. ESP_LOGI("board", "characterized using eFuse Vref");
  82. } else {
  83. ESP_LOGW("board", "characterized using default Vref");
  84. }
  85. }
  86. int32_t battery_measure(void)
  87. {
  88. int32_t adc_val;
  89. float bat_val;
  90. adc_val = adc1_get_raw(BATTERY_ADC_CHANNEL);
  91. bat_val = ((float) esp_adc_cal_raw_to_voltage(adc_val, adc_chars)) / 1000;
  92. bat_val = bat_val * ADC_CONSTANT;
  93. if (adc_val < 0)
  94. {
  95. ESP_LOGE("board", "invalid measurement");
  96. bat_val = -1;
  97. }
  98. return bat_val;
  99. }
  100. void battery_monitor_task(void *para)
  101. {
  102. int32_t adc_val;
  103. float bat_val, avg_bat_val;
  104. uint32_t cycle_count;
  105. // take 1st measurement
  106. bat_val = battery_measure();
  107. avg_bat_val = bat_val;
  108. // measure the battery every X seconds
  109. // if the battery voltage is <3.4V flash the
  110. // RX LED every 1 second
  111. // TODO: This is hella ghetto and likely will cause more issues
  112. // than it is worth.
  113. while(1)
  114. {
  115. if (avg_bat_val >= 3.4)
  116. {
  117. vTaskDelay(10000 / portTICK_PERIOD_MS);
  118. }
  119. else
  120. {
  121. disable_red_led();
  122. for(cycle_count=0;cycle_count<10;cycle_count++)
  123. {
  124. enable_red_led();
  125. vTaskDelay(250 / portTICK_PERIOD_MS);
  126. disable_red_led();
  127. vTaskDelay(740 / portTICK_PERIOD_MS);
  128. }
  129. enable_red_led();
  130. }
  131. bat_val = battery_measure();
  132. avg_bat_val = avg_bat_val*0.9 + bat_val*0.1;
  133. }
  134. }
  135. void board_init(void)
  136. {
  137. ESP_LOGI("board", "LED, debugging, and ADC initialization");
  138. // setup LED IO
  139. gpio_config_t led_pin_config =
  140. {
  141. .pin_bit_mask = (uint64_t) (BIT64(RED_LED)|BIT64(GREEN_LED)),
  142. .mode = GPIO_MODE_OUTPUT,
  143. .pull_up_en = GPIO_PULLUP_DISABLE,
  144. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  145. .intr_type = GPIO_INTR_DISABLE
  146. };
  147. gpio_config(&led_pin_config);
  148. // setup debugging IO
  149. gpio_config_t debug_pin_config =
  150. {
  151. .pin_bit_mask = (uint64_t) (BIT64(DEBUG_0)|BIT64(DEBUG_1)|BIT64(DEBUG_2)|BIT64(DEBUG_3)),
  152. .mode = GPIO_MODE_OUTPUT,
  153. .pull_up_en = GPIO_PULLUP_DISABLE,
  154. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  155. .intr_type = GPIO_INTR_DISABLE
  156. };
  157. gpio_config(&debug_pin_config);
  158. // setup ADC pins
  159. /* gpio_config_t adc_pin_config =
  160. {
  161. .pin_bit_mask = (uint64_t) (BIT64(ENABLE_VOLTAGE_DIVIDER)),
  162. .mode = GPIO_MODE_OUTPUT,
  163. .pull_up_en = GPIO_PULLUP_DISABLE,
  164. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  165. .intr_type = GPIO_INTR_DISABLE
  166. };
  167. gpio_config(&adc_pin_config);*/
  168. // check if ADC calibration is stored
  169. check_efuse();
  170. // configure ADC
  171. adc1_config_width(ADC_WIDTH_BIT_12);
  172. adc1_config_channel_atten(BATTERY_ADC_CHANNEL,ADC_ATTEN_DB_0);
  173. // attempt to load calibraiton information
  174. adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
  175. esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_0, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars);
  176. print_char_val_type(val_type);
  177. }