外设

1. 概述

SSC8x39支持的外设包括GPIOs, PWM, UART, Timers, SPI, I2C, IR, ADC, I2S等等。

图 ‑1 外设

2. GPIO

2.1. GPIO Index

GPIO API头文件Mercury5\proj\sc\driver\drv\io\pub\drv_gpio.h

图 2‑1 头文件中的定义

图 2‑2 HW Checklist.xls的PIN脚复用定义

通过原理图中的PIN脚命名在HW Checklist.xls中查看对应GPIO命名确定需要使用GPIO宏定义。

2.2. GPIO API

  • void DrvGPIOPadSet(DrvGPIOSe eGPIOIndex, bool bEnable)

    • 配置GPIO复用功能

    • bEnable = TRUE时打开此PIN脚的GPIO功能,同时其他复用功能被关闭

  • void DrvGPIOOutputEnable(DrvGPIOSe eGPIOIndex,bool bEnable)

    • GPIO输出使能

    • bEnable = TRUE时此GPIO输出模式使能,FALSE时此GPIO输入模式使能

  • bool DrvGPIOGetLevel(DrvGPIOSe eGPIOIndex)

    • 读取GPIO输入Level

    • 输入高电平返回TRUE,输入低电平返回FALSE

  • bool DrvGPIOGetDirection(DrvGPIOSe eGPIOIndex)

    • 获取GPIO输入输出模式

    • 返回TRUE表示此GPIO为输出模式,返回FALSE表示此GPIO为输入模式

  • void DrvGPIOSetOutputData(DrvGPIOSe eGPIOIndex,bool bHL)

    • 设定GPIO输出Level

    • bHL = TRUE,输出高电平,bHL = FALSE,输出低电平

  • bool DrvGPIOEnableINT(DrvGPIOSe eGPIOIndex, bool bEnable, PfnIntcISR pfCB)

    • GPIO中断使能

    • bEnable = TRUE,使能GPIO中断

    • pfCB 为中断处理回调函数

  • bool DrvGPIOSetPolarity(DrvGPIOSe eGPIOIndex,u8 reverse)

    • GPIO中断触发极性

    • 只支持高电平/低电平触发,不支持边沿触发

  • bool DrvGPIOEnablePull(DrvGPIOSe eGPIOIndex,u8 bEnable)

    • GPIO内部上下拉使能
  • bool DrvGPIOSetPullStatus(DrvGPIOSe eGPIOIndex,u8 bHL)

    • GPIO内部上拉/下拉状态设定
  • bool DrvGPIOSetDriving(DrvGPIOSe eGPIOIndex,u8 nLevel)

    • GPIO驱动电流能力设定

2.3. GPIO测试

在UART终端敲"io",会列出io可用方法。

/:io
io gpio     -- io gpio [GPIONum] [IN:1/OUT:0] [H:1/L:0]
io gpiodrv  -- io gpiodrv [GPIONum] [Level]
io gpiopull -- io gpiopull [GPIONum] [pull enable] [pull H/L]
io pwm      -- io pwm [PWMIndex] [PadMode] [Freq(Hz)] [shift(%)] [duty(%)] [NOT invert]

GPIONum即GPIO对应的枚举值。

以PAD_FUART_CTS的GPIO输出功能为例,操作如下:

通过HW CheckList.xls和DrvGPIOSe枚举定义,确认PAD_FUART_CTS这个PIN对应枚举DRV_IO_FUART_GPIO2,GPIONum = 15。

输出高电平:

/:io gpio 15 0 1
====GPIO : 15 ,Is Input? : 0, H/L : 0====

输出低电平:

/:io gpio 15 0 0
====GPIO : 15 ,Is Input? : 0, H/L : 1====

查看HW CheckList.xls Pull-Up/Down页确定GPIO是否支持驱动设定,Driving页确定支持的Level,大多数GPIO只支持2挡设定,分别对应nLevel = 1(8mA)/ nLevel = 0(4mA)。

