#include "bsp_lcd.h"

const uint8_t digit_segments[10] =
{
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,        // 0
  SEG_B | SEG_C,                                        // 1
  SEG_A | SEG_B | SEG_G | SEG_E | SEG_D,                // 2
  SEG_A | SEG_B | SEG_G | SEG_C | SEG_D,                // 3
  SEG_F | SEG_G | SEG_B | SEG_C,                        // 4
  SEG_A | SEG_F | SEG_G | SEG_C | SEG_D,                // 5
  SEG_A | SEG_F | SEG_E | SEG_D | SEG_C | SEG_G,        // 6
  SEG_A | SEG_B | SEG_C,                                // 7
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G, // 8
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G         // 9
};

const uint8_t segment_com[7] =
{ 0, // A
  1, // B
  2, // C
  3, // D
  2, // E
  0, // F
  1  // G
        };

// 每位数码管的SEG编号，顺序为 A-G，共6个数码管
const uint8_t digit_seg_map[6][7] =
{
{ 11, 11, 11, 3, 3, 3, 3 },  // 第1位（最左）
  { 16, 16, 16, 15, 15, 15, 15 }, // 第2位
  { 23, 23, 23, 22, 22, 22, 22 }, // 第3位
  { 29, 29, 29, 24, 24, 24, 24 }, // 第4位
  { 39, 39, 39, 30, 30, 30, 30 }, // 第5位
  { 41, 41, 41, 40, 40, 40, 40 }, // 第6位
        };

void LCD_Init(void)
{
    fsp_err_t err;
    err = R_SLCDC_Open (&g_slcdc0_ctrl, &g_slcdc0_cfg);
    assert(FSP_SUCCESS == err);
    R_BSP_SoftwareDelay (1, BSP_DELAY_UNITS_MILLISECONDS);

    err = R_SLCDC_Start (&g_slcdc0_ctrl);
    assert(FSP_SUCCESS == err);
    R_BSP_SoftwareDelay (1, BSP_DELAY_UNITS_MILLISECONDS);
}

void LCD_ShowDigit(uint8_t position, uint8_t digit)
{
    if (position > 5 || digit > 9)
        return;

    uint8_t segs = digit_segments[digit];

    for (int i = 0; i < 7; i++)
    {
        uint8_t seg_index = digit_seg_map[position][i];
        uint8_t com = segment_com[i];
        uint8_t bit = 1 << com;

        bool on = (segs & (1 << i)) != 0;
        uint8_t set = on ? bit : 0;

        R_SLCDC_Modify (&g_slcdc0_ctrl, seg_index, set, bit);
    }
}

/**
 * @brief 在LCD上显示数字，右对齐
 * @param number 要显示的数字
 * @param d 要显示位数
 */
void LCD_ShowNumber(uint32_t number, uint8_t d)
{
    for (int i = 0; i < d; i++)
    {
        uint8_t t = number % 10;
        LCD_ShowDigit (5 - i, t);  // 右对齐
        number /= 10;
    }
}

void LCD_setColon(bool on)
{
    R_SLCDC_Modify (&g_slcdc0_ctrl, 16, on ? 0x8 : 0x0, 0x8);  // COL1
}

void LCD_setDot(bool on)
{
    R_SLCDC_Modify (&g_slcdc0_ctrl, 29, on ? 0x8 : 0x0, 0x8);  // DOT1
}

/** @brief: 开启LCD屏幕左上角的电池显示
 @param: on: true:开启显示, false: 关闭显示
 @param: num: 显示电池电量 范围0~3
 */
void LCD_setBattery(bool on, uint8_t num)
{
    if (on)
    {
        switch (num)
        {
            case 0:
                R_SLCDC_Modify (&g_slcdc0_ctrl, 2, 0x1, 0xF);
            break;
            case 1:
                R_SLCDC_Modify (&g_slcdc0_ctrl, 2, 0x9, 0xF);
            break;
            case 2:
                R_SLCDC_Modify (&g_slcdc0_ctrl, 2, 0xD, 0xF);
            break;
            case 3:
                R_SLCDC_Modify (&g_slcdc0_ctrl, 2, 0xF, 0xF);
            break;
        }
    }
    else
    {
        R_SLCDC_Modify (&g_slcdc0_ctrl, 2, 0x0, 0xF);
    }
}