00001 #ifndef __MK_dspdriverAccess_H___ 00002 #define __MK_dspdriverAccess_H___ 00003 /* 00004 $Id: dspdriverAccess.h 489 2000-05-06 02:31:22Z leigh $ 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