1173 lines
39 KiB
C
1173 lines
39 KiB
C
/***************************************************************************//**
|
|
* @file
|
|
* @brief External Bus Interface (EBI) Peripheral API
|
|
* @author Energy Micro AS
|
|
* @version 3.0.0
|
|
*******************************************************************************
|
|
* @section License
|
|
* <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
|
|
*******************************************************************************
|
|
*
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
* including commercial applications, and to alter it and redistribute it
|
|
* freely, subject to the following restrictions:
|
|
*
|
|
* 1. The origin of this software must not be misrepresented; you must not
|
|
* claim that you wrote the original software.
|
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
* misrepresented as being the original software.
|
|
* 3. This notice may not be removed or altered from any source distribution.
|
|
*
|
|
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
|
|
* obligation to support this Software. Energy Micro AS is providing the
|
|
* Software "AS IS", with no express or implied warranties of any kind,
|
|
* including, but not limited to, any implied warranties of merchantability
|
|
* or fitness for any particular purpose or warranties against infringement
|
|
* of any proprietary rights of a third party.
|
|
*
|
|
* Energy Micro AS will not be liable for any consequential, incidental, or
|
|
* special damages, or any other relief, or for any claim by any third party,
|
|
* arising from your use of this Software.
|
|
*
|
|
******************************************************************************/
|
|
#include "em_ebi.h"
|
|
#if defined(EBI_COUNT) && (EBI_COUNT > 0)
|
|
#include "em_assert.h"
|
|
#include "em_bitband.h"
|
|
|
|
/***************************************************************************//**
|
|
* @addtogroup EM_Library
|
|
* @{
|
|
******************************************************************************/
|
|
|
|
/***************************************************************************//**
|
|
* @addtogroup EBI
|
|
* @brief EBI External Bus Interface (EBI) Peripheral API
|
|
* @{
|
|
******************************************************************************/
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure and enable External Bus Interface
|
|
*
|
|
* @param[in] ebiInit
|
|
* EBI configuration structure
|
|
*
|
|
* @note
|
|
* GPIO lines must be configured as PUSH_PULL for correct operation
|
|
* GPIO and EBI clocks must be enabled in the CMU
|
|
******************************************************************************/
|
|
void EBI_Init(const EBI_Init_TypeDef *ebiInit)
|
|
{
|
|
uint32_t ctrl = EBI->CTRL;
|
|
|
|
#if defined(_EFM32_GIANT_FAMILY)
|
|
/* Enable Independent Timing for devices that supports it */
|
|
ctrl |= EBI_CTRL_ITS;
|
|
|
|
/* Set polarity of address ready */
|
|
EBI_BankPolaritySet(ebiInit->banks, ebiLineARDY, ebiInit->ardyPolarity);
|
|
/* Set polarity of address latch enable */
|
|
EBI_BankPolaritySet(ebiInit->banks, ebiLineALE, ebiInit->alePolarity);
|
|
/* Set polarity of write enable */
|
|
EBI_BankPolaritySet(ebiInit->banks, ebiLineWE, ebiInit->wePolarity);
|
|
/* Set polarity of read enable */
|
|
EBI_BankPolaritySet(ebiInit->banks, ebiLineRE, ebiInit->rePolarity);
|
|
/* Set polarity of chip select lines */
|
|
EBI_BankPolaritySet(ebiInit->banks, ebiLineCS, ebiInit->csPolarity);
|
|
/* Set polarity of byte lane line */
|
|
EBI_BankPolaritySet(ebiInit->banks, ebiLineBL, ebiInit->blPolarity);
|
|
#else
|
|
/* Set polarity of address ready */
|
|
EBI_PolaritySet(ebiLineARDY, ebiInit->ardyPolarity);
|
|
/* Set polarity of address latch enable */
|
|
EBI_PolaritySet(ebiLineALE, ebiInit->alePolarity);
|
|
/* Set polarity of write enable */
|
|
EBI_PolaritySet(ebiLineWE, ebiInit->wePolarity);
|
|
/* Set polarity of read enable */
|
|
EBI_PolaritySet(ebiLineRE, ebiInit->rePolarity);
|
|
/* Set polarity of chip select lines */
|
|
EBI_PolaritySet(ebiLineCS, ebiInit->csPolarity);
|
|
#endif
|
|
|
|
/* Configure EBI mode and control settings */
|
|
#if defined(_EFM32_GIANT_FAMILY)
|
|
if (ebiInit->banks & EBI_BANK0)
|
|
{
|
|
ctrl &= ~(_EBI_CTRL_MODE_MASK|
|
|
_EBI_CTRL_ARDYEN_MASK|
|
|
_EBI_CTRL_ARDYTODIS_MASK|
|
|
_EBI_CTRL_BL_MASK|
|
|
_EBI_CTRL_NOIDLE_MASK|
|
|
_EBI_CTRL_BANK0EN_MASK);
|
|
ctrl |= (ebiInit->mode << _EBI_CTRL_MODE_SHIFT);
|
|
ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDYEN_SHIFT);
|
|
ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTODIS_SHIFT);
|
|
ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL_SHIFT);
|
|
ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE_SHIFT);
|
|
if ( ebiInit->enable)
|
|
{
|
|
ctrl |= EBI_CTRL_BANK0EN;
|
|
}
|
|
}
|
|
if (ebiInit->banks & EBI_BANK1)
|
|
{
|
|
ctrl &= ~(_EBI_CTRL_BL1_MASK|
|
|
_EBI_CTRL_MODE1_MASK|
|
|
_EBI_CTRL_ARDY1EN_MASK|
|
|
_EBI_CTRL_ARDYTO1DIS_MASK|
|
|
_EBI_CTRL_NOIDLE1_MASK|
|
|
_EBI_CTRL_BANK1EN_MASK);
|
|
ctrl |= (ebiInit->mode << _EBI_CTRL_MODE1_SHIFT);
|
|
ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDY1EN_SHIFT);
|
|
ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTO1DIS_SHIFT);
|
|
ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL1_SHIFT);
|
|
ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE1_SHIFT);
|
|
if ( ebiInit->enable)
|
|
{
|
|
ctrl |= EBI_CTRL_BANK1EN;
|
|
}
|
|
}
|
|
if (ebiInit->banks & EBI_BANK2)
|
|
{
|
|
ctrl &= ~(_EBI_CTRL_BL2_MASK|
|
|
_EBI_CTRL_MODE2_MASK|
|
|
_EBI_CTRL_ARDY2EN_MASK|
|
|
_EBI_CTRL_ARDYTO2DIS_MASK|
|
|
_EBI_CTRL_NOIDLE2_MASK|
|
|
_EBI_CTRL_BANK2EN_MASK);
|
|
ctrl |= (ebiInit->mode << _EBI_CTRL_MODE2_SHIFT);
|
|
ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDY2EN_SHIFT);
|
|
ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTO2DIS_SHIFT);
|
|
ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL2_SHIFT);
|
|
ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE2_SHIFT);
|
|
if ( ebiInit->enable)
|
|
{
|
|
ctrl |= EBI_CTRL_BANK2EN;
|
|
}
|
|
}
|
|
if (ebiInit->banks & EBI_BANK3)
|
|
{
|
|
ctrl &= ~(_EBI_CTRL_BL3_MASK|
|
|
_EBI_CTRL_MODE3_MASK|
|
|
_EBI_CTRL_ARDY3EN_MASK|
|
|
_EBI_CTRL_ARDYTO3DIS_MASK|
|
|
_EBI_CTRL_NOIDLE3_MASK|
|
|
_EBI_CTRL_BANK3EN_MASK);
|
|
ctrl |= (ebiInit->mode << _EBI_CTRL_MODE3_SHIFT);
|
|
ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDY3EN_SHIFT);
|
|
ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTO3DIS_SHIFT);
|
|
ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL3_SHIFT);
|
|
ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE3_SHIFT);
|
|
if ( ebiInit->enable)
|
|
{
|
|
ctrl |= EBI_CTRL_BANK3EN;
|
|
}
|
|
}
|
|
#else
|
|
ctrl &= ~(_EBI_CTRL_MODE_MASK|
|
|
_EBI_CTRL_ARDYEN_MASK|
|
|
_EBI_CTRL_ARDYTODIS_MASK|
|
|
_EBI_CTRL_BANK0EN_MASK|
|
|
_EBI_CTRL_BANK1EN_MASK|
|
|
_EBI_CTRL_BANK2EN_MASK|
|
|
_EBI_CTRL_BANK3EN_MASK);
|
|
if ( ebiInit->enable)
|
|
{
|
|
if ( ebiInit->banks & EBI_BANK0 )
|
|
{
|
|
ctrl |= EBI_CTRL_BANK0EN;
|
|
}
|
|
if ( ebiInit->banks & EBI_BANK1 )
|
|
{
|
|
ctrl |= EBI_CTRL_BANK1EN;
|
|
}
|
|
if ( ebiInit->banks & EBI_BANK2 )
|
|
{
|
|
ctrl |= EBI_CTRL_BANK2EN;
|
|
}
|
|
if ( ebiInit->banks & EBI_BANK3 )
|
|
{
|
|
ctrl |= EBI_CTRL_BANK3EN;
|
|
}
|
|
}
|
|
ctrl |= ebiInit->mode;
|
|
ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDYEN_SHIFT);
|
|
ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTODIS_SHIFT);
|
|
#endif
|
|
|
|
/* Configure timing */
|
|
#if defined(_EFM32_GIANT_FAMILY)
|
|
EBI_BankReadTimingSet(ebiInit->banks,
|
|
ebiInit->readSetupCycles,
|
|
ebiInit->readStrobeCycles,
|
|
ebiInit->readHoldCycles);
|
|
EBI_BankReadTimingConfig(ebiInit->banks,
|
|
ebiInit->readPageMode,
|
|
ebiInit->readPrefetch,
|
|
ebiInit->readHalfRE);
|
|
EBI_BankWriteTimingSet(ebiInit->banks,
|
|
ebiInit->writeSetupCycles,
|
|
ebiInit->writeStrobeCycles,
|
|
ebiInit->writeHoldCycles);
|
|
EBI_BankWriteTimingConfig(ebiInit->banks,
|
|
ebiInit->writeBufferDisable,
|
|
ebiInit->writeHalfWE);
|
|
EBI_BankAddressTimingSet(ebiInit->banks,
|
|
ebiInit->addrSetupCycles,
|
|
ebiInit->addrHoldCycles);
|
|
EBI_BankAddressTimingConfig(ebiInit->banks,
|
|
ebiInit->addrHalfALE);
|
|
#else
|
|
EBI_ReadTimingSet(ebiInit->readSetupCycles,
|
|
ebiInit->readStrobeCycles,
|
|
ebiInit->readHoldCycles);
|
|
EBI_WriteTimingSet(ebiInit->writeSetupCycles,
|
|
ebiInit->writeStrobeCycles,
|
|
ebiInit->writeHoldCycles);
|
|
EBI_AddressTimingSet(ebiInit->addrSetupCycles,
|
|
ebiInit->addrHoldCycles);
|
|
#endif
|
|
|
|
/* Configure Adress Latch Enable */
|
|
switch (ebiInit->mode)
|
|
{
|
|
case ebiModeD16A16ALE:
|
|
case ebiModeD8A24ALE:
|
|
/* Address Latch Enable */
|
|
BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_ALEPEN_SHIFT, 1);
|
|
break;
|
|
#if defined(_EFM32_GIANT_FAMILY)
|
|
case ebiModeD16:
|
|
#endif
|
|
case ebiModeD8A8:
|
|
/* Make sure Address Latch is disabled */
|
|
BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_ALEPEN_SHIFT, 0);
|
|
break;
|
|
}
|
|
#if defined(_EFM32_GIANT_FAMILY)
|
|
/* Limit pin enable */
|
|
EBI->ROUTE = (EBI->ROUTE & ~_EBI_ROUTE_ALB_MASK) | ebiInit->aLow;
|
|
EBI->ROUTE = (EBI->ROUTE & ~_EBI_ROUTE_APEN_MASK) | ebiInit->aHigh;
|
|
/* Location */
|
|
EBI->ROUTE = (EBI->ROUTE & ~_EBI_ROUTE_LOCATION_MASK) | ebiInit->location;
|
|
|
|
/* Enable EBI BL pin if necessary */
|
|
if(ctrl & (_EBI_CTRL_BL_MASK|_EBI_CTRL_BL1_MASK|_EBI_CTRL_BL2_MASK|_EBI_CTRL_BL3_MASK))
|
|
{
|
|
BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_BLPEN_SHIFT, ebiInit->blEnable);
|
|
}
|
|
#endif
|
|
/* Enable EBI pins EBI_WEn and EBI_REn */
|
|
BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_EBIPEN_SHIFT, 1);
|
|
|
|
/* Enable chip select lines */
|
|
EBI_ChipSelectEnable(ebiInit->csLines, true);
|
|
|
|
/* Activate new configuration */
|
|
EBI->CTRL = ctrl;
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Disable External Bus Interface
|
|
******************************************************************************/
|
|
void EBI_Disable(void)
|
|
{
|
|
/* Disable pins */
|
|
EBI->ROUTE = _EBI_ROUTE_RESETVALUE;
|
|
/* Disable banks */
|
|
EBI->CTRL = _EBI_CTRL_RESETVALUE;
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Enable or disable EBI Bank
|
|
*
|
|
* @param[in] banks
|
|
* Banks to reconfigure, mask of EBI_BANK<n> flags
|
|
*
|
|
* @param[in] enable
|
|
* True to enable, false to disable
|
|
******************************************************************************/
|
|
void EBI_BankEnable(uint32_t banks, bool enable)
|
|
{
|
|
if (banks & EBI_BANK0)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BANK0EN_SHIFT, enable);
|
|
}
|
|
if (banks & EBI_BANK1)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BANK1EN_SHIFT, enable);
|
|
}
|
|
if (banks & EBI_BANK2)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BANK2EN_SHIFT, enable);
|
|
}
|
|
if (banks & EBI_BANK3)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BANK3EN_SHIFT, enable);
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Return base address of EBI bank
|
|
*
|
|
* @param[in] bank
|
|
* Bank to return start address for
|
|
*
|
|
* @return
|
|
* Absolute address of bank
|
|
******************************************************************************/
|
|
uint32_t EBI_BankAddress(uint32_t bank)
|
|
{
|
|
#if defined (_EFM32_GIANT_FAMILY)
|
|
if(EBI->CTRL & EBI_CTRL_ALTMAP)
|
|
{
|
|
switch (bank)
|
|
{
|
|
case EBI_BANK0:
|
|
return(EBI_MEM_BASE);
|
|
|
|
case EBI_BANK1:
|
|
return(EBI_MEM_BASE + 0x10000000UL);
|
|
|
|
case EBI_BANK2:
|
|
return(EBI_MEM_BASE + 0x20000000UL);
|
|
|
|
case EBI_BANK3:
|
|
return(EBI_MEM_BASE + 0x30000000UL);
|
|
|
|
default:
|
|
EFM_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
switch (bank)
|
|
{
|
|
case EBI_BANK0:
|
|
return(EBI_MEM_BASE);
|
|
|
|
case EBI_BANK1:
|
|
return(EBI_MEM_BASE + 0x04000000UL);
|
|
|
|
case EBI_BANK2:
|
|
return(EBI_MEM_BASE + 0x08000000UL);
|
|
|
|
case EBI_BANK3:
|
|
return(EBI_MEM_BASE + 0x0C000000UL);
|
|
|
|
default:
|
|
EFM_ASSERT(0);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Enable or disable EBI Chip Select
|
|
*
|
|
* @param[in] cs
|
|
* ChipSelect lines to reconfigure, mask of EBI_CS<n> flags
|
|
*
|
|
* @param[in] enable
|
|
* True to enable, false to disable
|
|
******************************************************************************/
|
|
void EBI_ChipSelectEnable(uint32_t cs, bool enable)
|
|
{
|
|
if (cs & EBI_CS0)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_CS0PEN_SHIFT, enable);
|
|
}
|
|
if (cs & EBI_CS1)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_CS1PEN_SHIFT, enable);
|
|
}
|
|
if (cs & EBI_CS2)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_CS2PEN_SHIFT, enable);
|
|
}
|
|
if (cs & EBI_CS3)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->ROUTE), _EBI_ROUTE_CS3PEN_SHIFT, enable);
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure EBI pin polarity
|
|
*
|
|
* @param[in] line
|
|
* Which pin/line to configure
|
|
*
|
|
* @param[in] polarity
|
|
* Active high, or active low
|
|
******************************************************************************/
|
|
void EBI_PolaritySet(EBI_Line_TypeDef line, EBI_Polarity_TypeDef polarity)
|
|
{
|
|
switch (line)
|
|
{
|
|
case ebiLineARDY:
|
|
BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_ARDYPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineALE:
|
|
BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_ALEPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineWE:
|
|
BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_WEPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineRE:
|
|
BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_REPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineCS:
|
|
BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_CSPOL_SHIFT, polarity);
|
|
break;
|
|
#if defined (_EFM32_GIANT_FAMILY)
|
|
case ebiLineBL:
|
|
BITBAND_Peripheral(&(EBI->POLARITY), _EBI_POLARITY_BLPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineTFTVSync:
|
|
BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_VSYNCPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineTFTHSync:
|
|
BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_HSYNCPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineTFTDataEn:
|
|
BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DATAENPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineTFTDClk:
|
|
BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DCLKPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineTFTCS:
|
|
BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_CSPOL_SHIFT, polarity);
|
|
break;
|
|
#endif
|
|
default:
|
|
EFM_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure timing values of read bus accesses
|
|
*
|
|
* @param[in] setupCycles
|
|
* Number of clock cycles for address setup before REn is asserted
|
|
*
|
|
* @param[in] strobeCycles
|
|
* The number of cycles the REn is held active. After the specified number of
|
|
* cycles, data is read. If set to 0, 1 cycle is inserted by HW
|
|
*
|
|
* @param[in] holdCycles
|
|
* The number of cycles CSn is held active after the REn is dessarted
|
|
******************************************************************************/
|
|
void EBI_ReadTimingSet(int setupCycles, int strobeCycles, int holdCycles)
|
|
{
|
|
uint32_t readTiming;
|
|
|
|
/* Check that timings are within limits */
|
|
EFM_ASSERT(setupCycles < 4);
|
|
EFM_ASSERT(strobeCycles < 16);
|
|
EFM_ASSERT(holdCycles < 4);
|
|
|
|
/* Configure timing values */
|
|
readTiming = (setupCycles << _EBI_RDTIMING_RDSETUP_SHIFT) |
|
|
(strobeCycles << _EBI_RDTIMING_RDSTRB_SHIFT) |
|
|
(holdCycles << _EBI_RDTIMING_RDHOLD_SHIFT);
|
|
|
|
|
|
EBI->RDTIMING = (EBI->RDTIMING &
|
|
~(_EBI_RDTIMING_RDSETUP_MASK |
|
|
_EBI_RDTIMING_RDSTRB_MASK |
|
|
_EBI_RDTIMING_RDHOLD_MASK)) | readTiming;
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure timing values of write bus accesses
|
|
*
|
|
* @param[in] setupCycles
|
|
* Number of clock cycles for address setup before WEn is asserted
|
|
*
|
|
* @param[in] strobeCycles
|
|
* Number of cycles WEn is held active. If set to 0, 1 cycle is inserted by HW
|
|
*
|
|
* @param[in] holdCycles
|
|
* Number of cycles CSn is held active after the WEn is deasserted
|
|
******************************************************************************/
|
|
void EBI_WriteTimingSet(int setupCycles, int strobeCycles, int holdCycles)
|
|
{
|
|
uint32_t writeTiming;
|
|
|
|
/* Check that timings are within limits */
|
|
EFM_ASSERT(setupCycles < 4);
|
|
EFM_ASSERT(strobeCycles < 16);
|
|
EFM_ASSERT(holdCycles < 4);
|
|
|
|
/* Configure timing values */
|
|
writeTiming = (setupCycles << _EBI_WRTIMING_WRSETUP_SHIFT) |
|
|
(strobeCycles << _EBI_WRTIMING_WRSTRB_SHIFT) |
|
|
(holdCycles << _EBI_WRTIMING_WRHOLD_SHIFT);
|
|
|
|
EBI->WRTIMING = (EBI->WRTIMING &
|
|
~(_EBI_WRTIMING_WRSETUP_MASK |
|
|
_EBI_WRTIMING_WRSTRB_MASK |
|
|
_EBI_WRTIMING_WRHOLD_MASK)) | writeTiming;
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure timing values of address latch bus accesses
|
|
*
|
|
* @param[in] setupCycles
|
|
* Sets the number of cycles the address is held after ALE is asserted
|
|
*
|
|
* @param[in] holdCycles
|
|
* Sets the number of cycles the address is driven onto the ADDRDAT bus before
|
|
* ALE is asserted. If set 0, 1 cycle is inserted by HW
|
|
******************************************************************************/
|
|
void EBI_AddressTimingSet(int setupCycles, int holdCycles)
|
|
{
|
|
uint32_t addressLatchTiming;
|
|
|
|
/* Check that timing values are within limits */
|
|
EFM_ASSERT(setupCycles < 4);
|
|
EFM_ASSERT(holdCycles < 4);
|
|
|
|
/* Configure address latch timing values */
|
|
addressLatchTiming = (setupCycles << _EBI_ADDRTIMING_ADDRSETUP_SHIFT) |
|
|
(holdCycles << _EBI_ADDRTIMING_ADDRHOLD_SHIFT);
|
|
|
|
EBI->ADDRTIMING = (EBI->ADDRTIMING &
|
|
~(_EBI_ADDRTIMING_ADDRSETUP_MASK |
|
|
_EBI_ADDRTIMING_ADDRHOLD_MASK)) | addressLatchTiming;
|
|
}
|
|
|
|
#if defined(_EFM32_GIANT_FAMILY)
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure and initialize TFT Direct Drive
|
|
*
|
|
* @param[in] ebiTFTInit
|
|
* TFT Initialization structure
|
|
******************************************************************************/
|
|
void EBI_TFTInit(const EBI_TFTInit_TypeDef *ebiTFTInit)
|
|
{
|
|
uint32_t ctrl;
|
|
|
|
/* Configure base address for frame buffer offset to EBI bank */
|
|
EBI_TFTFrameBaseSet(ebiTFTInit->addressOffset);
|
|
|
|
/* Configure display size and porch areas */
|
|
EBI_TFTSizeSet(ebiTFTInit->hsize,
|
|
ebiTFTInit->vsize);
|
|
EBI_TFTHPorchSet(ebiTFTInit->hPorchFront,
|
|
ebiTFTInit->hPorchBack,
|
|
ebiTFTInit->hPulseWidth);
|
|
EBI_TFTVPorchSet(ebiTFTInit->vPorchFront,
|
|
ebiTFTInit->vPorchBack,
|
|
ebiTFTInit->vPulseWidth);
|
|
|
|
/* Configure timing settings */
|
|
EBI_TFTTimingSet(ebiTFTInit->dclkPeriod,
|
|
ebiTFTInit->startPosition,
|
|
ebiTFTInit->setupCycles,
|
|
ebiTFTInit->holdCycles);
|
|
|
|
/* Configure line polarity settings */
|
|
EBI_PolaritySet(ebiLineTFTCS, ebiTFTInit->csPolarity);
|
|
EBI_PolaritySet(ebiLineTFTDClk, ebiTFTInit->dclkPolarity);
|
|
EBI_PolaritySet(ebiLineTFTDataEn, ebiTFTInit->dataenPolarity);
|
|
EBI_PolaritySet(ebiLineTFTVSync, ebiTFTInit->vsyncPolarity);
|
|
EBI_PolaritySet(ebiLineTFTHSync, ebiTFTInit->hsyncPolarity);
|
|
|
|
/* Main control, EBI bank select, mask and blending configuration */
|
|
ctrl =
|
|
(uint32_t)(ebiTFTInit->bank) |
|
|
(uint32_t)(ebiTFTInit->width) |
|
|
(uint32_t)(ebiTFTInit->colSrc) |
|
|
(uint32_t)(ebiTFTInit->interleave) |
|
|
(uint32_t)(ebiTFTInit->fbTrigger) |
|
|
(uint32_t)(ebiTFTInit->shiftDClk == true ? (1 << _EBI_TFTCTRL_SHIFTDCLKEN_SHIFT) : 0) |
|
|
(uint32_t)(ebiTFTInit->maskBlend) |
|
|
(uint32_t)(ebiTFTInit->driveMode);
|
|
|
|
EBI->TFTCTRL = ctrl;
|
|
|
|
/* Enable TFT pins */
|
|
if (ebiTFTInit->driveMode != ebiTFTDDModeDisabled)
|
|
{
|
|
EBI->ROUTE |= (EBI_ROUTE_TFTPEN);
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure and initialize TFT size settings
|
|
*
|
|
* @param[in] horizontal
|
|
* TFT display horizontal size in pixels
|
|
* @param[in] vertical
|
|
* TFT display vertical size in pixels
|
|
******************************************************************************/
|
|
void EBI_TFTSizeSet(uint32_t horizontal, uint32_t vertical)
|
|
{
|
|
EFM_ASSERT((horizontal-1) < 1024);
|
|
EFM_ASSERT((vertical-1) < 1024);
|
|
|
|
EBI->TFTSIZE = ((horizontal-1) << _EBI_TFTSIZE_HSZ_SHIFT) |
|
|
((vertical-1) << _EBI_TFTSIZE_VSZ_SHIFT);
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure and initialize Horizontal Porch Settings
|
|
*
|
|
* @param[in] front
|
|
* Horizontal front porch size in pixels
|
|
* @param[in] back
|
|
* Horizontal back porch size in pixels
|
|
* @param[in] pulseWidth
|
|
* Horizontal synchronization pulse width. Set to required -1.
|
|
******************************************************************************/
|
|
void EBI_TFTHPorchSet(int front, int back, int pulseWidth)
|
|
{
|
|
EFM_ASSERT(front < 256);
|
|
EFM_ASSERT(back < 256);
|
|
EFM_ASSERT((pulseWidth-1) < 128);
|
|
|
|
EBI->TFTHPORCH = (front << _EBI_TFTHPORCH_HFPORCH_SHIFT) |
|
|
(back << _EBI_TFTHPORCH_HBPORCH_SHIFT) |
|
|
((pulseWidth-1) << _EBI_TFTHPORCH_HSYNC_SHIFT);
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure Vertical Porch Settings
|
|
*
|
|
* @param[in] front
|
|
* Vertical front porch size in pixels
|
|
* @param[in] back
|
|
* Vertical back porch size in pixels
|
|
* @param[in] pulseWidth
|
|
* Vertical synchronization pulse width. Set to required -1.
|
|
******************************************************************************/
|
|
void EBI_TFTVPorchSet(int front, int back, int pulseWidth)
|
|
{
|
|
EFM_ASSERT(front < 256);
|
|
EFM_ASSERT(back < 256);
|
|
EFM_ASSERT((pulseWidth-1) < 128);
|
|
|
|
EBI->TFTVPORCH = (front << _EBI_TFTVPORCH_VFPORCH_SHIFT) |
|
|
(back << _EBI_TFTVPORCH_VBPORCH_SHIFT) |
|
|
((pulseWidth-1) << _EBI_TFTVPORCH_VSYNC_SHIFT);
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure TFT Direct Drive Timing Settings
|
|
*
|
|
* @param[in] dclkPeriod
|
|
* DCLK period in internal cycles
|
|
*
|
|
* @param[in] start
|
|
* Starting position of external direct drive, relative to DCLK inactive edge
|
|
*
|
|
* @param[in] setup
|
|
* Number of cycles RGB data is driven before active edge of DCLK
|
|
*
|
|
* @param[in] hold
|
|
* Number of cycles RGB data is held after active edge of DCLK
|
|
******************************************************************************/
|
|
void EBI_TFTTimingSet(int dclkPeriod, int start, int setup, int hold)
|
|
{
|
|
EFM_ASSERT(dclkPeriod < 2048);
|
|
EFM_ASSERT(start < 2048);
|
|
EFM_ASSERT(setup < 4);
|
|
EFM_ASSERT(hold < 4);
|
|
|
|
EBI->TFTTIMING = (dclkPeriod << _EBI_TFTTIMING_DCLKPERIOD_SHIFT) |
|
|
(start << _EBI_TFTTIMING_TFTSTART_SHIFT) |
|
|
(setup << _EBI_TFTTIMING_TFTSETUP_SHIFT) |
|
|
(hold << _EBI_TFTTIMING_TFTHOLD_SHIFT);
|
|
}
|
|
#endif
|
|
|
|
#if defined(_EFM32_GIANT_FAMILY)
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure read operation parameters for selected bank
|
|
*
|
|
* @param[in] banks
|
|
* Mask of memory bank(s) to configure write timing for
|
|
*
|
|
* @param[in] pageMode
|
|
* Enables or disables half cycle WE strobe in last strobe cycle
|
|
*
|
|
* @param[in] prefetch
|
|
* Enables or disables half cycle WE strobe in last strobe cycle
|
|
*
|
|
* @param[in] halfRE
|
|
* Enables or disables half cycle WE strobe in last strobe cycle
|
|
******************************************************************************/
|
|
void EBI_BankReadTimingConfig(uint32_t banks, bool pageMode, bool prefetch, bool halfRE)
|
|
{
|
|
/* Verify only valid banks are used */
|
|
EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
|
|
|
|
/* Configure read operation parameters */
|
|
if( banks & EBI_BANK0 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->RDTIMING, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
|
|
BITBAND_Peripheral(&EBI->RDTIMING, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
|
|
BITBAND_Peripheral(&EBI->RDTIMING, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
|
|
}
|
|
if( banks & EBI_BANK1 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->RDTIMING1, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
|
|
BITBAND_Peripheral(&EBI->RDTIMING1, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
|
|
BITBAND_Peripheral(&EBI->RDTIMING1, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
|
|
}
|
|
if( banks & EBI_BANK2 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->RDTIMING2, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
|
|
BITBAND_Peripheral(&EBI->RDTIMING2, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
|
|
BITBAND_Peripheral(&EBI->RDTIMING2, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
|
|
}
|
|
if( banks & EBI_BANK3 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->RDTIMING3, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
|
|
BITBAND_Peripheral(&EBI->RDTIMING3, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
|
|
BITBAND_Peripheral(&EBI->RDTIMING3, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
|
|
}
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure timing values of read bus accesses
|
|
*
|
|
* @param[in] banks
|
|
* Mask of memory bank(s) to configure timing for
|
|
*
|
|
* @param[in] setupCycles
|
|
* Number of clock cycles for address setup before REn is asserted
|
|
*
|
|
* @param[in] strobeCycles
|
|
* The number of cycles the REn is held active. After the specified number of
|
|
* cycles, data is read. If set to 0, 1 cycle is inserted by HW
|
|
*
|
|
* @param[in] holdCycles
|
|
* The number of cycles CSn is held active after the REn is dessarted
|
|
******************************************************************************/
|
|
void EBI_BankReadTimingSet(uint32_t banks, int setupCycles, int strobeCycles, int holdCycles)
|
|
{
|
|
uint32_t readTiming;
|
|
|
|
/* Verify only valid banks are used */
|
|
EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
|
|
|
|
/* Check that timings are within limits */
|
|
EFM_ASSERT(setupCycles < 4);
|
|
EFM_ASSERT(strobeCycles < 64);
|
|
EFM_ASSERT(holdCycles < 4);
|
|
|
|
/* Configure timing values */
|
|
readTiming = (setupCycles << _EBI_RDTIMING_RDSETUP_SHIFT) |
|
|
(strobeCycles << _EBI_RDTIMING_RDSTRB_SHIFT) |
|
|
(holdCycles << _EBI_RDTIMING_RDHOLD_SHIFT);
|
|
|
|
if (banks & EBI_BANK0)
|
|
{
|
|
EBI->RDTIMING = (EBI->RDTIMING &
|
|
~(_EBI_RDTIMING_RDSETUP_MASK |
|
|
_EBI_RDTIMING_RDSTRB_MASK |
|
|
_EBI_RDTIMING_RDHOLD_MASK)) | readTiming;
|
|
}
|
|
if (banks & EBI_BANK1)
|
|
{
|
|
EBI->RDTIMING1 = (EBI->RDTIMING1 &
|
|
~(_EBI_RDTIMING1_RDSETUP_MASK |
|
|
_EBI_RDTIMING1_RDSTRB_MASK |
|
|
_EBI_RDTIMING1_RDHOLD_MASK)) | readTiming;
|
|
}
|
|
if (banks & EBI_BANK2)
|
|
{
|
|
EBI->RDTIMING2 = (EBI->RDTIMING2 &
|
|
~(_EBI_RDTIMING2_RDSETUP_MASK |
|
|
_EBI_RDTIMING2_RDSTRB_MASK |
|
|
_EBI_RDTIMING2_RDHOLD_MASK)) | readTiming;
|
|
}
|
|
if (banks & EBI_BANK3)
|
|
{
|
|
EBI->RDTIMING3 = (EBI->RDTIMING3 &
|
|
~(_EBI_RDTIMING3_RDSETUP_MASK |
|
|
_EBI_RDTIMING3_RDSTRB_MASK |
|
|
_EBI_RDTIMING3_RDHOLD_MASK)) | readTiming;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure write operation parameters for selected bank
|
|
*
|
|
* @param[in] banks
|
|
* Mask of memory bank(s) to configure write timing for
|
|
*
|
|
* @param[in] writeBufferDisable
|
|
* If true, disable the write buffer
|
|
*
|
|
* @param[in] halfWE
|
|
* Enables or disables half cycle WE strobe in last strobe cycle
|
|
******************************************************************************/
|
|
void EBI_BankWriteTimingConfig(uint32_t banks, bool writeBufDisable, bool halfWE)
|
|
{
|
|
/* Verify only valid banks are used */
|
|
EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
|
|
|
|
/* Configure write operation parameters */
|
|
if( banks & EBI_BANK0 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->WRTIMING, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
|
|
BITBAND_Peripheral(&EBI->WRTIMING, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
|
|
}
|
|
if( banks & EBI_BANK1 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->WRTIMING1, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
|
|
BITBAND_Peripheral(&EBI->WRTIMING1, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
|
|
}
|
|
if( banks & EBI_BANK2 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->WRTIMING2, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
|
|
BITBAND_Peripheral(&EBI->WRTIMING2, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
|
|
}
|
|
if( banks & EBI_BANK3 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->WRTIMING3, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
|
|
BITBAND_Peripheral(&EBI->WRTIMING3, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure timing values of write bus accesses
|
|
*
|
|
* @param[in] banks
|
|
* Mask of memory bank(s) to configure write timing for
|
|
*
|
|
* @param[in] setupCycles
|
|
* Number of clock cycles for address setup before WEn is asserted
|
|
*
|
|
* @param[in] strobeCycles
|
|
* Number of cycles WEn is held active. If set to 0, 1 cycle is inserted by HW
|
|
*
|
|
* @param[in] holdCycles
|
|
* Number of cycles CSn is held active after the WEn is deasserted
|
|
******************************************************************************/
|
|
void EBI_BankWriteTimingSet(uint32_t banks, int setupCycles, int strobeCycles, int holdCycles)
|
|
{
|
|
uint32_t writeTiming;
|
|
|
|
/* Verify only valid banks are used */
|
|
EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
|
|
|
|
/* Check that timings are within limits */
|
|
EFM_ASSERT(setupCycles < 4);
|
|
EFM_ASSERT(strobeCycles < 64);
|
|
EFM_ASSERT(holdCycles < 4);
|
|
|
|
/* Configure timing values */
|
|
writeTiming = (setupCycles << _EBI_WRTIMING_WRSETUP_SHIFT) |
|
|
(strobeCycles << _EBI_WRTIMING_WRSTRB_SHIFT) |
|
|
(holdCycles << _EBI_WRTIMING_WRHOLD_SHIFT);
|
|
|
|
if (banks & EBI_BANK0)
|
|
{
|
|
EBI->WRTIMING = (EBI->WRTIMING &
|
|
~(_EBI_WRTIMING_WRSETUP_MASK |
|
|
_EBI_WRTIMING_WRSTRB_MASK |
|
|
_EBI_WRTIMING_WRHOLD_MASK)) | writeTiming;
|
|
}
|
|
if (banks & EBI_BANK1)
|
|
{
|
|
EBI->WRTIMING1 = (EBI->WRTIMING1 &
|
|
~(_EBI_WRTIMING1_WRSETUP_MASK |
|
|
_EBI_WRTIMING1_WRSTRB_MASK |
|
|
_EBI_WRTIMING1_WRHOLD_MASK)) | writeTiming;
|
|
}
|
|
if (banks & EBI_BANK2)
|
|
{
|
|
EBI->WRTIMING2 = (EBI->WRTIMING2 &
|
|
~(_EBI_WRTIMING2_WRSETUP_MASK |
|
|
_EBI_WRTIMING2_WRSTRB_MASK |
|
|
_EBI_WRTIMING2_WRHOLD_MASK)) | writeTiming;
|
|
}
|
|
if (banks & EBI_BANK3)
|
|
{
|
|
EBI->WRTIMING3 = (EBI->WRTIMING3 &
|
|
~(_EBI_WRTIMING3_WRSETUP_MASK |
|
|
_EBI_WRTIMING3_WRSTRB_MASK |
|
|
_EBI_WRTIMING3_WRHOLD_MASK)) | writeTiming;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure address operation parameters for selected bank
|
|
*
|
|
* @param[in] banks
|
|
* Mask of memory bank(s) to configure write timing for
|
|
*
|
|
* @param[in] halfALE
|
|
* Enables or disables half cycle ALE strobe in last strobe cycle
|
|
******************************************************************************/
|
|
void EBI_BankAddressTimingConfig(uint32_t banks, bool halfALE)
|
|
{
|
|
/* Verify only valid banks are used */
|
|
EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
|
|
|
|
if( banks & EBI_BANK0 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->ADDRTIMING, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
|
|
}
|
|
if( banks & EBI_BANK1 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->ADDRTIMING1, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
|
|
}
|
|
if( banks & EBI_BANK2 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->ADDRTIMING2, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
|
|
}
|
|
if( banks & EBI_BANK3 )
|
|
{
|
|
BITBAND_Peripheral(&EBI->ADDRTIMING3, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure timing values of address latch bus accesses
|
|
*
|
|
* @param[in] banks
|
|
* Mask of memory bank(s) to configure address timing for
|
|
*
|
|
* @param[in] setupCycles
|
|
* Sets the number of cycles the address is held after ALE is asserted
|
|
*
|
|
* @param[in] holdCycles
|
|
* Sets the number of cycles the address is driven onto the ADDRDAT bus before
|
|
* ALE is asserted. If set 0, 1 cycle is inserted by HW
|
|
******************************************************************************/
|
|
void EBI_BankAddressTimingSet(uint32_t banks, int setupCycles, int holdCycles)
|
|
{
|
|
uint32_t addressLatchTiming;
|
|
|
|
/* Verify only valid banks are used */
|
|
EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
|
|
|
|
/* Check that timing values are within limits */
|
|
EFM_ASSERT(setupCycles < 4);
|
|
EFM_ASSERT(holdCycles < 4);
|
|
|
|
/* Configure address latch timing values */
|
|
addressLatchTiming = (setupCycles << _EBI_ADDRTIMING_ADDRSETUP_SHIFT) |
|
|
(holdCycles << _EBI_ADDRTIMING_ADDRHOLD_SHIFT);
|
|
|
|
if (banks & EBI_BANK0)
|
|
{
|
|
EBI->ADDRTIMING = (EBI->ADDRTIMING &
|
|
~(_EBI_ADDRTIMING_ADDRSETUP_MASK |
|
|
_EBI_ADDRTIMING_ADDRHOLD_MASK)) | addressLatchTiming;
|
|
}
|
|
if (banks & EBI_BANK1)
|
|
{
|
|
EBI->ADDRTIMING1 = (EBI->ADDRTIMING1 &
|
|
~(_EBI_ADDRTIMING1_ADDRSETUP_MASK |
|
|
_EBI_ADDRTIMING1_ADDRHOLD_MASK)) | addressLatchTiming;
|
|
}
|
|
if (banks & EBI_BANK2)
|
|
{
|
|
EBI->ADDRTIMING2 = (EBI->ADDRTIMING2 &
|
|
~(_EBI_ADDRTIMING2_ADDRSETUP_MASK |
|
|
_EBI_ADDRTIMING2_ADDRHOLD_MASK)) | addressLatchTiming;
|
|
}
|
|
if (banks & EBI_BANK3)
|
|
{
|
|
EBI->ADDRTIMING3 = (EBI->ADDRTIMING3 &
|
|
~(_EBI_ADDRTIMING3_ADDRSETUP_MASK |
|
|
_EBI_ADDRTIMING3_ADDRHOLD_MASK)) | addressLatchTiming;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure EBI pin polarity for selected bank(s) for devices with individual
|
|
* timing support
|
|
*
|
|
* @param[in] banks
|
|
* Mask of memory bank(s) to configure polarity for
|
|
*
|
|
* @param[in] line
|
|
* Which pin/line to configure
|
|
*
|
|
* @param[in] polarity
|
|
* Active high, or active low
|
|
******************************************************************************/
|
|
void EBI_BankPolaritySet(uint32_t banks, EBI_Line_TypeDef line, EBI_Polarity_TypeDef polarity)
|
|
{
|
|
uint32_t bankSet = 0;
|
|
volatile uint32_t *polRegister = 0;
|
|
|
|
/* Verify only valid banks are used */
|
|
EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
|
|
|
|
while (banks)
|
|
{
|
|
#if defined(_EFM32_GIANT_FAMILY)
|
|
if (banks & EBI_BANK0)
|
|
{
|
|
polRegister = &EBI->POLARITY;
|
|
bankSet = EBI_BANK0;
|
|
}
|
|
if (banks & EBI_BANK1)
|
|
{
|
|
polRegister = &EBI->POLARITY1;
|
|
bankSet = EBI_BANK1;
|
|
}
|
|
if (banks & EBI_BANK2)
|
|
{
|
|
polRegister = &EBI->POLARITY2;
|
|
bankSet = EBI_BANK2;
|
|
}
|
|
if (banks & EBI_BANK3)
|
|
{
|
|
polRegister = &EBI->POLARITY3;
|
|
bankSet = EBI_BANK3;
|
|
}
|
|
#else
|
|
polRegister = &EBI->POLARITY;
|
|
banks = 0;
|
|
#endif
|
|
|
|
/* What line to configure */
|
|
switch (line)
|
|
{
|
|
case ebiLineARDY:
|
|
BITBAND_Peripheral(polRegister, _EBI_POLARITY_ARDYPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineALE:
|
|
BITBAND_Peripheral(polRegister, _EBI_POLARITY_ALEPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineWE:
|
|
BITBAND_Peripheral(polRegister, _EBI_POLARITY_WEPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineRE:
|
|
BITBAND_Peripheral(polRegister, _EBI_POLARITY_REPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineCS:
|
|
BITBAND_Peripheral(polRegister, _EBI_POLARITY_CSPOL_SHIFT, polarity);
|
|
break;
|
|
#if defined(_EFM32_GIANT_FAMILY)
|
|
case ebiLineBL:
|
|
BITBAND_Peripheral(polRegister, _EBI_POLARITY_BLPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineTFTVSync:
|
|
BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_VSYNCPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineTFTHSync:
|
|
BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_HSYNCPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineTFTDataEn:
|
|
BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DATAENPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineTFTDClk:
|
|
BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DCLKPOL_SHIFT, polarity);
|
|
break;
|
|
case ebiLineTFTCS:
|
|
BITBAND_Peripheral(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_CSPOL_SHIFT, polarity);
|
|
break;
|
|
#endif
|
|
default:
|
|
EFM_ASSERT(0);
|
|
break;
|
|
}
|
|
banks = banks & (~bankSet);
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure Byte Lane Enable for select banks
|
|
* timing support
|
|
*
|
|
* @param[in] banks
|
|
* Mask of memory bank(s) to configure polarity for
|
|
*
|
|
* @param[in] enable
|
|
* Flag
|
|
******************************************************************************/
|
|
void EBI_BankByteLaneEnable(uint32_t banks, bool enable)
|
|
{
|
|
/* Verify only valid banks are used */
|
|
EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
|
|
|
|
/* Configure byte lane support for each selected bank */
|
|
if (banks & EBI_BANK0)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BL_SHIFT, enable);
|
|
}
|
|
if (banks & EBI_BANK1)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BL1_SHIFT, enable);
|
|
}
|
|
if (banks & EBI_BANK2)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BL2_SHIFT, enable);
|
|
}
|
|
if (banks & EBI_BANK3)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_BL3_SHIFT, enable);
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Configure Alternate Address Map support
|
|
* Enables or disables 256MB address range for all banks
|
|
*
|
|
* @param[in] enable
|
|
* Set or clear address map extension
|
|
******************************************************************************/
|
|
void EBI_AltMapEnable(bool enable)
|
|
{
|
|
BITBAND_Peripheral(&(EBI->CTRL), _EBI_CTRL_ALTMAP_SHIFT, enable);
|
|
}
|
|
|
|
#endif
|
|
|
|
/** @} (end addtogroup EBI) */
|
|
/** @} (end addtogroup EM_Library) */
|
|
|
|
#endif /* defined(EBI_COUNT) && (EBI_COUNT > 0) */
|