You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
410 lines
13 KiB
410 lines
13 KiB
5 months ago
|
/*
|
||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*
|
||
|
* 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
|
||
|
* 2011-07-12 onelife Add SWO output enable function
|
||
|
* 2011-12-08 onelife Add giant gecko development kit support
|
||
|
* 2011-12-09 onelife Add giant gecko support
|
||
|
* 2011-12-09 onelife Add LEUART module support
|
||
|
* 2011-12-14 onelife Add LFXO enabling routine in driver initialization function
|
||
|
* 2011-12-15 onelife Add MicroSD initialization routine in driver
|
||
|
* initialization function
|
||
|
* 2011-12-29 onelife Add keys and joystick initialization routine in
|
||
|
* driver initialization function
|
||
|
* 2012-02-15 onelife Modify SWO setup function to support giant gecko
|
||
|
* 2012-xx-xx onelife Modify system clock and ticket related code
|
||
|
*/
|
||
|
|
||
|
/***************************************************************************//**
|
||
|
* @addtogroup efm32
|
||
|
* @{
|
||
|
******************************************************************************/
|
||
|
|
||
|
/* Includes ------------------------------------------------------------------*/
|
||
|
#include "board.h"
|
||
|
|
||
|
/* Private typedef -----------------------------------------------------------*/
|
||
|
/* Private define ------------------------------------------------------------*/
|
||
|
#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == RAM_MEM_BASE) || \
|
||
|
((VECTTAB) == FLASH_MEM_BASE))
|
||
|
#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF)
|
||
|
|
||
|
/***************************************************************************//**
|
||
|
* @addtogroup SysTick_clock_source
|
||
|
* @{
|
||
|
******************************************************************************/
|
||
|
#define SysTick_CLKSource_MASK ((rt_uint32_t)0x00000004)
|
||
|
#define SysTick_CLKSource_RTC ((rt_uint32_t)0x00000000)
|
||
|
#define SysTick_CLKSource_HFCORECLK ((rt_uint32_t)0x00000004)
|
||
|
#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_RTC) || \
|
||
|
((SOURCE) == SysTick_CLKSource_HFCORECLK))
|
||
|
/***************************************************************************//**
|
||
|
* @}
|
||
|
******************************************************************************/
|
||
|
|
||
|
/* Private macro -------------------------------------------------------------*/
|
||
|
/* Private variables ---------------------------------------------------------*/
|
||
|
/* Private function prototypes -----------------------------------------------*/
|
||
|
/* Private functions ---------------------------------------------------------*/
|
||
|
/***************************************************************************//**
|
||
|
* @brief
|
||
|
* Set the allocation and offset of the vector table
|
||
|
*
|
||
|
* @details
|
||
|
*
|
||
|
* @note
|
||
|
*
|
||
|
* @param[in] NVIC_VectTab
|
||
|
* Indicate the vector table is allocated in RAM or ROM
|
||
|
*
|
||
|
* @param[in] Offset
|
||
|
* The vector table offset
|
||
|
******************************************************************************/
|
||
|
static void NVIC_SetVectorTable(
|
||
|
rt_uint32_t NVIC_VectTab,
|
||
|
rt_uint32_t Offset)
|
||
|
{
|
||
|
/* Check the parameters */
|
||
|
RT_ASSERT(IS_NVIC_VECTTAB(NVIC_VectTab));
|
||
|
RT_ASSERT(IS_NVIC_OFFSET(Offset));
|
||
|
|
||
|
SCB->VTOR = NVIC_VectTab | (Offset & (rt_uint32_t)0x1FFFFF80);
|
||
|
}
|
||
|
|
||
|
/***************************************************************************//**
|
||
|
* @brief
|
||
|
* Configure the address of vector table
|
||
|
*
|
||
|
* @details
|
||
|
*
|
||
|
* @note
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
static void NVIC_Configuration(void)
|
||
|
{
|
||
|
#ifdef VECT_TAB_RAM
|
||
|
/* Set the vector table allocated at 0x20000000 */
|
||
|
NVIC_SetVectorTable(RAM_MEM_BASE, 0x0);
|
||
|
#else /* VECT_TAB_FLASH */
|
||
|
/* Set the vector table allocated at 0x00000000 */
|
||
|
NVIC_SetVectorTable(FLASH_MEM_BASE, 0x0);
|
||
|
#endif
|
||
|
|
||
|
/* Set NVIC Preemption Priority Bits: 0 bit for pre-emption, 4 bits for
|
||
|
subpriority */
|
||
|
NVIC_SetPriorityGrouping(0x7UL);
|
||
|
|
||
|
/* Set Base Priority Mask Register */
|
||
|
__set_BASEPRI(EFM32_BASE_PRI_DEFAULT);
|
||
|
}
|
||
|
|
||
|
/***************************************************************************//**
|
||
|
* @brief
|
||
|
* Configure the SysTick clock source
|
||
|
*
|
||
|
* @details
|
||
|
*
|
||
|
* @note
|
||
|
*
|
||
|
* @param[in] SysTick_CLKSource
|
||
|
* Specifies the SysTick clock source.
|
||
|
*
|
||
|
* @arg SysTick_CLKSource_HCLK_Div8
|
||
|
* AHB clock divided by 8 selected as SysTick clock source.
|
||
|
*
|
||
|
* @arg SysTick_CLKSource_HCLK
|
||
|
* AHB clock selected as SysTick clock source.
|
||
|
******************************************************************************/
|
||
|
static void SysTick_CLKSourceConfig(rt_uint32_t SysTick_CLKSource)
|
||
|
{
|
||
|
/* Check the parameters */
|
||
|
RT_ASSERT(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
|
||
|
|
||
|
rt_uint32_t ctrl = SysTick->CTRL;
|
||
|
|
||
|
ctrl &= ~SysTick_CLKSource_MASK;
|
||
|
ctrl |= SysTick_CLKSource;
|
||
|
|
||
|
SysTick->CTRL = ctrl;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************//**
|
||
|
* @brief
|
||
|
* Configure the SysTick for OS tick.
|
||
|
*
|
||
|
* @details
|
||
|
*
|
||
|
* @note
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
static void SysTick_Configuration(void)
|
||
|
{
|
||
|
#if defined(EFM32_USING_LFXO)
|
||
|
/* LETIMER0 configurations */
|
||
|
const LETIMER_Init_TypeDef letimerInit =
|
||
|
{
|
||
|
.enable = true, /* Start counting when init completed. */
|
||
|
.debugRun = false, /* Counter shall not keep running during debug halt. */
|
||
|
.rtcComp0Enable = false, /* Don't start counting on RTC COMP0 match. */
|
||
|
.rtcComp1Enable = false, /* Don't start counting on RTC COMP1 match. */
|
||
|
.comp0Top = true, /* Load COMP0 register into CNT when counter underflows. COMP is used as TOP */
|
||
|
.bufTop = false, /* Don't load COMP1 into COMP0 when REP0 reaches 0. */
|
||
|
.out0Pol = 0, /* Idle value for output 0. */
|
||
|
.out1Pol = 0, /* Idle value for output 1. */
|
||
|
.ufoa0 = letimerUFOANone, /* No output on output 0. */
|
||
|
.ufoa1 = letimerUFOANone, /* No output on output 1. */
|
||
|
.repMode = letimerRepeatFree /* Count until stopped by SW. */
|
||
|
};
|
||
|
|
||
|
CMU_ClockDivSet(cmuClock_LETIMER0, cmuClkDiv_8);
|
||
|
CMU_ClockEnable(cmuClock_LETIMER0, true);
|
||
|
LETIMER_CompareSet(LETIMER0, 0,
|
||
|
EFM32_LETIMER_TOP_100HZ * RT_TICK_PER_SECOND / 100);
|
||
|
|
||
|
/* Enable underflow interrupt */
|
||
|
LETIMER_IntClear(LETIMER0, LETIMER_IF_UF);
|
||
|
LETIMER_IntEnable(LETIMER0, LETIMER_IF_UF);
|
||
|
/* Enable LETIMER0 interrupt vector in NVIC */
|
||
|
NVIC_ClearPendingIRQ(LETIMER0_IRQn);
|
||
|
NVIC_SetPriority(LETIMER0_IRQn, EFM32_IRQ_PRI_DEFAULT);
|
||
|
NVIC_EnableIRQ(LETIMER0_IRQn);
|
||
|
|
||
|
/* Start LETIMER0 */
|
||
|
LETIMER_Init(LETIMER0, &letimerInit);
|
||
|
#else
|
||
|
rt_uint32_t coreClk;
|
||
|
rt_uint32_t cnts;
|
||
|
|
||
|
coreClk = SystemCoreClockGet();
|
||
|
cnts = coreClk / RT_TICK_PER_SECOND;
|
||
|
|
||
|
SysTick_Config(cnts);
|
||
|
SysTick_CLKSourceConfig(SysTick_CLKSource_HFCORECLK);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/***************************************************************************//**
|
||
|
* @brief
|
||
|
* Enable SWO.
|
||
|
*
|
||
|
* @details
|
||
|
*
|
||
|
* @note
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
void Swo_Configuration(void)
|
||
|
{
|
||
|
rt_uint32_t *dwt_ctrl = (rt_uint32_t *) 0xE0001000;
|
||
|
rt_uint32_t *tpiu_prescaler = (rt_uint32_t *) 0xE0040010;
|
||
|
rt_uint32_t *tpiu_protocol = (rt_uint32_t *) 0xE00400F0;
|
||
|
|
||
|
CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
|
||
|
/* Enable Serial wire output pin */
|
||
|
GPIO->ROUTE |= GPIO_ROUTE_SWOPEN;
|
||
|
#if defined(_EFM32_GIANT_FAMILY)
|
||
|
/* Set location 0 */
|
||
|
GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC0;
|
||
|
|
||
|
/* Enable output on pin - GPIO Port F, Pin 2 */
|
||
|
GPIO->P[5].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK);
|
||
|
GPIO->P[5].MODEL |= GPIO_P_MODEL_MODE2_PUSHPULL;
|
||
|
#else
|
||
|
/* Set location 1 */
|
||
|
GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC1;
|
||
|
/* Enable output on pin */
|
||
|
GPIO->P[2].MODEH &= ~(_GPIO_P_MODEH_MODE15_MASK);
|
||
|
GPIO->P[2].MODEH |= GPIO_P_MODEH_MODE15_PUSHPULL;
|
||
|
#endif
|
||
|
/* Enable debug clock AUXHFRCO */
|
||
|
CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
|
||
|
|
||
|
while(!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY));
|
||
|
|
||
|
/* Enable trace in core debug */
|
||
|
CoreDebug->DHCSR |= 1;
|
||
|
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||
|
|
||
|
/* Enable PC and IRQ sampling output */
|
||
|
*dwt_ctrl = 0x400113FF;
|
||
|
/* Set TPIU prescaler to 16. */
|
||
|
*tpiu_prescaler = 0xf;
|
||
|
/* Set protocol to NRZ */
|
||
|
*tpiu_protocol = 2;
|
||
|
/* Unlock ITM and output data */
|
||
|
ITM->LAR = 0xC5ACCE55;
|
||
|
ITM->TCR = 0x10009;
|
||
|
}
|
||
|
|
||
|
/***************************************************************************//**
|
||
|
* @brief
|
||
|
* Initialize the board.
|
||
|
*
|
||
|
* @details
|
||
|
*
|
||
|
* @note
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
void rt_hw_board_init(void)
|
||
|
{
|
||
|
/* Chip errata */
|
||
|
CHIP_Init();
|
||
|
|
||
|
/* Initialize DVK board register access */
|
||
|
#if defined(EFM32_GXXX_DK)
|
||
|
DVK_init();
|
||
|
#elif defined(EFM32GG_DK3750)
|
||
|
DVK_init(DVK_Init_EBI);
|
||
|
|
||
|
/* Disable all DVK interrupts */
|
||
|
DVK_disableInterrupt(BC_INTEN_MASK);
|
||
|
DVK_clearInterruptFlags(BC_INTFLAG_MASK);
|
||
|
#endif
|
||
|
|
||
|
/* config NVIC Configuration */
|
||
|
NVIC_Configuration();
|
||
|
|
||
|
#if defined(EFM32_USING_HFXO)
|
||
|
/* Configure external oscillator */
|
||
|
SystemHFXOClockSet(EFM32_HFXO_FREQUENCY);
|
||
|
|
||
|
/* Switching the CPU clock source to HFXO */
|
||
|
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
|
||
|
|
||
|
/* Turning off the high frequency RC Oscillator (HFRCO) */
|
||
|
CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);
|
||
|
#endif
|
||
|
|
||
|
#if defined(EFM32_USING_LFXO)
|
||
|
CMU_ClockSelectSet(cmuClock_LFA,cmuSelect_LFXO);
|
||
|
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
|
||
|
#endif
|
||
|
|
||
|
#if defined(EFM32_SWO_ENABLE)
|
||
|
/* Enable SWO */
|
||
|
Swo_Configuration();
|
||
|
#endif
|
||
|
|
||
|
/* Enable high frequency peripheral clock */
|
||
|
CMU_ClockEnable(cmuClock_HFPER, true);
|
||
|
/* Enabling clock to the interface of the low energy modules */
|
||
|
CMU_ClockEnable(cmuClock_CORELE, true);
|
||
|
/* Enable GPIO clock */
|
||
|
CMU_ClockEnable(cmuClock_GPIO, true);
|
||
|
|
||
|
/* Configure the SysTick */
|
||
|
SysTick_Configuration();
|
||
|
}
|
||
|
|
||
|
/***************************************************************************//**
|
||
|
* @brief
|
||
|
* Initialize the hardware drivers.
|
||
|
*
|
||
|
* @details
|
||
|
*
|
||
|
* @note
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
void rt_hw_driver_init(void)
|
||
|
{
|
||
|
/* Initialize DMA */
|
||
|
rt_hw_dma_init();
|
||
|
|
||
|
/* Select LFXO for specified module (and wait for it to stabilize) */
|
||
|
#if (!defined(EFM32_USING_LFXO) && defined(RT_USING_RTC))
|
||
|
#error "Low frequency clock source is needed for using RTC"
|
||
|
#endif
|
||
|
|
||
|
#if (!defined(EFM32_USING_LFXO )&& \
|
||
|
(defined(RT_USING_LEUART0) || defined(RT_USING_LEUART1)))
|
||
|
#error "Low frequency clock source is needed for using LEUART"
|
||
|
#endif
|
||
|
|
||
|
/* Initialize USART */
|
||
|
#if (defined(RT_USING_USART0) || defined(RT_USING_USART1) || \
|
||
|
defined(RT_USING_USART2) || defined(RT_USING_UART0) || \
|
||
|
defined(RT_USING_UART1))
|
||
|
rt_hw_usart_init();
|
||
|
#endif
|
||
|
|
||
|
/* Initialize LEUART */
|
||
|
#if (defined(RT_USING_LEUART0) || defined(RT_USING_LEUART1))
|
||
|
rt_hw_leuart_init();
|
||
|
#endif
|
||
|
|
||
|
/* Setup Console */
|
||
|
#if defined(EFM32_GXXX_DK)
|
||
|
DVK_enablePeripheral(DVK_RS232A);
|
||
|
DVK_enablePeripheral(DVK_SPI);
|
||
|
#elif defined(EFM32GG_DK3750)
|
||
|
#if (RT_CONSOLE_DEVICE == EFM_UART1)
|
||
|
DVK_enablePeripheral(DVK_RS232_UART);
|
||
|
#elif (RT_CONSOLE_DEVICE == EFM_LEUART1)
|
||
|
DVK_enablePeripheral(DVK_RS232_LEUART);
|
||
|
#endif
|
||
|
#endif
|
||
|
rt_console_set_device(CONSOLE_DEVICE);
|
||
|
|
||
|
/* Initialize Timer */
|
||
|
#if (defined(RT_USING_TIMER0) || defined(RT_USING_TIMER1) || defined(RT_USING_TIMER2))
|
||
|
rt_hw_timer_init();
|
||
|
#endif
|
||
|
|
||
|
/* Initialize ADC */
|
||
|
#if defined(RT_USING_ADC0)
|
||
|
rt_hw_adc_init();
|
||
|
#endif
|
||
|
|
||
|
/* Initialize ACMP */
|
||
|
#if (defined(RT_USING_ACMP0) || defined(RT_USING_ACMP1))
|
||
|
rt_hw_acmp_init();
|
||
|
#endif
|
||
|
|
||
|
/* Initialize IIC */
|
||
|
#if (defined(RT_USING_IIC0) || defined(RT_USING_IIC1))
|
||
|
rt_hw_iic_init();
|
||
|
#endif
|
||
|
|
||
|
/* Initialize RTC */
|
||
|
#if defined(RT_USING_RTC)
|
||
|
rt_hw_rtc_init();
|
||
|
#endif
|
||
|
|
||
|
/* Enable SPI access to MicroSD card */
|
||
|
#if defined(EFM32_USING_SPISD)
|
||
|
#if defined(EFM32_GXXX_DK)
|
||
|
DVK_writeRegister(BC_SPI_CFG, 1);
|
||
|
#elif defined(EFM32GG_DK3750)
|
||
|
DVK_enablePeripheral(DVK_MICROSD);
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
/* Enable SPI access to Ethernet */
|
||
|
#if defined(EFM32_USING_ETHERNET)
|
||
|
#if defined(EFM32GG_DK3750)
|
||
|
DVK_enablePeripheral(DVK_ETH);
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
/* Initialize LCD */
|
||
|
#if defined(EFM32_USING_LCD)
|
||
|
efm32_spiLcd_init();
|
||
|
#endif
|
||
|
|
||
|
/* Initialize Keys */
|
||
|
#if defined(EFM32_USING_KEYS)
|
||
|
#if defined(EFM32GG_DK3750)
|
||
|
efm32_hw_keys_init();
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
/***************************************************************************//**
|
||
|
* @}
|
||
|
******************************************************************************/
|