/**
* @file hv_drv_GpioSimSWire.c
* @brief gpio smulitaion single wire driver layer file.
* @details This file provides the following functions: \n
* (1) gpio simulate swire tx/rx \n
* (2) gpio simulate swire init \n
*
* @author HiView SoC Software Team
* @version 1.0.0
* @date 2023-12-16
* @copyright Copyright(c),2023-12, Hiview Software. All rights reserved.
* @par History:
*
* Author | Date | Change Description
* |
---|
*/
#include "Common/hv_comm_DataType.h"
#include "Common/Assert/hv_comm_Assert.h"
#include "hv_comm_Define.h"
#include "hv_cal_Gpio.h"
#include "hv_vos_Comm.h"
#include "hv_drv_GpioSimSWire.h"
#define GPIOSIMSWIRE_DELAY 1U
static GpioSimSWire s_stgpiosimswire[SIMSWIRE_ID_MAX] =
{
{INVALID_PARAM_UHCAR8, INVALID_PARAM_UHCAR8, 1, 1, 1},
};
#define SET_SCK_OUT(uiIndex) Hv_Cal_Gpio_SetDirection(s_stgpiosimswire[uiIndex].ucSckPin, GPIO_DIR_OUTPUT)
#define SET_SCK_IN(uiIndex) Hv_Cal_Gpio_SetDirection(s_stgpiosimswire[uiIndex].ucSckPin, GPIO_DIR_INPUT)
#define SET_SDT_OUT(uiIndex) Hv_Cal_Gpio_SetDirection(s_stgpiosimswire[uiIndex].ucSdtPin, GPIO_DIR_OUTPUT)
#define SET_SDT_IN(uiIndex) Hv_Cal_Gpio_SetDirection(s_stgpiosimswire[uiIndex].ucSdtPin, GPIO_DIR_INPUT)
#define SET_SCK_HIGH(uiIndex) Hv_Cal_Gpio_SetPinLevel(s_stgpiosimswire[uiIndex].ucSckPin, GPIO_LEVEL_HIGH)
#define SET_SCK_LOW(uiIndex) Hv_Cal_Gpio_SetPinLevel(s_stgpiosimswire[uiIndex].ucSckPin, GPIO_LEVEL_LOW)
#define SET_SDT_HIGH(uiIndex) Hv_Cal_Gpio_SetPinLevel(s_stgpiosimswire[uiIndex].ucSdtPin, GPIO_LEVEL_HIGH)
#define SET_SDT_LOW(uiIndex) Hv_Cal_Gpio_SetPinLevel(s_stgpiosimswire[uiIndex].ucSdtPin, GPIO_LEVEL_LOW)
#define GET_SDT_LEVEL(uiIndex) Hv_Cal_Gpio_GetPinLevel(s_stgpiosimswire[uiIndex].ucSdtPin)
#define GET_SCK_TWHL(uiIndex) (s_stgpiosimswire[uiIndex].ucTWHL)
#define GET_SDT_SCK_TSU(uiIndex) (s_stgpiosimswire[uiIndex].ucTSU)
#define GET_SDT_SCK_THL(uiIndex) (s_stgpiosimswire[uiIndex].ucTHL)
/* 1nop about 13 ns */
static inline VOID GpioSimSWire_Delay_Nop(UINT32 uiNop)
{
HV_ASSERT_TRUE_VOID(uiNop > 0);
while(uiNop--)
{
asm("nop");
}
return;
}
/** Initialize gpio simulate single wire
* @param pstGpioSimSwire pointer to swire configuration parameters
* @param enBus select sginle wire bus id
* @return SUCCESS/FAILURE
*/
Status Hv_Drv_GpioSimSWire_Init(const GpioSimSWire *pstGpioSimSwire)
{
HV_ASSERT_VALID_PTR_RET(pstGpioSimSwire, HV_FAILURE);
HV_ASSERT_TRUE(pstGpioSimSwire->enBus < SIMSWIRE_ID_MAX);
memcpy(&s_stgpiosimswire[pstGpioSimSwire->enBus], pstGpioSimSwire, sizeof(GpioSimSWire));
SET_SCK_OUT(pstGpioSimSwire->enBus);
SET_SDT_OUT(pstGpioSimSwire->enBus);
SET_SCK_LOW(pstGpioSimSwire->enBus);
SET_SDT_LOW(pstGpioSimSwire->enBus);
return HV_SUCCESS;
}
/** Swire start signal
*@SCK and SDT keep low
*/
VOID Hv_GpioSimSWire_Start(UINT32 uiIndex)
{
SET_SCK_OUT(uiIndex);
SET_SDT_OUT(uiIndex);
SET_SDT_LOW(uiIndex);
SET_SCK_LOW(uiIndex);
return;
}
/** Swire stop signal
*@SCK and SDT keep Low
*/
VOID Hv_GpioSimSWire_Stop(UINT32 uiIndex)
{
SET_SCK_OUT(uiIndex);
SET_SDT_OUT(uiIndex);
SET_SDT_LOW(uiIndex);
SET_SCK_LOW(uiIndex);
return;
}
/** send data 1 byte
*@ Send data bit by bit and MSB first;
*@ When SCK keep high, data is valid;
*/
VOID Hv_GpioSimSWire_Send_Bit(UINT32 uiIndex, UCHAR8 ucBit)
{
SET_SDT_OUT(uiIndex);
SET_SCK_LOW(uiIndex);
if (ucBit)
{
SET_SDT_HIGH(uiIndex);
}
else
{
SET_SDT_LOW(uiIndex);
}
GpioSimSWire_Delay_Nop(GET_SDT_SCK_TSU(uiIndex));
SET_SCK_HIGH(uiIndex);
GpioSimSWire_Delay_Nop(GET_SCK_TWHL(uiIndex));
SET_SCK_LOW(uiIndex);
GpioSimSWire_Delay_Nop(GET_SDT_SCK_THL(uiIndex));
SET_SDT_LOW(uiIndex);
return;
}
/** receive 1 bit
*@Pull SCK high, to read SDT data from slave device bit by bit
*/
UCHAR8 Hv_GpioSimSWire_Recv_Bit(UINT32 uiIndex)
{
UCHAR8 ucBit = 0x0;
UCHAR8 ucStep = 0;
SET_SDT_IN(uiIndex);
SET_SCK_LOW(uiIndex);
GpioSimSWire_Delay_Nop(GPIOSIMSWIRE_DELAY);
SET_SCK_HIGH(uiIndex);
if (GET_SDT_LEVEL(uiIndex))
{
ucBit = ucBit | 0x01;
}
GpioSimSWire_Delay_Nop(GPIOSIMSWIRE_DELAY);
SET_SCK_LOW(uiIndex);
return ucBit;
}
/** send data 1 byte
*@ Send data bit by bit and MSB first;
*@ When SCK keep high, data is valid;
*/
VOID Hv_GpioSimSWire_Send_Byte(UINT32 uiIndex, UCHAR8 ucByte)
{
UCHAR8 ucStep = 0;
SET_SDT_OUT(uiIndex);
SET_SCK_LOW(uiIndex);
for (ucStep = 0;ucStep < 8; ucStep++)
{
if ((ucByte<