/**
 * \file    sys_smg_display.c
 * \brief   System segment display
 * 
 * \par     Copyright (c) 2019 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2019-09-02
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2019-09-02  Original Creation
 * 
 */

#include "libc.h"
#include "sys_smg_display.h"
#include "sys_config.h"

volatile SMG_CTRL_t g_smg_ctrl = {0,188,0,0};

//  related digit:           0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   LED Off,  H,   U,    ],   [,     |-, -|,   E, 
const u8_t g_smg_buf[18] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x00,    0x76,0x3e,  0x0f,0x39, 0x70,0x46, 0x79};

#define	SMG_BUF_OFFSET_LED_OFF                   (10)
#define	SMG_BUF_OFFSET_H                         (11)
#define	SMG_BUF_OFFSET_U                         (12)
#define	SMG_BUF_OFFSET_RIGHT_SQUARE_BRACKET      (13)
#define	SMG_BUF_OFFSET_LEFT_SQUARE_BRACKET       (14)
#define	SMG_BUF_OFFSET_VERTICAL_BAR_HYPHEN       (15)
#define	SMG_BUF_OFFSET_HYPHEN_VERTICAL_BAR       (16)
#define	SMG_BUF_OFFSET_E                         (17)


const SMG_LED_PIN_CTRL_t g_smg_led_pin_defs[] = {
    /*18 LEDs, bitmap for output val , bitmap for output mask */
    {(1 << (SMG_PIN2)), (1 << (SMG_PIN1))|(1 << (SMG_PIN2))},   /* B3: PIN1=0,PIN2=1; DIR1=1,DIR2=1 */
    {(1 << (SMG_PIN3)), (1 << (SMG_PIN1))|(1 << (SMG_PIN3))},   /* D3: PIN1=0,PIN3=1; DIR1=1,DIR3=1 */
    {(1 << (SMG_PIN4)), (1 << (SMG_PIN1))|(1 << (SMG_PIN4))},   /* F3: PIN1=0,PIN4=1; DIR1=1,DIR4=1 */
    {(1 << (SMG_PIN5)), (1 << (SMG_PIN1))|(1 << (SMG_PIN5))},   /* G3: PIN1=0,PIN5=1; DIR1=1,DIR5=1 */

    {(1 << (SMG_PIN3)), (1 << (SMG_PIN2))|(1 << (SMG_PIN3))},   /* B2: PIN2=0,PIN3=1; DIR2=1,DIR3=1 */
    {(1 << (SMG_PIN4)), (1 << (SMG_PIN2))|(1 << (SMG_PIN4))},   /* D2: PIN2=0,PIN4=1; DIR2=1,DIR4=1 */
    {(1 << (SMG_PIN5)), (1 << (SMG_PIN2))|(1 << (SMG_PIN5))},   /* E2: PIN2=0,PIN5=1; DIR2=1,DIR5=1 */
    {(1 << (SMG_PIN1)), (1 << (SMG_PIN1))|(1 << (SMG_PIN2))},   /* A3: PIN1=1,PIN2=0; DIR1=1,DIR2=1 */

    {(1 << (SMG_PIN2)), (1 << (SMG_PIN2))|(1 << (SMG_PIN3))},   /* A2: PIN2=1,PIN3=0; DIR2=1,DIR3=1 */
    {(1 << (SMG_PIN4)), (1 << (SMG_PIN3))|(1 << (SMG_PIN4))},   /* C2: PIN3=0,PIN4=1; DIR3=1,DIR4=1 */
    {(1 << (SMG_PIN5)), (1 << (SMG_PIN3))|(1 << (SMG_PIN5))},   /* F2: PIN3=0,PIN5=1; DIR3=1,DIR5=1 */
    {(1 << (SMG_PIN1)), (1 << (SMG_PIN1))|(1 << (SMG_PIN3))},   /* C3: PIN1=1,PIN3=0; DIR1=1,DIR3=1 */

    {(1 << (SMG_PIN3)), (1 << (SMG_PIN3))|(1 << (SMG_PIN4))},   /* B1: PIN3=1,PIN4=0; DIR3=1,DIR4=1 */
    {(1 << (SMG_PIN2)), (1 << (SMG_PIN2))|(1 << (SMG_PIN4))},   /* C1: PIN2=1,PIN4=0; DIR2=1,DIR4=1 */
    {(1 << (SMG_PIN5)), (1 << (SMG_PIN4))|(1 << (SMG_PIN5))},   /* G2: PIN4=0,PIN5=1; DIR4=1,DIR5=1 */
    {(1 << (SMG_PIN1)), (1 << (SMG_PIN1))|(1 << (SMG_PIN4))},   /* E3: PIN1=1,PIN4=0; DIR1=1,DIR4=1 */

    {(1 << (SMG_PIN3)), (1 << (SMG_PIN3))|(1 << (SMG_PIN5))},   /* I:  PIN3=1,PIN5=0; DIR3=1,DIR5=1 */
    {(1 << (SMG_PIN2)), (1 << (SMG_PIN2))|(1 << (SMG_PIN5))}    /* J:  PIN2=1,PIN5=0; DIR2=1,DIR5=1 */
};

