Files
smod_atsc_app/atsc_app/adi_hal/adi_hal.c
T

547 lines
15 KiB
C
Executable File

/**
* \file adi_hal.c
* \brief Contains ADI Hardware Abstraction functions
* End user must provide implementation based on their
* application and hardware platform.
*
* This file provides the ADI Evaluation platform implementation
* that will not be compiled unless the compiler option ADI_ZYNQ_PLATFORM
* is defined at compile time.
*
* Copyright 2015-2017 Analog Devices Inc.
* Released under the AD9378-AD9379 API license, for more information see the "LICENSE.txt" file in this zip file.
*/
#include "adi_hal.h"
#include "unistd.h"
#include "stdio.h"
#ifdef ADI_ZYNQ_PLATFORM
#include "zynq_platform.h"
#endif
//#include "../common.h"
#include "../inc/type.h"
#include "../adrv9009/adrv9009.h"
adiHalErr_t ADIHAL_setTimeout(void *devHalInfo, uint32_t halTimeout_ms)
{
adiHalErr_t retVal = ADIHAL_OK;
#ifdef ADI_ZYNQ_PLATFORM
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
devHalData->waitTimeout = halTimeout_ms;
HAL_writeToLogFile("ADIHAL_setTimeout at index %d to ", devHalData->devIndex, halTimeout_ms);
#endif
return retVal;
}
adiHalErr_t ADIHAL_openHw(void *devHalInfo, uint32_t halTimeout_ms)
{
adiHalErr_t retVal = ADIHAL_OK;
#ifdef ADI_ZYNQ_PLATFORM
int32_t error = 0;
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
devHalData->waitTimeout = halTimeout_ms;
switch(devHalData->devIndex)
{
/* SPI Devices*/
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
error = HAL_initSpiDriver(devHalData->spiSettings);
break;
default:
HAL_writeToLogFile("ERROR: ADIHAL_openHw: Unknown device index %d", devHalData->devIndex);
return (ADIHAL_GEN_SW);
}
HAL_writeToLogFile("ADIHAL_openHw: device index %d", devHalData->devIndex);
if (error != 0)
{
devHalData->spiErrCode = error;
HAL_writeToLogFile("ERROR: ADIHAL_openHw: HAL_initSpiDriver() failed with error %d for device %d", error, devHalData->devIndex);
retVal = ADIHAL_SPI_FAIL;
}
#endif
return (retVal);
}
adiHalErr_t ADIHAL_closeHw(void *devHalInfo)
{
adiHalErr_t retVal = ADIHAL_OK;
#ifdef ADI_ZYNQ_PLATFORM
int32_t error = 0;
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
switch(devHalData->devIndex)
{
/* SPI Devices */
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
error = HAL_closeSpiDriver(devHalData->spiSettings);
break;
default:
HAL_writeToLogFile("ERROR: ADIHAL_closeHw(): Unknown device index %d", devHalData->devIndex);
return (ADIHAL_GEN_SW);
}
HAL_writeToLogFile("ADIHAL_closeHw: device index %d", devHalData->devIndex);
if (error != 0)
{
devHalData->spiErrCode = error;
HAL_writeToLogFile("ERROR: ADIHAL_closeHw: HAL_closeSpiDriver() failed with error %d for device %d", error, devHalData->devIndex);
return (ADIHAL_SPI_FAIL);
}
#endif
return(retVal);
}
adiHalErr_t ADIHAL_resetHw(void *devHalInfo)
{
adiHalErr_t retVal = ADIHAL_OK;
int *pChipNo = (int *)devHalInfo;
retVal = (adiHalErr_t)ad9009_reset(*pChipNo);
#ifdef ADI_ZYNQ_PLATFORM
int32_t error = 0;
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
HAL_writeToLogFile("ADIHAL_resetHw at index %d", devHalData->devIndex);
error = HAL_resetHw(devHalData->devIndex);
if (error != 0)
{
devHalData->gpioErrCode = error;
HAL_writeToLogFile("ERROR: ADIHAL_resetHw: HAL_resetHw() failed with error %d for device %d", error, devHalData->devIndex);
return (ADIHAL_GPIO_FAIL);
}
#endif
return (retVal);
}
adiHalErr_t ADIHAL_spiWriteByte(void *devHalInfo, uint16_t addr, uint8_t data)
{
adiHalErr_t retVal = ADIHAL_OK;
int *pChipNo = (int*)devHalInfo;
u32 wr_value = data;
//retVal = (adiHalErr_t)write_ad9009(*pChipNo, addr, wr_value);
retVal = (adiHalErr_t)ad9009_write_spi(*pChipNo, addr, &wr_value, 1);
#ifdef ADI_ZYNQ_PLATFORM
int32_t error = 0;
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
error = HAL_SPIWriteByte(devHalData->spiSettings, addr, data);
if (error < 0)
{
devHalData->spiErrCode = error;
HAL_writeToLogFile("ERROR: ADIHAL_spiWriteByte(): HAL_SPIWriteByte() for device %d, chipSelect %d, returned error %d\n",
devHalData->devIndex, devHalData->spiSettings->chipSelectIndex, error);
return (ADIHAL_SPI_FAIL);
}
if (devHalData->logLevel & ADIHAL_LOG_SPI)
{
HAL_writeToLogFile("SPIWrite: CS:%2d, ADDR:0x%03X, DATA:0x%02X \n", devHalData->spiSettings->chipSelectIndex, addr, data);
}
#endif
return (retVal);
}
/*#if 0
#include "stdio.h"
#include <unistd.h>
#include <sys/time.h>
#include <unistd.h>
void usr_print_current_time(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
printf("time: %d.%d\n",tv.tv_sec,tv.tv_usec/1000);
}
int get_current_time_ms(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec*1000+tv.tv_usec/1000);
//printf("time: %d.%d\n",tv.tv_sec,tv.tv_usec/1000);
}
//#include "fpga.h"
void test_fpga_write_time()
{
// fpga write need 10ms
int time_start=0;
int time_stop=0;
int count=500;
time_start = get_current_time_ms();
for (u32 i = 0; i < count; i++)
{
//fpga_write(0x110, 0, 1);;
}
time_stop = get_current_time_ms();
printf("{time_cal fpga_write} count=%d total_time=%dms avg_time=%dms\n", count, time_stop - time_start, (time_stop - time_start)/count);
}
int time_start=0;
int time_stop=0;
#endif*/
adiHalErr_t ADIHAL_spiWriteBytes(void *devHalInfo, uint16_t *addr, uint8_t *data, uint32_t count)
{
adiHalErr_t retVal = ADIHAL_OK;
//test_fpga_write_time();
//printf("[%s,%d] start. count=%d addr=0x%x\n", __FUNCTION__, __LINE__, count, addr);
//usr_print_current_time();
//time_start = get_current_time_ms();
for (u32 i = 0; i < count; i++)
{
//printf("[%s,%d] start. count=%d addr=0x%x\n", __FUNCTION__, __LINE__, 1, addr);
if (ADIHAL_OK != (retVal = (adiHalErr_t)ADIHAL_spiWriteByte(devHalInfo, *(addr + i), *(data + i))))
//printf("[%s,%d] w_err. count=%d addr=0x%x\n", __FUNCTION__, __LINE__, 1, addr);
break;
//printf("[%s,%d] w_okk. count=%d addr=0x%x\n", __FUNCTION__, __LINE__, 1, addr);
}
//time_stop = get_current_time_ms();
//printf("{time_cal} count=%d total_time=%dms avg_time=%dms\n", count, time_stop - time_start, (time_stop - time_start)/count);
#ifdef ADI_ZYNQ_PLATFORM
int32_t error = 0;
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
uint32_t i = 0;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
error = HAL_SPIWriteBytes(devHalData->spiSettings, addr, data, count);
if (error < 0)
{
devHalData->spiErrCode = error;
HAL_writeToLogFile("ERROR: ADIHAL_spiWriteBytes(): HAL_SPIWriteBytes() for device %d, chipSelect %d, returned error %d\n",
devHalData->devIndex, devHalData->spiSettings->chipSelectIndex, error);
return (ADIHAL_SPI_FAIL);
}
if (devHalData->logLevel & ADIHAL_LOG_SPI)
{
for(i = 0; i < count; i++)
{
HAL_writeToLogFile("SPIWrite: CS:%2d, ADDR:0x%03X, DATA:0x%02X \n", devHalData->spiSettings->chipSelectIndex, addr[i], data[i]);
}
}
#endif
return (retVal);
}
adiHalErr_t ADIHAL_spiReadByte(void *devHalInfo, uint16_t addr, uint8_t *readdata)
{
adiHalErr_t retVal = ADIHAL_OK;
int *pChipNo = (int *)devHalInfo;
unsigned int value;
//retVal = (adiHalErr_t)read_ad9009_value(*pChipNo, addr, &value);
//ad9009_read_spi(int num, u32 addr, u32 *pdata, u32 count)
retVal = (adiHalErr_t)ad9009_read_spi(*pChipNo, addr, &value, 1);
*readdata = value;
#ifdef ADI_ZYNQ_PLATFORM
int32_t error = 0;
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
error = HAL_SPIReadByte(devHalData->spiSettings, addr, readdata);
if (error < 0)
{
devHalData->spiErrCode = error;
HAL_writeToLogFile("ERROR: HAL_SPIReadByte() returned error %d, reading from device %d, ChipSelect:%d\n",
error, devHalData->devIndex, devHalData->spiSettings->chipSelectIndex);
return (ADIHAL_SPI_FAIL);
}
if (devHalData->logLevel & ADIHAL_LOG_SPI)
{
HAL_writeToLogFile("SPIRead: CS:%2d, ADDR:0x%03X, ReadData:0x%02X\n",
devHalData->devIndex, addr, *readdata);
}
#endif
return (retVal);
}
adiHalErr_t ADIHAL_spiReadBytes(void *devHalInfo, uint16_t *addr, uint8_t *readdata, uint32_t count)
{
adiHalErr_t retVal = ADIHAL_OK;
for (int i = 0; i < count; i++)
{
if (ADIHAL_OK != (retVal = ADIHAL_spiReadByte(devHalInfo, *(addr + i), readdata + i)))
break;
}
#ifdef ADI_ZYNQ_PLATFORM
int32_t error = 0;
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
uint32_t i = 0;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
error = HAL_SPIReadBytes(devHalData->spiSettings, addr, readdata, count);
if (error < 0)
{
devHalData->spiErrCode = error;
HAL_writeToLogFile("ERROR: ADIHAL_spiWriteBytes(): HAL_SPIReadBytes() for device %d, chipSelect %d, returned error %d\n",
devHalData->devIndex, devHalData->spiSettings->chipSelectIndex, error);
return (ADIHAL_SPI_FAIL);
}
if (devHalData->logLevel & ADIHAL_LOG_SPI)
{
for(i = 0; i < count; i++)
{
HAL_writeToLogFile("SPIRead: CS:%2d, ADDR:0x%03X, ReadData:0x%02X\n",
devHalData->devIndex, addr[i], readdata[i]);
}
}
#endif
return (retVal);
}
adiHalErr_t ADIHAL_spiWriteField(void *devHalInfo,
uint16_t addr, uint8_t fieldVal, uint8_t mask, uint8_t startBit)
{
adiHalErr_t retVal = ADIHAL_OK;
uint8_t readVal = 0;
if (ADIHAL_OK != (retVal = ADIHAL_spiReadByte(devHalInfo, addr, &readVal)))
return retVal;
readVal = (readVal & ~mask) | ((fieldVal << startBit) & mask);
retVal = ADIHAL_spiWriteByte(devHalInfo, addr, readVal);
#ifdef ADI_ZYNQ_PLATFORM
uint8_t readVal = 0;
int32_t error = 0;
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
error = HAL_SPIReadByte(devHalData->spiSettings, addr, &readVal);
if (error < 0)
{
devHalData->spiErrCode = error;
HAL_writeToLogFile("ERROR: HAL_SPIReadByte() returned error %d in ADIHAL_spiWriteField()\n", error);
return (ADIHAL_SPI_FAIL);
}
readVal = (readVal & ~mask) | ((fieldVal << startBit) & mask);
error = HAL_SPIWriteByte(devHalData->spiSettings, addr, readVal);
if (error < 0 )
{
devHalData->spiErrCode = error;
HAL_writeToLogFile("ERROR: HAL_SPIWriteByte() returned error %d in ADIHAL_spiWriteField()\n", error);
return (ADIHAL_SPI_FAIL);
}
if (devHalData->logLevel & ADIHAL_LOG_SPI)
{
HAL_writeToLogFile("SPIWriteField: CS:%2d, ADDR:0x%03X, FIELDVAL:0x%02X, MASK:0x%02X, STARTBIT:%d\n",
devHalData->devIndex,addr, fieldVal, mask, startBit);
}
#endif
return (retVal);
}
adiHalErr_t ADIHAL_spiReadField(void *devHalInfo, uint16_t addr, uint8_t *fieldVal, uint8_t mask, uint8_t startBit)
{
adiHalErr_t retVal = ADIHAL_OK;
uint8_t readVal = 0;
if (ADIHAL_OK != (retVal = ADIHAL_spiReadByte(devHalInfo, addr, &readVal)))
return retVal;
*fieldVal = ((readVal & mask) >> startBit);
#ifdef ADI_ZYNQ_PLATFORM
uint8_t readVal = 0;
int32_t error = 0;
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
error = HAL_SPIReadByte(devHalData->spiSettings, addr, &readVal);
if (error < 0)
{
devHalData->spiErrCode = error;
HAL_writeToLogFile("ERROR: HAL_SPIReadByte() returned error %d in ADIHAL_spiReadField()\n", error);
return (ADIHAL_SPI_FAIL);
}
*fieldVal = ((readVal & mask) >> startBit);
if(devHalData->logLevel & ADIHAL_LOG_SPI)
{
HAL_writeToLogFile("SPIReadField: CS:%2d, ADDR:0x%03X, MASK:0x%02X, STARTBIT:%d, FieldVal:0x%02X\n",
devHalData->devIndex,addr, mask, startBit, *fieldVal);
}
#endif
return (retVal);
}
adiHalErr_t ADIHAL_wait_us(void *devHalInfo, uint32_t time_us)
{
adiHalErr_t retVal = ADIHAL_OK;
usleep(time_us);
#ifdef ADI_ZYNQ_PLATFORM
int32_t error = 0;
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
error = HAL_wait_us(time_us);
if (error != 0)
{
devHalData->timerErrCode = error;
HAL_writeToLogFile("ERROR: HAL_wait_us() returned error %d in ADIHAL_wait_us()\n", error);
return (ADIHAL_TIMER_FAIL);
}
#endif
return (retVal);
}
adiHalErr_t ADIHAL_writeToLog(void *devHalInfo, adiLogLevel_t logLevel, uint32_t errorCode, const char *comment)
{
adiHalErr_t retVal = ADIHAL_OK;
#ifdef ADI_ZYNQ_PLATFORM
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
int32_t error = 0;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
if((devHalData->logLevel & ADIHAL_LOG_ERR) && (logLevel == ADIHAL_LOG_ERR))
{
error = HAL_writeToLogFile("ERROR: %d: %s", (int)errorCode, comment);
}
else if((devHalData->logLevel & ADIHAL_LOG_WARN) && (logLevel == ADIHAL_LOG_WARN))
{
error = HAL_writeToLogFile("WARNING: %d: %s", (int)errorCode, comment);
}
else if((devHalData->logLevel & ADIHAL_LOG_MSG) && (logLevel == ADIHAL_LOG_MSG))
{
error = HAL_writeToLogFile("MESSAGE: %d: %s",(int)errorCode, comment);
}
else
{
error = HAL_writeToLogFile("Undefined Log Level: 0x%X: %d: %s", logLevel, (int)errorCode, comment);
}
if(error != 0)
{
retVal = ADIHAL_WARNING;
}
#endif
return (retVal);
}
adiHalErr_t ADIHAL_setLogLevel(void *devHalInfo, uint16_t logLevel)
{
adiHalErr_t retVal = ADIHAL_OK;
#ifdef ADI_ZYNQ_PLATFORM
zynqAdiDev_t *devHalData = (zynqAdiDev_t *)devHalInfo;
if(devHalInfo == NULL)
{
return (ADIHAL_GEN_SW);
}
devHalData->logLevel = logLevel;
#endif
return retVal;
}