/** * @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<