MusicKit  0.0.0
dspdriverAccess.h
00001 #ifndef __MK_dspdriverAccess_H___
00002 #define __MK_dspdriverAccess_H___
00003 /*
00004   $Id$
00005   David Jaffe, CCRMA, Stanford University.
00006   Feb. 1994
00007 
00008   This module is private with respect to the Music Kit and libdsp.
00009   However it may be exported so other systems can access the driver
00010   functionality directly.
00011 */
00012 typedef unsigned int dsp_id;
00013 
00014 #import "dsp_types.h"
00015 
00016 /************  Set-up functions ****************************/
00017 
00018 /* To use a DSP, you must first "add" it, then "open" it, then "reset" it. 
00019  */
00020 extern int dsp_addDsp(dsp_id dspId,const char *driver,int unit,int subUnit);
00021 /* dspId must not have been added yet. */
00022 
00023 extern int dsp_open(dsp_id dspId);  
00024 extern int dsp_close(dsp_id dspId); 
00025 extern int dsp_reset(dsp_id dspId,char on);
00026 
00027 extern void 
00028   setDSPDriverErrorProc(void (*errFunc)(dsp_id dspId,
00029                                         char *caller,
00030                                         char *errorMessage,
00031                                         int errorCode));
00032 /* Use this to register an error function.  Otherwise, errors are
00033  * printed to stderr.  Note that stderr is not thread-safe.
00034  * Hence if you access the dspdriver in other than the main
00035  * thread, you should probably register your own error handler.
00036  */
00037 
00038 /* Simple low level functions *************************/
00039 extern char dsp_getICR(dsp_id dspId);
00040 extern char dsp_getCVR(dsp_id dspId);
00041 extern char dsp_getISR(dsp_id dspId);
00042 extern char dsp_getIVR(dsp_id dspId);
00043 
00044 extern void dsp_putICR(dsp_id dspId, char b);
00045 extern void dsp_putCVR(dsp_id dspId, char b);
00046 extern void dsp_putIVR(dsp_id dspId, char b);
00047 
00048 extern void dsp_putTXRaw(dsp_id dspId,char high,char med,char low);
00049 extern void dsp_getRXRaw(dsp_id dspId,char *high,char *med,char *low);
00050 
00051 extern int dsp_getHI(dsp_id dspId); /* Returns: ICR|CVR|ISR|IVR packed */
00052 
00053 /**************** Word I/O with checking of ISR bits ******/
00054 extern void dsp_putTX(dsp_id dspId,char high,char med,char low);
00055 /* Like dsp_putTXRaw, but waits for TXDE to be set. */
00056 
00057 extern void dsp_getRX(dsp_id dspId,char *high,char *med,char *low);
00058 /* Like dsp_getRXRaw but waits for ISR&1 (RXDF) to be set. */
00059 
00060 
00061 /**************** Array (TX/RX) I/O with checking of ISR bits ******/
00062 extern void dsp_putArray(dsp_id dspId,int *arr,unsigned int count);
00063 /* Like dsp_putTX, but puts a whole array of 24-bit numbers, right-justified   
00064    in 32-bits
00065    */
00066 
00067 extern void dsp_getArray(dsp_id dspId,int *arr,unsigned int count);
00068 /* Like dsp_getRX but gets a whole array.
00069    arr must point to at least count elements 
00070    */
00071 
00072 extern void dsp_putShortArray(dsp_id dspId,short *arr,unsigned int count);
00073 /* Like dsp_putTX but puts a whole array of 16-bit numbers.  These numbers
00074    are sign extended into TXH */
00075 
00076 extern void dsp_putLeftArray(dsp_id dspId,int *arr,unsigned int count);
00077 /* Like dsp_putTX but puts a whole array of 24-bit numbers, left-justified
00078    in 32-bits
00079    */
00080 
00081 extern void dsp_putByteArray(dsp_id dspId,char *arr,unsigned int count);
00082 /* Like dsp_putTX but puts a whole array of bytes.  These numbers are
00083    sign extended into TXH and TXM 
00084    */
00085 
00086 extern void dsp_putPackedArray(dsp_id dspId,char *arr,unsigned int count);
00087 /* Like dsp_putTX but puts a whole array of 24-bit packed numbers.  
00088    Note that count is the number of 24-bit numbers, not the number of bytes.
00089    */
00090 
00091 #define DSPDRIVER_DEBUG_UNEXPECTED 1
00092 #define DSPDRIVER_DEBUG_DEBUG      2
00093 #define DSPDRIVER_DEBUG_TRACE      4
00094 #define DSPDRIVER_DEBUG_VERBOSE    8
00095 
00096 extern int dsp_debug(char *driverName,int flags);
00097 /* Sets debugging flags for all units.  This may be done even if you're
00098  * not the owner of the driver (so another process can set/clear debug flags)
00099  * Returns 0 if successful, -1 if bad driverName, -2 if can't set flags.
00100  */
00101 
00102 /******************* Special Music Kit functions. *************/
00103 extern void dsp_executeMKTimedMessage(dsp_id dspId,int highWord,int lowWord,
00104                                       int opCode);
00105     /* Special Music Kit function for finishing a timed message */
00106 
00107 extern void dsp_executeMKHostMessage(dsp_id dspId);
00108     /* Special Music Kit function for executing a Host Message, which
00109      * is assumed already written to the HMS. (obsolete)
00110      */
00111 
00112 extern void dsp_call(dsp_id dspId,int *arr,unsigned int count); 
00113     /* Special Music Kit function for writing a host message to the HMS 
00114      * and executing it.
00115      */
00116 
00117 
00118 #import <mach/mach_types.h>
00119 
00120 /******************* Special functions for DSP-initiated transfer protocol ***/
00121 
00122 extern void dsp_setMessaging(dsp_id dspId, boolean_t flag);
00123     /* Turns DSP messaging (i.e. "DSP-initiated DMA") on or off.
00124      * Messaging should be turned on once the DSP has been booted
00125      * and code loaded, using the functions above.  Reseting the
00126      * DSP always turns off messaging.  Once messaging is on, you
00127      * can use the following functions to send or receive data
00128      * efficiently.  Note, however, that if you are using a DSP-initiated
00129      * communication path, you should do no other simultaneous communication
00130      * in that direction. 
00131      */
00132 
00133 extern void dsp_putPage(dsp_id dspId, vm_address_t pageAddress,
00134                         int regionTag, boolean_t msgStarted,
00135                         boolean_t msgCompleted, mach_port_t reply_port);
00136     /* Puts a page of ints (actually 2048 DSPFix24s), located at
00137      * the vm allocated by the user at pageAddress, to the DSP.
00138      * A mach message is returned to the reply_port if the caller
00139      * sets the write started or completed flag.  This function
00140      * partially replaces the functionality of the
00141      * snddriver_start_writing function found on black hardware.
00142      * This function does not rely on messaging (i.e. interrupts)
00143      * used in the following three functions, so it can be used
00144      * like the other "put" functions above.  However, this function
00145      * is somewhat more efficient since the data is mapped, not copied,
00146      * using out-of-line mach messaging.
00147      * 
00148      * This function is not used by the Music Kit.  It is included
00149      * for compatibility with snddriver protocol.
00150      */
00151 
00152 extern void dsp_queuePage(dsp_id dspId, vm_address_t pageAddress,
00153                           int regionTag, boolean_t msgStarted,
00154                           boolean_t msgCompleted, mach_port_t reply_port);
00155     /* Queues a page of 2048 DSPFix24s to the driver.  This queue is
00156      * a circular buffer which can hold up to 16 pages, so be sure the
00157      * DSP starts reading data before the queue overfills.  The DSP
00158      * reads data from the queue using the "DMA stream" protocol found
00159      * on black hardware (i.e. the DSP initiates the transfer by sending
00160      * a $040002 to the host, and then follows the handshaking sequence).
00161      * A mach message is returned to the reply_port if the msgStarted or
00162      * msgCompleted flags are set.  This function provides a minimal
00163      * emulation of the snddriver_start_writing function found on black
00164      * hardware.  It is efficient since the data is mapped, not copied,
00165      * using out-of-line mach messaging, and the data is sent to the DSP
00166      * when the DSP messages (interrupts) the host.
00167      *
00168      * This function is not used by the Music Kit.  It is included
00169      * for compatibility with snddriver protocol.
00170      */
00171 
00172 #define DSPDRIVER_MAX_TRANSFER_CHAN             18
00173 
00174 extern void dsp_setShortBigEndianReturn(dsp_id dspId, int regionTag,
00175                                         int wordCount, mach_port_t reply_port, 
00176                                         int chan);
00177     /* Sets the reply_port, region tag, and buffer size for returning
00178      * 16 bit sample data to the host.  The wordCount is the buffer size
00179      * used by the DSP for one transfer to the host.  The host must
00180      * use msg_receive to get this data, and must deallocate the vm
00181      * sent in the out-of-line message.  (The user should implement
00182      * a function that emulates snddriver_reply_handler(), to read the
00183      * reply messages the driver now generates in this, and the above,
00184      * function).  The DSP sends data to the host using the "DMA stream"
00185      * protocol on found on black hardware (i.e. the DSP initiates the
00186      * transfer by sending a $050000|chan to the host, and then follows the
00187      * established handshaking sequence).  This function provides
00188      * a minimal emulation of the snddriver_start_reading function on
00189      * black hardware.  It is efficient since data is mapped in out-of-line
00190      * mach messages, and the data is sent immediately when the DSP
00191      * interrupts (i.e. messages) the host.  Note that the host takes the
00192      * lower two bytes of data transferred, and swaps them, so that the
00193      * returned region contains big-endian short (16 bit) ints.
00194      *
00195      * Note that channel 1 is special: It is buffered, whereas all
00196      * other channels are unbuffered.  Channel 1 requests must be
00197      * a power of 2. 
00198      * All requests must be less than MSG_SIZE_MAX/sizeof(short).
00199      * Channel is between 0 and DSPDRIVER_MAX_TRANSFER_CHAN
00200      */
00201 
00202 extern void dsp_setShortReturn(dsp_id dspId, int regionTag,
00203                                int wordCount, mach_port_t reply_port, 
00204                                int chan);
00205      /* Like dsp_setShortBigEndianReturn(), but little-endian.  */
00206 
00207 
00208 extern void dsp_setLongReturn(dsp_id dspId, int regionTag,
00209                               int wordCount, mach_port_t reply_port, 
00210                                 int chan);
00211      /* Like dsp_setShortReturn(), but for 24-bit numbers, 
00212       * right justified in 32 bits. 
00213       * All requests must be less than MSG_SIZE_MAX/sizeof(long).
00214       * Channel is between 0 and DSPDRIVER_MAX_TRANSFER_CHAN
00215       */
00216 
00217 extern void dsp_freePage(dsp_id dspId, int pageIndex);
00218 /* 
00219  * May be called in a separate thread. Use instead of vm_deallocate() to
00220  * free memory returned by above functions.  pageIndex is a field
00221  * in the message.
00222  */
00223 
00224 extern void dsp_setMsgPort(dsp_id dspId, mach_port_t replyPort);
00225 /* Set port to receive asynchronous DSP messages */
00226 
00227 extern void dsp_setErrorPort(dsp_id dspId, mach_port_t replyPort);
00228 /* Set port to receive asynchronous DSP errors */
00229 
00230 /*** The following are for decoding messages returned via reply ports ***/
00231 
00232 /* Reply mach message IDs. */
00233 #define DSPDRIVER_MSG_WRITE_STARTED            1    
00234 #define DSPDRIVER_MSG_WRITE_COMPLETED          2    
00235 #define DSPDRIVER_MSG_READ_SHORT_COMPLETED     3    
00236 #define DSPDRIVER_MSG_READ_LONG_COMPLETED      4    
00237 #define DSPDRIVER_MSG_READ_BIG_ENDIAN_SHORT_COMPLETED  300 
00238                                         /* Must match SND_MSG_RECORDED_DATA */
00239 #define DSPDRIVER_MSG_RET_DSP_ERR  315  /* Must match SND_MSG_RET_DSP_ERR */
00240 #define DSPDRIVER_MSG_RET_DSP_MSG  316  /* Must match SND_MSG_RET_DSP_MSG */
00241 
00242 /* Mach message typedefs */
00243 typedef struct {
00244     vm_address_t pagePtr;
00245     int regionTag;
00246     boolean_t msgStarted;
00247     boolean_t msgCompleted;
00248     mach_port_t replyPort;
00249 } DSPDRIVEROutputQueueMessage;
00250 
00251 typedef struct {
00252     msg_header_t  h;
00253     msg_type_t    t;
00254     int           regionTag; /* Also used for dsperror and dspmsg codes */
00255 } DSPDRIVERSimpleMessage;
00256 
00257 typedef struct {
00258     msg_header_t  h;
00259     msg_type_t    t1;
00260     int           regionTag;
00261     int           nbytes;
00262     int           pageIndex;
00263     int           chan;
00264     msg_type_t    t2;
00265     void          *data;  /* Either short * or int * */
00266 } DSPDRIVERDataMessage;
00267 
00268 /* 
00269  * The following must be kept in synch with DSPObject.h.
00270  * We can't include DSPObject.h here because we're trying to keep this 
00271  * module independent of libdsp so CLM and others can use it.
00272  */
00273 #ifndef DSPDRIVER_PAR_MONITOR
00274 
00275 /* Parameters of DSPDRIVERs */
00276 #define DSPDRIVER_PAR_MONITOR "Monitor"
00277 #define DSPDRIVER_PAR_MONITOR_4_2 "Monitor_4_2"
00278 #define DSPDRIVER_PAR_SERIALPORTDEVICE "SerialPortDevice"
00279 #define DSPDRIVER_PAR_ORCHESTRA "Orchestra"
00280 #define DSPDRIVER_PAR_WAITSTATES "WaitStates"
00281 #define DSPDRIVER_PAR_SUBUNITS "SubUnits"
00282 #define DSPDRIVER_PAR_CLOCKRATE "ClockRate"
00283 #endif
00284 
00285 #endif
00286