/*
 * hal_MFRC530.c
 *
 *  Created on: Nov 11, 2011
 *      Author: RomanM
 */

/******************************************************************************
 * Function headers
 *****************************************************************************/
#include "stm32f10x.h"
#include "hal_Mfrc530.h"

// Add other headers dependent on HW
#include "drivers/Periph/SPI/hal_SPI.h"

/******************************************************************************
 * Prototypes of user defined functions
 *****************************************************************************/
void hal_Mfrc530_RCC_Config(void);
void hal_Mfrc530_GPIO_Config(void);
void hal_Mfrc530_EXTI_Config(void);
void hal_Mfrc530_NVIC_Config(void);
void hal_Mfrc530_Delay(__IO uint32_t nTick);



/******************************************************************************
 * HW dependent functions
 *****************************************************************************/

/*
 *	Initialization of HW layer
 *
 * 		Function to initialize MCU ports. Please add code to initialize
 * 		SPI, control pins and external interrupt.
 */
void hal_Mfrc530_Init(void) {
	hal_Mfrc530_RCC_Config();
	hal_Mfrc530_GPIO_Config();
	hal_SPI_Init(SPI2);
	hal_Mfrc530_EXTI_Config();
	hal_Mfrc530_NVIC_Config();
}

/*
 *	One byte SPI communication
 *
 *		Function to send and receive one byte from SPI. Please add code
 *		for communication.
 */
uint8_t hal_Mfrc530_RW(uint8_t data) {
	return hal_SPI_RW(SPI2, data);
}

/*
 *	Set NSS low
 *
 *		Add code to set NSS pin low.
 */
void hal_Mfrc530_NSS_Low(void) {
	GPIO_ResetBits(GPIOB, GPIO_Pin_12);
}

/*
 *	Set NSS high
 *
 *		Add code to set NSS pin high.
 */
void hal_Mfrc530_NSS_High(void) {
	GPIO_SetBits(GPIOB, GPIO_Pin_12);
}

/*
 *	Set RSTPD low
 *
 *		Add code to set RSTPD pin low.
 */
void hal_Mfrc530_RSTPD_Low(void) {
	GPIO_ResetBits(GPIOB, GPIO_Pin_1);
}

/*
 *	Set RSTPD high
 *
 *		Add code to set RSTPD pin high.
 */
void hal_MFRC530_RSTPD_High(void) {
	GPIO_SetBits(GPIOB, GPIO_Pin_1);
}

/*
 *	Delay 100us
 *
 *		Add code for 100us delay.
 */
void hal_Mfrc530_Wait100us(void) {
	hal_Mfrc530_Delay(2400);
}

/*
 *	Delay 5ms
 *
 *		Add code for 5ms delay.
 */
void hal_Mfrc530_Wait5ms(void) {
	hal_Mfrc530_Delay(120000);
}

/******************************************************************************
 * HW independent functions
 *****************************************************************************/

/*
 *	Write n bytes to SPI
 */
void hal_Mfrc530_WriteN(uint8_t *outBuff, uint8_t n) {
	while (n--) hal_Mfrc530_RW(*(outBuff++));
}

/*
 *	Read n bytes from SPI
 */
void hal_Mfrc530_ReadN(uint8_t *inBuff, uint8_t n) {
	while (n--) *(inBuff++) = hal_Mfrc530_RW(0);
}

/******************************************************************************
 * User defined functions
 *****************************************************************************/

void hal_Mfrc530_RCC_Config(void) {
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
}

void hal_Mfrc530_GPIO_Config(void) {
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_1;	// NSS and RSTPD pin
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;							// Out push-pull
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;							// IRQ pin
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;								// Input pull-up
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	hal_MFRC530_RSTPD_High();													// Set RSTPD high
	hal_Mfrc530_NSS_High();														// Set NSS high
}

void hal_Mfrc530_EXTI_Config(void) {
	EXTI_InitTypeDef EXTI_InitStructure;

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);

	EXTI_StructInit(&EXTI_InitStructure);
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);

	EXTI_ClearITPendingBit(EXTI0_IRQn);
}

void hal_Mfrc530_NVIC_Config(void) {
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	NVIC_ClearPendingIRQ(EXTI0_IRQn);

	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

void hal_Mfrc530_Delay(__IO uint32_t nTick) {
	for(; nTick != 0; nTick--);
}
