📄 bestcomm_api.c
字号:
TaskRunning[taskId] = 1;
return TASK_ERR_NO_ERR;
}
/*!
* \brief Stop a running task.
* \param taskId Task handle passed back from a successful TaskSetup()
* \returns TASK_ERR_NO_ERR on success or TASK_ERR_INVALID_ARG if taskId
* is invalid.
*
* \em Note: Stopping a polling buffer descriptor task is a catastrophic
* operation. It does not merely pause execution. Context is not
* saved. The task's pointer into the BD ring is reset back to the
* beginning.
*
* \em Note: This is not the case for the new "fall-through" BD tasks.
* They save the BD ring pointer across stop/start boundaries. The
* previous polling tasks are considered deprecated.
*/
int TaskStop(TaskId taskId)
{
SDMA_INT_DISABLE(SDMA_INT_MASK, taskId);
SDMA_TASK_DISABLE(SDMA_TCR, taskId);
TaskRunning[taskId] = 0;
return TASK_ERR_NO_ERR;
}
/*!
* \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;
}
/*!
* \brief Release last buffer in the buffer descriptor ring.
* \param taskId Task handle passed back from a successful TaskSetup()
*
* \returns Buffer descriptor index of next buffer index that will be released
* by another call of this function.
* TASK_ERR_BD_RING_EMPTY is returned if the ring is already empty.
*
* This function allows the system to reallocate the memory used by
* the buffer. It also cleans up the structure in the BD ring by
* removing the tail buffer in the ring. The buffer descriptor tasks
* are designed around this. Non-BD tasks do not use this function.
*
* Using this function on non-buffer descriptor tasks will produce
* unpredictable results.
*/
BDIdx TaskBDRelease(TaskId taskId)
{
BDIdx *bdTail;
TaskBD_t *bd;
bdTail = &BDTail[taskId];
if (TaskBDIdxTable[taskId].currBDInUse == 0) {
/*
* Buffer Descriptor ring is empty, Can't Release!
*/
return TASK_ERR_BD_RING_EMPTY;
}
/*
* Get a generic TaskBD_t pointer to the next BD to be released.
*/
bd = TaskGetBD(taskId, *bdTail);
/*
* Verify the ready bit is clear.
*/
if (bd->Status & SDMA_BD_MASK_READY) {
return TASK_ERR_BD_BUSY;
}
/*
* Increment the tail pointer around the ring, decrement in-use.
*/
*bdTail = (BDIdx)((*bdTail + 1) % (BDIdx)TaskBDIdxTable[taskId].numBD);
--TaskBDIdxTable[taskId].currBDInUse;
return *bdTail;
}
/*!
* \brief Release all buffers.
* \param taskId Task handle passed back from a successful TaskSetup()
*
* \returns Buffer descriptor index of next buffer that will be
* assigned by TaskBDAssign() which will also be the first
* released by the next call to TaskBDRelease() or
* TASK_ERR_TASK_RUNNING if the task has not been stopped.
*
* This function is similar to TaskBDRelease() except that it releases
* all assigned buffers including those not yet processed by the BestComm
* task; i.e. SDMA_BD_MASK_READY is set.
* Non-BD tasks do not use this
* function.
*
* The task should not be running. Call TaskStop() first.
*
* \em Note: Partially transmitted buffers are up to the user to handle.
*
* Using this function on non-buffer descriptor tasks will produce
* unpredictable results.
*/
BDIdx TaskBDReset(TaskId taskId)
{
BDIdx i;
TaskBD_t *bd, *bdTab;
if (TaskRunning[taskId]) {
return TASK_ERR_TASK_RUNNING;
}
bdTab = TaskBDIdxTable[taskId].BDTablePtr;
for (i = (BDIdx)TaskBDIdxTable[taskId].numBD - 1; i >= 0; --i) {
if (TaskBDIdxTable[taskId].numPtr == 1) {
bd = (TaskBD_t *)&(((TaskBD1_t *)bdTab)[i]);
} else {
bd = (TaskBD_t *)&(((TaskBD2_t *)bdTab)[i]);
}
bd->Status = 0x0;
}
TaskBDIdxTable[taskId].currBDInUse = 0;
*TaskBDIdxTable[taskId].BDStartPtr =
(volatile uint32)((volatile uint32)TaskBDIdxTable[taskId].BDTablePtr
+ MBarPhysOffsetGlobal);
return BDHead[taskId] = BDTail[taskId] = 0;
}
/*!
* \brief Return BestComm debug information.
* \param taskId Task handle passed back from a successful TaskSetup()
* \param paramSet TBD
* \returns TBD
*
* The implementation of this function is yet to be determined.
*/
int TaskDebug(TaskId taskId, TaskDebugParamSet_t *paramSet)
{
if ((taskId < 0) || (taskId >= MAX_TASKS)) {
return TASK_ERR_INVALID_ARG;
}
if (paramSet == NULL) {
return TASK_ERR_INVALID_ARG;
}
return TASK_ERR_NO_ERR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -