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