diff --git a/bsp/efm32/EFM32_Gxxx_DK/dvk.c b/bsp/efm32/EFM32_Gxxx_DK/dvk.c
new file mode 100644
index 0000000000..c10fa09b4e
--- /dev/null
+++ b/bsp/efm32/EFM32_Gxxx_DK/dvk.c
@@ -0,0 +1,62 @@
+/**************************************************************************//**
+ * @file
+ * @brief DVK board support package, initialization
+ * @author Energy Micro AS
+ * @version 1.6.0
+ ******************************************************************************
+ * @section License
+ * (C) Copyright 2010 Energy Micro AS, http://www.energymicro.com
+ ******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************/
+
+#include "efm32.h"
+#include "dvk.h"
+
+/**************************************************************************//**
+ * @brief Initializes DVK, configures board control access
+ *****************************************************************************/
+void DVK_init(void)
+{
+#ifdef DVK_EBI_CONTROL
+ DVK_EBI_init();
+#endif
+#ifdef DVK_SPI_CONTROL
+ DVK_SPI_init();
+#endif
+ /* Inform AEM application that we are in Energy Mode 0 by default */
+ DVK_setEnergyMode(0);
+}
+
+/**************************************************************************//**
+ * @brief Disables DVK, free up resources
+ *****************************************************************************/
+void DVK_disable(void)
+{
+#ifdef DVK_EBI_CONTROL
+ /* Handover bus control */
+ DVK_disableBus();
+ /* Disable EBI interface */
+ DVK_EBI_disable();
+#endif
+
+#ifdef DVK_SPI_CONTROL
+ DVK_SPI_disable();
+#endif
+}
diff --git a/bsp/efm32/EFM32_Gxxx_DK/dvk.h b/bsp/efm32/EFM32_Gxxx_DK/dvk.h
new file mode 100644
index 0000000000..bac1c9ecb0
--- /dev/null
+++ b/bsp/efm32/EFM32_Gxxx_DK/dvk.h
@@ -0,0 +1,125 @@
+/**************************************************************************//**
+ * @file
+ * @brief DVK Board Support, master header file
+ * @author Energy Micro AS
+ * @version 1.6.0
+ ******************************************************************************
+ * @section License
+ * (C) Copyright 2010 Energy Micro AS, http://www.energymicro.com
+ ******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************/
+
+#ifndef __DVK_H
+#define __DVK_H
+
+#include
+#include "dvk_boardcontrol.h"
+#include "dvk_bcregisters.h"
+
+/* onelife: Add missing define */
+#define NULL ((void *)0)
+
+/* IF not user overrides default, try to decide DVK access interface based on
+ * part number */
+#ifndef DVK_SPI_CONTROL
+#ifndef DVK_EBI_CONTROL
+
+#if defined(EFM32G200F16)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G200F32)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G200F64)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G210F128)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G230F128)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G230F32)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G230F64)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G280F128)
+#define DVK_EBI_CONTROL
+#elif defined(EFM32G280F32)
+#define DVK_EBI_CONTROL
+#elif defined(EFM32G280F64)
+#define DVK_EBI_CONTROL
+#elif defined(EFM32G290F128)
+#define DVK_EBI_CONTROL
+#elif defined(EFM32G290F32)
+#define DVK_EBI_CONTROL
+#elif defined(EFM32G290F64)
+#define DVK_EBI_CONTROL
+#elif defined(EFM32G840F128)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G840F32)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G840F64)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G880F128)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G880F32)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G880F64)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G890F128)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G890F32)
+#define DVK_SPI_CONTROL
+#elif defined(EFM32G890F64)
+#define DVK_SPI_CONTROL
+#else
+#define DVK_SPI_CONTROL
+#endif
+
+#endif
+#endif
+
+/* EBI access */
+void DVK_EBI_init(void);
+void DVK_EBI_disable(void);
+
+void DVK_EBI_writeRegister(volatile uint16_t *addr, uint16_t data);
+uint16_t DVK_EBI_readRegister(volatile uint16_t *addr);
+
+/* SPI access */
+void DVK_SPI_init(void);
+void DVK_SPI_disable(void);
+
+void DVK_SPI_writeRegister(volatile uint16_t *addr, uint16_t data);
+uint16_t DVK_SPI_readRegister(volatile uint16_t *addr);
+
+
+/* Accodring to configuration, use either SPI or EBI */
+#ifdef DVK_EBI_CONTROL
+#define DVK_writeRegister(A, B) DVK_EBI_writeRegister(A, B)
+#define DVK_readRegister(A) DVK_EBI_readRegister(A)
+#endif
+
+#ifdef DVK_SPI_CONTROL
+#define DVK_writeRegister(A, B) DVK_SPI_writeRegister(A, B)
+#define DVK_readRegister(A) DVK_SPI_readRegister(A)
+#endif
+
+/* General initialization routines */
+void DVK_init(void);
+void DVK_disable(void);
+
+#endif
diff --git a/bsp/efm32/EFM32_Gxxx_DK/dvk_bcregisters.h b/bsp/efm32/EFM32_Gxxx_DK/dvk_bcregisters.h
new file mode 100644
index 0000000000..b0f9357113
--- /dev/null
+++ b/bsp/efm32/EFM32_Gxxx_DK/dvk_bcregisters.h
@@ -0,0 +1,174 @@
+/**************************************************************************//**
+ * @file
+ * @brief Board Control register definitions
+ * @author Energy Micro AS
+ * @version 1.6.0
+ ******************************************************************************
+ * @section License
+ * (C) Copyright 2010 Energy Micro AS, http://www.energymicro.com
+ ******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************/
+
+#ifndef __DVK_BCREGISTERS_H
+#define __DVK_BCREGISTERS_H
+
+#include
+
+/**************************************************************************//**
+ * Defines FPGA register bank for Energy Micro Development Kit (DVK) board,
+ * i.e. board control registers
+ *****************************************************************************/
+#define BC_FLASH_BASE 0x80000000 /**< FLASH memory base address */
+#define BC_SRAM_BASE 0x84000000 /**< SRAM base address */
+#define BC_SSD2119_BASE 0x88000000 /**< TFT Controller base address */
+#define BC_REGISTER_BASE 0x8c000000 /**< Board Controller registers base address */
+
+#define BC_CFG ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x00)) /**< CFG */
+#define BC_EM ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x01)) /**< EM */
+#define BC_MAGIC ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x02)) /**< MAGIC */
+#define BC_LED ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x03)) /**< LEDs */
+#define BC_PUSHBUTTON ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x04)) /**< Push Buttons */
+#define BC_DIPSWITCH ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x05)) /**< Dip switches */
+#define BC_JOYSTICK ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x06)) /**< Joystick */
+#define BC_AEM ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x07)) /**< AEM push button status */
+#define BC_DISPLAY_CTRL ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x08)) /**< Display Control */
+#define BC_EBI_CFG ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x09)) /**< EBI config */
+#define BC_BUS_CFG ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x0a)) /**< BUS config */
+#define BC_PERCTRL ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x0c)) /**< Peripheral Control */
+#define BC_AEMSTATE ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x0d)) /**< AEM state of push button switch */
+#define BC_SPI_CFG ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x0e)) /**< SPI config */
+#define BC_RESET ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x0f)) /**< Reset */
+#define BC_ADC_START ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x10)) /**< ADC start */
+#define BC_ADC_STATUS ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x11)) /**< ADC status */
+#define BC_ADC_DATA ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x12)) /**< ADC data */
+#define BC_HW_VERSION ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x14)) /**< HW version */
+#define BC_FW_BUILDNO ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x15)) /**< FW build number */
+#define BC_FW_VERSION ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x16)) /**< FW version */
+#define BC_SCRATCH_COMMON ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x17)) /**< Scratch common */
+#define BC_SCRATCH_EFM0 ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x18)) /**< Scratch EFM0 */
+#define BC_SCRATCH_EFM1 ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x19)) /**< Scratch EFM1 */
+#define BC_SCRATCH_EFM2 ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x1A)) /**< Scratch EFM2 */
+#define BC_SCRATCH_EFM3 ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x1B)) /**< Scratch EFM3 */
+#define BC_SCRATCH_BC0 ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x1C)) /**< Scratch BC0 */
+#define BC_SCRATCH_BC1 ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x1D)) /**< Scratch BC1 */
+#define BC_SCRATCH_BC2 ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x1E)) /**< Scratch BC2 */
+#define BC_SCRATCH_BC3 ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x1f)) /**< Scratch BC3 */
+#define BC_INTFLAG ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x20)) /**< Interrupt flag */
+#define BC_INTEN ((volatile uint16_t *)(BC_REGISTER_BASE + sizeof(uint16_t) * 0x21)) /**< Interrupt enable */
+
+/**************************************************************************//**
+ * Defines bit fields for board control registers
+ *****************************************************************************/
+
+#define BC_CFG_SPI (0) /**< SPI mode */
+#define BC_CFG_EBI (1) /**< EBI mode */
+
+#define BC_EM_EM0 (0) /**< Indicate EM0 */
+#define BC_EM_EM1 (1) /**< Indicate EM1 */
+#define BC_EM_EM2 (2) /**< Indicate EM2 */
+#define BC_EM_EM3 (3) /**< Indicate EM3 */
+#define BC_EM_EM4 (4) /**< Indicate EM4 */
+
+#define BC_MAGIC_VALUE (0xef32) /**< Magic */
+
+#define BC_PUSHBUTTON_MASK (0x000f) /**< Push button mask */
+#define BC_PUSHBUTTON_SW1 (1 << 0) /**< Push button SW1 */
+#define BC_PUSHBUTTON_SW2 (1 << 1) /**< Push button SW2 */
+#define BC_PUSHBUTTON_SW3 (1 << 2) /**< Push button SW3 */
+#define BC_PUSHBUTTON_SW4 (1 << 3) /**< Push button SW4 */
+
+#define BC_DIPSWITCH_MASK (0x00ff) /**< Dip switch mask */
+
+#define BC_JOYSTICK_MASK (0x001f) /**< Joystick mask */
+#define BC_JOYSTICK_DOWN (1 << 0) /**< Joystick down */
+#define BC_JOYSTICK_RIGHT (1 << 1) /**< Joystick right */
+#define BC_JOYSTICK_UP (1 << 2) /**< Joystick up */
+#define BC_JOYSTICK_LEFT (1 << 3) /**< Joystick left */
+#define BC_JOYSTICK_CENTER (1 << 4) /**< Joystick center button */
+
+#define BC_DISPCTRL_RESET (1 << 0) /**< Reset */
+#define BC_DISPCTRL_POWER_ENABLE (1 << 1) /**< Display Control Power Enable */
+
+#define BC_EBI_CFG_MASK (0x0003) /**< EBI Config */
+#define BC_EBI_CFG_16X16 (0) /**< 16x16 address/data mode */
+#define BC_EBI_CFG_8X8 (1) /**< 8x8 address/data mode */
+#define BC_EBI_CFG_24X8 (2) /**< 24x8 address/data mode */
+
+#define BC_BUS_CFG_MASK (0x0003) /**< Bus config */
+#define BC_BUS_CFG_FSMC (0) /**< Kit Board Controller owns bus */
+#define BC_BUS_CFG_EBI (1) /**< EBI drives bus */
+#define BC_BUS_CFG_SPI (2) /**< SPI drives bus */
+
+#define BC_PERCTRL_ACCEL (1 << 0) /**< Accelerometer enable */
+#define BC_PERCTRL_AMBIENT (1 << 1) /**< Ambient light sensor enable */
+#define BC_PERCTRL_POTMETER (1 << 2) /**< Potentiometer enable */
+#define BC_PERCTRL_RS232A (1 << 3) /**< RS232A enable */
+#define BC_PERCTRL_RS232B (1 << 4) /**< RS232B enable */
+#define BC_PERCTRL_SPI (1 << 5) /**< SPI enable */
+#define BC_PERCTRL_I2C (1 << 6) /**< I2C enable */
+#define BC_PERCTRL_IRDA (1 << 7) /**< IRDA enable */
+#define BC_PERCTRL_ANALOG_SE (1 << 8) /**< Analog SE enable */
+#define BC_PERCTRL_ANALOG_DIFF (1 << 9) /**< Analog Diff enable */
+#define BC_PERCTRL_AUDIO_OUT (1 << 10) /**< Audio Out enable */
+#define BC_PERCTRL_AUDIO_IN (1 << 11) /**< Audio In enable */
+#define BC_PERCTRL_ACCEL_GSEL (1 << 12) /**< Accel Gsel enable */
+#define BC_PERCTRL_ACCEL_SELFTEST (1 << 13) /**< Accel Self test enable */
+#define BC_PERCTRL_RS232_SHUTDOWN (1 << 14) /**< RS232 shutdown */
+#define BC_PERCTRL_IRDA_SHUTDOWN (1 << 15) /**< IRDA shutdown */
+
+#define BC_AEMSTATE_BC (0) /**< AEM button state, BC controls buttons */
+#define BC_AEMSTATE_EFM (1) /**< AEM button state, EFM32 controls buttons */
+
+#define BC_SPI_CFG_FLASH (0) /**< SPI Flash config */
+#define BC_SPI_CFG_MICROSD (1) /**< SPI MicroSD config */
+
+#define BC_RESET_FLASH (1 << 0) /**< Reset Flash */
+#define BC_RESET_EFM (1 << 1) /**< Reset EFM */
+
+#define BC_ADC_START_MASK (0x00ff) /**< ADC Start mask */
+
+#define BC_ADC_STATUS_DONE (0) /**< ADC Status Done */
+#define BC_ADC_STATUS_BUSY (1) /**< ADC Status Busy */
+
+#define BC_HW_VERSION_PCB_MASK (0x07f0) /**< PCB Version mask */
+#define BC_HW_VERSION_PCB_SHIFT (4) /**< PCB Version shift */
+#define BC_HW_VERSION_BOARD_MASK (0x000f) /**< Board version mask */
+#define BC_HW_VERSION_BOARD_SHIFT (0) /**< Board version shift */
+
+#define BC_HW_FW_VERSION_MAJOR_MASK (0xf000) /**< FW Version major mask */
+#define BC_HW_FW_VERSION_MAJOR_SHIFT (12) /**< FW version major shift */
+#define BC_HW_FW_VERSION_MINOR_MASK (0x0f00) /**< FW version minor mask */
+#define BC_HW_FW_VERSION_MINOR_SHIFT (8) /**< FW version minor shift */
+#define BC_HW_FW_VERSION_PATCHLEVEL_MASK (0x00ff) /**< FW Patchlevel mask */
+#define BC_HW_FW_VERSION_PATCHLEVEL_SHIFT (0) /**< FW Patchlevel shift */
+
+#define BC_INTEN_MASK (0x000f) /**< Interrupt enable mask */
+#define BC_INTEN_PB (1 << 0) /**< Push Button Interrupt enable */
+#define BC_INTEN_DIP (1 << 1) /**< DIP Switch Interrupt enable */
+#define BC_INTEN_JOYSTICK (1 << 2) /**< Joystick Interrupt enable */
+#define BC_INTEN_AEM (1 << 3) /**< AEM Interrupt enable */
+
+#define BC_INTFLAG_MASK (0x000f) /**< Interrupt flag mask */
+#define BC_INTFLAG_PB (1 << 0) /**< Push Button interrupt triggered */
+#define BC_INTFLAG_DIP (1 << 1) /**< DIP interrupt triggered */
+#define BC_INTFLAG_JOYSTICK (1 << 2) /**< Joystick interrupt triggered */
+#define BC_INTFLAG_AEM (1 << 3) /**< AEM interrupt triggered */
+
+#endif
diff --git a/bsp/efm32/EFM32_Gxxx_DK/dvk_boardcontrol.c b/bsp/efm32/EFM32_Gxxx_DK/dvk_boardcontrol.c
new file mode 100644
index 0000000000..b14e0fc44e
--- /dev/null
+++ b/bsp/efm32/EFM32_Gxxx_DK/dvk_boardcontrol.c
@@ -0,0 +1,248 @@
+/**************************************************************************//**
+ * @file
+ * @brief DVK Peripheral Board Control API implementation
+ * @author Energy Micro AS
+ * @version 1.6.0
+ ******************************************************************************
+ * @section License
+ * (C) Copyright 2010 Energy Micro AS, http://www.energymicro.com
+ ******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************/
+
+#include "efm32.h"
+#include "dvk.h"
+#include "dvk_boardcontrol.h"
+#include "dvk_bcregisters.h"
+
+/**************************************************************************//**
+ * @brief Enable EFM32 access to periheral on DVK board
+ * @param peri Peripheral to enable
+ *****************************************************************************/
+void DVK_enablePeripheral(DVKPeripheral peri)
+{
+ uint16_t bit;
+ uint16_t tmp;
+
+ /* Calculate which bit to set */
+ bit = (uint16_t) peri;
+
+ /* Read peripheral control register */
+ tmp = DVK_readRegister(BC_PERCTRL);
+
+ /* Enable peripheral */
+ tmp |= bit;
+
+ /* Special case for RS232, if enabled disable shutdown */
+ if ((peri == DVK_RS232A) || (peri == DVK_RS232B))
+ {
+ /* clear shutdown bit */
+ tmp &= ~(BC_PERCTRL_RS232_SHUTDOWN);
+ }
+
+ /* Special case for IRDA if enabled disable shutdown */
+ if (peri == DVK_IRDA)
+ {
+ /* clear shutdown bit */
+ tmp &= ~(BC_PERCTRL_IRDA_SHUTDOWN);
+ }
+
+ DVK_writeRegister(BC_PERCTRL, tmp);
+}
+
+/**************************************************************************//**
+ * @brief Disable EFM32 access to peripheral on DVK board
+ * @param peri Peripheral to disable
+ *****************************************************************************/
+void DVK_disablePeripheral(DVKPeripheral peri)
+{
+ uint16_t bit;
+ uint16_t tmp;
+
+ /* Calculate which bit to set */
+ bit = (uint16_t) peri;
+
+ /* Read peripheral control register */
+ tmp = DVK_readRegister(BC_PERCTRL);
+
+ /* Disable peripheral */
+ tmp &= ~(bit);
+
+ /* Special case for RS232, if enabled disable shutdown */
+ if ((peri == DVK_RS232A) || (peri == DVK_RS232B))
+ {
+ /* Set shutdown bit */
+ tmp |= (BC_PERCTRL_RS232_SHUTDOWN);
+ }
+
+ /* Special case for IRDA */
+ if (peri == DVK_IRDA)
+ {
+ /* Set shutdown bit */
+ tmp |= (BC_PERCTRL_IRDA_SHUTDOWN);
+ }
+
+ DVK_writeRegister(BC_PERCTRL, tmp);
+}
+
+
+/**************************************************************************//**
+ * @brief Enable BUS access
+ *****************************************************************************/
+void DVK_enableBus(void)
+{
+ /* Enable bus access */
+ DVK_writeRegister(BC_BUS_CFG, 1);
+}
+
+
+/**************************************************************************//**
+ * @brief Disable BUS access
+ *****************************************************************************/
+void DVK_disableBus(void)
+{
+ DVK_writeRegister(BC_BUS_CFG, 0);
+}
+
+
+/**************************************************************************//**
+ * @brief Inform AEM about current energy mode
+ * @param energyMode What energy mode we are going to use next
+ *****************************************************************************/
+void DVK_setEnergyMode(uint16_t energyMode)
+{
+ DVK_writeRegister(BC_EM, energyMode);
+}
+
+
+/**************************************************************************//**
+ * @brief Get status of bush buttons
+ * @return Status of push buttons
+ *****************************************************************************/
+uint16_t DVK_getPushButtons(void)
+{
+ uint16_t pb = 0;
+ uint16_t aemState;
+
+ /* Check state */
+ aemState = DVK_readRegister(BC_AEMSTATE);
+ /* Read pushbutton status */
+ if ( aemState == BC_AEMSTATE_EFM )
+ {
+ pb = (~(DVK_readRegister(BC_PUSHBUTTON))) & 0x000f;
+ }
+ return pb;
+}
+
+/**************************************************************************//**
+ * @brief Get joystick button status
+ * @return Joystick controller status
+ *****************************************************************************/
+uint16_t DVK_getJoystick(void)
+{
+ uint16_t joyStick = 0;
+ uint16_t aemState;
+
+ /* Check state */
+ aemState = DVK_readRegister(BC_AEMSTATE);
+ /* Read pushbutton status */
+ if ( aemState == BC_AEMSTATE_EFM )
+ {
+ joyStick = (~(DVK_readRegister(BC_JOYSTICK))) & 0x001f;
+ }
+ return joyStick;
+}
+
+/**************************************************************************//**
+ * @brief Get dipswitch status
+ * The DIP switches are free for user programmable purposes
+ * @return Joystick controller status
+ *****************************************************************************/
+uint16_t DVK_getDipSwitch(void)
+{
+ uint16_t tmp;
+
+ tmp = (~(DVK_readRegister(BC_DIPSWITCH))) & 0x00ff;
+ return tmp;
+}
+
+/**************************************************************************//**
+ * @brief Sets user leds
+ * @param leds 16-bits which enables or disables the board "User leds"
+ *****************************************************************************/
+void DVK_setLEDs(uint16_t leds)
+{
+ DVK_writeRegister(BC_LED, leds);
+}
+
+/**************************************************************************//**
+ * @brief Get status of user LEDs
+ * @return Status of 16 user leds, bit 1 = on, bit 0 = off
+ *****************************************************************************/
+uint16_t DVK_getLEDs(void)
+{
+ return DVK_readRegister(BC_LED);
+}
+
+/**************************************************************************//**
+ * @brief Enable "Control" buttons/joystick/dip switch interrupts
+ * @param flags Board control interrupt flags, BC_INTEN_
+ *****************************************************************************/
+void DVK_enableInterrupt(uint16_t flags)
+{
+ uint16_t tmp;
+
+ /* Add flags to interrupt enable register */
+ tmp = DVK_readRegister(BC_INTEN);
+ tmp |= flags;
+ DVK_writeRegister(BC_INTEN, tmp);
+}
+
+/**************************************************************************//**
+ * @brief Disable "Control" buttons/joystick/dip switch interrupts
+ * @param flags Board control interrupt flags, BC_INTEN_
+ *****************************************************************************/
+void DVK_disableInterrupt(uint16_t flags)
+{
+ uint16_t tmp;
+
+ /* Clear flags from interrupt enable register */
+ tmp = DVK_readRegister(BC_INTEN);
+ flags = ~(flags);
+ tmp &= flags;
+ DVK_writeRegister(BC_INTEN, tmp);
+}
+
+/**************************************************************************//**
+ * @brief Clear interrupts
+ * @param flags Board control interrupt flags, BC_INTEN_
+ *****************************************************************************/
+void DVK_clearInterruptFlags(uint16_t flags)
+{
+ DVK_writeRegister(BC_INTFLAG, flags);
+}
+
+/**************************************************************************//**
+ * @brief Read interrupt flags
+ * @return Returns currently triggered interrupts
+ *****************************************************************************/
+uint16_t DVK_getInterruptFlags(void)
+{
+ return DVK_readRegister(BC_INTFLAG);
+}
diff --git a/bsp/efm32/EFM32_Gxxx_DK/dvk_boardcontrol.h b/bsp/efm32/EFM32_Gxxx_DK/dvk_boardcontrol.h
new file mode 100644
index 0000000000..1323ceec1a
--- /dev/null
+++ b/bsp/efm32/EFM32_Gxxx_DK/dvk_boardcontrol.h
@@ -0,0 +1,81 @@
+/**************************************************************************//**
+ * @file
+ * @brief DVK Peripheral Board Control, prototypes and definitions
+ * @author Energy Micro AS
+ * @version 1.6.0
+ ******************************************************************************
+ * @section License
+ * (C) Copyright 2010 Energy Micro AS, http://www.energymicro.com
+ ******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************/
+
+#ifndef __DVK_BOARDCONTROL_H
+#define __DVK_BOARDCONTROL_H
+
+#include
+#include "dvk_bcregisters.h"
+
+/** Periperhal access switches */
+typedef enum
+{
+ DVK_ACCEL = BC_PERCTRL_ACCEL,
+ DVK_AMBIENT = BC_PERCTRL_AMBIENT,
+ DVK_POTMETER = BC_PERCTRL_POTMETER,
+ DVK_RS232A = BC_PERCTRL_RS232A,
+ DVK_RS232B = BC_PERCTRL_RS232B,
+ DVK_SPI = BC_PERCTRL_SPI,
+ DVK_I2C = BC_PERCTRL_I2C,
+ DVK_IRDA = BC_PERCTRL_IRDA,
+ DVK_ANALOG_SE = BC_PERCTRL_ANALOG_SE,
+ DVK_ANALOG_DIFF = BC_PERCTRL_ANALOG_DIFF,
+ DVK_AUDIO_OUT = BC_PERCTRL_AUDIO_OUT,
+ DVK_AUDIO_IN = BC_PERCTRL_AUDIO_IN,
+ DVK_ACCEL_GSEL = BC_PERCTRL_ACCEL_GSEL,
+ DVK_ACCEL_SELFTEST = BC_PERCTRL_ACCEL_SELFTEST,
+ DVK_RS232_SHUTDOWN = BC_PERCTRL_RS232_SHUTDOWN,
+ DVK_IRDA_SHUTDOWN = BC_PERCTRL_IRDA_SHUTDOWN
+} DVKPeripheral;
+
+/* Peripheral Control */
+void DVK_enablePeripheral(DVKPeripheral peri);
+void DVK_disablePeripheral(DVKPeripheral peri);
+void DVK_enableBus(void);
+void DVK_disableBus(void);
+
+/* Read board controllers */
+uint16_t DVK_getPushButtons(void);
+uint16_t DVK_getJoystick(void);
+uint16_t DVK_getDipSwitch(void);
+
+/* Report AEM status */
+void DVK_setEnergyMode(uint16_t energyMode);
+
+/* User LEDs */
+void DVK_setLEDs(uint16_t leds);
+uint16_t DVK_getLEDs(void);
+
+/* Interrupt callback */
+void DVK_enableInterrupt(uint16_t flags);
+void DVK_disableInterrupt(uint16_t flags);
+
+uint16_t DVK_getInterruptFlags(void);
+void DVK_clearInterruptFlags(uint16_t flags);
+
+#endif
diff --git a/bsp/efm32/EFM32_Gxxx_DK/dvk_ebi.c b/bsp/efm32/EFM32_Gxxx_DK/dvk_ebi.c
new file mode 100644
index 0000000000..1d37f358cf
--- /dev/null
+++ b/bsp/efm32/EFM32_Gxxx_DK/dvk_ebi.c
@@ -0,0 +1,237 @@
+/**************************************************************************//**
+ * @file
+ * @brief EBI implementation of Board Control interface
+ * This implementation works for devices w/o LCD display on the
+ * MCU module, specifically the EFM32_G2xx_DK development board
+ * @author Energy Micro AS
+ * @version 1.6.0
+ ******************************************************************************
+ * @section License
+ * (C) Copyright 2010 Energy Micro AS, http://www.energymicro.com
+ ******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************/
+#include "efm32.h"
+#include "efm32_ebi.h"
+#include "efm32_cmu.h"
+#include "efm32_gpio.h"
+#include "dvk.h"
+#include "dvk_bcregisters.h"
+
+
+/**************************************************************************//**
+ * @brief Configure EBI (external bus interface) for Board Control register
+ * access
+ *****************************************************************************/
+void DVK_EBI_configure(void)
+{
+ EBI_Init_TypeDef ebiConfig = EBI_INIT_DEFAULT;
+
+ /* Run time check if we have EBI on-chip capability on this device */
+ switch ((DEVINFO->PART & _DEVINFO_PART_DEVICE_NUMBER_MASK) >>
+ _DEVINFO_PART_DEVICE_NUMBER_SHIFT)
+ {
+ /* Only device types EFM32G 280/290/880 and 890 have EBI capability */
+ case 280:
+ case 290:
+ case 880:
+ case 890:
+ break;
+ default:
+ /* This device do not have EBI capability - use SPI to interface DVK */
+ /* With high probability your project has been configured for an */
+ /* incorrect part number. */
+ while (1) ;
+ }
+
+ /* Enable clocks */
+ CMU_ClockEnable(cmuClock_EBI, true);
+ CMU_ClockEnable(cmuClock_GPIO, true);
+
+ /* Configure bus connect PC bit 12 active low */
+ GPIO_PinModeSet(gpioPortC, 12, gpioModePushPull, 0);
+
+ /* Configure GPIO pins as push pull */
+ /* EBI AD9..15 */
+ GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortA, 1, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortA, 2, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortA, 3, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortA, 4, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortA, 6, gpioModePushPull, 0);
+
+ /* EBI AD8 */
+ GPIO_PinModeSet(gpioPortA, 15, gpioModePushPull, 0);
+
+ /* EBI CS0-CS3 */
+ GPIO_PinModeSet(gpioPortD, 9, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortD, 10, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortD, 11, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortD, 12, gpioModePushPull, 0);
+
+ /* EBI AD0..7 */
+ GPIO_PinModeSet(gpioPortE, 8, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortE, 9, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortE, 10, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortE, 11, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortE, 12, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortE, 13, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortE, 14, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortE, 15, gpioModePushPull, 0);
+
+ /* EBI ARDY/ALEN/Wen/Ren */
+ GPIO_PinModeSet(gpioPortF, 2, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortF, 3, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortF, 4, gpioModePushPull, 0);
+ GPIO_PinModeSet(gpioPortF, 5, gpioModePushPull, 0);
+
+ /* Configure EBI controller, changing default values */
+ ebiConfig.mode = ebiModeD16A16ALE;
+ /* Enable bank 0 address map 0x80000000, FPGA Flash */
+ /* Enable bank 1 address map 0x84000000, FPGA SRAM */
+ /* Enable bank 2 address map 0x88000000, FPGA TFT Display (SSD2119) */
+ /* Enable bank 3 address map 0x8c000000, FPGA Board Control Registers */
+ ebiConfig.banks = EBI_BANK0|EBI_BANK1|EBI_BANK2|EBI_BANK3;
+ ebiConfig.csLines = EBI_CS0|EBI_CS1|EBI_CS2|EBI_CS3;
+
+ /* Address Setup and hold time */
+ ebiConfig.addrHoldCycles = 3;
+ ebiConfig.addrSetupCycles = 3;
+
+ /* Read cycle times */
+ ebiConfig.readStrobeCycles = 7;
+ ebiConfig.readHoldCycles = 3;
+ ebiConfig.readSetupCycles = 3;
+
+ /* Write cycle times */
+ ebiConfig.writeStrobeCycles = 7;
+ ebiConfig.writeHoldCycles = 3;
+ ebiConfig.writeSetupCycles = 3;
+
+ /* Polarity values are default */
+
+ /* Configure EBI */
+ EBI_Init(&ebiConfig);
+}
+
+
+/**************************************************************************//**
+ * @brief Initialize EBI
+ * access
+ *****************************************************************************/
+void DVK_EBI_init(void)
+{
+ uint16_t ebiMagic;
+ int ctr;
+
+ /* Disable all GPIO pins and register */
+ DVK_EBI_disable();
+ /* Configure EBI */
+ DVK_EBI_configure();
+ /* Verify that EBI access is working, if not kit is in SPI mode and needs to
+ * be configured for EBI access */
+ ebiMagic = DVK_EBI_readRegister(BC_MAGIC);
+ if (ebiMagic != BC_MAGIC_VALUE)
+ {
+ /* Disable EBI */
+ DVK_EBI_disable();
+ /* Enable SPI interface */
+ DVK_SPI_init();
+ /* Set EBI mode - after this SPI access will no longer be available */
+ DVK_SPI_writeRegister(BC_CFG, BC_CFG_EBI);
+ /* Disable SPI */
+ DVK_SPI_disable();
+ /* Now setup EBI again */
+ DVK_EBI_configure();
+ /* Wait until ready */
+ ctr = 0;
+ do
+ {
+ /* Check if FPGA responds */
+ ebiMagic = DVK_EBI_readRegister(BC_MAGIC);
+ ctr++;
+ DVK_EBI_writeRegister(BC_LED, ctr);
+ } while (ebiMagic != BC_MAGIC_VALUE);
+ }
+}
+
+/**************************************************************************//**
+ * @brief Disable EBI interface, free all GPIO pins
+ *****************************************************************************/
+void DVK_EBI_disable(void)
+{
+ /* Disable EBI controller */
+ EBI_Disable();
+
+ /* Disable EBI clock in CMU */
+ CMU_ClockEnable(cmuClock_EBI, false);
+
+ /* Disable EBI _BC_BUS_CONNECT */
+ GPIO_PinModeSet(gpioPortC, 12, gpioModeDisabled, 0);
+
+ /* Configure GPIO pins as disabled */
+ GPIO_PinModeSet(gpioPortA, 0, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortA, 1, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortA, 2, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortA, 3, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortA, 4, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortA, 5, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortA, 6, gpioModeDisabled, 0);
+
+ GPIO_PinModeSet(gpioPortA, 15, gpioModeDisabled, 0);
+
+ GPIO_PinModeSet(gpioPortD, 9, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortD, 10, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortD, 11, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortD, 12, gpioModeDisabled, 0);
+
+ GPIO_PinModeSet(gpioPortE, 8, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortE, 9, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortE, 10, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortE, 11, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortE, 12, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortE, 13, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortE, 14, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortE, 15, gpioModeDisabled, 0);
+
+ GPIO_PinModeSet(gpioPortF, 2, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortF, 3, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortF, 4, gpioModeDisabled, 0);
+ GPIO_PinModeSet(gpioPortF, 5, gpioModeDisabled, 0);
+}
+
+/**************************************************************************//**
+ * @brief Write data into 16-bit board control register
+ * @param addr Address to board control register
+ * @param data Data to write into register
+ *****************************************************************************/
+void DVK_EBI_writeRegister(volatile uint16_t *addr, uint16_t data)
+{
+ *addr = data;
+}
+
+/**************************************************************************//**
+ * @brief Write data into 16-bit board control register
+ * @param addr Register to read from
+ *****************************************************************************/
+uint16_t DVK_EBI_readRegister(volatile uint16_t *addr)
+{
+ return *addr;
+}
diff --git a/bsp/efm32/EFM32_Gxxx_DK/dvk_spi.c b/bsp/efm32/EFM32_Gxxx_DK/dvk_spi.c
new file mode 100644
index 0000000000..a3f9c4dafc
--- /dev/null
+++ b/bsp/efm32/EFM32_Gxxx_DK/dvk_spi.c
@@ -0,0 +1,230 @@
+/**************************************************************************//**
+ * @file
+ * @brief SPI implementation of Board Control interface
+ * This implementation use the USART2 SPI interface to control board
+ * control registers. It works
+ * @author Energy Micro AS
+ * @version 1.6.0
+ ******************************************************************************
+ * @section License
+ * (C) Copyright 2010 Energy Micro AS, http://www.energymicro.com
+ ******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************/
+
+#include
+#include "efm32.h"
+#include "efm32_usart.h"
+#include "efm32_gpio.h"
+#include "efm32_cmu.h"
+#include "dvk.h"
+#include "dvk_bcregisters.h"
+
+/* USART used for SPI access */
+#define USART_USED USART2
+#define USART_CLK cmuClock_USART2
+
+/* GPIO pins used, please refer to DVK user guide. */
+#define PIN_SPIBUS_CONNECT 13
+#define PORT_SPIBUS_CONNECT gpioPortC
+#define PIN_SPI_TX 2
+#define PORT_SPI_TX gpioPortC
+#define PIN_SPI_RX 3
+#define PORT_SPI_RX gpioPortC
+#define PIN_SPI_CLK 4
+#define PORT_SPI_CLK gpioPortC
+#define PIN_SPI_CS 5
+#define PORT_SPI_CS gpioPortC
+
+static volatile uint16_t *lastAddr = NULL;
+
+/**************************************************************************//**
+ * @brief Initializes SPI interface for access to FPGA registers
+ * for board control
+ *****************************************************************************/
+static void spiInit(void)
+{
+ USART_InitSync_TypeDef init = USART_INITSYNC_DEFAULT;
+
+ /* Enable module clocks */
+ CMU_ClockEnable(cmuClock_GPIO, true);
+ CMU_ClockEnable(cmuClock_HFPER, true);
+ CMU_ClockEnable(USART_CLK, true);
+
+ /* Configure SPI bus connect pins, DOUT set to 0 */
+ GPIO_PinModeSet(PORT_SPIBUS_CONNECT, PIN_SPIBUS_CONNECT, gpioModePushPull, 0);
+
+ /* Configure SPI pins */
+ GPIO_PinModeSet(PORT_SPI_TX, PIN_SPI_TX, gpioModePushPull, 0);
+ GPIO_PinModeSet(PORT_SPI_RX, PIN_SPI_RX, gpioModePushPull, 0);
+ GPIO_PinModeSet(PORT_SPI_CLK, PIN_SPI_CLK, gpioModePushPull, 0);
+ /* Keep CS high to not activate slave */
+ GPIO_PinModeSet(PORT_SPI_CS, PIN_SPI_CS, gpioModePushPull, 1);
+
+ /* Enable pins at default location */
+ USART_USED->ROUTE = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CLKPEN;
+
+ /* Reset USART just in case */
+ USART_Reset(USART_USED);
+
+ /* Configure to use SPI master with manual CS */
+ /* For now, configure SPI for worst case 32MHz clock in order to work for all */
+ /* configurations. */
+ init.refFreq = 32000000;
+ init.baudrate = 7000000;
+ USART_InitSync(USART_USED, &init);
+}
+
+/**************************************************************************//**
+ * @brief Disables GPIO pins and USART from FPGA register access
+ *****************************************************************************/
+static void spiDisable(void)
+{
+ USART_Reset(USART_USED);
+
+ /* Route setup must be reset separately */
+ USART_USED->ROUTE = _USART_ROUTE_RESETVALUE;
+
+ /* Disable SPI pins */
+ GPIO_PinModeSet(PORT_SPIBUS_CONNECT, PIN_SPIBUS_CONNECT, gpioModeDisabled, 0);
+ GPIO_PinModeSet(PORT_SPI_TX, PIN_SPI_TX, gpioModeDisabled, 0);
+ GPIO_PinModeSet(PORT_SPI_RX, PIN_SPI_RX, gpioModeDisabled, 0);
+ GPIO_PinModeSet(PORT_SPI_CLK, PIN_SPI_CLK, gpioModeDisabled, 0);
+ GPIO_PinModeSet(PORT_SPI_CS, PIN_SPI_CS, gpioModeDisabled, 0);
+
+ /* Disable USART clock - we can't disable GPIO or HFPER as we don't know who else
+ * might be using it */
+ CMU_ClockEnable(USART_CLK, false);
+}
+
+/**************************************************************************//**
+ * @brief Perform SPI Transfer
+ *****************************************************************************/
+static uint16_t spiAccess(uint8_t spiaddr, uint8_t rw, uint16_t spidata)
+{
+ uint16_t tmp;
+
+ GPIO_PinOutClear(PORT_SPI_CS, PIN_SPI_CS);
+
+ /* For every byte sent, one is received */
+
+ /* Write SPI address */
+ USART_Tx(USART_USED, (spiaddr & 0x3) | rw << 3);
+ /* Just ignore data read back */
+ USART_Rx(USART_USED);
+
+ /* SPI data LSB */
+ USART_Tx(USART_USED, spidata & 0xFF);
+ tmp = (uint16_t)USART_Rx(USART_USED);
+
+ /* SPI data MSB */
+ USART_Tx(USART_USED, spidata >> 8);
+ tmp |= (uint16_t)USART_Rx(USART_USED) << 8;
+
+ GPIO_PinOutSet(PORT_SPI_CS, PIN_SPI_CS);
+
+ return tmp;
+}
+
+/**************************************************************************//**
+ * @brief Performs SPI write to FPGA register
+ * @param spiadr Address of register
+ * @param spidata Data to write
+ *****************************************************************************/
+static void spiWrite(uint8_t spiadr, uint16_t spidata)
+{
+ spiAccess(spiadr, 0, spidata);
+}
+
+/**************************************************************************//**
+ * @brief Performs SPI read from FPGA register
+ * @param spiadr Address of register
+ * @param spidata Dummy data
+ *****************************************************************************/
+static uint16_t spiRead(uint8_t spiadr, uint16_t spidata)
+{
+ return spiAccess(spiadr, 1, spidata);
+}
+
+/**************************************************************************//**
+ * @brief Initializes DVK register access
+ *****************************************************************************/
+void DVK_SPI_init(void)
+{
+ uint16_t spiMagic;
+
+ spiInit();
+ /* Read "board control Magic" register to verify SPI is up and running */
+ /* if not FPGA is configured to be in EBI mode */
+
+ spiMagic = DVK_SPI_readRegister(BC_MAGIC);
+ if (spiMagic != BC_MAGIC_VALUE)
+ {
+ /* Development Kit is configured to use EBI mode, restart of kit required */
+ /* to use SPI for configuration */
+ spiDisable();
+ while (1) ;
+ }
+}
+
+/**************************************************************************//**
+ * @brief Disable and free up resources used by SPI board control access
+ *****************************************************************************/
+void DVK_SPI_disable(void)
+{
+ spiDisable();
+}
+
+/**************************************************************************//**
+ * @brief Perform read from DVK board control register
+ * @param addr Address of register to read from
+ *****************************************************************************/
+uint16_t DVK_SPI_readRegister(volatile uint16_t *addr)
+{
+ uint16_t data;
+
+ if (addr != lastAddr)
+ {
+ spiWrite(0x00, 0xFFFF & ((uint32_t) addr)); /*LSBs of address*/
+ spiWrite(0x01, 0xFF & ((uint32_t) addr >> 16)); /*MSBs of address*/
+ spiWrite(0x02, (0x0C000000 & (uint32_t) addr) >> 26); /*Chip select*/
+ }
+ /* Read twice */
+ data = spiRead(0x03, 0);
+ data = spiRead(0x03, 0);
+ lastAddr = addr;
+ return data;
+}
+
+/**************************************************************************//**
+ * @brief Perform write to DVK board control register
+ * @param addr Address of register to write to
+ * @param data 16-bit to write into register
+ *****************************************************************************/
+void DVK_SPI_writeRegister(volatile uint16_t *addr, uint16_t data)
+{
+ if (addr != lastAddr)
+ {
+ spiWrite(0x00, 0xFFFF & ((uint32_t) addr)); /*LSBs of address*/
+ spiWrite(0x01, 0xFF & ((uint32_t) addr >> 16)); /*MSBs of address*/
+ spiWrite(0x02, (0x0C000000 & (uint32_t) addr) >> 26); /*Chip select*/
+ }
+ spiWrite(0x03, data); /*Data*/
+ lastAddr = addr;
+}
diff --git a/bsp/efm32/SConscript b/bsp/efm32/SConscript
index 97f795f977..a9083c9362 100644
--- a/bsp/efm32/SConscript
+++ b/bsp/efm32/SConscript
@@ -2,13 +2,20 @@ import rtconfig
Import('RTT_ROOT')
from building import *
+if rtconfig.EFM32_BOARD == 'EFM32_G290_DK':
+ src_kit = Glob('EFM32_Gxxx_DK/*.c')
+ CPPPATH = [RTT_ROOT + '/bsp/efm32/EFM32_Gxxx_DK']
+else:
+ src_kit = []
+ CPPPATH = []
+
src_bsp = ['application.c', 'startup.c', 'board.c']
src_drv = ['drv_dma.c', 'drv_rtc.c', 'drv_adc.c', 'drv_acmp.c', 'drv_usart.c', 'drv_iic.c', 'drv_timer.c']
-src_dev = ['dev_misc.c', 'dev_led.c']
+src_dev = ['dev_misc.c', 'dev_led.c', 'dev_sflash.c']
src_hdl = ['hdl_interrupt.c']
-src = src_bsp + src_drv + src_dev + src_hdl
-CPPPATH = [RTT_ROOT + '/bsp/efm32']
+src = src_kit + src_bsp + src_drv + src_dev + src_hdl
+CPPPATH.append(RTT_ROOT + '/bsp/efm32')
CPPDEFINES = ['USE_STDPERIPH_DRIVER', rtconfig.EFM32_BOARD, rtconfig.EFM32_TYPE]
group = DefineGroup('Startup', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
diff --git a/bsp/efm32/application.c b/bsp/efm32/application.c
index 8d519685a4..1688e42461 100644
--- a/bsp/efm32/application.c
+++ b/bsp/efm32/application.c
@@ -13,6 +13,7 @@
* Date Author Notes
* 2009-01-05 Bernard first version
* 2010-12-29 onelife Modify for EFM32
+ * 2011-05-06 onelife Add SPI Flash DEMO
*********************************************************************/
/******************************************************************//**
@@ -32,10 +33,9 @@
#include
#endif
-#ifdef RT_USING_LWIP
-#include
-#include
-#include
+#include "dev_led.h"
+#ifdef EFM32_USING_SFLASH
+#include "dev_sflash.h"
#endif
/* Private typedef -------------------------------------------------------------*/
@@ -46,28 +46,74 @@ rt_uint32_t rt_system_status = 0;
/* Private function prototypes ---------------------------------------------------*/
/* Private functions ------------------------------------------------------------*/
+void rt_demo_thread_entry(void* parameter)
+{
+#ifdef EFM32_USING_SFLASH
+ rt_uint8_t i;
+ rt_uint8_t test[] = "123456789ABCDEF";
+ rt_uint8_t buf[30], buf2[30];
+
+ efm_spiFash_cmd(sflash_inst_rdid_l, EFM32_NO_DATA, buf, sizeof(buf));
+ rt_kprintf("Manuf ID: %x\n", buf[0]);
+ rt_kprintf("Memory type: %x\n", buf[1]);
+ rt_kprintf("Memory capacity: %x\n", buf[2]);
+ rt_kprintf("CFD length: %x\n", buf[3]);
+ rt_kprintf("CFD: %x%x%x...%x%x\n", buf[4], buf[5], buf[6], buf[18], buf[19]);
+
+ efm_spiFash_cmd(sflash_inst_wren, EFM32_NO_DATA, EFM32_NO_POINTER, EFM32_NO_DATA);
+ do
+ {
+ efm_spiFash_cmd(sflash_inst_rdsr, EFM32_NO_DATA, buf2, sizeof(buf2));
+ rt_kprintf("Status: %x\n", buf2[0]);
+ } while (buf2[0] == 0xFF);
+ rt_kprintf("Status: %x\n", buf2[0]);
+
+ //efm_spiFash_cmd(sflash_inst_pp, 0x000003F8, test, sizeof(test) - 1);
+
+ efm_spiFash_cmd(sflash_inst_rdsr, EFM32_NO_DATA, buf2, sizeof(buf2));
+ rt_kprintf("Status: %x\n", buf2[0]);
+
+ efm_spiFash_cmd(sflash_inst_read, 0x00000300, buf, sizeof(buf));
+ rt_kprintf("READ: \n");
+ for (i = 0; i < sizeof(buf); i++)
+ {
+ rt_kprintf("%c\n", buf[i]);
+ }
+
+ //efm_spiFash_deinit();
+#endif
+}
+
void rt_led_thread_entry(void* parameter)
{
-// rt_uint8_t n = 0;
-
+ rt_uint8_t n = 0;
+
rt_hw_led_on(0);
rt_hw_led_on(1);
rt_hw_led_on(2);
rt_hw_led_on(3);
-
-// while(1)
-// {
- /* light on leds for one second */
-// rt_hw_led_toggle(n++);
-// if (n == 4)
-// n =0;
-// rt_thread_delay(200);
-// }
+
+ while(1)
+ {
+ /* Toggle a led per second */
+ rt_hw_led_toggle(n++);
+ if (n == LEDS_MAX_NUMBER)
+ {
+ n =0;
+ }
+ rt_thread_delay(100);
+ }
}
int rt_application_init()
{
- rt_thread_t led_thread;
+ rt_thread_t demo_thread, led_thread;
+
+#if (defined(EFM32_G290_DK) && defined(EFM32_USING_SFLASH))
+ /* Enable SPI access to Flash */
+ DVK_writeRegister(BC_SPI_CFG, 0);
+ efm_spiFash_init();
+#endif
/* Initialize all device drivers (dev_?.c) */
if (rt_hw_led_init() != RT_EOK)
@@ -82,19 +128,32 @@ int rt_application_init()
}
#if (RT_THREAD_PRIORITY_MAX == 32)
+ demo_thread = rt_thread_create(
+ "demo",
+ rt_demo_thread_entry,
+ RT_NULL,
+ 2048,
+ 3,
+ 20);
+
led_thread = rt_thread_create(
"led",
rt_led_thread_entry,
RT_NULL,
- 256,
+ 256,
3,
20);
#else
#endif
+ if(demo_thread != RT_NULL)
+ {
+ rt_kprintf("demo sp:%x\n", demo_thread->sp);
+ rt_thread_startup(demo_thread);
+ }
+
if(led_thread != RT_NULL)
{
- rt_kprintf("led sp:%x\n", led_thread->sp);
rt_thread_startup(led_thread);
}
diff --git a/bsp/efm32/board.c b/bsp/efm32/board.c
index 507a416ef6..a9a0f7648f 100644
--- a/bsp/efm32/board.c
+++ b/bsp/efm32/board.c
@@ -12,6 +12,7 @@
* @section Change Logs
* Date Author Notes
* 2010-12-21 onelife Initial creation for EFM32
+ * 2011-05-06 onelife Add EFM32 development kit and SPI Flash support
*********************************************************************/
/******************************************************************//**
@@ -189,6 +190,11 @@ void rt_hw_board_init(void)
/* Chip errata */
CHIP_Init();
+#if defined(EFM32_G290_DK)
+ /* Initialize DVK board register access */
+ DVK_init();
+#endif
+
/* NVIC Configuration */
NVIC_Configuration();
@@ -222,6 +228,10 @@ void rt_hw_driver_init(void)
rt_hw_dma_init();
/* Initialize USART */
+#if defined(EFM32_G290_DK)
+ DVK_enablePeripheral(DVK_RS232A);
+ DVK_enablePeripheral(DVK_SPI);
+#endif
rt_hw_usart_init();
/* Initialize Timer */
diff --git a/bsp/efm32/board.h b/bsp/efm32/board.h
index be56bcc326..fb4e9b08f1 100644
--- a/bsp/efm32/board.h
+++ b/bsp/efm32/board.h
@@ -12,6 +12,7 @@
* @section Change Logs
* Date Author Notes
* 2010-12-21 onelife Initial creation for EFM32
+ * 2011-05-06 onelife Add EFM32 development kit and SPI Flash support
*********************************************************************/
#ifndef __BOARD_H__
#define __BOARD_H__
@@ -39,6 +40,10 @@
#include
+#if defined(EFM32_G290_DK)
+#include
+#endif
+
/* Exported types -------------------------------------------------------------*/
/* Exported constants ---------------------------------------------------------*/
/* Exported variables ----------------------------------------------------------*/
@@ -48,41 +53,53 @@ extern rt_uint32_t rt_system_status;
#define DEBUG_EFM
#define DEBUG_EFM_USER
-#define EFM32_NO_DATA (0)
-#define EFM32_NO_OFFSET (-1)
-#define EFM32_NO_POINTER (RT_NULL)
+#define EFM32_SFLASH_DEBUG
-#define EFM32_SRAM_END (RAM_MEM_BASE + SRAM_SIZE)
+#define EFM32_NO_DATA (0)
+#define EFM32_NO_OFFSET (-1)
+#define EFM32_NO_POINTER (RT_NULL)
-#define EFM32_BASE_PRI_DEFAULT (0x0UL << 5)
-#define EFM32_IRQ_PRI_DEFAULT (0x4UL << 5)
+#define EFM32_SRAM_END (RAM_MEM_BASE + SRAM_SIZE)
+
+#define EFM32_BASE_PRI_DEFAULT (0x0UL << 5)
+#define EFM32_IRQ_PRI_DEFAULT (0x4UL << 5)
#if (defined(EFM32_G890_STK) || defined(EFM32_G290_DK))
-#define EFM32_HFXO_FREQUENCY (32000000)
+#define EFM32_HFXO_FREQUENCY (32000000)
#else
-#define EFM32_HFXO_FREQUENCY (00000000)
+#define EFM32_HFXO_FREQUENCY (00000000)
#endif
-#define UART_BAUDRATE (115200)
+#define UART_BAUDRATE (115200)
+#define USART_RX_BUFFER_SIZE (64)
-#define SERIAL_RX_BUFFER_SIZE (64)
+/* Max SPI clock: HFPERCLK/2 for master, HFPERCLK/8 for slave */
+#define SPI_BAUDRATE (4000000)
-#define IIC_RX_BUFFER_SIZE (32)
+/* Slave select PIN setting for unit 2, 1 and 0 */
+#define SPI_AUTOCS_ENABLE ((0 << 2) | (0 << 1) | (1 << 0))
-#define ADC_INIT_REF adcRef2V5
-#define ADC_INIT_CH adcSingleInpCh5
-#define ADC_CONVERT_FREQUENCY (7000000)
+#define IIC_RX_BUFFER_SIZE (32)
+
+#define ADC_INIT_REF adcRef2V5
+#define ADC_INIT_CH adcSingleInpCh5
+#define ADC_CONVERT_FREQUENCY (7000000)
#if (RT_CONSOLE_DEVICE == 0x0UL)
-#define CONSOLE_DEVICE RT_USART0_NAME
+#define CONSOLE_DEVICE RT_USART0_NAME
#elif (RT_CONSOLE_DEVICE == 0x1UL)
-#define CONSOLE_DEVICE RT_USART1_NAME
+#define CONSOLE_DEVICE RT_USART1_NAME
#elif (RT_CONSOLE_DEVICE == 0x2UL)
-#define CONSOLE_DEVICE RT_USART2_NAME
+#define CONSOLE_DEVICE RT_USART2_NAME
#else
-#define CONSOLE_DEVICE "no"
+#define CONSOLE_DEVICE "no"
#endif
+#if defined(EFM32_G290_DK)
+#define EFM32_USING_SFLASH
+#endif
+#define SFLASH_USING_DEVICE_NAME RT_USART0_NAME
+
/*! fixme: move the following define to Rtdef.h */
#define RT_DEVICE_CTRL_USART_RBUFFER (0xF1) /*!< set USART rx buffer */
#define RT_DEVICE_CTRL_IIC_SETTING (0xF2) /*!< change IIC setting */
diff --git a/bsp/efm32/dev_led.c b/bsp/efm32/dev_led.c
index 060e6644d0..c1cceb92e8 100644
--- a/bsp/efm32/dev_led.c
+++ b/bsp/efm32/dev_led.c
@@ -12,7 +12,8 @@
* @section Change Logs
* Date Author Notes
* 2009-01-05 Bernard the first version
- * 2010-12-27 onelife modify for EFM32
+ * 2010-12-27 onelife Modify for EFM32
+ * 2011-05-06 onelife Add EFM32 development kit support
*********************************************************************/
/******************************************************************//**
@@ -28,6 +29,7 @@
/* Private define --------------------------------------------------------------*/
/* Private macro --------------------------------------------------------------*/
/* Private constants -----------------------------------------------------------*/
+#if defined(EFM32_G890_STK)
static const rt_uint8_t leds_list[LEDS_MAX_NUMBER][2] = \
{
{LEDS_PIN_PORT_0, LEDS_PIN_NUMBER_0},
@@ -35,6 +37,7 @@ static const rt_uint8_t leds_list[LEDS_MAX_NUMBER][2] = \
{LEDS_PIN_PORT_2, LEDS_PIN_NUMBER_2},
{LEDS_PIN_PORT_3, LEDS_PIN_NUMBER_3}
};
+#endif
/* Private variables ------------------------------------------------------------*/
/* Private function prototypes ---------------------------------------------------*/
@@ -54,8 +57,17 @@ static const rt_uint8_t leds_list[LEDS_MAX_NUMBER][2] = \
void rt_hw_led_on(rt_uint8_t num)
{
RT_ASSERT(num < LEDS_MAX_NUMBER);
-
+
+#if defined(EFM32_G890_STK)
GPIO_PinOutSet(leds_list[num][0], leds_list[num][1]);
+#elif defined(EFM32_G290_DK)
+{
+ rt_uint16_t leds;
+
+ leds = DVK_getLEDs() | (rt_uint16_t)(1 << num);
+ DVK_setLEDs(leds);
+}
+#endif
}
/******************************************************************//**
@@ -73,8 +85,17 @@ void rt_hw_led_on(rt_uint8_t num)
void rt_hw_led_off(rt_uint8_t num)
{
RT_ASSERT(num < LEDS_MAX_NUMBER);
-
+
+#if defined(EFM32_G890_STK)
GPIO_PinOutClear(leds_list[num][0], leds_list[num][1]);
+#elif defined(EFM32_G290_DK)
+{
+ rt_uint16_t leds;
+
+ leds = DVK_getLEDs() & ~(rt_uint16_t)(1 << num);
+ DVK_setLEDs(leds);
+}
+#endif
}
/******************************************************************//**
@@ -92,15 +113,29 @@ void rt_hw_led_off(rt_uint8_t num)
void rt_hw_led_toggle(rt_uint8_t num)
{
RT_ASSERT(num < LEDS_MAX_NUMBER);
-
+
+#if defined(EFM32_G890_STK)
GPIO_PinOutToggle(leds_list[num][0], leds_list[num][1]);
+#elif defined(EFM32_G290_DK)
+{
+ rt_uint16_t leds;
+
+ leds = DVK_getLEDs() ^ (rt_uint16_t)(1 << num);
+ DVK_setLEDs(leds);
+}
+#endif
}
rt_uint8_t rt_hw_led_state(rt_uint8_t num)
{
RT_ASSERT(num < LEDS_MAX_NUMBER);
-
+
+#if defined(EFM32_G890_STK)
return (rt_uint8_t)GPIO_PinInGet(leds_list[num][0], leds_list[num][1]);
+#elif defined(EFM32_G290_DK)
+ return ((DVK_getLEDs() & (rt_uint16_t)(1 << num)) >> num);
+#endif
+
}
/******************************************************************//**
@@ -116,6 +151,7 @@ rt_uint8_t rt_hw_led_state(rt_uint8_t num)
*********************************************************************/
rt_err_t rt_hw_led_init(void)
{
+#if defined(EFM32_G890_STK)
rt_uint8_t i;
/* Configure GPIO */
@@ -127,7 +163,7 @@ rt_err_t rt_hw_led_init(void)
gpioModePushPull,
0);
}
-
+#endif
return RT_EOK;
}
@@ -146,8 +182,16 @@ void list_leds(void)
for (i = 0; i < LEDS_MAX_NUMBER; i++)
{
+#if defined(EFM32_G890_STK)
rt_kprintf(" %d \t %x \t %x \t %x \n",
i, leds_list[i][0], leds_list[i][1], rt_hw_led_state(i));
+#elif defined(EFM32_G290_DK)
+ rt_uint16_t leds;
+
+ leds = DVK_getLEDs();
+ rt_kprintf(" %d \t FPGA \t FPGA \t %x \n",
+ i, (leds & (1 << i))? 1 : 0);
+#endif
}
}
FINSH_FUNCTION_EXPORT(list_leds, list all the LEDs.)
diff --git a/bsp/efm32/dev_led.h b/bsp/efm32/dev_led.h
index 14b6ccc1f3..9bc7190e4a 100644
--- a/bsp/efm32/dev_led.h
+++ b/bsp/efm32/dev_led.h
@@ -12,7 +12,8 @@
* @section Change Logs
* Date Author Notes
* 2009-01-05 Bernard the first version
- * 2010-12-27 onelife modify for EFM32
+ * 2010-12-27 onelife Modify for EFM32
+ * 2011-05-06 onelife Add EFM32 development kit support
*********************************************************************/
#ifndef __DEV_LED_H__
#define __DEV_LED_H__
@@ -32,9 +33,8 @@
#define LEDS_PIN_NUMBER_2 (2)
#define LEDS_PIN_PORT_3 gpioPortC
#define LEDS_PIN_NUMBER_3 (3)
-
#elif defined(EFM32_G290_DK)
- // TODO:
+#define LEDS_MAX_NUMBER (16)
#endif
/* Exported functions --------------------------------------------------------- */
diff --git a/bsp/efm32/dev_sflash.c b/bsp/efm32/dev_sflash.c
new file mode 100644
index 0000000000..fa79ce6883
--- /dev/null
+++ b/bsp/efm32/dev_sflash.c
@@ -0,0 +1,355 @@
+/******************************************************************//**
+ * @file dev_sflash.c
+ * @brief SPI Flash driver of RT-Thread RTOS for using EFM32 USART module.
+ * This driver is tested by using the M25PX16 device on the EFM32 development kit.
+ * COPYRIGHT (C) 2011, RT-Thread Development Team
+ * @author onelife
+ * @version 0.4 beta
+ **********************************************************************
+ * @section License
+ * The license and distribution terms for this file may be found in the file LICENSE in this
+ * distribution or at http://www.rt-thread.org/license/LICENSE
+ **********************************************************************
+ * @section Change Logs
+ * Date Author Notes
+ * 2010-05-06 onelife Initial creation for using EFM32 USART module
+ *********************************************************************/
+
+/******************************************************************//**
+ * @addtogroup efm32_dk
+ * @{
+*********************************************************************/
+
+/* Includes -------------------------------------------------------------------*/
+#include "board.h"
+#include "dev_sflash.h"
+
+#if defined(EFM32_USING_SFLASH)
+/* Private typedef -------------------------------------------------------------*/
+typedef struct
+{
+ rt_uint8_t code;
+ rt_uint32_t address:24;
+ rt_uint32_t dummy:8;
+} sflash_instruction;
+
+/* Private define --------------------------------------------------------------*/
+/* Private macro --------------------------------------------------------------*/
+#ifdef EFM32_SFLASH_DEBUG
+#define sflash_debug(format,args...) rt_kprintf(format, ##args)
+#else
+#define sflash_debug(format,args...)
+#endif
+
+/* Private constants -----------------------------------------------------------*/
+static rt_uint8_t sflash_inst_code_tbl[] =
+{
+ /* Instruction only */
+ SFLASH_INST_CODE_WREN,
+ SFLASH_INST_CODE_WRDI,
+ SFLASH_INST_CODE_RDID_L,
+ SFLASH_INST_CODE_RDID_S,
+ SFLASH_INST_CODE_RDSR,
+ SFLASH_INST_CODE_WRSR,
+ SFLASH_INST_CODE_BE,
+ SFLASH_INST_CODE_DP,
+ SFLASH_INST_CODE_RDP,
+ /* Instruction and address */
+ SFLASH_INST_CODE_WRLR,
+ SFLASH_INST_CODE_RDLR,
+ SFLASH_INST_CODE_READ,
+ SFLASH_INST_CODE_POTP,
+ SFLASH_INST_CODE_PP,
+ SFLASH_INST_CODE_DIFP,
+ SFLASH_INST_CODE_SSE,
+ SFLASH_INST_CODE_SE,
+ /* Instruction, address and dummy read */
+ SFLASH_INST_CODE_READ_F,
+ SFLASH_INST_CODE_DOFR,
+ SFLASH_INST_CODE_ROTP
+};
+static rt_uint16_t sflash_data_len_tbl[] =
+{
+ /* Instruction only */
+ SFLASH_REPLY_LEN_WREN,
+ SFLASH_REPLY_LEN_WRDI,
+ SFLASH_REPLY_LEN_RDID_L,
+ SFLASH_REPLY_LEN_RDID_S,
+ SFLASH_REPLY_LEN_RDSR,
+ SFLASH_REPLY_LEN_WRSR,
+ SFLASH_REPLY_LEN_BE,
+ SFLASH_REPLY_LEN_DP,
+ SFLASH_REPLY_LEN_RDP,
+ /* Instruction and address */
+ SFLASH_REPLY_LEN_WRLR,
+ SFLASH_REPLY_LEN_RDLR,
+ SFLASH_REPLY_LEN_READ,
+ SFLASH_REPLY_LEN_POTP,
+ SFLASH_REPLY_LEN_PP,
+ SFLASH_REPLY_LEN_DIFP,
+ SFLASH_REPLY_LEN_SSE,
+ SFLASH_REPLY_LEN_SE,
+ /* Instruction, address and dummy read */
+ SFLASH_REPLY_LEN_READ_F,
+ SFLASH_REPLY_LEN_DOFR,
+ SFLASH_REPLY_LEN_ROTP
+};
+static rt_bool_t sflash_read_inst_tbl[] =
+{
+ /* Instruction only */
+ false,
+ false,
+ true,
+ true,
+ true,
+ false,
+ false,
+ false,
+ false,
+ /* Instruction and address */
+ false,
+ true,
+ true,
+ false,
+ false,
+ false,
+ false,
+ false,
+ /* Instruction, address and dummy read */
+ true,
+ true,
+ true
+};
+
+/* Private variables ------------------------------------------------------------*/
+static rt_device_t sflash = RT_NULL;
+
+/* Private function prototypes ---------------------------------------------------*/
+/* Private functions ------------------------------------------------------------*/
+/******************************************************************//**
+ * @brief
+ * Initialize the SPI Flash
+ *
+ * @details
+ *
+ * @note
+ *
+ * @return
+ * Error code
+ *********************************************************************/
+rt_err_t efm_spiFash_init(void)
+{
+ /* Find SPI device */
+ sflash = rt_device_find(SFLASH_USING_DEVICE_NAME);
+
+ do
+ {
+ if (sflash == RT_NULL)
+ {
+ sflash_debug("SFLASH: Can't find device %s!\n",
+ SFLASH_USING_DEVICE_NAME);
+ break;
+ }
+ sflash_debug("SFLASH: Find device %s\n", SFLASH_USING_DEVICE_NAME);
+
+ /* Open SPI device */
+ if (sflash->open(sflash, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
+ {
+ break;
+ }
+
+ return RT_EOK;
+ } while(0);
+
+ sflash_debug("SFLASH: Init failed!\n");
+ return -RT_ERROR;
+}
+
+/******************************************************************//**
+ * @brief
+ * De-initialize the SPI Flash
+ *
+ * @details
+ *
+ * @note
+ *
+ * @return
+ * Error code
+ *********************************************************************/
+rt_err_t efm_spiFash_deinit(void)
+{
+ do
+ {
+ if (sflash == RT_NULL)
+ {
+ sflash_debug("SFLASH: Already deinit!\n");
+ break;
+ }
+
+ /* Close SPI device */
+ if (sflash->close(sflash) != RT_EOK)
+ {
+ break;
+ }
+ sflash = RT_NULL;
+ sflash_debug("SFLASH: Close device %s\n", SFLASH_USING_DEVICE_NAME);
+
+ return RT_EOK;
+ } while(0);
+
+ sflash_debug("SFLASH: Deinit failed!\n");
+ return -RT_ERROR;
+}
+
+
+/******************************************************************//**
+ * @brief
+ * Execute a command
+ *
+ * @details
+ *
+ * @note
+ *
+ * @param[in] command
+ * SPI Flash instruction
+ *
+ * @param[in] address
+ * Memory address
+ *
+ * @param[in] buffer
+ * Poniter to the read/write buffer
+ *
+ * @param[in] size
+ * Buffer size in byte
+ *
+ * @return
+ * Number of read/written bytes
+ *********************************************************************/
+rt_uint32_t efm_spiFash_cmd(
+ enum sflash_inst_type_t command,
+ rt_uint32_t address,
+ rt_uint8_t *buffer,
+ rt_uint32_t size)
+{
+ RT_ASSERT(sflash != RT_NULL);
+
+ sflash_instruction *inst;
+ rt_uint8_t *inst_buf;
+ rt_uint8_t inst_len, head_len;
+ rt_uint32_t data_len;
+
+ sflash_debug("SFLASH: Inst %x\n", sflash_inst_code_tbl[command]);
+ if (sflash_data_len_tbl[command] && !size)
+ {
+ sflash_debug("SFLASH: No data!\n");
+ return 0x00;
+ }
+
+ data_len = (sflash_data_len_tbl[command] < size)? \
+ sflash_data_len_tbl[command] : size;
+ if (data_len && (buffer == RT_NULL))
+ {
+ sflash_debug("SFLASH: No buffer specified!\n");
+ return 0x00;
+ }
+
+ /* Allocate memory for write buffer */
+ if (sflash_read_inst_tbl[command])
+ {
+ inst_buf = rt_malloc(6 + 4);
+ inst = (sflash_instruction *)(inst_buf + 1);
+ head_len = 1;
+ }
+ else
+ {
+ inst_buf = rt_malloc(5 + data_len);
+ inst = (sflash_instruction *)inst_buf;
+ head_len = 0;
+ }
+
+ /* Fill in instruction */
+ inst->code = sflash_inst_code_tbl[command];
+ if (command >= sflash_inst_wrlr)
+ {
+ /* MSB first */
+ inst->address = ((address & 0x000000FF) << 16) | \
+ (address & 0x0000FF00) | \
+ ((address & 0x00FF0000) >> 16);
+ if (command >= sflash_inst_read_f)
+ {
+ inst->dummy = 0x00;
+ inst_len = 5;
+ }
+ else
+ {
+ inst_len = 4;
+ }
+ }
+ else
+ {
+ inst_len = 1;
+ }
+ head_len += inst_len;
+
+ /* Fill in data and send the buffer */
+ if (sflash_read_inst_tbl[command])
+ {
+ inst_buf[0] = inst_len;
+ *(rt_uint8_t **)(inst_buf + head_len) = buffer;
+
+ if (sflash->read(sflash, EFM32_NO_DATA, inst_buf, \
+ (data_len == size)? data_len - 1 : data_len) == 0)
+ {
+ sflash_debug("SFLASH: Read failed!\n");
+ return 0x00;
+ }
+ buffer[data_len] = 0x00;
+ sflash_debug("SFLASH: Read %d bytes data to 0x%x\n", data_len, buffer);
+ }
+ else
+ {
+ if (data_len)
+ {
+ rt_memcpy((inst_buf + head_len), buffer, data_len);
+ }
+
+ if (sflash->write(sflash, EFM32_NO_DATA, inst_buf, \
+ head_len + data_len) == 0)
+ {
+ sflash_debug("SFLASH: Write failed!\n");
+ return 0x00;
+ }
+ sflash_debug("SFLASH: Write %d/%d bytes data\n", data_len, \
+ head_len + data_len);
+ }
+
+ /* Free the buffer */
+ rt_free(inst_buf);
+ return data_len;
+}
+
+/*********************************************************************
+* Export to FINSH
+*********************************************************************/
+#ifdef RT_USING_FINSH
+#include
+
+void list_sflash(void)
+{
+ rt_uint8_t buf[4];
+
+ efm_spiFash_cmd(sflash_inst_rdid_s, EFM32_NO_DATA, buf, sizeof(buf));
+
+ rt_kprintf(" spi flash on %s\n", SFLASH_USING_DEVICE_NAME);
+ rt_kprintf(" manufacturer id: \t%x\n", buf[0]);
+ rt_kprintf(" memory type: \t\t%x\n", buf[1]);
+ rt_kprintf(" memory capacity: \t%x\n", buf[2]);
+}
+FINSH_FUNCTION_EXPORT(list_sflash, list the SPI Flash.)
+#endif
+
+#endif /* defined(EFM32_USING_SFLASH) */
+
+/******************************************************************//**
+ * @}
+*********************************************************************/
diff --git a/bsp/efm32/dev_sflash.h b/bsp/efm32/dev_sflash.h
new file mode 100644
index 0000000000..1a10999331
--- /dev/null
+++ b/bsp/efm32/dev_sflash.h
@@ -0,0 +1,102 @@
+/******************************************************************//**
+ * @file dev_sflash.h
+ * @brief SPI Flash driver of RT-Thread RTOS for using EFM32 USART module
+ * This driver is tested by using the M25PX16 device on the EFM32 development kit.
+ * COPYRIGHT (C) 2011, RT-Thread Development Team
+ * @author onelife
+ * @version 0.4 beta
+ **********************************************************************
+ * @section License
+ * The license and distribution terms for this file may be found in the file LICENSE in this
+ * distribution or at http://www.rt-thread.org/license/LICENSE
+ **********************************************************************
+ * @section Change Logs
+ * Date Author Notes
+ * 2010-05-06 onelife Initial creation for using EFM32 USART module
+ *********************************************************************/
+#ifndef __DEV_SFLASH_H__
+#define __DEV_SFLASH_H__
+
+/* Includes -------------------------------------------------------------------*/
+/* Exported types -------------------------------------------------------------*/
+enum sflash_inst_type_t
+{
+ /* Instruction only */
+ sflash_inst_wren = 0x00,
+ sflash_inst_wrdi,
+ sflash_inst_rdid_l,
+ sflash_inst_rdid_s,
+ sflash_inst_rdsr,
+ sflash_inst_wrsr,
+ sflash_inst_be,
+ sflash_inst_dp,
+ sflash_inst_rdp,
+ /* Instruction and address */
+ sflash_inst_wrlr,
+ sflash_inst_rdlr,
+ sflash_inst_read,
+ sflash_inst_potp,
+ sflash_inst_pp,
+ sflash_inst_difp,
+ sflash_inst_sse,
+ sflash_inst_se,
+ /* Instruction, address and dummy read */
+ sflash_inst_read_f,
+ sflash_inst_dofr,
+ sflash_inst_rotp
+};
+
+/* Exported constants ---------------------------------------------------------*/
+/* Exported macro -------------------------------------------------------------*/
+#define SFLASH_INST_CODE_WREN (0x06)
+#define SFLASH_INST_CODE_WRDI (0x04)
+#define SFLASH_INST_CODE_RDID_L (0x9F)
+#define SFLASH_INST_CODE_RDID_S (0x9E)
+#define SFLASH_INST_CODE_RDSR (0x05)
+#define SFLASH_INST_CODE_WRSR (0x01)
+#define SFLASH_INST_CODE_WRLR (0xE5)
+#define SFLASH_INST_CODE_RDLR (0xE8)
+#define SFLASH_INST_CODE_READ (0x03)
+#define SFLASH_INST_CODE_READ_F (0x0B)
+#define SFLASH_INST_CODE_DOFR (0x3B)
+#define SFLASH_INST_CODE_ROTP (0x4B)
+#define SFLASH_INST_CODE_POTP (0x42)
+#define SFLASH_INST_CODE_PP (0x02)
+#define SFLASH_INST_CODE_DIFP (0xA2)
+#define SFLASH_INST_CODE_SSE (0x20)
+#define SFLASH_INST_CODE_SE (0xD8)
+#define SFLASH_INST_CODE_BE (0xC7)
+#define SFLASH_INST_CODE_DP (0xB9)
+#define SFLASH_INST_CODE_RDP (0xAB)
+
+#define SFLASH_REPLY_LEN_WREN (0)
+#define SFLASH_REPLY_LEN_WRDI (0)
+#define SFLASH_REPLY_LEN_RDID_L (20)
+#define SFLASH_REPLY_LEN_RDID_S (3)
+#define SFLASH_REPLY_LEN_RDSR (1)
+#define SFLASH_REPLY_LEN_WRSR (1)
+#define SFLASH_REPLY_LEN_WRLR (1)
+#define SFLASH_REPLY_LEN_RDLR (1)
+#define SFLASH_REPLY_LEN_READ (-1)
+#define SFLASH_REPLY_LEN_READ_F (-1)
+#define SFLASH_REPLY_LEN_DOFR (-1)
+#define SFLASH_REPLY_LEN_ROTP (65)
+#define SFLASH_REPLY_LEN_POTP (65)
+#define SFLASH_REPLY_LEN_PP (256)
+#define SFLASH_REPLY_LEN_DIFP (256)
+#define SFLASH_REPLY_LEN_SSE (0)
+#define SFLASH_REPLY_LEN_SE (0)
+#define SFLASH_REPLY_LEN_BE (0)
+#define SFLASH_REPLY_LEN_DP (0)
+#define SFLASH_REPLY_LEN_RDP (0)
+
+/* Exported functions --------------------------------------------------------- */
+rt_err_t efm_spiFash_init(void);
+rt_err_t efm_spiFash_deinit(void);
+rt_uint32_t efm_spiFash_cmd(
+ enum sflash_inst_type_t command,
+ rt_uint32_t address,
+ rt_uint8_t *buffer,
+ rt_uint32_t size);
+
+#endif /* __DEV_SFLASH_H__ */
diff --git a/bsp/efm32/drv_usart.c b/bsp/efm32/drv_usart.c
index 2119af6860..26997bf3dc 100644
--- a/bsp/efm32/drv_usart.c
+++ b/bsp/efm32/drv_usart.c
@@ -13,6 +13,7 @@
* Date Author Notes
* 2010-12-22 onelife Initial creation for EFM32
* 2011-01-17 onelife Merge with serial.c
+ * 2011-05-06 onelife Add sync mode (SPI) support
*
* @section Change Logs of serial.c
* 2009-02-05 Bernard first version
@@ -31,8 +32,20 @@
#include "drv_usart.h"
/* Private typedef -------------------------------------------------------------*/
+union efm32_usart_init_t
+{
+ USART_InitAsync_TypeDef async;
+ USART_InitSync_TypeDef sync;
+};
+
/* Private define --------------------------------------------------------------*/
/* Private macro --------------------------------------------------------------*/
+#ifdef RT_USART_DEBUG
+#define usart_debug(format,args...) rt_kprintf(format, ##args)
+#else
+#define usart_debug(format,args...)
+#endif
+
/* Private variables ------------------------------------------------------------*/
#ifdef RT_USING_USART0
#if (RT_USING_USART0 > 3)
@@ -128,64 +141,64 @@ static rt_err_t rt_usart_open(rt_device_t dev, rt_uint16_t oflag)
RT_ASSERT(dev != RT_NULL);
struct efm32_usart_device_t *usart;
- IRQn_Type rxIrq;
-
+
usart = (struct efm32_usart_device_t *)(dev->user_data);
-
- //if (usart->state & USART_STATE_CONSOLE)
- { /* Allocate new RX buffer */
- struct efm32_usart_int_mode_t *int_mode;
-
- int_mode = (struct efm32_usart_int_mode_t *)(usart->rx_mode);
-
- if ((int_mode->data_ptr = rt_malloc(SERIAL_RX_BUFFER_SIZE)) == RT_NULL)
- {
-#ifdef RT_USART_DEBUG
- rt_kprintf("no memory for serial RX buffer\n");
-#endif
- return -RT_ENOMEM;
- }
- rt_memset(int_mode->data_ptr, 0, SERIAL_RX_BUFFER_SIZE);
- int_mode->data_size = SERIAL_RX_BUFFER_SIZE;
- int_mode->read_index = 0;
- int_mode->save_index = 0;
- }
- /* Enable TX/RX interrupt */
- switch (usart->unit)
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
- case 0:
- rxIrq = USART0_RX_IRQn;
- break;
- case 1:
- rxIrq = USART1_RX_IRQn;
- break;
- case 2:
- rxIrq = USART2_RX_IRQn;
- break;
- }
+ IRQn_Type rxIrq;
+
+ //if (usart->state & USART_STATE_CONSOLE)
+ { /* Allocate new RX buffer */
+ struct efm32_usart_int_mode_t *int_mode;
+
+ int_mode = (struct efm32_usart_int_mode_t *)(usart->rx_mode);
- /* Enable RX interrupts */
- usart->usart_device->IEN = USART_IEN_RXDATAV;
+ if ((int_mode->data_ptr = rt_malloc(USART_RX_BUFFER_SIZE)) == RT_NULL)
+ {
+ usart_debug("USART: no memory for RX buffer\n");
+ return -RT_ENOMEM;
+ }
+ rt_memset(int_mode->data_ptr, 0, USART_RX_BUFFER_SIZE);
+ int_mode->data_size = USART_RX_BUFFER_SIZE;
+ int_mode->read_index = 0;
+ int_mode->save_index = 0;
+ }
+
+ /* Enable TX/RX interrupt */
+ switch (usart->unit)
+ {
+ case 0:
+ rxIrq = USART0_RX_IRQn;
+ break;
+ case 1:
+ rxIrq = USART1_RX_IRQn;
+ break;
+ case 2:
+ rxIrq = USART2_RX_IRQn;
+ break;
+ }
+
+ /* Enable RX interrupts */
+ usart->usart_device->IEN = USART_IEN_RXDATAV;
+
+ /* Enable IRQ */
+ if (oflag != RT_DEVICE_OFLAG_WRONLY)
+ {
+ NVIC_ClearPendingIRQ(rxIrq);
+ NVIC_SetPriority(rxIrq, EFM32_IRQ_PRI_DEFAULT);
+ NVIC_EnableIRQ(rxIrq);
+ }
+ }
usart->usart_device->IFC = _USART_IFC_MASK;
-
- /* Enable IRQ */
- if (oflag != RT_DEVICE_OFLAG_WRONLY)
- {
- NVIC_ClearPendingIRQ(rxIrq);
- NVIC_SetPriority(rxIrq, EFM32_IRQ_PRI_DEFAULT);
- NVIC_EnableIRQ(rxIrq);
- }
- if (oflag != RT_DEVICE_OFLAG_RDONLY)
+
+ if ((dev->flag & RT_DEVICE_FLAG_DMA_TX) && (oflag != RT_DEVICE_OFLAG_RDONLY))
{
/* DMA IRQ is enabled by DMA_Init() */
NVIC_SetPriority(DMA_IRQn, EFM32_IRQ_PRI_DEFAULT);
}
-#ifdef RT_USART_DEBUG
- rt_kprintf("USART%d: Open with flag %x\n", usart->unit, oflag);
-#endif
-
+ usart_debug("USART%d: Open with flag %x\n", usart->unit, oflag);
return RT_EOK;
}
@@ -205,14 +218,16 @@ static rt_err_t rt_usart_open(rt_device_t dev, rt_uint16_t oflag)
*********************************************************************/
static rt_err_t rt_usart_close(rt_device_t dev)
{
- struct efm32_usart_int_mode_t *int_rx;
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ struct efm32_usart_int_mode_t *int_rx;
- int_rx = (struct efm32_usart_int_mode_t *)\
- (((struct efm32_usart_device_t *)(dev->user_data))->rx_mode);
-
- rt_free(int_rx->data_ptr);
- int_rx->data_ptr = RT_NULL;
-
+ int_rx = (struct efm32_usart_int_mode_t *)\
+ (((struct efm32_usart_device_t *)(dev->user_data))->rx_mode);
+
+ rt_free(int_rx->data_ptr);
+ int_rx->data_ptr = RT_NULL;
+ }
return RT_EOK;
}
@@ -242,17 +257,19 @@ static rt_err_t rt_usart_close(rt_device_t dev)
static rt_size_t rt_usart_read (
rt_device_t dev,
rt_off_t pos,
- void* buffer,
+ void *buffer,
rt_size_t size)
{
- rt_uint8_t* ptr;
+ rt_uint8_t *ptr;
rt_err_t err_code;
+ rt_size_t read_len;
- ptr = buffer;
err_code = RT_EOK;
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
+ ptr = buffer;
+
/* interrupt mode Rx */
while (size)
{
@@ -273,7 +290,7 @@ static rt_size_t rt_usart_read (
/* move to next position */
int_rx->read_index ++;
- if (int_rx->read_index >= SERIAL_RX_BUFFER_SIZE)
+ if (int_rx->read_index >= USART_RX_BUFFER_SIZE)
{
int_rx->read_index = 0;
}
@@ -291,28 +308,77 @@ static rt_size_t rt_usart_read (
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
+
+ read_len = (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
else
{
- /* polling mode */
+ RT_ASSERT(buffer != RT_NULL);
+
+ struct efm32_usart_device_t *usart;
USART_TypeDef *usart_device;
- RT_ASSERT(buffer != RT_NULL);
+ usart = (struct efm32_usart_device_t *)(dev->user_data);
usart_device = ((struct efm32_usart_device_t *)(dev->user_data))->usart_device;
-
- while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
+
+ if (usart->state & USART_STATE_SYNC)
{
- while (usart_device->STATUS & USART_STATUS_RXDATAV)
+ /* SPI read */
+ rt_uint8_t inst_len = *((rt_uint8_t *)buffer);
+ rt_uint8_t *inst_ptr = (rt_uint8_t *)(buffer + 1);
+ rt_uint8_t *rx_buf = *((rt_uint8_t **)(buffer + inst_len + 1));
+
+ ptr = rx_buf;
+
+ /* write instruction */
+ while (inst_len)
{
+ while (!(usart->usart_device->STATUS & USART_STATUS_TXBL));
+ usart->usart_device->TXDATA = (rt_uint32_t)*inst_ptr;
+ ++inst_ptr; --inst_len;
+ }
+
+ /* Flushing RX */
+ usart_device->CMD = USART_CMD_CLEARRX;
+ /* dummy write */
+ while (!(usart_device->STATUS & USART_STATUS_TXBL));
+ usart_device->TXDATA = (rt_uint32_t)0x00;
+ /* dummy read */
+ while (!(usart_device->STATUS & USART_STATUS_RXDATAV));
+ *((rt_uint32_t *)0x00) = usart_device->RXDATA;
+
+ while ((rt_uint32_t)ptr - (rt_uint32_t)rx_buf < size)
+ {
+ /* dummy write */
+ while (!(usart_device->STATUS & USART_STATUS_TXBL));
+ usart_device->TXDATA = (rt_uint32_t)0x00;
+ /* read a byte of data */
+ while (!(usart_device->STATUS & USART_STATUS_RXDATAV));
*ptr = usart_device->RXDATA & 0xff;
ptr ++;
}
}
+ else
+ {
+ ptr = buffer;
+
+ /* polling mode */
+ while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
+ {
+ while (usart_device->STATUS & USART_STATUS_RXDATAV)
+ {
+ *ptr = usart_device->RXDATA & 0xff;
+ ptr ++;
+ }
+ }
+ }
+
+ read_len = size;
}
/* set error code */
rt_set_errno(err_code);
- return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+ return read_len;
}
/******************************************************************//**
@@ -336,7 +402,7 @@ static rt_size_t rt_usart_read (
* Buffer size in byte
*
* @return
- * Error code
+ * Number of written bytes
*********************************************************************/
static rt_size_t rt_usart_write (
rt_device_t dev,
@@ -352,7 +418,7 @@ static rt_size_t rt_usart_write (
write_size = 0;
usart = (struct efm32_usart_device_t*)(dev->user_data);
- if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
+ if ((dev->flag & RT_DEVICE_FLAG_DMA_TX) && (size > 1))
{ /* DMA mode Tx */
struct efm32_usart_dma_mode_t *dma_tx;
@@ -393,7 +459,7 @@ static rt_size_t rt_usart_write (
}
else
{ /* polling mode */
- rt_uint8_t* ptr = (rt_uint8_t*)buffer;
+ rt_uint8_t *ptr = (rt_uint8_t *)buffer;
if (dev->flag & RT_DEVICE_FLAG_STREAM)
{
@@ -408,7 +474,6 @@ static rt_size_t rt_usart_write (
while (!(usart->usart_device->STATUS & USART_STATUS_TXBL));
usart->usart_device->TXDATA = (rt_uint32_t)*ptr;
-
++ptr; --size;
}
}
@@ -419,7 +484,6 @@ static rt_size_t rt_usart_write (
{
while (!(usart->usart_device->STATUS & USART_STATUS_TXBL));
usart->usart_device->TXDATA = (rt_uint32_t)*ptr;
-
++ptr; --size;
}
}
@@ -500,9 +564,7 @@ static rt_err_t rt_usart_control (
if ((int_rx->data_ptr = rt_realloc(int_rx->data_ptr, size)) \
== RT_NULL)
{
-#ifdef RT_USART_DEBUG
- rt_kprintf("no memory for usart rx buffer\n");
-#endif
+ usart_debug("USART: no memory for RX buffer\n");
return -RT_ENOMEM;
}
// TODO: Is the following line necessary?
@@ -514,9 +576,7 @@ static rt_err_t rt_usart_control (
/* Allocate new RX buffer */
if ((int_rx->data_ptr = rt_malloc(size)) == RT_NULL)
{
-#ifdef RT_USART_DEBUG
- rt_kprintf("no memory for usart rx buffer\n");
-#endif
+ usart_debug("USART: no memory for RX buffer\n");
return -RT_ENOMEM;
}
}
@@ -570,14 +630,14 @@ void rt_hw_usart_rx_isr(rt_device_t dev)
int_rx->data_ptr[int_rx->save_index] = \
(rt_uint8_t)(usart->usart_device->RXDATA & 0xFFUL);
int_rx->save_index ++;
- if (int_rx->save_index >= SERIAL_RX_BUFFER_SIZE)
+ if (int_rx->save_index >= USART_RX_BUFFER_SIZE)
int_rx->save_index = 0;
/* if the next position is read index, discard this 'read char' */
if (int_rx->save_index == int_rx->read_index)
{
int_rx->read_index ++;
- if (int_rx->read_index >= SERIAL_RX_BUFFER_SIZE)
+ if (int_rx->read_index >= USART_RX_BUFFER_SIZE)
{
int_rx->read_index = 0;
}
@@ -594,7 +654,7 @@ void rt_hw_usart_rx_isr(rt_device_t dev)
/* get rx length */
rx_length = int_rx->read_index > int_rx->save_index ?
- SERIAL_RX_BUFFER_SIZE - int_rx->read_index + int_rx->save_index : \
+ USART_RX_BUFFER_SIZE - int_rx->read_index + int_rx->save_index : \
int_rx->save_index - int_rx->read_index;
dev->rx_indicate(dev, rx_length);
@@ -720,33 +780,24 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init(
rt_uint8_t location,
rt_uint32_t flag,
rt_uint32_t dmaChannel,
- rt_bool_t console)
+ rt_uint8_t config)
{
struct efm32_usart_device_t *usart;
struct efm32_usart_dma_mode_t *dma_mode;
CMU_Clock_TypeDef usartClock;
rt_uint32_t txDmaSelect;
- USART_InitAsync_TypeDef init;
+ union efm32_usart_init_t init;
efm32_irq_hook_init_t hook;
/* Allocate device */
usart = rt_malloc(sizeof(struct efm32_usart_device_t));
if (usart == RT_NULL)
{
-#ifdef RT_USART_DEBUG
- rt_kprintf("no memory for USART driver\n");
-#endif
+ usart_debug("USART: no memory for device\n");
return usart;
}
usart->unit = unitNumber;
- if (console == true)
- {
- usart->state = USART_STATE_CONSOLE;
- }
- else
- {
- usart->state = 0;
- }
+ usart->state = config;
usart->tx_mode = RT_NULL;
usart->rx_mode = RT_NULL;
@@ -757,9 +808,7 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init(
usart->tx_mode = dma_mode = rt_malloc(sizeof(struct efm32_usart_dma_mode_t));
if (dma_mode == RT_NULL)
{
-#ifdef RT_USART_DEBUG
- rt_kprintf("no memory for USART TX by DMA\n");
-#endif
+ usart_debug("USART: no memory for DMA TX\n");
rt_free(usart->rx_mode);
rt_free(usart);
usart = RT_NULL;
@@ -774,9 +823,7 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init(
usart->rx_mode = rt_malloc(sizeof(struct efm32_usart_int_mode_t));
if (usart->rx_mode == RT_NULL)
{
-#ifdef RT_USART_DEBUG
- rt_kprintf("no memory for USART RX by interrupt\n");
-#endif
+ usart_debug("USART: no memory for interrupt RX\n");
rt_free(usart->tx_mode);
rt_free(usart);
usart = RT_NULL;
@@ -823,6 +870,22 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init(
AF_PIN(AF_USART_RX(unitNumber), location),
gpioModeInputPull,
1);
+ if (config & USART_STATE_SYNC)
+ {
+ GPIO_PinModeSet(
+ (GPIO_Port_TypeDef)AF_PORT(AF_USART_CLK(unitNumber), location),
+ AF_PIN(AF_USART_CLK(unitNumber), location),
+ gpioModePushPull,
+ 0);
+ }
+ if (config & USART_STATE_AUTOCS)
+ {
+ GPIO_PinModeSet(
+ (GPIO_Port_TypeDef)AF_PORT(AF_USART_CS(unitNumber), location),
+ AF_PIN(AF_USART_CS(unitNumber), location),
+ gpioModePushPull,
+ 1);
+ }
/* Config interrupt and NVIC */
if (flag & RT_DEVICE_FLAG_INT_RX)
@@ -871,16 +934,49 @@ static struct efm32_usart_device_t *rt_hw_usart_unit_init(
/* Enable RX and TX pins and set location */
usart->usart_device->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | \
(location << _USART_ROUTE_LOCATION_SHIFT);
+ if (config & USART_STATE_SYNC)
+ {
+ usart->usart_device->ROUTE |= USART_ROUTE_CLKPEN;
+ }
+ if (config & USART_STATE_AUTOCS)
+ {
+ usart->usart_device->ROUTE |= USART_ROUTE_CSPEN;
+ if (config & USART_STATE_MASTER)
+ {
+ usart->usart_device->CTRL |= USART_CTRL_AUTOCS;
+ }
+ }
/* Init specified USART unit */
- init.enable = usartEnable;
- init.refFreq = 0;
- init.baudrate = UART_BAUDRATE;
- init.oversampling = USART_CTRL_OVS_X4;
- init.databits = USART_FRAME_DATABITS_EIGHT;
- init.parity = USART_FRAME_PARITY_NONE;
- init.stopbits = USART_FRAME_STOPBITS_ONE;
- USART_InitAsync(usart->usart_device, &init);
+ if (config & USART_STATE_SYNC)
+ {
+ init.sync.enable = usartEnable;
+ init.sync.refFreq = 0;
+ init.sync.baudrate = SPI_BAUDRATE;
+ init.sync.databits = usartDatabits8;
+ if (config & USART_STATE_MASTER)
+ {
+ init.sync.master = true;
+ }
+ else
+ {
+ init.sync.master = false;
+ }
+ init.sync.msbf = true;
+ init.sync.clockMode = usartClockMode0; /* Clock idle low, sample on rising edge. */
+ USART_InitSync(usart->usart_device, &init.sync);
+ }
+ else
+ {
+ init.async.enable = usartEnable;
+ init.async.refFreq = 0;
+ init.async.baudrate = UART_BAUDRATE;
+ init.async.oversampling = USART_CTRL_OVS_X4;
+ init.async.databits = USART_FRAME_DATABITS_EIGHT;
+ init.async.parity = USART_FRAME_PARITY_NONE;
+ init.async.stopbits = USART_FRAME_STOPBITS_ONE;
+ USART_InitAsync(usart->usart_device, &init.async);
+ }
/* Clear RX/TX buffers */
usart->usart_device->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
@@ -900,17 +996,31 @@ void rt_hw_usart_init(void)
{
struct efm32_usart_device_t *usart;
rt_uint32_t flag;
- rt_bool_t console;
+ rt_uint8_t config;
/* Register usart0 */
#ifdef RT_USING_USART0
+ config = 0x00;
flag = RT_DEVICE_FLAG_RDWR;
- #if (RT_CONSOLE_DEVICE == 0x0UL)
- console = true;
- flag |= RT_DEVICE_FLAG_STREAM;
+ #ifdef RT_USART0_SYNC_MODE
+ config |= USART_STATE_SYNC;
+ #if (RT_USART0_SYNC_MODE != 0x0UL)
+ config |= USART_STATE_MASTER;
+ #else
+ flag |= RT_DEVICE_FLAG_INT_RX;
+ #endif
#else
- console = false;
+ flag |= RT_DEVICE_FLAG_INT_RX;
+ #endif
+
+ #if (SPI_AUTOCS_ENABLE & (1 << 0))
+ config |= USART_STATE_AUTOCS;
+ #endif
+
+ #if (RT_CONSOLE_DEVICE == 0x0UL)
+ config |= USART_STATE_CONSOLE;
+ flag |= RT_DEVICE_FLAG_STREAM;
#endif
#ifdef RT_USART0_USING_DMA
@@ -920,28 +1030,40 @@ void rt_hw_usart_init(void)
#define RT_USART0_USING_DMA EFM32_NO_DATA
#endif
- flag |= RT_DEVICE_FLAG_INT_RX;
-
usart = rt_hw_usart_unit_init(
&usart0_device,
0,
RT_USING_USART0,
flag,
RT_USART0_USING_DMA,
- console);
+ config);
rt_hw_usart_register(&usart0_device, RT_USART0_NAME, flag, usart);
#endif
/* Register usart1 */
#ifdef RT_USING_USART1
+ config = 0x00;
flag = RT_DEVICE_FLAG_RDWR;
- #if (RT_CONSOLE_DEVICE == 0x1UL)
- console = true;
- flag |= RT_DEVICE_FLAG_STREAM;
+ #ifdef RT_USART1_SYNC_MODE
+ config |= USART_STATE_SYNC;
+ #if (RT_USART1_SYNC_MODE != 0x0UL)
+ config |= USART_STATE_MASTER;
+ #else
+ flag |= RT_DEVICE_FLAG_INT_RX;
+ #endif
#else
- console = false;
+ flag |= RT_DEVICE_FLAG_INT_RX;
+ #endif
+
+ #if (SPI_AUTOCS_ENABLE & (1 << 1))
+ config |= USART_STATE_AUTOCS;
+ #endif
+
+ #if (RT_CONSOLE_DEVICE == 0x1UL)
+ config |= USART_STATE_CONSOLE;
+ flag |= RT_DEVICE_FLAG_STREAM;
#endif
#ifdef RT_USART1_USING_DMA
@@ -951,8 +1073,6 @@ void rt_hw_usart_init(void)
#define RT_USART1_USING_DMA EFM32_NO_DATA
#endif
-
- flag |= RT_DEVICE_FLAG_INT_RX;
usart = rt_hw_usart_unit_init(
&usart1_device,
@@ -960,22 +1080,36 @@ void rt_hw_usart_init(void)
RT_USING_USART1,
flag,
RT_USART1_USING_DMA,
- console);
+ config);
rt_hw_usart_register(&usart1_device, RT_USART1_NAME, flag, usart);
#endif
/* Register usart2 */
#ifdef RT_USING_USART2
+ config = 0x00;
flag = RT_DEVICE_FLAG_RDWR;
- #if (RT_CONSOLE_DEVICE == 0x2UL)
- console = true;
- flag |= RT_DEVICE_FLAG_STREAM;
+ #ifdef RT_USART2_SYNC_MODE
+ config |= USART_STATE_SYNC;
+ #if (RT_USART2_SYNC_MODE != 0x0UL)
+ config |= USART_STATE_MASTER;
+ #else
+ flag |= RT_DEVICE_FLAG_INT_RX;
+ #endif
#else
- console = false;
+ flag |= RT_DEVICE_FLAG_INT_RX;
#endif
+#if (SPI_AUTOCS_ENABLE & (1 << 2))
+ config |= USART_STATE_AUTOCS;
+#endif
+
+#if (RT_CONSOLE_DEVICE == 0x2UL)
+ config |= USART_STATE_CONSOLE;
+ flag |= RT_DEVICE_FLAG_STREAM;
+#endif
+
#ifdef RT_USART2_USING_DMA
RT_ASSERT(RT_USART2_USING_DMA < DMA_CHAN_COUNT);
flag |= RT_DEVICE_FLAG_DMA_TX;
@@ -985,15 +1119,13 @@ void rt_hw_usart_init(void)
#define RT_USART2_USING_DMA EFM32_NO_DATA
#endif
- flag |= RT_DEVICE_FLAG_INT_RX;
-
usart = rt_hw_usart_unit_init(
&usart2_device,
2,
RT_USING_USART2,
flag,
RT_USART2_USING_DMA,
- console);
+ config);
rt_hw_usart_register(&usart2_device, RT_USART2_NAME, flag, usart);
#endif
diff --git a/bsp/efm32/drv_usart.h b/bsp/efm32/drv_usart.h
index 134b094c3c..e0e844b52c 100644
--- a/bsp/efm32/drv_usart.h
+++ b/bsp/efm32/drv_usart.h
@@ -54,8 +54,11 @@ struct efm32_usart_device_t
#define USART_WAIT_TIME_TX (RT_TICK_PER_SECOND / 100 * 3)
#define USART_STATE_CONSOLE (1 << 0)
-#define USART_STATE_TX_BUSY (1 << 1)
-#define USART_STATE_RX_BUSY (1 << 2)
+#define USART_STATE_SYNC (1 << 1)
+#define USART_STATE_MASTER (1 << 2)
+#define USART_STATE_AUTOCS (1 << 3)
+#define USART_STATE_TX_BUSY (1 << 4)
+#define USART_STATE_RX_BUSY (1 << 5)
/* Exported functions --------------------------------------------------------- */
diff --git a/bsp/efm32/hdl_interrupt.c b/bsp/efm32/hdl_interrupt.c
index ea8e388909..2b3894a283 100644
--- a/bsp/efm32/hdl_interrupt.c
+++ b/bsp/efm32/hdl_interrupt.c
@@ -563,7 +563,7 @@ void I2C0_IRQHandler(void)
* @note
*
*********************************************************************/
-rt_err_t efm32_irq_hook_register(efm32_irq_hook_init_t *hook)
+void efm32_irq_hook_register(efm32_irq_hook_init_t *hook)
{
switch (hook->type)
{
diff --git a/bsp/efm32/hdl_interrupt.h b/bsp/efm32/hdl_interrupt.h
index 13f33c947b..6003e8dd2d 100644
--- a/bsp/efm32/hdl_interrupt.h
+++ b/bsp/efm32/hdl_interrupt.h
@@ -55,7 +55,7 @@ typedef struct
//void SVC_Handler(void);
//void DebugMon_Handler(void);
void DMA_IRQHandler_All(unsigned int channel, bool primary, void *user);
-rt_err_t efm32_irq_hook_register(efm32_irq_hook_init_t *hook);
+void efm32_irq_hook_register(efm32_irq_hook_init_t *hook);
#endif /* __HDL_INTERRUPT_H__ */
diff --git a/bsp/efm32/rtconfig.h b/bsp/efm32/rtconfig.h
index d23f515c18..b24b25b9cb 100644
--- a/bsp/efm32/rtconfig.h
+++ b/bsp/efm32/rtconfig.h
@@ -39,7 +39,7 @@
//#define RT_ADC_DEBUG
//#define RT_ACMP_DEBUG
//#define RT_TIMER_DEBUG
-//#define RT_USART_DEBUG
+#define RT_USART_DEBUG
/* Using Hook */
//#define RT_USING_HOOK
@@ -82,15 +82,28 @@
/* USART Device for Console */
#if defined(EFM32_G290_DK)
-#define RT_USING_USART0 0x2UL
-#define RT_USART0_NAME "debug"
-#define RT_USART0_USING_DMA 0x0UL
+#define RT_USING_USART1 0x0UL
+#define RT_USART1_NAME "debug"
+#define RT_USART1_USING_DMA 0x0UL
#elif defined(EFM32_G890_STK)
#define RT_USING_USART1 0x1UL
#define RT_USART1_NAME "debug"
#define RT_USART1_USING_DMA 0x0UL
#endif
+/* SECTION: SPI options */
+#if defined(EFM32_G290_DK)
+#define RT_USING_USART0 0x2UL
+#define RT_USART0_SYNC_MODE 0x1UL /* Master */
+#define RT_USART0_NAME "spi0"
+#define RT_USART0_USING_DMA 0x1UL
+#elif defined(EFM32_G890_STK)
+//#define RT_USING_USART0 0x0UL
+//#define RT_USART0_SYNC_MODE 0x1UL /* Master */
+//#define RT_USART0_NAME "spi0"
+//#define RT_USART0_USING_DMA 0x1UL
+#endif
+
/* SECTION: RTC options */
#if (defined(EFM32_G290_DK) || defined(EFM32_G890_STK))
#define RT_USING_RTC
@@ -107,7 +120,7 @@
/* SECTION: Serial options */
#if defined(EFM32_G290_DK)
-#define RT_CONSOLE_DEVICE 0x0UL
+#define RT_CONSOLE_DEVICE 0x1UL
#elif defined(EFM32_G890_STK)
#define RT_CONSOLE_DEVICE 0x1UL
#endif
@@ -125,4 +138,4 @@
/* Exported functions --------------------------------------------------------- */
-#endif /* __RTTHREAD_CFG_H__ */
\ No newline at end of file
+#endif /* __RTTHREAD_CFG_H__ */
diff --git a/bsp/efm32/rtconfig.py b/bsp/efm32/rtconfig.py
index 61bc0ea801..c98e1d3b30 100644
--- a/bsp/efm32/rtconfig.py
+++ b/bsp/efm32/rtconfig.py
@@ -8,8 +8,8 @@ if CROSS_TOOL == 'gcc':
EXEC_PATH = 'C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin'
BUILD = 'debug'
-EFM32_BOARD = 'EFM32_G890_STK'
-# EFM32_BOARD = 'EFM32_G290_DK'
+# EFM32_BOARD = 'EFM32_G890_STK'
+EFM32_BOARD = 'EFM32_G290_DK'
if EFM32_BOARD == 'EFM32_G890_STK':
EFM32_TYPE = 'EFM32G890F128'