/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2024 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #define CYCLE_LENGTH 5000 /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ enum MODES { ALL_PWM = 0, SEQUENTIAL_GLOWING = 1, SEQUENTIAL_SINGLE_PWM = 2, SEQUENTIAL_DOUBLE_PWM = 3, SEQUENTIAL_TRIPLE_PWM = 4, PAIRED_BLINKING_WITH_PAIRED_GLOWING = 5, PAIRED_BLINKING = 6, STANDBY = 7, }; unsigned int current_mode = 0; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ static void paired_blinking(void) { HAL_GPIO_WritePin(GPIOD, 0xF000, GPIO_PIN_RESET); for (unsigned int j = 0; j < 2; j++) { for (unsigned int i = 0; i < 2; i++) { HAL_GPIO_WritePin(GPIOD, LED_BLUE_Pin | LED_YELLOW_Pin, GPIO_PIN_SET); HAL_Delay(90); HAL_GPIO_WritePin(GPIOD, LED_BLUE_Pin | LED_YELLOW_Pin, GPIO_PIN_RESET); HAL_Delay(90); } for (unsigned int i = 0; i < 2; i++) { HAL_GPIO_WritePin(GPIOD, LED_RED_Pin | LED_GREEN_Pin, GPIO_PIN_SET); HAL_Delay(90); HAL_GPIO_WritePin(GPIOD, LED_RED_Pin | LED_GREEN_Pin, GPIO_PIN_RESET); HAL_Delay(90); } } } static void paired_glowing(void) { for (unsigned int i = 0; i < 4; i++) { HAL_GPIO_WritePin(GPIOD, LED_BLUE_Pin | LED_GREEN_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD, LED_YELLOW_Pin | LED_RED_Pin, GPIO_PIN_RESET); HAL_Delay(180); HAL_GPIO_WritePin(GPIOD, LED_YELLOW_Pin | LED_RED_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD, LED_BLUE_Pin | LED_GREEN_Pin, GPIO_PIN_RESET); HAL_Delay(180); } } static void paired_blinking_with_paired_glowing(void) { paired_blinking(); paired_glowing(); } static void pwm_leds_single(uint16_t leds, unsigned int step) { int brightness = 0; while (brightness <= CYCLE_LENGTH) { HAL_GPIO_WritePin(GPIOD, leds, GPIO_PIN_SET); for (int j = 0; j < brightness; j++) { asm("nop"); } HAL_GPIO_WritePin(GPIOD, leds, GPIO_PIN_RESET); for (int j = 0; j < CYCLE_LENGTH - brightness; j++) { asm("nop"); } brightness += step; } while (brightness >= 0) { HAL_GPIO_WritePin(GPIOD, leds, GPIO_PIN_SET); for (int j = 0; j < brightness; j++) { asm("nop"); } HAL_GPIO_WritePin(GPIOD, leds, GPIO_PIN_RESET); for (int j = 0; j < CYCLE_LENGTH - brightness; j++) { asm("nop"); } brightness -= step; } } static void pwm_leds_chain(uint16_t leds_on, uint16_t leds_off, unsigned int step) { int PWM_HALF_CYCLE = (CYCLE_LENGTH >> 1); int on_brightness = 0; // leds_on 0 -> on_brightness // leds_off 0 -> CYCLE_LENGTH - on_brightness // On this stage DUTY_ON is longer for leds_off: while (on_brightness <= PWM_HALF_CYCLE) { HAL_GPIO_WritePin(GPIOD, leds_on | leds_off, GPIO_PIN_SET); for (int j = 0; j < on_brightness; j++) { asm("nop"); } HAL_GPIO_WritePin(GPIOD, leds_on, GPIO_PIN_RESET); for (int j = on_brightness; j < (CYCLE_LENGTH - on_brightness); j++) { asm("nop"); } HAL_GPIO_WritePin(GPIOD, leds_off, GPIO_PIN_RESET); for (int j = CYCLE_LENGTH - on_brightness; j < CYCLE_LENGTH; j++) { asm("nop"); } on_brightness += step; } // clamp to half the pwm cycle duration on_brightness = PWM_HALF_CYCLE; // On this stage DUTY_ON is longer for leds_on: while (on_brightness >= 0) { HAL_GPIO_WritePin(GPIOD, leds_on | leds_off, GPIO_PIN_SET); for (int j = 0; j < on_brightness; j++) { asm("nop"); } HAL_GPIO_WritePin(GPIOD, leds_off, GPIO_PIN_RESET); for (int j = on_brightness; j < (CYCLE_LENGTH - on_brightness); j++) { asm("nop"); } HAL_GPIO_WritePin(GPIOD, leds_on, GPIO_PIN_RESET); for (int j = CYCLE_LENGTH - on_brightness; j < CYCLE_LENGTH; j++) { asm("nop"); } on_brightness -= step; } // leave required LEDs on for better chaining effect HAL_GPIO_WritePin(GPIOD, leds_on, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD, leds_off, GPIO_PIN_RESET); } static void update_state_counter(unsigned int* current_mode, unsigned int* last_mode, unsigned int* current_state) { if (*current_mode != *last_mode) { *last_mode = *current_mode; *current_state = 0; HAL_GPIO_WritePin(GPIOD, LED_RED_Pin | LED_GREEN_Pin | LED_BLUE_Pin | LED_YELLOW_Pin, GPIO_PIN_RESET); } else { *current_state += 1; *current_state &= 0x3; } } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ unsigned int current_state = 0; unsigned int last_mode = current_mode; while (1) { switch (current_mode) { case ALL_PWM: //pwm_leds_single(LED_RED_Pin | LED_YELLOW_Pin | LED_GREEN_Pin | LED_BLUE_Pin, 20); pwm_leds_chain(LED_RED_Pin | LED_GREEN_Pin, LED_BLUE_Pin | LED_YELLOW_Pin, 140); pwm_leds_chain(LED_BLUE_Pin | LED_YELLOW_Pin, LED_RED_Pin | LED_GREEN_Pin, 140); break; case SEQUENTIAL_GLOWING: update_state_counter(¤t_mode, &last_mode, ¤t_state); switch (current_state) { case 0: HAL_GPIO_WritePin(GPIOD, LED_BLUE_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD, LED_GREEN_Pin, GPIO_PIN_RESET); break; case 1: HAL_GPIO_WritePin(GPIOD, LED_RED_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD, LED_BLUE_Pin, GPIO_PIN_RESET); break; case 2: HAL_GPIO_WritePin(GPIOD, LED_YELLOW_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD, LED_RED_Pin, GPIO_PIN_RESET); break; case 3: HAL_GPIO_WritePin(GPIOD, LED_GREEN_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD, LED_YELLOW_Pin, GPIO_PIN_RESET); break; } HAL_Delay(2000); break; case SEQUENTIAL_SINGLE_PWM: update_state_counter(¤t_mode, &last_mode, ¤t_state); switch (current_state) { case 0: pwm_leds_single(LED_BLUE_Pin, 10); break; case 1: pwm_leds_single(LED_RED_Pin, 10); break; case 2: pwm_leds_single(LED_YELLOW_Pin, 10); break; case 3: pwm_leds_single(LED_GREEN_Pin, 10); break; } HAL_Delay(1000); break; case SEQUENTIAL_DOUBLE_PWM: update_state_counter(¤t_mode, &last_mode, ¤t_state); switch (current_state) { case 0: pwm_leds_chain(LED_RED_Pin, LED_BLUE_Pin, 10); break; case 1: pwm_leds_chain(LED_YELLOW_Pin, LED_RED_Pin, 10); break; case 2: pwm_leds_chain(LED_GREEN_Pin, LED_YELLOW_Pin, 10); break; case 3: pwm_leds_chain(LED_BLUE_Pin, LED_GREEN_Pin, 10); break; } HAL_Delay(2000); break; case SEQUENTIAL_TRIPLE_PWM: update_state_counter(¤t_mode, &last_mode, ¤t_state); switch (current_state) { case 0: pwm_leds_chain(LED_YELLOW_Pin, LED_BLUE_Pin, 20); break; case 1: pwm_leds_chain(LED_GREEN_Pin, LED_RED_Pin, 20); break; case 2: pwm_leds_chain(LED_BLUE_Pin, LED_YELLOW_Pin, 20); break; case 3: pwm_leds_chain(LED_RED_Pin, LED_GREEN_Pin, 20); break; } break; case PAIRED_BLINKING_WITH_PAIRED_GLOWING: paired_blinking_with_paired_glowing(); break; case PAIRED_BLINKING: paired_blinking(); break; case STANDBY: HAL_GPIO_WritePin(GPIOD, 0xF000, 1); break; } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* USER CODE BEGIN MX_GPIO_Init_1 */ /* USER CODE END MX_GPIO_Init_1 */ /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOD, LED_GREEN_Pin|LED_YELLOW_Pin|LED_RED_Pin|LED_BLUE_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : PA0 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pins : LED_GREEN_Pin LED_YELLOW_Pin LED_RED_Pin LED_BLUE_Pin */ GPIO_InitStruct.Pin = LED_GREEN_Pin|LED_YELLOW_Pin|LED_RED_Pin|LED_BLUE_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /* EXTI interrupt init*/ HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); /* USER CODE BEGIN MX_GPIO_Init_2 */ /* USER CODE END MX_GPIO_Init_2 */ } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */