/*
Домашнее задание №2. (Светофор на STM32)
Использована версия C031C6, т.к.  F103, рекомендуемая преподователем
недоступна на WOKWI*
Другие симуляторы закрыты из-за санкций на текущий момент.

Задание:
Сделать “светофор” на трех светодиодах: красный, желтый, зеленый

-Светофор работает в строгой последовательности цветов сигналов
1. Зеленый сигнал — разрешает движение в данном направлении.
2. Зеленый мигающий сигнал 3 раза — разрешает движение и предупреждает,
что будет смена сигнала.
3. Желтый сигнал — запрещает движение и предупреждает,
что будет красный сигнал.
4. Красный сигнал — запрещает движение в данном направлении
-Добавить кнопку перехода пешехода в светофор

Алгоритм работы:

1. Пешеход нажимает кнопку.
2. Через определенное программно время (например, 5 сек) светофор
для машин переходит в режим мигающий зеленый 3 раза.
3. Красный для перехода пешеходов горит строго определенное время,
сколько бы раз кнопку не нажимали
4. После "зеленого" с установленным временем задержки (5 сек)
происходит разрешение нажатия кнопки (до этого кнопка не реагирует).

*Светофор готов к новому циклу. *

{}Включение светодиода по команде с консоли{*}

-Из заданий 2 и 4, рассмотренных на семинаре, синтезируем код,с помощью которого можно будет управлять состоянием светодиода.
Необходимые компоненты: STM32, резистор, светодиод, макетная плата.
-Соберите цепи из указанных компонентов и напишите данный код. 
Запустите serial monitor.
Введите с клавиатуры «1», светодиод загорится зеленый.
При вводе «0» зеленый светодиод потухнет.
Можно сделать для разных светодиодов.
*/

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stm32c0xx_hal.h>


// Конфигурация портов светодиодов
#define LED_RED     GPIO_PIN_5
#define LED_YELLOW  GPIO_PIN_6
#define LED_GREEN   GPIO_PIN_7

#define BUTTON      GPIO_PIN_13

// Тайм-ауты для светодиодов
#define TIMEOUT_RED      3000
#define TIMEOUT_YEL      1690
#define TIMEOUT_GREEN    2000
#define TIMEOUT_FLASH_GREEN  500

// Глобальные переменные
static GPIO_TypeDef *ledPorts[3] = {GPIOB, GPIOB, GPIOB};
static uint16_t ledPins[3] = {LED_RED, LED_YELLOW, LED_GREEN};
volatile static bool buttonPressed = false;

void systickDelayMS(uint32_t ms)
{
    uint32_t start = HAL_GetTick();
    while (HAL_GetTick() - start < ms);
}

void setup()
{
    GPIO_InitTypeDef gpioInitStruct;

    // Инициализация тайм-аутов
    systickDelayMS(2000);

    // Инициализация портов GPIO
    for (uint8_t i = 0; i < 3; i++)
    {
        gpioInitStruct.Pin = ledPins[i];
        gpioInitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        gpioInitStruct.Pull = GPIO_NOPULL;
        gpioInitStruct.Speed = GPIO_SPEED_FREQ_LOW;
        HAL_GPIO_Init(ledPorts[i], &gpioInitStruct);
    }

    // Инициализация всех светодиодов отключенными
    HAL_GPIO_WritePin(ledPorts[0], ledPins[0], GPIO_PIN_RESET);
    HAL_GPIO_WritePin(ledPorts[1], ledPins[1], GPIO_PIN_RESET);
    HAL_GPIO_WritePin(ledPorts[2], ledPins[2], GPIO_PIN_RESET);

    // Инициализация кнопки
    gpioInitStruct.Pin = BUTTON;
    gpioInitStruct.Mode = GPIO_MODE_IT_RISING;
    gpioInitStruct.Pull = GPIO_PULLDOWN;
    gpioInitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOC, &gpioInitStruct);

     // Установка прерывания кнопки
    HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(SPI1_IRQn);
}

void GPIOC_IRQHandler(void)
{
    if (__HAL_GPIO_EXTI_GET_FLAG(BUTTON) != RESET)
    {
        __HAL_GPIO_EXTI_CLEAR_FLAG(BUTTON);
        buttonPressed = true;
    }
}

void loop()
{
    // Включить зеленый светодиод
    HAL_GPIO_WritePin(ledPorts[2], ledPins[2], GPIO_PIN_SET);
    systickDelayMS(TIMEOUT_GREEN);

  if(buttonPressed)
  {
    // Мигать зеленым светодиодом 3 раза
    for (int i = 0; i < 3; i++)
    {
        HAL_GPIO_WritePin(ledPorts[2], ledPins[2], GPIO_PIN_RESET);
        systickDelayMS(TIMEOUT_FLASH_GREEN);
        HAL_GPIO_WritePin(ledPorts[2], ledPins[2], GPIO_PIN_SET);
        systickDelayMS(TIMEOUT_FLASH_GREEN);

        buttonPressed = false;
    }
  }
    // Включить желтый светодиод
    HAL_GPIO_WritePin(ledPorts[1], ledPins[1], GPIO_PIN_SET);
    systickDelayMS(TIMEOUT_YEL);

    // Отключить желтый светодиод
    HAL_GPIO_WritePin(ledPorts[1], ledPins[1], GPIO_PIN_RESET);

    // Включить красный светодиод
    HAL_GPIO_WritePin(ledPorts[0], ledPins[0], GPIO_PIN_SET);
    systickDelayMS(TIMEOUT_RED);

    // Включить желтый светодиод
    HAL_GPIO_WritePin(ledPorts[1], ledPins[1], GPIO_PIN_SET);
    systickDelayMS(TIMEOUT_YEL);

    // Отключить желтый и красный светодиоды
    HAL_GPIO_WritePin(ledPorts[1], ledPins[1], GPIO_PIN_RESET);
    HAL_GPIO_WritePin(ledPorts[0], ledPins[0], GPIO_PIN_RESET);

}

int main(void)
{
    HAL_Init();
    SystemCoreClockUpdate();

    setup();

    while (1)
    {
        loop();
    }

    return 0;
}
$abcdeabcde151015202530fghijfghij