/*
 * pribors.c
 *
 *  Created on: 6 сент. 2024 г.
 *      Author: user
 */
#include "pribors.h"
#include "lwip/ip_addr.h"

extern _Bool flag_load_ems_g;
extern _Bool flag_load_ems_b0;
extern _Bool flag_load_ems_b1;
extern _Bool flag_load_kems_b;
extern uint32_t pribor_type;	// Тип прибора, где стоит ячейка, нужен для выбора загрузки flash
uint32_t get_ip(void)
{
	uint32_t pribor = (((GPIOC->IDR) >> 6) & 0x7) | (((GPIOC->IDR) >> 9) & 0x18);
	switch(pribor)
	{
		case PRIBOR_UF: return ipaddr_addr(IP_PRIBOR_UF);
		case PRIBOR_PRDN1: return ipaddr_addr(IP_PRIBOR_PRDN1);
		case PRIBOR_PRDN2: return ipaddr_addr(IP_PRIBOR_PRDN2);
		case PRIBOR_PRDN3: return ipaddr_addr(IP_PRIBOR_PRDN3);
		case PRIBOR_PRDN4: return ipaddr_addr(IP_PRIBOR_PRDN4);
		case PRIBOR_PRDV1: return ipaddr_addr(IP_PRIBOR_PRDV1);
		case PRIBOR_PRDV2: return ipaddr_addr(IP_PRIBOR_PRDV2);
		case PRIBOR_PRDV3: return ipaddr_addr(IP_PRIBOR_PRDV3);
		case PRIBOR_PRDV4: return ipaddr_addr(IP_PRIBOR_PRDV4);
		case PRIBOR_PRDK1: return ipaddr_addr(IP_PRIBOR_PRDK1);
		case PRIBOR_PRDK2: return ipaddr_addr(IP_PRIBOR_PRDK2);
		case PRIBOR_PRDK3: return ipaddr_addr(IP_PRIBOR_PRDK3);
		case PRIBOR_PRDK4: return ipaddr_addr(IP_PRIBOR_PRDK4);
		default: return ipaddr_addr(IP_PRIBOR_DEFAULT);
	}
}

uint16_t get_port(void)
{
	uint32_t pribor = (((GPIOC->IDR) >> 6) & 0x7) | (((GPIOC->IDR) >> 9) & 0x18);
	switch(pribor)
	{
		case PRIBOR_UF: return 50000U + PORT_PRIBOR_UF;
		case PRIBOR_PRDN1: return 50000U + PORT_PRIBOR_PRDN1;
		case PRIBOR_PRDN2: return 50000U + PORT_PRIBOR_PRDN2;
		case PRIBOR_PRDN3: return 50000U + PORT_PRIBOR_PRDN3;
		case PRIBOR_PRDN4: return 50000U + PORT_PRIBOR_PRDN4;
		case PRIBOR_PRDV1: return 50000U + PORT_PRIBOR_PRDV1;
		case PRIBOR_PRDV2: return 50000U + PORT_PRIBOR_PRDV2;
		case PRIBOR_PRDV3: return 50000U + PORT_PRIBOR_PRDV3;
		case PRIBOR_PRDV4: return 50000U + PORT_PRIBOR_PRDV4;
		case PRIBOR_PRDK1: return 50000U + PORT_PRIBOR_PRDK1;
		case PRIBOR_PRDK2: return 50000U + PORT_PRIBOR_PRDK2;
		case PRIBOR_PRDK3: return 50000U + PORT_PRIBOR_PRDK3;
		case PRIBOR_PRDK4: return 50000U + PORT_PRIBOR_PRDK4;
		default: return 50000U + PORT_PRIBOR_DEFAULT;
	}
}

uint16_t set_status(unsigned char *buf, uint32_t pribor)
{
	uint16_t status_len = 0;
	switch(pribor)
	{
		case PRIBOR_UF: return set_status_uf(buf);
		case PRIBOR_PRDN1: return set_status_prd(buf);
		case PRIBOR_PRDN2: return set_status_prd(buf);
		case PRIBOR_PRDN3: return set_status_prd(buf);
		case PRIBOR_PRDN4: return set_status_prd(buf);
		case PRIBOR_PRDV1: return set_status_prd(buf);
		case PRIBOR_PRDV2: return set_status_prd(buf);
		case PRIBOR_PRDV3: return set_status_prd(buf);
		case PRIBOR_PRDV4: return set_status_prd(buf);
		case PRIBOR_PRDK1: return set_status_prd(buf);
		case PRIBOR_PRDK2: return set_status_prd(buf);
		case PRIBOR_PRDK3: return set_status_prd(buf);
		case PRIBOR_PRDK4: return set_status_prd(buf);
		default:
		{
			buf[6] = 2;
			buf[7] = 0;
			buf[8] = 1;
			buf[9] = 2;
			status_len = 4;
			pribor_type = PRIBOR_TYPE_DEFAULT;
		}
	}

	return(status_len);
}

