⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 si47xxfmrx.c

📁 this is Si47xx Example Code
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//
// si47xxFMRX.c
//
// Contains the FM radio functions with the exceptions of autoseek and rds.
//
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f320.h>
#include <stddef.h>
#include "typedefs.h"
#include "portdef.h"
#include "commanddefs.h"
#include "propertydefs.h"
#include "si47xxFMRX.h"

//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------
#define POWERUP_TIME 110    // Powerup delay in milliseconds

//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
extern bit WaitSTCInterrupt;
extern bit PoweredUp;
extern bit SeekTuneInProc;
extern u8  idata cmd[8];
extern u8  idata rsp[13];
extern u8  chipFunction;

// This variables are used by the status commands.  Make sure to call those
// commands (fmRsqStatus, fmTuneStatus, or fmRdsStatus) prior to access.
extern u8  xdata Status;
extern u8  xdata RsqInts;
extern u8  xdata STC;
extern u8  xdata SMUTE;
extern u8  xdata BLTF;
extern u8  xdata AFCRL;
extern u8  xdata Valid;
extern u8  xdata Pilot;
extern u8  xdata Blend;
extern u16 xdata Freq;
extern u8  xdata RSSI;
extern u8  xdata ASNR;
extern u16 xdata AntCap;
extern u8  xdata FreqOff;
u8  xdata RdsInts;
u8  xdata RdsSync;
u8  xdata GrpLost;
u8  xdata RdsFifoUsed;
u16 xdata BlockA;
u16 xdata BlockB;
u16 xdata BlockC;
u16 xdata BlockD;
u8  xdata BleA;
u8  xdata BleB;
u8  xdata BleC;
u8  xdata BleD;



typedef enum {USA, EUROPE, JAPAN} country_enum; // Could be expanded

//-----------------------------------------------------------------------------
// Function prototypes
//-----------------------------------------------------------------------------
void wait_ms(u16 ms);
void si47xx_command(u8 cmd_size, u8 idata *cmd, u8 reply_size, u8 idata *reply);
void si47xx_reset(void);
u8 getIntStatus(void);
void fmTuneFreq(u16 frequency);
static void fmSeekStart(u8 seekUp, u8 wrap);
static void fmTuneStatus(u8 cancel, u8 intack);
static void fmRsqStatus(u8 intack);

//-----------------------------------------------------------------------------
// Take the Si47xx out of powerdown mode.
//-----------------------------------------------------------------------------
void si47xxFMRX_powerup(void)
{

    // Check if the device is already powered up.
    if (PoweredUp) {
    } else {
        // Put the ID for the command in the first byte.
        cmd[0] = POWER_UP;

		// Enable the GPO2OEN on the part because it will be used to determine
        // RDS Sync timing.
        cmd[1] = POWER_UP_IN_GPO2OEN;

		// The device is being powered up in FM RX mode.
        cmd[1] |= POWER_UP_IN_FUNC_FMRX;

		// The opmode needs to be set to analog mode
        cmd[2] = POWER_UP_IN_OPMODE_RX_ANALOG;

        // Powerup the device
		si47xx_command(3, cmd, 8, rsp);
        wait_ms(POWERUP_TIME);               // wait for si47xx to powerup

        // Since we did not boot the part in query mode the result will not
        // contain the part information.

		PoweredUp = 1;
    }
}

//-----------------------------------------------------------------------------
// Place the Si47xx into powerdown mode.
//-----------------------------------------------------------------------------
void si47xxFMRX_powerdown(void)
{

	// Check to see if the device is powered up.  If not do not do anything.
    if(PoweredUp)
    {   
        // Set the powered up variable to 0
        PoweredUp = 0;

	    // Put the ID for the command in the first byte.
	    cmd[0] = POWER_DOWN;

	    // Invoke the command
		si47xx_command(1, cmd, 1, rsp);
    }
}

