/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.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 version 0
#define user_key  !HAL_GPIO_ReadPin(INKEY_GPIO_Port, INKEY_Pin)
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
void set_light(uint8_t num, uint8_t red, uint8_t green, uint8_t blue);
int initial_check(void);
void set_mycolor(uint8_t  num, uint8_t mycolor);
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint8_t Master = 0;
uint8_t masterSide = 'n';
uint8_t numof_left = 0, numof_right = 0;

uint8_t i2cstate = 0;
uint8_t data_gather_mode = 0;
uint8_t i2cIN[10], i2cOUT[10];

uint8_t send_l[4], send_r[4], reci_l[4], reci_r[4];
uint8_t uartsendL_stat = 1, uartsendR_stat = 1;

uint32_t colors = 0x00000000;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */


/* 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();
  MX_I2C1_Init();
//  MX_USART1_UART_Init();
//  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  Master = 1;


//  set_light(1,1,1,1);
//  set_light(2,1,1,1);
//  set_light(3,1,1,1);
//  set_light(4,1,1,1);
//
//  while(1)
//  {
//	   set_light(1,!HAL_GPIO_ReadPin(INKEY1_GPIO_Port, INKEY1_Pin),0,0);
//	   set_light(2,!HAL_GPIO_ReadPin(INKEY2_GPIO_Port, INKEY2_Pin),0,0);
//	   set_light(3,!HAL_GPIO_ReadPin(INKEY3_GPIO_Port, INKEY3_Pin),0,0);
//	   set_light(4,!HAL_GPIO_ReadPin(INKEY4_GPIO_Port, INKEY4_Pin),0,0);
//  }
    initial_check();

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */



	while (1)
	{
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

			if (HAL_I2C_Slave_Receive(&hi2c1, i2cIN, 4, 600) != HAL_OK)
				i2cstate = 0;
			else if (i2cIN[0] == 's') // setting and init
				{
					data_gather_mode = 0;
					i2cstate = 1;
					colors = (i2cIN[1] << 16) + (i2cIN[2] << 8) + (i2cIN[3]);
					set_mycolor(1, colors >> 20);
					set_mycolor(2, colors >> 16);
					set_mycolor(3, colors >> 12);
					set_mycolor(4, colors >> 8);
					
					i2cIN[0] = 'S';


					i2cIN[0] = 'n';
					i2cOUT[0] = 'S';
					i2cOUT[1] = 0x01;
					i2cOUT[2] = 4;//numof_left + numof_right + 1;
					i2cOUT[3] = 0xfa;
					if (HAL_I2C_Slave_Transmit(&hi2c1,i2cOUT, 4, 100) == HAL_ERROR)
					{
						set_light(1, 1, 1, 0);
					}
				}

			else if (i2cIN[0] == 'd') // data gathering is on
				{
					if (data_gather_mode == 0)
					{
						data_gather_mode = 1;
					}
					
					i2cIN[0] = 'n';
					i2cOUT[0] = 'D';
					i2cOUT[1] = 0x01;
					i2cOUT[2] = 0x00;
					i2cOUT[3] = (!HAL_GPIO_ReadPin(INKEY1_GPIO_Port, INKEY1_Pin) << 3) + 
								(!HAL_GPIO_ReadPin(INKEY2_GPIO_Port, INKEY2_Pin) << 2) + 
								(!HAL_GPIO_ReadPin(INKEY3_GPIO_Port, INKEY3_Pin) << 1) + 
								!HAL_GPIO_ReadPin(INKEY4_GPIO_Port, INKEY4_Pin);


					if (HAL_I2C_Slave_Transmit(&hi2c1,i2cOUT, 4, 100) == HAL_OK)
					{
						i2cstate = 1;
					}
					else
					{
						i2cstate = 0;
					}
				}
				else
					i2cstate = 0;

				////////////////////////////////////////////
				
				if (i2cstate == 0)
				{
					if(send_l[1] == 4) 
					{
						send_l[1] = 0;
						
					}
					else 
					{
						send_l[1] = 4;
					}
					set_mycolor(1, send_l[1]);set_mycolor(2, send_l[1]);set_mycolor(3, send_l[1]);set_mycolor(4, send_l[1]);

					HAL_Delay(20);
				}

	  	}

  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
