#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"

#define I2C_PORT i2c0
#define KHZ 1000
#define CLOCK 100 * KHZ
#define I2C_SDA_PIN 4
#define I2C_SCL_PIN 5
#define DS1307_ADDR 0x68  // Endereço I2C do RTC DS1307

// Definições das funções
void set_rtc_time(uint8_t year, uint8_t month, uint8_t day, uint8_t weekday, uint8_t hour, uint8_t minute, uint8_t second);
void read_rtc_time(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *weekday, uint8_t *hour, uint8_t *minute, uint8_t *second);
void i2c_config();
uint8_t decimal_to_bcd(uint8_t decimal);
uint8_t bcd_to_dec(uint8_t bcd);

int main() {
    
    stdio_init_all();  // Inicializa a comunicação serial
    i2c_config();
    set_rtc_time(24,9,24,3,13,27,0); // Configuração do I2C
    
    uint8_t year, month, day, weekday, hour, minute, second;


    while (1) {
        read_rtc_time(&year,&month,&day,&weekday,&hour,&minute,&second);
        printf("A data e hora atual é: %02d\\%02d\\%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second);
        sleep_ms(5000);
    }

    return 0;
}

void read_rtc_time(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *weekday, uint8_t *hour, uint8_t *minute, uint8_t *second) {
    uint8_t reg = 0x00;              // Registro inicial
    uint8_t datetime[7];             // Array para armazenar os dados de tempo

    i2c_write_blocking(I2C_PORT, DS1307_ADDR, &reg, 1, true);  // Solicita dados
    i2c_read_blocking(I2C_PORT, DS1307_ADDR, datetime, 7, false); // Lê os dados de tempo

    *second = bcd_to_dec(datetime[0]);  // Converte segundos
    *minute = bcd_to_dec(datetime[1]);  // Converte minutos
    *hour   = bcd_to_dec(datetime[2]);  // Converte horas
    *weekday = bcd_to_dec(datetime[3]); // Converte dia da semana
    *day     = bcd_to_dec(datetime[4]);  // Converte dia do mês
    *month   = bcd_to_dec(datetime[5]);  // Converte mês
    *year    = bcd_to_dec(datetime[6]);  // Converte ano
}

void i2c_config(){
    // Configuração do I2C
    
    i2c_init(I2C_PORT, CLOCK);
    gpio_set_function(I2C_SDA_PIN, GPIO_FUNC_I2C);
    gpio_set_function(I2C_SCL_PIN, GPIO_FUNC_I2C);
    gpio_pull_up(I2C_SDA_PIN);
    gpio_pull_up(I2C_SCL_PIN);

}

void set_rtc_time(uint8_t year, uint8_t month, uint8_t day, uint8_t weekday, uint8_t hour, uint8_t minute, uint8_t second) {
    uint8_t datetime[] = {
        0x00,                        // Inicia configuração
        decimal_to_bcd(second),      // Segundos
        decimal_to_bcd(minute),      // Minutos
        decimal_to_bcd(hour),        // Horas
        decimal_to_bcd(weekday),     // Dia da semana
        decimal_to_bcd(day),         // Dia do mês
        decimal_to_bcd(month),       // Mês
        decimal_to_bcd(year)         // Ano (últimos dois dígitos)
    };
    i2c_write_blocking(I2C_PORT, DS1307_ADDR, datetime, 8, false); // Envia os dados para o RTC
}

// Função para converter decimal para BCD
uint8_t decimal_to_bcd(uint8_t decimal) {
    return ((decimal / 10) << 4) | (decimal % 10);
}

uint8_t bcd_to_dec(uint8_t bcd)
{
    // Converte BCD para decimal
    return ((bcd / 16) * 10) + (bcd % 16);
}

GND5VSDASCLSQWRTCDS1307+