?? st16c554.c
字號:
#include "st16c554d.h"
#include "2410addr.h"
#include "2410lib.h"
#include <string.h>
struct
{
int sizes;
unsigned char bufs[512];
}port_buffers[4];
void s3c2410_init_memory_control()
{
//no need to set BWSCON, use default:8-bits bus,no wait,
rBWSCON = rBWSCON & 0xff00f00f;
rBANKCON1 = (B_Tacs << Tacs_Offset) | (B_Tcos << Tcos_Offset) | (B_Tacc <<Tacc_Offset) | (B_Tcoh << Tcoh_Offset) | (B_Tcah <<Tcah_Offset) | (B_Tacp << Tacp_Offset) | (B_PMC << PMC_Offset);
rBANKCON2 = (B_Tacs << Tacs_Offset) | (B_Tcos << Tcos_Offset) | (B_Tacc <<Tacc_Offset) | (B_Tcoh << Tcoh_Offset) | (B_Tcah <<Tcah_Offset) | (B_Tacp << Tacp_Offset) | (B_PMC << PMC_Offset);
rBANKCON4 = (B_Tacs << Tacs_Offset) | (B_Tcos << Tcos_Offset) | (B_Tacc <<Tacc_Offset) | (B_Tcoh << Tcoh_Offset) | (B_Tcah <<Tcah_Offset) | (B_Tacp << Tacp_Offset) | (B_PMC << PMC_Offset);
rBANKCON5 = (B_Tacs << Tacs_Offset) | (B_Tcos << Tcos_Offset) | (B_Tacc <<Tacc_Offset) | (B_Tcoh << Tcoh_Offset) | (B_Tcah <<Tcah_Offset) | (B_Tacp << Tacp_Offset) | (B_PMC << PMC_Offset);
}
void s3c2410_reset_CS_pin()
{
//set CS1,2,4,5 as cs pins
rGPACON = rGPACON | 0x1b000;
}
void s3c2410_init_interrupt()
{
//set gpf 0,1,2,3 as eint
rGPFCON = (rGPFCON | 0xaa) & 0xffffffaa;
//set the signaling method as high
rEXTINT0 = (rEXTINT0 | 0x1111) & 0xffff1111;
//set the signaling method as low
//rEXTINT0 = rEXTINT0 & 0xfffff000;
//set the signaling method as rising edge
//rEXTINT0 = (rEXTINT0 | 0x4444) & 0xffff4444;
}
void st16c554_reset_chip() //set PB0 as output
{
rGPBCON = (rGPBCON & 0xfffffffd) | 0x01;
//set PB0 high
rGPBDAT = rGPBDAT | 0x01;
//keep PB0 high for 40 ns to reset st16c554
Delay(1);
//set PB0 low
rGPBDAT= rGPBDAT & 0xfffffffe;
}
//dtr:0,1 - force DTR# pin output high,low
//rts:0,1 - force RTS# pin output high,low
//intOutput:0,1 - INT(a-d) output disable(three state),INT(a-d) output enable(active)
void st16c554d_set_mcr(int port, int dtr, int rts, int intOutput)
{
unsigned char *portAddr;
switch(port)
{
case 1:
portAddr = Add_st16c554d_portA;
break;
case 2:
portAddr = Add_st16c554d_portB;
break;
case 3:
portAddr = Add_st16c554d_portC;
break;
case 4:
portAddr = Add_st16c554d_portD;
break;
default:
return;
}
portAddr += rST16C554D_MCR;
*portAddr = dtr | (rts << 1) | (intOutput << 3);
Uart_Printf("%x=%x ",portAddr,*portAddr);
}
//fifi:0,1 - disable,enalbe
//resetRxFifo:0,1 - not reset,reset
//resetTxFifo:0,1 - not reset,reset
//dma:0,1 - normal,dma mode
//RxTrigger:0,1,2,3 - 1,4,8,14
void st16c554d_set_fcr(int port, int fifo, int resetRxFifo, int resetTxFifo, int dma, int rxTrigger)
{
unsigned char *portAddr;
switch(port)
{
case 1:
portAddr = Add_st16c554d_portA;
break;
case 2:
portAddr = Add_st16c554d_portB;
break;
case 3:
portAddr = Add_st16c554d_portC;
break;
case 4:
portAddr = Add_st16c554d_portD;
break;
default:
return;
}
portAddr += rST16C554D_FCR;
*portAddr = fifo | (resetRxFifo << 1) | (resetTxFifo << 2) | (dma << 3) | (rxTrigger << 6);
}
//worldLength:0,1,2,3 - 5,6,7,8
//stopBit:0,1,1 - 1(5,6,7,8 bits length),1-1/2(5 bits length),2(6,7,8 bits length)
//parity: 0,1,3,5,7 - none,odd,even,forced 1,forced 0
void st16c554d_set_line(int port, int wordLength, int stopBit, int parity)
{
unsigned char *portAddr;
switch(port)
{
case 1:
portAddr = Add_st16c554d_portA;
break;
case 2:
portAddr = Add_st16c554d_portB;
break;
case 3:
portAddr = Add_st16c554d_portC;
break;
case 4:
portAddr = Add_st16c554d_portD;
break;
default:
return;
}
portAddr += rST16C554D_LCR;
*portAddr = wordLength | (stopBit << 2) | (parity << 3);
Uart_Printf("%x=%x ",portAddr,*portAddr);
}
//baud 200,1200,2400,4800,9600,19200,38400,76800,115200,230400,460800
void st16c554d_set_band(int port, int baud)
{
unsigned char *portAddr;
unsigned char dll = 0, dlm = 0;
switch(port)
{
case 1:
portAddr = Add_st16c554d_portA;
break;
case 2:
portAddr = Add_st16c554d_portB;
break;
case 3:
portAddr = Add_st16c554d_portC;
break;
case 4:
portAddr = Add_st16c554d_portD;
break;
default:
return;
}
switch(baud)
{
case 200:
dlm = 0x09;
break;
case 1200:
dlm = 0x01;
dll = 0x80;
break;
case 2400:
dll = 0xc0;
break;
case 4800:
dll = 0x60;
break;
case 9600:
dll = 0x30;
break;
case 19200:
dll = 0x18;
break;
case 38400:
dll = 0x0c;
break;
case 76800:
dll = 0x06;
break;
case 115200:
dll = 0x04;
break;
case 230400:
dll = 0x02;
break;
case 460800:
dll = 0x01;
break;
default:
return;
}
//enalbe baudrate divisor
*(portAddr + rST16C554D_LCR) = *(portAddr + rST16C554D_LCR) | 0x80;
//write to dll and dlm
*(portAddr + rST16C554D_DLL) = dll;
*(portAddr + rST16C554D_DLM) = dlm;
//disable baudrate divsior
*(portAddr + rST16C554D_LCR) = *(portAddr + rST16C554D_LCR) & 0x7f;
}
void st16c554d_enable_irq(int port)
{
unsigned char *portAddr;
switch(port)
{
case 1:
portAddr = Add_st16c554d_portA;
break;
case 2:
portAddr = Add_st16c554d_portB;
break;
case 3:
portAddr = Add_st16c554d_portC;
break;
case 4:
portAddr = Add_st16c554d_portD;
break;
default:
return;
}
portAddr += rST16C554D_IER;
*portAddr = 0x01;
}
void st16c554d_disable_irq(int port)
{
unsigned char *portAddr;
switch(port)
{
case 1:
portAddr = Add_st16c554d_portA;
break;
case 2:
portAddr = Add_st16c554d_portB;
break;
case 3:
portAddr = Add_st16c554d_portC;
break;
case 4:
portAddr = Add_st16c554d_portD;
break;
default:
return;
}
portAddr += rST16C554D_IER;
*portAddr = 0x0;
}
void __irq st16c554_port_a_rx(void)
{
int maxcount = 256;
Uart_Printf("eint 0 occur!\n");
//disable interrupt
rINTMSK = rINTMSK | 1;
ClearPending(BIT_EINT0);
while (maxcount--)
{
if ((*( Add_st16c554d_portA + rST16C554D_LSR) & 0x01) == 0)
break;
port_buffers[0].bufs[port_buffers[0].sizes++] = *Add_st16c554d_portA;
}
//enable interrupt
rINTMSK = rINTMSK & 0xfffffffe;
}
void __irq st16c554_port_b_rx(void)
{
int maxcount = 256;
//disable interrupt
Uart_Printf("eint 1 occur!\n");
rINTMSK = rINTMSK | 2;
ClearPending(BIT_EINT1);
while (maxcount--)
{
if ((*( Add_st16c554d_portB + rST16C554D_LSR) & 0x01) == 0)
break;
port_buffers[1].bufs[port_buffers[1].sizes++] = *Add_st16c554d_portB;
}
//enable interrupt
rINTMSK = rINTMSK & 0xfffffffd;
}
void __irq st16c554_port_c_rx(void)
{
int maxcount = 256;
Uart_Printf("eint 2 occur!\n");
//disable interrupt
rINTMSK = rINTMSK | 4;
ClearPending(BIT_EINT2);
while (maxcount--)
{
if ((*( Add_st16c554d_portC + rST16C554D_LSR) & 0x01) == 0)
break;
port_buffers[2].bufs[port_buffers[2].sizes++] = *Add_st16c554d_portC;
}
//enable interrupt
rINTMSK = rINTMSK & 0xfffffffb;
}
void __irq st16c554_port_d_rx(void)
{
int maxcount = 256;
Uart_Printf("eint 3 occur!\n");
//disable interrupt
rINTMSK = rINTMSK | 8;
ClearPending(BIT_EINT3);
while (maxcount--)
{
if ((*( Add_st16c554d_portD + rST16C554D_LSR) & 0x01) == 0)
break;
port_buffers[3].bufs[port_buffers[3].sizes++] = *Add_st16c554d_portD;
}
//enable interrupt
rINTMSK = rINTMSK & 0xfffffff7;
}
void s3c2410_set_intmod(int port)
{
}
void s3c2410_enable_irq(int port)
{
unsigned int mskvalue;
switch(port)
{
case 1:
mskvalue = 0xfffffffe;
break;
case 2:
mskvalue = 0xfffffffd;
break;
case 3:
mskvalue = 0xfffffffb;
break;
case 4:
mskvalue = 0xfffffff7;
break;
default:
return;
}
rINTMSK = rINTMSK & mskvalue;
}
void s3c2410_disable_irq(int port)
{
unsigned int mskvalue;
switch (port)
{
case 1:
mskvalue = 1;
break;
case 2:
mskvalue = 2;
break;
case 3:
mskvalue = 4;
break;
case 4:
mskvalue = 8;
break;
default:
return;
}
rINTMSK = rINTMSK | mskvalue;
}
void st16c554d_send_char(int port, unsigned char ch)
{
unsigned char *portAddr;
switch(port)
{
case 1:
portAddr = Add_st16c554d_portA;
break;
case 2:
portAddr = Add_st16c554d_portB;
break;
case 3:
portAddr = Add_st16c554d_portC;
break;
case 4:
portAddr = Add_st16c554d_portD;
break;
default:
return;
}
while (!(*(portAddr + rST16C554D_LSR) & 0x20));
*portAddr = ch;
}
void st16c554d_write(int port, char *source, int sizes)
{
int i = 0,j,k,m;
unsigned char *portAddr;
switch(port)
{
case 1:
portAddr = Add_st16c554d_portA;
break;
case 2:
portAddr = Add_st16c554d_portB;
break;
case 3:
portAddr = Add_st16c554d_portC;
break;
case 4:
portAddr = Add_st16c554d_portD;
break;
default:
return;
}
j = sizes / 16;
k = sizes % 16;
for (m = 0; m < j; m++)
{
while (!(*(portAddr + rST16C554D_LSR) & 0x20));
for (m = 0; m < 16; m++)
*portAddr = *(source + i++);
}
while (!(*(portAddr + rST16C554D_LSR) & 0x20));
for (m = 0; m < k; m++)
{
*portAddr = *(source + i++);
}
}
int st16c554d_read(int port, unsigned char *dest)
{
unsigned char *portAddr;
int maxcount = 0;
switch(port)
{
case 1:
portAddr = Add_st16c554d_portA;
break;
case 2:
portAddr = Add_st16c554d_portB;
break;
case 3:
portAddr = Add_st16c554d_portC;
break;
case 4:
portAddr = Add_st16c554d_portD;
break;
default:
return 0;
}
while ((*(portAddr + rST16C554D_LSR ) & 0x01) && (maxcount < 256))
{
*(dest + maxcount++) = *portAddr;
}
return maxcount;
}
void Test_St16c554d_Uart(void)
{
int i;
int counter[4] = {0, 0, 0, 0};
char string[][100] = {"hello,this demo string come from port A",
"hello,this demo string come from port B",
"hello,this demo string come from port C",
"hello,this demo string come from port D"};
Uart_Printf("Reset St16c554 Test!\n");
s3c2410_reset_CS_pin();
s3c2410_init_interrupt();
st16c554_reset_chip();
Uart_Printf("Init 1,2,4,5 memory control bank!\n");
s3c2410_init_memory_control();
for (i = 0; i < 4; i++)
{
//disable interrupt
s3c2410_disable_irq(i+1);
//have to clear pengding interrupt
ClearPending((1<<i));
st16c554d_disable_irq(i+1);
//clear buffer
port_buffers[i].sizes = 0;
memset(port_buffers[i].bufs,0,512);
//baud 50,300,600,1200,2400,4800,9600,19200,38400,57600,115200
st16c554d_set_band(i+1, 115200);
//set moden control register
//DTR#=high, RTS#=high, INT(a-d) output enable(active)
st16c554d_set_mcr(i + 1, 0, 0, 1);
//set fifo control register
//enable fifo mode, reset thr, reset rhr, not dma mode, trigger level=1
st16c554d_set_fcr(i+1, 1, 1, 1, 0, 0);
//set line control resiter
//8 databits, 1 stopbit, none parity
st16c554d_set_line(i+1, 3, 0, 0);
Uart_Printf("\n____________________________\n");
}
Uart_Printf("rGPACON=%x,rBWSCON=%x, rBANKCON1=%x, rBANKCON2=%x, rBANKCON4=%x, rBANKCON5=%x\n",rGPACON,rBWSCON,rBANKCON1,rBANKCON2,rBANKCON4,rBANKCON5);
Uart_Printf("MCRA=%x, LCRA=%x\n",*(Add_st16c554d_portA+rST16C554D_MCR),*(Add_st16c554d_portA+rST16C554D_LCR));
Uart_Printf("MCRB=%x, LCRB=%x\n",*(Add_st16c554d_portB+rST16C554D_MCR),*(Add_st16c554d_portB+rST16C554D_LCR));
Uart_Printf("MCRC=%x, LCRC=%x\n",*(Add_st16c554d_portC+rST16C554D_MCR),*(Add_st16c554d_portC+rST16C554D_LCR));
Uart_Printf("MCRD=%x, LCRD=%x\n",*(Add_st16c554d_portD+rST16C554D_MCR),*(Add_st16c554d_portD+rST16C554D_LCR));
pISR_EINT0 = (unsigned)st16c554_port_a_rx;
pISR_EINT1 = (unsigned)st16c554_port_b_rx;
pISR_EINT2 = (unsigned)st16c554_port_c_rx;
pISR_EINT3 = (unsigned)st16c554_port_d_rx;
for (i = 0; i < 4; i++)
{
st16c554d_enable_irq(i+1);
s3c2410_enable_irq(i+1);
}
Uart_Printf("enable all interrupt!\n");
while(1)
{
for(i = 0; i < 4; i++)
{
if (port_buffers[i].sizes)
{
port_buffers[i].bufs[port_buffers[i].sizes] = '\0';
Uart_Printf("%s\n",port_buffers[i].bufs);
port_buffers[i].sizes = 0;
memset(port_buffers[i].bufs,0,512);
}
//port_buffers[i].sizes = st16c554d_read(i,port_buffers[i].bufs);
//if (port_buffers[i].sizes)
//{
// port_buffers[i].bufs[port_buffers[i].sizes] = '\0';
// Uart_Printf("%s\n", port_buffers[i].bufs);
//}
if (counter[i] > 5000000)
{
st16c554d_write(i + 1, string[i], strlen(string[i]));
//Uart_Printf("%s", string[i]);
counter[i] = 0;
}
else
counter[i]++;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -