osd-contiki/ADF7023.c

285 lines
10 KiB
C
Raw Normal View History

/***************************************************************************//**
* @file ADF7023.c
* @brief Implementation of ADF7023 Driver.
* @author DBogdan (Dragos.Bogdan@analog.com)
********************************************************************************
* Copyright 2013(c) Analog Devices, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
********************************************************************************
* SVN Revision: $WCREV$
*******************************************************************************/
/******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
#include "ADF7023.h"
#include "ADF7023_Config.h"
#include "Communication.h"
/******************************************************************************/
/*************************** Macros Definitions *******************************/
/******************************************************************************/
#define ADF7023_CS_ASSERT CS_PIN_LOW
#define ADF7023_CS_DEASSERT CS_PIN_HIGH
#define ADF7023_MISO MISO_PIN
/******************************************************************************/
/************************ Variables Definitions *******************************/
/******************************************************************************/
struct ADF7023_BBRAM ADF7023_BBRAMCurrent;
/***************************************************************************//**
* @brief Transfers one byte of data.
*
* @param writeByte - Write data.
* @param readByte - Read data.
*
* @return None.
*******************************************************************************/
void ADF7023_WriteReadByte(unsigned char writeByte,
unsigned char* readByte)
{
unsigned char data = 0;
data = writeByte;
SPI_Read(0, &data, 1);
if(readByte)
{
*readByte = data;
}
}
/***************************************************************************//**
* @brief Initializes the ADF7023.
*
* @return retVal - Result of the initialization procedure.
* Example: 0 - if initialization was successful;
* -1 - if initialization was unsuccessful.
*******************************************************************************/
char ADF7023_Init(void)
{
char retVal = 0;
unsigned char miso = 0;
unsigned short timeout = 0;
unsigned char status = 0;
ADF7023_BBRAMCurrent = ADF7023_BBRAMDefault;
SPI_Init(0, // MSB first.
1000000, // Clock frequency.
0, // Idle state for clock is a high level; active state is a low level.
1); // Serial output data changes on transition from idle clock state to active clock state.
ADF7023_CS_ASSERT;
while ((miso == 0) && (timeout < 1000))
{
miso = ADF7023_MISO;
timeout++;
}
if(timeout == 1000)
{
retVal = -1;
}
while(!(status & STATUS_CMD_READY))
{
ADF7023_GetStatus(&status);
}
ADF7023_SetRAM(0x100, 64, (unsigned char*)&ADF7023_BBRAMCurrent);
ADF7023_SetCommand(CMD_CONFIG_DEV);
return retVal;
}
/***************************************************************************//**
* @brief Reads the status word of the ADF7023.
*
* @param status - Status word.
*
* @return None.
*******************************************************************************/
void ADF7023_GetStatus(unsigned char* status)
{
ADF7023_CS_ASSERT;
ADF7023_WriteReadByte(SPI_NOP, 0);
ADF7023_WriteReadByte(SPI_NOP, status);
ADF7023_CS_DEASSERT;
}
/***************************************************************************//**
* @brief Initiates a command.
*
* @param command - Command.
*
* @return None.
*******************************************************************************/
void ADF7023_SetCommand(unsigned char command)
{
ADF7023_CS_ASSERT;
ADF7023_WriteReadByte(command, 0);
ADF7023_CS_DEASSERT;
}
/***************************************************************************//**
* @brief Sets a FW state and waits until the device enters in that state.
*
* @param fwState - FW state.
*
* @return None.
*******************************************************************************/
void ADF7023_SetFwState(unsigned char fwState)
{
unsigned char status = 0;
switch(fwState)
{
case FW_STATE_PHY_OFF:
ADF7023_SetCommand(CMD_PHY_OFF);
break;
case FW_STATE_PHY_ON:
ADF7023_SetCommand(CMD_PHY_ON);
break;
case FW_STATE_PHY_RX:
ADF7023_SetCommand(CMD_PHY_RX);
break;
case FW_STATE_PHY_TX:
ADF7023_SetCommand(CMD_PHY_TX);
break;
default:
ADF7023_SetCommand(CMD_PHY_SLEEP);
}
while((status & STATUS_FW_STATE) != fwState)
{
ADF7023_GetStatus(&status);
}
}
/***************************************************************************//**
* @brief Reads data from the RAM.
*
* @param address - Start address.
* @param length - Number of bytes to write.
* @param data - Read buffer.
*
* @return None.
*******************************************************************************/
void ADF7023_GetRAM(unsigned long address,
unsigned long length,
unsigned char* data)
{
ADF7023_CS_ASSERT;
ADF7023_WriteReadByte(SPI_MEM_RD | ((address & 0x700) >> 8), 0);
ADF7023_WriteReadByte(address & 0xFF, 0);
ADF7023_WriteReadByte(SPI_NOP, 0);
while(length--)
{
ADF7023_WriteReadByte(SPI_NOP, data++);
}
ADF7023_CS_DEASSERT;
}
/***************************************************************************//**
* @brief Writes data to RAM.
*
* @param address - Start address.
* @param length - Number of bytes to write.
* @param data - Write buffer.
*
* @return None.
*******************************************************************************/
void ADF7023_SetRAM(unsigned long address,
unsigned long length,
unsigned char* data)
{
ADF7023_CS_ASSERT;
ADF7023_WriteReadByte(SPI_MEM_WR | ((address & 0x700) >> 8), 0);
ADF7023_WriteReadByte(address & 0xFF, 0);
while(length--)
{
ADF7023_WriteReadByte(*(data++), 0);
}
ADF7023_CS_DEASSERT;
}
/***************************************************************************//**
* @brief Receives one packet.
*
* @param packet - Data buffer.
* @param length - Number of received bytes.
*
* @return None.
*******************************************************************************/
void ADF7023_ReceivePacket(unsigned char* packet, unsigned char* length)
{
unsigned char interruptReg = 0;
ADF7023_SetFwState(FW_STATE_PHY_ON);
ADF7023_SetFwState(FW_STATE_PHY_RX);
while(!(interruptReg & BBRAM_INTERRUPT_MASK_0_INTERRUPT_CRC_CORRECT))
{
ADF7023_GetRAM(MCR_REG_INTERRUPT_SOURCE_0,
0x1,
&interruptReg);
}
ADF7023_SetRAM(MCR_REG_INTERRUPT_SOURCE_0,
0x1,
&interruptReg);
ADF7023_GetRAM(0x10, 1, length);
ADF7023_GetRAM(0x12, *length - 2, packet);
}
/***************************************************************************//**
* @brief Transmits one packet.
*
* @param packet - Data buffer.
* @param length - Number of bytes to transmit.
*
* @return None.
*******************************************************************************/
void ADF7023_TransmitPacket(unsigned char* packet, unsigned char length)
{
unsigned char interruptReg = 0;
unsigned char header[2] = {0, 0};
header[0] = 2 + length;
header[1] = ADF7023_BBRAMCurrent.addressMatchOffset;
ADF7023_SetRAM(0x10, 2, header);
ADF7023_SetRAM(0x12, length, packet);
ADF7023_SetFwState(FW_STATE_PHY_ON);
ADF7023_SetFwState(FW_STATE_PHY_TX);
while(!(interruptReg & BBRAM_INTERRUPT_MASK_0_INTERRUPT_TX_EOF))
{
ADF7023_GetRAM(MCR_REG_INTERRUPT_SOURCE_0,
0x1,
&interruptReg);
}
}