2.4. GPIO应用

  • PAD_FUART_CTS: GPIO输出高/低电平

    DrvGPIOPadSet(DRV_IO_FUART_GPIO2, 1); //设置为输出
    DrvGPIOOutputEnable(DRV_IO_FUART_GPIO2, 1); //设置为输出使能
    

    在不改变GPIO输入输出状态的情况下,PadSet/OutputEnable只需要Call一次即可。

    改变输出电平高低不需要重复做 PadSet/OutputEnable。

    DrvGPIOSetOutputData(DRV_IO_FUART_GPIO2, 0); //输出低电平
    DrvGPIOSetOutputData(DRV_IO_FUART_GPIO2, 1); //输出高电平
    
  • PAD_FUART_CTS: GPIO中断(注意:使用GPIO中断功能时需要通过HW CheckList.xls确认此GPIO是否支持中断功能。)

    void _GPIOInputISR(void)
    {
        //中断处理函数,根据需要决定在中断中处理的业务。
        UartSendTrace("_GPIOInputISR Enter!\n");
    }
    
    DrvGPIOPadSet(DRV_IO_FUART_GPIO2,1);
    DrvGPIOEnableINT(DRV_IO_FUART_GPIO2,1, _GPIOInputISR);
    DrvGPIOSetPolarity(DRV_IO_FUART_GPIO2,0);//设定为低电平触发
    

3. I2C

头文件Mercury5\proj\sc\driver\drv\bus\pub\drv_bus_i2c.h

I2CErrorCode_e DrvI2cOpen(s32 *pHandle, I2COptions_t *psI2cSettings);
I2CErrorCode_e DrvI2cClose(s32 nHandle);
I2CErrorCode_e DrvI2cWrite(s32 nHandle, void * pDataToWrite, u32 nNbBytes, bool bStopBit);
I2CErrorCode_e DrvI2cRead(s32 nHandle, void * pDataToRead, u32 nNbBytes);
I2CErrorCode_e DrvI2cWriteAndRead(s32 nHandle, void * pDataToWrite, u32 nNbBytesToWrite, void * pDataToRead, u32 nNbBytesToRead);
I2CErrorCode_e DrvI2cOpenSW(u32 nAddress, I2cClockSpeed_e eClkSpeed, IoChipPadNum_e eScl, IoChipPadNum_e eSda, s32 *pHandle);
I2CErrorCode_e DrvI2cAddrWrite(s32 nHandle, u16 nAddress, u16 nDataToWrite, bool bStopBit);
I2CErrorCode_e DrvI2cAddrRead(s32 nHandle, u16 nAddress, u16 *pDataToRead, bool bStopBit);

4. SPI

头文件Mercury5\proj\sc\driver\drv\bus\pub\drv_mspi.h

MSpiErrorCode_e DrvMSpiOpen(MSpiChannel_e *pHandle, MSpiSettings_t *ptMSpiSetting);
MSpiErrorCode_e DrvMSpiClose(MSpiChannel_e nHandle);
MSpiErrorCode_e DrvMSpiWrite(MSpiChannel_e nHandle, void *pDataToWrite, u32 nWriteLen);
MSpiErrorCode_e DrvMSpiRead(MSpiChannel_e nHandle, void *pDataToRead, u32 nReadLen);
MSpiErrorCode_e DrvMSpiReadEx(MSpiChannel_e nHandle, void *pDataToWrite, u32 nWriteLen, void *pDataToRead, u32 nReadLen);

SPI时钟源有108M/54M/12M,DIV有2/4/8/16/32/64/128/256,根据用户设定MSpiSettings t参数nMspiClk,driver自动计算对应Div和时钟源,SPI CLK最大支持54MHz,最小支持46875Hz。

MSPI参数设定结构体:

