/* * board.c * * Created on: Jun 15, 2019 * Author: curiousmuch */ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "driver/adc.h" #include "esp_adc_cal.h" #include "esp_log.h" #include "board.h" // Debugging IO Functions inline void IRAM_ATTR enable_debug_IO(uint32_t io_num) { gpio_set_level(io_num, 1); } inline void IRAM_ATTR disable_debug_IO(uint32_t io_num) { gpio_set_level(io_num, 0); } // Red LED Functions void enable_red_led(void) { gpio_set_level(RED_LED, 1); } void disable_red_led(void) { gpio_set_level(RED_LED, 0); } // Green LED Functions void enable_green_led(void) { gpio_set_level(GREEN_LED, 1); } void disable_green_led(void) { gpio_set_level(GREEN_LED, 0); } // ADC Functions #define DEFAULT_VREF 1100 // units in mV static esp_adc_cal_characteristics_t *adc_chars; #define ADC_CONSTANT (100) / (100 + 350) void enable_voltage_divider(void) { gpio_set_level(ENABLE_VOLTAGE_DIVIDER, 0); } void disable_voltage_divider(void) { // TODO: set to Hi-Z instead gpio_set_level(ENABLE_VOLTAGE_DIVIDER, 1); } static void check_efuse(void) { // check TP is burned into eFuse if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) { ESP_LOGI("board", "eFuse two point: supported"); } else { ESP_LOGW("board", "eFuse two point: NOT supported"); } // check Vref is burned into eFuse if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) { ESP_LOGI("board", "eFuse Vref: supported"); } else { ESP_LOGW("board", "eFuse Vref: NOT supported"); } } static void print_char_val_type(esp_adc_cal_value_t val_type) { if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { ESP_LOGI("board", "characterized using two point value"); } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { ESP_LOGI("board", "characterized using eFuse Vref"); } else { ESP_LOGW("board", "characterized using default Vref"); } } int32_t battery_measure(void) { int32_t adc_val; float bat_val; adc_val = adc1_get_raw(BATTERY_ADC_CHANNEL); bat_val = ((float) esp_adc_cal_raw_to_voltage(adc_val, adc_chars)) / 1000; bat_val = bat_val * ADC_CONSTANT; if (adc_val < 0) { ESP_LOGE("board", "invalid measurement"); bat_val = -1; } return bat_val; } void battery_monitor_task(void *para) { int32_t adc_val; float bat_val, avg_bat_val; uint32_t cycle_count; // take 1st measurement bat_val = battery_measure(); avg_bat_val = bat_val; // measure the battery every X seconds // if the battery voltage is <3.4V flash the // RX LED every 1 second // TODO: This is hella ghetto and likely will cause more issues // than it is worth. while(1) { if (avg_bat_val >= 3.4) { vTaskDelay(10000 / portTICK_PERIOD_MS); } else { disable_red_led(); for(cycle_count=0;cycle_count<10;cycle_count++) { enable_red_led(); vTaskDelay(250 / portTICK_PERIOD_MS); disable_red_led(); vTaskDelay(740 / portTICK_PERIOD_MS); } enable_red_led(); } bat_val = battery_measure(); avg_bat_val = avg_bat_val*0.9 + bat_val*0.1; } } void board_init(void) { ESP_LOGI("board", "LED, debugging, and ADC initialization"); // setup LED IO gpio_config_t led_pin_config = { .pin_bit_mask = (uint64_t) (BIT64(RED_LED)|BIT64(GREEN_LED)), .mode = GPIO_MODE_OUTPUT, .pull_up_en = GPIO_PULLUP_DISABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE }; gpio_config(&led_pin_config); // setup debugging IO gpio_config_t debug_pin_config = { .pin_bit_mask = (uint64_t) (BIT64(DEBUG_0)|BIT64(DEBUG_1)|BIT64(DEBUG_2)|BIT64(DEBUG_3)), .mode = GPIO_MODE_OUTPUT, .pull_up_en = GPIO_PULLUP_DISABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE }; gpio_config(&debug_pin_config); // setup ADC pins /* gpio_config_t adc_pin_config = { .pin_bit_mask = (uint64_t) (BIT64(ENABLE_VOLTAGE_DIVIDER)), .mode = GPIO_MODE_OUTPUT, .pull_up_en = GPIO_PULLUP_DISABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE }; gpio_config(&adc_pin_config);*/ // check if ADC calibration is stored check_efuse(); // configure ADC adc1_config_width(ADC_WIDTH_BIT_12); adc1_config_channel_atten(BATTERY_ADC_CHANNEL,ADC_ATTEN_DB_0); // attempt to load calibraiton information adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t)); 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); print_char_val_type(val_type); }