/*********************************************************************************

 * 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 함수를 손봐야될 성싶은데.... 어떻게하는지 좀 알려주셈 ㅠ