547 lines
15 KiB
C
Executable File
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;
|
|
}
|