/*
 * my_EPI.c
 *
 *  Created on: gg/mmm/ccaa
 *      Author: cognome.nome
 *
 * funzioni per la RAM esterna
 *
 * EPI0S0  - PH0
 * EPI0S1  - PH1
 * EPI0S2  - PH2
 * EPI0S3  - PH3
 * EPI0S4  - PC7
 * EPI0S5  - PC6
 * EPI0S6  - PC5
 * EPI0S7  - PC4
 * EPI0S8  - PA6
 * EPI0S9  - PA7
 * EPI0S10 - PG1
 * EPI0S11 - PG0
 * EPI0S12 - PM3
 * EPI0S13 - PM2
 * EPI0S14 - PM1
 * EPI0S15 - PM0
 * EPI0S16 - PL0
 * EPI0S17 - PL1
 * EPI0S18 - PL2
 * EPI0S19 - PL3
 * EPI0S20 - PQ0
 * EPI0S21 - PQ1
 * EPI0S22 -
 * EPI0S23 -
 * EPI0S24 -
 * EPI0S25 -
 * EPI0S26 -
 * EPI0S27 -
 * EPI0S28 - PB3
 * EPI0S29 - PN2
 * EPI0S30 - PN3
 * EPI0S31 -
 *
 */

//==============================================================================
// Include files

#include "string.h"
#include "stdbool.h"
#include "stdint.h"

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_epi.h"

#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"
#include "driverlib/epi.h"
#include "driverlib/pin_map.h"

//==============================================================================
// Constants

#define EPI_PORTA_PINS (GPIO_PIN_7 | GPIO_PIN_6)
#define EPI_PORTB_PINS (GPIO_PIN_3)
#define EPI_PORTC_PINS (GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_5 | GPIO_PIN_4)
#define EPI_PORTG_PINS (GPIO_PIN_1 | GPIO_PIN_0)
#define EPI_PORTH_PINS (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_0)
#define EPI_PORTL_PINS (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_0)
#define EPI_PORTM_PINS (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_0)
#define EPI_PORTN_PINS (GPIO_PIN_3 | GPIO_PIN_2)
#define EPI_PORTQ_PINS (GPIO_PIN_1 | GPIO_PIN_0)

//==============================================================================
// Types

//==============================================================================
// Static global variables

static volatile unsigned short *g_EPISdram;

//==============================================================================
// Static functions

//==============================================================================
// Global variables


//==============================================================================
// Global functions

