This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: serial line ISR problem -- again:(


On Wed, Sep 10, 2003 at 10:17:06AM +0100, Robert Cragie wrote:
> It would help if you post truly representative code, i.e the most basic set
> which exhibits the problems. Anything else confuses the issue considerably.

you're right, so here it goes...

the output from my program is:
iid = 0x00, c = 0
msr = 0x88, c = 0
iid = 0x00, c = 0
msr = 0x08, c = 0
... [this loops forever, and this sequence takes about 1 second
(DCD is high for 0.2 second), which coresponds to signal I can see
on osciloscope and my test LED diode]

as you can see, I read Interrupt Identification Register (iid) in UART, and
when it says there is a pending interrupt (iid = 0x00, which also means
that it was interrupt was caused by change on input signal lines) I
simoply reads modem status register to reenable interrupts from UART.

values 0x08 and 0x88 coresponds to signal change on DCD line.

so, there is a proof, that my hardware works fine and exactly as I
expect. all works just fine in polling mode.

now I need to make it works in interrupt mode, but my ISR is not executed
by ECOS. under both Linux and FreeBSD COM1 works fine under IRQ4.

-- 
Piotr Trojanek
#include <cyg/kernel/kapi.h>
#include <cyg/hal/hal_arch.h>
#include <stdio.h>

volatile unsigned int c;

cyg_interrupt intr;
cyg_handle_t intr_handle;

/*
ttyS00 at 0x03f8 (irq = 4) is a 16550A
ttyS01 at 0x02f8 (irq = 3) is a 16550A
*/

#define	COM_IRQ		4
#define	COM_ADDR	0x3f8

#define CYGNUM_HAL_PRI_HIGH 0

#define PRODUCER_PRIORITY   0
#define PRODUCER_STACKSIZE  CYGNUM_HAL_STACK_SIZE_TYPICAL

unsigned char producer_stack[PRODUCER_STACKSIZE];
cyg_handle_t producer_handle;
cyg_thread producer_thread;
		
cyg_uint32 isr(
        cyg_vector_t vector,
        cyg_addrword_t data)
{
        /* do the work... */
        c++;

        cyg_interrupt_acknowledge( vector );
        return CYG_ISR_HANDLED;
}

void
producer(cyg_addrword_t data)
{
	cyg_uint8 iid;
	cyg_interrupt intr;
	cyg_handle_t intr_handle;
        cyg_vector_t intr_vector = CYGNUM_HAL_ISR_MIN + COM_IRQ;
        cyg_priority_t intr_priority = CYGNUM_HAL_PRI_HIGH;

	cyg_interrupt_create(
			intr_vector,
			intr_priority,
			0,
			isr,
			0,
			&intr_handle,
			&intr);

	cyg_interrupt_attach(intr_handle);
	cyg_interrupt_unmask(intr_vector);

        /* get acces to Interrupt Enable Register */
        HAL_WRITE_UINT8 (COM_ADDR + 3, 0x00);
	/* make UART interrupt on DCD transition */
	HAL_WRITE_UINT8 (COM_ADDR + 1, 0x08);

	printf("start\n");

	for (;;) {
		HAL_READ_UINT8 (COM_ADDR + 2, iid);
		if ((iid & 0x01) == 0x00) {
			/* interrupt pending */
			cyg_uint8 msr;

			printf("iid = 0x%02x, c = %u\n", iid, c);

			/*
			 * read modem status register
			 * to delete interrupt
			 */
			HAL_READ_UINT8 (COM_ADDR + 6, msr);
			printf ("msr = 0x%02x, c = %u\n", msr, c);
		}
	}
}

int main( void)
{
	cyg_thread_create(PRODUCER_PRIORITY, &producer, 0, "producer",
		producer_stack, PRODUCER_STACKSIZE,
		&producer_handle, &producer_thread);
	cyg_thread_resume(producer_handle);

	cyg_scheduler_start();
}

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]