You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
7.7 KiB
C
240 lines
7.7 KiB
C
// *************************************************************************************************
|
|
//
|
|
// Actual revision: $Revision: $
|
|
// Revision label: $Name: $
|
|
// Revision state: $State: $
|
|
//
|
|
// *************************************************************************************************
|
|
// Radio core access functions. Taken from TI reference code for CC430.
|
|
// *************************************************************************************************
|
|
|
|
|
|
// *************************************************************************************************
|
|
// Include section
|
|
|
|
// system
|
|
#include <project.h>
|
|
|
|
// driver
|
|
#include "rf1a.h"
|
|
|
|
|
|
// *************************************************************************************************
|
|
// Global section
|
|
|
|
|
|
// *************************************************************************************************
|
|
// Define section
|
|
#define st(x) do { x } while (__LINE__ == -1)
|
|
#define ENTER_CRITICAL_SECTION(x) st( x = __get_interrupt_state(); __disable_interrupt(); )
|
|
#define EXIT_CRITICAL_SECTION(x) __set_interrupt_state(x)
|
|
|
|
|
|
// *************************************************************************************************
|
|
// @fn Strobe
|
|
// @brief Send command to radio.
|
|
// @param none
|
|
// @return none
|
|
// *************************************************************************************************
|
|
unsigned char Strobe(unsigned char strobe)
|
|
{
|
|
u8 statusByte = 0;
|
|
u16 int_state, gdo_state;
|
|
|
|
// Check for valid strobe command
|
|
if((strobe == 0xBD) || ((strobe > RF_SRES) && (strobe < RF_SNOP)))
|
|
{
|
|
ENTER_CRITICAL_SECTION(int_state);
|
|
|
|
// Clear the Status read flag
|
|
RF1AIFCTL1 &= ~(RFSTATIFG);
|
|
|
|
// Wait for radio to be ready for next instruction
|
|
while( !(RF1AIFCTL1 & RFINSTRIFG));
|
|
|
|
// Write the strobe instruction
|
|
if ((strobe > RF_SRES) && (strobe < RF_SNOP))
|
|
{
|
|
|
|
gdo_state = ReadSingleReg(IOCFG2); // buffer IOCFG2 state
|
|
WriteSingleReg(IOCFG2, 0x29); // c-ready to GDO2
|
|
|
|
RF1AINSTRB = strobe;
|
|
if ( (RF1AIN&0x04)== 0x04 ) // chip at sleep mode
|
|
{
|
|
if ( (strobe == RF_SXOFF) || (strobe == RF_SPWD) || (strobe == RF_SWOR) ) { }
|
|
else
|
|
{
|
|
while ((RF1AIN&0x04)== 0x04); // c-ready ?
|
|
__delay_cycles(9800); // Delay for ~810usec at 12MHz CPU clock
|
|
}
|
|
}
|
|
WriteSingleReg(IOCFG2, gdo_state); // restore IOCFG2 setting
|
|
}
|
|
else // chip active mode
|
|
{
|
|
RF1AINSTRB = strobe;
|
|
}
|
|
statusByte = RF1ASTATB;
|
|
while( !(RF1AIFCTL1 & RFSTATIFG) );
|
|
EXIT_CRITICAL_SECTION(int_state);
|
|
}
|
|
return statusByte;
|
|
}
|
|
|
|
|
|
// *************************************************************************************************
|
|
// @fn ResetRadioCore
|
|
// @brief Software reset radio core.
|
|
// @param none
|
|
// @return none
|
|
// *************************************************************************************************
|
|
void ResetRadioCore(void)
|
|
{
|
|
Strobe(RF_SRES); // Reset the Radio Core
|
|
Strobe(RF_SNOP); // Reset Radio Pointer
|
|
}
|
|
|
|
|
|
// *************************************************************************************************
|
|
// @fn ReadSingleReg
|
|
// @brief Read byte from register.
|
|
// @param none
|
|
// @return none
|
|
// *************************************************************************************************
|
|
unsigned char ReadSingleReg(unsigned char addr)
|
|
{
|
|
unsigned char x;
|
|
u16 int_state;
|
|
|
|
ENTER_CRITICAL_SECTION(int_state);
|
|
|
|
RF1AINSTR1B = (addr | RF_REGRD);
|
|
x = RF1ADOUT1B;
|
|
|
|
EXIT_CRITICAL_SECTION(int_state);
|
|
|
|
return x;
|
|
}
|
|
|
|
|
|
// *************************************************************************************************
|
|
// @fn WriteSingleReg
|
|
// @brief Write byte to register.
|
|
// @param none
|
|
// @return none
|
|
// *************************************************************************************************
|
|
void WriteSingleReg(unsigned char addr, unsigned char value)
|
|
{
|
|
volatile unsigned int i;
|
|
u16 int_state;
|
|
|
|
ENTER_CRITICAL_SECTION(int_state);
|
|
|
|
while (!(RF1AIFCTL1 & RFINSTRIFG)); // Wait for the Radio to be ready for the next instruction
|
|
|
|
RF1AINSTRW = ((addr | RF_REGWR)<<8 ) + value; // Send address + Instruction
|
|
while (!(RFDINIFG & RF1AIFCTL1));
|
|
|
|
i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status byte
|
|
|
|
EXIT_CRITICAL_SECTION(int_state);
|
|
}
|
|
|
|
|
|
// *************************************************************************************************
|
|
// @fn ReadBurstReg
|
|
// @brief Read sequence of bytes from register.
|
|
// @param none
|
|
// @return none
|
|
// *************************************************************************************************
|
|
void ReadBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count)
|
|
{
|
|
unsigned int i;
|
|
u16 int_state;
|
|
|
|
ENTER_CRITICAL_SECTION(int_state);
|
|
|
|
while (!(RF1AIFCTL1 & RFINSTRIFG)); // Wait for the Radio to be ready for next instruction
|
|
RF1AINSTR1B = (addr | RF_REGRD); // Send address + Instruction
|
|
|
|
for (i = 0; i < (count-1); i++)
|
|
{
|
|
while (!(RFDOUTIFG&RF1AIFCTL1)); // Wait for the Radio Core to update the RF1ADOUTB reg
|
|
buffer[i] = RF1ADOUT1B; // Read DOUT from Radio Core + clears RFDOUTIFG
|
|
// Also initiates auo-read for next DOUT byte
|
|
}
|
|
buffer[count-1] = RF1ADOUT0B; // Store the last DOUT from Radio Core
|
|
|
|
EXIT_CRITICAL_SECTION(int_state);
|
|
}
|
|
|
|
|
|
// *************************************************************************************************
|
|
// @fn WriteBurstReg
|
|
// @brief Write sequence of bytes to register.
|
|
// @param none
|
|
// @return none
|
|
// *************************************************************************************************
|
|
void WriteBurstReg(unsigned char addr, unsigned char *buffer, unsigned char count)
|
|
{
|
|
// Write Burst works wordwise not bytewise - bug known already
|
|
unsigned char i;
|
|
u16 int_state;
|
|
|
|
ENTER_CRITICAL_SECTION(int_state);
|
|
|
|
while (!(RF1AIFCTL1 & RFINSTRIFG)); // Wait for the Radio to be ready for next instruction
|
|
RF1AINSTRW = ((addr | RF_REGWR)<<8 ) + buffer[0]; // Send address + Instruction
|
|
|
|
for (i = 1; i < count; i++)
|
|
{
|
|
RF1ADINB = buffer[i]; // Send data
|
|
while (!(RFDINIFG & RF1AIFCTL1)); // Wait for TX to finish
|
|
}
|
|
i = RF1ADOUTB; // Reset RFDOUTIFG flag which contains status byte
|
|
|
|
EXIT_CRITICAL_SECTION(int_state);
|
|
}
|
|
|
|
|
|
// *************************************************************************************************
|
|
// @fn WritePATable
|
|
// @brief Write data to power table
|
|
// @param unsigned char value Value to write
|
|
// @return none
|
|
// *************************************************************************************************
|
|
void WritePATable(unsigned char value)
|
|
{
|
|
unsigned char readbackPATableValue = 0;
|
|
u16 int_state;
|
|
|
|
ENTER_CRITICAL_SECTION(int_state);
|
|
|
|
while(readbackPATableValue != value)
|
|
{
|
|
while( !(RF1AIFCTL1 & RFINSTRIFG));
|
|
RF1AINSTRW = 0x7E00 + value; // PA Table write (burst)
|
|
|
|
while( !(RF1AIFCTL1 & RFINSTRIFG));
|
|
RF1AINSTRB = RF_SNOP; // reset pointer
|
|
|
|
|
|
while( !(RF1AIFCTL1 & RFINSTRIFG));
|
|
RF1AINSTRB = 0xFE; // PA Table read (burst)
|
|
|
|
while( !(RF1AIFCTL1 & RFDINIFG));
|
|
RF1ADINB = 0x00; //dummy write
|
|
|
|
while( !(RF1AIFCTL1 & RFDOUTIFG));
|
|
readbackPATableValue = RF1ADOUT0B;
|
|
|
|
while( !(RF1AIFCTL1 & RFINSTRIFG));
|
|
RF1AINSTRB = RF_SNOP;
|
|
}
|
|
|
|
EXIT_CRITICAL_SECTION(int_state);
|
|
}
|
|
|
|
|