uint16_t set_status_prd(unsigned char *buf)
{
	uint16_t ports_data, i;
	buf[7] = 0;
	ports_data = read_isa(BASE_ADDR_EMS_G);
	buf[8] = 0;
	if( ports_data != 0xFFFF )
	{
		buf[8] = set_bit(buf[8], 0, 1);
		buf[8] = set_bit(buf[8], 4, flag_load_ems_g);
	}
	else flag_load_ems_g = 0;
	ports_data = read_isa(BASE_ADDR_UG);
	if( ports_data != 0xFFFF ) buf[8] = set_bit(buf[8], 1, 1);
	ports_data = read_isa(BASE_ADDR_UKP0);
	if( ports_data != 0xFFFF ) buf[8] = set_bit(buf[8], 2, 1);
	ports_data = read_isa(BASE_ADDR_UKP1);
	if( ports_data != 0xFFFF ) buf[8] = set_bit(buf[8], 3, 1);

	for (uint16_t i = 1; i <14; i++)
	{
		write_isa(BASE_ADDR_EMS_G + 0xC, i );
		ports_data = read_isa(BASE_ADDR_EMS_G + 0xE );
		buf[9 + (i - 1) * 2] = ports_data & 0xFF;
		buf[10 + (i -1) * 2] = ports_data >> 8;
	}

	ports_data = read_isa( BASE_ADDR_UG + 0xC );
	buf[35] = ports_data & 0xFF;
	buf[36] = ports_data >> 8;
	ports_data = read_isa( BASE_ADDR_UG + 0xE );
	buf[37] = ports_data & 0xFF;
	buf[38] = ports_data >> 8;

	//BASE_ADDR_UKP0

	for (uint16_t i = 0; i <16; i++)
	{
		ports_data = read_isa(BASE_ADDR_UKP0 + 0x8);
		buf[39 + i * 2] = ports_data & 0xFF;
		buf[40 + i * 2] = ports_data >> 8;
	}
	write_isa(BASE_ADDR_UKP0 + 0x4, 1);


	//BASE_ADDR_UKP1
	for (uint16_t i = 0; i <16; i++)
	{
		ports_data = read_isa(BASE_ADDR_UKP1 + 0x8);
		buf[71 + i * 2] = ports_data & 0xFF;
		buf[72 + i * 2] = ports_data >> 8;
	}
	write_isa(BASE_ADDR_UKP1 + 0x4, 1);

	pribor_type = PRIBOR_TYPE_PRD;
	buf[6] = 103;
	return buf[6] + 2;
}

uint16_t set_status_uf(unsigned char *buf)
{
	uint16_t ports_data, i;
	buf[6] = 79;
	buf[7] = 0;
	buf[8] = 0;
	ports_data = read_isa(BASE_ADDR_KEMS_B);
	if( ports_data != 0xFFFF )
	{
		buf[8] = set_bit(buf[8], 0, 1);
		buf[8] = set_bit(buf[8], 3, flag_load_kems_b);
	}
	else flag_load_kems_b = 0;
	ports_data = read_isa(BASE_ADDR_EMS_B0);
	if( ports_data != 0xFFFF )
	{
		buf[8] = set_bit(buf[8], 1, 1);
		buf[8] = set_bit(buf[8], 4, flag_load_ems_b0);
	}
	else flag_load_ems_b0 = 0;
	ports_data = read_isa(BASE_ADDR_EMS_B1);
	if( ports_data != 0xFFFF )
	{
		buf[8] = set_bit(buf[8], 2, 1);
		buf[8] = set_bit(buf[8], 5, flag_load_ems_b1);
	}
	else flag_load_ems_b1 = 0;
	for (i = 1; i <14; i++)
	{
		write_isa( BASE_ADDR_KEMS_B + 0xC, i );
		ports_data = read_isa( BASE_ADDR_KEMS_B + 0xE );
		buf[9+(i-1)*2] = ports_data & 0xFF;
		buf[10+(i-1)*2] = ports_data >> 8;
		write_isa( BASE_ADDR_EMS_B0 + 0xC, i );
		ports_data = read_isa( BASE_ADDR_EMS_B0 + 0xE );
		buf[9+(i-1)*2 + 26] = ports_data & 0xFF;
		buf[10+(i-1)*2 + 26] = ports_data >> 8;
		write_isa( BASE_ADDR_EMS_B1 + 0xC, i );
		ports_data = read_isa( BASE_ADDR_EMS_B1 + 0xE );
		buf[9+(i-1)*2 + 52] = ports_data & 0xFF;
		buf[10+(i-1)*2 + 52] = ports_data >> 8;
	}

	pribor_type = PRIBOR_TYPE_UF;

	return 81;
}

unsigned char set_bit(unsigned char bits, unsigned char index, _Bool val)
{
	unsigned char new_val;
    if (val == 1) new_val = bits | (1 << index);
    else new_val = bits & ~(1 << index);
    return new_val;
}
