#include <SPI.h>
#include <EEPROM.h>

#define CS D10
#define ELEMENT_AMOUNT 6  // 6 for { H, H, M, M, S, S}

// set hardware timer
static HardwareTimer timer2 = HardwareTimer(TIM2);

// set EEPROM addresses
const int SecEepromAddress = 0, MinEepromAddress = 1, HrEepromAddress = 2;

// declare non-const vars
int secs, mins, hrs;
int time_segments[ELEMENT_AMOUNT];

void ISR_Timer2(void) {
  secs++;
  update_clock();
}

void setup() {
  // initialize serial monitor
  Serial.begin(115200);

  // configure chip select
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);

  // configure SPI bus
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV32);
  SPI.setDataMode(SPI_MODE0);

  // call MAX7219 initialization func
  init_MAX7219();

  // call EEPROM initialization func
  init_EEPROM();

  // configure timer
  timer2.setOverflow(1, HERTZ_FORMAT);
  timer2.attachInterrupt(ISR_Timer2);
  timer2.resume();

  Serial.println("Setup done");
}

void loop() {
  // display hours
  send_to_MAX7219(0x01, time_segments[0]);
  send_to_MAX7219(0x02, time_segments[1]);

  // display minutes
  send_to_MAX7219(0x04, time_segments[2]);
  send_to_MAX7219(0x05, time_segments[3]);

  // display seconds
  send_to_MAX7219(0x07, time_segments[4]);
  send_to_MAX7219(0x08, time_segments[5]);
}
void update_clock(void) {
  // clock logic
  if (secs >= 60) {
    secs = 0;
    mins++;
  }
  if (mins >= 60) {
    mins = 0;
    hrs++;
  }
  if (hrs >= 24) {
    hrs = 0;
  }

  // write current time values to EEPROM
  write_time_to_EEPROM();

  // output current time
  char clock_buf[16];
  sprintf(clock_buf, "%02u:%02u:%02u", hrs, mins, secs);
  Serial.println("Updated Clock: " + String(clock_buf));

  // call segment update func
  update_time_segments();
}

void update_time_segments(void) {
  int times[3] = { secs, mins, hrs };

  // split time values into tens and ones and put into array
  for (int i = 0; i < 3; i++) {
    time_segments[2 * i] = times[i] % 10;
    time_segments[2 * i + 1] = times[i] / 10;
  }

  // move elements bitwise so that time is displayed centered
  for (int i = 0; i < ELEMENT_AMOUNT; i++) {
    time_segments[i] = time_segments[i] << 2;
  }
}
void init_MAX7219(void) {
  // configuration
  send_to_MAX7219(0x09, 0x00);  // Decoding off (0xAddr Data)
  send_to_MAX7219(0x0A, 0x08);  // Brightness to intermediate
  send_to_MAX7219(0x0B, 0x07);  // Scan limit = 7
  send_to_MAX7219(0x0C, 0x01);  // Normal operation mode
  send_to_MAX7219(0x0F, 0x0F);  // Enable display test
  send_to_MAX7219(0x0F, 0x00);  // Disable display test
  delay(500);                   // safety delay

  // clear every row
  for (int i = 1; i <= 8; i++) {
    send_to_MAX7219(i, 0x00);
  }

  Serial.println("Initialized MAX7219");
  delay(500); // safety delay
}

// row (of the matrix) includes the MSB,
// column (of the matrix) the LSB
void send_to_MAX7219(unsigned char row, unsigned char column) {
  // write to SPI bus
  digitalWrite(CS, LOW);
  SPI.transfer(row);
  SPI.transfer(column);
  digitalWrite(CS, HIGH);
}
void init_EEPROM(void) {
  EEPROM.begin();
  // if value for seconds, that is read from EEPROM, is invalid
  if (EEPROM.read(SecEepromAddress == -1) || EEPROM.read(SecEepromAddress) >= 60) {
    Serial.println("Read EEPROM values invalid, setting new values");

    // set default time values
    secs = 0;
    mins = 0;
    hrs = 0;

    // write them to EEPROM
    write_time_to_EEPROM();
  } else {
    // else read time values from EEPROM
    Serial.println("EEPROM values valid, copying them");
    secs = EEPROM.read(SecEepromAddress);
    mins = EEPROM.read(MinEepromAddress);
    hrs = EEPROM.read(HrEepromAddress);
  }
}

void write_time_to_EEPROM(void) {
  Serial.println("Writing time values to EEPROM");
  EEPROM.begin();
  EEPROM.write(SecEepromAddress, secs);
  EEPROM.write(MinEepromAddress, mins);
  EEPROM.write(HrEepromAddress, hrs);
  EEPROM.end();
}

why is eeprom not working?