#include "stm32f10x.h"
#include <stdlib.h>
#include "../Include/GPIO.h"

int ChercherEtat(GPIO_TypeDef * GPIO, int pin){ // Trouvons la valeur d'un broche sur un certain GPIO
return((GPIO -> IDR & (0x01 << pin)));
}

void ResetBroche(uint32_t GPIO, int Broche){ // Mettre à zero d'un certain broche d'un certain GPIO
  GPIO -> BSRR |= BSBroche;
}

void SetBroche(uint32_t GPIO, int Broche){ // Mettre à zero d'un certain broche d'un certain GPIO
  GPIO -> BSRR |= BSBroche << 16;
}

void TogglePin(GPIO_TypeDef*GPIO, int Broche){ // Inverser la valueur de broche sur GPIO
  GPIO -> ODR = GPIO -> ODR ^ (0x1 << Broche);
}

void ConfigureGPIO(uint32_t GPIO, int Broche, int IO, char Mode){ // Mettre un broche d'un GPIO sur un mode
                                                                  // Possble de améliorer avec des int à la place de string
	//Start clock pour les GPIO concernés
if(GPIO == GPIOA){
	RCC -> APB2ENR |= RCC_APB2ENR_IOPAEN;
}
else if(GPIO == GPIOB){
	RCC -> APB2ENR |= RCC_APB2ENR_IOPBEN;
}
else if(GPIO == GPIOC){
	RCC -> APB2ENR |= RCC_APB2ENR_IOPCEN;
}
else if(GPIO == GPIOD){
	RCC -> APB2ENR |= RCC_APB2ENR_IOPDEN;
}
 // Cas d'u CRL, broche 0 à 7
  if (Broche < 8) {
  GPIO -> CRL &= ~(0x1 << Broche *4) & ~(0x1 << Broche *4 +1) & ~(0x1 << Broche *4 + 2) & ~(0x1 << Broche *4 + 3); // Clean bits 
  if (IO == 0){ //Input
    if (strcmp(Mode,"Floating")) {
      GPIO -> CRL |= (0x1 << Broche *4) | (0x1 << Broche * 4 + 1);	
    }
    else if (strcmp(Mode,"Pull-Up") || strcmp(Mode,"Pull-Down")){
      GPIO -> CRL |=  (0x1 << 6*4 + 1);	
    }
    else {
      return; // Mode invalid
    }
  }
  else if ( IO  < 5) { // Output
    GPIO -> CRL |= (0xIO << Broche * 4 + 2); // Frequency mode
    if (strcmp(Mode, "Open-Drain")){
      GPIO -> CRL |= (0x1 << Broche *4);	
    }
    else if (strcmp(Mode, "Push-Pull Alterne")){
      GPIO -> CRL |= (0x1 << Broche *4 + 1);
      RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // Alternate Function I/O clock enable GPIOA
    }
    else if (strcmp(Mode, "Open-Drain Alterne")){
      GPIO -> CRL |= (0x1 << Broche * 4) | (0x1 << Broche * 4 + 1);	
    }
    else {
      return; // Mode invalid
    }
  }
  else{
    return;
  }
  }
  else if (Broche < 16) {
    GPIO -> CRH &= ~(0x1 << Broche *4) & ~(0x1 << Broche *4 +1) & ~(0x1 << Broche *4 + 2) & ~(0x1 << Broche *4 + 3); // Clean bits
    if (IO == 0){ //Input
      if (strcmp(Mode,"Floating")) {
        GPIO -> CRH |= (0x1 << Broche *4) | (0x1 << Broche * 4 + 1);	
      }
      else if (strcmp(Mode,"Pull-Up") || strcmp(Mode,"Pull-Down")){
        GPIO -> CRH |=  (0x1 << 6*4 + 1);	
      }
      else {
        return; // Mode invalid or doesn't exist
      } 
    }
    else if ( IO  < 5) { // Output
    GPIO -> CRH |= (0xIO << Broche * 4 + 2); // Frequency mode
      if (strcmp(Mode, "Open-Drain")){
        GPIO -> CRH |= (0x1 << Broche *4);	
      }
      else if (strcmp(Mode, "Push-Pull Alterne")){
        GPIO -> CRH |= (0x1 << Broche *4 + 1);	
      }
      else if (strcmp(Mode, "Open-Drain Alterne")){
        GPIO -> CRH |= (0x1 << Broche * 4) | (0x1 << Broche * 4 + 1);	
      }
      else {
        return; // Mode invalid or doesn't exits
      }
    }
    else{
      return; // IO invalid
    }
  }  
  else{
	return; // Pin number invalid
  }
}

