sylixos下的imxRT1050的SPI总线驱动

SPI驱动分总线驱动及适配器驱动,和SPI子设备驱动。
下面是sylixos下的imxRT1050的SPI总线驱动源码.

/*********************************************************************************************************
**
**                                    中国软件开源组织
**
**                                   嵌入式实时操作系统
**
**                                       SylixOS(TM)
**
**                               Copyright  All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文   件   名: spi.c
**
** 创   建   人: Jiang.Heng(蒋恒)
**
** 文件创建日期: 2017 年 12 月 26 日
**
** 描        述: IMRT1050 处理器 SPI 总线驱动
*********************************************************************************************************/
#define  __SYLIXOS_KERNEL
#include <SylixOS.h>
#include <module.h>
#include "linux/compat.h"
#include "spi.h"
#include "fsl_clock.h"
#include "fsl_lpspi.h"
#include "fsl_gpio.h"
#include "fsl_iomuxc.h"
#include "pinmux/pinmux.h"
#include "clk/clk.h"
#include "config.h"
/*********************************************************************************************************
  SPI总线其他的宏定义
*********************************************************************************************************/
#define SPI_DEBUG(fmt, arg...)     printk("[SPI] %s() : "fmt, __func__, ##arg)
                                                                        /*  调试打印信息                */
#define SPI_CHANNEL_NUM            (4)                                  /*  SPI总线数量                 */
#define SPI_CHANNEL_0              (0)                                  /*  SPI0通道号                  */
#define SPI_CHANNEL_1              (1)                                  /*  SPI1通道号                  */
#define SPI_CHANNEL_2              (2)                                  /*  SPI2通道号                  */
#define SPI_CHANNEL_3              (3)                                  /*  SPI3通道号                  */
#define BAUDRATE_DEFAULT           (500000)                             /*  默认波特率 500 KHZ          */
#define NSEC                       (1000000000)                         /*  纳秒换算                    */
#define TIMEOUT                    (1600)                               /*  pend 超时时间               */
#define SPI_TIMEOUT                (1000000)                            /*  超时时间                    */
#define LPSPI_CLOCK_SOURCE_DIVIDER (7)                                  /*  时钟源分频系数              */
#define LPSPI_CLOCK_SOURCE_SELECT  (1)                                  /*  LPSPI 时钟源选择            */
#define LPSPI_CLOCK_FREQ \
    (CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (LPSPI_CLOCK_SOURCE_DIVIDER + 1U))
                                                                        /*  获得 LPSPI 时钟频率         */
#define LPSPI_MASTER_CLOCK_FREQ    (LPSPI_CLOCK_FREQ)                   /*  LPSPI 时钟频率              */
#define LPSPI_INT_PRIORITY         (0xe)                                /*  LPSPI 中断优先级            */
/*********************************************************************************************************
  控制命令
*********************************************************************************************************/
#define SPI_M_CPOL_0      (0x0000)                                      /*  CPOL 配置                   */
#define SPI_M_CPOL_1      (0x0001)                                      /*  CPOL 配置                   */
#define SPI_M_CPHA_0      (0x0000)                                      /*  CPHA 配置                   */
#define SPI_M_CPHA_1      (0x0002)                                      /*  CPOL 配置                   */
#define SPI_M_PCS_MASK    (0x0300)                                      /*  PCS 配置                    */
#define SPI_M_PCS_SHIFT   (8)                                           /*  PCS 移位                    */
#define SPI_M_PCS_0       (0x0000)                                      /*  片选0                       */
#define SPI_M_PCS_1       (0x0100)                                      /*  片选1                       */
#define SPI_M_PCS_2       (0x0200)                                      /*  片选2                       */
#define SPI_M_PCS_3       (0x0300)                                      /*  片选3                       */
/*********************************************************************************************************
  控制命令结构体定义
*********************************************************************************************************/
typedef struct spi_arg {
    ULONG  SPI_ulBaud;                                                  /*  波特率                      */
    UINT8  SPI_ucFlags;                                                 /*  传输控制参数                */
}SPI_ARG;
typedef struct spi_arg  *PSPI_ARG;
/*********************************************************************************************************
  SPI通道类型定义
*********************************************************************************************************/
struct spi_channel{
    UINT32              SPI_uiChannel;                                  /*  通道号                      */
    UINT32              SPI_uiIntVector;                                /*  中断号                      */
    BOOL                SPI_bIsInit;                                    /*  是否进行控制器初始化标志    */
    LW_OBJECT_HANDLE    SPI_hSignal;                                    /*  句柄                        */