////////////////////////////////////
void set_mycolor(uint8_t num, uint8_t mycolor)
{
	 switch (mycolor % 16)
	  {
		case 0:
			set_light(num,0,0,0);
			break;
		case 1:
			set_light(num,0,0,1);
			break;
		case 2:
			set_light(num,0,1,0);
			break;
		case 3:
			set_light(num,0,1,1);
			break;
		case 4:
			set_light(num,1,0,0);
			break;
		case 5:
			set_light(num,1,0,1);
			break;
		case 6:
			set_light(num, 1,1,0);
			break;
		case 7:
			set_light(num, 1,1,1);
			break;
		default:
			break;
	  }
}
/*
 * set led state (on or off)
each color:
	0 : off
	1 : on
	2 : toggle
	3 : no change
*/
void set_light(uint8_t num, uint8_t red, uint8_t green, uint8_t blue)
{
	if (num == 1)
	{
		if (blue == 0)
				HAL_GPIO_WritePin(LEDG1_GPIO_Port, LEDG1_Pin, 0);
		else if (blue == 1)
				HAL_GPIO_WritePin(LEDG1_GPIO_Port, LEDG1_Pin, 1);
		else if (blue == 2)
				HAL_GPIO_TogglePin(LEDG1_GPIO_Port, LEDG1_Pin);

		if (green == 0)
				HAL_GPIO_WritePin(LEDB1_GPIO_Port, LEDB1_Pin, 0);
		else if (green == 1)
				HAL_GPIO_WritePin(LEDB1_GPIO_Port, LEDB1_Pin, 1);
		else if (green == 2)
				HAL_GPIO_TogglePin(LEDB1_GPIO_Port, LEDB1_Pin);

		if (red == 0)
				HAL_GPIO_WritePin(LEDR1_GPIO_Port, LEDR1_Pin, 0);
		else if (red == 1)
				HAL_GPIO_WritePin(LEDR1_GPIO_Port, LEDR1_Pin, 1);
		else if (red == 2)
				HAL_GPIO_TogglePin(LEDR1_GPIO_Port, LEDR1_Pin);
	}

	if (num == 2)
	{
		if (blue == 0)
				HAL_GPIO_WritePin(LEDG2_GPIO_Port, LEDG2_Pin, 0);
		else if (blue == 1)
				HAL_GPIO_WritePin(LEDG2_GPIO_Port, LEDG2_Pin, 1);
		else if (blue == 2)
				HAL_GPIO_TogglePin(LEDG2_GPIO_Port, LEDG2_Pin);

		if (green == 0)
				HAL_GPIO_WritePin(LEDB2_GPIO_Port, LEDB2_Pin, 0);
		else if (green == 1)
				HAL_GPIO_WritePin(LEDB2_GPIO_Port, LEDB2_Pin, 1);
		else if (green == 2)
				HAL_GPIO_TogglePin(LEDB2_GPIO_Port, LEDB2_Pin);

		if (red == 0)
				HAL_GPIO_WritePin(LEDR2_GPIO_Port, LEDR2_Pin, 0);
		else if (red == 1)
				HAL_GPIO_WritePin(LEDR2_GPIO_Port, LEDR2_Pin, 1);
		else if (red == 2)
				HAL_GPIO_TogglePin(LEDR2_GPIO_Port, LEDR2_Pin);
	}

	if (num == 3)
	{
		if (blue == 0)
				HAL_GPIO_WritePin(LEDG3_GPIO_Port, LEDG3_Pin, 0);
		else if (blue == 1)
				HAL_GPIO_WritePin(LEDG3_GPIO_Port, LEDG3_Pin, 1);
		else if (blue == 2)
				HAL_GPIO_TogglePin(LEDG3_GPIO_Port, LEDG3_Pin);

		if (green == 0)
				HAL_GPIO_WritePin(LEDB3_GPIO_Port, LEDB3_Pin, 0);
		else if (green == 1)
				HAL_GPIO_WritePin(LEDB3_GPIO_Port, LEDB3_Pin, 1);
		else if (green == 2)
				HAL_GPIO_TogglePin(LEDB3_GPIO_Port, LEDB3_Pin);

		if (red == 0)
				HAL_GPIO_WritePin(LEDR3_GPIO_Port, LEDR3_Pin, 0);
		else if (red == 1)
				HAL_GPIO_WritePin(LEDR3_GPIO_Port, LEDR3_Pin, 1);
		else if (red == 2)
				HAL_GPIO_TogglePin(LEDR3_GPIO_Port, LEDR3_Pin);
	}

	if (num == 4)
	{
		if (blue == 0)
				HAL_GPIO_WritePin(LEDG4_GPIO_Port, LEDG4_Pin, 0);
		else if (blue == 1)
				HAL_GPIO_WritePin(LEDG4_GPIO_Port, LEDG4_Pin, 1);
		else if (blue == 2)
				HAL_GPIO_TogglePin(LEDG4_GPIO_Port, LEDG4_Pin);

		if (green == 0)
				HAL_GPIO_WritePin(LEDB4_GPIO_Port, LEDB4_Pin, 0);
		else if (green == 1)
				HAL_GPIO_WritePin(LEDB4_GPIO_Port, LEDB4_Pin, 1);
		else if (green == 2)
				HAL_GPIO_TogglePin(LEDB4_GPIO_Port, LEDB4_Pin);

		if (red == 0)
				HAL_GPIO_WritePin(LEDR4_GPIO_Port, LEDR4_Pin, 0);
		else if (red == 1)
				HAL_GPIO_WritePin(LEDR4_GPIO_Port, LEDR4_Pin, 1);
		else if (red == 2)
				HAL_GPIO_TogglePin(LEDR4_GPIO_Port, LEDR4_Pin);
	}

}

int initial_check(void)
{
	int deldel = 400;
	set_light(1,1, 0, 0);set_light(2,1, 0, 0);set_light(3,1, 0, 0);set_light(4,1, 0, 0);
	HAL_Delay(deldel);
	set_light(1, 0, 0, 0);set_light(2, 0, 0, 0);set_light(3, 0, 0, 0);set_light(4, 0, 0, 0);
	HAL_Delay(deldel);
	set_light(1,1, 0, 0);set_light(2,1, 0, 0);set_light(3,1, 0, 0);set_light(4,1, 0, 0);
	HAL_Delay(deldel);
	set_light(1, 0, 0, 0);set_light(2, 0, 0, 0);set_light(3, 0, 0, 0);set_light(4, 0, 0, 0);
	HAL_Delay(deldel);
	set_light(1,1, 0, 0);set_light(2,1, 0, 0);set_light(3,1, 0, 0);set_light(4,1, 0, 0);
	HAL_Delay(deldel);
	set_light(1, 1, 0, 0);
	return 1;
}

/* 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 */

  /* 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,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
