Page 1 of 1

Problems reading data from COM1

Posted: Wed Jul 12, 2006 6:59 pm
by earlz
Hello I'm attempting to implement COM port io but I'm having some problems I can write perfectly, its the reading stuff I have problems with it acts as if it never gets a read interrupt

here is my code:

Code: Select all

/*the include file with the defines*/

#ifndef COM_PORTS_H
#define COM_PORTS_H

//ports
#define COM1_TRANSMIT_RECEIVE_BUFFER 0x3F8 //also is baud rate divisor LSB
#define COM1_INTERRUPT_ENABLE 0x3F9 //also is baud rate divisor MSB
#define COM1_INTERRUPT_ID 0x3FA
#define COM1_LINE_CONTROL 0x3FB
#define COM1_MODEM_CONTROL 0x3FC
#define COM1_LINE_STATUS 0x3FD
#define COM1_MODEM_STATUS 0x3FE
#define COM1_SCRATCH_PAD 0x3FF






//interrupt enable register macros
#define INT_RECEIVED_DATA 1 //ready to read
#define INT_TRANSMITTER_EMPTY 2 //ready to send
#define INT_RECEIVER_STATUS 4 //error occured
#define INT_MODEM_STATUS 8  //just a change, useless

//interrupt identification
#define ID_MODEM_STATUS 0 //means it has changed, read xxC
#define ID_TRANSMITTER_EMPTY 2 //ready to write
#define ID_RECEIVED_DATA 4 //a byte is in the buffer(ready to read)
#define ID_RECEIVER_STATUS 6 //an error occured, read xxD(line status)
#define NO_INTERRUPTS_PENDING 1

//Line Control
#define LINE_5BIT_1STOP 0
#define LINE_6BIT_1STOP 1
#define LINE_7BIT_1STOP 2
#define LINE_8BIT_1STOP 3
#define LINE_5BIT_1_5STOP 4
#define LINE_6BIT_2STOP 5
#define LINE_7BIT_2STOP 6
#define LINE_8BIT_2STOP 7

#define LINE_PARITY_ON 8
#define LINE_ODD_PARITY 0
#define LINE_EVEN_PARITY 16
#define LINE_ALWAYS0_PARITY 32
#define LINE_ALWAYS1_PARITY 48

#define LINE_BREAK_ENABLED 64
#define LINE_ADDRESS_BAUD 128


//Modem Control

#define ACTIVATE_DTR 1
#define ACTIVATE_RTS 2
#define INTERRUPTS_ENABLE 8
#define LOOPBACK_MODE 16



//9600 is 0x3F9:0 0x3F8:0x0C


//line status
//errors
#define OVERRUN_ERROR 2
#define PARITY_ERROR 4
#define FRAMING_ERROR 8
#define CONNECT_LOST 16 //actually referred to break interrupt
























#endif






/* the main file*/


/******************************
This is the Com port interface
*****************************/
#include <com_ports>
#include <k_JouleOS>
#include <mytypes>
#include <stdio>
#include <video>
#include <debug>

typedef  unsigned char(*ComEvent)(unsigned char);

volatile ComEvent ReadFunc=0;
volatile unsigned char Com1Error; //this is basically a copy of the error stuff, its a bitmap

