Problems reading data from COM1
Posted: Wed Jul 12, 2006 6:59 pm
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:
and yes I know some things aren't done(trying to get basics in first)
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)