typedef struct
{
    MSpiChannel_e       eChannel;
    MSpiRWMethod_e      eRWMethod;                      
    MSpiMode_e          eMSpiMode;                      
    MSpiPad_e           ePadSelect;                     
    u32                 nMspiClk;                       
    MSpi_BufferConfig   sBufferCfg;
} MSpiSettings_t;
成员名称 描述
eChannel SPI的Channel,SPI0就是Channel0,SPI1就是Channel1
eRWMethod SPI读写方式,支持polling or interrupt
eMSpiMode SPI的相位(CPHA)和极性(CPOL)模式
Mode 0 CPOL=0, CPHA=0
Mode 1 CPOL=0, CPHA=1
Mode 2 CPOL=1, CPHA=0
Mode 3 CPOL=1, CPHA=1
ePadSelect SPI的PadMux,一个SPI Channel可能有多组PIN复用,Padmux参数决定使用哪一组PIN。根据硬件原理图设计查看HW CheckList文档确定参数配置。
nMspiClk SPI Clk参数,单位Hz
sBufferCfg SPI 读写数据Buffer参数配置

MSPI读写Buffer bits参数结构体:

typedef struct
{
    u8 u8WBitConfig[8];      //bits will be transferred in write buffer ,0~7 means 1bit~8bit
    u8 u8RBitConfig[8];      //bits Will be transferred in read buffer ,0~7 means 1bit~8bit
} MSpi_BufferConfig;
成员名称 描述
u8WBitConfig[8] MSPI最大支持8Bytes的WriterBuffer,每个Byte的有效数据bits,参数范围07,对应1bit8bit有效数据
u8RBitConfig[8] MSPI最大支持8Bytes的ReadBuffer,每个Byte的有效数据bits,参数范围07,对应1bit8bit有效数据
MSpiErrorCode_e eRtn;
MSpiSettings_t  tSetting;

tSetting.eChannel       = MSPI_CH1;
tSetting.eMSpiMode  = MSPI_MODE0; 
tSetting.ePadSelect     = MSPI_PAD1;
tSetting.eRWMethod  = MSPI_RW_METHOD_POLLING;
tSetting.nMspiClk       = 27000000;
for (i = 0 ; i < 8 ; i++) {
    tSetting.sBufferCfg.u8RBitConfig[i] = 7; //Read Buffer有效位数参数7表示8bit有效
    tSetting.sBufferCfg.u8WBitConfig[i] = 7; //Write Buffer 有效位数参数7表示8bit有效
}   
eRtn = (DrvMSpiOpen(&eSPIHandle,&tSetting));
if(MSPI_PROC_DONE != eRtn)
    UartSendTrace(" MSpi Open err  %d \n", eRtn);

//SPI Read Data
{
    int i;
    MSpiErrorCode_e eRtn;

    u8 aReadBuf[8] = {0};
    memset(aReadBuf, 0x0, sizeof(aReadBuf));

    eRtn = DrvMSpiRead(eSPIHandle, aReadBuf, sizeof(aReadBuf));
    UartSendTrace("=== DrvMSpiRead res = [%d] ===\r\n", eRtn);
    for(i = 0 ; i < sizeof(aReadBuf) ; i++)
    {       
        UartSendTrace(" %x ", aReadBuf[i]);
    }
    UartSendTrace("\r\n");
}

//SPI Write Data
{
    MSpiErrorCode_e eRtn;
    u8 aWriteBuf[8] = {0};

    memset(aWriteBuf, 0x0, sizeof(aWriteBuf));
    aWriteBuf[0] = 0x00;
    aWriteBuf[1] = 0x01;
    aWriteBuf[2] = 0x02;
    aWriteBuf[3] = 0x03;
    aWriteBuf[4] = 0x04;
    aWriteBuf[5] = 0x05;
    aWriteBuf[6] = 0x06;
    aWriteBuf[7] = 0x07;

    eRtn = DrvMSpiWrite(eSPIHandle, aWriteBuf, sizeof(aWriteBuf));
    UartSendTrace("=== DrvMSpiWrite res = [%d] ===\r\n", eRtn);
}

5. UART

