how can I catch an interrupt signal?

alberto capella alberto.capella at terra.es
Sat Oct 7 11:48:43 UTC 2000


This is my first message to this list.

I am a begginer user of RTEMS and I have to program a Sound Blaster 16
Driver in C.

The program works O.K. except that I can`t execute muy own interrupt
routine
when the end of the DMA buffer is reached.

I am using the "rtems_interrupt_catch" routine to assign my routine to
the
interrupt vector. The IRQ of the SB is 5.

Does anybody tell me if I have to do something else or I have to change
any
configuration parameter?

The vector number to the rtems_interrupt_catch is my IRQ=5?

Here is my code, if you can look at it and tell me if there is something
wrong,
I will be gratefull for you for ever.


The code of the program is:


#define TEST_INIT

#include <bsp.h>

#include <stdio.h>

#include <stdlib.h>
#include <rtems/score/i386.h>

  rtems_unsigned16         Base=0x220;
  rtems_unsigned8          DMA=5;
  rtems_unsigned8          IRQ=5;

  rtems_unsigned16 *DMABuffer;
  rtems_unsigned8  Page;
  rtems_unsigned32 Offset;

  rtems_unsigned32 TamanoBuff=32768;  /*Longitud del buffer (en bytes)*/

  rtems_unsigned32 NumeroSamples=64000; /*numero de samples de 16 bits
que
                                          tenemos que reproducir*/
  rtems_unsigned8 RBuffer=0;

void outb(rtems_unsigned8 val,rtems_unsigned16 port)
{
  outport_byte(port,val);
}

rtems_unsigned8 inb(rtems_unsigned16 port)
{
  rtems_unsigned8 val=0;

  inport_byte(port, val);
  return val;
}

rtems_unsigned8 ResetDSP (rtems_unsigned16 Test)
{
  rtems_unsigned32 i;

/*Reset del DSP*/
  outb (1,Test + 0x6);
 for(i=0;i<1000;i++);
  outb (0,Test + 0x6);
  for(i=0;i<3000;i++);
  /*miramos si el reset fue correcto*/
  if (((inb (Test + 0xE) & 0x80) == 0x80) && (inb (Test + 0xA) == 0xAA))
{
    /*DSP encontrado*/
    Base = Test;
    return 1;
  }
  /*DSP no encontrado*/
  return 0;
}
void WriteDSP(rtems_unsigned8 Value)
{
  /*Esperamos a que el DSP este listo para recibir datos*/
  while ((inb (Base + 0xC) & 0x80) == 0x80);
  /*Enviamos el byte*/
  outb (Value,Base + 0xC);
}

void AutoInitPlayback ()
{
  rtems_unsigned32 aux=0;

  aux=TamanoBuff/2; /*a reproducir la mitad p q  son words */
  aux--;            /* y hay que pasarle el numero de words-1*/

  outb (4 | (DMA&3),0xD4);             /*Mask canal DMA  */
  outb (0,0xD8);                       /*Clear byte pointer*/
  outb (0x58 | (DMA&3),0xD6);          /*Ponemos el mode */

  outb (Offset & 0xFF,((DMA&3)<<2)+0xC0); /* low offset al DMA  */
  outb ((Offset >> 8)&0xFF,((DMA&3)<<2)+0xC0);/* high offset al DMA*/

  /*reproducimos TODO EL BUFFER*/
  outb(aux&0xFF,((DMA&3)<<2) + 2 + 0xC0);  /*low length al DMA*/
  outb((aux>>8)&0xFF,((DMA&3)<<2) + 2 + 0xC0); /* high length al DMA */

  /*pagina al DMA  */
  if (DMA==5) outb(Page,0x8B);
  if (DMA==6) outb(Page,0x89);
  if (DMA==7) outb(Page,0x8A);

  outb ((DMA&3),0xD4); /*Unmask canal DMA  */

  /*aux=TamanoBuff/4;
  aux--;*/

  /*DSP-command B6h - 16bit autoinit playback */
  WriteDSP (0xB6);
  WriteDSP (0x00);

  /* reproducimos MITAD DEL BUFFER*/
  WriteDSP(aux & 0xFF);
  WriteDSP((aux>>8) & 0xFF);

}

void AssignBuffer ()
{
  rtems_unsigned16  *TempBuf;       /*puntero temporal*/
  rtems_unsigned32  LinearAddress;  /*dirección física*/
  rtems_unsigned8   Page1, Page2;   /*paginas de comienzo y fin del
buffer*/

  /*Asignamos el buffer
  TempBuf = malloc (TamanoBuff);*/
  TempBuf = calloc (TamanoBuff,1);

  /*Calculamos la LinearAddress (direccion fisica)*/
  LinearAddress=(rtems_unsigned32)(TempBuf);

 /*Calculamos la pagina de comienzo del buffer*/
  Page1 = ((LinearAddress >> 16) & 0xfe );

  /*Calculamos la pagina en la que finaliza el buffer*/
  Page2 = (((LinearAddress + TamanoBuff-1) >> 16) & 0xfe);

  /*Miramos si una page boundary is crossed*/
    if (Page1 != Page2) {
    printf("he entrado en el if de la memoria\n");
    /*Si es así, ponemos el buffer en otro sitio
    DMABuffer = malloc(TamanoBuff);*/
    DMABuffer = calloc(TamanoBuff,1);
    free (TempBuf);

  } else /*usamos el que ya habiamos cogido*/
    DMABuffer = TempBuf;

  /*Convertimos a dirección física*/
  LinearAddress=(rtems_unsigned32)(DMABuffer);

  Page = (LinearAddress >> 16) & 0xfe ;

  Offset = (LinearAddress >> 1) & 0xFFFF;
}

void ReadBuffer(rtems_unsigned8 buf, rtems_unsigned8 relleno)
{
  /*aqui tendre que mirar si hay samples por leer*/
  /* si relleno==1 hay que rellenar con silencios*/

  rtems_unsigned32 comienzo,fin,i;

  comienzo=buf*TamanoBuff/4;
  fin=comienzo+TamanoBuff/4;

  /*si relleno==1 entonces lleno el buffer de silencios
    y luego cargo la parte de samples que queda (indicado
    por NumeroSamples)

   sino relleno el buffer directamente con el fichero*/
  for(i=comienzo;i<fin;i++) {
    DMABuffer[i]=i;
    DMABuffer++;
  }
  NumeroSamples=NumeroSamples-TamanoBuff/4;
}

rtems_isr sb16_isr(rtems_vector_number ignored)
{
  inb(Base+0xF);

  outb(0x20,0x20);
}

void SBPlay ()
{
  if (!DMABuffer) return;

  WriteDSP (0x41);
  WriteDSP (0x00);
  WriteDSP (0x01);

  /*DSP-command D1h - Activamos altavoz*/
  WriteDSP (0xD1);

  /*AQUI TENEMOS QUE RELLENAR EL BUFFER*/
  /* miraremos que haya suficientes al ppio para rellenar el buffer*/
  ReadBuffer(0,0);
  ReadBuffer(1,0);

  AutoInitPlayback ();
}


rtems_task Init(
  rtems_task_argument ignored
)
{
  rtems_unsigned32 i;
  rtems_isr_entry old_isr_handler;
  rtems_status_code resul=RTEMS_INVALID_NUMBER;

  ResetDSP(Base);
  AssignBuffer();

  resul=rtems_interrupt_catch(sb16_isr,0x34,&old_isr_handler);
  if (resul==RTEMS_SUCCESSFUL) printf("\nEl catch ha tenido exito\n");
  else
    if (resul==RTEMS_INVALID_NUMBER) printf("\nilegal vector number\n");

    else
      if (resul==RTEMS_INVALID_ADDRESS)
        printf("\ndirec de isr o oldisr handler no valido\n");

  /*REPRODUCIMOS */
  SBPlay ();

  for(i=0;i<500000;i++);


  free(DMABuffer);


  exit(0);
}

/* configuration information */

#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER

#define CONFIGURE_RTEMS_INIT_TASKS_TABLE

#define CONFIGURE_INIT

#include <confdefs.h>

/* end of file */





More information about the users mailing list