BAT_ADC (GPIO4) sits between two 100k resistors on the switched supply rail, so it reads the cell on battery and ~4.4 V on USB; above 4.25 V is reported as USB power. On battery the caption shows a glyph + percentage from a LiPo OCV table; the menu shows voltage and source. Menu lists now wrap at both ends.
98 lines
3.3 KiB
C
98 lines
3.3 KiB
C
#include "board.h"
|
|
#include "sdkconfig.h"
|
|
#include "driver/gpio.h"
|
|
#include "driver/i2c_master.h"
|
|
#include "esp_log.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
|
|
static const char *TAG = "board";
|
|
|
|
static const board_t tembed = {
|
|
.variant = BOARD_TEMBED, .name = "T-Embed",
|
|
.pwr_en = 46,
|
|
.lcd_mosi = 11, .lcd_miso = -1, .lcd_sclk = 12, .lcd_cs = 10, .lcd_dc = 13, .lcd_rst = 9, .lcd_bl = 15,
|
|
.lcd_bgr = false,
|
|
.enc_a = 2, .enc_b = 1, .enc_btn = 0, .user_key = -1,
|
|
.led_ws2812 = false, .led_clk = 45, .led_data = 42, .led_count = 7,
|
|
.bat_adc = 4,
|
|
.i2c_sda = 18, .i2c_scl = 8,
|
|
.spi_other_cs = {-1, -1, -1},
|
|
};
|
|
|
|
static const board_t tembed_cc1101 = {
|
|
.variant = BOARD_TEMBED_CC1101, .name = "T-Embed CC1101",
|
|
.pwr_en = 15,
|
|
.lcd_mosi = 9, .lcd_miso = 10, .lcd_sclk = 11, .lcd_cs = 41, .lcd_dc = 16, .lcd_rst = -1, .lcd_bl = 21,
|
|
.lcd_bgr = true,
|
|
.enc_a = 4, .enc_b = 5, .enc_btn = 0, .user_key = 6,
|
|
.led_ws2812 = true, .led_clk = -1, .led_data = 14, .led_count = 8,
|
|
.bat_adc = -1,
|
|
.i2c_sda = 8, .i2c_scl = 18,
|
|
.spi_other_cs = {13, 12, 44}, // SD, CC1101, nRF24
|
|
};
|
|
|
|
const board_t *board = &tembed;
|
|
|
|
static void drive_high(int pin)
|
|
{
|
|
if (pin < 0) return;
|
|
gpio_config_t io = {.pin_bit_mask = 1ULL << pin, .mode = GPIO_MODE_OUTPUT};
|
|
gpio_config(&io);
|
|
gpio_set_level(pin, 1);
|
|
}
|
|
|
|
// Probe a list of 7-bit addresses on a temporary I2C bus; true if any ACKs.
|
|
static bool i2c_any_present(int sda, int scl, const uint8_t *addrs, int n)
|
|
{
|
|
i2c_master_bus_config_t cfg = {
|
|
.i2c_port = -1, .sda_io_num = sda, .scl_io_num = scl,
|
|
.clk_source = I2C_CLK_SRC_DEFAULT, .glitch_ignore_cnt = 7,
|
|
.flags.enable_internal_pullup = true,
|
|
};
|
|
i2c_master_bus_handle_t bus;
|
|
if (i2c_new_master_bus(&cfg, &bus) != ESP_OK) return false;
|
|
bool found = false;
|
|
for (int i = 0; i < n && !found; i++) {
|
|
if (i2c_master_probe(bus, addrs[i], 20) == ESP_OK) {
|
|
ESP_LOGI(TAG, "I2C device 0x%02x answered on SDA%d/SCL%d", addrs[i], sda, scl);
|
|
found = true;
|
|
}
|
|
}
|
|
i2c_del_master_bus(bus);
|
|
return found;
|
|
}
|
|
|
|
static const board_t *detect(void)
|
|
{
|
|
#if CONFIG_TEMBED_VARIANT_ORIGINAL
|
|
return &tembed;
|
|
#elif CONFIG_TEMBED_VARIANT_CC1101
|
|
return &tembed_cc1101;
|
|
#else
|
|
// Both boards' power latches are set before probing so the codec is up.
|
|
static const uint8_t cc1101_chips[] = {0x55, 0x6b, 0x24}; // BQ27220, BQ25896, PN532
|
|
static const uint8_t original_chips[] = {0x40, 0x41, 0x42, 0x43}; // ES7210 (AD1/AD0 straps)
|
|
if (i2c_any_present(tembed_cc1101.i2c_sda, tembed_cc1101.i2c_scl, cc1101_chips, sizeof cc1101_chips))
|
|
return &tembed_cc1101;
|
|
if (i2c_any_present(tembed.i2c_sda, tembed.i2c_scl, original_chips, sizeof original_chips))
|
|
return &tembed;
|
|
ESP_LOGW(TAG, "no known I2C device found on either pin map; assuming original T-Embed");
|
|
return &tembed;
|
|
#endif
|
|
}
|
|
|
|
void board_init(void)
|
|
{
|
|
// Power latches of both variants (GPIO46 original, GPIO15 CC1101). Harmless on the
|
|
// other board: GPIO15 is the original's backlight, GPIO46 the CC1101's I2S clock.
|
|
drive_high(tembed.pwr_en);
|
|
drive_high(tembed_cc1101.pwr_en);
|
|
vTaskDelay(pdMS_TO_TICKS(50));
|
|
|
|
board = detect();
|
|
ESP_LOGI(TAG, "board: %s", board->name);
|
|
|
|
for (int i = 0; i < 3; i++) drive_high(board->spi_other_cs[i]);
|
|
}
|