#include "STM32F4FMC.hpp"

/**
* @fn void STM32F4FMC::init(void)
* @brief Low level initialization for FMC module, STM32F4 specific
*/
void STM32F4FMC::init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	//GPIO clock enable
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | 
	RCC_AHB1Periph_GPIOE | 
	RCC_AHB1Periph_GPIOF |
	RCC_AHB1Periph_GPIOG, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
	
	//PG9 configured as FMC function CS# (FMC_NE2)
	GPIO_PinAFConfig(GPIOG, GPIO_PinSource9, GPIO_AF_FMC);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_Init(GPIOG, &GPIO_InitStructure);
	
	//PF0 configured as FMC function DC (FMC_A0)
	GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_FMC);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_Init(GPIOF, &GPIO_InitStructure);	
	
	//PE[7:15] configured as FMC data bus
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_FMC);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 |
																GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 |
																GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
																
	GPIO_Init(GPIOE, &GPIO_InitStructure);

	//PD0,1,4,5,8,9,10,14,15 configured as FMC data bus & WR#, RD#
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FMC);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 |
																GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9 |
																GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
																
	GPIO_Init(GPIOD, &GPIO_InitStructure);	
	
  /* Enable the FMC/FSMC interface clock */
	RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);	
}
