527 lines
17 KiB
C
527 lines
17 KiB
C
/**************************************************************************//**
|
|
* @file
|
|
* @brief EFM32GG_DK3750 board support package
|
|
* @author Energy Micro AS
|
|
* @version 1.2.2
|
|
******************************************************************************
|
|
* @section License
|
|
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
|
|
******************************************************************************
|
|
*
|
|
* This source code is the property of Energy Micro AS. The source and compiled
|
|
* code may only be used on Energy Micro "EFM32" microcontrollers.
|
|
*
|
|
* This copyright notice may not be removed from the source code nor changed.
|
|
*
|
|
* 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.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
/***************************************************************************//**
|
|
* @addtogroup BSP
|
|
* @{
|
|
******************************************************************************/
|
|
|
|
#include "efm32.h"
|
|
#include "efm32_gpio.h"
|
|
#include "efm32_cmu.h"
|
|
#include "dvk.h"
|
|
#include "dvk_bcregisters.h"
|
|
|
|
/** Keep intialization mode */
|
|
DVK_Init_TypeDef dvkOperationMode;
|
|
|
|
/**************************************************************************//**
|
|
* @brief Initialize EMF32GG_DK3750 board support package functionality
|
|
* @param[in] mode Initialize in EBI or SPI mode
|
|
*****************************************************************************/
|
|
void DVK_init(DVK_Init_TypeDef mode)
|
|
{
|
|
bool ret = false;
|
|
|
|
if (mode == DVK_Init_EBI)
|
|
{
|
|
dvkOperationMode = mode;
|
|
DVK_busControlMode(DVK_BusControl_EBI);
|
|
ret = DVK_EBI_init();
|
|
}
|
|
if (mode == DVK_Init_SPI)
|
|
{
|
|
dvkOperationMode = mode;
|
|
DVK_busControlMode(DVK_BusControl_SPI);
|
|
ret = DVK_SPI_init();
|
|
}
|
|
|
|
if (ret == false)
|
|
{
|
|
/* Unable to access board control, this is an abornomal situation. */
|
|
/* Try to restart kit and reprogram EFM32 with a standard example */
|
|
/* as this is most likely caused by a peripheral misconfiguration. */
|
|
while (1) ;
|
|
}
|
|
|
|
DVK_setEnergyMode(0);
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Disable EFM32GG_DK3750 board support package functionality
|
|
*****************************************************************************/
|
|
void DVK_disable(void)
|
|
{
|
|
if (dvkOperationMode == DVK_Init_EBI)
|
|
{
|
|
DVK_EBI_disable();
|
|
}
|
|
if (dvkOperationMode == DVK_Init_SPI)
|
|
{
|
|
DVK_SPI_disable();
|
|
}
|
|
DVK_busControlMode(DVK_BusControl_OFF);
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Configure Board Controller bus decode logic
|
|
* @param[in] mode Mode of operation for decode logic
|
|
*****************************************************************************/
|
|
void DVK_busControlMode(DVK_BusControl_TypeDef mode)
|
|
{
|
|
/* Configure GPIO pins for Board Bus mode */
|
|
/* Note: Inverter on GPIO lines to BC, so signals are active low */
|
|
CMU_ClockEnable(cmuClock_GPIO, true);
|
|
|
|
switch (mode)
|
|
{
|
|
case DVK_BusControl_OFF:
|
|
/* Configure board for OFF mode on PB15 MCU_EBI_CONNECT */
|
|
GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 1);
|
|
/* Configure board for OFF mode on PD13 MCU_SPI_CONNECT */
|
|
GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 1);
|
|
break;
|
|
case DVK_BusControl_DIRECT:
|
|
/* Configure board for DIRECT on PB15 MCU_EBI_CONNECT */
|
|
GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 0);
|
|
/* Configure board for DIRECT on PD13 MCU_SPI_CONNECT */
|
|
GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 0);
|
|
break;
|
|
case DVK_BusControl_SPI:
|
|
/* Configure board for SPI mode on PB15 MCU_EBI_CONNECT */
|
|
GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 1);
|
|
/* Configure board for SPI mode on PD13 MCU_SPI_CONNECT */
|
|
GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 0);
|
|
break;
|
|
case DVK_BusControl_EBI:
|
|
default:
|
|
/* Configure board for EBI mode on PB15 MCU_EBI_CONNECT */
|
|
GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 0);
|
|
/* Configure board for EBI mode on PD13 MCU_SPI_CONNECT */
|
|
GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Set board LEDs
|
|
*
|
|
* @param[in] leds
|
|
* 16 bits enabling or disabling individual board LEDs
|
|
*****************************************************************************/
|
|
void DVK_setLEDs(uint16_t leds)
|
|
{
|
|
DVK_writeRegister(&BC_REGISTER->UIF_LEDS, leds);
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Get board LED configuration
|
|
*
|
|
* @return
|
|
* 16 bits of LED status
|
|
*****************************************************************************/
|
|
uint16_t DVK_getLEDs(void)
|
|
{
|
|
return DVK_readRegister(&BC_REGISTER->UIF_LEDS);
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief DK3750 Peripheral Access Control
|
|
* Enable or disable access to on-board peripherals through switches
|
|
* and SPI switch where applicable
|
|
* @param[in] perf
|
|
* Which peripheral to configure
|
|
* @param[in] enable
|
|
* If true, sets up access to peripheral, if false disables it
|
|
*****************************************************************************/
|
|
void DVK_peripheralAccess(DVK_Peripheral_TypeDef perf, bool enable)
|
|
{
|
|
uint16_t perfControl;
|
|
|
|
perfControl = DVK_readRegister(&BC_REGISTER->PERICON);
|
|
|
|
/* Enable or disable the specificed peripheral by setting board control switch */
|
|
if (enable)
|
|
{
|
|
switch (perf)
|
|
{
|
|
case DVK_RS232_SHUTDOWN:
|
|
perfControl |= (1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
|
|
break;
|
|
|
|
case DVK_RS232_UART:
|
|
perfControl &= ~(1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
|
|
perfControl &= ~(1 << BC_PERICON_RS232_LEUART_SHIFT);
|
|
perfControl |= (1 << BC_PERICON_RS232_UART_SHIFT);
|
|
break;
|
|
|
|
case DVK_RS232_LEUART:
|
|
perfControl &= ~(1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
|
|
perfControl &= ~(1 << BC_PERICON_RS232_UART_SHIFT);
|
|
perfControl |= (1 << BC_PERICON_RS232_LEUART_SHIFT);
|
|
break;
|
|
|
|
case DVK_I2C:
|
|
perfControl |= (1 << BC_PERICON_I2C_SHIFT);
|
|
break;
|
|
|
|
case DVK_ETH:
|
|
/* Enable SPI interface */
|
|
DVK_spiControl(DVK_SPI_Ethernet);
|
|
|
|
/* Enable Ethernet analog switches */
|
|
perfControl |= (1 << BC_PERICON_I2S_ETH_SHIFT);
|
|
perfControl |= (1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
|
|
break;
|
|
|
|
case DVK_I2S:
|
|
/* Direct SPI interface to I2S DAC */
|
|
DVK_spiControl(DVK_SPI_Audio);
|
|
|
|
/* Also make surea Audio out is connected for I2S operation */
|
|
perfControl |= (1 << BC_PERICON_AUDIO_OUT_SHIFT);
|
|
perfControl |= (1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
|
|
perfControl |= (1 << BC_PERICON_I2S_ETH_SHIFT);
|
|
perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
|
|
break;
|
|
|
|
case DVK_TRACE:
|
|
perfControl |= (1 << BC_PERICON_TRACE_SHIFT);
|
|
break;
|
|
|
|
case DVK_TOUCH:
|
|
perfControl |= (1 << BC_PERICON_TOUCH_SHIFT);
|
|
break;
|
|
|
|
case DVK_AUDIO_IN:
|
|
perfControl |= (1 << BC_PERICON_AUDIO_IN_SHIFT);
|
|
break;
|
|
|
|
case DVK_AUDIO_OUT:
|
|
perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
|
|
perfControl |= (1 << BC_PERICON_AUDIO_OUT_SHIFT);
|
|
break;
|
|
|
|
case DVK_ANALOG_DIFF:
|
|
perfControl |= (1 << BC_PERICON_ANALOG_DIFF_SHIFT);
|
|
break;
|
|
|
|
case DVK_ANALOG_SE:
|
|
perfControl |= (1 << BC_PERICON_ANALOG_SE_SHIFT);
|
|
break;
|
|
|
|
case DVK_MICROSD:
|
|
perfControl |= (1 << BC_PERICON_SPI_SHIFT);
|
|
break;
|
|
|
|
case DVK_TFT:
|
|
/* Enable SPI to SSD2119 */
|
|
DVK_spiControl(DVK_SPI_Display);
|
|
/* Enable SPI analog switch */
|
|
perfControl |= (1 << BC_PERICON_I2S_ETH_SHIFT);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (perf)
|
|
{
|
|
case DVK_RS232_SHUTDOWN:
|
|
perfControl &= ~(1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
|
|
break;
|
|
|
|
case DVK_RS232_UART:
|
|
perfControl |= (1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
|
|
perfControl &= ~(1 << BC_PERICON_RS232_UART_SHIFT);
|
|
break;
|
|
|
|
case DVK_RS232_LEUART:
|
|
perfControl |= (1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
|
|
perfControl &= ~(1 << BC_PERICON_RS232_LEUART_SHIFT);
|
|
break;
|
|
|
|
case DVK_I2C:
|
|
perfControl &= ~(1 << BC_PERICON_I2C_SHIFT);
|
|
break;
|
|
|
|
case DVK_ETH:
|
|
/* Enable Ethernet analog switches */
|
|
perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
|
|
perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
|
|
break;
|
|
|
|
case DVK_I2S:
|
|
/* Also make surea Audio out is connected for I2S operation */
|
|
perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SHIFT);
|
|
perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
|
|
perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
|
|
perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
|
|
break;
|
|
|
|
case DVK_TRACE:
|
|
perfControl &= ~(1 << BC_PERICON_TRACE_SHIFT);
|
|
break;
|
|
|
|
case DVK_TOUCH:
|
|
perfControl &= ~(1 << BC_PERICON_TOUCH_SHIFT);
|
|
break;
|
|
|
|
case DVK_AUDIO_IN:
|
|
perfControl &= ~(1 << BC_PERICON_AUDIO_IN_SHIFT);
|
|
break;
|
|
|
|
case DVK_AUDIO_OUT:
|
|
perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
|
|
perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SHIFT);
|
|
break;
|
|
|
|
case DVK_ANALOG_DIFF:
|
|
perfControl &= ~(1 << BC_PERICON_ANALOG_DIFF_SHIFT);
|
|
break;
|
|
|
|
case DVK_ANALOG_SE:
|
|
perfControl &= ~(1 << BC_PERICON_ANALOG_SE_SHIFT);
|
|
break;
|
|
|
|
case DVK_MICROSD:
|
|
perfControl &= ~(1 << BC_PERICON_SPI_SHIFT);
|
|
break;
|
|
|
|
case DVK_TFT:
|
|
/* Disable SPI analog switch */
|
|
perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
|
|
break;
|
|
}
|
|
}
|
|
/* Write back register */
|
|
DVK_writeRegister(&BC_REGISTER->PERICON, perfControl);
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Get status of push buttons on kit
|
|
*
|
|
* @return
|
|
* Button state, each bit representing each push button PB0-PB4
|
|
*****************************************************************************/
|
|
uint16_t DVK_getPushButtons(void)
|
|
{
|
|
uint16_t tmp;
|
|
|
|
tmp = DVK_readRegister(&BC_REGISTER->UIF_PB);
|
|
|
|
return (~tmp) & 0x000F;
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Configure SPI for correct peripheral
|
|
*
|
|
* @param[in] device
|
|
* Device to enable SPI bus for
|
|
*****************************************************************************/
|
|
void DVK_spiControl(DVK_SpiControl_TypeDef device)
|
|
{
|
|
switch (device)
|
|
{
|
|
case DVK_SPI_Audio:
|
|
DVK_writeRegister(&BC_REGISTER->SPI_DEMUX, BC_SPI_DEMUX_SLAVE_AUDIO);
|
|
break;
|
|
|
|
case DVK_SPI_Ethernet:
|
|
DVK_writeRegister(&BC_REGISTER->SPI_DEMUX, BC_SPI_DEMUX_SLAVE_ETHERNET);
|
|
break;
|
|
|
|
case DVK_SPI_Display:
|
|
DVK_writeRegister(&BC_REGISTER->SPI_DEMUX, BC_SPI_DEMUX_SLAVE_DISPLAY);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Inform AEM/Board Controller about what energy mode we are currently
|
|
* entering. This information can be used for better visual feedback of
|
|
* EFM32GG activity for the board controller and PC applications
|
|
* @param energyMode What energy mode we are going to use next
|
|
*****************************************************************************/
|
|
void DVK_setEnergyMode(uint16_t energyMode)
|
|
{
|
|
DVK_writeRegister(&BC_REGISTER->EM, energyMode);
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Enable "Control" buttons/joystick/dip switch interrupts
|
|
* @param flags Board control interrupt flags, INTEN_<something>
|
|
*****************************************************************************/
|
|
void DVK_enableInterrupt(uint16_t flags)
|
|
{
|
|
uint16_t tmp;
|
|
|
|
/* Add flags to interrupt enable register */
|
|
tmp = DVK_readRegister(&BC_REGISTER->INTEN);
|
|
tmp |= flags;
|
|
DVK_writeRegister(&BC_REGISTER->INTEN, tmp);
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Disable "Control" buttons/joystick/dip switch interrupts
|
|
* @param flags Board control interrupt flags, BC_INTEN_<something>
|
|
*****************************************************************************/
|
|
void DVK_disableInterrupt(uint16_t flags)
|
|
{
|
|
uint16_t tmp;
|
|
|
|
/* Clear flags from interrupt enable register */
|
|
tmp = DVK_readRegister(&BC_REGISTER->INTEN);
|
|
flags = ~(flags);
|
|
tmp &= flags;
|
|
DVK_writeRegister(&BC_REGISTER->INTEN, tmp);
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Clear interrupts
|
|
* @param flags Board control interrupt flags, BC_INTEN_<something>
|
|
*****************************************************************************/
|
|
void DVK_clearInterruptFlags(uint16_t flags)
|
|
{
|
|
uint16_t tmp;
|
|
tmp = DVK_readRegister(&BC_REGISTER->INTFLAG);
|
|
tmp &= ~(flags);
|
|
DVK_writeRegister(&BC_REGISTER->INTFLAG, tmp);
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Read interrupt flags
|
|
* @return Returns currently triggered interrupts
|
|
*****************************************************************************/
|
|
uint16_t DVK_getInterruptFlags(void)
|
|
{
|
|
return DVK_readRegister(&BC_REGISTER->INTFLAG);
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Get joystick button status
|
|
* @return Joystick controller status
|
|
*****************************************************************************/
|
|
uint16_t DVK_getJoystick(void)
|
|
{
|
|
uint16_t joyStick = 0;
|
|
|
|
joyStick = ~(DVK_readRegister(&BC_REGISTER->UIF_JOYSTICK)) & 0x001f;
|
|
|
|
return joyStick;
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Get dipswitch status
|
|
* The DIP switches are free for user programmable purposes
|
|
* @return Dip switch
|
|
*****************************************************************************/
|
|
uint16_t DVK_getDipSwitch(void)
|
|
{
|
|
return DVK_readRegister(&BC_REGISTER->UIF_DIP) & 0x000f;
|
|
}
|
|
|
|
|
|
/**************************************************************************//**
|
|
* @brief Configure display control
|
|
*****************************************************************************/
|
|
void DVK_displayControl(DVK_Display_TypeDef option)
|
|
{
|
|
uint16_t tmp;
|
|
|
|
switch (option)
|
|
{
|
|
case DVK_Display_EBI:
|
|
DVK_writeRegister(&BC_REGISTER->ARB_CTRL, BC_ARB_CTRL_EBI);
|
|
break;
|
|
|
|
case DVK_Display_SPI:
|
|
DVK_writeRegister(&BC_REGISTER->ARB_CTRL, BC_ARB_CTRL_SPI);
|
|
break;
|
|
|
|
case DVK_Display_BC:
|
|
DVK_writeRegister(&BC_REGISTER->ARB_CTRL, BC_ARB_CTRL_BC);
|
|
break;
|
|
|
|
case DVK_Display_PowerEnable:
|
|
tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
|
|
tmp |= (BC_DISPLAY_CTRL_POWER_ENABLE);
|
|
DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
|
|
break;
|
|
|
|
case DVK_Display_PowerDisable:
|
|
tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
|
|
tmp &= ~(BC_DISPLAY_CTRL_POWER_ENABLE);
|
|
DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
|
|
break;
|
|
|
|
case DVK_Display_ResetAssert:
|
|
tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
|
|
tmp |= (BC_DISPLAY_CTRL_RESET);
|
|
DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
|
|
break;
|
|
|
|
case DVK_Display_ResetRelease:
|
|
tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
|
|
tmp &= ~(BC_DISPLAY_CTRL_RESET);
|
|
DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
|
|
break;
|
|
|
|
case DVK_Display_Mode8080:
|
|
tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
|
|
tmp &= ~(BC_DISPLAY_CTRL_MODE_GENERIC);
|
|
DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
|
|
break;
|
|
|
|
case DVK_Display_ModeGeneric:
|
|
tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
|
|
tmp |= (BC_DISPLAY_CTRL_MODE_GENERIC);
|
|
DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
|
|
break;
|
|
|
|
default:
|
|
/* Unknown command */
|
|
while (1) ;
|
|
}
|
|
}
|
|
|
|
/** @} (end group BSP) */
|