Ram Gandikota
/
IOTMetronome
FRDM K64F Metronome
Diff: easy-connect/mcr20a-rf-driver/source/MCR20Drv.c
- Revision:
- 0:dbad57390bd1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/easy-connect/mcr20a-rf-driver/source/MCR20Drv.c Sun May 14 18:37:05 2017 +0000 @@ -0,0 +1,675 @@ +/*! +* Copyright (c) 2015, Freescale Semiconductor, Inc. +* All rights reserved. +* +* \file MCR20Drv.c +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o 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. +* +* o Neither the name of Freescale Semiconductor, Inc. nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, 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. +*/ + + +/***************************************************************************** +* INCLUDED HEADERS * +*---------------------------------------------------------------------------* +* Add to this section all the headers that this module needs to include. * +*---------------------------------------------------------------------------* +*****************************************************************************/ + +#include "platform/arm_hal_interrupt.h" +#include "MCR20Drv.h" +#include "MCR20Reg.h" +#include "XcvrSpi.h" + + +/***************************************************************************** +* PRIVATE VARIABLES * +*---------------------------------------------------------------------------* +* Add to this section all the variables and constants that have local * +* (file) scope. * +* Each of this declarations shall be preceded by the 'static' keyword. * +* These variables / constants cannot be accessed outside this module. * +*---------------------------------------------------------------------------* +*****************************************************************************/ +uint32_t mPhyIrqDisableCnt = 1; + +/***************************************************************************** +* PUBLIC VARIABLES * +*---------------------------------------------------------------------------* +* Add to this section all the variables and constants that have global * +* (project) scope. * +* These variables / constants can be accessed outside this module. * +* These variables / constants shall be preceded by the 'extern' keyword in * +* the interface header. * +*---------------------------------------------------------------------------* +*****************************************************************************/ + +/***************************************************************************** +* PRIVATE FUNCTIONS PROTOTYPES * +*---------------------------------------------------------------------------* +* Add to this section all the functions prototypes that have local (file) * +* scope. * +* These functions cannot be accessed outside this module. * +* These declarations shall be preceded by the 'static' keyword. * +*---------------------------------------------------------------------------* +*****************************************************************************/ + +/***************************************************************************** +* PRIVATE FUNCTIONS * +*---------------------------------------------------------------------------* +* Add to this section all the functions that have local (file) scope. * +* These functions cannot be accessed outside this module. * +* These definitions shall be preceded by the 'static' keyword. * +*---------------------------------------------------------------------------* +*****************************************************************************/ + + +/***************************************************************************** +* PUBLIC FUNCTIONS * +*---------------------------------------------------------------------------* +* Add to this section all the functions that have global (project) scope. * +* These functions can be accessed outside this module. * +* These functions shall have their declarations (prototypes) within the * +* interface header file and shall be preceded by the 'extern' keyword. * +*---------------------------------------------------------------------------* +*****************************************************************************/ + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_Init +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_Init +( +void +) +{ + xcvr_spi_init(gXcvrSpiInstance_c); + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000); + + gXcvrDeassertCS_d(); + MCR20Drv_RST_B_Deassert(); + RF_IRQ_Init(); + RF_IRQ_Disable(); + mPhyIrqDisableCnt = 1; +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_DirectAccessSPIWrite +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_DirectAccessSPIWrite +( +uint8_t address, +uint8_t value +) +{ + uint16_t txData; + + ProtectFromMCR20Interrupt(); + + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000); + + gXcvrAssertCS_d(); + + txData = (address & TransceiverSPI_DirectRegisterAddressMask); + txData |= value << 8; + + xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t *)&txData, 0, sizeof(txData)); + + gXcvrDeassertCS_d(); + UnprotectFromMCR20Interrupt(); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_DirectAccessSPIMultiByteWrite +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_DirectAccessSPIMultiByteWrite +( +uint8_t startAddress, +uint8_t * byteArray, +uint8_t numOfBytes +) +{ + uint8_t txData; + + if( (numOfBytes == 0) || (byteArray == 0) ) + { + return; + } + + ProtectFromMCR20Interrupt(); + + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000); + + gXcvrAssertCS_d(); + + txData = (startAddress & TransceiverSPI_DirectRegisterAddressMask); + + xcvr_spi_transfer(gXcvrSpiInstance_c, &txData, 0, sizeof(txData)); + xcvr_spi_transfer(gXcvrSpiInstance_c, byteArray, 0, numOfBytes); + + gXcvrDeassertCS_d(); + UnprotectFromMCR20Interrupt(); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_PB_SPIByteWrite +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_PB_SPIByteWrite +( +uint8_t address, +uint8_t value +) +{ + uint32_t txData; + + ProtectFromMCR20Interrupt(); + + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000); + + gXcvrAssertCS_d(); + + txData = TransceiverSPI_WriteSelect | + TransceiverSPI_PacketBuffAccessSelect | + TransceiverSPI_PacketBuffByteModeSelect; + txData |= (address) << 8; + txData |= (value) << 16; + + xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)&txData, 0, 3); + + gXcvrDeassertCS_d(); + UnprotectFromMCR20Interrupt(); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_PB_SPIBurstWrite +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_PB_SPIBurstWrite +( +uint8_t * byteArray, +uint8_t numOfBytes +) +{ + uint8_t txData; + + if( (numOfBytes == 0) || (byteArray == 0) ) + { + return; + } + + ProtectFromMCR20Interrupt(); + + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000); + + gXcvrAssertCS_d(); + + txData = TransceiverSPI_WriteSelect | + TransceiverSPI_PacketBuffAccessSelect | + TransceiverSPI_PacketBuffBurstModeSelect; + + xcvr_spi_transfer(gXcvrSpiInstance_c, &txData, 0, 1); + xcvr_spi_transfer(gXcvrSpiInstance_c, byteArray, 0, numOfBytes); + + gXcvrDeassertCS_d(); + UnprotectFromMCR20Interrupt(); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_DirectAccessSPIRead +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ + +uint8_t MCR20Drv_DirectAccessSPIRead +( +uint8_t address +) +{ + uint8_t txData; + uint8_t rxData; + + ProtectFromMCR20Interrupt(); + + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000); + + gXcvrAssertCS_d(); + + txData = (address & TransceiverSPI_DirectRegisterAddressMask) | + TransceiverSPI_ReadSelect; + + xcvr_spi_transfer(gXcvrSpiInstance_c, &txData, 0, sizeof(txData)); + xcvr_spi_transfer(gXcvrSpiInstance_c, 0, &rxData, sizeof(rxData)); + + gXcvrDeassertCS_d(); + UnprotectFromMCR20Interrupt(); + + return rxData; + +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_DirectAccessSPIMultyByteRead +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +uint8_t MCR20Drv_DirectAccessSPIMultiByteRead +( +uint8_t startAddress, +uint8_t * byteArray, +uint8_t numOfBytes +) +{ + uint8_t txData; + uint8_t phyIRQSTS1; + + if( (numOfBytes == 0) || (byteArray == 0) ) + { + return 0; + } + + ProtectFromMCR20Interrupt(); + + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000); + + gXcvrAssertCS_d(); + + txData = (startAddress & TransceiverSPI_DirectRegisterAddressMask) | + TransceiverSPI_ReadSelect; + + xcvr_spi_transfer(gXcvrSpiInstance_c, &txData, &phyIRQSTS1, sizeof(txData)); + xcvr_spi_transfer(gXcvrSpiInstance_c, 0, byteArray, numOfBytes); + + gXcvrDeassertCS_d(); + UnprotectFromMCR20Interrupt(); + + return phyIRQSTS1; +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_PB_SPIBurstRead +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +uint8_t MCR20Drv_PB_SPIBurstRead +( +uint8_t * byteArray, +uint8_t numOfBytes +) +{ + uint8_t txData; + uint8_t phyIRQSTS1; + + if( (numOfBytes == 0) || (byteArray == 0) ) + { + return 0; + } + + ProtectFromMCR20Interrupt(); + + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000); + + gXcvrAssertCS_d(); + + txData = TransceiverSPI_ReadSelect | + TransceiverSPI_PacketBuffAccessSelect | + TransceiverSPI_PacketBuffBurstModeSelect; + + xcvr_spi_transfer(gXcvrSpiInstance_c, &txData, &phyIRQSTS1, sizeof(txData)); + xcvr_spi_transfer(gXcvrSpiInstance_c, 0, byteArray, numOfBytes); + + gXcvrDeassertCS_d(); + UnprotectFromMCR20Interrupt(); + + return phyIRQSTS1; +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_IndirectAccessSPIWrite +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_IndirectAccessSPIWrite +( +uint8_t address, +uint8_t value +) +{ + uint32_t txData; + + ProtectFromMCR20Interrupt(); + + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000); + + gXcvrAssertCS_d(); + + txData = TransceiverSPI_IARIndexReg; + txData |= (address) << 8; + txData |= (value) << 16; + + xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)&txData, 0, 3); + + gXcvrDeassertCS_d(); + UnprotectFromMCR20Interrupt(); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_IndirectAccessSPIMultiByteWrite +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_IndirectAccessSPIMultiByteWrite +( +uint8_t startAddress, +uint8_t * byteArray, +uint8_t numOfBytes +) +{ + uint16_t txData; + + if( (numOfBytes == 0) || (byteArray == 0) ) + { + return; + } + + ProtectFromMCR20Interrupt(); + + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000); + + gXcvrAssertCS_d(); + + txData = TransceiverSPI_IARIndexReg; + txData |= (startAddress) << 8; + + xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)&txData, 0, sizeof(txData)); + xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)byteArray, 0, numOfBytes); + + gXcvrDeassertCS_d(); + UnprotectFromMCR20Interrupt(); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_IndirectAccessSPIRead +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +uint8_t MCR20Drv_IndirectAccessSPIRead +( +uint8_t address +) +{ + uint16_t txData; + uint8_t rxData; + + ProtectFromMCR20Interrupt(); + + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000); + + gXcvrAssertCS_d(); + + txData = TransceiverSPI_IARIndexReg | TransceiverSPI_ReadSelect; + txData |= (address) << 8; + + xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)&txData, 0, sizeof(txData)); + xcvr_spi_transfer(gXcvrSpiInstance_c, 0, &rxData, sizeof(rxData)); + + gXcvrDeassertCS_d(); + UnprotectFromMCR20Interrupt(); + + return rxData; +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_IndirectAccessSPIMultiByteRead +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_IndirectAccessSPIMultiByteRead +( +uint8_t startAddress, +uint8_t * byteArray, +uint8_t numOfBytes +) +{ + uint16_t txData; + + if( (numOfBytes == 0) || (byteArray == 0) ) + { + return; + } + + ProtectFromMCR20Interrupt(); + + xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000); + + gXcvrAssertCS_d(); + + txData = (TransceiverSPI_IARIndexReg | TransceiverSPI_ReadSelect); + txData |= (startAddress) << 8; + + xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)&txData, 0, sizeof(txData)); + xcvr_spi_transfer(gXcvrSpiInstance_c, 0, byteArray, numOfBytes); + + gXcvrDeassertCS_d(); + UnprotectFromMCR20Interrupt(); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_IsIrqPending +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +uint32_t MCR20Drv_IsIrqPending +( +void +) +{ + return RF_isIRQ_Pending(); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_IRQ_Disable +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_IRQ_Disable +( +void +) +{ + platform_enter_critical(); + + if( mPhyIrqDisableCnt == 0 ) + { + RF_IRQ_Disable(); + } + + mPhyIrqDisableCnt++; + + platform_exit_critical(); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_IRQ_Enable +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_IRQ_Enable +( +void +) +{ + platform_enter_critical(); + + if( mPhyIrqDisableCnt ) + { + mPhyIrqDisableCnt--; + + if( mPhyIrqDisableCnt == 0 ) + { + RF_IRQ_Enable(); + } + } + + platform_exit_critical(); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_RST_Assert +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_RST_B_Assert +( +void +) +{ + RF_RST_Set(0); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_RST_Deassert +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_RST_B_Deassert +( +void +) +{ + RF_RST_Set(1); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_SoftRST_Assert +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_SoftRST_Assert +( +void +) +{ + MCR20Drv_IndirectAccessSPIWrite(SOFT_RESET, (0x80)); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_SoftRST_Deassert +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_SoftRST_Deassert +( +void +) +{ + MCR20Drv_IndirectAccessSPIWrite(SOFT_RESET, (0x00)); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_Soft_RESET +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_Soft_RESET +( +void +) +{ + //assert SOG_RST + MCR20Drv_IndirectAccessSPIWrite(SOFT_RESET, (0x80)); + + //deassert SOG_RST + MCR20Drv_IndirectAccessSPIWrite(SOFT_RESET, (0x00)); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_RESET +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_RESET +( +void +) +{ + volatile uint32_t delay = 1000; + //assert RST_B + MCR20Drv_RST_B_Assert(); + + while(delay--); + + //deassert RST_B + MCR20Drv_RST_B_Deassert(); +} + +/*--------------------------------------------------------------------------- +* Name: MCR20Drv_Set_CLK_OUT_Freq +* Description: - +* Parameters: - +* Return: - +*---------------------------------------------------------------------------*/ +void MCR20Drv_Set_CLK_OUT_Freq +( +uint8_t freqDiv +) +{ + uint8_t clkOutCtrlReg = (freqDiv & cCLK_OUT_DIV_Mask) | cCLK_OUT_EN | cCLK_OUT_EXTEND; + + if(freqDiv == gCLK_OUT_FREQ_DISABLE) + { + clkOutCtrlReg = (cCLK_OUT_EXTEND | gCLK_OUT_FREQ_4_MHz); //reset value with clock out disabled + } + + MCR20Drv_DirectAccessSPIWrite((uint8_t) CLK_OUT_CTRL, clkOutCtrlReg); +}