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.
Diff: ADMX2001.cpp
- Revision:
- 2:4af4940055a7
- Parent:
- 1:416c87ab2f9f
- Child:
- 4:eb7a23c25751
--- a/ADMX2001.cpp Tue May 25 15:45:50 2021 +0000
+++ b/ADMX2001.cpp Tue Oct 05 10:31:50 2021 +0000
@@ -0,0 +1,325 @@
+/******************************************************************************
+ 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 "admx200x.h"
+#include "admx200x_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;
+}
+
+/**
+ * @}
+ */
