[comp.sys.next] DSP Example

eht@f.word.cs.cmu.edu (Eric Thayer) (07/05/89)

This example should work:

/* cc test_memmap.c -o test_memmap -ldsp */ 

#include <dsp/dsp.h> 

/* 
 * Test program for memory-mapped control of the DSP host 
 * interface.  The output of this program should be as follows:
 *
 * Original values of the eight host-interface bytes: <any>
 * icr = 0x0
 * cvr = 0x12
 * isr = 0x6
 * After cvr set to 0x1F, cvr  = 0x1F
 * After icr set to 0x18, icr  = 0x18
 * Waiting for RXDF ... got it.
 * After TX set to 0xBBCCDD, RX is 0x5DE66E which is correct.
 *	 rxh  = 0x5D
 *	 rxm  = 0xE6
 *	 rxl  = 0x6E
 */

/********************** getDSPRegs() *************************/ 

/* #include <dsp/dsp.h> */
#include <sys/file.h>
#include <sys/mman.h>

DSPRegs *getDSPRegs() 
/* 
 * The following function memory-maps the DSP host interface.
 * Memory-mapped access can interfere with the Mach Sound/DSP 
 * driver, so normally the driver is kept unaware during 
 * memory-mapped control by zeroing RREQ and TREQ in the 
 * Interrupt Control Register (ICR) of the host interface;
 * this ensures that the DSP never interrupts the host which 
 * would cause the driver to read and possibly write the DSP.
 */
{
    char *alloc_addr;	/* page address for DSP memory map */
    int dsp_fd;

    dsp_fd = open("/dev/dsp",O_RDWR);	/* need <sys/file.h> */
    if (dsp_fd == -1) 
      return(NULL);

    if (( alloc_addr = (char *)valloc(getpagesize()) ) == NULL) 
      return(NULL);

    if ( -1 == mmap(alloc_addr,
	 getpagesize(),			/* Must map a full page */
	 PROT_READ|PROT_WRITE,	/* rw access <sys/mman.h> */
	 MAP_SHARED,			/* shared access (of course) */
	 dsp_fd,				/* This device */
	 0) )					/* 0 offset */
      return(NULL);

    return (DSPRegs *)alloc_addr; /* <dsp/dspstructs.h> */
}

/******************** Global definitions *********************/ 

static DSPRegs *hostInterface = 0; /* host interface pointer */

#define ICR hostInterface->icr
#define CVR hostInterface->cvr
#define ISR hostInterface->isr

#define TXH hostInterface->data.tx.h
#define TXM hostInterface->data.tx.m
#define TXL hostInterface->data.tx.l
#define TX hostInterface->data.transmit

#define RXH hostInterface->data.rx.h
#define RXM hostInterface->data.rx.m
#define RXL hostInterface->data.rx.l
#define RX hostInterface->data.receive

#define put_icr(x) ICR = x
#define put_cvr(x) CVR = x
#define put_isr(x) ISR = x
#define put_txh(x) TXH = x
#define put_txm(x) TXM = x
#define put_txl(x) TXL = x
#define put_tx(x)  TX = x

#define get_icr(x) *(x) = ICR
#define get_cvr(x) *(x) = CVR
#define get_isr(x) *(x) = ISR
#define get_rxh(x) *(x) = RXH
#define get_rxm(x) *(x) = RXM
#define get_rxl(x) *(x) = RXL
#define get_rx(x)  *(x) = RX

/************************** main() ***************************/ 

main() { 
    int tval,reply,err;
    DSPLoadSpec *bootProg; /* /usr/include/dsp/dspstructs.h */
    
    err = DSPReadFile(&bootProg,"boot56k"); /* Read boot prog */
    if (err) {
	fprintf(stderr,"Could not open file boot56k.[lod,dsp]\n");
	exit(1);
    }

    err = DSPBoot(bootProg); 		/* Load struct to DSP */
    if (err) {
	fprintf(stderr,"Could not load contents of boot56k.\n");
	exit(1);
    }

/*  DSPBootFile("boot56k");	/* Same as previous 2 lines */

    hostInterface = getDSPRegs();

    if (hostInterface == NULL) {
		fprintf(stderr,"Could not memory-map DSP host interface\n");
		exit(1);
    }
	
    fprintf(stderr," Original values of the eight "
	   "host-interface bytes: 0x%X 0x%X\n", 
	   *(int *)hostInterface, 
	   *((int *)hostInterface+1));

    put_icr(0);		/* Turn off TREQ and RREQ */
    fprintf(stderr," icr = 0x%X\n",ICR);

    put_cvr(0x12);	/* Set CVR to known value */
    fprintf(stderr," cvr = 0x%X\n",CVR);

    fprintf(stderr," isr = 0x%X\n",ISR);

    CVR = 0x1F;		/* Test writing of CVR */
    fprintf(stderr," After cvr set to 0x1F, cvr  = 0x%X\n", CVR);

    put_icr(0x18);	/* Set HF1 and HF0 */ 
    fprintf(stderr," After icr set to 0x18, icr  = 0x%X\n", ICR);
    
    tval = 0xBBCCDD;	/* Value for TX write test */ 
    put_tx(tval);	/* 24 bits, right-justified in 32 */
    
    fprintf(stderr," Waiting for RXDF ...");
    while (!(ISR&1))	/* Wait until return value exists */
      ;
    fprintf(stderr," got it.\n");

    get_rx(&reply);	/* Read value returned by boot56k */
    fprintf(stderr," After TX set to 0xBBCCDD, RX is 0x%X ", reply);
    if (reply == tval>>1) 
      fprintf(stderr,"which is correct.\n");
    else
      fprintf(stderr,"\n*** DSP PROBLEM ***\nrx should be"
	     " 0x%X\n",tval>>1);
    
    fprintf(stderr,"\t rxh  = 0x%X\n",RXH);
    fprintf(stderr,"\t rxm  = 0x%X\n",RXM);
    fprintf(stderr,"\t rxl  = 0x%X\n",RXL);
    
    DSPClose(); 
}

; ================================================================
; boot56k.asm 1 Example DSP bootstrap program that goes into an 
; infinite loop reading HRX, right-shifting one place, 
; and writing HTX
;
; This will work with internal memory only.  Also, ROM may not be enabled.

		org p:0 
reset	jmp >rcv_buz

		dup $40-2	; output must be a contiguous segment 
			nop 
		endm

		org p:$40	; typical starting address

rcv_buz jclr #0,x:$FFE9,rcv_buz	; wait for data from host 
		move x:$FFEB,A1

		LSR A	; right-shift one place

xmt_buz jclr #1,x:$FFE9,xmt_buz	; send shifted word to host 
		move A1,x:$FFEB

		jmp rcv_buz

	end $40
-- 
Eric H. Thayer		Carnegie Mellon School of Computer Science
(412) 268-{8724,6973}	5000 Forbes Ave, Pittsburgh, PA 15213

carlos@tybalt.caltech.edu (Carlos Salinas) (07/08/89)

Why doesn't someone local to Motorola's DSP BBS upload the files to the ar-

chives. Better yet, someone at Motorola should upload them.
					Carlos Salinas
VI SUX!