/**
 * @file        encoder.c
 */

/* Includes *******************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include "stm32f4xx_hal.h"
#include "Timer.h"
#include "encoder.h"

/* Public variables ***********************************************************/

/* Private variables **********************************************************/
static uint16_t encoder_count = 0;
static int16_t encoder_revolutions = 0;

/* Exported variables *********************************************************/

/* Constants ******************************************************************/
#define MSB16(a) ((uint8_t)(((a) & 0xFF00) >> 8))
#define LSB16(a) ((uint8_t)(((a) & 0x00FF) >> 0))

/* Private functions **********************************************************/

/* Public functions ***********************************************************/
/**
 * @brief   Encoder_Init
 *          Initialization of the encoder module.
 */
void Encoder_Init(void)
{
    encoder_count = 0;
    encoder_revolutions = 0;
}

/**
 * @brief   Encoder_Handler
 *          This functions must be called from the super-loop. It handles the
 *          total rotations count
 */
void Encoder_Handler(void)
{
    Encoder_Update();
}

void Encoder_Update(void)
{
    uint16_t new_count = TIM1->CNT;
    if (new_count != encoder_count) {
        if ((new_count < ENCODER_LOWLIMIT) && (encoder_count > ENCODER_HIGHLIMIT)) {
            encoder_revolutions++;
        }
        else if ((encoder_count < ENCODER_LOWLIMIT) && (new_count > ENCODER_HIGHLIMIT)) {
            encoder_revolutions--;
        }

        encoder_count = new_count;
    }
}

uint16_t Encoder_GetCount(void)
{
    return encoder_count;
}
int16_t Encoder_GetRevolutions(void)
{
    return encoder_revolutions;
}
