CC2640外设的object &HWAttrs & fxn & config

在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但是不让客户看到源码的场景下。






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值