183 lines
4.3 KiB
C
183 lines
4.3 KiB
C
/*
|
|
* Copyright (c) 2019, RT-Thread Development Team
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Change Logs:
|
|
* Date Author Notes
|
|
* 2019-05-05 jg1uaa the first version
|
|
*/
|
|
|
|
#include <rtthread.h>
|
|
#include <rthw.h>
|
|
|
|
#include "board.h"
|
|
#include "drv_uart.h"
|
|
|
|
#define SYSCON_BASE 0x40048000
|
|
#define MEMMAP HWREG32(SYSCON_BASE + 0x000)
|
|
#define SYSPLLCTRL HWREG32(SYSCON_BASE + 0x008)
|
|
#define SYSPLLSTAT HWREG32(SYSCON_BASE + 0x00c)
|
|
#define SYSPLLCLKSEL HWREG32(SYSCON_BASE + 0x040)
|
|
#define SYSPLLCLKUEN HWREG32(SYSCON_BASE + 0x044)
|
|
#define MAINCLKSEL HWREG32(SYSCON_BASE + 0x070)
|
|
#define MAINCLKUEN HWREG32(SYSCON_BASE + 0x074)
|
|
#define AHBCLKCTRL HWREG32(SYSCON_BASE + 0x080)
|
|
#define PDRUNCFG HWREG32(SYSCON_BASE + 0x238)
|
|
|
|
#define SCB_BASE 0xe000e000
|
|
#define SYST_CSR HWREG32(SCB_BASE + 0x010)
|
|
#define SYST_RVR HWREG32(SCB_BASE + 0x014)
|
|
#define NVIC_ISER HWREG32(SCB_BASE + 0x100)
|
|
#define NVIC_ICER HWREG32(SCB_BASE + 0x180)
|
|
#define NVIC_ISPR HWREG32(SCB_BASE + 0x200)
|
|
#define NVIC_ICPR HWREG32(SCB_BASE + 0x280)
|
|
#define NVIC_IPR(irqno) HWREG32(SCB_BASE + 0x400 + (((irqno) / 4) << 2))
|
|
#define SCB_SHPR3 HWREG32(SCB_BASE + 0xd20)
|
|
|
|
extern unsigned char __bss_end__[];
|
|
extern unsigned char _ram_end[];
|
|
|
|
/**
|
|
* This is the timer interrupt service routine.
|
|
*/
|
|
void SysTick_Handler(void)
|
|
{
|
|
/* enter interrupt */
|
|
rt_interrupt_enter();
|
|
|
|
rt_tick_increase();
|
|
|
|
/* leave interrupt */
|
|
rt_interrupt_leave();
|
|
}
|
|
|
|
void os_clock_init(void)
|
|
{
|
|
/* bump up system clock 12MHz to 48MHz, using IRC (internal RC) osc. */
|
|
|
|
MAINCLKSEL = 0; // main clock: IRC @12MHz (default, for safety)
|
|
MAINCLKUEN = 0;
|
|
MAINCLKUEN = 1;
|
|
|
|
PDRUNCFG &= ~0x80; // power up System PLL
|
|
|
|
SYSPLLCLKSEL = 0; // PLL clock source: IRC osc
|
|
SYSPLLCLKUEN = 0;
|
|
SYSPLLCLKUEN = 1;
|
|
|
|
SYSPLLCTRL = 0x23; // Fcco = 2 x P x FCLKOUT
|
|
// 192MHz = 2 x 2 x 48MHz
|
|
// M = FCLKOUT / FCLKIN
|
|
// 4 = 48MHz / 12MHz
|
|
|
|
while (!(SYSPLLSTAT & 1)); // wait for lock PLL
|
|
|
|
MAINCLKSEL = 3; // main clock: system PLL
|
|
MAINCLKUEN = 0;
|
|
MAINCLKUEN = 1;
|
|
|
|
AHBCLKCTRL |= (1 << 16); // power up IOCON
|
|
}
|
|
|
|
void SysTick_init(void)
|
|
{
|
|
rt_uint32_t shpr3;
|
|
|
|
/* set SysTick interrupt priority */
|
|
shpr3 = SCB_SHPR3;
|
|
shpr3 &= ~0xff000000;
|
|
shpr3 |= 0x40 << 24;
|
|
SCB_SHPR3 = shpr3;
|
|
|
|
/* start SysTick */
|
|
SYST_CSR = 0x06; // Clock source:Core, SysTick Exception:enable
|
|
SYST_RVR = (CPU_CLOCK / RT_TICK_PER_SECOND) - 1;
|
|
SYST_CSR = 0x07; // Counter:enable
|
|
}
|
|
|
|
/**
|
|
* This function initializes LPC1114 SoC.
|
|
*/
|
|
void rt_hw_board_init(void)
|
|
{
|
|
os_clock_init();
|
|
|
|
/* init SysTick */
|
|
SysTick_init();
|
|
|
|
#ifdef RT_USING_HEAP
|
|
/* initialize system heap */
|
|
rt_system_heap_init((void *)&__bss_end__, (void *)&_ram_end);
|
|
#endif
|
|
/* initialize uart */
|
|
rt_hw_uart_init();
|
|
|
|
#ifdef RT_USING_CONSOLE
|
|
/* set console device */
|
|
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
|
#endif
|
|
|
|
#ifdef RT_USING_COMPONENTS_INIT
|
|
rt_components_board_init();
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* Enable External Interrupt
|
|
*/
|
|
void NVIC_EnableIRQ(rt_int32_t irqno)
|
|
{
|
|
NVIC_ISER = 1UL << (irqno & 0x1f);
|
|
}
|
|
|
|
/**
|
|
* Disable External Interrupt
|
|
*/
|
|
void NVIC_DisableIRQ(rt_int32_t irqno)
|
|
{
|
|
NVIC_ICER = 1UL << (irqno & 0x1f);
|
|
}
|
|
|
|
/**
|
|
* Get Pending Interrupt
|
|
* Different from CMSIS implementation,
|
|
* returns zero/non-zero, not zero/one.
|
|
*/
|
|
rt_uint32_t NVIC_GetPendingIRQ(rt_int32_t irqno)
|
|
{
|
|
return NVIC_ISPR & (1UL << (irqno & 0x1f));
|
|
}
|
|
|
|
/**
|
|
* Set Pending Interrupt
|
|
*/
|
|
void NVIC_SetPendingIRQ(rt_int32_t irqno)
|
|
{
|
|
NVIC_ISPR = 1UL << (irqno & 0x1f);
|
|
}
|
|
|
|
/**
|
|
* Clear Pending Interrupt
|
|
*/
|
|
void NVIC_ClearPendingIRQ(rt_int32_t irqno)
|
|
{
|
|
NVIC_ICPR = 1UL << (irqno & 0x1f);
|
|
}
|
|
|
|
/**
|
|
* Set Interrupt Priority
|
|
* Different from CMSIS implementation,
|
|
* this code supports only external (device specific) interrupt.
|
|
*/
|
|
void NVIC_SetPriority(rt_int32_t irqno, rt_uint32_t priority)
|
|
{
|
|
rt_uint32_t shift, ipr;
|
|
|
|
shift = (irqno % 4) * 8;
|
|
ipr = NVIC_IPR(irqno);
|
|
ipr &= ~(0xffUL << shift);
|
|
ipr |= (priority & 0xff) << shift;
|
|
NVIC_IPR(irqno) = ipr;
|
|
}
|