#include "S32K148.h"
#include "S32K148_features.h"
void IIC0_PORT_init(void)
{

    /*!
     * Pins definitions
     * ===================================================
     *
     * Pin number        | Function
     * ----------------- |------------------
     * PTA2              | LPI2C_SDA
     * PTA3              | LPI2C_SCL
     *
     */

	PCC->PCCn[PCC_PORTA_INDEX ]|=PCC_PCCn_CGC_MASK;/* Enable PORTA*/

    PORTA->PCR[2]   |= PORT_PCR_MUX(3) ;     /* Port A2: MUX = ALT3, LPI2C_SDA */
                                             //  | PORT_PCR_PE_MASK   /* Pull resistor enable */
                                            //   | PORT_PCR_PS(1);    /* Pull up selected */
    PORTA->PCR[3]   |= PORT_PCR_MUX(3)  ;    /* Port A3: MUX = ALT3, LPI2C_SCL */
                                            //    | PORT_PCR_PE_MASK  /* Pull resistor enable */
                                             //   | PORT_PCR_PS(1);   /* Pull up selected */
}
void IIC1_PORT_init(void)
{

    /*!
     * Pins definitions
     * ===================================================
     *
     * Pin number        | Function
     * ----------------- |------------------
     * PTA2              | LPI2C_SDA
     * PTA3              | LPI2C_SCL
     *
     */

	PCC->PCCn[PCC_PORTE_INDEX ]|=PCC_PCCn_CGC_MASK;/* Enable PORTA*/

    PORTE->PCR[0]   |= PORT_PCR_MUX(2)      /* Port A2: MUX = ALT3, LPI2C_SDA */
                                               | PORT_PCR_PE_MASK   /* Pull resistor enable */
                                               | PORT_PCR_PS(1);    /* Pull up selected */
    PORTE->PCR[1]   |= PORT_PCR_MUX(2)      /* Port A3: MUX = ALT3, LPI2C_SCL */
                                                | PORT_PCR_PE_MASK  /* Pull resistor enable */
                                                | PORT_PCR_PS(1);   /* Pull up selected */
}

