#include "system_init.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_i2c.h"
#include "em_vcmp.h"
//#include "efm32zg108f16.h"
#include "efm32zg222f8.h"

#include "slave_i2c_interface.h"
void clock_init(void)
{
   //-->using HFRCO at 21MHz as high frequency clock, HFCLK
   CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO);
   CMU_HFRCOBandSet(cmuHFRCOBand_21MHz);
	 CMU_AUXHFRCOBandSet(cmuAUXHFRCOBand_21MHz);
   //-->no low frequency clock source selected
   //-->enable GPIO clock
   CMU_ClockEnable(cmuClock_GPIO, true);
   //-->enable clock for I2C0
   CMU_ClockEnable(cmuClock_I2C0, true);
}

void gpio_init(void)
{
   //-->module pin setup
   //-->pin PA0 is configured to Open-drain
   GPIO->P[0].MODEL = (GPIO->P[0].MODEL & ~_GPIO_P_MODEL_MODE0_MASK) | GPIO_P_MODEL_MODE0_WIREDAND;
   //-->pin PB8 is configured to Open-drain
   GPIO->P[1].MODEH = (GPIO->P[1].MODEH & ~_GPIO_P_MODEH_MODE8_MASK) | GPIO_P_MODEH_MODE8_WIREDAND;
   //-->pin PB11 is configured to Open-drain
   GPIO->P[1].MODEH = (GPIO->P[1].MODEH & ~_GPIO_P_MODEH_MODE11_MASK) | GPIO_P_MODEH_MODE11_WIREDAND;
   //-->pin PB14 is configured to Open-drain
   GPIO->P[1].MODEH = (GPIO->P[1].MODEH & ~_GPIO_P_MODEH_MODE14_MASK) | GPIO_P_MODEH_MODE14_WIREDAND;
   //-->pin PC0 is configured to Open-drain
   GPIO->P[2].MODEL = (GPIO->P[2].MODEL & ~_GPIO_P_MODEL_MODE0_MASK) | GPIO_P_MODEL_MODE0_WIREDAND;
   //-->pin PC1 is configured to Open-drain
   GPIO->P[2].MODEL = (GPIO->P[2].MODEL & ~_GPIO_P_MODEL_MODE1_MASK) | GPIO_P_MODEL_MODE1_WIREDAND;
   //--> pin PD6 is configured to Open-drain
   GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE6_MASK) | GPIO_P_MODEL_MODE6_WIREDAND;
   //--> pin PD7 is configured to Open-drain
   GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE7_MASK) | GPIO_P_MODEL_MODE7_WIREDAND;
   //-->pin PE13 is configured to Open-drain
   GPIO->P[4].MODEH = (GPIO->P[4].MODEH & ~_GPIO_P_MODEH_MODE13_MASK) | GPIO_P_MODEH_MODE13_WIREDAND;
   //-->Pin PF2 is configured to Input enabled with pull-up
   GPIO->P[5].DOUT |= (1 << 2);
   GPIO->P[5].MODEL = (GPIO->P[5].MODEL & ~_GPIO_P_MODEL_MODE2_MASK) | GPIO_P_MODEL_MODE2_INPUTPULL;
}

void i2c_init(void)
{
   //-->module I2C0 is configured to location 1
   I2C0->ROUTE = (I2C0->ROUTE & ~_I2C_ROUTE_LOCATION_MASK) | I2C_ROUTE_LOCATION_LOC1;
   //--> enable signals SDA, SCL
   I2C0->ROUTE |= I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN;
   //-->set the slave address
   I2C0->SADDR = I2C_SLAVE_ADDRESS;
   //-->set the slave address mask to
   //-->0x7F will only match the exact address specified by SADDR.
   I2C0->SADDRMASK = 0xA0;
   //-->set the interrupts to be generated
	//I2C_IntClear(I2C0, I2C_IEN_ADDR | I2C_IEN_RXDATAV | I2C_IEN_SSTOP);
	 I2C0->IFC |= I2C_IEN_START | I2C_IEN_RSTART | I2C_IEN_ADDR | I2C_IEN_RXDATAV | I2C_IEN_ACK | I2C_IEN_NACK | I2C_IEN_SSTOP;
   I2C0->IEN |= I2C_IEN_START | I2C_IEN_RSTART | I2C_IEN_ADDR | I2C_IEN_RXDATAV | I2C_IEN_ACK | I2C_IEN_NACK | I2C_IEN_SSTOP;

 
	//-->clear all flags
   I2C0->IFC |= _I2C_IFC_MASK;
   //-->clock divisor must be at least 1 in slave mode according to reference
   //-->manual (in which case there is normally no need to set bus frequency)
   I2C0->CLKDIV = 1;
   //-->set I2C as slave and enable it and disable the arabitration since there is only this MCU on the bus
   I2C0->CTRL |= I2C_CTRL_SLAVE | I2C_CTRL_EN |I2C_CTRL_ARBDIS ;
  //I2C0->CTRL |= I2C_CTRL_SLAVE | I2C_CTRL_AUTOACK | I2C_CTRL_AUTOSN; 
	 //////////////////////////////
   //I2C0->CTRL |= I2C_CTRL_AUTOACK;
   //////////////////////////////
   //-->when re-enabling the I2C, the ABORT command or the Bus Idle Timeout feature must be
   //-->applied prior to use even if the BUSY flag is not set.
   //-->setting the ABORT command will make the I2C module discard any data currently being transmitted
   //-->or received, release the SDA and SCL lines and go to an idle mode. ABORT effectively makes the I2C
   //-->module forget about any ongoing transfers.
   I2C0->CMD = I2C_CMD_ABORT;
}

void interrupt_init(void)
{
   //-->clear/enable interrupt from I2C module
   NVIC_ClearPendingIRQ(I2C0_IRQn);
   NVIC_EnableIRQ(I2C0_IRQn);
   //-->clear/enable MODSEL pin interrupt
   GPIO_IntConfig(gpioPortF, 2, true, true, true);
   NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn);
   NVIC_EnableIRQ(GPIO_EVEN_IRQn);
}

void initialize_mcu_resources(void)
{
   clock_init();
   gpio_init();
   i2c_init();
   interrupt_init();
}