#define SYS_SMG_LED_ON(idx/*0-17*/) \
    do { \
        DRV_REG_FIELD_SET3(GPIO_DR_REG, SMG_PIN_OUT_VAL, (g_smg_led_pin_defs[idx].out_bitmap)); \
        DRV_REG_FIELD_SET3(GPIO_DDR_REG, SMG_PIN_DDR, (g_smg_led_pin_defs[idx].dir_bitmap)); \
    } while(0)  


u32_t display_cap_units_digit = 8;
u32_t display_cap_tens_digit = 8;
u32_t display_cap_hundreds_digit = 1;
u32_t display_cap = 188;
u32_t display_cap_specific = 0;

void sys_smg_display_data_set(u32_t val)
{
    sync_enter_critical();
    if (g_smg_ctrl.display_data != val)
    {
        g_smg_ctrl.display_data = val;
        switch (val)
        {
            //显示 ][
            case SMG_X:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_RIGHT_SQUARE_BRACKET;
                display_cap_units_digit = SMG_BUF_OFFSET_LEFT_SQUARE_BRACKET;
                break;
            //显示 |--|
            case SMG_H:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_VERTICAL_BAR_HYPHEN;
                display_cap_units_digit = SMG_BUF_OFFSET_HYPHEN_VERTICAL_BAR;
                break;
            //显示 E0
            case SMG_E0:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_E;
                display_cap_units_digit = 0;
                break;
            //显示 E1
            case SMG_E1:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_E;
                display_cap_units_digit = 1;
                break;
            //显示 E2
            case SMG_E2:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_E;
                display_cap_units_digit = 2;
                break;
            //显示 E3
            case SMG_E3:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_E;
                display_cap_units_digit = 3;
                break;
            //显示 E4
            case SMG_E4:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_E;
                display_cap_units_digit = 4;
                break;
            //显示 E5
            case SMG_E5:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_E;
                display_cap_units_digit = 5;
                break;
            //显示 E6
            case SMG_E6:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_E;
                display_cap_units_digit = 6;
                break;
            //显示 E7
            case SMG_E7:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_E;
                display_cap_units_digit = 7;
                break;
            //显示 E8
            case SMG_E8:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_E;
                display_cap_units_digit = 8;
                break;
            //显示 E9
            case SMG_E9:
                display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                display_cap_tens_digit = SMG_BUF_OFFSET_E;
                display_cap_units_digit = 9;
                break;
            default:
                {
                    display_cap = val & 0xFF;
                    display_cap_specific = val & 0xF00;
                    switch (display_cap_specific)
                    {
                        case SMG_UNITS_DIGIT_OFF:
                            display_cap_hundreds_digit = display_cap * 0.01;
                            display_cap = display_cap % 100;
                            display_cap_tens_digit = display_cap * 0.1;
                            display_cap_units_digit = SMG_BUF_OFFSET_LED_OFF;
                            break;
                        case SMG_TENS_DIGIT_OFF:
                            display_cap_hundreds_digit = display_cap * 0.01;
                            display_cap = display_cap % 100;
                            display_cap_tens_digit = SMG_BUF_OFFSET_LED_OFF;
                            display_cap_units_digit = display_cap % 10;
                            break;
                        case SMG_HUNDREDS_DIGIT_OFF:
                            display_cap_hundreds_digit = SMG_BUF_OFFSET_LED_OFF;
                            display_cap = display_cap % 100;
                            display_cap_tens_digit = display_cap * 0.1;
                            display_cap_units_digit = display_cap % 10;
                            break;
                        default:
                            display_cap_hundreds_digit = display_cap * 0.01;
                            display_cap = display_cap % 100;
                            display_cap_tens_digit = display_cap * 0.1;
                            display_cap_units_digit = display_cap % 10;
                            break;
                    }
                }
                break;            
        }
    }
    sync_exit_critical();
}