//-----------------------------------------------------------------------------
// This function will set up some general items on the hardware like
// initializing the RDS and STC interrupts.
//
// Note:
//     * RDS is only available on certain parts.  Please refer to the data
//       sheet for your part to determine if your part supports RDS.
//-----------------------------------------------------------------------------
static void si47xxFMRX_hardware_cfg(void)
{
	// Enable the RDS and STC interrupt here
    si47xx_set_property(GPO_IEN, GPO_IEN_STCIEN_MASK | GPO_IEN_RDSIEN_MASK);
}

//-----------------------------------------------------------------------------
// Set up general configuration properties:
//      Soft Mute Rate, Soft Mute Max Attenuation, Soft Mute SNR Threshold,
//      Blend Mono Threshold, Blend Stereo Threshold, Max Tune Error,
//      Seek Tune SNR Threshold, Seek Tune RSSI Threshold
//
// Note:
//     * RDS is only available on certain parts.  Please refer to the data
//       sheet for your part to determine if your part supports RDS.
//-----------------------------------------------------------------------------
static void si47xxFMRX_general_cfg(void)
{
    // Typically the settings used for stereo blend are determined by the 
    // designer and not exposed to the end user. They should be adjusted here.
    // If the user wishes to force mono set both of these values to 127.
    // si47xx_set_property(FM_BLEND_MONO_THRESHOLD, 30);
    // si47xx_set_property(FM_BLEND_STEREO_THRESHOLD, 49);

    // The softmute feature can be disabled, but it is normally left on.
    // The softmute feature is disabled by setting the attenuation property
    // to zero.
    //  si47xx_set_property(FM_SOFT_MUTE_RATE, 64);
    //  si47xx_set_property(FM_SOFT_MUTE_MAX_ATTENUATION, 16);
    //  si47xx_set_property(FM_SOFT_MUTE_SNR_THRESHOLD, 4);

    // The max tune error is normally left in its default state.  The designer
    // can change if desired.
    //  si47xx_set_property(FM_MAX_TUNE_ERROR, 30);
 
    // Typically the settings used for seek are determined by the designer
    // and not exposed to the end user. They should be adjusted here.
    si47xx_set_property(FM_SEEK_TUNE_SNR_THRESHOLD, 3);
    si47xx_set_property(FM_SEEK_TUNE_RSSI_THRESHOLD, 20);
}

