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.
OpenChronos/driver/rf1a.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);
}