void sys_smg_display(void)
{

    sys_smg_display_off(); //io作为输入LED灭

    g_smg_ctrl.scan_cnt++;

    if (g_smg_ctrl.scan_cnt >= SMG_LED_NUM)
    {
        g_smg_ctrl.scan_cnt = 0;
    }

    if (g_smg_ctrl.display_data != SMG_NC)
    {
        switch (g_smg_ctrl.scan_cnt)
        {
            case 0:
            {
                if (g_smg_buf[display_cap_units_digit]&0x02)//B3//PIN2
                {
                    SYS_SMG_LED_ON(0);
                }
                break;
            }
            case 1:
            {
                if (g_smg_buf[display_cap_units_digit]&0x08)//D3//PIN3
                {
                    SYS_SMG_LED_ON(1);
                }
                break;
            }
            case 2:
            {
                if (g_smg_buf[display_cap_units_digit]&0x20)//F3//PIN4
                {
                    SYS_SMG_LED_ON(2);
                }
                break;
            }
            case 3:
            {
                if (g_smg_buf[display_cap_units_digit]&0x40)//G3//PIN5
                {
                    SYS_SMG_LED_ON(3);
                }
                break;
            }
            case 4:
            {
                if (g_smg_buf[display_cap_tens_digit]&0x02)//B2//PIN3
                {
                    SYS_SMG_LED_ON(4);
                }
                break;
            }
            case 5:
            {
                if (g_smg_buf[display_cap_tens_digit]&0x08)//D2//PIN4
                {
                    SYS_SMG_LED_ON(5);
                }
                break;
            }
            case 6:
            {
                if (g_smg_buf[display_cap_tens_digit]&0x10)//E2//PIN5
                {
                    SYS_SMG_LED_ON(6);
                }
                break;
            }
            case 7:
            {
                if (g_smg_buf[display_cap_units_digit]&0x01)//A3//PIN1
                {
                    SYS_SMG_LED_ON(7);
                }
                break;
            }
            case 8:
            {
                if (g_smg_buf[display_cap_tens_digit]&0x01)//A2//PIN2
                {
                    SYS_SMG_LED_ON(8);
                }
                break;
            }
            case 9:
            {
                if (g_smg_buf[display_cap_tens_digit]&0x04)//C2//PIN4
                {
                    SYS_SMG_LED_ON(9);
                }
                break;
            }
            case 10:
            {
                if (g_smg_buf[display_cap_tens_digit]&0x20)//F2//PIN5
                {
                    SYS_SMG_LED_ON(10);
                }
                break;
            }
            case 11:
            {
                if (g_smg_buf[display_cap_units_digit]&0x04)//C3//PIN1
                {
                    SYS_SMG_LED_ON(11);
                }
                break;
            }
            case 12:
            {
                if (display_cap_hundreds_digit == 1)//百位数字1B1//PIN3
                {
                    SYS_SMG_LED_ON(12);
                }
                break;
            }
            case 13:
            {
                if (display_cap_hundreds_digit == 1)//百位数字1C1//PIN2
                {
                    SYS_SMG_LED_ON(13);
                }
                break;
            }
            case 14:
            {
                if (g_smg_buf[display_cap_tens_digit]&0x40)//G2//PIN5
                {
                    SYS_SMG_LED_ON(14);
                }
                break;
            }
            case 15:
            {
                if (g_smg_buf[display_cap_units_digit]&0x10)//E3//PIN1
                {
                    SYS_SMG_LED_ON(15);
                }
                break;
            }
            case 16:
            {
                SYS_SMG_LED_ON(16);
                break;
            }
            case 17:
            {
                SYS_SMG_LED_ON(17);
                break;
            }

            default :
            {
                break;
            }
        }
    }
}

void sys_smg_display_scan(void)
{
	if (sys_smg_ctrl_on_get())
	{
        sys_smg_display();
	}
}


