This is the mail archive of the ecos-discuss@sourceware.cygnus.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]

SMC2 - no interrupts?




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;
} 


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