头文件Mercury5\proj\sc\driver\drv\uart\inc\drv_uart.h

s32 uart_Open( Uart_Num_t uart_num, Uart_cfg_t *uart_cfg );
void uart_SetRate(Uart_Num_t uart_num, vm_v24_Rate_t Rate );
void uart_SetFraming( Uart_Num_t uart_num, vm_v24_Framing_t Framing );
s32 uart_Write( Uart_Num_t uart_num, u8 *string,  u32 length);
s32 uart_Read( Uart_Num_t uart_num, u8 *string,  u32 length);
s32 uart_GetRxFifoLevel( Uart_Num_t uart_num);
bool uart_IsTxFifoEmpty( Uart_Num_t uart_num);
s32 uart_ClearRxBuffer( Uart_Num_t uart_num);

UART配置参数结构体:

typedef struct {
    vm_v24_SerialLength_t       length;           ///< length in number of bits
    vm_v24_SerialParity_t       parity;           ///< parity
    vm_v24_SerialStop_t         stop;              ///< stop bit
    vm_v24_Rate_t           rate;              ///< bit rate
    vm_v24_FlowControl_t      RxFlowCtrlMethod; ///< type of Rx flow control
    vm_v24_FlowControl_t      TxFlowCtrlMethod; ///< type of Tx flow control
    u8                  signal_mask;    ///< signals to use
    u8                  padMode;        ///< pad mode
    UartCallbackData_t              rxCallback;     ///< callback called when data received in hardware FIFO
    UartCallbackData_t          txCallback;     ///< callback called when all data of software FIFO sent
    UartCallbackInd_t           EvtCallback;        ///< callback called when UART event raise of type \ref Uart_Ind_t
    u32                       dmaEnable;      ///< TX/RX by dma>
    u32                       autoCtsRts;
} Uart_cfg_t;
成员名称 描述
length Uart Data bits长度参数
typedef enum
{
VM_V24_5BIT_LENGTH, ///< 5 bits per char
VM_V24_6BIT_LENGTH, ///< 6 bits per char
VM_V24_7BIT_LENGTH, ///< 7 bits per char
VM_V24_8BIT_LENGTH ///< 8 bits per char
} vm_v24_SerialLength_t;
parity Uart奇偶校验位参数
typedef enum
{
VM_V24_NO_PARITY, ///< no parity checking
VM_V24_ODD_PARITY, ///< odd parity
VM_V24_EVEN_PARITY, ///< even parity
VM_V24_SPACE_PARITY = VM_V24_EVEN_PARITY
stop Uart 停止位参数
typedef enum
{
VM_V24_1STOP_BIT, ///< 1 stop bit
VM_V24_2STOP_BIT ///< 2 stop bits
} vm_v24_SerialStop_t;
rate Uart波特率参数
typedef enum
{
VM_V24_1200, ///< 1200 bauds
VM_V24_2400, ///< 2400 bauds
VM_V24_4800, ///< 4800 bauds
VM_V24_9600, ///< 9600 bauds
VM_V24_19200, ///< 19200 bauds
VM_V24_38400, ///< 38400 bauds
VM_V24_57600, ///< 57600 bauds
VM_V24_115200, ///< 115200 bauds
VM_V24_300, ///< 300 bauds
VM_V24_600, ///< 600 bauds
VM_V24_230400, ///< 230400 bauds
VM_V24_460800, ///< 460800 bauds
VM_V24_921600, ///< 921600 bauds
VM_V24_UNDEFINED_RATE, ///< undefined baudrate
#ifdef DOWNLOADER
VM_OV13_V24_NB_RATES,
VM_OV13_V24_SET_AUTOBAUD = 0x80,
VM_V24_SET_AUTOBAUD /* to active autobauding */
#else
VM_V24_SET_AUTOBAUD ///< to active autobauding
#endif
} vm_v24_Rate_t;
RxFlowCtrlMethod Uart Rx流控方式参数,FastUart时使用VM_V24_HARD,Normal Uart则使用VM_V24_NONE
typedef enum
{
VM_V24_NONE,
VM_V24_HARD, /* RTS/CTS * /
VM_V24_SOFT, /* XON/XOFF */
VM_V24_HARD_SOFT = VM_V24_HARD | VM_V24_SOFT
} vm_v24_FlowControl_t;
TxFlowCtrlMethod Uart Tx流控方式参数,同RxFlowCtrlMethod
signal_mask Uart PIN信号Mask,FastUart需要Mask RX/TX/RTS/CTS 4个PIN,Normal Uart只需要Mask RX/TX两个PIN。
typedef enum
{
VM_V24_SIGNAL_RX, ///< Rxd (from PC to BaseBand) pin
VM_V24_SIGNAL_TX, ///< Txd (from BaseBand to PC) pin
VM_V24_SIGNAL_RTS, ///< RTS (Ready To Send) pin
VM_V24_SIGNAL_CTS, ///< CTS (Clear To Send) pin
VM_V24_SIGNAL_DTR, ///< DTR pin
VM_V24_SIGNAL_DSR, ///< DSR pin
VM_V24_SIGNAL_RI, ///< Ring Indicator pin
VM_V24_SIGNAL_DCD, ///< DCD pin
VM_V24_SIGNAL_BRK, ///< Break pin (fake signal)
VM_V24_SIGNAL_LAST ///< last signal
}vm_v24_Signal_t;
padMode Uart PadMux参数
配置Uart Channel 使用的复用PIN脚。
rxCallback RX回调函数,用于处理Uart接收数据
txCallback TX回调函数,用于处理Uart发送数据
EvtCallback NA
dmaEnable DMA使能,仅Fast Uart支持,Normal Uart 设0
autoCtsRts 流控使能,仅Fast Uart支持,Normal Uart 设0

Uart_num参数说明:

typedef enum {
    UART_1,
    UART_2,
    UART_3,
    FUART,
    NB_UART
} Uart_Num_t;

SDK应用层Uart Num枚举定义与HW CheckList以及其它硬件资料中UartNum不一致,使用Uart时需要注意:

  • UART_1对应硬件资料的UART0

  • UART_2对应硬件资料的UART1

  • UART_3对应硬件资料的UART2

  • FUART对应硬件资料的FUART

PAD_SNR1_DA0P/PAD_SNR1_DA0N这组PIN复用位UART2的Mode7时,软件使用示例如下:

//Rx CallBack
void Uart_rxCallback(Uart_Num_t uart_num, u8 *buffer, u32 size)
{   
    UartSendTrace("# Uart_rxCallback -%d read[%d] sz[%d]\r\n", __LINE__, *buffer, size);
}
//Uart Init
{
    Uart_cfg_t      uart_cfg;
    memset(&uart_cfg, 0, sizeof(Uart_cfg_t));
    uart_cfg.length             = VM_V24_8BIT_LENGTH;
    uart_cfg.parity             = VM_V24_NO_PARITY;
    uart_cfg.stop               = VM_V24_1STOP_BIT;
    uart_cfg.padMode            = 7;
    uart_cfg.rate               = VM_V24_115200;
    uart_cfg.signal_mask        = (VM_V24_SIGNAL_RX | VM_V24_SIGNAL_TX);
    uart_cfg.RxFlowCtrlMethod   = VM_V24_NONE;
    uart_cfg.TxFlowCtrlMethod   = VM_V24_NONE;
    uart_cfg.autoCtsRts     = 0;
    uart_cfg.rxCallback         = Uart_rxCallback; 
    uart_cfg.txCallback         = NULL;
    uart_cfg.EvtCallback        = NULL;
    uart_Open(UART_3, &uart_cfg);
}
//Uart Write
{
    u8 u8SendString[]=”Hello,I’m UART2 Mode7!”;
    uart_Write(UART_3, u8SendString, sizeof(u8SendString));
}