/*! * \brief Start an initialized task running. * \param taskId Task handle passed back from a successful TaskSetup() * \param autoStartEnable Boolean for whether autostart bit is enabled. * If this is set then the parameter autoStartTask * defines the task to auto start. * \param autoStartTask TaskId for task to autostart. If autoStartEnable * is not set then this parameter is a don't care. * \param intrEnable Boolean for interrupt enable for this task. * \returns TASK_ERR_NO_ERR on success or TASK_ERR_INVALID_ARG if taskId * is invalid. */ int TaskStart(TaskId taskId, uint32 autoStartEnable, TaskId autoStartTask, uint32 intrEnable) { if (intrEnable) { SDMA_INT_ENABLE(SDMA_INT_MASK, taskId); } else { SDMA_INT_DISABLE(SDMA_INT_MASK, taskId); } SDMA_TASK_AUTO_START(SDMA_TCR, taskId, autoStartEnable, autoStartTask) SDMA_TASK_ENABLE(SDMA_TCR, taskId); TaskRunning[taskId] = 1; return TASK_ERR_NO_ERR; }
/*! * \brief Start an initialized task running. * \param taskId Task handle passed back from a successful TaskSetup() * \param autoStartEnable Boolean for whether autostart bit is enabled. * If this is set then the parameter autoStartTask * defines the task to auto start. * \param autoStartTask TaskId for task to autostart. If autoStartEnable * is not set then this parameter is a don't care. * \param intrEnable Boolean for interrupt enable for this task. * \returns TASK_ERR_NO_ERR on success or TASK_ERR_INVALID_ARG if taskId * is invalid. */ int TaskStart( TaskId taskId, uint32 autoStartEnable, TaskId autoStartTask, uint32 intrEnable ) { if( (0 <= taskId) && (taskId < MAX_TASKS) ) { if ( intrEnable ) { SDMA_INT_ENABLE( SDMA_INT_MASK, taskId ); } else { SDMA_INT_DISABLE( SDMA_INT_MASK, taskId ); } SDMA_TASK_AUTO_START(SDMA_TCR, taskId, autoStartEnable, autoStartTask) SDMA_TASK_ENABLE( SDMA_TCR, taskId ); return TASK_ERR_NO_ERR; } else { return TASK_ERR_INVALID_ARG; } }
static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, volatile FEC_RBD * pRbd) { /* * Reset buffer descriptor as empty */ if ((fec->rbdIndex) == (FEC_RBD_NUM - 1)) pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY); else pRbd->status = FEC_RBD_EMPTY; pRbd->dataLength = 0; /* * Now, we have an empty RxBD, restart the SmartDMA receive task */ SDMA_TASK_ENABLE(FEC_RECV_TASK_NO); /* * Increment BD count */ fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM; }
/*! * \brief Assign a buffer to a buffer descriptor. * \param taskId Task handle passed back from a successful TaskSetup() * \param buffer0 A buffer to send data from or receive data into a device * \param buffer1 A second buffer to send data from or receive data into * a device for use with double-buffer tasks. * \param size Size of the buffer in bytes. * \param bdFlags Buffer descriptor flags to set. Used by ethernet BD tasks. * \returns Handle to the buffer descriptor used by this DMA transfer. * Error is indicated by a negative return value (see TaskErr_t). * * This function is used for both transmit and receive buffer descriptor * tasks. The buffer may be freed by the TaskBDRelease() function. * In the case of tasks with a buffer descriptor with two buffer pointers * this function uses both buffer0 and buffer1 where buffer0 is a source * and buffer1 is a destination. When the buffer descriptor is a single * pointer type, the buffer0 is the only pointer used and buffer1 is ignored. * * Using this function on non-buffer descriptor tasks will produce * unpredictable results. */ BDIdx TaskBDAssign(TaskId taskId, void *buffer0, void *buffer1, int size, uint32 bdFlags) { BDIdx *bdHead; TaskBD_t *bd; BDIdx r = TASK_ERR_NO_ERR; if (TaskBDIdxTable[taskId].currBDInUse == TaskBDIdxTable[taskId].numBD) { /* * The buffer ring is full. */ r = TASK_ERR_BD_RING_FULL; } else if ( (TaskBDIdxTable[taskId].apiConfig & API_CONFIG_BD_FLAG) && ((uint32)size & (uint32)(~SDMA_DRD_MASK_LENGTH))) { r = TASK_ERR_SIZE_TOO_LARGE; } else if ( !(TaskBDIdxTable[taskId].apiConfig & API_CONFIG_BD_FLAG) && ((uint32)size & (uint32)(0xffffffff<<SDMA_BD_BIT_READY))) { r = TASK_ERR_SIZE_TOO_LARGE; } else { bdHead = &BDHead[taskId]; /* * Increase Buffer Descriptor in-use variable. */ ++TaskBDIdxTable[taskId].currBDInUse; /* * Get a generic TaskBD_t pointer to the BD to be assigned. * Assign the buffer pointers. */ bd = TaskBDIdxTable[taskId].BDTablePtr; if (TaskBDIdxTable[taskId].numPtr == 1) { bd = (TaskBD_t *)&(((TaskBD1_t *)bd)[*bdHead]); ((TaskBD1_t *)bd)->DataPtr[0] = (uint32)buffer0; } else { bd = (TaskBD_t *)&(((TaskBD2_t *)bd)[*bdHead]); ((TaskBD2_t *)bd)->DataPtr[0] = (uint32)buffer0; ((TaskBD2_t *)bd)->DataPtr[1] = (uint32)buffer1; } if (bd->Status & SDMA_BD_MASK_READY) { /* * This BD is in use. */ r = TASK_ERR_BD_BUSY; } else { /* * Set status bits and length. As soon as Status is written, the * BestComm may perform the transfer. */ if (TaskBDIdxTable[taskId].apiConfig & API_CONFIG_BD_FLAG) { bd->Status = ( ((uint32)SDMA_DRD_MASK_FLAGS & bdFlags) | ((uint32)SDMA_DRD_MASK_LENGTH & (uint32)size) | ((uint32)SDMA_BD_MASK_READY)); } else { bd->Status = ( ((uint32)SDMA_BD_MASK_SIGN & (uint32)size) | ((uint32)SDMA_BD_MASK_READY)); } /* * Return the current BD index and increment. */ r = *bdHead; *bdHead = (BDIdx)((*bdHead + 1) % (BDIdx)TaskBDIdxTable[taskId].numBD); } } /* * Reenable a fall-through BD tasks that might have exited. */ if (TaskRunning[taskId]) { SDMA_TASK_ENABLE(SDMA_TCR, taskId); } return r; }