/**Load the context for a channel to SDMA * * <b>Algorithm:</b>\n * - Send context and poll for answer. * * @param *cd_p channel descriptor for channel 0 * @param *buf pointer to context data * @param channel channel to place the context for * * @return none */ void iapi_lowSetContext(channelDescriptor *cd_p, void *buf, unsigned char channel) { bufferDescriptor *local_bd_p; #ifdef SDMA_SKYE unsigned char command = 0; local_bd_p = (bufferDescriptor *) iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); command = channel << 3; command = command | C0_SETCTX; iapi_SetBufferDescriptor(&local_bd_p[0], command, (unsigned char)(BD_DONE | BD_INTR | BD_WRAP), (unsigned short)(sizeof(contextData) / 4), buf, NULL); #else local_bd_p = (bufferDescriptor *) iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); iapi_SetBufferDescriptor(&local_bd_p[0], C0_SETDM, (unsigned char)(BD_DONE | BD_INTR | BD_WRAP | BD_EXTD), (unsigned short)(sizeof(contextData) / 4), buf, (void *)(2048 + (sizeof(contextData) / 4) * channel)); #endif /* Send */ iapi_lowStartChannel(cd_p->channelNumber); iapi_lowSynchChannel(cd_p->channelNumber); }
/**Load a SDMA script to SDMA * * <b>Algorithm:</b>\n * - Setup BD with appropiate parameters (C0_SETPM) * - Start channel * - Poll for answer * * <b>Notes</b>\b * - Parameter "size" is in bytes, it represents the size of "buf", e.g. * the size in bytes of the script to be uploaded. * - Parameter "address" denotes the RAM address for the script in SDMA * * @param *cd_p channel descriptor for channel 0 * @param *buf pointer to the script * @param size size of the script, in bytes * @param address address in SDMA RAM to place the script * * @return none */ void iapi_lowSetScript(channelDescriptor *cd_p, void *buf, unsigned short size, unsigned long address) { bufferDescriptor *bd_p; bd_p = (bufferDescriptor *) iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); /*Setup buffer descriptor with channel 0 command */ iapi_SetBufferDescriptor(&bd_p[0], C0_SETPM, (unsigned char)(BD_DONE | BD_INTR | BD_WRAP | BD_EXTD), (unsigned short)size / 2, /*count in shorts */ buf, (void *)(address)); /* Receive, polling method */ iapi_lowStartChannel(cd_p->channelNumber); iapi_lowSynchChannel(cd_p->channelNumber); }
/**Load the context data of a channel from SDMA * * <b>Algorithm:</b>\n * - Setup BD with appropiate parameters * - Start channel * - Poll for answer * * @param *cd_p channel descriptor for channel 0 * @param *buf pointer to receive context data * @param channel channel for which the context data is requested * * @return none */ void iapi_lowGetContext(channelDescriptor * cd_p, void * buf, unsigned char channel) { bufferDescriptor * bd_p; bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); /*Setup buffer descriptor with channel 0 command*/ iapi_SetBufferDescriptor(&bd_p[0], C0_GETDM, (unsigned char)(BD_DONE | BD_INTR | BD_WRAP | BD_EXTD), (unsigned short)sizeof(contextData)/4, buf, (void *)(CHANNEL_CONTEXT_BASE_ADDRESS + (sizeof(contextData)*channel/4))); /* Receive, polling method*/ iapi_lowStartChannel(cd_p->channelNumber); iapi_lowSynchChannel(cd_p->channelNumber); }
/**Load the context for a channel to SDMA * * <b>Algorithm:</b>\n * - Send context and poll for answer. * * @param *cd_p channel descriptor for channel 0 * @param *buf pointer to context data * @param channel channel to place the context for * * @return none */ void iapi_lowSetContext(channelDescriptor * cd_p, void * buf, unsigned char channel) { bufferDescriptor * local_bd_p; local_bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); iapi_SetBufferDescriptor( &local_bd_p[0], C0_SETDM, (unsigned char)(BD_DONE | BD_INTR | BD_WRAP|BD_EXTD), (unsigned short)(sizeof(contextData)/4), buf, (void *)(2048+(sizeof(contextData)/4)*channel)); /* Send */ iapi_lowStartChannel( cd_p->channelNumber ); iapi_lowSynchChannel( cd_p->channelNumber ); }
/**Changes channel description information after performing sanity checks. * * <b>Algorithm:</b>\n * - Check channel properties. * - Then modifies the properties of the channel description. * * @param *cd_p channel descriptor of the channel to change * @param whatToChange control code indicating the desired change * @param newval new value * * @return * - IAPI_SUCCESS * - IAPI_FAILURE if change failed * */ int iapi_ChangeChannelDesc(channelDescriptor *cd_p, unsigned char whatToChange, unsigned long newval) { bufferDescriptor *tmpBDptr; unsigned char index = 0; int result = IAPI_SUCCESS; /* verify parameter validity */ if (cd_p == NULL) { result = IAPI_ERR_CD_UNINITIALIZED; iapi_errno = result; return -result; } /* verify channel descriptor initialization */ if (cd_p->ccb_ptr == NULL) { result = IAPI_ERR_CCB_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | cd_p->channelNumber; iapi_errno = result; return -result; } /* verify channel is not in use */ tmpBDptr = (bufferDescriptor *) iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); for (index = cd_p->bufferDescNumber; index > 0; index--) { if (tmpBDptr->mode.status & BD_DONE) { result = IAPI_ERR_CH_IN_USE | IAPI_ERR_CH_AVAILABLE | cd_p->channelNumber; iapi_errno = result; return -result; } tmpBDptr++; } /* Select the change accorded to the selector given in parameter */ switch (whatToChange) { /* * Channel Number */ case IAPI_CHANNELNUMBER: /* Channel number can not be changed (description remains attached) */ result = IAPI_ERR_CD_CHANGE_CH_NUMBER | IAPI_ERR_CH_AVAILABLE | cd_p->channelNumber; iapi_errno = result; return -result; /* * Buffer Descriptor Number */ case IAPI_BUFFERDESCNUMBER: if (newval < MAX_BD_NUM) { if (newval != cd_p->bufferDescNumber) { /* Free memory used for previous old data */ if (cd_p->ccb_ptr->baseBDptr != NULL) { tmpBDptr = (bufferDescriptor *) iapi_Phys2Virt(cd_p-> ccb_ptr->baseBDptr); for (index = 0; index < cd_p->bufferDescNumber; index++) { if (tmpBDptr->bufferAddr != NULL) { if (cd_p->trust == FALSE) { FREE(iapi_Phys2Virt(tmpBDptr->bufferAddr)); } } tmpBDptr++; } FREE((bufferDescriptor *) iapi_Phys2Virt((cd_p-> ccb_ptr)->baseBDptr)); } (cd_p->ccb_ptr)->baseBDptr = NULL; (cd_p->ccb_ptr)->currentBDptr = NULL; /* Allocate and initialize structures */ cd_p->bufferDescNumber = (unsigned char)newval; cd_p->ccb_ptr->status.openedInit = FALSE; if (IAPI_SUCCESS != iapi_InitializeMemory(cd_p->ccb_ptr)) { result = IAPI_ERR_BD_ALLOCATION | cd_p->channelNumber; iapi_errno = result; return -result; } cd_p->ccb_ptr->status.openedInit = TRUE; } break; } else { result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | cd_p->channelNumber; iapi_errno = result; return -result; } /* * Buffer size */ case IAPI_BUFFERSIZE: if (newval < MAX_BD_SIZE) { if (newval != cd_p->bufferSize) { /* Free memory used for previous old data */ if (cd_p->ccb_ptr->baseBDptr != NULL) { tmpBDptr = (bufferDescriptor *) iapi_Phys2Virt(cd_p-> ccb_ptr->baseBDptr); for (index = 0; index < cd_p->bufferDescNumber; index++) { if (cd_p->trust == FALSE) { FREE(iapi_Phys2Virt (tmpBDptr->bufferAddr)); } tmpBDptr++; } FREE((bufferDescriptor *) iapi_Phys2Virt((cd_p-> ccb_ptr)->baseBDptr)); } (cd_p->ccb_ptr)->baseBDptr = NULL; (cd_p->ccb_ptr)->currentBDptr = NULL; /* Allocate and initialize structures */ cd_p->bufferSize = (unsigned short)newval; cd_p->ccb_ptr->status.openedInit = FALSE; if (IAPI_SUCCESS != iapi_InitializeMemory(cd_p->ccb_ptr)) { result = IAPI_ERR_BD_ALLOCATION | cd_p->channelNumber; iapi_errno = result; return -result; } cd_p->ccb_ptr->status.openedInit = TRUE; } break; } else { result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | cd_p->channelNumber; iapi_errno = result; return -result; } /* * Blocking / non blocking feature */ case IAPI_BLOCKING: if (newval < MAX_BLOCKING) { cd_p->blocking = newval; break; } else { result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | cd_p->channelNumber; iapi_errno = result; return -result; } /* * Synchronization method */ case IAPI_CALLBACKSYNCH: if (newval < MAX_SYNCH) { cd_p->callbackSynch = newval; iapi_ChangeCallbackISR(cd_p, cd_p->callbackISR_ptr); break; } else { result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | cd_p->channelNumber; iapi_errno = result; return -result; } /* * Ownership of the channel */ case IAPI_OWNERSHIP: #ifdef DSP result = IAPI_ERR_NOT_ALLOWED | cd_p->channelNumber; iapi_errno = result; return -result; #endif /* DSP */ #ifdef MCU if (newval < MAX_OWNERSHIP) { cd_p->ownership = newval; iapi_ChannelConfig(cd_p->channelNumber, (newval >> CH_OWNSHP_OFFSET_EVT) & 1, (newval >> CH_OWNSHP_OFFSET_MCU) & 1, (newval >> CH_OWNSHP_OFFSET_DSP) & 1); break; } else {