//-----------------------------------------------------------------------------
// F320_Si470x_Interface.h
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This is the header file for interfacing with Si470x using the F320 SPI.
//
// FID:            32X000038
// Target:         C8051F320
// Tool chain:     KEIL C51 7.0.0.1
//                 Silicon Laboratories IDE version 2.3
// Command Line:   See Readme.txt
// Project Name:   F320_FM_Radio
//
// Release 1.1
//    -No changes made to this module (DM)
//    -16 JAN 2006
//
// Release 1.0
//    -Initial Revision (DM)
//    -22 JUN 2005
//

#ifndef F320_SI470X_INTERFACE_H_
#define F320_SI470X_INTERFACE_H_
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------

// Constants for the Si4701 register names
enum { DEVICEID, CHIPID, POWERCONFIG, CHANNEL, SYSCONFIG1, SYSCONFIG2, \
SYSCONFIG3, TEST1, TEST2, BOOTCONFIG, STATUSRSSI, READCHAN, RDSA, RDSB, RDSC, \
RDSD };

// PowerConfig Register Bitmasks
#define MUTE_OFF_PC 0x4000
#define SEEK_PC 0x0100
#define DISABLE_PC 0x0040
#define ENABLE_PC 0x0001

// Channel Register Bitmasks
#define TUNE_CH 0x8000
#define CHANMASK_CH 0x03FF

// StatusRSSI Register Bitmasks
#define RDSR_SC 0x8000
#define STC_SC 0x4000
#define SF_SC 0x2000
#define ST_SC 0x0100

//-----------------------------------------------------------------------------
// Macros
//-----------------------------------------------------------------------------

// Wait for hardware SPI to finish pending transaction
#define WAIT_SPI { \
   while (!SPIF); \
   SPIF = OFF; }

// Control write to Si4701
#define CONTROL_WRITE(addr, data8) { \
   WAIT_SPI; \
   SEN_bar = OFF; \
   SPIDAT = 0x60 | (addr >> 1); \
   WAIT_SPI; \
   SPIDAT = (data8.c[MSB] >> 1) | (addr << 7); \
   WAIT_SPI; \
   SPIDAT = (data8.c[LSB] >> 1) | (data8.c[MSB] << 7); \
   WAIT_SPI; \
   SPIDAT = (data8.c[LSB] << 7); \
   WAIT_SPI; \
   SEN_bar = ON; \
   SPIDAT = 0xFF; }

// Control read from Si4701
#define CONTROL_READ(addr, data8) { \
   WAIT_SPI; \
   SEN_bar = OFF; \
   SPIDAT = 0x70 | (addr >> 1); \
   WAIT_SPI; \
   SPIDAT = 0x7F | (addr << 7); \
   WAIT_SPI; \
   data8.c[MSB] = (SPIDAT << 1); \
   SPIDAT = 0xFF; \
   WAIT_SPI; \
   data8.c[MSB] |= (SPIDAT >> 7); \
   data8.c[LSB] = (SPIDAT << 1); \
   SPIDAT = 0xFF; \
   WAIT_SPI; \
   data8.c[LSB] |= (SPIDAT >> 7); \
   SEN_bar = ON; \
   SPIDAT = 0xFF; }

// Sets the register at addr to a certain value
// word_storage is used as intermediate storage, so that value can be a constant
#define SET_REGISTER(addr, value, word_storage) { \
   word_storage.i = value; \
   CONTROL_WRITE (addr, word_storage); }


// Bitwise AND the register at addr with a certain value
// word_storage is used as intermediate storage, so that value can be a constant
#define ANL_REGISTER(addr, value, word_storage) { \
   CONTROL_READ(addr, word_storage); \
   word_storage.i &= value; \
   CONTROL_WRITE(addr, word_storage); }

// Bitwise OR the register at addr with a certain value
// word_storage is used as intermediate storage, so that value can be a constant
#define ORL_REGISTER(addr, value, word_storage) { \
   CONTROL_READ(addr, word_storage); \
   word_storage.i |= value; \
   CONTROL_WRITE(addr, word_storage); }

//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------

void EnableRadio (void);               // Initialize and enable Si4701

#endif // F320_SI470X_INTERFACE_H_
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------