#include "main.h"
#include "aq.h"

//Nombre de points envoyés -> 65535 (c'est un uint16 => 65536 == 0)
#define DLENGTH 500
//tim2 period (sampling)
#define SAMPLEPERIOD 84 //1MHz

//stockage des mesures
uint8_t mes[DLENGTH];
uint16_t mes_idx = 0;
uint8_t aq = 255; //machine d'état
uint16_t nvars = 256 + 4;//c'est un bitfield => on ajoute 256
uint16_t dlength = DLENGTH;

uint16_t pot = 0; //variable pour stocker le potentiomètre virtuel


//timer 2
TIM_HandleTypeDef htim2;

extern UART_HandleTypeDef huart2;

void send_data (void)
{
	HAL_UART_Transmit(&huart2,(uint8_t*)&dlength,2, 1000);
	HAL_UART_Transmit(&huart2,(uint8_t*)&nvars,2, 1000);
	HAL_UART_Transmit(&huart2,(uint8_t*)mes,dlength, 10000);
}

void MSP_init_modif(void ) {
	HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_1);
	HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 1, 2);
	__HAL_RCC_TIM2_CLK_ENABLE();
	/* TIM2 interrupt Init */
	HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(TIM2_IRQn);
	HAL_InitTick (1);
};

/**
  * @brief TIM2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM2_Init(void)
{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 0;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = SAMPLEPERIOD;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_OC_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_TIMING;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */

}

void aq_main(void)
{
	uint8_t c;
	static uint16_t nombre = 0;
	uint8_t bouton = HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin);
	switch (aq) {
		  case 0:
			  //on attend
			  mes_idx = 0;
			  if (HAL_UART_Receive(&huart2, &c, 1, 0)==HAL_OK) {
				  if (c=='\n') {
					  pot = nombre;
					  nombre = 0;
				  } else {
					  if ((c >= '0') && (c <= '9')) {
						  nombre = nombre*10+(c-'0');
						  if (nombre > 4095) nombre = 0;
					  } else {
						  nombre = 0;
					  }
				  }
			  }
			  if (bouton == 0) aq++;
			  break;
		  case 1:
			  //le bouton a été pressé
			  if (bouton == 1) aq++;
			  break;
		  case 2:
			  //le bouton a été relaché
			  //on démarre l'acquisition
			  HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_1);
			  aq++;
			  break;
		  case 3:
			  break;
		  case 4:
			  break;
		  case 5:
			  send_data();
			  aq = 0;
			  break;
		  case 255 :
			  //init
			  MSP_init_modif();
			  MX_TIM2_Init();
			  aq = 0;
			  break;
	}
}



/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32f4xx.s).                    */
/******************************************************************************/

/**
  * @brief This function handles TIM2 global interrupt.
  */
void TIM2_IRQHandler(void)
{
	mes[mes_idx] =((GPIOA->IDR>>8)&3)+((GPIOB->IDR>>11)&12);
	//pour vérifier que cette interrupt soit la plus prioritaire
	//mes[mes_idx] = htim2.Instance->CNT;
	__HAL_TIM_CLEAR_IT(&htim2, TIM_IT_CC1);
	if (mes_idx == (DLENGTH-1)){
		HAL_TIM_OC_Stop_IT(&htim2, TIM_CHANNEL_1);
		aq = 5;
	}
	mes_idx++;
}
