
/*
 * misc.c
 *
 *  Created on: 21 Sep 2016
 *      Author: Mike
 */
#include "stm32f1xx_hal.h"
#include "misc.h"
#include "main.h"

unsigned volatile long RPM_Time[RPM_SAMPLES];  // sampled on both  edges
unsigned volatile char RPM_Level[RPM_SAMPLES]; // active level when sampled
unsigned volatile long RPM_Count;              // incremented every reading

// this is set if there is a timer timeout interrupt
unsigned char volatile periodPulse = 0;

unsigned char volatile tim3triggered = 0;

static void
triggerTim3(void)
{
  htim3.Instance->CNT = 0;
  htim3.Instance->CR1 |= TIM_CR1_CEN;
}

void TIM2_IRQHandler(void)
{
  // rising edge trigger CB pulse
  if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_CC1))
  {
    __HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_CC1);
    RPM_Time[RPM_Count] = __HAL_TIM_GET_COMPARE(&htim2, TIM_CHANNEL_1);
    RPM_Level[RPM_Count] = 1; // rising so it is high now.
    RPM_Count = (RPM_Count + 1) % RPM_SAMPLES;
    // trigger timer some time after falling edge
    if (tim3triggered == 0)

    {
      tim3triggered = 1;
      triggerTim3();
    }
  }
  // falling edge trigger CB pulse
  if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_CC2))
  {
    __HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_CC2);
    RPM_Time[RPM_Count] = __HAL_TIM_GET_COMPARE(&htim2, TIM_CHANNEL_2);
    RPM_Level[RPM_Count] = 0; // falling so it is low now.
    RPM_Count = (RPM_Count + 1) % RPM_SAMPLES;
    // indicate that CB pulse is owning the timer 3 timing
    periodPulse = 0;
  }
}

// timer variable shared between TIM3 and TIM4 handler.
static char chtTimer = 0;

void TIM3_IRQHandler(void)
{
  if (__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_UPDATE))
  {
    __HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);

    tim3triggered = 0;
    if (chtTimer >= 3) // every 300mS
    {
      chtTimer = 0;

      resetTempCS();
      for (int instance = 0; instance < NUM_SPI_TEMP_SENS; instance++)
      {
        uint8_t buffer[2];

        nextTempCS();
        HAL_SPI_Receive(&hspi1, buffer, 2, 2);

        uint16_t obs = (buffer[0] << 8) | buffer[1];

        // good observation if the status bit is clear, and the reading is less than 1023

        uint16_t temp_c = obs >> 5;

        uint8_t good = ((obs & 7) == 0) && (temp_c > 0) && (temp_c < 250);

        if (good)
        {
          Temp_Observations[instance] = temp_c;
        }
      }
      nextTempCS(); // clock CS one more time to deselect all chips
    }
  }
}

// 100mS periodic sampler handler
void TIM4_IRQHandler(void)
{
  static char blink = 0;
  if (__HAL_TIM_GET_FLAG(&htim4, TIM_FLAG_UPDATE))
  {
    __HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_UPDATE);

    blink = !blink;
    HAL_GPIO_WritePin(LED_Blink_GPIO_Port, LED_Blink_Pin,
                      blink ? GPIO_PIN_SET : GPIO_PIN_RESET);

    TimerFlag = 1;
    if (NoSerialInCTR < 5)
    {
      NoSerialInCTR++;
      if (NoSerialInCTR == 5)
      {
        NoSerialIn = 1;
      }
    }

    if (periodPulse == 1)
    {
      triggerTim3();
    }
    // indicate that timer 4 firing is owning the timer 3 trigger
    periodPulse = 1;

    chtTimer++;
  }
}

void resetSerialTimeout(void)
{
  __disable_irq();
  NoSerialInCTR = 0;
  NoSerialIn = 0;
  __enable_irq();
}
