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.
253 lines
5.4 KiB
253 lines
5.4 KiB
/*
|
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Change Logs:
|
|
* Date Author Notes
|
|
* 2012-02-13 mojingxian first version
|
|
*/
|
|
|
|
#include "board.h"
|
|
#include "rtconfig.h"
|
|
#include "rtdef.h"
|
|
#include "rthw.h"
|
|
#include "serial.h"
|
|
|
|
#include <signal.h>
|
|
#include <sys/platform.h>
|
|
#include <ccblkfn.h>
|
|
#include <sysreg.h>
|
|
#include <string.h>
|
|
#include <sys\exception.h>
|
|
#include <stdio.h>
|
|
|
|
#define IVG_CLR(index) (index > 0 ? ((0xFFFFFFF0 << (index * 0x04)) | \
|
|
(0xFFFFFFF0 >> ((0x08 - index) * 0x04))):0xFFFFFFF0)
|
|
#define IVG_SET(index,ivg) ((((ivg) - 0x07) & 0x0F) << (index * 0x04))
|
|
|
|
#define UART0 ((struct uartport *)pUART_THR)
|
|
struct serial_int_rx uart0_int_rx;
|
|
struct serial_device uart0 =
|
|
{
|
|
UART0,
|
|
&uart0_int_rx,
|
|
RT_NULL
|
|
};
|
|
struct rt_device uart0_device;
|
|
|
|
/**
|
|
* This function is to set the EBIU(EXTERNAL BUS INTERFACE UNIT).
|
|
*/
|
|
static void rt_hw_ebiu_init(void)
|
|
{
|
|
*pEBIU_AMBCTL0 = 0xffc2ffc2;
|
|
|
|
*pEBIU_AMBCTL1 = 0xffc2ffc3;
|
|
|
|
*pEBIU_AMGCTL = 0x010f;
|
|
}
|
|
|
|
/**
|
|
* This is the timer interrupt service routine.
|
|
*/
|
|
EX_INTERRUPT_HANDLER(rt_hw_timer_handler)
|
|
{
|
|
/* enter interrupt */
|
|
rt_interrupt_enter();
|
|
|
|
rt_tick_increase();
|
|
|
|
/* leave interrupt */
|
|
rt_interrupt_leave();
|
|
}
|
|
|
|
/**
|
|
* This function is called to initialize system tick source (typically a
|
|
* timer generating interrupts every 1 to 100 mS).
|
|
* We decided to use Core Timer as the tick interrupt source.
|
|
*/
|
|
void rt_hw_core_timer_init(void)
|
|
{
|
|
*pTCNTL = 1; // Turn on timer, TMPWR
|
|
*pTSCALE = 0x00;
|
|
*pTCOUNT = CCLKSPEED / RT_TICK_PER_SECOND;
|
|
*pTPERIOD = CCLKSPEED / RT_TICK_PER_SECOND;
|
|
register_handler(ik_timer,rt_hw_timer_handler);
|
|
*pTCNTL = 0x07; // Start Timer and set Auto-reload
|
|
}
|
|
|
|
void rt_hw_interrupt_init(void)
|
|
{
|
|
extern rt_uint32_t rt_interrupt_from_thread;
|
|
extern rt_uint32_t rt_interrupt_to_thread;
|
|
extern rt_uint32_t rt_thread_switch_interrupt_flag;
|
|
extern rt_uint8_t rt_interrupt_nest;
|
|
extern void interrupt_thread_switch(void);
|
|
|
|
register_handler(ik_ivg14,interrupt_thread_switch); //context_vdsp.S
|
|
|
|
/* init interrupt nest, and context in thread sp */
|
|
rt_interrupt_nest = 0;
|
|
rt_interrupt_from_thread = 0;
|
|
rt_interrupt_to_thread = 0;
|
|
rt_thread_switch_interrupt_flag = 0;
|
|
}
|
|
|
|
static void rt_hw_pll_init(void)
|
|
{
|
|
unsigned long imask;
|
|
|
|
sysreg_write(reg_SYSCFG, 0x32);
|
|
|
|
*pSIC_IWR = 0x01;
|
|
|
|
*pPLL_CTL = SET_MSEL(SPEED_MULTIPLE);
|
|
|
|
// PLL Re-programming Sequence.
|
|
// Core is idle'ed to allow the PPL to re-lock.
|
|
imask = cli();
|
|
idle();
|
|
sti(imask);
|
|
*pVR_CTL = 0x00FB;
|
|
|
|
// PLL Re-programming Sequence.
|
|
// Core is idle'ed to allow the PPL to re-lock.
|
|
imask = cli();
|
|
idle();
|
|
sti(imask);
|
|
|
|
*pPLL_DIV = BUS_DIVISOR;
|
|
}
|
|
|
|
/**
|
|
* This function is called to initialize external sdram.
|
|
*/
|
|
static void rt_hw_exdram_init(void)
|
|
{
|
|
// Initalize EBIU control registers to enable all banks
|
|
*pEBIU_AMBCTL1 = 0xFFFFFF02;
|
|
ssync();
|
|
|
|
*pEBIU_AMGCTL = 0x00FF;
|
|
ssync();
|
|
|
|
// Check if already enabled
|
|
if (SDRS != ((*pEBIU_SDSTAT) & SDRS))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//SDRAM Refresh Rate Control Register
|
|
*pEBIU_SDRRC = 0x01A0;
|
|
|
|
//SDRAM Memory Bank Control Register
|
|
*pEBIU_SDBCTL = 0x0025; //1.7 64 MB
|
|
|
|
//SDRAM Memory Global Control Register
|
|
*pEBIU_SDGCTL = 0x0091998D;//0x998D0491
|
|
|
|
ssync();
|
|
}
|
|
|
|
short uart_set_bitrate(unsigned long bit_rate)
|
|
{
|
|
unsigned short int divisor;
|
|
|
|
switch (bit_rate)
|
|
{
|
|
case 1200:
|
|
case 2400:
|
|
case 4800:
|
|
case 9600:
|
|
case 19200:
|
|
case 28800:
|
|
case 38400:
|
|
case 57600:
|
|
case 115200:
|
|
case 125000:
|
|
divisor = (unsigned short int) ((float) SCLKSPEED / ((float) bit_rate * 16.0f) + 0.5f);
|
|
|
|
*(pUART_LCR) |= DLAB; // Enable access to DLL and DLH registers
|
|
*(pUART_DLL) = divisor & 0xFF;
|
|
*(pUART_DLH) = divisor >> 8;
|
|
*(pUART_LCR) &= ~DLAB; // clear DLAB bit
|
|
|
|
break;
|
|
|
|
default: // baud rate not supported
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void rt_hw_uart_init(void)
|
|
{
|
|
// Apply UART configuration 8 bit data, No parity, 1 stop bit
|
|
*pUART_LCR = 0x0000; // Reset value
|
|
*pUART_LCR = WLS(8);
|
|
|
|
// Ensure that Loopback mode is disabled by clearing LOOP_ENA bit
|
|
*pUART_MCR = 0x0000; //Reset value
|
|
|
|
uart_set_bitrate(19200);// Set communication baudrate 115200
|
|
|
|
*pUART_IER = ERBFI;
|
|
|
|
// Enable UART clock
|
|
*pUART_GCTL = UCEN;
|
|
}
|
|
|
|
int uart_put_char(const char c)
|
|
{
|
|
while (!(*pUART_LSR & THRE))
|
|
{
|
|
/* wait */
|
|
}
|
|
|
|
*pUART_THR = c;
|
|
|
|
return c;
|
|
}
|
|
|
|
void rt_hw_console_output(const char *str)
|
|
{
|
|
while (*str != '\0')
|
|
{
|
|
if (*str == '\n')
|
|
uart_put_char('\r');
|
|
uart_put_char(*str++);
|
|
}
|
|
}
|
|
|
|
EX_INTERRUPT_HANDLER(uart_rx_isr)
|
|
{
|
|
rt_interrupt_enter();
|
|
|
|
rt_hw_serial_isr(&uart0_device);
|
|
|
|
rt_interrupt_leave();
|
|
}
|
|
|
|
void rt_hw_isr_install(void)
|
|
{
|
|
*pSIC_IWR = 0xFFFFFFFF;
|
|
*pSIC_IMASK = 0x00000000;
|
|
|
|
*pSIC_IAR1 &= IVG_CLR(IAR1_DMA6_UARTRX_IVG);
|
|
*pSIC_IAR1 |= IVG_SET(IAR1_DMA6_UARTRX_IVG,ik_ivg9);
|
|
register_handler(ik_ivg9,uart_rx_isr);
|
|
*pSIC_IMASK |= DMA6_UART_RX_INT_MASK;/* 开中断 */
|
|
}
|
|
|
|
void rt_hw_board_init(void)
|
|
{
|
|
rt_hw_pll_init();
|
|
|
|
rt_hw_ebiu_init();
|
|
|
|
rt_hw_exdram_init();
|
|
|
|
rt_hw_uart_init();
|
|
}
|
|
|