170 lines
4.7 KiB
C
170 lines
4.7 KiB
C
#include "driver/i2c.h"
|
|
#include "esp_log.h"
|
|
#include "display.h"
|
|
|
|
#define DISP_ADDR 0x70
|
|
#define I2C_PORT I2C_NUM_0
|
|
|
|
const char *TAG = "DISPLAY";
|
|
|
|
|
|
// ------------------------------
|
|
// DISPLAY INIT
|
|
// ------------------------------
|
|
void display_init(void)
|
|
{
|
|
uint8_t cmd1 = 0x21; // oscillator ON
|
|
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd1, 1, 20 / portTICK_PERIOD_MS);
|
|
|
|
uint8_t cmd2 = 0x81; // display ON, blink OFF
|
|
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd2, 1, 20 / portTICK_PERIOD_MS);
|
|
|
|
uint8_t cmd3 = 0xEF; // brightness
|
|
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd3, 1, 20 / portTICK_PERIOD_MS);
|
|
|
|
display_clear();
|
|
}
|
|
|
|
// ------------------------------
|
|
// CLEAR DISPLAY
|
|
// ------------------------------
|
|
void display_clear(void)
|
|
{
|
|
uint8_t buf[17] = {0};
|
|
buf[0] = 0x00;
|
|
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, buf, sizeof(buf), 20 / portTICK_PERIOD_MS);
|
|
}
|
|
|
|
// --------------------------------------------------------
|
|
// RAW WRITE — 14 segmentos (cada dígito = 16 bits)
|
|
// --------------------------------------------------------
|
|
void display_raw(int pos, uint16_t mask)
|
|
{
|
|
if (pos < 0 || pos > 3) return;
|
|
|
|
uint8_t buf[3];
|
|
buf[0] = pos * 2;
|
|
buf[1] = mask & 0xFF;
|
|
buf[2] = (mask >> 8) & 0xFF;
|
|
|
|
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, buf, 3, 20 / portTICK_PERIOD_MS);
|
|
}
|
|
|
|
// --------------------------------------------------------
|
|
// Tabela alfanumérica 14 segmentos
|
|
// (corrigido: H com os 2 segmentos horizontais g1/g2)
|
|
// --------------------------------------------------------
|
|
static uint16_t charset(char c)
|
|
{
|
|
switch (c)
|
|
{
|
|
case '0': return 0b0000000000111111;
|
|
case '1': return 0b0000000000000110;
|
|
case '2': return 0b0000000001011011;
|
|
case '3': return 0b0000000001001111;
|
|
case '4': return 0b0000000001100110;
|
|
case '5': return 0b0000000001101101;
|
|
case '6': return 0b0000000001111101;
|
|
case '7': return 0b0000000000000111;
|
|
case '8': return 0b0000000001111111;
|
|
case '9': return 0b0000000001101111;
|
|
|
|
// Letras principais
|
|
case 'A': case 'a': return 0b0000000001110111;
|
|
case 'B': case 'b': return 0b0001000011111100;
|
|
case 'C': case 'c': return 0b0000000000111001;
|
|
case 'D': case 'd': return 0b0001000011011110;
|
|
case 'E': case 'e': return 0b0000000001111001;
|
|
case 'F': case 'f': return 0b0000000001110001;
|
|
|
|
// CORRIGIDO → H com g1 + g2
|
|
case 'H': case 'h': return
|
|
(1<<5) | // f
|
|
(1<<4) | // e
|
|
(1<<1) | // b
|
|
(1<<2) | // c
|
|
(1<<6) | // g1
|
|
(1<<7); // g2
|
|
|
|
case 'I': case 'i': return 0b0001000000000000 | 0b0000000000000110;
|
|
case 'L': case 'l': return 0b0000000000111000;
|
|
case 'O': case 'o': return 0b0001000010011100;
|
|
case 'P': case 'p': return 0b0000000001110011;
|
|
case 'S': case 's': return 0b0000000001101101;
|
|
case 'U': case 'u': return 0b0000000000011100;
|
|
|
|
case '-': return 0b0000000001000000;
|
|
case ' ': return 0;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------
|
|
// display_char()
|
|
// --------------------------------------------------------
|
|
void display_char(int pos, char c)
|
|
{
|
|
uint16_t mask = charset(c);
|
|
display_raw(pos, mask);
|
|
}
|
|
|
|
// --------------------------------------------------------
|
|
// display_text() (4 caracteres)
|
|
// --------------------------------------------------------
|
|
void display_text(const char *txt)
|
|
{
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
char c = txt[i];
|
|
if (c == 0) c = ' ';
|
|
display_char(i, c);
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------
|
|
// display_number()
|
|
// Mantida para compatibilidade com 7-segment
|
|
// --------------------------------------------------------
|
|
void display_digit(int pos, uint8_t val)
|
|
{
|
|
static const uint8_t seg7[10] = {
|
|
0b00111111,
|
|
0b00000110,
|
|
0b01011011,
|
|
0b01001111,
|
|
0b01100110,
|
|
0b01101101,
|
|
0b01111101,
|
|
0b00000111,
|
|
0b01111111,
|
|
0b01101111
|
|
};
|
|
|
|
if (val > 9) val = 0;
|
|
|
|
display_raw(pos, seg7[val]);
|
|
}
|
|
|
|
void display_number(int num)
|
|
{
|
|
if (num < 0) num = 0;
|
|
if (num > 9999) num = 9999;
|
|
|
|
display_digit(3, num % 10);
|
|
display_digit(2, (num / 10) % 10);
|
|
display_digit(1, (num / 100) % 10);
|
|
display_digit(0, (num / 1000) % 10);
|
|
}
|
|
void display_set_time(int horas, int minutos)
|
|
{
|
|
if (horas < 0) horas = 0;
|
|
if (horas > 99) horas = 99;
|
|
if (minutos < 0) minutos = 0;
|
|
if (minutos > 99) minutos = 99;
|
|
|
|
int num = horas * 100 + minutos;
|
|
display_number(num);
|
|
}
|