CC2640外设的object &HWAttrs & fxn & config

来源:互联网 发布:赛睿淘宝旗舰店 编辑:程序博客网 时间:2024/05/21 22:25

在cc2640的board相关的文件中,经常会看到如下的配置:

/* SPI objects */SPICC26XXDMA_Object spiCC26XXDMAObjects[CC2650_LAUNCHXL_SPICOUNT];/* SPI configuration structure, describing which pins are to be used */const SPICC26XXDMA_HWAttrsV1 spiCC26XXDMAHWAttrs[CC2650_LAUNCHXL_SPICOUNT] = {    {        .baseAddr           = SSI0_BASE,        .intNum             = INT_SSI0_COMB,        .intPriority        = ~0,        .swiPriority        = 0,        .powerMngrId        = PowerCC26XX_PERIPH_SSI0,        .defaultTxBufValue  = 0,        .rxChannelBitMask   = 1<<UDMA_CHAN_SSI0_RX,        .txChannelBitMask   = 1<<UDMA_CHAN_SSI0_TX,        .mosiPin            = Board_SPI0_MOSI,        .misoPin            = Board_SPI0_MISO,        .clkPin             = Board_SPI0_CLK,        .csnPin             = Board_SPI0_CSN    },    {        .baseAddr           = SSI1_BASE,        .intNum             = INT_SSI1_COMB,        .intPriority        = ~0,        .swiPriority        = 0,        .powerMngrId        = PowerCC26XX_PERIPH_SSI1,        .defaultTxBufValue  = 0,        .rxChannelBitMask   = 1<<UDMA_CHAN_SSI1_RX,        .txChannelBitMask   = 1<<UDMA_CHAN_SSI1_TX,        .mosiPin            = Board_SPI1_MOSI,        .misoPin            = Board_SPI1_MISO,        .clkPin             = Board_SPI1_CLK,        .csnPin             = Board_SPI1_CSN    }};/* SPI configuration structure */const SPI_Config SPI_config[] = {    {         .fxnTablePtr = &SPICC26XXDMA_fxnTable,         .object      = &spiCC26XXDMAObjects[0],         .hwAttrs     = &spiCC26XXDMAHWAttrs[0]    },    {         .fxnTablePtr = &SPICC26XXDMA_fxnTable,         .object      = &spiCC26XXDMAObjects[1],         .hwAttrs     = &spiCC26XXDMAHWAttrs[1]    },    {NULL, NULL, NULL}};

这里有两个SPI端口,但是使用不同的配置。

其中object的定义如下:

