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