This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
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