    UINT                SPI_uiRemainingBytes;                           /*  消息剩余大小                */
    PLW_SPI_MESSAGE     SPI_pMsg;                                       /*  消息队列                    */
    UINT32              SPI_uiFifoSize;                                 /*  SPI FIFO 大小               */
};
typedef struct spi_channel  __SPI_CHANNEL;
typedef struct spi_channel *__PSPI_CHANNEL;
/*********************************************************************************************************
  全局变量
*********************************************************************************************************/
static __SPI_CHANNEL  _G_spiChannels[SPI_CHANNEL_NUM] = {
    {
        SPI_CHANNEL_0,                                                  /*  SPI0 通道号                 */
        BSP_IRQ_TO_VECTOR(LPSPI1_IRQn),                                 /*  SPI0 中断号                 */
    },

    {
        SPI_CHANNEL_1,                                                  /*  SPI0 通道号                 */
        BSP_IRQ_TO_VECTOR(LPSPI2_IRQn),                                 /*  SPI0 中断号                 */
    },

    {
        SPI_CHANNEL_2,                                                  /*  SPI0 通道号                 */
        BSP_IRQ_TO_VECTOR(LPSPI3_IRQn),                                 /*  SPI0 中断号                 */
    },

    {
        SPI_CHANNEL_3,                                                  /*  SPI0 通道号                 */
        BSP_IRQ_TO_VECTOR(LPSPI4_IRQn),                                 /*  SPI0 中断号                 */
    },
};
/*********************************************************************************************************
** 函数名称: __spiBaseGet
** 功能描述: 获得 SPI 基址
** 输  入  : uiChannel     SPI 通道号
** 输  出  : NONE
** 返  回  : NONE
*********************************************************************************************************/
static LW_INLINE LPSPI_Type  *__spiBaseGet (UINT32  uiChannel)
{
    switch (uiChannel) {

    case SPI_CHANNEL_0:
        return  (LPSPI1);

    case SPI_CHANNEL_1:
        return  (LPSPI2);

    case SPI_CHANNEL_2:
        return  (LPSPI3);

    case SPI_CHANNEL_3:
        return  (LPSPI4);

    default:
        SPI_DEBUG("channel num is error\n");

        return  (LPSPI1);
    }
}
/*********************************************************************************************************
** 函数名称: __spiDataReceive
** 功能描述: SPI 接收数据函数
** 输  入  : pSpiChannel        SPI 通道
** 输  出  : NONE
** 返  回  : NONE
*********************************************************************************************************/
static VOID __spiDataReceive (__PSPI_CHANNEL  pSpiChannel)
{
    PLW_SPI_MESSAGE  pSpimsg    = pSpiChannel->SPI_pMsg;                /*  传输控制消息                */
    UINT32           uiChannel  = pSpiChannel->SPI_uiChannel;           /*  获取通道号                  */
    UINT32           uiPosition = pSpimsg->SPIMSG_uiLen - pSpiChannel->SPI_uiRemainingBytes;
                                                                        /*  当前消息的位置              */
    UINT8           *pucRxbuf   = pSpimsg->SPIMSG_pucRdBuffer;          /*  接收数据缓存区              */
    UINT8           *pucBytes   = (UINT8  *)(pucRxbuf + uiPosition);
    UINT32           uiNumBytes;
    UINT32           uiRd;                                              /*  保存 RDR 寄存器的值         */

    uiNumBytes  = LPSPI_GetRxFifoCount(__spiBaseGet(uiChannel));        /*  当前接收FIFO中消息的数量    */

    /*
     *  更新消息剩余大小
     */
    if (pSpiChannel->SPI_uiRemainingBytes > uiNumBytes) {
        pSpiChannel->SPI_uiRemainingBytes -= uiNumBytes;
    } else {
        pSpiChannel->SPI_uiRemainingBytes  = 0;                         /*  剩余字节数为0               */
    }

    /*
     *  从接收FIFO中读数据
     */
    while (uiNumBytes) {
        uiRd = LPSPI_ReadData(__spiBaseGet(uiChannel));
        if (pucRxbuf) {
            *pucBytes++ = uiRd;
        }
        uiNumBytes--;
    }
}
/*********************************************************************************************************
** 函数名称: __spiIsr
** 功能描述: 发送中断
** 输  入  : pSpiChannel     SPI 通道
**           uiVector        中断向量号
** 输  出  : NONE
** 返  回  : 中断返回值
*********************************************************************************************************/
static irqreturn_t  __spiIsr (__PSPI_CHANNEL  pSpiChannel, ULONG  uiVector)
{
    UINT32       uiStatus;
    LPSPI_Type  *pBase = __spiBaseGet(pSpiChannel->SPI_uiChannel);


    uiStatus = LPSPI_GetStatusFlags(pBase);                             /*  获得状态寄存器的值          */

    LPSPI_ClearStatusFlags(pBase, uiStatus);                            /*  清除中断标志                */

    if (uiStatus & kLPSPI_ReceiveErrorFlag) {
        SPI_DEBUG("spi rx error uiStatus is %x!!\n", uiStatus);
    }

    if (uiStatus & kLPSPI_RxDataReadyFlag) {
        if (pSpiChannel->SPI_uiRemainingBytes) {
            __spiDataReceive(pSpiChannel);                              /*  接收数据                    */

            if(0 == pSpiChannel->SPI_uiRemainingBytes) {                /*  消息数量为0                 */
                LPSPI_DisableInterrupts(pBase, kLPSPI_AllInterruptEnable);
                                                                        /*  关闭中断                    */
            }
        }

        API_SemaphoreBPost(pSpiChannel->SPI_hSignal);                   /*  释放信号量                  */
    }

    return  (LW_IRQ_HANDLED);
}
/*********************************************************************************************************
** 函数名称: __spiInit
** 功能描述: spi 控制器初始化
** 输  入  : uiChannel     SPI 通道号
** 输  出  : NONE
** 返  回  : ERROR_NONE
*********************************************************************************************************/
static INT  __spiInit (UINT32  uiChannel)
{
    LPSPI_Type            *pBase = __spiBaseGet(uiChannel);
    lpspi_master_config_t  masterConfig;

    /*
     *  设置 LPSPI 时钟源
     */
    CLOCK_SetMux(kCLOCK_LpspiMux, LPSPI_CLOCK_SOURCE_SELECT);
    CLOCK_SetDiv(kCLOCK_LpspiDiv, LPSPI_CLOCK_SOURCE_DIVIDER);

    pinmuxSpiEnable(uiChannel);                                         /*  管脚复用                    */

    /*
     *  设置默认的传输控制参数
     */
    masterConfig.baudRate                      = BAUDRATE_DEFAULT;      /*  设置波特率                  */
    masterConfig.bitsPerFrame                  = 8;                     /*  8 bit 每帧                  */

    /*
     *  默认时钟极性和相位
     */
    masterConfig.cpol                          = kLPSPI_ClockPolarityActiveHigh;
    masterConfig.cpha                          = kLPSPI_ClockPhaseFirstEdge;
    masterConfig.direction                     = kLPSPI_MsbFirst;       /*  高字节先发                  */

    /*
     *  内部延时设置
     */
    masterConfig.pcsToSckDelayInNanoSec        = NSEC / masterConfig.baudRate;
    masterConfig.lastSckToPcsDelayInNanoSec    = NSEC / masterConfig.baudRate;
    masterConfig.betweenTransferDelayInNanoSec = NSEC / masterConfig.baudRate;
    masterConfig.whichPcs                      = kLPSPI_Pcs0;           /*  默认片选 PCS0               */
    masterConfig.pcsActiveHighOrLow            = kLPSPI_PcsActiveLow;   /*  片选为低电平有效            */
    masterConfig.pinCfg                        = kLPSPI_SdiInSdoOut;    /*  SDI 输入、SDO 输出          */
    masterConfig.dataOutConfig                 = kLpspiDataOutRetained; /*  无效片选后,数据保持最后值  */
    LPSPI_MasterInit(pBase, &masterConfig, LPSPI_MASTER_CLOCK_FREQ);

    /*
     *  清中断和状态
     */
    LPSPI_ClearStatusFlags(pBase, kLPSPI_AllStatusFlag);
    LPSPI_DisableInterrupts(pBase, kLPSPI_AllInterruptEnable);

    return  (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: __spiHwInit
** 功能描述: spi 通道初始化,硬件初始化
** 输  入  : pSpiChannel        SPI 通道
** 输  出  : NONE
** 返  回  : ERROR_CODE
*********************************************************************************************************/
static INT  __spiHwInit (__PSPI_CHANNEL  pSpiChannel)
{
    CHAR  cName[20];                                                    /*  中断服务函数名称            */

    if (LW_NULL == pSpiChannel) {                                       /*  指针有效性判断              */
        return  (PX_ERROR);
    }

    if (!pSpiChannel->SPI_bIsInit) {                                    /*  是否进行了控制器初始化      */
        if (ERROR_NONE !=__spiInit(pSpiChannel->SPI_uiChannel)) {       /*  初始化控制器                */
            return  (PX_ERROR);
        }

        pSpiChannel->SPI_bIsInit = LW_TRUE;                             /*  进行初始化后,置1           */
    }

    sprintf(cName, "lpspi%d_isr", pSpiChannel->SPI_uiChannel);
    API_InterVectorSetPriority(pSpiChannel->SPI_uiIntVector, LPSPI_INT_PRIORITY);
    API_InterVectorConnect(pSpiChannel->SPI_uiIntVector,
                           (PINT_SVR_ROUTINE)__spiIsr,
                           (PVOID)pSpiChannel,
                           cName);
    API_InterVectorEnable(pSpiChannel->SPI_uiIntVector);

    return  (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: __trySpiTransfer
** 功能描述: spi 传输函数
** 输  入  : pspiChannel     SPI 通道
**           pSpiAdapter     SPI 适配器
**           pSpiMsg         SPI 传输消息组
** 输  出  : NONE
** 返  回  : ERROR_CODE
*********************************************************************************************************/
static INT   __trySpiTransfer(__PSPI_CHANNEL    pspiChannel,
                              PLW_SPI_ADAPTER   pSpiAdapter,
                              PLW_SPI_MESSAGE   pSpiMsg)
{
    UCHAR                 *pucTxBuf  = LW_NULL;
    UCHAR                 *pucByte   = LW_NULL;
    LPSPI_Type            *pBase     = LW_NULL;
    UINT                   uiTimeOut = SPI_TIMEOUT;
    INT                    iWaterMark;
    UINT                   uiOffset;

    if ((LW_NULL == pSpiMsg)                     ||
       ((LW_NULL == pSpiMsg->SPIMSG_pucWrBuffer) &&
        (LW_NULL == pSpiMsg->SPIMSG_pucRdBuffer))) {
        SPI_DEBUG("transfer message is invalid\n");

        return  (PX_ERROR);
    }

    pBase                             = __spiBaseGet(pspiChannel->SPI_uiChannel);
    pspiChannel->SPI_uiRemainingBytes = pSpiMsg->SPIMSG_uiLen;          /*  消息剩余字节数              */

    pucTxBuf  = pSpiMsg->SPIMSG_pucWrBuffer;

    while (pspiChannel->SPI_uiRemainingBytes) {                         /*  消息剩余字节数不为0         */
        pspiChannel->SPI_uiFifoSize = LPSPI_GetRxFifoSize(pBase);       /*  TX、RX FIFO 大小相同        */
        uiOffset   = pSpiMsg->SPIMSG_uiLen - pspiChannel->SPI_uiRemainingBytes;
        pucByte    = (UCHAR *)pucTxBuf + uiOffset;                      /*  得到剩余消息的位置          */

        iWaterMark = min(pspiChannel->SPI_uiRemainingBytes, pspiChannel->SPI_uiFifoSize);

        /*
         *  设置 RX FIFO 的阈值,没有用到 TX FIFO 阈值,因此随便设置一个
         */
        LPSPI_SetFifoWatermarks(pBase, 1, iWaterMark - 1);
        /*
         *  清空 FIFO、清空状态、失能中断
         */
        LPSPI_FlushFifo(pBase, LW_TRUE, LW_TRUE);
        LPSPI_ClearStatusFlags(pBase, kLPSPI_AllStatusFlag);
        LPSPI_DisableInterrupts(pBase, kLPSPI_AllInterruptEnable);

        /*
         *  等待 TX FIFO 为空
         */
        while (0 != (LPSPI_GetTxFifoCount(pBase)) && (uiTimeOut--)) {
            udelay(1);
            if (0 == uiTimeOut) {
                SPI_DEBUG("tx fifo empty timeout\n");

                return  (PX_ERROR);
            }
        }

        /*
         *  写入发送数据
         */
        while (iWaterMark) {
            if (pucByte) {
                LPSPI_WriteData(pBase, *pucByte++);
            } else {
                LPSPI_WriteData(pBase, 0);
            }
            iWaterMark--;
        }

        /*
         *  使能接收和接收错误中断
         */
        LPSPI_EnableInterrupts(pBase, kLPSPI_RxInterruptEnable | kLPSPI_ReceiveErrorInterruptEnable);

        uiTimeOut =  API_SemaphoreBPend(pspiChannel->SPI_hSignal, TIMEOUT);
                                                                        /*  挂起,等待中断完成          */
        if (ERROR_NONE != uiTimeOut) {
            SPI_DEBUG("sem timeout, uiTimeOut is %d\n", uiTimeOut);

            return (PX_ERROR);
        }
    }

    return  (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: __spiTransfer
** 功能描述: spi 传输函数
** 输  入  : uiChannel       spi 通道号
**           pSpiAdapter     spi 适配器
**           pSpiMsg         spi 传输消息组
**           iNum            消息数量
** 输  出  : NONE
** 返  回  : 完成传输的消息数量
*********************************************************************************************************/
static INT  __spiTransfer (UINT32            uiChannel,
                           PLW_SPI_ADAPTER   pSpiAdapter,
                           PLW_SPI_MESSAGE   pSpiMsg,
                           INT               iNum)
{
    INT             iMsgNum;
    __PSPI_CHANNEL  pspiChannel = &_G_spiChannels[uiChannel];

    for (iMsgNum = 0; iMsgNum < iNum; iMsgNum++, pSpiMsg++) {           /*  每个 MSG 循环传输           */
        pspiChannel->SPI_pMsg = pSpiMsg;
        if (ERROR_NONE != __trySpiTransfer(pspiChannel,
                                           pSpiAdapter,
                                           pSpiMsg)) {
            SPI_DEBUG("transfer msg_err num %d\n", iMsgNum);
            break;
        }
    }

    return  (iMsgNum);
}
/*********************************************************************************************************
** 函数名称: __spiMasterCtl
** 功能描述: spi 传输控制函数
** 输  入  : uiChannel       spi 通道号
**           pSpiAdapter     spi 适配器
**           iCmd            spi 命令
**           lArg            spi 参数
** 输  出  : NONE
** 返  回  : ERROR_CODE
*********************************************************************************************************/
static INT  __spiMasterCtl (UINT              uiChannel,
                            PLW_SPI_ADAPTER   pSpiAdapter,
                            INT               iCmd,
                            ULONG             ulArg)
{
    LPSPI_Type            *pBase    = LW_NULL;
    SPI_ARG               *pArg     = LW_NULL;
    UINT                   uiPcs;
    lpspi_master_config_t  masterConfig;

    if (uiChannel >= SPI_CHANNEL_NUM) {
        SPI_DEBUG("channel num error\n");

        return  (PX_ERROR);
    }

    pBase = __spiBaseGet(uiChannel);
    pArg  = (SPI_ARG *)ulArg;
    uiPcs = (pArg->SPI_ucFlags & SPI_M_PCS_MASK) >> SPI_M_PCS_SHIFT;

    masterConfig.baudRate                      = pArg->SPI_ulBaud;       /*  波特率                     */
    masterConfig.bitsPerFrame                  = 8;                      /*  每帧 8 bit 数据            */
    masterConfig.cpol                          = (pArg->SPI_ucFlags & SPI_M_CPOL_1) ? 1 : 0;
                                                                         /*  CPOL 位                    */
    masterConfig.cpha                          = (pArg->SPI_ucFlags & SPI_M_CPHA_1) ? 1 :0 ;
    masterConfig.direction                     = kLPSPI_MsbFirst;        /*  高位先发                   */
    masterConfig.pcsToSckDelayInNanoSec        = NSEC / masterConfig.baudRate;
    masterConfig.lastSckToPcsDelayInNanoSec    = NSEC / masterConfig.baudRate;
    masterConfig.betweenTransferDelayInNanoSec = NSEC / masterConfig.baudRate;
    masterConfig.whichPcs                      = uiPcs;                  /*  片选管脚                   */
    masterConfig.pcsActiveHighOrLow            = kLPSPI_PcsActiveLow;    /*  片选电平为低时有效         */
    masterConfig.pinCfg                        = kLPSPI_SdiInSdoOut;
    masterConfig.dataOutConfig                 = kLpspiDataOutRetained;
    LPSPI_MasterInit(pBase, &masterConfig, LPSPI_MASTER_CLOCK_FREQ);

    return  (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: __spi0Transfer
** 功能描述: spi0 传输函数
** 输  入  : pSpiAdapter     spi 适配器
**           pSpiMsg         spi 传输消息组
**           iNum            消息数量
** 输  出  : NONE
** 返  回  : 完成传输的消息数量
*********************************************************************************************************/
static INT  __spi0Transfer (PLW_SPI_ADAPTER     pSpiadapter,
                            PLW_SPI_MESSAGE     pSpiMsg,
                            INT                 iNum)
{
    return  (__spiTransfer(SPI_CHANNEL_0,
                           pSpiadapter,
                           pSpiMsg,
                           iNum));
}
/*********************************************************************************************************
** 函数名称: __spi0MasterCtl
** 功能描述: spi0 传输控制函数
** 输  入  : pSpiAdapter     spi 适配器
**           iCmd            控制命令
**           lArg            控制参数
** 输  出  : NONE
** 返  回  : 完成传输的消息数量
*********************************************************************************************************/
static INT  __spi0MasterCtl (PLW_SPI_ADAPTER    pSpiAdapter,
                             INT                iCmd,
                             LONG               lArg)
{
    return  (__spiMasterCtl(SPI_CHANNEL_0,
                            pSpiAdapter,
                            iCmd,
                            lArg));
}
/*********************************************************************************************************
** 函数名称: __spi1Transfer
** 功能描述: spi1 传输函数
** 输  入  : pSpiAdapter     spi 适配器
**           pSpiMsg         spi 传输消息组
**           iNum            消息数量
** 输  出  : NONE
** 返  回  : 完成传输的消息数量
*********************************************************************************************************/
static INT  __spi1Transfer (PLW_SPI_ADAPTER     pSpiAdapter,
                            PLW_SPI_MESSAGE     pSpiMsg,
                            INT                 iNum)
{
    return  (__spiTransfer(SPI_CHANNEL_1,
                           pSpiAdapter,
                           pSpiMsg,
                           iNum));
}
/*********************************************************************************************************
** 函数名称: __spi1MasterCtl
** 功能描述: spi1 传输控制函数
** 输  入  : pSpiAdapter     spi 适配器
**           iCmd            控制命令
**           lArg            控制参数
** 输  出  : NONE
** 返  回  : 完成传输的消息数量
*********************************************************************************************************/
static INT  __spi1MasterCtl (PLW_SPI_ADAPTER    pSpiAdapter,
                             INT                iCmd,
                             LONG               lArg)
{
    return  (__spiMasterCtl(SPI_CHANNEL_1,
                            pSpiAdapter,
                            iCmd,
                            lArg));
}
/*********************************************************************************************************
** 函数名称: __spi2Transfer
** 功能描述: spi2 传输函数
** 输  入  : pSpiAdapter     spi 适配器
**           pSpiMsg         spi 传输消息组
**           iNum            消息数量
** 输  出  : NONE
** 返  回  : 完成传输的消息数量
*********************************************************************************************************/
static INT  __spi2Transfer (PLW_SPI_ADAPTER     pSpiAdapter,
                            PLW_SPI_MESSAGE     pSpiMsg,
                            INT                 iNum)
{
    return  (__spiTransfer(SPI_CHANNEL_2,
                           pSpiAdapter,
                           pSpiMsg,
                           iNum));
}
/*********************************************************************************************************
** 函数名称: __spi2MasterCtl
** 功能描述: spi2 传输控制函数
** 输  入  : pSpiAdapter     spi 适配器
**           iCmd            控制命令
**           lArg            控制参数
** 输  出  : NONE
** 返  回  : 完成传输的消息数量
*********************************************************************************************************/
static INT  __spi2MasterCtl (PLW_SPI_ADAPTER    pSpiAdapter,
                             INT                iCmd,
                             LONG               lArg)
{
    return  (__spiMasterCtl(SPI_CHANNEL_2,
                            pSpiAdapter,
                            iCmd,
                            lArg));
}
/*********************************************************************************************************
** 函数名称: __spi3Transfer
** 功能描述: spi3 传输函数
** 输  入  : pSpiAdapter     spi 适配器
**           pSpiMsg         spi 传输消息组
**           iNum            消息数量
** 输  出  : NONE
** 返  回  : 完成传输的消息数量
*********************************************************************************************************/
static INT  __spi3Transfer (PLW_SPI_ADAPTER     pSpiAdapter,
                            PLW_SPI_MESSAGE     pSpiMsg,
                            INT                 iNum)
{
    return  (__spiTransfer(SPI_CHANNEL_3,
                           pSpiAdapter,
                           pSpiMsg,
                           iNum));
}
/*********************************************************************************************************
** 函数名称: __spi3MasterCtl
** 功能描述: spi3 传输控制函数
** 输  入  : pSpiAdapter     spi 适配器
**           iCmd            控制命令
**           lArg            控制参数
** 输  出  : NONE
** 返  回  : 完成传输的消息数量
*********************************************************************************************************/
static INT  __spi3MasterCtl (PLW_SPI_ADAPTER    pSpiAdapter,
                             INT                iCmd,
                             LONG               lArg)
{
    return  (__spiMasterCtl(SPI_CHANNEL_3,
                            pSpiAdapter,
                            iCmd,
                            lArg));
}
/*********************************************************************************************************
  SPI总线函数集
*********************************************************************************************************/
static LW_SPI_FUNCS _G_spiFuncs[SPI_CHANNEL_NUM] = {
    {
        __spi0Transfer,
        __spi0MasterCtl,
    },
    {
        __spi1Transfer,
        __spi1MasterCtl,
    },
    {
        __spi2Transfer,
        __spi2MasterCtl,
    },
    {
        __spi3Transfer,
        __spi3MasterCtl,
    }
};
/*********************************************************************************************************
** 函数名称: __spiBusDrv
** 功能描述: 初始化 spi 总线并获取操作函数集
** 输    入: uiChannel  通道号
** 输    出: NONE
** 返  回  : spi总线驱动程序
*********************************************************************************************************/
static PLW_SPI_FUNCS  __spiBusDrv (UINT32  uiChannel)
{
    CHAR  cName[20];

    if (uiChannel >= SPI_CHANNEL_NUM) {                                 /*  通道号有效性判断            */
        SPI_DEBUG("spi channel invalid!\n");

        return  (LW_NULL);
    }

    sprintf(cName, "spi%d_sem", uiChannel);
    _G_spiChannels[uiChannel].SPI_hSignal = API_SemaphoreBCreate(cName,
                                                                 LW_FALSE,
                                                                 LW_OPTION_OBJECT_LOCAL,
                                                                 LW_NULL);
    if (LW_HANDLE_INVALID == _G_spiChannels[uiChannel].SPI_hSignal) {
        SPI_DEBUG("fail to create signal\n");

        return  (LW_NULL);
    }

    if (ERROR_NONE != __spiHwInit(&_G_spiChannels[uiChannel])) {        /*  判断硬件初始化是否成功      */
        SPI_DEBUG("fail to init hardware\n");
        API_SemaphoreBDelete(&_G_spiChannels[uiChannel].SPI_hSignal);

        return  (LW_NULL);
    }

    return  (&_G_spiFuncs[uiChannel]);                                  /*  返回操作函数集              */
}
/*********************************************************************************************************
** 函数名称: spiBusCreate
** 功能描述: 初始化目标电路板spi总线系统
** 输  入  : NONE
** 输  出  : NONE
** 返  回  : NONE
*********************************************************************************************************/
VOID  spiBusCreate (VOID)
{
    PLW_SPI_FUNCS    pSpiFuncs = LW_NULL;

    API_SpiLibInit();                                                   /*  初始化 spi 组件库           */

    pSpiFuncs = __spiBusDrv(SPI_CHANNEL_0);
    if (LW_NULL != pSpiFuncs) {                                         /*  判断是否正常获取SPI函数集   */
        API_SpiAdapterCreate("/bus/spi/0", pSpiFuncs);                  /*  创建spi0 总线适配器         */
    }

    pSpiFuncs = __spiBusDrv(SPI_CHANNEL_2);
    if (LW_NULL != pSpiFuncs) {                                         /*  判断是否正常获取SPI函数集   */
        API_SpiAdapterCreate("/bus/spi/2", pSpiFuncs);                  /*  创建spi2 总线适配器         */
    }
}
/*********************************************************************************************************
  END
*********************************************************************************************************/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ScilogyHunter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值