typedef struct SPICC26XXDMA_Object {    /* SPI control variables */    SPI_TransferMode       transferMode;        /*!< Blocking or Callback mode */    unsigned int           transferTimeout;     /*!< Timeout for the transfer when in blocking mode */    SPI_CallbackFxn        transferCallbackFxn; /*!< Callback function pointer */    SPI_Mode               mode;                /*!< Master or Slave mode */    /*! @brief SPI bit rate in Hz.     *     *  When the SPI is configured as SPI slave, the maximum bitrate is 4MHz.     *     *  When the SPI is configured as SPI master, the maximum bitrate is 12MHz.     */    unsigned int           bitRate;    unsigned int           dataSize;            /*!< SPI data frame size in bits */    SPI_FrameFormat        frameFormat;         /*!< SPI frame format */    /* SPI SYS/BIOS objects */    ti_sysbios_family_arm_m3_Hwi_Struct hwi;    /*!< Hwi object handle */    Swi_Struct             swi;                 /*!< Swi object */    Semaphore_Struct       transferComplete;    /*!< Notify finished SPICC26XXDMA transfer */    /* SPI current transaction */    SPI_Transaction        *currentTransaction; /*!< Ptr to the current transaction*/    SPICC26XXDMA_FrameSize frameSize;           /*!< Data frame size variable */    /* Support for dynamic CSN pin allocation */    PIN_Id                 csnPin;              /*!< SPI CSN pin */    /* PIN driver state object and handle */    PIN_State              pinState;    PIN_Handle             pinHandle;    /* UDMA driver handle */    UDMACC26XX_Handle      udmaHandle;    /* Optional slave mode features */    bool                   returnPartial;      /*!< Optional slave mode return partial on CSN deassert */#ifdef SPICC26XXDMA_WAKEUP_ENABLED    SPICC26XXDMA_CallbackFxn wakeupCallbackFxn;/*!< Optional slave mode wake up on CSN assert */#endif    /* Scratch buffer of size uint32_t */    uint16_t               scratchBuf;    /* SPI pre- and post notification functions */    void                   *spiPreFxn;         /*!< SPI pre-notification function pointer */    void                   *spiPostFxn;        /*!< SPI post-notification function pointer */    Power_NotifyObj        spiPreObj;          /*!< SPI pre-notification object */    Power_NotifyObj        spiPostObj;         /*!< SPI post-notification object */    volatile bool          spiPowerConstraint; /*!< SPI power constraint flag, guard to avoid power constraints getting out of sync */    bool                   isOpen;             /*!< Has the object been opened */} SPICC26XXDMA_Object, *SPICC26XXDMA_Handle;
这里的object是指和spi相关的一些变量及callback地址等。

留意最后一句:*SPICC26XXDMA_Handle,这意味着*SPICC26XXDMA_Handle为某个spi的object结构体的首地址,知道这个首地址就可以修改该object相关的参数。

       通常,外设初始化的时候,我们会初始化一个params结构体,给params的成员赋值,然后再把params的首地址给某个init函数。实际上就是把params的参数传给object的结构体。object结构体的内容包含params的内容。


hwattr的定义如下

typedef struct SPICC26XXDMA_HWAttrsV1 {    /*! SPI Peripheral's base address */    uint32_t         baseAddr;    /*! SPI CC26XXDMA Peripheral's interrupt vector */    uint8_t          intNum;    /*! @brief SPI CC26XXDMA Peripheral's interrupt priority.        The CC26xx uses three of the priority bits,        meaning ~0 has the same effect as (7 << 5).        (7 << 5) will apply the lowest priority.        (1 << 5) will apply the highest priority.        Setting the priority to 0 is not supported by this driver.        HWI's with priority 0 ignore the HWI dispatcher to support zero-latency interrupts, thus invalidating the critical sections in this driver.    */    uint8_t          intPriority;    /*! @brief SPI SWI priority.        The higher the number, the higher the priority.        The minimum is 0 and the maximum is 15 by default.        The maximum can be reduced to save RAM by adding or modifying Swi.numPriorities in the kernel configuration file.    */    uint32_t         swiPriority;    /*! SPI Peripheral's power manager ID */    PowerCC26XX_Resource   powerMngrId;    /*! Default TX value if txBuf == NULL */    uint16_t         defaultTxBufValue;    /*! uDMA controlTable channel index */    uint32_t         rxChannelBitMask;    /*! uDMA controlTable channel index */    uint32_t         txChannelBitMask;    /*!< SPI MOSI pin */    PIN_Id           mosiPin;    /*!< SPI MISO pin */    PIN_Id           misoPin;    /*!< SPI CLK pin */    PIN_Id           clkPin;    /*!< SPI CSN pin */    PIN_Id           csnPin;} SPICC26XXDMA_HWAttrsV1;
HWAttrs通常是和硬件相关的一些参数,比如pin之类的const的内容。在board的.c文件中,给HWAttrs赋初值。



FxnTable定义了SPI能够使用的API,这里用一个结构体把这些函数指针整合起来。

const SPI_FxnTable SPICC26XXDMA_fxnTable = {    SPICC26XXDMA_close,    SPICC26XXDMA_control,    SPICC26XXDMA_init,    SPICC26XXDMA_open,    SPICC26XXDMA_transfer,    SPICC26XXDMA_transferCancel,    SPICC26XXDMA_serviceISR    };
同样,需要写这些函数的源代码,然后在某个.c文件中集中到SPI_FxnTable结构体中,等待外部引用。


SPI_Config其实就是把以上三个结构体的指针用数据的方式集中起来。

const SPI_Config SPI_config[] = {    {         .fxnTablePtr = &SPICC26XXDMA_fxnTable,         .object      = &spiCC26XXDMAObjects[0],         .hwAttrs     = &spiCC26XXDMAHWAttrs[0]    },    {         .fxnTablePtr = &SPICC26XXDMA_fxnTable,         .object      = &spiCC26XXDMAObjects[1],         .hwAttrs     = &spiCC26XXDMAHWAttrs[1]    },    {NULL, NULL, NULL}};
然后定义 handle 为config的指针。操作该handle就能操作该SPI相关所有的变量、硬件配置、可用的函数。
获取handle的方式,实际是上定义了一个名称SPIName,该名称定义为一个enmu的数字index,这样SPI0的handele,  SPIhandle0 = gethandleFxn( index)。

对于SPIDMA这里是有原型的,如果没有原型,那么使用的是libary文件,参见工程->Option->Linker->Library里面的lib文件

       其中library可以用在给客户提供API但是不让客户看到源码的场景下。






原创粉丝点击