#include "at32f403a_407.h"
#include "mux.h"
#include "FreeRTOS.h"
#include "task.h"
#include <stdbool.h>


mux_channel_t leds[LED_NUMBER] = {
                                  {STATUS_G, {1, 1, 0}, LED_OFF, 0},
                                  {STATUS_R, {1, 1, 0}, LED_OFF, 0},
                                  {RX_G, {1, 1, 0}, LED_OFF, 0},
                                  {TX_R, {1, 1, 0}, LED_OFF, 0},
                                 };



//
void mux_led_init(mux_channel_t *ch)
{
}


//
void mux_gpio_init(void)
{
    gpio_init_type gpio_initstructure;
  
    
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
    
    // LED_COL
    //      COL_1 - PD6
    //      COL_2 - PD7
    //      COL_3 - PB6
    //      COL_4 - PB7
    gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;  
    gpio_initstructure.gpio_pull           = GPIO_PULL_NONE;  
    gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;  
    gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_initstructure.gpio_pins           = GPIO_PINS_6 | GPIO_PINS_7;
    gpio_init(GPIOB, &gpio_initstructure); 

    gpio_initstructure.gpio_pins           = GPIO_PINS_6 | GPIO_PINS_7;
    gpio_init(GPIOD, &gpio_initstructure); 
    
    gpio_bits_reset(GPIOB, GPIO_PINS_6 | GPIO_PINS_7);
    gpio_bits_reset(GPIOD, GPIO_PINS_6 | GPIO_PINS_7);
    
    // LED_LINE (низкий уровень на пине = высокий уровень на входе MUX)
    //      LINE_0 - PE3
    //      LINE_1 - PE2
    //      LINE_2 - PB9
    gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;  
    gpio_initstructure.gpio_pull           = GPIO_PULL_NONE;  
    gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;  
    gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_initstructure.gpio_pins           = GPIO_PINS_2 | GPIO_PINS_3;
    gpio_init(GPIOE, &gpio_initstructure); 

    gpio_initstructure.gpio_pins           = GPIO_PINS_9;
    gpio_init(GPIOB, &gpio_initstructure);
    
    gpio_bits_reset(GPIOE, GPIO_PINS_2 | GPIO_PINS_3);
    gpio_bits_reset(GPIOB, GPIO_PINS_9);
}


//
void mux_led_proc(void)
{
    uint8_t shift = 0;
    
    for (uint8_t i = 0; i < LED_NUMBER/4; i++)
    {
        leds[shift].line[0] ? (LINE_0_RESET) : (LINE_0_SET);
        leds[shift].line[1] ? (LINE_1_RESET) : (LINE_1_SET);
        leds[shift].line[2] ? (LINE_2_RESET) : (LINE_2_SET);
        
        leds[i*4].state     == LED_ON ? (COL_1_SET) : (COL_1_RESET);
        leds[i*4 + 1].state == LED_ON ? (COL_2_SET) : (COL_2_RESET);
        leds[i*4 + 2].state == LED_ON ? (COL_3_SET) : (COL_3_RESET);
        leds[i*4 + 3].state == LED_ON ? (COL_4_SET) : (COL_4_RESET);
        
        if (leds[i*4].state == LED_ON || leds[i*4 + 1].state == LED_ON || 
            leds[i*4 + 2].state == LED_ON || leds[i*4 + 3].state == LED_ON) 
        {
            vTaskDelay(1);
        }
        
        shift += 4;
    }
}

//
void mux_led_test_init(void)
{
    LINE_0_SET;
    LINE_1_SET;
    LINE_2_SET;
}

//
void mux_led_test_toggle(void)
{
    static bool flag = false;
    
    if (!flag) {
        COL_1_SET;
        flag = true;
    }
    else {
        COL_1_RESET;
        flag = false;
    }
}

//
void mux_led_blink(void)
{
    for (int i = 0; i < LED_NUMBER; i++)
    {
        leds[i].state = LED_ON;
        
        vTaskDelay(100);
        
        leds[i].state = LED_OFF;
    }
}

// true - normal
// false - alarm
void mux_led_status(bool state)
{
    if (state) {
        leds[STATUS_G].state = LED_ON;
        leds[STATUS_R].state = LED_OFF;
    }
    else {
        leds[STATUS_G].state = LED_OFF;
        leds[STATUS_R].state = LED_ON;
    }
}
