This is the mail archive of the
ecos-discuss@sourceware.cygnus.com
mailing list for the eCos project.
SMC2 - no interrupts?
- To: Ecos Discussion List <ecos-discuss at sourceware dot cygnus dot com>
- Subject: [ECOS] SMC2 - no interrupts?
- From: Jamie Guinan <guinan at bluebutton dot com>
- Date: Tue, 9 Nov 1999 22:34:30 -0500 (EST)
- Reply-To: guinan at bluebutton dot com
Hi all,
[ Note - I'll also send a formal bug report related to this under
my client's support contract, so some Cygnus folks may see this twice. ]
I'm using eCos on an MBX 821 board, and I'm trying to coerce SMC2
into a functioning state. A few weeks ago I got as far as figuring out
I needed a transceiver (duh), and I verified that the port was operational
by sending EPPCBug's console out SMC2.
I've been studying quicc_smc_serial.c, and I'm a bit stumped as to
why nothing is coming out the SMC2 port in my test application.
My simple test app is attached, but in a nutshell, the code goes,
const char *device = "/dev/ser2";
char *msg;
cyg_io_handle_t handle;
int len;
cyg_io_lookup(device, &handle);
msg = "Hello from SMC2\n";
len = strlen(msg);
cyg_io_write(handle, msg, &len);
and nothing comes out the port. Debugging the driver, I found that
after it fills the transmit buffer, it calls quicc_smc_serial_flush(),
which sets the R and I bits (Ready/Interrupt) in the tx buffer descriptor,
so that an interrupt will be generated once the data is sent. It *should*
work, but since nothing was happening I decided to add some counter
variables (see attached patch file) and guess what- neither
quicc_smc_serial_ISR() nor quicc_smc_serial_DSR() seem to get called. :/
I'm working out of CVS at the moment (updated late night, Nov 8th).
My configuration goes,
tclsh .../packages/pkgconf.tcl --target powerpc --platform mbx --startup ram --disable-uitron
Then I manually tweak some pkgconf settings,
hal.h:
#define CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
#define CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE 4096
#undef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
#undef CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
#undef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
#undef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS
#undef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
#define CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
#define CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
#undef CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT
#define CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
io_serial.h:
#define CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC
#define CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1
(defaults, 38400, etc.)
#define CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2
(defaults, 38400, etc.)
hal_powerpc_mbx.h:
#define CYGHWR_HAL_POWERPC_BOARD_SPEED 40
infra.h:
#define CYGPKG_INFRA_DEBUG
#define CYGDBG_INFRA_DIAG_USE_DEVICE
Is there anything else I need to do to get the interrupts into
operation? Maybe its a cache issue?
For what its worth, here is a dump of the smc_chan structure passed
to quicc_smc_serial_flush(). It looks Ok to me (pram, txbd, etc. seem
reasonable at least),
(gdb) p *smc_chan
$1 = {channel = 176, int_num = 55, brg = 0xff0009f4, pram = 0xff003f80,
ctl = 0xff000a90,
txbd = 0xff002840, rxbd = 0xff002860, tbase = 0xff002840, rbase =
0xff002860, txsize = 16,
rxsize = 16, serial_interrupt = {vector = 55, priority = 0, isr =
0x130dc <quicc_smc_serial_ISR>,
dsr = 0x12ce0 <quicc_smc_serial_DSR>, data = 322024, dsr_count = 0,
next_dsr = 0x0},
serial_interrupt_handle = 322208, tx_enabled = 0}
Thanks in advance...
-Jamie
================================================================
Jamie Guinan Blue Button Solutions, Inc.
guinan@bluebutton.com http://www.bluebutton.com
================================================================
*** /usr/local/ecos-cvs/ecos/packages/io/serial/current/src/powerpc/quicc_smc_serial.c Fri Oct 1 09:25:48 1999
--- quicc_smc_serial.c Tue Nov 9 21:14:02 1999
***************
*** 588,603 ****
--- 588,606 ----
}
// Serial I/O - low level interrupt handler (ISR)
+ static int ISRcount=0;
static cyg_uint32
quicc_smc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
{
serial_channel *chan = (serial_channel *)data;
quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv;
+ ISRcount++;
cyg_drv_interrupt_mask(smc_chan->int_num);
return CYG_ISR_CALL_DSR; // Cause DSR to be run
}
// Serial I/O - high level interrupt handler (DSR)
+ static int DSRcount=0;
static void
quicc_smc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
***************
*** 618,623 ****
--- 621,627 ----
diag_printf("DSR start - CE: %x, time: %x.%x\n", ctl->smc_smce, _stime, _time);
enable_diag_uart = 1;
#endif // CYGDBG_DIAG_BUF
+ DSRcount++;
if (ctl->smc_smce & QUICC_SMCE_TX) {
#ifdef XX_CYGDBG_DIAG_BUF
enable_diag_uart = 0;
serialtest.disassem : serialtest
powerpc-eabi-objdump --disassemble-all serialtest > serialtest.disassem
serialtest: serialtest.c
powerpc-eabi-gcc -g -I$(ECOS_BASE)/include \
serialtest.c -L$(ECOS_BASE)/lib -Ttarget.ld -nostdlib \
-o serialtest
clean:
rm -f serialtest serialtest.mx
/* Testing serial ports */
#include <stdio.h>
#include <cyg/kernel/kapi.h>
#include <cyg/io/io.h>
#include <cyg/io/serialio.h>
#include <cyg/hal/hal_cache.h>
void test(const char *device)
{
Cyg_ErrNo rc;
cyg_io_handle_t handle;
cyg_serial_info_t serial_config;
char *word_length, *baud, *stop, *parity;
int len;
char *msg;
char buff[20];
rc = cyg_io_lookup(device, &handle);
if (ENOERR != rc)
{
printf("error opening %s\n", device);
cyg_thread_suspend(cyg_thread_self());
}
len = sizeof(serial_config);
rc = cyg_io_get_config(handle,
CYG_IO_GET_CONFIG_SERIAL_INFO,
&serial_config,
&len);
if (ENOERR != rc)
{
printf("get_config failed\n");
cyg_thread_suspend(cyg_thread_self());
}
switch(serial_config.baud)
{
case CYGNUM_SERIAL_BAUD_50: baud = "50"; break;
case CYGNUM_SERIAL_BAUD_75: baud = "75"; break;
case CYGNUM_SERIAL_BAUD_110: baud = "110"; break;
case CYGNUM_SERIAL_BAUD_134_5: baud = "5"; break;
case CYGNUM_SERIAL_BAUD_150: baud = "150"; break;
case CYGNUM_SERIAL_BAUD_200: baud = "200"; break;
case CYGNUM_SERIAL_BAUD_300: baud = "300"; break;
case CYGNUM_SERIAL_BAUD_600: baud = "600"; break;
case CYGNUM_SERIAL_BAUD_1200: baud = "1200"; break;
case CYGNUM_SERIAL_BAUD_1800: baud = "1800"; break;
case CYGNUM_SERIAL_BAUD_2400: baud = "2400"; break;
case CYGNUM_SERIAL_BAUD_3600: baud = "3600"; break;
case CYGNUM_SERIAL_BAUD_4800: baud = "4800"; break;
case CYGNUM_SERIAL_BAUD_7200: baud = "7200"; break;
case CYGNUM_SERIAL_BAUD_9600: baud = "9600"; break;
case CYGNUM_SERIAL_BAUD_14400: baud = "14400"; break;
case CYGNUM_SERIAL_BAUD_19200: baud = "19200"; break;
case CYGNUM_SERIAL_BAUD_38400: baud = "38400"; break;
case CYGNUM_SERIAL_BAUD_57600: baud = "57600"; break;
case CYGNUM_SERIAL_BAUD_115200: baud = "115200"; break;
case CYGNUM_SERIAL_BAUD_234000: baud = "234000"; break;
}
switch(serial_config.word_length)
{
case CYGNUM_SERIAL_WORD_LENGTH_5: word_length = "5"; break;
case CYGNUM_SERIAL_WORD_LENGTH_6: word_length = "6"; break;
case CYGNUM_SERIAL_WORD_LENGTH_7: word_length = "7"; break;
case CYGNUM_SERIAL_WORD_LENGTH_8: word_length = "8"; break;
}
switch(serial_config.stop)
{
case CYGNUM_SERIAL_STOP_1: stop = "1"; break;
case CYGNUM_SERIAL_STOP_1_5: stop = "1.5"; break;
case CYGNUM_SERIAL_STOP_2: stop = "2"; break;
}
switch(serial_config.parity)
{
case CYGNUM_SERIAL_PARITY_NONE: parity="NONE"; break;
case CYGNUM_SERIAL_PARITY_EVEN: parity="EVEN"; break;
case CYGNUM_SERIAL_PARITY_ODD: parity="ODD"; break;
case CYGNUM_SERIAL_PARITY_MARK: parity="MARK"; break;
case CYGNUM_SERIAL_PARITY_SPACE: parity="SPACE"; break;
}
printf("Serial parameters: %s baud, %s/%s/%s\n", baud, word_length, parity, stop);
msg = "Hello from SMC2\n";
len = strlen(msg);
while(1)
{
rc = cyg_io_write(handle, msg, &len);
printf("rc=%d, len=%d\n", rc, len);
cyg_thread_delay(100);
}
}
int main(void)
{
test("/dev/ser2");
return 0;
}