/*********************************************************************************
* UART 16550 Basic Operation.
* Print a message and output key-in data.
* IPs to be added.
* 1) RS232 : UART 16550
* 2) GPIO 8 bit out : LED
*********************************************************************************/
#include <stdio.h>
#define BASEADDRESS_LEDS 0x81400000
#define BASEADDRESS_UART16550 0x83e00000
#define RBR (*((volatile unsigned char *)(BASEADDRESS_UART16550 + 0x1000 + 3))) // Receiver Buffer Register (RBR)
#define THR (*((volatile unsigned char *)(BASEADDRESS_UART16550 + 0x1000 + 3))) // Transmitter Holding Register (THR)
#define LCR (*((volatile unsigned char *)(BASEADDRESS_UART16550 + 0x100C + 3))) // Line Control Register (LCR)
#define LSR (*((volatile unsigned char *)(BASEADDRESS_UART16550 + 0x1014 + 3))) // Line Status Register (LSR)
#define DLL (*((volatile unsigned char *)(BASEADDRESS_UART16550 + 0x1000 + 3))) // Divisor Latch Register (DLL). Least Significant Byte
#define DLM (*((volatile unsigned char *)(BASEADDRESS_UART16550 + 0x1004 + 3))) // Divisor Latch Register (DLM). Most Significant Byte
#define LEDS (*((volatile unsigned char *)(BASEADDRESS_LEDS + 3))) // LED port
/* for future use
unsigned short Bin2ASCII(unsigned char BinData) {
unsigned char Nibble, UpperAscii, LowerAscii;
Nibble = BinData >> 4;
if (Nibble <= 9) {
UpperAscii = Nibble + '0'; // 0x30;
}
else
UpperAscii = Nibble + 'A' - 10; // 0x41;
Nibble = BinData & 0x0f;
if (Nibble <= 9) {
LowerAscii = Nibble + '0'; // 0x30;
}
else
LowerAscii = Nibble + 'A' - 10; // 0x41;
return(UpperAscii << 8 | LowerAscii );
}
void Print8bits(unsigned char ch) {
unsigned char tmp;
unsigned short Hex16Value;
Hex16Value=Bin2ASCII(ch); // Convert 8 bit binary data to 16 bit ASCII code
tmp = Hex16Value >> 8; PutCh(tmp); // *TxFifo = ch; // Send ASCII of the 1st digit.
tmp = Hex16Value & 0xff; PutCh(tmp); //*TxFifo = ch; // Send ASCII of the 2nd digit.
}
void Print16bits(unsigned short ch) {
unsigned char tmp;
tmp = ch >> 8; Print8bits(tmp);
tmp = (unsigned char) ch ; Print8bits(tmp);
}
void Print32bits(unsigned long ch) {
unsigned short tmp;
tmp = ch >> 16; Print16bits(tmp);
tmp = (unsigned short) ch ; Print16bits(tmp);
}
*/
unsigned char GetCh(void) {
unsigned char Status;
do {
Status = LSR; // Read in Status. Line Status Register
} while ( (Status & 0x1) == 0 ); // if bit 0 is logic 1, then it means RxFIFO has some valid data.
return(RBR); // return with RxFIFO value, if RxFIFO has valid data.
}
void PutCh(unsigned char ch) {
unsigned char Status;
do {
Status = LSR; // Read in Status. Line Status Register
} while ( (Status & 0x20) == 0 ); // Wait until TxFIFO gets empty. Bit 26 will be set, if empty.
THR = ch;
if(ch=='\n') PutCh('\r'); // Add carriage return(\r) if the code is line feed(\n).
}
void Printf(char *String) {
int i;
for(i=0; String[i] != NULL; i++) {
PutCh(String[i]);
if (String[i] == '\n') PutCh('\r'); // Add carriage return(\r) if the code is line feed(\n).
}
}
void InitilaizeUART16550(unsigned int clk, unsigned int DesiredBPS) {
// clk = SLPB_Clk. Clock of MicroBlaze
// DesiredBPS = BAUD rate of UART
// LCR set value in binary = 1001_0011. BLAB =1. None parity, 1 stop bit. 8 bit data
LCR = 0x93;
unsigned short divisor = (unsigned short) (clk / (DesiredBPS * 16));
unsigned char high = (unsigned char) (divisor >> 8);
unsigned char low = (unsigned char) divisor;
DLL = low; // outportb(Divisor_Latch_LSB, low);
DLM = high; // outportb(Divisor_Latch_MSB, high);
LCR = 0x13; // Clear bit 7 for general usage
}
//*********************************************************************************
// Lab. 1 - Print message and key in/out
//*********************************************************************************
int main() {
unsigned int CPU_CLOCK = 50*1000*1000; // MicroBlaze Processor Clock.
//unsigned int BAUD = 9600; // 9600 bps
unsigned int BAUD = 57600; // 9600 bps
LEDS = 0xaa;
InitilaizeUART16550(CPU_CLOCK, BAUD);
Printf("\n\n****** UART 16550 set up successfully. ******\nKey in any character! : ");
LEDS = 0x55;
while(1) {
unsigned char ch = GetCh();
PutCh(ch);
LEDS = ch;
}
}
UART 16550 활용해서 teraterm 터미널 활용해서 입출력 시스템 만드는건데
보드 래잇을 921600으로 주어서 정상적으로 출력하게 만들라는데....뭔 손대야될지 모르겠다.
일단 unsigned int BAUD을 수정하면 printf 란 출력값붙터 한자로 뷁뷁 이런식으로 나오는거봐서는..
전송속도를 보드가 못따라가는 것같음(NEXYS 2)사용
저기 printf 함수를 손봐야될 성싶은데.... 어떻게하는지 좀 알려주셈 ㅠ
댓글 0