long EPI_init(void)
{
    // The EPI0 peripheral must be enabled for use.
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EPI0);
	
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);
	
	ROM_GPIOPinConfigure(GPIO_PH0_EPI0S0); // AD0
	ROM_GPIOPinConfigure(GPIO_PH1_EPI0S1); // AD1
	ROM_GPIOPinConfigure(GPIO_PH2_EPI0S2); // AD2
	ROM_GPIOPinConfigure(GPIO_PH3_EPI0S3); // AD3
	ROM_GPIOPinConfigure(GPIO_PC7_EPI0S4); // AD4
	ROM_GPIOPinConfigure(GPIO_PC6_EPI0S5); // AD5
	ROM_GPIOPinConfigure(GPIO_PC5_EPI0S6); // AD6
	ROM_GPIOPinConfigure(GPIO_PC4_EPI0S7); // AD7
	ROM_GPIOPinConfigure(GPIO_PA6_EPI0S8); // AD8
	ROM_GPIOPinConfigure(GPIO_PA7_EPI0S9); // AD9
	ROM_GPIOPinConfigure(GPIO_PG1_EPI0S10); // AD10
	ROM_GPIOPinConfigure(GPIO_PG0_EPI0S11); // AD11
	ROM_GPIOPinConfigure(GPIO_PM3_EPI0S12); // AD12
	ROM_GPIOPinConfigure(GPIO_PM2_EPI0S13); // AD13
	ROM_GPIOPinConfigure(GPIO_PM1_EPI0S14); // AD14
	ROM_GPIOPinConfigure(GPIO_PM0_EPI0S15); // AD15
	ROM_GPIOPinConfigure(GPIO_PL0_EPI0S16); // AD16
	ROM_GPIOPinConfigure(GPIO_PL1_EPI0S17); // AD17
	ROM_GPIOPinConfigure(GPIO_PL2_EPI0S18); // AD18
	ROM_GPIOPinConfigure(GPIO_PL3_EPI0S19); // AD19
	ROM_GPIOPinConfigure(GPIO_PQ0_EPI0S20); // AD20
	ROM_GPIOPinConfigure(GPIO_PQ1_EPI0S21); // AD21

	ROM_GPIOPinConfigure(GPIO_PB3_EPI0S28);// RD
	ROM_GPIOPinConfigure(GPIO_PN2_EPI0S29);// WR
	ROM_GPIOPinConfigure(GPIO_PN3_EPI0S30);// ALE

    GPIOPinTypeEPI(GPIO_PORTA_BASE, EPI_PORTA_PINS);
    GPIOPinTypeEPI(GPIO_PORTB_BASE, EPI_PORTB_PINS);
    GPIOPinTypeEPI(GPIO_PORTC_BASE, EPI_PORTC_PINS);
    GPIOPinTypeEPI(GPIO_PORTG_BASE, EPI_PORTG_PINS);
    GPIOPinTypeEPI(GPIO_PORTH_BASE, EPI_PORTH_PINS);
    GPIOPinTypeEPI(GPIO_PORTL_BASE, EPI_PORTL_PINS);
    GPIOPinTypeEPI(GPIO_PORTM_BASE, EPI_PORTM_PINS);
    GPIOPinTypeEPI(GPIO_PORTN_BASE, EPI_PORTN_PINS);
    GPIOPinTypeEPI(GPIO_PORTQ_BASE, EPI_PORTQ_PINS);
    
    EPIDividerSet(EPI0_BASE, 0);// 16MHz

    // Sets the usage mode of the EPI module.  For this example we will use
    // the HB16 mode to talk to the external 8MB SDRAM daughter card.
    //
    EPIModeSet(EPI0_BASE, EPI_MODE_HB16);
    
    EPIConfigHB16Set(EPI0_BASE, EPI_HB16_MODE_ADMUX | EPI_HB16_CSCFG_ALE | EPI_HB16_ALE_HIGH, 0);
    
    //
    // Set the address map.  The EPI0 is mapped from 0x60000000 to 0xCFFFFFFF.
    // For this example, we will start from a base address of 0x60000000 with
    // a size of 16MB.  We use 16MB so we have the ability to access the
    // entire 8MB SDRAM daughter card.  Since there is no 8MB option, so we
    // use the next closest one.  If you attempt to access an address higher
    // than 4Meg (since SDRAM mode uses 16-bit data, you have 4Meg of
    // of addresses by 16-bits of data) a fault will not occur since we
    // configured the EPI for 16MB addressability.  In the case that you do
    // access an address higher than 0x3FFFFF, the MSb of the address gets
    // ignored.
    EPIAddressMapSet(EPI0_BASE,  EPI_ADDR_RAM_SIZE_16MB | EPI_ADDR_RAM_BASE_8);
    
    //
    // Wait for the SDRAM wake-up to complete by polling the SDRAM
    // initialization sequence bit.  This bit is true when the SDRAM interface
    // is going through the initialization and false when the SDRAM interface
    // it is not in a wake-up period.
    while(HWREG(EPI0_BASE + EPI_O_STAT) &  EPI_STAT_INITSEQ)
    {
    }

	g_EPISdram = (unsigned short *)0x80000000;

	return 0;	
}

// lettura RAM
long EPI_read_RAM(unsigned long address, unsigned short *data)
{
	(*data) = g_EPISdram[address];

	return 0;
}

// scrittura RAM
long EPI_write_RAM(unsigned long address, unsigned short data)
{
	g_EPISdram[address] = data;

	return 0;
}


