📄 serial.c
字号:
/***************************************************************************
;
; 2002 Altera Corporation. All rights reserved. Altera products are protected
; under numerous U.S. and foreign patents, maskwork rights, copyrights and other
; intellectual property laws. This reference design file, and your use thereof,
; is subject to and governed by the terms and conditions of the applicable
; Altera Reference Design License Agreement (found at www.altera.com). By using
; this reference design file, you indicate your acceptance of such terms and
; conditions between you and Altera Corporation. In the event that you do not
; agree with such terms and conditions, you may not use the reference design file
; and please promptly destroy any copies you have made. This reference design
; file being provided on an "as-is" basis and as an accommodation and therefore
; all warranties, representations or guarantees of any kind (whether express,
; implied or statutory) including, without limitation, warranties of
; merchantability, non-infringement, or fitness for a particular purpose, are
; specifically disclaimed. By making this reference design file available, Altera
; expressly does not recommend, suggest or require that this reference design file
; be used in combination with any other product not provided by Altera.
;
;***************************************************************************
;
; Filename: serial.c
; Uart initialization routines for both the hard uart and a soft uart. Timer
; routines are also found here
;
;
;***************************************************************************/
#include "stripe.h"
#include "serial.h"
#include "adam.h"
void init_serial_A(int baud)
{
#ifdef SERIAL
*(volatile unsigned long *)(EXC_UART_FCR) = 0xfc; // 15 byte threshold
*(volatile unsigned long *)(EXC_UART_MC) = 0x03; // no parity, 1 stop bits, 8data bits
*(volatile unsigned long *)(EXC_UART_DIV_LO) = EXC_AHB2_CLK_FREQUENCY / (baud * 16);
*(volatile unsigned long *)(EXC_UART_DIV_HI) = 0x00;
#endif
}
void sendchar(char *ch)
{
char chr1 = 0x0d;
#ifdef SERIAL
if (*ch == 0x0a) sendchar(&chr1);
while ( ((*(volatile unsigned long *)(EXC_UART_TSR)) & 0x1f) > 0x0 );
*(volatile unsigned long *)(EXC_UART_TD) = (unsigned long)*ch;
#endif
}
char receivechar(void)
{
unsigned long ch = 0x45; // dummy 'E'
#ifdef SERIAL
// wait for rxfifo not empty
while ( ((*(volatile unsigned long *)(EXC_UART_RSR)) & 0x1f) == 0 );
ch = *(volatile unsigned long *)(EXC_UART_RD);
#endif
return (char)ch;
}
int kbhit(void)
{
#ifdef SERIAL
if ( ((*(volatile unsigned long *)(EXC_UART_RSR)) & 0x1f) == 0 )
return 0;
else
return 1;
#else
return 0;
#endif
}
void flushall(void)
{
#ifdef SERIAL
unsigned long ch = 0x45;
// wait for rxfifo not empty
while ( ((*(volatile unsigned long *)(EXC_UART_RSR)) & 0x1f) > 0 )
ch = *(volatile unsigned long *)(EXC_UART_RD);
#endif
}
//-------------------------------------------------------------------------
void init_serial_B(int baud)
{
#ifdef SOFT_UART
*(volatile unsigned long *)(SOFT_UART_FCR) = 0xfc; // 15 byte threshold
*(volatile unsigned long *)(SOFT_UART_MC) = 0x03; // no parity, 1 stop bits, 8data bits
*(volatile unsigned long *)(SOFT_UART_DIV_LO) = PLD_AHB_CLK_FREQUENCY / (baud * 16);
*(volatile unsigned long *)(SOFT_UART_DIV_HI) = 0x00; //
#endif
}
void sendcharB(char *ch)
{
#ifdef SOFT_UART
char chr1 = 0x0d;
if (*ch == 0x0a) sendchar(&chr1);
while ( ((*(volatile unsigned long *)(SOFT_UART_TSR)) & 0x1f) > 0x0 );
*(volatile unsigned long *)(SOFT_UART_TD) = (unsigned long)*ch;
#endif
}
char receivecharB(void)
{
unsigned long ch = 0x45; // dummy 'E'
#ifdef SOFT_UART
// wait for rxfifo not empty
while ( ((*(volatile unsigned long *)(SOFT_UART_RSR)) & 0x1f) == 0 );
ch = *(volatile unsigned long *)(SOFT_UART_RD);
#endif
return (char)ch;
}
int kbhitB(void)
{
#ifdef SOFT_UART
if ( ((*(volatile unsigned long *)(SOFT_UART_RSR)) & 0x1f) == 0 )
return 0;
else
return 1;
#else
return 0;
#endif
}
void flushallB(void)
{
#ifdef SOFT_UART
unsigned long ch = 0x45;
// wait for rxfifo not empty
while ( ((*(volatile unsigned long *)(SOFT_UART_RSR)) & 0x1f) > 0 )
ch = *(volatile unsigned long *)(SOFT_UART_RD);
#endif
}
//-------------------------------------------------------------------------
ULONG timeushigh;
ULONG timeuslow;
ULONG timems;
// this timer counts in us
// it will wrap every 4000 seconds (approx 1 hour)
// it uses the excalibur timer0
// could use an irq to wrap the counters
int init_timer0(void)
{
// @50MHz, 1 tick = 20ns
timeuslow = 0;
timeushigh = 0;
timems = 0;
*(volatile ULONG *)(EXC_TIMER0_CR) = 0x0; // stop timer
*(volatile ULONG *)(EXC_TIMER0_PRE) = EXC_AHB2_CLK_FREQUENCY/1000000; // timer runs @ ahb2 / 1e6 = 1us
*(volatile ULONG *)(EXC_TIMER0_LIMIT) = 0xee6b2800; // =4e9 = 4000 seconds
*(volatile ULONG *)(EXC_TIMER0_CR) = 0x10; // start timer
return 0;
}
// this timer counts at ahb2 rate
// it will generate an interrupt every 1ms
// it uses the excalibur timer1
int init_timer1(void)
{
// @50MHz, 1 tick = 20ns
*(volatile ULONG *)(EXC_TIMER1_CR) = 0x0; // stop timer
*(volatile ULONG *)(EXC_TIMER1_PRE) = 1; // timer runs @ ahb2
*(volatile ULONG *)(EXC_TIMER1_LIMIT) = EXC_AHB2_CLK_FREQUENCY / 2000; // limit = 1ms
*(volatile ULONG *)(EXC_TIMER1_CR) = 0x1c; // start timer, enable interrupts
*(ULONG *)(INT_MASK_SET) = *(ULONG *)(INT_MASK_SET) | 0x200; // enable timer1 interrupts
return 0;
}
// read the us counter, calculate the ms timer
// cope with the wrap at 4000 seconds
// initialise the timer on the first read
ULONG readtimeus(void)
{
ULONG timeus;
static int started = 0;
if (!started)
{
init_timer0();
started = 1;
}
timeus = *(volatile ULONG *)(EXC_TIMER0_READ); // read timer0
// check if wrapped = 4000 seconds = ~ 1 hour
// could do this in an irq ...
if (timeus < timeuslow)
{
timeushigh ++;
timems += 4000000;
}
timeuslow = timeus;
timems = (timeushigh * 4000000) + (timeuslow / 1000);
return timeus;
}
ULONG readtimems(void)
{
readtimeus();
return timems;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -