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 15213carlos@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!