This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
serial line ISR problem -- again:(
- From: Piotr Trojanek <ptroja at elproma dot com dot pl>
- To: ecos-discuss <ecos-discuss at sources dot redhat dot com>
- Date: Mon, 8 Sep 2003 19:13:29 +0200
- Subject: [ECOS] serial line ISR problem -- again:(
Hi,
I still have a problem with my ISR, which should simply act when signal
transition on DCD pin of COM1 serial port (i386 PC). I'm 100% signal
is 200ms 'high', and then 800ms 'low'. Tested with both linux, freebsd,
qnx.
The worst is that this code used to work on my another PC machine:(,
but only on _that_ one...
Please, help, what do I do wrong?
--
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_sem_t data_ready;
volatile cyg_uint8 ier;
cyg_uint32 isr(
cyg_vector_t vector,
cyg_addrword_t data)
{
/* do the work... */
int i;
c++;
/* reenable IRQ on UART */
for (i = 0; i < 8; i++)
HAL_READ_UINT8(COM_ADDR + i, ier);
cyg_interrupt_acknowledge( vector );
return CYG_ISR_HANDLED;
}
void dsr(
cyg_vector_t vector,
cyg_ucount32 count,
cyg_addrword_t data)
{
/* 0x08 means transition from low go high */
if (ier == 0x08) {
cyg_semaphore_post( &data_ready );
}
}
void
producer(cyg_addrword_t data)
{
for (;;)
{
cyg_semaphore_wait( &data_ready );
printf("c = %d\n", c);
}
}
int dcd_main( void)
{
cyg_vector_t intr_vector = CYGNUM_HAL_ISR_MIN + COM_IRQ;
cyg_priority_t intr_priority = CYGNUM_HAL_PRI_HIGH;
int in_use;
cyg_semaphore_init( &data_ready, 0 );
HAL_INTERRUPT_IN_USE( intr_vector, in_use );
printf("in_use(%d) = %d\n", intr_vector, in_use);
cyg_thread_create(PRODUCER_PRIORITY, &producer, 0, "producer",
producer_stack, PRODUCER_STACKSIZE,
&producer_handle, &producer_thread);
cyg_thread_resume(producer_handle);
cyg_interrupt_create(
intr_vector,
intr_priority,
0,
isr,
dsr,
&intr_handle,
&intr);
// Attach the interrupt created to the vector.
cyg_interrupt_attach( intr_handle );
// Unmask the interrupt we just configured.
cyg_interrupt_unmask( intr_vector );
/* get acces to Interrupt Enable Register */
HAL_READ_UINT8 (COM_ADDR + 3, ier);
HAL_WRITE_UINT8 (COM_ADDR + 3, ier & 0x7f);
/* make UART interrupt on DCD transition */
HAL_WRITE_UINT8 (COM_ADDR + 1, 0x08);
HAL_INTERRUPT_IN_USE( intr_vector, in_use );
printf("in_use(%d) = %d\n", intr_vector, in_use);
printf("cyg_scheduler_start()\n");
cyg_scheduler_start();
}
externC void
cyg_start( void )
{
dcd_main();
}
--
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss