Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
ADMX2001.cpp
- Committer:
- nsheth
- Date:
- 2021-10-07
- Revision:
- 5:b9608e6cc24b
- Parent:
- 4:eb7a23c25751
- Child:
- 6:7d8f30b3bc57
File content as of revision 5:b9608e6cc24b:
/******************************************************************************
Copyright (c) 2020 - 2021 Analog Devices Inc. All Rights Reserved.
This software is proprietary & confidential to Analog Devices, Inc.
and its licensors.
******************************************************************************/
/**
* @file admx200x.c
* @brief This file contains admx200x APIs for sdpk1 host
* @addtogroup SDPK1
* @{
*/
/*============= I N C L U D E S =============*/
#include "ADMX2001.h"
#include "ADMX2001_commands.h"
#include "message.h"
#include <stdlib.h>
#include <string.h>
static uint32_t SwapEndian(uint32_t *pData);
/** milli second delay**/
static void Admx200xDelay(uint32_t msec);
/**
* Swaps endian of a 32 bit number
* @param data - 32 bit number
* @return
*/
uint32_t SwapEndian(uint32_t *pData)
{
uint8_t *pDataU8 = (uint8_t *)pData;
return (uint32_t)pDataU8[0] << 24 | (uint32_t)pDataU8[1] << 16 |
(uint32_t)pDataU8[2] << 8 | (uint32_t)pDataU8[3];
}
/**
* @brief Initializes the ADMX200X.
*
* @param pDevice - The device structure.
* @param pSpiDesc - Pointer to spi device
* @return Returns 0 for success or negative error code.
*/
int32_t Admx200xInit(Admx200xDev *pDevice, spi_desc *pSpiDesc)
{
int32_t ret = 0;
pDevice->pSpiDesc = pSpiDesc;
return ret;
}
/**
* Wrapper fro delay
* @param msecs - delay in milliseconds
*/
void Admx200xDelay(uint32_t msecs)
{
mdelay(msecs);
}
/**
* @brief Create a command payload in buffer with inputs.
*
* @param pCmdId - Command ID.
* @param pAddr - Sub commands addresses.
* @param pData - Data to wildcat.
* @param pBuffer - Data to wildcat.
*
* @return Returns 0 for success or negative error code.
*/
int32_t Admx200xCreateCmdPayload(uint8_t *pCmdId, uint16_t *pAddr,
uint32_t *pData, uint8_t *pBuffer)
{
int32_t ret = 0;
//DEBUG_MSG("cmd:%d,addr:%d, data: 0x%x\n\r", *pCmdId, *pAddr, *pData);
pBuffer[0] = pCmdId[0];
pBuffer[1] = ((uint8_t *)pAddr)[1];
pBuffer[2] = ((uint8_t *)pAddr)[0];
pBuffer[3] = ((uint8_t *)pData)[3];
pBuffer[4] = ((uint8_t *)pData)[2];
pBuffer[5] = ((uint8_t *)pData)[1];
pBuffer[6] = ((uint8_t *)pData)[0];
return ret;
}
/**
* @brief Parse the payload to get cmdID, addr and data.
* @param[in] pBuffer - Data from wildcat.
* @param[out] pCmdId - Pointer to store Command ID.
* @param[out] pAddr - Pointer to store addresses.
* @param[out] pData - Pointer to store Data
*
* @return Returns 0 for success or negative error code.
*/
int32_t Admx200xParseCmdPayload(uint8_t *pBuffer, uint8_t *pCmdId,
uint16_t *pAddr, uint32_t *pData)
{
int32_t ret = 0;
*pCmdId = pBuffer[0];
*pAddr = ((uint16_t)pBuffer[1] << 8) | ((uint16_t)pBuffer[2]);
*pData = SwapEndian((uint32_t *)&pBuffer[3]);
return ret;
}
/**
* @brief Waits till done bit is set in the status
*
* @param pDevice - The handler of the instance of the driver.
* @param timeout - Count representing the number of polls to be done until the
* function returns if no new data is available.
* @param reqStatus - The status to be checked is passed via this argument.
* @param pStatReg - Get the status word in pStatReg.
*
* @return Returns 0 for success or negative error code.
*/
int32_t Admx200xWaitForStatus(Admx200xDev *pDevice, uint32_t timeout,
uint32_t reqStatus, uint32_t *pStatReg)
{
int32_t status = ADMX_STATUS_SUCCESS;
int8_t done = 0;
uint8_t cmdId = CMD_STATUS_READ;
if (pDevice != NULL)
{
while (!done && --timeout)
{
status = Admx200xReadData(pDevice, cmdId, pStatReg);
if (status == 0)
{
/* Check the DONE bit in the Status Register */
if (((*pStatReg) & reqStatus) == reqStatus)
{
done = 1;
if (*pStatReg & ADMX200X_STATUS_ERROR_BITM)
{
status = *pStatReg & ADMX200X_STATUS_CODE_BITM;
if (status & ADMX_STATUS_LOG_ZERO_ERROR)
{
ERROR_MSG("sweep_start/sweep_end cannot be zero "
"for logarithmic sweep");
status &= (~ADMX_STATUS_LOG_ZERO_ERROR);
}
if (status & ADMX_STATUS_LOG_SIGN_ERROR)
{
ERROR_MSG("sweep_start and sweep_end need to have "
"the same sign "
"for logarithmic sweep");
status &= (~ADMX_STATUS_LOG_SIGN_ERROR);
}
if (status & ADMX_STATUS_VOLT_ADC_ERROR)
{
ERROR_MSG("Voltage ADC Saturated\n");
status &= (~ADMX_STATUS_VOLT_ADC_ERROR);
}
if (status & ADMX_STATUS_CURR_ADC_ERROR)
{
ERROR_MSG("Current ADC Saturated\n");
status &= (~ADMX_STATUS_CURR_ADC_ERROR);
}
if (status & ADMX_STATUS_FIFO_ERROR)
{
ERROR_MSG(
"FIFO either Overflowed or Underflowed\n");
status &= (~ADMX_STATUS_FIFO_ERROR);
}
if (status & ADMX_STATUS_COUNT_EXCEEDED)
{
ERROR_MSG("Sweep count exceeded maximum value");
status &= (~ADMX_STATUS_COUNT_EXCEEDED);
}
}
}
}
}
if (!timeout)
{
status = ADMX_STATUS_TIMEOUT;
}
}
else
{
status = ADMX_STATUS_FAILED;
}
return status;
}
/**
* @brief Sends teh command to ADMX200x and wait till done bit is set
* @param pDevice - Device Handle
* @param pCmdId - The command ID
* @param pAddr - Address
* @param pData - Data
* @param pStatReg - Status register info
* @return Returns 0 for success or negative error code.
*/
int32_t Admx200xSendCmd(Admx200xDev *pDevice, uint8_t *pCmdId, uint16_t *pAddr,
uint32_t *pData, uint32_t *pStatReg)
{
int32_t status = ADMX_STATUS_SUCCESS;
uint8_t cmdPayload[ADMX200X_CMD_LENGTH];
Admx200xCreateCmdPayload(pCmdId, pAddr, pData, &cmdPayload[0]);
status = spi_write_and_read(pDevice->pSpiDesc, &cmdPayload[0],
ADMX200X_CMD_LENGTH);
Admx200xDelay(100);
// printf("CMD :%02x ADDR: %04x DATA: %08x\n\r",*pCmdId, *pAddr, *pData);
if (!status)
{
/** Wait for status done = 1,Warn/error/command result = 0 from result
*/
status = Admx200xWaitForStatus(pDevice, SPI_TIMEOUT,
ADMX200X_STATUS_DONE_BITM, pStatReg);
// printf("Stat Reg: %08x\n\r", *pStatReg);
if (status == ADMX_STATUS_SUCCESS)
{
status = *pStatReg & ADMX200X_STATUS_CODE_BITM;
}
}
if (status == ADMX_STATUS_TIMEOUT)
{
ERROR_MSG("SPI interface timed out : Not responding");
}
return status;
}
/**
* @brief Read result register from the WILDCAT
* @param pDevice - Device Handle
* @param cmdId - This determines where the data is read from - result
* register, status register or Fifo
* @param pResult - The data in the result register
* @return Returns 0 for success or negative error code.
*/
int32_t Admx200xReadData(Admx200xDev *pDevice, uint8_t cmdId, uint32_t *pResult)
{
int32_t ret = ADMX_STATUS_SUCCESS;
uint8_t cmdTemp;
uint16_t addrTemp;
uint16_t addr;
uint32_t data;
uint8_t cmdPayload[ADMX200X_CMD_LENGTH];
/*FIXME: Insert checks here. Not all command IDs are accepted here */
addr = 0;
data = 0;
Admx200xCreateCmdPayload(&cmdId, &addr, &data, &cmdPayload[0]);
/* Send command and Read response from the slave */
ret = spi_write_and_read(pDevice->pSpiDesc, &cmdPayload[0],
ADMX200X_CMD_LENGTH);
Admx200xDelay(100);
Admx200xParseCmdPayload(&cmdPayload[0], &cmdTemp, &addrTemp, pResult);
return ret;
}
/**
* @brief Read array of datatype doube from the fifo of the WILDCAT
* @param pDevice - Device Handle
* @param pFifo - Double array that stores the data
* @param pCount - Stores the number of double values stored in the pFifo array
*/
int32_t Admx200xReadFifo(Admx200xDev *pDevice, double *pFifo, int32_t *pCount)
{
int32_t status = ADMX_STATUS_SUCCESS;
int32_t i;
uint32_t *pData = (uint32_t *)pFifo;
uint8_t cmdId = CMD_STATUS_READ;
uint32_t statusReg;
int32_t numDoublesInFifo;
status = Admx200xReadData(pDevice, cmdId, &statusReg);
/* Fifo depth in doubles */
numDoublesInFifo = (statusReg & ADMX200X_STATUS_FIFO_DEPTH_BITM) >> 17;
if (numDoublesInFifo < *pCount)
{
*pCount = numDoublesInFifo;
}
for (i = 0; i < *pCount; i++)
{
/* Read a double -- Split it into two reads for redability*/
Admx200xReadData(pDevice, CMD_FIFO_READ, &pData[2 * i]);
Admx200xReadData(pDevice, CMD_FIFO_READ, &pData[2 * i + 1]);
}
return status;
}
/**
* @brief Clears the Admx2001 SPI FIFO & errors
*
* @param pDevice - Device Handle
* @return Returns 0 for success or error code.
*/
int32_t Admx200xClearSPI(Admx200xDev *pDevice)
{
int32_t status = ADMX_STATUS_SUCCESS;
uint8_t cmdID;
uint16_t addr = 0;
uint32_t statReg = 0;
uint32_t data = 0;
cmdID = CMD_CLEAR_ERROR;
status = Admx200xSendCmd(pDevice, &cmdID, &addr, &data, &statReg);
return status;
}
/**
* @}
*/