void LPI2C0_init(void)
{
	for(uint32_t i=0;i<50000;i++)
	{

	}
    PCC->PCCn[PCC_LPI2C0_INDEX] |= PCC_PCCn_PCS(2)        /* Clk src: SIRCDIV2_CLK */
                              | PCC_PCCn_CGC_MASK;   	/* Enable clock for LPI2C0 */

    LPI2C0->MCR = LPI2C_MCR_RST_MASK; /* Enable LPI2C as master */

    LPI2C0->MCR = 0;

    LPI2C0->MCFGR1 = 	LPI2C_MCFGR1_PRESCALE(2);		/* Prescale = 4*/
						//|LPI2C_MCFGR1_AUTOSTOP(1);
						//|LPI2C_MCFGR1_IGNACK_MASK;		/* Ignore NACK*/

	/* SCL_freq = Input_freq / (2^PRESCALER * (CLKLO + CLKHI + 2))*/

    LPI2C0->MCCR0 = LPI2C_MCCR0_CLKLO(12)
                | LPI2C_MCCR0_CLKHI(6)
                | LPI2C_MCCR0_SETHOLD(6)
                | LPI2C_MCCR0_DATAVD(3);



    LPI2C0->MFCR = LPI2C_MFCR_TXWATER(0)	/* Transmitter Water mark set to 0*/
                  |LPI2C_MFCR_RXWATER(0);	/* Receiver Water mark set to 3*/

    LPI2C0->MCR = LPI2C_MCR_MEN_MASK /* Enable LPI2C as master */
				| LPI2C_MCR_RTF_MASK
				| LPI2C_MCR_RRF_MASK;
           // | LPI2C_MCR_DBGEN_MASK;
}
void LPI2C1_init(void)
{
	for(uint32_t i=0;i<50000;i++)
	{

	}
    PCC->PCCn[PCC_LPI2C1_INDEX] |= PCC_PCCn_PCS(2)        /* Clk src: SIRCDIV2_CLK */
                              | PCC_PCCn_CGC_MASK;   	/* Enable clock for LPI2C0 */

    LPI2C1->MCR = LPI2C_MCR_RST_MASK; /* Enable LPI2C as master */

    LPI2C1->MCR = 0;

    LPI2C1->MCFGR1 = 	LPI2C_MCFGR1_PRESCALE(2);		/* Prescale = 4*/
					//|LPI2C_MCFGR1_IGNACK_MASK;		/* Ignore NACK*/

	/* SCL_freq = Input_freq / (2^PRESCALER * (CLKLO + CLKHI + 2))*/

    LPI2C1->MCCR0 = LPI2C_MCCR0_CLKLO(12)
                | LPI2C_MCCR0_CLKHI(6)
                | LPI2C_MCCR0_SETHOLD(6)
                | LPI2C_MCCR0_DATAVD(3);



    LPI2C1->MFCR = LPI2C_MFCR_TXWATER(0)	/* Transmitter Water mark set to 0*/
                  |LPI2C_MFCR_RXWATER(0);	/* Receiver Water mark set to 3*/

    LPI2C1->MCR = LPI2C_MCR_MEN_MASK /* Enable LPI2C as master */
    			| LPI2C_MCR_RTF_MASK
    			| LPI2C_MCR_RRF_MASK;
           // | LPI2C_MCR_DBGEN_MASK;
}
uint8_t LPI2C0_BUS_BUSY(void)
{
	uint32_t reg = LPI2C0->MSR;
	if((reg & 0x02000000)==0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
uint8_t LPI2C0_MASTER_BUSY(void)
{
	uint32_t reg = LPI2C0->MSR;
	if((reg & 0x01000000)==0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
uint8_t LPI2C0_ACK_FLAG(void)
{
	uint32_t reg = LPI2C0->MSR;
	if((reg & 0x00000400)==0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
uint8_t LPI2C0_RX_FLAG(void)
{
	uint32_t reg = LPI2C0->MSR;
	if((reg & 0x00000002)==0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
uint8_t LPI2C0_RX_WAIT(void)
{
	uint32_t counter = 0;
	while(LPI2C0_RX_FLAG() == 0)
	{
		counter ++;
		if(counter >= 10000)
		{

			return 1;
		}
	}
	return 0;
}
uint8_t LPI2C0_SEND_SLAVE_ADDR(uint8_t slave_address)
{
	LPI2C0->MTDR = ((0x04<<8)|slave_address);//start
	if(LPI2C0_ACK_FLAG() == 0)
	{
		return 0;
	}
	else
	{
		return 1;
	}

}
uint8_t LPI2C0_SEND_REG(uint8_t *reg_buff,uint8_t reg_len)
{
	uint8_t send_len = 0;
	for(send_len = 0;send_len<reg_len;send_len++)
	{
		LPI2C0->MTDR = ((0x00<<8)|(*reg_buff));//start
		if(LPI2C0_ACK_FLAG() == 0)
		{

		}
		else
		{
			return 1;
		}
		send_len++;
		reg_buff++;
	}
	return 0;

}
uint8_t LPI2C0_SEND_DATA(uint8_t *tx_data,uint32_t tx_data_len)
{
	uint8_t send_len = 0;
	for(send_len = 0;send_len<tx_data_len;send_len++)
	{
		LPI2C0->MTDR = ((0x00<<8)|(*tx_data));//start
		if(LPI2C0_ACK_FLAG() == 0)
		{

		}
		else
		{
			return 1;
		}
		//send_len++;
		tx_data++;
	}
	LPI2C0->MTDR = ((0x02<<8)|00);
	return 0;

}

uint8_t LPI2C0_RECEIVE_DATA(uint8_t slave_address ,uint8_t *rx_data,uint32_t rx_data_len)
{
	uint8_t receive_len = 0;

	LPI2C0->MTDR = ((0x04<<8)|(slave_address|01));
	if(LPI2C0_ACK_FLAG() == 0)
	{

	}
	else
	{
		LPI2C0->MTDR = ((0x02<<8)|00);
		return 1;
	}

	LPI2C0->MTDR = ((0x01<<8)|(rx_data_len-1));

	for(receive_len = 0;receive_len<rx_data_len;receive_len++)
	{
		if( LPI2C0_RX_WAIT() == 0)
		{
			*rx_data = (LPI2C0->MRDR)&0xFF;
			rx_data++;
		}
		else
		{
			LPI2C0->MTDR = ((0x02<<8)|00);
			return 1;
		}
	}
	LPI2C0->MTDR = ((0x02<<8)|00);
	return 0;

}
uint8_t LPI2C0_tx(uint8_t slave_address,uint8_t *reg_buff,uint8_t reg_len,uint8_t *tx_data,uint32_t tx_data_len)
{
	for(uint32_t i=0;i<50000;i++)
	{

	}
	if(LPI2C0_BUS_BUSY() == 0)
	{

		if(LPI2C0_MASTER_BUSY() == 0)
		{
			if(LPI2C0_SEND_SLAVE_ADDR(slave_address) == 0)
			{
				if(LPI2C0_SEND_REG(reg_buff,reg_len) == 0)
				{
					if(LPI2C0_SEND_DATA(tx_data,tx_data_len) == 0)
					{
						return 0;
					}
					else
					{
						LPI2C0->MSR = 0x7F00;
						LPI2C0->MTDR = ((0x02<<8)|00);
						return 1;
					}
				}
				else
				{
					LPI2C0->MSR =0x7F00;
					LPI2C0->MTDR = ((0x02<<8)|00);
					return 1;
				}
			}
			else
			{
				LPI2C0->MSR = 0x7F00;
				LPI2C0->MTDR = ((0x02<<8)|00);
				return 1;
			}
		}
		else
		{
			LPI2C0->MTDR = ((0x02<<8)|00);
			return 1;
		}
	}
	else
	{
		LPI2C0->MTDR = ((0x02<<8)|00);
		return 1;
	}
}
uint8_t LPI2C0_rx(uint8_t slave_address,uint8_t *reg_buff,uint8_t reg_len,uint8_t *rx_data,uint32_t rx_data_len)
{
	for(uint32_t i=0;i<50000;i++)
	{

	}
	if(LPI2C0_BUS_BUSY() == 0)
	{
		if(LPI2C0_MASTER_BUSY() == 0)
		{
			if(LPI2C0_SEND_SLAVE_ADDR(slave_address) == 0)
			{
				if(LPI2C0_SEND_REG(reg_buff,reg_len) == 0)
				{
					if(LPI2C0_RECEIVE_DATA(slave_address,rx_data,rx_data_len) == 0)
					{
						return 0;
					}
					else
					{
						LPI2C0->MSR = 0x7F00;
						LPI2C0->MTDR = ((0x02<<8)|00);
						return 1;
					}
				}
				else
				{
					LPI2C0->MSR = 0x7F00;
					LPI2C0->MTDR = ((0x02<<8)|00);
					return 1;
				}
			}
			else
			{
				LPI2C0->MSR = 0x7F00;
				LPI2C0->MTDR = ((0x02<<8)|00);
				return 1;
			}
		}
		else
		{
			LPI2C0->MTDR = ((0x02<<8)|00);
			return 1;
		}
	}
	else
	{
		LPI2C0->MTDR = ((0x02<<8)|00);
		return 1;
	}
}


////////////////////////////////////////////////////////////////

uint8_t LPI2C1_BUS_BUSY(void)
{
	uint32_t reg = LPI2C1->MSR;
	if((reg & 0x02000000)==0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
uint8_t LPI2C1_MASTER_BUSY(void)
{
	uint32_t reg = LPI2C1->MSR;
	if((reg & 0x01000000)==0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
uint8_t LPI2C1_ACK_FLAG(void)
{
	uint32_t reg = LPI2C1->MSR;
	if((reg & 0x00000400)==0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
uint8_t LPI2C1_RX_FLAG(void)
{
	uint32_t reg = LPI2C1->MSR;
	if((reg & 0x00000002)==0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
uint8_t LPI2C1_RX_WAIT(void)
{
	uint32_t counter = 0;
	while(LPI2C1_RX_FLAG() == 0)
	{
		counter ++;
		if(counter >= 10000)
		{

			return 1;
		}
	}
	return 0;
}
uint8_t LPI2C1_SEND_SLAVE_ADDR(uint8_t slave_address)
{
	LPI2C1->MTDR = ((0x04<<8)|slave_address);//start
	if(LPI2C1_ACK_FLAG() == 0)
	{
		return 0;
	}
	else
	{
		return 1;
	}

}
uint8_t LPI2C1_SEND_REG(uint8_t *reg_buff,uint8_t reg_len)
{
	uint8_t send_len = 0;
	for(send_len = 0;send_len<reg_len;send_len++)
	{
		LPI2C1->MTDR = ((0x00<<8)|(*reg_buff));//start
		if(LPI2C1_ACK_FLAG() == 0)
		{

		}
		else
		{
			return 1;
		}
		send_len++;
		reg_buff++;
	}
	return 0;

}
uint8_t LPI2C1_SEND_DATA(uint8_t *tx_data,uint32_t tx_data_len)
{
	uint8_t send_len = 0;
	for(send_len = 0;send_len<tx_data_len;send_len++)
	{
		LPI2C1->MTDR = ((0x00<<8)|(*tx_data));//start
		if(LPI2C1_ACK_FLAG() == 0)
		{

		}
		else
		{
			return 1;
		}
		//send_len++;
		tx_data++;
	}
	LPI2C1->MTDR = ((0x02<<8)|00);
	return 0;

}

uint8_t LPI2C1_RECEIVE_DATA(uint8_t slave_address ,uint8_t *rx_data,uint32_t rx_data_len)
{
	uint8_t receive_len = 0;

	LPI2C1->MTDR = ((0x04<<8)|(slave_address|01));
	if(LPI2C1_ACK_FLAG() == 0)
	{

	}
	else
	{
		LPI2C1->MTDR = ((0x02<<8)|00);
		return 1;
	}

	LPI2C1->MTDR = ((0x01<<8)|(rx_data_len-1));

	for(receive_len = 0;receive_len<rx_data_len;receive_len++)
	{
		if( LPI2C1_RX_WAIT() == 0)
		{
			*rx_data = (LPI2C1->MRDR)&0xFF;
			rx_data++;
		}
		else
		{
			LPI2C1->MTDR = ((0x02<<8)|00);
			return 1;
		}
	}
	LPI2C1->MTDR = ((0x02<<8)|00);
	return 0;

}
uint8_t LPI2C1_tx(uint8_t slave_address,uint8_t *reg_buff,uint8_t reg_len,uint8_t *tx_data,uint32_t tx_data_len)
{
	for(uint32_t i=0;i<50000;i++)
		{

		}
	if(LPI2C1_BUS_BUSY() == 0)
	{
		if(LPI2C1_MASTER_BUSY() == 0)
		{
			if(LPI2C1_SEND_SLAVE_ADDR(slave_address) == 0)
			{
				if(LPI2C1_SEND_REG(reg_buff,reg_len) == 0)
				{
					if(LPI2C1_SEND_DATA(tx_data,tx_data_len) == 0)
					{
						return 0;
					}
					else
					{
						LPI2C1->MSR = 0x7F00;
						LPI2C1->MTDR = ((0x02<<8)|00);
						return 1;
					}
				}
				else
				{
					LPI2C1->MSR =0x7F00;
					LPI2C1->MTDR = ((0x02<<8)|00);
					return 1;
				}
			}
			else
			{
				LPI2C1->MSR = 0x7F00;
				LPI2C1->MTDR = ((0x02<<8)|00);
				return 1;
			}
		}
		else
		{
			LPI2C1->MTDR = ((0x02<<8)|00);
			return 1;
		}
	}
	else
	{
		LPI2C1->MTDR = ((0x02<<8)|00);
		return 1;
	}
}
uint8_t LPI2C1_rx(uint8_t slave_address,uint8_t *reg_buff,uint8_t reg_len,uint8_t *rx_data,uint32_t rx_data_len)
{
	for(uint32_t i=0;i<50000;i++)
		{

		}
	if(LPI2C1_BUS_BUSY() == 0)
	{
		if(LPI2C1_MASTER_BUSY() == 0)
		{
			if(LPI2C1_SEND_SLAVE_ADDR(slave_address) == 0)
			{
				if(LPI2C1_SEND_REG(reg_buff,reg_len) == 0)
				{
					if(LPI2C1_RECEIVE_DATA(slave_address,rx_data,rx_data_len) == 0)
					{
						return 0;
					}
					else
					{
						LPI2C1->MSR = 0x7F00;
						LPI2C1->MTDR = ((0x02<<8)|00);
						return 1;
					}
				}
				else
				{
					LPI2C1->MSR = 0x7F00;
					LPI2C1->MTDR = ((0x02<<8)|00);
					return 1;
				}
			}
			else
			{
				LPI2C1->MSR = 0x7F00;
				LPI2C1->MTDR = ((0x02<<8)|00);
				return 1;
			}
		}
		else
		{
			LPI2C1->MTDR = ((0x02<<8)|00);
			return 1;
		}
	}
	else
	{
		LPI2C1->MTDR = ((0x02<<8)|00);
		return 1;
	}
}

