smart_alarm/display.cpp
2025-09-20 18:09:58 +02:00

152 lines
3.9 KiB
C++

#include "display.h"
#include <array>
#include "GC9A01/VGA1_16x32.h"
#include "gc9a01.h"
#include "hardware/gpio.h"
#include "hardware/spi.h"
#include "hardware/structs/io_bank0.h"
#include "pico/time.h"
#include "spi.h"
#include <cmath>
#include <stdio.h>
#include "Font5x7FixedMono.h"
#include "hardware/rtc.h"
int32_t t_fine;
uint16_t dig_T1;
int16_t dig_T2, dig_T3;
// LCD config
gc9a01_GC9A01_obj_t create_lcd() {
spi_init(SPI_PORT, SPI_CLOCK_HZ); // Use your defined SPI port and clock speed
// Initialize GPIO pins for SPI communication using your definitions
gpio_set_function(PIN_SCK, GPIO_FUNC_SPI); // SCK = 18
gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI); // MOSI = 19
// Note: MISO not needed for display, but if you had one it would be on a
// separate pin
// Configure Chip Select
gpio_init(PIN_CS); // CS = 17
gpio_set_dir(PIN_CS, GPIO_OUT);
gpio_put(PIN_CS, 1); // Set CS High
// Configure Reset pin
gpio_init(PIN_RST); // Reset = 20
gpio_set_dir(PIN_RST, GPIO_OUT);
gpio_put(PIN_RST, 0);
// Configure DC pin
gpio_init(PIN_DC); // DC = 16
gpio_set_dir(PIN_DC, GPIO_OUT);
gpio_put(PIN_DC, 0);
// Note: You don't have a backlight pin defined in spi.h
// If you have a backlight control, define PIN_BL in spi.h
// For now, commenting out backlight control:
/*
gpio_init(PIN_BL);
gpio_set_dir(PIN_BL, GPIO_OUT);
gpio_put(PIN_BL, 0);
*/
gc9a01_GC9A01_obj_t lcd;
lcd.spi_obj = SPI_PORT;
lcd.reset = PIN_RST;
lcd.dc = PIN_DC;
lcd.cs = PIN_CS;
lcd.backlight =
-1; // Set to -1 if no backlight control, or define PIN_BL in spi.h
lcd.xstart = 0;
lcd.ystart = 0;
lcd.display_width = 240;
lcd.display_height = 240;
lcd.rotation = 0;
lcd.buffer_size = 2048;
lcd.i2c_buffer = static_cast<uint16_t *>(malloc(2048));
return lcd;
}
gc9a01_GC9A01_obj_t display;
void draw_ui_circle(uint16_t color)
{
for (int i = 720; i > 0; i--) {
int x = 120 + (int)(119.0 * sin((180.0 + i / 2.0) * M_TWOPI / 360.0));
int y = 120 + (int)(119.0 * cos((180.0 + i / 2.0) * M_TWOPI / 360.0));
gc9a01_draw_pixel(&display, x, y, color);
}
}
std::array<uint16_t,2> get_ui_circle_vertical_pos(uint16_t x, uint16_t center_x, uint16_t center_y, uint16_t radius)
{
// Ctalculate horizontal distance from point to center
uint16_t dx = x - center_x;
uint16_t dx_squared = dx * dx;
uint16_t radius_squared = radius * radius;
// Check if point's x-coordinate is within circle bounds
if (dx_squared >= radius_squared) {
return {0,0}; // Outside circle - no vertical space
}
// Calculate vertical distance from center to circle edge at this x
float vertical_offset = sqrt(radius_squared - dx_squared);
// Find y-coordinates where vertical line intersects circle
uint16_t y_top = center_y - (uint16_t)vertical_offset;
uint16_t y_bottom = center_y + (uint16_t)vertical_offset;
std::array<uint16_t,2> positions ={y_top,y_bottom};
return positions;
}
void clear_display() {
gc9a01_fill(&display, BLACK);
}
void display_start() {
char buf[10];
display = create_lcd();
gc9a01_init(&display);
sleep_ms(100);
clear_display();
draw_ui_circle(MAGENTA);
}
void print_time(const bool force_refresh) {
datetime_t t;
if (rtc_get_datetime(&t)) {
const GFXfont* font = &VGA1_16x32;
char buf[11];
sprintf(buf,"%02d:%02d:%02d", t.hour, t.min, t.sec);
gc9a01_text(&display,font,buf,120-((16*8)/2),120-16,WHITE, BLACK);
static uint8_t last_day = UINT8_MAX;
if (last_day != t.day || force_refresh) {
font = &Font5x7FixedMono;
sprintf(buf,"%02d.%02d.%04d",t.day,t.month,t.year);
gc9a01_text_gfx_buffered(&display,font,buf,120-((6*10)/2),((120-16)+32)+7,WHITE,BLACK);
last_day = t.day;
}
} else {
const char* rtc_fail= "NO SYNC!";
const GFXfont* font = &Font5x7FixedMono;
gc9a01_text_gfx_buffered(&display,font,rtc_fail,120-((5*8)/2),120-((7*1)/2),RED,BLACK);
}
}