/*----------------------------------------------------------------------------
**
**	Radio.c 
**	
**  Low level drivers for the MC13111A radio receiver IC transmit section.
**
**--------------------------------------------------------------------------*/
                     
#include "Onboard.h"
#include "Hardware.h"           
#include "Radio.h"
#include "ShiftReg.h"

/*----------------------------------------------------------------------------
//
//  WriteRadioAddress
//
//  Write an address to the MC13111 radio chip.
//
// Modification Record:
//  21-Jul-00   Paul Hills      First version.
---------------------------------------------------------------------------*/
void WriteRadioAddress(unsigned char Addr)
{        
    int i;
    
    RADIO_EN = 1;   
    no_operation();
    RADIO_CLK = 0;  
    no_operation();
    
    for (i=0 ; i<8 ; i++)
    {
        RADIO_DATA = (Addr & 0x80);     
        no_operation();
        RADIO_CLK = 1;                  
        no_operation();
        RADIO_CLK = 0;                  
        no_operation();
        Addr <<= 1;
    }              
    
    RADIO_EN = 0;   
    no_operation();
}

/*----------------------------------------------------------------------------
//
//  WriteRadioData
//
//  Write data to the MC13111 radio chip.
//
// Modification Record:
//  21-Jul-00   Paul Hills      First version.
---------------------------------------------------------------------------*/
void WriteRadioData(unsigned int Data)
{           
    int i;
    
    RADIO_EN = 0;
    no_operation();
    RADIO_CLK = 0;
    no_operation();
    
    for (i=0 ; i<16 ; i++)
    {
        RADIO_DATA = (Data & 0x80);
        no_operation();
        RADIO_CLK = 1;
        no_operation();
        RADIO_CLK = 0;
        no_operation();
        Data <<= 1;
    }              
    
    RADIO_EN = 1;
    no_operation();
    RADIO_EN = 0;
    no_operation();
}


/*----------------------------------------------------------------------------
//
//  SetRadioRegister
//
//  Writes the 16-bit data to the appropriate register of the MC13111.
// Always writes the address first - the overhead involved in this will be 
// minimal since radio writes are not that common.
//
// Modification Record:
//  21-Jul-00   Paul Hills      First version.
---------------------------------------------------------------------------*/
void SetRadioRegister(unsigned char Addr, unsigned int Value)
{                                               
    WriteRadioAddress(Addr);
    WriteRadioData(Value);
}

/*----------------------------------------------------------------------------
//
//  InitialiseRadio
//
//  Read the channel required from the selector switch, and set the MC13111
// carrier frequency appropriately. Set the channel width, and initial gain.
//
// Modification Record:
//  21-Jul-00   Paul Hills      First version.
---------------------------------------------------------------------------*/
void InitialiseRadio(void)
{   
    unsigned char Channel;
    unsigned char RadioChannel; // Actual channel number, 66 (CH66) to 99 (CH99)
                                             
    //
    // Read required radio channel. Note that the available legal channels
    // are CH66 (40.665MHz) up to CH99 (40.995MHz), although settings
    // below CH66 are allowed by the hardware. The base frequency, CH00 is
    // 40.605MHz. Channel spacing is 10kHz.
    //
    
    
    RADIO_READ_DECADE;          // Select decade switch.
    UpdateChain();
    Channel = ChainReadBit(RADIO_CHANNEL_SELECT_0) +
             (ChainReadBit(RADIO_CHANNEL_SELECT_1) << 1) +
             (ChainReadBit(RADIO_CHANNEL_SELECT_2) << 2) +
             (ChainReadBit(RADIO_CHANNEL_SELECT_3) << 3);
    RadioChannel = 10 * Channel;
    RADIO_READ_UNITS;           // Select units switch.
    UpdateChain();
    Channel = ChainReadBit(RADIO_CHANNEL_SELECT_0) +
             (ChainReadBit(RADIO_CHANNEL_SELECT_1) << 1) +
             (ChainReadBit(RADIO_CHANNEL_SELECT_2) << 2) +
             (ChainReadBit(RADIO_CHANNEL_SELECT_3) << 3);
    RadioChannel += Channel;
    
    //
    // Setup MC13111.
    //
                                                             
    SetRadioRegister(MODE_CONTROL, 0x00E0);     // All bits 0 except volume nibble, = 7 (0dB)
    SetRadioRegister(REFERENCE_COUNTER, 2048);  // 5kHz channel spacing (every other channel used)
    SetRadioRegister(GAIN_CONTROL, 0x3DF4);     // Default gain values, = 0dB
    SetRadioRegister(SCF_CLOCK_DIVIDERS, 15);   // Default value, = 0dB
    SetRadioRegister(AUXILIARY, 0);             // Default values.
                  
    //
    // Set the radio frequency channel based on what was read from the 
    // switches. An increment of 1 in the counter register increments
    // the frequency by 5kHz, hence the channels, being 10kHz apart,
    // must be doubled before adding to the base frequency.
    // Note that the receive frequency register has an extra bit, IP3
    // at b14 which is set, hence the addition of 0x4000.
    //
    
    SetRadioRegister(TX_COUNTER, BASE_CHANNEL + RadioChannel*2);
    SetRadioRegister(RX_COUNTER, BASE_CHANNEL + RadioChannel*2 + 0x4000);
}