added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Revision:
144:ef7eb2e8f9f7
Parent:
50:a417edff4437
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_ebi.c	Tue Aug 02 14:07:36 2016 +0000
+++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_ebi.c	Fri Sep 02 15:07:44 2016 +0100
@@ -1,1187 +1,1187 @@
-/***************************************************************************//**
- * @file em_ebi.c
- * @brief External Bus Interface (EBI) Peripheral API
- * @version 4.2.1
- *******************************************************************************
- * @section License
- * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.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: Silicon Labs has no
- * obligation to support this Software. Silicon Labs 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.
- *
- * Silicon Labs 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_bus.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) || defined(_EFM32_WONDER_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) || defined(_EFM32_WONDER_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) || defined(_EFM32_WONDER_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
-
-  /* Activate new configuration */
-  EBI->CTRL = ctrl;
-
-  /* Configure Adress Latch Enable */
-  switch (ebiInit->mode)
-  {
-    case ebiModeD16A16ALE:
-    case ebiModeD8A24ALE:
-      /* Address Latch Enable */
-      BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_ALEPEN_SHIFT, 1);
-      break;
-#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
-    case ebiModeD16:
-#endif
-    case ebiModeD8A8:
-      /* Make sure Address Latch is disabled */
-      BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_ALEPEN_SHIFT, 0);
-      break;
-  }
-#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_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))
-  {
-    BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_BLPEN_SHIFT, ebiInit->blEnable);
-  }
-#endif
-  /* Enable EBI pins EBI_WEn and EBI_REn */
-  BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_EBIPEN_SHIFT, 1);
-
-  /* Enable chip select lines */
-  EBI_ChipSelectEnable(ebiInit->csLines, true);
-}
-
-
-/***************************************************************************//**
- * @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)
-  {
-    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BANK0EN_SHIFT, enable);
-  }
-  if (banks & EBI_BANK1)
-  {
-    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BANK1EN_SHIFT, enable);
-  }
-  if (banks & EBI_BANK2)
-  {
-    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BANK2EN_SHIFT, enable);
-  }
-  if (banks & EBI_BANK3)
-  {
-    BUS_RegBitWrite(&(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) || defined(_EFM32_WONDER_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)
-  {
-    BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_CS0PEN_SHIFT, enable);
-  }
-  if (cs & EBI_CS1)
-  {
-    BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_CS1PEN_SHIFT, enable);
-  }
-  if (cs & EBI_CS2)
-  {
-    BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_CS2PEN_SHIFT, enable);
-  }
-  if (cs & EBI_CS3)
-  {
-    BUS_RegBitWrite(&(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:
-      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_ARDYPOL_SHIFT, polarity);
-      break;
-    case ebiLineALE:
-      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_ALEPOL_SHIFT, polarity);
-      break;
-    case ebiLineWE:
-      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_WEPOL_SHIFT, polarity);
-      break;
-    case ebiLineRE:
-      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_REPOL_SHIFT, polarity);
-      break;
-    case ebiLineCS:
-      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_CSPOL_SHIFT, polarity);
-      break;
-#if defined (_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
-    case ebiLineBL:
-      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_BLPOL_SHIFT, polarity);
-      break;
-    case ebiLineTFTVSync:
-      BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_VSYNCPOL_SHIFT, polarity);
-      break;
-    case ebiLineTFTHSync:
-      BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_HSYNCPOL_SHIFT, polarity);
-      break;
-    case ebiLineTFTDataEn:
-      BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DATAENPOL_SHIFT, polarity);
-      break;
-    case ebiLineTFTDClk:
-      BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DCLKPOL_SHIFT, polarity);
-      break;
-    case ebiLineTFTCS:
-      BUS_RegBitWrite(&(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) || defined(_EFM32_WONDER_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) || defined(_EFM32_WONDER_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 )
-  {
-    BUS_RegBitWrite(&EBI->RDTIMING, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
-    BUS_RegBitWrite(&EBI->RDTIMING, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
-    BUS_RegBitWrite(&EBI->RDTIMING, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
-  }
-  if( banks & EBI_BANK1 )
-  {
-    BUS_RegBitWrite(&EBI->RDTIMING1, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
-    BUS_RegBitWrite(&EBI->RDTIMING1, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
-    BUS_RegBitWrite(&EBI->RDTIMING1, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
-  }
-  if( banks & EBI_BANK2 )
-  {
-    BUS_RegBitWrite(&EBI->RDTIMING2, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
-    BUS_RegBitWrite(&EBI->RDTIMING2, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
-    BUS_RegBitWrite(&EBI->RDTIMING2, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
-  }
-  if( banks & EBI_BANK3 )
-  {
-    BUS_RegBitWrite(&EBI->RDTIMING3, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
-    BUS_RegBitWrite(&EBI->RDTIMING3, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
-    BUS_RegBitWrite(&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] writeBufDisable
- *   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 )
-  {
-    BUS_RegBitWrite(&EBI->WRTIMING, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
-    BUS_RegBitWrite(&EBI->WRTIMING, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
-  }
-  if( banks & EBI_BANK1 )
-  {
-    BUS_RegBitWrite(&EBI->WRTIMING1, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
-    BUS_RegBitWrite(&EBI->WRTIMING1, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
-  }
-  if( banks & EBI_BANK2 )
-  {
-    BUS_RegBitWrite(&EBI->WRTIMING2, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
-    BUS_RegBitWrite(&EBI->WRTIMING2, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
-  }
-  if( banks & EBI_BANK3 )
-  {
-    BUS_RegBitWrite(&EBI->WRTIMING3, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
-    BUS_RegBitWrite(&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 )
-  {
-    BUS_RegBitWrite(&EBI->ADDRTIMING, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
-  }
-  if( banks & EBI_BANK1 )
-  {
-    BUS_RegBitWrite(&EBI->ADDRTIMING1, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
-  }
-  if( banks & EBI_BANK2 )
-  {
-    BUS_RegBitWrite(&EBI->ADDRTIMING2, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
-  }
-  if( banks & EBI_BANK3 )
-  {
-    BUS_RegBitWrite(&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) || defined(_EFM32_WONDER_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:
-        BUS_RegBitWrite(polRegister, _EBI_POLARITY_ARDYPOL_SHIFT, polarity);
-        break;
-      case ebiLineALE:
-        BUS_RegBitWrite(polRegister, _EBI_POLARITY_ALEPOL_SHIFT, polarity);
-        break;
-      case ebiLineWE:
-        BUS_RegBitWrite(polRegister, _EBI_POLARITY_WEPOL_SHIFT, polarity);
-        break;
-      case ebiLineRE:
-        BUS_RegBitWrite(polRegister, _EBI_POLARITY_REPOL_SHIFT, polarity);
-        break;
-      case ebiLineCS:
-        BUS_RegBitWrite(polRegister, _EBI_POLARITY_CSPOL_SHIFT, polarity);
-        break;
-#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
-      case ebiLineBL:
-        BUS_RegBitWrite(polRegister, _EBI_POLARITY_BLPOL_SHIFT, polarity);
-        break;
-      case ebiLineTFTVSync:
-        BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_VSYNCPOL_SHIFT, polarity);
-        break;
-      case ebiLineTFTHSync:
-        BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_HSYNCPOL_SHIFT, polarity);
-        break;
-      case ebiLineTFTDataEn:
-        BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DATAENPOL_SHIFT, polarity);
-        break;
-      case ebiLineTFTDClk:
-        BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DCLKPOL_SHIFT, polarity);
-        break;
-      case ebiLineTFTCS:
-        BUS_RegBitWrite(&(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)
-  {
-    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BL_SHIFT, enable);
-  }
-  if (banks & EBI_BANK1)
-  {
-    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BL1_SHIFT, enable);
-  }
-  if (banks & EBI_BANK2)
-  {
-    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BL2_SHIFT, enable);
-  }
-  if (banks & EBI_BANK3)
-  {
-    BUS_RegBitWrite(&(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)
-{
-  BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_ALTMAP_SHIFT, enable);
-}
-
-#endif
-
-/** @} (end addtogroup EBI) */
-/** @} (end addtogroup EM_Library) */
-
-#endif /* defined(EBI_COUNT) && (EBI_COUNT > 0) */
+/***************************************************************************//**
+ * @file em_ebi.c
+ * @brief External Bus Interface (EBI) Peripheral API
+ * @version 4.2.1
+ *******************************************************************************
+ * @section License
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.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: Silicon Labs has no
+ * obligation to support this Software. Silicon Labs 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.
+ *
+ * Silicon Labs 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_bus.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) || defined(_EFM32_WONDER_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) || defined(_EFM32_WONDER_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) || defined(_EFM32_WONDER_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
+
+  /* Activate new configuration */
+  EBI->CTRL = ctrl;
+
+  /* Configure Adress Latch Enable */
+  switch (ebiInit->mode)
+  {
+    case ebiModeD16A16ALE:
+    case ebiModeD8A24ALE:
+      /* Address Latch Enable */
+      BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_ALEPEN_SHIFT, 1);
+      break;
+#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
+    case ebiModeD16:
+#endif
+    case ebiModeD8A8:
+      /* Make sure Address Latch is disabled */
+      BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_ALEPEN_SHIFT, 0);
+      break;
+  }
+#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_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))
+  {
+    BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_BLPEN_SHIFT, ebiInit->blEnable);
+  }
+#endif
+  /* Enable EBI pins EBI_WEn and EBI_REn */
+  BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_EBIPEN_SHIFT, 1);
+
+  /* Enable chip select lines */
+  EBI_ChipSelectEnable(ebiInit->csLines, true);
+}
+
+
+/***************************************************************************//**
+ * @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)
+  {
+    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BANK0EN_SHIFT, enable);
+  }
+  if (banks & EBI_BANK1)
+  {
+    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BANK1EN_SHIFT, enable);
+  }
+  if (banks & EBI_BANK2)
+  {
+    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BANK2EN_SHIFT, enable);
+  }
+  if (banks & EBI_BANK3)
+  {
+    BUS_RegBitWrite(&(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) || defined(_EFM32_WONDER_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)
+  {
+    BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_CS0PEN_SHIFT, enable);
+  }
+  if (cs & EBI_CS1)
+  {
+    BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_CS1PEN_SHIFT, enable);
+  }
+  if (cs & EBI_CS2)
+  {
+    BUS_RegBitWrite(&(EBI->ROUTE), _EBI_ROUTE_CS2PEN_SHIFT, enable);
+  }
+  if (cs & EBI_CS3)
+  {
+    BUS_RegBitWrite(&(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:
+      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_ARDYPOL_SHIFT, polarity);
+      break;
+    case ebiLineALE:
+      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_ALEPOL_SHIFT, polarity);
+      break;
+    case ebiLineWE:
+      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_WEPOL_SHIFT, polarity);
+      break;
+    case ebiLineRE:
+      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_REPOL_SHIFT, polarity);
+      break;
+    case ebiLineCS:
+      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_CSPOL_SHIFT, polarity);
+      break;
+#if defined (_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
+    case ebiLineBL:
+      BUS_RegBitWrite(&(EBI->POLARITY), _EBI_POLARITY_BLPOL_SHIFT, polarity);
+      break;
+    case ebiLineTFTVSync:
+      BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_VSYNCPOL_SHIFT, polarity);
+      break;
+    case ebiLineTFTHSync:
+      BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_HSYNCPOL_SHIFT, polarity);
+      break;
+    case ebiLineTFTDataEn:
+      BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DATAENPOL_SHIFT, polarity);
+      break;
+    case ebiLineTFTDClk:
+      BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DCLKPOL_SHIFT, polarity);
+      break;
+    case ebiLineTFTCS:
+      BUS_RegBitWrite(&(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) || defined(_EFM32_WONDER_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) || defined(_EFM32_WONDER_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 )
+  {
+    BUS_RegBitWrite(&EBI->RDTIMING, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
+    BUS_RegBitWrite(&EBI->RDTIMING, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
+    BUS_RegBitWrite(&EBI->RDTIMING, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
+  }
+  if( banks & EBI_BANK1 )
+  {
+    BUS_RegBitWrite(&EBI->RDTIMING1, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
+    BUS_RegBitWrite(&EBI->RDTIMING1, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
+    BUS_RegBitWrite(&EBI->RDTIMING1, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
+  }
+  if( banks & EBI_BANK2 )
+  {
+    BUS_RegBitWrite(&EBI->RDTIMING2, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
+    BUS_RegBitWrite(&EBI->RDTIMING2, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
+    BUS_RegBitWrite(&EBI->RDTIMING2, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
+  }
+  if( banks & EBI_BANK3 )
+  {
+    BUS_RegBitWrite(&EBI->RDTIMING3, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
+    BUS_RegBitWrite(&EBI->RDTIMING3, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
+    BUS_RegBitWrite(&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] writeBufDisable
+ *   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 )
+  {
+    BUS_RegBitWrite(&EBI->WRTIMING, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
+    BUS_RegBitWrite(&EBI->WRTIMING, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
+  }
+  if( banks & EBI_BANK1 )
+  {
+    BUS_RegBitWrite(&EBI->WRTIMING1, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
+    BUS_RegBitWrite(&EBI->WRTIMING1, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
+  }
+  if( banks & EBI_BANK2 )
+  {
+    BUS_RegBitWrite(&EBI->WRTIMING2, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
+    BUS_RegBitWrite(&EBI->WRTIMING2, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
+  }
+  if( banks & EBI_BANK3 )
+  {
+    BUS_RegBitWrite(&EBI->WRTIMING3, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
+    BUS_RegBitWrite(&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 )
+  {
+    BUS_RegBitWrite(&EBI->ADDRTIMING, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
+  }
+  if( banks & EBI_BANK1 )
+  {
+    BUS_RegBitWrite(&EBI->ADDRTIMING1, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
+  }
+  if( banks & EBI_BANK2 )
+  {
+    BUS_RegBitWrite(&EBI->ADDRTIMING2, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
+  }
+  if( banks & EBI_BANK3 )
+  {
+    BUS_RegBitWrite(&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) || defined(_EFM32_WONDER_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:
+        BUS_RegBitWrite(polRegister, _EBI_POLARITY_ARDYPOL_SHIFT, polarity);
+        break;
+      case ebiLineALE:
+        BUS_RegBitWrite(polRegister, _EBI_POLARITY_ALEPOL_SHIFT, polarity);
+        break;
+      case ebiLineWE:
+        BUS_RegBitWrite(polRegister, _EBI_POLARITY_WEPOL_SHIFT, polarity);
+        break;
+      case ebiLineRE:
+        BUS_RegBitWrite(polRegister, _EBI_POLARITY_REPOL_SHIFT, polarity);
+        break;
+      case ebiLineCS:
+        BUS_RegBitWrite(polRegister, _EBI_POLARITY_CSPOL_SHIFT, polarity);
+        break;
+#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
+      case ebiLineBL:
+        BUS_RegBitWrite(polRegister, _EBI_POLARITY_BLPOL_SHIFT, polarity);
+        break;
+      case ebiLineTFTVSync:
+        BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_VSYNCPOL_SHIFT, polarity);
+        break;
+      case ebiLineTFTHSync:
+        BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_HSYNCPOL_SHIFT, polarity);
+        break;
+      case ebiLineTFTDataEn:
+        BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DATAENPOL_SHIFT, polarity);
+        break;
+      case ebiLineTFTDClk:
+        BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DCLKPOL_SHIFT, polarity);
+        break;
+      case ebiLineTFTCS:
+        BUS_RegBitWrite(&(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)
+  {
+    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BL_SHIFT, enable);
+  }
+  if (banks & EBI_BANK1)
+  {
+    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BL1_SHIFT, enable);
+  }
+  if (banks & EBI_BANK2)
+  {
+    BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BL2_SHIFT, enable);
+  }
+  if (banks & EBI_BANK3)
+  {
+    BUS_RegBitWrite(&(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)
+{
+  BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_ALTMAP_SHIFT, enable);
+}
+
+#endif
+
+/** @} (end addtogroup EBI) */
+/** @} (end addtogroup EM_Library) */
+
+#endif /* defined(EBI_COUNT) && (EBI_COUNT > 0) */