volatile BOOL IgnoreReads=TRUE; //ignores reads(lets the pc store it in its internal buffer)
volatile BOOL NoWriting=TRUE; //doesn't write anything
volatile BOOL ReadyWrite=TRUE; //ready to write, only set when IgnoreWrites is set or Com1WriteCounter==Com1WriteLength
volatile BOOL ReadyRead=TRUE; //ready to read, only set when IgnoreReads is set or Com1ReadCounter==Com1ReadLength
volatile unsigned char Com1IgnoredReadBuffer; //done just to avoid errors
volatile unsigned char *Com1ReadBuffer;
volatile unsigned int Com1ReadCounter=0;
volatile unsigned int Com1ReadLength=0;
volatile unsigned char *Com1WriteBuffer;
volatile unsigned int Com1WriteCounter=0; //Where we are at in Com1WriteBuffer
volatile unsigned int Com1WriteLength=0; //length of Com1WriteBuffer
void Init_ComPort1(BOOL on_boot){ //on_boot is 1 if it is called on boot so that it prints the messages
	//ComBuffer=malloc(32);
	//Com1Counter=0;
	//set to address baud
	outportb(COM1_LINE_CONTROL,  LINE_ADDRESS_BAUD);
     //send baud rate
	outportb( COM1_TRANSMIT_RECEIVE_BUFFER,0x0C);
	outportb(COM1_INTERRUPT_ENABLE,0);
	//set the comport up
     outportb(COM1_LINE_CONTROL, LINE_8BIT_1STOP );
     outportb(COM1_INTERRUPT_ENABLE, INT_RECEIVED_DATA|INT_TRANSMITTER_EMPTY|INT_RECEIVER_STATUS);
	outportb(COM1_MODEM_CONTROL,INTERRUPTS_ENABLE);
	//reset the serial port
	inportb(COM1_INTERRUPT_ID);
	inportb(COM1_LINE_STATUS);
	inportb(COM1_MODEM_CONTROL);
	if(on_boot){
	printf("COM1 Hardware:");
     def_console->curx=60;def_console->color=GREEN;printf("[OK]");
     def_console->cury++;def_console->curx=0;def_console->color=0x0F;
	}
	wait(500);
	if(on_boot){
          printf("COM1 Line:");
		if(Com1Error==0){
               def_console->curx=60;def_console->color=GREEN;printf("[OK]");
               def_console->cury++;def_console->curx=0;def_console->color=0x0F;
		}else{
               def_console->curx=58;def_console->color=RED;
               printf("[FAILED]\n");
               def_console->cury++;def_console->curx=0;def_console->color=0x0F;
		}
	}
	
}

unsigned char SendByteCom1(unsigned char dat){
	//sending without the automatic interrupt
	unsigned int delay;
	delay=timer_ticks+2000; //wait 2s
	while(delay>timer_ticks){
		if(ReadyWrite==TRUE){
			outportb(COM1_TRANSMIT_RECEIVE_BUFFER,dat);
			return 0;
		}
	}
	return 1;
}



void Com1SetupReadEvent(void *ptr){
	ReadFunc=ptr;
}



void ComPort1_Handler(){ //This is the interrupt handler
	unsigned char which,tmp;
	unsigned char tmpy[2];
	which=inportb(COM1_INTERRUPT_ID);
	tmp=which&0x06; //isolate the type of interrupt
	switch(tmp){
		case ID_MODEM_STATUS: //ignored
		//do nothing
		break;
		case  ID_TRANSMITTER_EMPTY: //ready to write
		if(NoWriting ||  Com1WriteLength<=Com1WriteCounter){
			ReadyWrite=TRUE;
		}
		break;
		case ID_RECEIVED_DATA:
		debug{ //special macro so that this only runs in debug mode
			tmpy[1]=0;
			tmpy[0]=inportb(COM1_TRANSMIT_RECEIVE_BUFFER);
			printf(tmpy); 
			printf("i");
		}
		//if(ReadFunc!=0){ReadFunc(inportb(COM1_TRANSMIT_RECEIVE_BUFFER));return;}
		if(IgnoreReads || Com1ReadLength<=Com1ReadCounter){
			ReadyRead=TRUE;
		}
		break;
		case ID_RECEIVER_STATUS: //ERROR!!
		which=inportb(COM1_LINE_STATUS);
		which=which&30; //isolates bits 1-4
		switch(which){
			case OVERRUN_ERROR: //buffer overrun
			Com1IgnoredReadBuffer=inportb(COM1_TRANSMIT_RECEIVE_BUFFER);
			break;
			case PARITY_ERROR:
			Com1Error=PARITY_ERROR;
			//do nothing I guess
			break;
			case FRAMING_ERROR:
			Com1Error=FRAMING_ERROR;
			//do nothing again
			break;
			case CONNECT_LOST:
			Com1Error=CONNECT_LOST;
			break;
		}
		break;
	}
	
}




and yes I know some things aren't done(trying to get basics in first)

Posted: Fri Jul 14, 2006 10:54 am
by chase
I don't even have a serial port in my computer any more :)

Have you seen this site http://www.beyondlogic.org/serial/serial1.htm ?

Posted: Fri Jul 14, 2006 11:28 am
by Dex
Some good info here: http://www.nondot.org/sabre/os/articles ... onDevices/
This one is good "Exhaustive Serial Port Doc"

Posted: Fri Jul 14, 2006 1:10 pm
by earlz
nah I think I got it figured out now
just need someone at mega-tokyo to test it on real hardware