#include "stm32c0xx_hal.h"

// Function prototypes
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);

// Timer handle declaration
TIM_HandleTypeDef htim1;

// Counter variable
volatile uint8_t counter = 0;  // 3-bit counter

/* USER CODE BEGIN 0 */
void increment_counter(void) {
    counter = (counter + 1) % 8;  // Increment counter and wrap around using modulo
    // Set LED states based on counter value
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, (counter & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET);  // LD1 (LSB)
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, (counter & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET);  // LD2
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, (counter & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET);  // LD3 (MSB)
}
/* USER CODE END 0 */

int main(void) {
    // Initialize the HAL Library
    HAL_Init();

    // Configure the system clock
    SystemClock_Config();

    // Initialize GPIOs
    MX_GPIO_Init();

    // Initialize Timer
    MX_TIM1_Init();

    // Start timer in interrupt mode
    HAL_TIM_Base_Start_IT(&htim1);

    /* USER CODE BEGIN WHILE */
    while (1) {
        // Main loop can perform other tasks or go to sleep
        // Here, we can use a low-power mode if required
    }
    /* USER CODE END WHILE */
}

/* USER CODE BEGIN 4 */
// Timer interrupt callback
void HAL_TIM_PeriodElapsedCallback_1(TIM_HandleTypeDef *htim) {
    if (htim->Instance == TIM1) {
        increment_counter();  // Update LED states based on counter value
    }
}
/* USER CODE END 4 */

// GPIO initialization function
static void MX_GPIO_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // Enable GPIOA clock
    __HAL_RCC_GPIOA_CLK_ENABLE();

    // Configure GPIO pins: PA5, PA6, PA7
    GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // Push-pull output
    GPIO_InitStruct.Pull = GPIO_NOPULL;         // No pull-up or pull-down
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // Low speed
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

// Timer initialization function
static void MX_TIM1_Init(void) {
    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};

    // Enable TIM1 clock
    __HAL_RCC_TIM1_CLK_ENABLE();

    // Configure TIM1
    htim1.Instance = TIM1;
    htim1.Init.Prescaler = 8000 - 1; // Assuming 8 MHz clock, prescaler gives 1 kHz
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim1.Init.Period = 1000 - 1; // 1000 counts = 1 second
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    HAL_TIM_Base_Init(&htim1);

    // Configure the clock source
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig);

    // Configure master
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);
}

// System Clock Configuration (You may need to adjust this based on your specific requirements)
void SystemClock_Config(void) {
    // Implement your clock configuration here (if needed)
}