![]() |
|
|||
File indexing completed on 2025-05-11 08:23:52
0001 /****************************************************************************** 0002 * 0003 * Copyright (c) 2004 Freescale Semiconductor, Inc. 0004 * 0005 * Permission is hereby granted, free of charge, to any person obtaining a 0006 * copy of this software and associated documentation files (the "Software"), 0007 * to deal in the Software without restriction, including without limitation 0008 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 0009 * and/or sell copies of the Software, and to permit persons to whom the 0010 * Software is furnished to do so, subject to the following conditions: 0011 * 0012 * The above copyright notice and this permission notice shall be included 0013 * in all copies or substantial portions of the Software. 0014 * 0015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 0018 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 0019 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 0020 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 0021 * OTHER DEALINGS IN THE SOFTWARE. 0022 * 0023 ******************************************************************************/ 0024 0025 /*! 0026 * \file bestcomm_api.c 0027 * 0028 * Bestcomm_api.c implements most of the BestComm C API. The 0029 * TaskSetup() function is generated by the BestComm Task API tools 0030 * in capi/task_api/tasksetup_general.h as configured and included by 0031 * code_dma/image_rtos?/task_capi/(*).c. Other functions are defined as 0032 * inline in capi/bestcomm_api.h. 0033 */ 0034 0035 #include <bsp/bestcomm/include/ppctypes.h> 0036 #include <bsp/bestcomm/bestcomm_api.h> 0037 #include <bsp/bestcomm/task_api/bestcomm_cntrl.h> 0038 #include <bsp/bestcomm/task_api/bestcomm_api_mem.h> 0039 #include <bsp/bestcomm/task_api/tasksetup_bdtable.h> 0040 0041 /*********************************************************************** 0042 */ 0043 static const char* const TaskVersionString = "BestComm API v2.2 20041209"; 0044 0045 /* 0046 * Hidden API data per task. 0047 */ 0048 0049 static BDIdx BDHead[MAX_TASKS]; 0050 static BDIdx BDTail[MAX_TASKS]; 0051 0052 /* 0053 * Virtual memory location of the MBAR. System registers and SRAM are 0054 * offset from this address. 0055 */ 0056 uint8 *MBarGlobal; 0057 0058 /* 0059 * Offset from MBarGlobal to get the physical memory address of the 0060 * MBAR. This will be zero for systems that do not use virtual memory in 0061 * their device driver model. 0062 */ 0063 sint64 MBarPhysOffsetGlobal; 0064 0065 /* 0066 * This flag is false when TaskStart() has not yet been called on a 0067 * task newly configured by TaskSetup() or TaskStop() has been called. 0068 * Otherwise it is true. It is possible that a task disabled itself 0069 * (transfer complete or BD ring empty) which will not show up in this 0070 * flag. 0071 * 0072 * It is really only useful for BD tasks that assign buffers (via 0073 * TaskBDAssign()) before TaskStart() or after TaskStop() are called. 0074 */ 0075 int TaskRunning[MAX_TASKS]; 0076 0077 /*! 0078 * \brief Get a string containing API version information. 0079 * \returns Pointer to the API version string 0080 */ 0081 const char *TaskVersion(void) 0082 { 0083 return TaskVersionString; 0084 } 0085 0086 /*! 0087 * \brief Initialize the API. 0088 * \param MBarRef Reference pointer to the device register memory 0089 * map. 0090 * 0091 * \returns TASK_ERR_NO_ERR on successful initialization. 0092 * or TASK_ERR_API_ALREADY_INITIALIZED. 0093 * 0094 * This function is only used with physical addresses. 0095 * 0096 * This function will also initialize API internal variables. The return 0097 * value TASK_ERR_API_ALREADY_INITIALIZED is intended to help determine if 0098 * another process has already instantiated a version of the API. 0099 */ 0100 int TasksInitAPI(uint8 *MBarRef) 0101 { 0102 /* 0103 * Copy pointer of register space to global variable. 0104 * for use by other functions. 0105 */ 0106 MBarGlobal = MBarRef; 0107 0108 /* 0109 * The offset is 0 if physical and virtual are the same. 0110 */ 0111 MBarPhysOffsetGlobal = 0; 0112 0113 /* 0114 * IF API has not been initialized yet then... 0115 * Make sure all BestComm interrupts are disabled and not pending. 0116 * Make sure all tasks are disabled. 0117 * This feature can only be put in after a way has been found to 0118 * communicaticate with other processes. 0119 */ 0120 return TASK_ERR_NO_ERR; 0121 } 0122 0123 /*! 0124 * \brief Initialize the API when virtual memory is used. 0125 * \param MBarRef Reference pointer to the device register memory 0126 * map. 0127 * \param MBarPhys Actual physical location of MBAR device register 0128 * memory map. 0129 * 0130 * \returns TASK_ERR_NO_ERR on successful initialization. 0131 * or TASK_ERR_API_ALREADY_INITIALIZED. 0132 * 0133 * This function allows using virtual memory addresses as well as physical 0134 * addresses. All device registers are offset to the address supplied here, 0135 * so the virtual memory space should include enough space for the entire 0136 * register set of the device to include the SRAM space. 0137 * 0138 * This function will also initialize API internal variables. The return 0139 * value TASK_ERR_API_ALREADY_INITIALIZED is intended to help determine if 0140 * another process has already instantiated a version of the API. 0141 */ 0142 int TasksInitAPI_VM(uint8 *MBarRef, uint8 *MBarPhys) 0143 { 0144 /* 0145 * Copy pointer of register space to global variable. 0146 * for use by other functions. 0147 */ 0148 MBarGlobal = MBarRef; 0149 MBarPhysOffsetGlobal = MBarPhys - MBarRef; 0150 0151 /* 0152 * If API has not been initialized yet then... 0153 * Make sure all BestComm interrupts are disabled and not pending. 0154 * Make sure all tasks are disabled. 0155 * This feature can only be put in after a way has been found to 0156 * communicaticate with other processes. 0157 */ 0158 return TASK_ERR_NO_ERR; 0159 } 0160 0161 /*! 0162 * \brief \em Deprecated 0163 * \param sdma Base address of the BestComm register set 0164 * 0165 * \returns TASK_ERR_NO_ERR 0166 * 0167 * Use of this function is no longer necessary. It is retained for 0168 * compatibility with previous versions of the API. 0169 */ 0170 int TasksAttachImage(sdma_regs *sdma) 0171 { 0172 return TASK_ERR_NO_ERR; 0173 } 0174 0175 /*! 0176 * \brief Start an initialized task running. 0177 * \param taskId Task handle passed back from a successful TaskSetup() 0178 * \param autoStartEnable Boolean for whether autostart bit is enabled. 0179 * If this is set then the parameter autoStartTask 0180 * defines the task to auto start. 0181 * \param autoStartTask TaskId for task to autostart. If autoStartEnable 0182 * is not set then this parameter is a don't care. 0183 * \param intrEnable Boolean for interrupt enable for this task. 0184 * \returns TASK_ERR_NO_ERR on success or TASK_ERR_INVALID_ARG if taskId 0185 * is invalid. 0186 */ 0187 int TaskStart(TaskId taskId, uint32 autoStartEnable, TaskId autoStartTask, 0188 uint32 intrEnable) 0189 { 0190 if (intrEnable) { 0191 SDMA_INT_ENABLE(SDMA_INT_MASK, taskId); 0192 } else { 0193 SDMA_INT_DISABLE(SDMA_INT_MASK, taskId); 0194 } 0195 SDMA_TASK_AUTO_START(SDMA_TCR, taskId, autoStartEnable, autoStartTask) 0196 SDMA_TASK_ENABLE(SDMA_TCR, taskId); 0197 0198 TaskRunning[taskId] = 1; 0199 return TASK_ERR_NO_ERR; 0200 } 0201 0202 /*! 0203 * \brief Stop a running task. 0204 * \param taskId Task handle passed back from a successful TaskSetup() 0205 * \returns TASK_ERR_NO_ERR on success or TASK_ERR_INVALID_ARG if taskId 0206 * is invalid. 0207 * 0208 * \em Note: Stopping a polling buffer descriptor task is a catastrophic 0209 * operation. It does not merely pause execution. Context is not 0210 * saved. The task's pointer into the BD ring is reset back to the 0211 * beginning. 0212 * 0213 * \em Note: This is not the case for the new "fall-through" BD tasks. 0214 * They save the BD ring pointer across stop/start boundaries. The 0215 * previous polling tasks are considered deprecated. 0216 */ 0217 int TaskStop(TaskId taskId) 0218 { 0219 SDMA_INT_DISABLE(SDMA_INT_MASK, taskId); 0220 SDMA_TASK_DISABLE(SDMA_TCR, taskId); 0221 0222 TaskRunning[taskId] = 0; 0223 return TASK_ERR_NO_ERR; 0224 } 0225 0226 /*! 0227 * \brief Assign a buffer to a buffer descriptor. 0228 * \param taskId Task handle passed back from a successful TaskSetup() 0229 * \param buffer0 A buffer to send data from or receive data into a device 0230 * \param buffer1 A second buffer to send data from or receive data into 0231 * a device for use with double-buffer tasks. 0232 * \param size Size of the buffer in bytes. 0233 * \param bdFlags Buffer descriptor flags to set. Used by ethernet BD tasks. 0234 * \returns Handle to the buffer descriptor used by this DMA transfer. 0235 * Error is indicated by a negative return value (see TaskErr_t). 0236 * 0237 * This function is used for both transmit and receive buffer descriptor 0238 * tasks. The buffer may be freed by the TaskBDRelease() function. 0239 * In the case of tasks with a buffer descriptor with two buffer pointers 0240 * this function uses both buffer0 and buffer1 where buffer0 is a source 0241 * and buffer1 is a destination. When the buffer descriptor is a single 0242 * pointer type, the buffer0 is the only pointer used and buffer1 is ignored. 0243 * 0244 * Using this function on non-buffer descriptor tasks will produce 0245 * unpredictable results. 0246 */ 0247 BDIdx TaskBDAssign(TaskId taskId, void *buffer0, void *buffer1, int size, uint32 bdFlags) 0248 { 0249 BDIdx *bdHead; 0250 TaskBD_t *bd; 0251 BDIdx r = TASK_ERR_NO_ERR; 0252 0253 if (TaskBDIdxTable[taskId].currBDInUse == TaskBDIdxTable[taskId].numBD) { 0254 /* 0255 * The buffer ring is full. 0256 */ 0257 r = TASK_ERR_BD_RING_FULL; 0258 0259 } else if ( (TaskBDIdxTable[taskId].apiConfig & API_CONFIG_BD_FLAG) 0260 && ((uint32)size & (uint32)(~SDMA_DRD_MASK_LENGTH))) { 0261 r = TASK_ERR_SIZE_TOO_LARGE; 0262 0263 } else if ( !(TaskBDIdxTable[taskId].apiConfig & API_CONFIG_BD_FLAG) 0264 && ((uint32)size & (uint32)(0xffffffff<<SDMA_BD_BIT_READY))) { 0265 r = TASK_ERR_SIZE_TOO_LARGE; 0266 0267 } else { 0268 bdHead = &BDHead[taskId]; 0269 0270 /* 0271 * Increase Buffer Descriptor in-use variable. 0272 */ 0273 ++TaskBDIdxTable[taskId].currBDInUse; 0274 0275 /* 0276 * Get a generic TaskBD_t pointer to the BD to be assigned. 0277 * Assign the buffer pointers. 0278 */ 0279 bd = TaskBDIdxTable[taskId].BDTablePtr; 0280 if (TaskBDIdxTable[taskId].numPtr == 1) { 0281 bd = (TaskBD_t *)&(((TaskBD1_t *)bd)[*bdHead]); 0282 0283 ((TaskBD1_t *)bd)->DataPtr[0] = (uint32)buffer0; 0284 } else { 0285 bd = (TaskBD_t *)&(((TaskBD2_t *)bd)[*bdHead]); 0286 0287 ((TaskBD2_t *)bd)->DataPtr[0] = (uint32)buffer0; 0288 ((TaskBD2_t *)bd)->DataPtr[1] = (uint32)buffer1; 0289 } 0290 0291 0292 if (bd->Status & SDMA_BD_MASK_READY) { 0293 /* 0294 * This BD is in use. 0295 */ 0296 r = TASK_ERR_BD_BUSY; 0297 0298 } else { 0299 0300 /* 0301 * Set status bits and length. As soon as Status is written, the 0302 * BestComm may perform the transfer. 0303 */ 0304 if (TaskBDIdxTable[taskId].apiConfig & API_CONFIG_BD_FLAG) { 0305 bd->Status = ( ((uint32)SDMA_DRD_MASK_FLAGS & bdFlags) 0306 | ((uint32)SDMA_DRD_MASK_LENGTH & (uint32)size) 0307 | ((uint32)SDMA_BD_MASK_READY)); 0308 } else { 0309 bd->Status = ( ((uint32)SDMA_BD_MASK_SIGN & (uint32)size) 0310 | ((uint32)SDMA_BD_MASK_READY)); 0311 } 0312 0313 /* 0314 * Return the current BD index and increment. 0315 */ 0316 r = *bdHead; 0317 *bdHead = (BDIdx)((*bdHead + 1) % (BDIdx)TaskBDIdxTable[taskId].numBD); 0318 } 0319 } 0320 0321 /* 0322 * Reenable a fall-through BD tasks that might have exited. 0323 */ 0324 if (TaskRunning[taskId]) { 0325 SDMA_TASK_ENABLE(SDMA_TCR, taskId); 0326 } 0327 return r; 0328 } 0329 0330 /*! 0331 * \brief Release last buffer in the buffer descriptor ring. 0332 * \param taskId Task handle passed back from a successful TaskSetup() 0333 * 0334 * \returns Buffer descriptor index of next buffer index that will be released 0335 * by another call of this function. 0336 * TASK_ERR_BD_RING_EMPTY is returned if the ring is already empty. 0337 * 0338 * This function allows the system to reallocate the memory used by 0339 * the buffer. It also cleans up the structure in the BD ring by 0340 * removing the tail buffer in the ring. The buffer descriptor tasks 0341 * are designed around this. Non-BD tasks do not use this function. 0342 * 0343 * Using this function on non-buffer descriptor tasks will produce 0344 * unpredictable results. 0345 */ 0346 BDIdx TaskBDRelease(TaskId taskId) 0347 { 0348 BDIdx *bdTail; 0349 TaskBD_t *bd; 0350 0351 bdTail = &BDTail[taskId]; 0352 0353 if (TaskBDIdxTable[taskId].currBDInUse == 0) { 0354 /* 0355 * Buffer Descriptor ring is empty, Can't Release! 0356 */ 0357 return TASK_ERR_BD_RING_EMPTY; 0358 } 0359 0360 /* 0361 * Get a generic TaskBD_t pointer to the next BD to be released. 0362 */ 0363 bd = TaskGetBD(taskId, *bdTail); 0364 0365 /* 0366 * Verify the ready bit is clear. 0367 */ 0368 if (bd->Status & SDMA_BD_MASK_READY) { 0369 return TASK_ERR_BD_BUSY; 0370 } 0371 0372 /* 0373 * Increment the tail pointer around the ring, decrement in-use. 0374 */ 0375 *bdTail = (BDIdx)((*bdTail + 1) % (BDIdx)TaskBDIdxTable[taskId].numBD); 0376 --TaskBDIdxTable[taskId].currBDInUse; 0377 0378 return *bdTail; 0379 } 0380 0381 0382 /*! 0383 * \brief Release all buffers. 0384 * \param taskId Task handle passed back from a successful TaskSetup() 0385 * 0386 * \returns Buffer descriptor index of next buffer that will be 0387 * assigned by TaskBDAssign() which will also be the first 0388 * released by the next call to TaskBDRelease() or 0389 * TASK_ERR_TASK_RUNNING if the task has not been stopped. 0390 * 0391 * This function is similar to TaskBDRelease() except that it releases 0392 * all assigned buffers including those not yet processed by the BestComm 0393 * task; i.e. SDMA_BD_MASK_READY is set. 0394 * Non-BD tasks do not use this 0395 * function. 0396 * 0397 * The task should not be running. Call TaskStop() first. 0398 * 0399 * \em Note: Partially transmitted buffers are up to the user to handle. 0400 * 0401 * Using this function on non-buffer descriptor tasks will produce 0402 * unpredictable results. 0403 */ 0404 BDIdx TaskBDReset(TaskId taskId) 0405 { 0406 BDIdx i; 0407 TaskBD_t *bd, *bdTab; 0408 0409 if (TaskRunning[taskId]) { 0410 return TASK_ERR_TASK_RUNNING; 0411 } 0412 0413 bdTab = TaskBDIdxTable[taskId].BDTablePtr; 0414 0415 for (i = (BDIdx)TaskBDIdxTable[taskId].numBD - 1; i >= 0; --i) { 0416 0417 if (TaskBDIdxTable[taskId].numPtr == 1) { 0418 bd = (TaskBD_t *)&(((TaskBD1_t *)bdTab)[i]); 0419 } else { 0420 bd = (TaskBD_t *)&(((TaskBD2_t *)bdTab)[i]); 0421 } 0422 0423 bd->Status = 0x0; 0424 } 0425 0426 TaskBDIdxTable[taskId].currBDInUse = 0; 0427 *TaskBDIdxTable[taskId].BDStartPtr = 0428 (volatile uint32)((volatile uint32)TaskBDIdxTable[taskId].BDTablePtr 0429 + MBarPhysOffsetGlobal); 0430 return BDHead[taskId] = BDTail[taskId] = 0; 0431 } 0432 0433 0434 /*! 0435 * \brief Return BestComm debug information. 0436 * \param taskId Task handle passed back from a successful TaskSetup() 0437 * \param paramSet TBD 0438 * \returns TBD 0439 * 0440 * The implementation of this function is yet to be determined. 0441 */ 0442 int TaskDebug(TaskId taskId, TaskDebugParamSet_t *paramSet) 0443 { 0444 if ((taskId < 0) || (taskId >= MAX_TASKS)) { 0445 return TASK_ERR_INVALID_ARG; 0446 } 0447 if (paramSet == NULL) { 0448 return TASK_ERR_INVALID_ARG; 0449 } 0450 0451 return TASK_ERR_NO_ERR; 0452 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |