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