#include "stm32f0xx.h"
#include "stm32f0308_Discovery.h"

#define in0 GPIO_Pin_0
#define in1 GPIO_Pin_1
#define in2 GPIO_Pin_2
#define in3 GPIO_Pin_3
#define in4 GPIO_Pin_4
#define in5 GPIO_Pin_5
#define in_GPIO GPIOA


#define out0 GPIO_Pin_1
#define out1 GPIO_Pin_1
#define out2 GPIO_Pin_2
#define out3 GPIO_Pin_3
#define out4 GPIO_Pin_4
#define out5 GPIO_Pin_5
#define out_GPIO GPIOC

void TM_Delay_Init(void);
void TM_DelayMillis(uint32_t millis);
void TM_DelayMillis1(uint32_t millis);
void TM_DelayMillis2(uint32_t millis);

GPIO_InitTypeDef       GPIO_InitStructure ;

uint32_t multiplier;


int main(void)
{
					SystemInit();
					SystemCoreClockUpdate();
					TM_Delay_Init();
	
	
				RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
				RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
	
		/* Configure PA in input mode */
			GPIO_InitStructure.GPIO_Pin = ((GPIO_Pin_0)|(GPIO_Pin_1)|(GPIO_Pin_2)|(GPIO_Pin_3)|(GPIO_Pin_4)|(GPIO_Pin_5)) ;
			GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;									
			GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;							// enable internal Pullup resistors on the GPIO pins
			GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	
	/*configure PC in output mode */
			
	GPIOC->MODER  |= ((GPIO_MODER_MODER0_0)|(GPIO_MODER_MODER1_0)|(GPIO_MODER_MODER2_0)|(GPIO_MODER_MODER3_0)|(GPIO_MODER_MODER4_0)|(GPIO_MODER_MODER5_0)) ;
	//GPIOC-> GPIO_MODER_MODER8_0 = 0x01;
	GPIOC->OTYPER &= ~((GPIO_OTYPER_OT_0)|(GPIO_OTYPER_OT_1)|(GPIO_OTYPER_OT_2)|(GPIO_OTYPER_OT_3)|(GPIO_OTYPER_OT_4)|(GPIO_OTYPER_OT_5)) ;
	//GPIOC->OTYPER = 0x00;
	GPIOC->OSPEEDR |= ((GPIO_OSPEEDER_OSPEEDR0)|(GPIO_OSPEEDER_OSPEEDR1)|(GPIO_OSPEEDER_OSPEEDR2)|(GPIO_OSPEEDER_OSPEEDR3)|(GPIO_OSPEEDER_OSPEEDR4)|(GPIO_OSPEEDER_OSPEEDR5));
	//GPIOC->OSPEEDR = 0x00;
	GPIOC->PUPDR &= ~((GPIO_PUPDR_PUPDR0)|(GPIO_PUPDR_PUPDR1)|(GPIO_PUPDR_PUPDR2)|(GPIO_PUPDR_PUPDR3)|(GPIO_PUPDR_PUPDR4)|(GPIO_PUPDR_PUPDR5));
	
	
	while(1)
	{
		if(GPIO_ReadInputDataBit(GPIOA, (GPIO_Pin_0|1|2|3|4|5==1)))
		{
			GPIO_SetBits(out_GPIO,(out0)|(out1)|(out2)|(out3)|(out4)|(out5));
				TM_DelayMillis(7);
				GPIO_ResetBits(out_GPIO,(out0)|(out1)|(out2)|(out3)|(out4)|(out5));
			
			while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0|1|2|3|4|5)==1)
				{
					
					GPIO_SetBits(out_GPIO,(out0)|(out1)|(out2)|(out3)|(out4)|(out5));
					TM_DelayMillis1(3);
					GPIO_ResetBits(out_GPIO,(out0)|(out1)|(out2)|(out3)|(out4)|(out5));
					TM_DelayMillis2(22);
					
				}	
		}
	}
}

void TM_DelayMillis(uint32_t millis) {
    /* Multiply millis with multipler */
    /* Substract 10 */
    millis = 100 * millis * multiplier - 10;
    /* 4 cycles for one loop */
    while (millis--);
}

void TM_DelayMillis1(uint32_t millis) {
    /* Multiply millis with multipler */
    /* Substract 10 */
    millis = 1 * millis * multiplier - 10;
    /* 4 cycles for one loop */
    while (millis--);
}

void TM_DelayMillis2(uint32_t millis) {
    /* Multiply millis with multipler */
    /* Substract 10 */
    millis = 1 * millis * multiplier - 10;
    /* 4 cycles for one loop */
    while (millis--);
}



void TM_Delay_Init(void) {
    RCC_ClocksTypeDef RCC_Clocks;
    
    /* Get system clocks */
    RCC_GetClocksFreq(&RCC_Clocks);
    
    /* While loop takes 4 cycles */
    /* For 1 us delay, we need to divide with 4M */
    multiplier = RCC_Clocks.HCLK_Frequency / 4000000;
}

