/*
 * alarm.c
 *
 *  Created on: Jun 2, 2017
 *      Author: wn
 */


#include "stm32f1xx_hal.h"
#include <PontCoopScheduler.h>
#include "alarm.h"


extern TIM_HandleTypeDef htim1;


typedef struct {
  uint16_t f;
  uint8_t inUse;
} tBuzzerHandle;

tBuzzerHandle buzzerHandle;


static void startBuzzer(uint16_t f) {
  HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_1);
  __HAL_TIM_SET_COUNTER(&htim1, 0);
  __HAL_TIM_SET_AUTORELOAD(&htim1, f);
  HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);
}

static void stopBuzzer() {
  HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_1);
}



void buzzerTest(void *handle) {
  static enum {BUZZER_OFF, BUZZER_LOW, BUZZER_HIGH} state = BUZZER_OFF;

  switch (state) {
  case BUZZER_OFF:
    HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_1);
    state = BUZZER_LOW;
    break;
  case BUZZER_LOW:
    HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_1);
    __HAL_TIM_SET_COUNTER(&htim1, 0);
    __HAL_TIM_SET_AUTORELOAD(&htim1, 2000);
    HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);
    state = BUZZER_HIGH;
    break;
  case BUZZER_HIGH:
    HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_1);
    __HAL_TIM_SET_COUNTER(&htim1, 0);
    __HAL_TIM_SET_AUTORELOAD(&htim1, 1000);
    HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);
    state = BUZZER_OFF;
    break;
  }
}

void stopBuzzing(void *handle) {
  stopBuzzer();
}

void buzz(void *handle) {
  tBuzzerHandle *lBuzzerHandle = (tBuzzerHandle*) handle;
  startBuzzer(lBuzzerHandle->f);
  schAdd(stopBuzzing, NULL, 50, 0);
}

void alarmInit() {
//  schAdd(buzzerTest, NULL, 0, 5000);
}


void blink(void *handle) {
  HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}



void enableAlarm(tAlarmType alarmType) {
  schAdd(blink, NULL, 0, 100);

  uint16_t f;
  if (alarmType == TIME_ALARM) {
    buzzerHandle.f = 1000;
  } else {
    buzzerHandle.f = 4000;
  }
  if (buzzerHandle.inUse == 0) {
    buzzerHandle.inUse = 1;
    schAdd(buzz, &buzzerHandle, 0, 10000);
  }
}

void disableAlarm() {
  schDel(blink, NULL);
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, RESET);
  schDel(buzz, &buzzerHandle);
}
