/***********************************************************************
 * Copyright (c)  2017 - 2023, Unicmicro Co.,Ltd .
 * All rights reserved.
 * Filename    : um16436_spi.c
 * Description : um16436 spi source file
 * Author(s)   : MCU Team
 * version     : V1.0
 * Modify date : 2023-06-13
 ***********************************************************************/

#include "um16436_spi.h"
#include "um16436_fonts.h"
#include "string.h"
#include "stdlib.h"

//LCD图像缓存，用于保存上一次的显示内容
volatile uint8_t lcd_buff[38];

/************************************************************************
 * function   : umlcd_write_reg
 * Description: umlcd write reg 写寄存器
 *			uint8_t addr ：写的寄存器地址
 *			uint8_t data ：需要写入的数据
 * return: none
 ************************************************************************/
void umlcd_write_reg(uint8_t addr, uint8_t data)
{
	uint8_t wr_buf[2];
	
	wr_buf[0] = UMLCD_WR_CMD | (addr & 0x7f); //WREG | ADDR 地址为7位
	wr_buf[1] = data;
	spi0_command(2, wr_buf, 0, NULL, UMLCD_SLAVE_SELECT);
}

/************************************************************************
 * function   : umlcd_read_reg
 * Description: umlcd read reg 读寄存器值
 * input : uint8_t addr : 寄存器地址
 * return: 寄存器值
 ************************************************************************/
uint8_t umlcd_read_reg(uint8_t addr)
{
	uint8_t rd_buf[1];
	uint8_t wr_buf[1];

	wr_buf[0] = UMLCD_RD_CMD | (addr & 0x7f); //RREG | ADDR 地址为7位
	spi0_command(1, wr_buf, 1, rd_buf, UMLCD_SLAVE_SELECT);
	return rd_buf[0];
}

/************************************************************************
 * function   : umlcd_clear_display
 * Description: umlcd_clear_display全屏清空显示
 * input : none
 * return: none
 ************************************************************************/
void umlcd_clear_display(void)
{
	uint8_t i;
	for(i = 0; i < 38; i++)
	{
		umlcd_write_reg(UMLCD_COM0_DATA0_REG + i, 0);	
		lcd_buff[i] = 0;
	}
}

/************************************************************************
 * function   : umlcd_all_display
 * Description: umlcd_all_display全屏显示
 * input : none
 * return: none
 ************************************************************************/
void umlcd_all_display(void)
{
	uint8_t i;
	for(i = 0; i < 38; i++)
	{
		umlcd_write_reg(UMLCD_COM0_DATA0_REG + i, 0xff);
		lcd_buff[i] = 0xff;
	}
}

/************************************************************************
 * function   : umlcd_find_font
 * Description: umlcd_find_font
 * input : char *display_table ：需要查找的字符
 * return: 查找的字符在fonts_table字符库中的所在位置
 ************************************************************************/
static uint16_t umlcd_find_font(char *display_table)
{
	uint16_t j;
	
	for(j = 0; j < 304; j++)
	{
		if(fonts_table[j] != NULL)//如果不为NULL，则判断当前j位置的字符是否为要查找的字符，是则返回当前位置值
			if(strncmp(fonts_table[j], display_table, 4) == NULL)
				break;
	}
	
	return j;
}

/************************************************************************
 * function   : umlcd_display
 * Description: umlcd_display用于控制单个段码的显示
 * input : 
 *			char *display_table		：显示段码的字符数组
 *			uint8_t length			：显示段码的个数
 * return: none
 ************************************************************************/
void umlcd_display(char *display_table, uint8_t length)
{
	uint8_t i;
	uint16_t temp;		

	for(i = 0; i < length; i++)
	{
		temp = umlcd_find_font((display_table + i*4));//查找目标段码的位置
		lcd_buff[temp/8] |= (1 << (temp%8));//往缓存中写入数据
		umlcd_write_reg(UMLCD_COM0_DATA0_REG + temp/8, lcd_buff[temp/8]);//往数据寄存器中写入缓存的数据
	}	
}

/************************************************************************
 * function   : umlcd_num_display
 * Description: umlcd_num_display段码数字显示0-9
 * input : 
 *			uint8_t num_location：第几个段码
 *			uint8_t num			：需要显示的数字
 * return: none
 ************************************************************************/
void umlcd_num_display(uint8_t num_location, uint8_t num)
{
	char location[13][2] = {"01","02","03","04","05","06","07","08","09","10","11","12","13",};
	char location_temp[3];
	uint8_t i;
	uint16_t temp;	
	char *str_temp;
	
	for(i = 0; i < 7; i++)//将第num_location位的数字内容更新
	{
		location_temp[0] = location[num_location - 1][0];
		location_temp[1] = location[num_location - 1][1];
		location_temp[2] = NULL;
		if(strncmp(fonts_num_table[num*7 + i], (location_temp + 2), 1) != NULL)//点亮对应位置的段码
		{		
			if(location_temp[0] == '0')
				str_temp = strncat((location_temp + 1), fonts_num_table[num*7 + i], 2);
			else
				str_temp = strncat(location_temp, fonts_num_table[num*7 + i], 2);
			temp = umlcd_find_font(str_temp);
			lcd_buff[temp/8] |= (1 << (temp%8));		
		}	
		else//熄灭对应位置的段码
		{	
			if(location_temp[0] == '0')
				str_temp = strncat((location_temp + 1),fonts_num_table[56 + i], 2);
			else
				str_temp = strncat(location_temp, fonts_num_table[56 + i], 2);			
			temp = umlcd_find_font(str_temp);
			lcd_buff[temp/8] &= ~(1 << (temp%8));
		}		
	}

	for(i = 0; i < 38; i++)//更新数据寄存器
	{
		umlcd_write_reg(UMLCD_COM0_DATA0_REG + i, lcd_buff[i]);			
	}	
}

