/* * dsp_dma_stream - Example of streaming into and out of the DSP using DMA * in both directions. This is very similar to dsp_example_3. In fact, the * stream from the DSP is identical even though it has a different name. */ #import #import #import #import #import #import "sd_error.h" /* should be */ #define DATA_SIZE (32*1024) /* The following must agree with dsp_dma_stream.asm */ #define DSP_DMA_BUFFER_SIZE 2048 /* 16-bit words */ #define READ_TAG 1 #define WRITE_TAG 2 #define FLUSH_TAG 3 #define VIEW_SIZE 4 static port_t cmd_port; static int done = 0; static unsigned short *read_data; static int bytes_read; static port_t reply_port, write_port; static int sd_err; static void write_completed(void *arg, int tag) /* Called when the input to the DSP has been written. */ { printf("write done.\n"); } static void read_completed(void *arg, int tag, void *p, int nbytes) /* This gets called when the entire result array has been read from the DSP. */ { if (tag == READ_TAG) { read_data = (unsigned short *)p; printf("read done\n"); bytes_read = nbytes; done++; } } main (int argc, char *argv[]) { int i, j, s_err, size, protocol; kern_return_t k_err; port_t dev_port=0, owner_port=0, temp_port, read_port; SNDSoundStruct *dspStruct; snddriver_handlers_t handlers = { 0, 0, 0, write_completed, 0, 0, 0, 0, read_completed}; msg_header_t *reply_msg; int low_water = 48*1024; int high_water = 64*1024; int read_width = 2; /* bytes per sample */ int read_buf_size = DSP_DMA_BUFFER_SIZE; unsigned short *write_data; int write_count; int read_count; int write_width = 2; /* bytes per sample */ int write_buf_size = DSP_DMA_BUFFER_SIZE; int dsp_scale_factor = 0x400000; /* 1/2 in DSP number format */ // // initialize input buffer with some arbitrary but known data // write_count = DATA_SIZE+DSP_DMA_BUFFER_SIZE; read_count = DATA_SIZE; /* vm_allocate() always grabs whole pages. We need the alignment. */ vm_allocate(task_self(),(vm_address_t *)(&write_data), write_count*write_width,TRUE); srand(time(0)); for (i=0; imsg_size = MSG_SIZE_MAX; reply_msg->msg_local_port = reply_port; k_err = msg_receive(reply_msg, MSG_OPTION_NONE, 0); if (k_err != KERN_SUCCESS) { mach_error("Cannot receive message from DSP", k_err); exit(1); } // // dispatch to the appropriate handler // sd_err = snddriver_reply_handler(reply_msg,&handlers); if (sd_err != 0) { sd_error("Cannot parse message from DSP", sd_err); exit(1); } } // // print first few elements of result // for (i=0; i> 1)) { printf("*** output[%d] = 0x%x but expected 0x%x.\n", i,read_data[i],write_data[i]>>1); if(j++ > 10) { printf(" . . . \n"); exit(1); } } printf("Data received from DSP is correct.\n"); // // Data received in the read_handler should be deallocated // vm_deallocate(task_self(),(pointer_t)read_data,bytes_read); exit(0); }