#include "stm32c0xx_hal.h"

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

// Debounce delay
#define DEBOUNCE_DELAY_MS 50  // Debounce delay in milliseconds

// Counter variable
volatile uint8_t counter = 0;  // 3-bit counter
volatile uint32_t last_interrupt_time = 0;  // Last interrupt time in milliseconds

/* 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();

    // Infinite loop
    while (1) {
        // No additional logic needed in the main loop, everything is handled in interrupts
    }
}

/* USER CODE BEGIN 4 */
// External interrupt handler
void HAL_GPIO_EXTI_Callback_1(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_13) {  // Check for push button on PB13
        uint32_t current_time = HAL_GetTick();
        if ((current_time - last_interrupt_time) > DEBOUNCE_DELAY_MS) {
            last_interrupt_time = current_time;  // Update last interrupt time
            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 and GPIOB clock
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();

    // Configure GPIO pins: PA5, PA6, PA7 for LEDs
    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);

    // Configure GPIO pin: PB13 for the button
    GPIO_InitStruct.Pin = GPIO_PIN_13;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; // Interrupt on rising and falling edge
    GPIO_InitStruct.Pull = GPIO_NOPULL;                  // No pull-up or pull-down
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    // Enable and set EXTI line 13 interrupt to the lowest priority
    HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);  // Use EXTI4_15_IRQn for PB13
    HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}

// System Clock Configuration (Implement this based on your requirements)
void SystemClock_Config(void) {
    // Implement your clock configuration here (if needed)
}