//-----------------------------------------------------------------------------
// Set up regional configuration properties including:
//      Seek Band Bottom, Seek Band Top, Seek Freq Spacing, Deemphasis
//
// Inputs:
//     country
//
// Note:
//     * RDS is only available on certain parts.  Please see the part's
//       datasheet for more information.
//-----------------------------------------------------------------------------
static void si47xxFMRX_regional_cfg(country_enum country)
{
    // Typically the settings used for stereo blend are determined by the 
    // designer and not exposed to the end user. They should be adjusted here.
    // If the user wishes to force mono set both of these values to 127.
    // si47xx_set_property(FM_BLEND_MONO_THRESHOLD, 30);
    // si47xx_set_property(FM_BLEND_STEREO_THRESHOLD, 49);

    // Depending on the country, set the de-emphasis, band, and space settings
    // Also optionally enable RDS for countries that support it
    switch (country) {
    case USA :
        // This interrupt will be used to determine when RDS is available.
        si47xx_set_property(FM_RDS_INTERRUPT_SOURCE, 
					FM_RDS_INTERRUPT_SOURCE_SYNCFOUND_MASK); // RDS Interrupt

		// Enable the RDS and allow all blocks so we can compute the error
        // rate later.
        si47xx_set_property(FM_RDS_CONFIG, FM_RDS_CONFIG_RDSEN_MASK |
			(3 << FM_RDS_CONFIG_BLETHA_SHFT) |
			(3 << FM_RDS_CONFIG_BLETHB_SHFT) |
			(3 << FM_RDS_CONFIG_BLETHC_SHFT) |
			(3 << FM_RDS_CONFIG_BLETHD_SHFT));

        si47xx_set_property(FM_DEEMPHASIS, FM_DEEMPH_75US); // Deemphasis
        // Band is already set to 87.5-107.9MHz (US)
        // Space is already set to 200kHz (US)
        break;
    case JAPAN :
        si47xx_set_property(FM_RDS_CONFIG, 0);              // Disable RDS
        si47xx_set_property(FM_DEEMPHASIS, FM_DEEMPH_50US); // Deemphasis
        si47xx_set_property(FM_SEEK_BAND_BOTTOM, 7600);     // 76 MHz Bottom
        si47xx_set_property(FM_SEEK_BAND_TOP, 9000);        // 90 MHz Top
        si47xx_set_property(FM_SEEK_FREQ_SPACING, 10);      // 100 kHz Spacing
        break;
    case EUROPE :
    default:
        // This interrupt will be used to determine when RDS is available.
        si47xx_set_property(FM_RDS_INTERRUPT_SOURCE, 
			FM_RDS_INTERRUPT_SOURCE_SYNCFOUND_MASK); // RDS Interrupt

	    // Enable the RDS and allow all blocks so we can compute the error
        // rate later.
        si47xx_set_property(FM_RDS_CONFIG, FM_RDS_CONFIG_RDSEN_MASK |
		    (3 << FM_RDS_CONFIG_BLETHA_SHFT) |
			(3 << FM_RDS_CONFIG_BLETHB_SHFT) |
			(3 << FM_RDS_CONFIG_BLETHC_SHFT) |
			(3 << FM_RDS_CONFIG_BLETHD_SHFT));

        si47xx_set_property(FM_DEEMPHASIS, FM_DEEMPH_50US); // Deemphasis
        // Band is already set to 87.5-107.9MHz (Europe)
        si47xx_set_property(FM_SEEK_FREQ_SPACING, 10);      // 100 kHz Spacing
        break;
    }
}

//-----------------------------------------------------------------------------
// Configures the device for normal operation
//-----------------------------------------------------------------------------
void si47xxFMRX_configure(void)
{
    // Configure all other registers
    si47xxFMRX_hardware_cfg();
    si47xxFMRX_general_cfg();
    si47xxFMRX_regional_cfg(USA);

	// Turn on the Headphone Amp and analog out.
	M_INPUT_AD = 1;
	M_OUTPUT_AD = 0;
	GP1 = 1;
}

//-----------------------------------------------------------------------------
// Resets the part and initializes registers to the point of being ready for
// the first tune or seek.
//-----------------------------------------------------------------------------
void si47xxFMRX_initialize(void)
{
    // Zero status registers.
	PoweredUp = 0;

    // Perform a hardware reset, power up the device, and then perform the
    // initial configuration.
    si47xx_reset();
    si47xxFMRX_powerup();
    si47xxFMRX_configure();
}

//-----------------------------------------------------------------------------
// Set the volume and mute/unmute status
//
// Inputs:
//      volume:    a 6-bit volume value
//
// Note: It is assumed that if the volume is being adjusted, the device should
// not be muted.
//-----------------------------------------------------------------------------
void si47xxFMRX_set_volume(u8 volume)
{
    // Turn off the mute
    si47xx_set_property(RX_HARD_MUTE, 0);

    // Set the volume to the passed value
    si47xx_set_property(RX_VOLUME, (u16)volume & RX_VOLUME_MASK);
}

//-----------------------------------------------------------------------------
// Mute/unmute audio
//
// Inputs:
//      mute:  0 = output enabled (mute disabled)
//             1 = output muted
//-----------------------------------------------------------------------------
void si47xxFMRX_mute(u8 mute)
{
    if(mute)
    	si47xx_set_property(RX_HARD_MUTE, 
                                RX_HARD_MUTE_RMUTE_MASK | RX_HARD_MUTE_LMUTE_MASK);
    else
    	si47xx_set_property(RX_HARD_MUTE, 0);
}

//-----------------------------------------------------------------------------
// Tunes to a station number using the current band and spacing settings.
//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -