Serial port outputs random data

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Serial port outputs random data

Post by Ycep »

Hi, I was recently writing my Serial Port Driver, and it seems to output random data.
When I try to send character 'X', I get 0x18.
This is my SendSerial function. ex. SendSerial(0,'X');

Code: Select all

void SendSerial(uint8 COM, uint8 data)
{
	if(COM>SerialComAmount-1)
	{
		if(SerialComAmount==0)cerror("No Serial Hardware in System.");
		else cerror("Can't use unregistered serial port!");
		return;
	}
	uint16 SerAddr=SerialPort[COM];
	while(!(inb(SerAddr+5)&0x20));
	outb(SerAddr,data);
}
Bochs and VMWare just output 0x18 rather than 0x58 on serial port.
InitSerial():

Code: Select all

bool InitSerial()
{
	for(uint8 i=0;i<4;i++)
	{
		uint16 val=*((uint16*)(0x0400+i*2));
		if(!val)continue;
		SerialPort[i]=val;
		SerialComAmount++;
		InitPort(val);
	}
	printf("\nSerial Ports:%d\n",SerialComAmount);
	if(SerialComAmount)return true;
	else return false;
}
SetBaud (Function for setting baud) and InitPort:

Code: Select all

void SetBaud(uint16 portaddr,uint8 divisor)
{
	outb(portaddr+3,0x80);
	outb(portaddr,divisor);
	outb(portaddr+1,0);//I will not use divisors bigger than 255
}
void InitPort(uint8 portaddr)
{
	outb(portaddr+1,0x00);
	SetBaud(portaddr,3);
	outb(portaddr,0x03);//0000 0011
	outb(portaddr+2,0xC7);
	outb(portaddr+4,0x0B);
}
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Serial port outputs random data

Post by Octacone »

Your code seems overly complex. (I use something much simpler, personal preference)
Try this:

Code: Select all

outportb(COM1, 'o');
//com1 is 0x3F8
and tell me the output.
Last edited by Octacone on Sun Aug 28, 2016 3:30 pm, edited 1 time in total.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: Serial port outputs random data

Post by Ycep »

octacone wrote:Your code seems overly complex.
Try this:

Code: Select all

outportb(COM1, 'o');
//com1 is 0x3F8
and tell me the output.
0x0F. Again random.
It isn't complex. It only has support for multiple serial ports, serial port address detection, etc. Nothing complex, I'll rather refer it simple.
Thanks for suggestion.
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Serial port outputs random data

Post by Octacone »

Lukand wrote:
octacone wrote:Your code seems overly complex.
Try this:

Code: Select all

outportb(COM1, 'o');
//com1 is 0x3F8
and tell me the output.
0x0F. Again random.
It isn't complex. It only has support for multiple serial ports, serial port address detection, etc. Nothing complex, I'll rather refer it simple.
Thanks for suggestion.
What!? That is not what I expected. Give me a moment.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
f2
Member
Member
Posts: 311
Joined: Mon Jun 15, 2009 10:01 am
Location: France

Re: Serial port outputs random data

Post by f2 »

Hmm, your code seems OK. Could you show your outb() function?
"Open source seems to embrace the dark side of human nature." - Ville Turjanmaa
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Serial port outputs random data

Post by Octacone »

@f2

This is the one I use:

Code: Select all

void outportb(uint16 _port, uint8 _data)
{
	__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
Works perfectly fine, he can try it out.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: Serial port outputs random data

Post by Ycep »

f2 wrote:Hmm, your code seems OK. Could you show your outb() function?
No problem. Why is it needen? It's working flawlessly for everything else:

Code: Select all

void outb(uint16 prt, uint8 val)
{
	_asm
	{
		mov     al, byte ptr[val]
		mov     dx, word ptr[prt]
		out     dx, al
	}
}
octacone wrote:@f2

This is the one I use:

Code: Select all

void outportb(uint16 _port, uint8 _data)
{
	__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
Works perfectly fine, he can try it out.
Eh... =P~. I don't want to, since that is GCC compilant. Please do not make fool from me. Do you really think that my outb() code isn't working?
Last edited by Ycep on Sun Aug 28, 2016 3:26 pm, edited 1 time in total.
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Serial port outputs random data

Post by Octacone »

So did it work?
Edit: what emulator do you use?
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: Serial port outputs random data

Post by Ycep »

octacone wrote:So did it work?
Edit: what emulator do you use?
I said I tried it on VMWare and Bochs.
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Serial port outputs random data

Post by Octacone »

Lukand wrote:
octacone wrote:So did it work?
Edit: what emulator do you use?
I said I tried it on VMWare and Bochs.
Try Qemu with and don't forget std -serial stdio
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: Serial port outputs random data

Post by Ycep »

octacone wrote:
Lukand wrote:
octacone wrote:So did it work?
Edit: what emulator do you use?
I said I tried it on VMWare and Bochs.
Try Qemu with and don't forget std -serial stdio
I am using MS Windows. QEMU is Linux emulator. And if it won't work on VMWare and Bochs what is the purpose then?
User avatar
f2
Member
Member
Posts: 311
Joined: Mon Jun 15, 2009 10:01 am
Location: France

Re: Serial port outputs random data

Post by f2 »

OK, so your outb() seems correct.

I just found something in your InitPort() function I haven't seen before.
Look at this code from OSDev Wiki ( http://wiki.osdev.org/Serial_Ports#Example_Code ):

Code: Select all

#define PORT 0x3f8   /* COM1 */
void init_serial() {
   outb(PORT + 1, 0x00);    // Disable all interrupts
   outb(PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
   outb(PORT + 0, 0x03);    // Set divisor to 3 (lo byte) 38400 baud
   outb(PORT + 1, 0x00);    //                  (hi byte)
   outb(PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
   outb(PORT + 2, 0xC7);    // Enable FIFO, clear them, with 14-byte threshold
   outb(PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
}
If I compare it with your code:

Code: Select all

outb(portaddr+1,0x00);
   SetBaud(portaddr,3);
   outb(portaddr,0x03);//0000 0011
   outb(portaddr+2,0xC7);
   outb(portaddr+4,0x0B);
I see on the third line that you are sending the value 0x03 to portaddr and not to portaddr + 3, as you can see in the init_serial() function.
Can you change the line outb(portaddr,0x03) to outb(portaddr+3,0x03) and see if that fixes your problem?

EDIT: removed a comma, thanks octacone :)
Last edited by f2 on Sun Aug 28, 2016 3:43 pm, edited 1 time in total.
"Open source seems to embrace the dark side of human nature." - Ville Turjanmaa
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Serial port outputs random data

Post by Octacone »

f2 wrote: Can you change the line outb(portaddr,0x03) to outb(portaddr,+3,0x03) and see if that fixes your problem?
outb(portaddr,+3,0x03) -> outb(portaddr+3,0x03)
Edit: @f2 ;)
Last edited by Octacone on Sun Aug 28, 2016 3:47 pm, edited 1 time in total.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: Serial port outputs random data

Post by BrightLight »

Lukand wrote:I am using MS Windows. QEMU is Linux emulator.
QEMU is by no means tied to Linux. A quick Google search "QEMU on Windows" will get you good results.
The code snippets on the serial port Wiki page are enough to properly initialize the serial port.

Code: Select all

void com1_init()
{
	short* com1_bda = (short*)0x400;
	com1_base = com1_bda[0];
	if(com1_base == 0) return;	// if there is no serial port, there's nothing to do

	outb(com1_base+1, 1);
	iowait();
	outb(com1_base+3, 0x80);
	iowait();
	outb(com1_base+0, 2);
	iowait();
	outb(com1_base+1, 0);
	iowait();
	outb(com1_base+3, 3);
	iowait();
	outb(com1_base+2, 0xC7);
	iowait();

	dprintf(KERNEL_STRING);
	dprintf("\n");
	dprintf("com1: initialized serial port, base IO port is at 0x%x.\n", com1_base);
}

void com1_send_byte(char byte)
{
	if(com1_base == 0) return;
	while(!(inb(com1_base+5) & 0x20));

	if(byte == '\n')
	{
		while(!(inb(com1_base+5) & 0x20));
		outb(com1_base, 13);	// carriage
		while(!(inb(com1_base+5) & 0x20));
		outb(com1_base, 10);	// newline
		while(!(inb(com1_base+5) & 0x20));
		return;
	}

	outb(com1_base, byte);
	while(!(inb(com1_base+5) & 0x20));
}
You know your OS is advanced when you stop using the Intel programming guide as a reference.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Serial port outputs random data

Post by iansjack »

'X' = 0x58, you get 0x18
'o' = 0x6F, you get 0x0F

Do you spot the pattern? You haven't set the number of data bits, so it looks like it has defaulted to 5 bits rather than 7 or 8.
Post Reply