#include "Driver_SPI.h"
#include "Driver_GPIO.h"

//////////////////////////////////////////////////////////
//--------------------Initialisation--------------------//
//////////////////////////////////////////////////////////

MyGPIO_Struct_TypeDef sortieSPI ;

void SPI_activate_clock(int numSPI) {
	if (numSPI==1) {
		RCC->APB2ENR |= (0x01 << 12) ;
	}
	else if (numSPI==2) {
		RCC->APB1ENR |= (0x01 << 14) ;
	}
	else if (numSPI==3) {
		RCC->APB1ENR |= (0x01 << 15) ;
	}
}

void SPI_init_master(SPI_TypeDef * SPI) {

	//config pin PA4 PA5 PA6 PA7 
	sortieSPI.GPIO = GPIOA ;
	sortieSPI.GPIO_Pin = 4 ;
	sortieSPI.GPIO_Conf = AltOut_Ppull ;
	MyGPIO_Init(&sortieSPI) ;
	sortieSPI.GPIO_Pin = 5 ;
	MyGPIO_Init(&sortieSPI) ;
	sortieSPI.GPIO_Pin = 6 ;
	sortieSPI.GPIO_Conf =  In_Floating;
	MyGPIO_Init(&sortieSPI) ;
	sortieSPI.GPIO_Conf = AltOut_Ppull ;
	sortieSPI.GPIO_Pin = 7 ;
	MyGPIO_Init(&sortieSPI) ;
	sortieSPI.GPIO_Pin = 8 ;
	sortieSPI.GPIO_Conf =  Out_Ppull;
	MyGPIO_Init(&sortieSPI) ;
	MyGPIO_Set(sortieSPI.GPIO,8);

	//activer clock SPI1
	SPI_activate_clock(1);

	//on met la polarité à 1 par défaut
	SPI->CR1 |= SPI_CR1_CPOL ;

	//Baud rate : fpclok/128
	SPI->CR1 |= (SPI_CR1_BR_1 | SPI_CR1_BR_2) ;
	SPI->CR1 &= ~SPI_CR1_BR_0 ;
	
	//On met la clock phase à 1 
	SPI->CR1 |= SPI_CR1_CPHA;

	//8 bits data frame format
	SPI->CR1 &= ~SPI_CR1_DFF;

	//on envoie le bit de poids fort en premier
	SPI->CR1 &= ~SPI_CR1_LSBFIRST ;

	SPI->CR1 |= SPI_CR1_SSM;
	SPI->CR1 |= SPI_CR1_SSI;

	//NSS pin is required in output
	//SPI->CR2 |= SPI_CR2_SSOE ;

	//on se met en mode master 
	SPI->CR1 |= SPI_CR1_MSTR ;

	//SPI enabled
	SPI->CR1 |= SPI_CR1_SPE ;
}


//////////////////////////////////////////////////////////
//----------------------- Ecrire -----------------------//
//////////////////////////////////////////////////////////
void SPI_send(SPI_TypeDef * SPI, char data) {
	int a;
	//SPI enabled
	//SPI->CR1 |= SPI_CR1_SPE ;
	while (!(SPI->SR & SPI_SR_TXE)) {
		//tant que TXE=0 on attend (on attend que le buffer soit vide)
	}
	//le buffer est mtn vide, on peut écrire
	SPI->DR = data ;
	while (!(SPI->SR & SPI_SR_RXNE)) {
		//tant que RXNE=0 on attend (on attend qu'il y ait qqchose à lire)
	} 
	a = SPI->DR ;
	//SPI->CR1 &= ~SPI_CR1_SPE ;

}


//////////////////////////////////////////////////////////
//------------------------ Lire ------------------------//
//////////////////////////////////////////////////////////
char SPI_rcv(SPI_TypeDef * SPI) {
	int a;
	//SPI enabled
	//SPI->CR1 |= SPI_CR1_SPE ;
	while (!(SPI->SR & SPI_SR_TXE)) {
		//tant que TXE=0 on attend (on attend que le buffer soit vide)
	}
	//le buffer est mtn vide, on peut écrire
	SPI->DR = 0 ;
	while (!(SPI->SR & SPI_SR_RXNE)) {
		//tant que RXNE=0 on attend (on attend qu'il y ait qqchose à lire)
	} 
	return SPI->DR ;
	//SPI->CR1 &= ~SPI_CR1_SPE ;
	
}
