Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:52

0001 #ifndef __BESTCOMM_API_H
0002 #define __BESTCOMM_API_H 1
0003 
0004 /******************************************************************************
0005 *
0006 * Copyright (c) 2004 Freescale Semiconductor, Inc.
0007 *
0008 * Permission is hereby granted, free of charge, to any person obtaining a
0009 * copy of this software and associated documentation files (the "Software"),
0010 * to deal in the Software without restriction, including without limitation
0011 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0012 * and/or sell copies of the Software, and to permit persons to whom the
0013 * Software is furnished to do so, subject to the following conditions:
0014 *
0015 * The above copyright notice and this permission notice shall be included
0016 * in all copies or substantial portions of the Software.
0017 *
0018 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0019 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0020 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
0021 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
0022 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0023 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0024 * OTHER DEALINGS IN THE SOFTWARE.
0025 *
0026 ******************************************************************************/
0027 
0028 /*!
0029  * \file    bestcomm_api.h
0030  *
0031  * Bestcomm_api.h is the only header necessary for inclusion by user
0032  * code. The include path the C compiler searches to find .h files
0033  * should contain bestcomm/capi and one of bestcomm/code_dma/image_*.
0034  * This second entry selects which set of BestComm tasks will be used.
0035  * Of course the appropriate files in image_* must also be compiled and
0036  * linked.
0037  */
0038 
0039 #include <rtems.h>
0040 
0041 #include "include/ppctypes.h"
0042 #include "include/mgt5200/sdma.h"
0043 #include "task_api/tasksetup_bdtable.h"
0044 #include "task_api/bestcomm_cntrl.h"
0045 #include "task_api/bestcomm_api_mem.h"
0046 
0047 #ifdef __cplusplus
0048 extern "C" {
0049 #endif /* __cplusplus */
0050 
0051 /*!
0052  * \brief   TaskSetup() debugging
0053  *
0054  * Define this macro as follows for debugging printf()s to see
0055  * what the API receives and sets from the TaskSetupParamSet_t
0056  * struct. Implemented in capi/task_api/tasksetup_general.h.
0057  *
0058  * \verbatim
0059  * >0  : print basic debug messages
0060  * >=10: also print C-API interface variables
0061  * >=20: also print task API interface variables
0062  * else: do nothing
0063  * \endverbatim
0064  */
0065 #define DEBUG_BESTCOMM_API 0
0066 
0067 /*!
0068  * \brief   Maximum number of tasks in the system.
0069  * This number is hardware-dependent and not user configuration.
0070  */
0071 #define MAX_TASKS 16
0072 
0073 /*
0074  * This may need to be removed in certain implementations.
0075  */
0076 #ifndef NULL
0077 # define NULL ((void *)0)
0078 #endif  /* NULL */
0079 
0080 typedef sint8 TaskId;
0081 typedef sint32 BDIdx;
0082 
0083 /*
0084  * Special "task IDs" for interrupt handling API functions
0085  */
0086 /*! \brief  Debug interrupt "task ID" */
0087 #define DEBUG_INTR_ID   SDMA_INT_BIT_DBG
0088 
0089 /*! \brief  TEA interrupt "task ID" */
0090 #define TEA_INTR_ID     SDMA_INT_BIT_TEA
0091 
0092 /*! \brief  Task start autostart enable */
0093 #define TASK_AUTOSTART_ENABLE   1
0094 
0095 /*! \brief  Task start autostart disable */
0096 #define TASK_AUTOSTART_DISABLE  0
0097 
0098 /*! \brief  Task start interrupt enable */
0099 #define TASK_INTERRUPT_ENABLE   1
0100 
0101 /*! \brief  Task start interrupt disable */
0102 #define TASK_INTERRUPT_DISABLE  0
0103 
0104 /*
0105  * Buffer descriptor flags to pass to TaskBDAssign().
0106  */
0107 /*! \brief  Transmit frame done */
0108 #define TASK_BD_TFD (1 << SDMA_DRD_BIT_TFD)
0109 
0110 /*! \brief  Interrupt on frame done */
0111 #define TASK_BD_INT (1 << SDMA_DRD_BIT_INT)
0112 
0113 /*!
0114  * \brief   Data transfer size
0115  */
0116 typedef enum {
0117     SZ_FLEX     = 3,    /*!< invalid for TaskSetupParamSet_t */
0118     SZ_UINT8    = 1,    /*!< 1-byte */
0119     SZ_UINT16   = 2,    /*!< 2-byte */
0120     SZ_UINT32   = 4     /*!< 4-byte */
0121 } Sz_t;
0122 
0123 /*!
0124  * \brief   API error codes
0125  */
0126 typedef enum {
0127     TASK_ERR_NO_ERR         = -1,   /*!< No error                   */
0128     TASK_ERR_NO_INTR        = TASK_ERR_NO_ERR,
0129                                     /*!< No interrupt               */
0130     TASK_ERR_INVALID_ARG    = -2,   /*!< Invalid function argument  */
0131     TASK_ERR_BD_RING_FULL   = -3,   /*!< Buffer descriptor ring full*/
0132     TASK_ERR_API_ALREADY_INITIALIZED
0133                             = -4,   /*!< API has already been initialized */
0134     TASK_ERR_SIZE_TOO_LARGE = -5,   /*!< Buffer descriptor cannot support size parameter */
0135     TASK_ERR_BD_RING_EMPTY  = -6,   /*!< Buffer descriptor ring is empty*/
0136     TASK_ERR_BD_BUSY        = -7,   /*!< The buffer descriptor is in use
0137                                          by the BestComm            */
0138     TASK_ERR_TASK_RUNNING   = -8    /*!< The task is running.       */
0139 
0140 } TaskErr_t;
0141 
0142 /*!
0143  * \brief   BestComm initiators
0144  *
0145  * These are assigned by TaskSetup().
0146  */
0147 typedef enum {
0148 
0149     INITIATOR_ALWAYS    =  0,
0150     INITIATOR_SCTMR_0   =  1,
0151     INITIATOR_SCTMR_1   =  2,
0152     INITIATOR_FEC_RX    =  3,
0153     INITIATOR_FEC_TX    =  4,
0154     INITIATOR_ATA_RX    =  5,
0155     INITIATOR_ATA_TX    =  6,
0156     INITIATOR_SCPCI_RX  =  7,
0157     INITIATOR_SCPCI_TX  =  8,
0158     INITIATOR_PSC3_RX   =  9,
0159     INITIATOR_PSC3_TX   = 10,
0160     INITIATOR_PSC2_RX   = 11,
0161     INITIATOR_PSC2_TX   = 12,
0162     INITIATOR_PSC1_RX   = 13,
0163     INITIATOR_PSC1_TX   = 14,
0164     INITIATOR_SCTMR_2   = 15,
0165 
0166     INITIATOR_SCLPC     = 16,
0167     INITIATOR_PSC5_RX   = 17,
0168     INITIATOR_PSC5_TX   = 18,
0169     INITIATOR_PSC4_RX   = 19,
0170     INITIATOR_PSC4_TX   = 20,
0171     INITIATOR_I2C2_RX   = 21,
0172     INITIATOR_I2C2_TX   = 22,
0173     INITIATOR_I2C1_RX   = 23,
0174     INITIATOR_I2C1_TX   = 24,
0175     INITIATOR_PSC6_RX   = 25,
0176     INITIATOR_PSC6_TX   = 26,
0177     INITIATOR_IRDA_RX   = 25,
0178     INITIATOR_IRDA_TX   = 26,
0179     INITIATOR_SCTMR_3   = 27,
0180     INITIATOR_SCTMR_4   = 28,
0181     INITIATOR_SCTMR_5   = 29,
0182     INITIATOR_SCTMR_6   = 30,
0183     INITIATOR_SCTMR_7   = 31
0184 
0185 } MPC5200Initiator_t;
0186 
0187 /*!
0188  * \brief   Parameters for TaskSetup()
0189  *
0190  * All parameters can be hard-coded by the task API. Hard-coded values
0191  * will be changed in the struct passed to TaskSetup() for the user to
0192  * examine later.
0193  */
0194 typedef struct {
0195     uint32  NumBD;          /*!< Number of buffer descriptors               */
0196 
0197     union {
0198        uint32 MaxBuf;       /*!< Maximum buffer size                        */
0199        uint32 NumBytes;     /*!< Number of bytes to transfer                */
0200     } Size;                 /*!< Buffer size union for BD and non-BD tasks  */
0201 
0202     MPC5200Initiator_t
0203             Initiator;      /*!< BestComm initiator (ignored if hard-wired) */
0204     uint32  StartAddrSrc;   /*!< Address of the DMA source (e.g. a FIFO)    */
0205     sint16  IncrSrc;        /*!< Amount to increment source pointer         */
0206     Sz_t    SzSrc;          /*!< Size of source data access                 */
0207     uint32  StartAddrDst;   /*!< Address of the DMA destination (e.g. a FIFO) */
0208     sint16  IncrDst;        /*!< Amount to increment data pointer           */
0209     Sz_t    SzDst;          /*!< Size of destination data access            */
0210 } TaskSetupParamSet_t;
0211 
0212 /*!
0213  * \brief   Parameters for TaskDebug()
0214  *
0215  * TaskDebug() and the contents of this data structure are yet to be
0216  * determined.
0217  */
0218 typedef struct {
0219     int dummy;              /* Some compilers don't like empty struct typedefs */
0220 } TaskDebugParamSet_t;
0221 
0222 /*!
0223  * \brief   Generic buffer descriptor.
0224  *
0225  * It is generally used as a pointer which should be cast to one of the
0226  * other BD types based on the number of buffers per descriptor.
0227  */
0228 typedef struct {
0229     uint32 Status;          /*!< Status and length bits     */
0230 } TaskBD_t;
0231 
0232 /*!
0233  * \brief   Single buffer descriptor.
0234  */
0235 typedef struct {
0236     uint32 Status;          /*!< Status and length bits     */
0237     uint32 DataPtr[1];      /*!< Pointer to data buffer     */
0238 } TaskBD1_t;
0239 
0240 /*!
0241  * \brief   Dual buffer descriptor.
0242  */
0243 typedef struct {
0244     uint32 Status;          /*!< Status and length bits     */
0245     uint32 DataPtr[2];      /*!< Pointer to data buffers    */
0246 } TaskBD2_t;
0247 
0248 
0249 
0250 /***************************
0251  * Start of API Prototypes
0252  ***************************/
0253 
0254 #include "bestcomm_priv.h"
0255 #include "dma_image.capi.h"
0256 
0257 /*!
0258  * \brief   Initialize a single task.
0259  * \param   TaskName    Type of task to initialize. E.g. PCI transmit,
0260  *                      ethernet receive, general purpose dual-pointer.
0261  *                      Values expected can be found in the TaskName_t
0262  *                      enum defined in dma_image.capi.h.
0263  * \param   TaskSetupParams Task-specific parameters. The user must fill out
0264  *                      the pertinent parts of a TaskSetupParamSet_t
0265  *                      data structure.
0266  * \returns TaskId task identification token which is a required
0267  *          parameter for most other API functions.
0268  *
0269  * This function returns a task identification token which is a required
0270  * parameter for most other API functions.
0271  *
0272  * Certain values of the structure pointed to by TaskParams are set
0273  * as a side-effect based on task type. These may be examined after
0274  * a successful call to TaskSetup(). User-specified values may be
0275  * overridden.
0276  *
0277  * TaskId TaskSetup( TaskName_t TaskName,
0278  *                   TaskSetupParamSet_t *TaskSetupParams );
0279  */
0280 #define         TaskSetupHelper(TaskName, TaskSetupParams)  \
0281                 TaskSetup_ ## TaskName (TaskName ## _api, TaskSetupParams)
0282 #define         TaskSetup(TaskName, TaskSetupParams) \
0283                 TaskSetupHelper(TaskName, TaskSetupParams)
0284 
0285 const char      *TaskVersion(void);
0286 
0287 int             TasksInitAPI(uint8 *MBarRef);
0288 
0289 int             TasksInitAPI_VM(uint8 *MBarRef, uint8 *MBarPhys);
0290 
0291 void            TasksLoadImage(sdma_regs *sdma);
0292 int             TasksAttachImage(sdma_regs *sdma);
0293 
0294 int             TaskStart(TaskId taskId, uint32 autoStartEnable,
0295                           TaskId autoStartTask, uint32 intrEnable);
0296 int             TaskStop(TaskId taskId);
0297 static int      TaskStatus(TaskId taskId);
0298 BDIdx           TaskBDAssign(TaskId taskId, void *buffer0, void *buffer1,
0299                              int size, uint32 bdFlags);
0300 BDIdx           TaskBDRelease(TaskId taskId);
0301 BDIdx           TaskBDReset(TaskId taskId);
0302 static TaskBD_t *TaskGetBD(TaskId taskId, BDIdx bd);
0303 static TaskBD_t *TaskGetBDRing(TaskId taskId);
0304 int             TaskDebug(TaskId taskId, TaskDebugParamSet_t *paramSet);
0305 static int      TaskIntClear(TaskId taskId);
0306 static TaskId   TaskIntStatus(TaskId taskId);
0307 static int      TaskIntPending(TaskId taskId);
0308 static TaskId   TaskIntSource(void);
0309 static uint16   TaskBDInUse(TaskId taskId);
0310 
0311 
0312 /*!
0313  * \brief   Get the enable/disable status of a task.
0314  * \param   taskId  Task handle passed back from a successful TaskSetup()
0315  * \returns Boolean true indicates enabled or false indicates disabled
0316  *          or invalid taskId.
0317  */
0318 static inline int TaskStatus(TaskId taskId)
0319 {
0320     return SDMA_TASK_STATUS(SDMA_TCR, taskId) & 0x8000;
0321 }
0322 
0323 /*!
0324  * \brief   Return a pointer to a buffer descriptor at index BDIdx
0325  * \param   taskId  Task handle passed back from a successful TaskSetup()
0326  * \param   bd      Buffer descriptor handle returned by
0327  *                  TaskBDAssign() or TaskBDRelease().
0328  * \returns Pointer to the requested buffer descriptor or NULL on error.
0329  *
0330  * The returned pointer should be cast to the appropriate buffer
0331  * descriptor type, TaskBD1_t or TaskBD2_t.
0332  */
0333 static inline TaskBD_t *TaskGetBD(TaskId taskId, BDIdx bd)
0334 {
0335     void *bdTab;
0336 
0337     bdTab = TaskBDIdxTable[taskId].BDTablePtr;
0338     if (TaskBDIdxTable[taskId].numPtr == 1) {
0339         return (TaskBD_t *)&(((TaskBD1_t *)bdTab)[bd]);
0340     } else {
0341         return (TaskBD_t *)&(((TaskBD2_t *)bdTab)[bd]);
0342     }
0343 }
0344 
0345 /*!
0346  * \brief   Return a pointer to the first buffer descriptor in the ring.
0347  * \param   taskId  Task handle passed back from a successful TaskSetup()
0348  * \returns Pointer to the array of buffer descriptors making up the
0349  *          ring or NULL on error.
0350  *
0351  * A device driver author may choose to use this in lieu of
0352  * TaskBDAssign()/TaskBDRelease() to get direct access to the
0353  * BD ring with the warning that the underlying data structure may change.
0354  * Use at one's own discretion.
0355  */
0356 static inline TaskBD_t *TaskGetBDRing(TaskId taskId)
0357 {
0358     return (TaskBD_t *) TaskBDIdxTable[taskId].BDTablePtr;
0359 }
0360 
0361 /*!
0362  * \brief   Clear the interrupt for a given BestComm task.
0363  * \param   taskId  Task handle passed back from a successful TaskSetup()
0364  * \returns TASK_ERR_NO_ERR (which is not really an error) for success
0365  */
0366 static inline int TaskIntClear(TaskId taskId)
0367 {
0368     SDMA_CLEAR_IEVENT(SDMA_INT_PEND, taskId);
0369     return TASK_ERR_NO_ERR; /* success */
0370 }
0371 
0372 /*!
0373  * \brief   Get the interrupt status for a given task.
0374  * \param   taskId  Task handle passed back from a successful TaskSetup()
0375  * \returns TASK_ERR_NO_INTR (which is not really an error) for no interrupt
0376  *          pending, taskId for a regular interrupt, DEBUG_INTR_ID for
0377  *          a debug interrupt and TEA_INTR_ID for a TEA interrupt.
0378  *          \b Note: TaskIntStatus() may return 0, but this means that that
0379  *          taskId 0 is interrupt pending.
0380  */
0381 static inline TaskId TaskIntStatus(TaskId taskId)
0382 {
0383     uint32 pending;
0384 
0385     pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK);
0386 
0387     if (SDMA_INT_TEST(pending, taskId)) {
0388         return taskId;
0389     } else if (SDMA_INT_TEST(pending, DEBUG_INTR_ID)) {
0390         return DEBUG_INTR_ID;
0391     } else if (SDMA_INT_TEST(pending, TEA_INTR_ID)) {
0392         return TEA_INTR_ID;
0393     }
0394 
0395     return TASK_ERR_NO_INTR;
0396 }
0397 
0398 /*!
0399  * \brief   Get the interrupt pending status for a given task.
0400  * \param   taskId  Task handle passed back from a successful TaskSetup()
0401  * \returns 0 if task does not have a pending interrupt. 1 if the task
0402  *          has an interrupt pending.
0403  */
0404 static inline int TaskIntPending(TaskId taskId)
0405 {
0406     uint32 pending;
0407 
0408     pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK);
0409     if (SDMA_INT_TEST(pending, taskId)) {
0410         return 1;
0411     } else {
0412         return 0;
0413     }
0414 }
0415 
0416 /*!
0417  * \brief   Returns the task ID of an interrupting BestComm task.
0418  * \returns TASK_ERR_NO_INTR (which is not really an error) for no interrupt
0419  *          pending or the taskId of the interrupting task.
0420  *
0421  * The user must query TaskIntStatus() to discover if this is a debug
0422  * or TEA interrupt. This function is designed for use by an operating
0423  * system interrupt handler.
0424  */
0425 static inline TaskId TaskIntSource(void)
0426 {
0427     uint32 pending;
0428     uint32 mask = 1 << (MAX_TASKS - 1);
0429     TaskId i;
0430 
0431     pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK);
0432 
0433     if (SDMA_INT_TEST(pending, SDMA_INT_BIT_TEA)) {
0434         return (TaskId)SDMA_TEA_SOURCE(SDMA_INT_PEND);
0435     }
0436 
0437     for (i = (MAX_TASKS - 1); i >= 0; --i, mask >>= 1) {
0438         if (pending & mask) {
0439             return i;
0440         }
0441     }
0442 
0443     return TASK_ERR_NO_INTR;
0444 }
0445 
0446 /*!
0447  * \brief   Get a count of in-use buffer descriptors.
0448  * \param   taskId  Task handle passed back from a successful TaskSetup()
0449  * \returns Count of the current number of BDs in use by the given task.
0450  */
0451 static inline uint16 TaskBDInUse(TaskId taskId)
0452 {
0453     return TaskBDIdxTable[taskId].currBDInUse;
0454 }
0455 
0456 #ifdef __cplusplus
0457 }
0458 #endif /* __cplusplus */
0459 
0460 #endif  /* __BESTCOMM_API_H */