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

📄 fmrxrds.c

📁 this is Si47xx Example Code
💻 C
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <stddef.h>
#include "c8051f320.h"
#include "typedefs.h"
#include "portdef.h"
#include "FMRXrds.h"
#include "si47xxFMRX.h"

//-----------------------------------------------------------------------------
// local defines
//-----------------------------------------------------------------------------
#define RDS_TYPE_0A     ( 0 * 2 + 0)
#define RDS_TYPE_0B     ( 0 * 2 + 1)
#define RDS_TYPE_1A     ( 1 * 2 + 0)
#define RDS_TYPE_1B     ( 1 * 2 + 1)
#define RDS_TYPE_2A     ( 2 * 2 + 0)
#define RDS_TYPE_2B     ( 2 * 2 + 1)
#define RDS_TYPE_3A     ( 3 * 2 + 0)
#define RDS_TYPE_3B     ( 3 * 2 + 1)
#define RDS_TYPE_4A     ( 4 * 2 + 0)
#define RDS_TYPE_4B     ( 4 * 2 + 1)
#define RDS_TYPE_5A     ( 5 * 2 + 0)
#define RDS_TYPE_5B     ( 5 * 2 + 1)
#define RDS_TYPE_6A     ( 6 * 2 + 0)
#define RDS_TYPE_6B     ( 6 * 2 + 1)
#define RDS_TYPE_7A     ( 7 * 2 + 0)
#define RDS_TYPE_7B     ( 7 * 2 + 1)
#define RDS_TYPE_8A     ( 8 * 2 + 0)
#define RDS_TYPE_8B     ( 8 * 2 + 1)
#define RDS_TYPE_9A     ( 9 * 2 + 0)
#define RDS_TYPE_9B     ( 9 * 2 + 1)
#define RDS_TYPE_10A    (10 * 2 + 0)
#define RDS_TYPE_10B    (10 * 2 + 1)
#define RDS_TYPE_11A    (11 * 2 + 0)
#define RDS_TYPE_11B    (11 * 2 + 1)
#define RDS_TYPE_12A    (12 * 2 + 0)
#define RDS_TYPE_12B    (12 * 2 + 1)
#define RDS_TYPE_13A    (13 * 2 + 0)
#define RDS_TYPE_13B    (13 * 2 + 1)
#define RDS_TYPE_14A    (14 * 2 + 0)
#define RDS_TYPE_14B    (14 * 2 + 1)
#define RDS_TYPE_15A    (15 * 2 + 0)
#define RDS_TYPE_15B    (15 * 2 + 1)

#define CORRECTED_NONE          0
#define CORRECTED_ONE_TO_TWO    1
#define CORRECTED_THREE_TO_FIVE 2
#define UNCORRECTABLE           3
#define ERRORS_CORRECTED(data,block) ((data>>block)&0x03)

#define BLER_SCALE_MAX 200  // Block Errors are reported in .5% increments

//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------
u8 xdata RdsReadPtr;
u8 xdata RdsWritePtr;
bit RdsFifoEmpty;

// Determines if the basic or advanced PS/RT RDS display functions are used
// The basic functions are closely tied to the recommendations in the RBDS
// specification and are faster to update but more error prone. The advanced
// functions attempt to detect errors and only display complete messages
static bit rdsBasic = 0;

bit Gpio2StickyBit = 0;

// RDS Program Identifier
u16 xdata piDisplay;              // Displayed Program Identifier

// RDS Program Type
u8  xdata ptyDisplay;             // Displayed Program Type

bit firstInitDone;
u8  xdata rdsBlerMax[4];

// RDS Radio Text
       u8  xdata rtDisplay[64];   // Displayed Radio Text
       u8  xdata rtSimple[64];    // Simple Displayed Radio Text
static u8  xdata rtTmp0[64];      // Temporary Radio Text (high probability)
static u8  xdata rtTmp1[64];      // Temporary radio text (low probability)
static u8  xdata rtCnt[64];       // Hit count of high probabiltiy radio text
static bit       rtFlag;          // Radio Text A/B flag
static bit       rtFlagValid;     // Radio Text A/B flag is valid
static bit       rtsFlag;         // Radio Text A/B flag
static bit       rtsFlagValid;    // Radio Text A/B flag is valid

// RDS Program Service
       u8  xdata psDisplay[8];    // Displayed Program Service text
static u8  xdata psTmp0[8];       // Temporary PS text (high probability)
static u8  xdata psTmp1[8];       // Temporary PS text (low probability)
static u8  xdata psCnt[8];        // Hit count of high probability PS text

// RDS Clock Time and Date
       bit       ctDayHigh;       // Modified Julian Day high bit
       u16 xdata ctDayLow;        // Modified Julian Day low 16 bits
       u8  xdata ctHour;          // Hour
       u8  xdata ctMinute;        // Minute
       i8  xdata ctOffset;        // Local Time Offset from UTC

// RDS Alternate Frequency List
static u8  xdata afCount;
static u16 xdata afList[25];

// RDS flags and counters
       u8  xdata RdsDataAvailable = 0;  // Count of unprocessed RDS Groups
static u8  xdata RdsIndicator     = 0;  // If true, RDS was recently detected
static u16 xdata RdsDataLost      = 0;  // Number of Groups lost
static u16 xdata RdsBlocksValid   = 0;  // Number of valid blocks received
static u16 xdata RdsBlocksTotal   = 0;  // Total number of blocks expected
static u16 xdata RdsBlockTimer    = 0;  // Total number of blocks expected
static u16 xdata RdsGroupCounters[32];  // Number of each kind of group received

       bit       RdsSynchTimer  = 0;
static u16 xdata RdsSynchValid  = 0;
static u16 xdata RdsSynchTotal  = 0;
static u16 xdata RdsGroupsTotal = 0;
static u16 xdata RdsGroups      = 0;
static u16 xdata RdsValid[4];

       bit       rdsIgnoreAB;

//-----------------------------------------------------------------------------
// Function prototypes
//-----------------------------------------------------------------------------

void wait_ms(u16 ms);
static void updateRdsFifo(u16 * group, u8 errorFlags);
static void init_alt_freq(void);

//-----------------------------------------------------------------------------
// Externals
//-----------------------------------------------------------------------------

extern u8  xdata RdsInts;
extern u8  xdata RdsSync;
extern u8  xdata GrpLost;
extern u8  xdata RdsFifoUsed;
extern u16 xdata BlockA;
extern u16 xdata BlockB;
extern u16 xdata BlockC;
extern u16 xdata BlockD;
extern u8  xdata BleA;
extern u8  xdata BleB;
extern u8  xdata BleC;
extern u8  xdata BleD;

//-----------------------------------------------------------------------------
// After tuning to a new station, the RDS tracking variables need to be
// initialized.
//-----------------------------------------------------------------------------
void
initRdsVars(void)
{
    u8 i;

    // Set the maximum allowable errors in a block considered acceptable
    // It's critical that block B be correct since it determines what's
    // contained in the latter blocks. For this reason, a stricter tolerance
    // is placed on block B
    if (!firstInitDone)
    {
        rdsBlerMax[0] = CORRECTED_THREE_TO_FIVE; // Block A
        rdsBlerMax[1] = CORRECTED_ONE_TO_TWO;    // Block B
        rdsBlerMax[2] = CORRECTED_THREE_TO_FIVE; // Block C
        rdsBlerMax[3] = CORRECTED_THREE_TO_FIVE; // Block D
        firstInitDone = 1;
    }

    // Reset RDS variables
    RdsDataAvailable = 0;
    RdsDataLost      = 0;
    RdsIndicator     = 0;
    RdsBlocksValid   = 0;
    RdsBlocksTotal   = 0;

    // Clear RDS Fifo
    RdsFifoEmpty = 1;
    RdsReadPtr = 0;
    RdsWritePtr = 0;

    // Clear Radio Text
    rtFlagValid     = 0;
    rtsFlagValid    = 0;
    for (i=0; i<sizeof(rtDisplay); i++)
    {
        rtSimple[i]  = 0;
        rtDisplay[i] = 0;
        rtTmp0[i]    = 0;
        rtTmp1[i]    = 0;
        rtCnt[i]     = 0;
    }

    // Clear Program Service
    for (i=0;i<sizeof(psDisplay);i++)
    {
        psDisplay[i] = 0;
        psTmp0[i]    = 0;
        psTmp1[i]    = 0;
        psCnt[i]     = 0;
    }

    // Reset Debug Group counters
    for (i=0; i<32; i++)
    {
        RdsGroupCounters[i] = 0;
    }

    // Reset alternate frequency tables
    init_alt_freq();

    RdsSynchValid  = 0;
    RdsSynchTotal  = 0;
    RdsValid[0]    = 0;
    RdsValid[1]    = 0;
    RdsValid[2]    = 0;
    RdsValid[3]    = 0;
    RdsGroups      = 0;
    RdsGroupsTotal = 0;
    ptyDisplay     = 0;
    piDisplay      = 0;
    ctDayHigh      = 0;
    ctDayLow       = 0;
    ctHour         = 0;
    ctMinute       = 0;
    ctOffset       = 0;
}

//-----------------------------------------------------------------------------
// This routine adds an additional level of error checking on the PI code.
// A PI code is only considered valid when it has been identical for several
// groups.
//-----------------------------------------------------------------------------
#define RDS_PI_VALIDATE_LIMIT  4

static void
update_pi(u16 current_pi)
{
    static u8 rds_pi_validate_count = 0;
    static u16 rds_pi_nonvalidated;

    // if the pi value is the same for a certain number of times, update
    // a validated pi variable
    if (rds_pi_nonvalidated != current_pi)
    {
        rds_pi_nonvalidated =  current_pi;
        rds_pi_validate_count = 1;
    }
    else
    {
        rds_pi_validate_count++;
    }

    if (rds_pi_validate_count > RDS_PI_VALIDATE_LIMIT)
    {
        piDisplay = rds_pi_nonvalidated;
    }
}


//-----------------------------------------------------------------------------
// This routine adds an additional level of error checking on the PTY code.
// A PTY code is only considered valid when it has been identical for several
// groups.
//-----------------------------------------------------------------------------
#define RDS_PTY_VALIDATE_LIMIT 4

static void
update_pty(u8 current_pty)
{
    static u8 xdata rds_pty_validate_count = 0;
    static u8 xdata rds_pty_nonvalidated;

    // if the pty value is the same for a certain number of times, update
    // a validated pty variable
    if (rds_pty_nonvalidated != current_pty)
    {
        rds_pty_nonvalidated =  current_pty;
        rds_pty_validate_count = 1;
    }
    else
    {
        rds_pty_validate_count++;
    }

    if (rds_pty_validate_count > RDS_PTY_VALIDATE_LIMIT)
    {
        ptyDisplay = rds_pty_nonvalidated;
    }
}


//-----------------------------------------------------------------------------
// The basic implementation of the Program Service update displays data
// immediately but does no additional error detection.
//-----------------------------------------------------------------------------
static void
update_ps_basic(u8 current_ps_addr, u8 current_ps_byte)
{
    psDisplay[current_ps_addr] = current_ps_byte;
}

//-----------------------------------------------------------------------------
// This implelentation of the Program Service update attempts to display
// only complete messages for stations who rotate text through the PS field
// in violation of the RBDS standard as well as providing enhanced error
// detection.
//-----------------------------------------------------------------------------
#define PS_VALIDATE_LIMIT 2
static void
update_ps(u8 addr, u8 byte)
{
    u8 i;
    bit textChange = 0; // indicates if the PS text is in transition
    bit psComplete = 1; // indicates that the PS text is ready to be displayed

    if(psTmp0[addr] == byte)
    {
        // The new byte matches the high probability byte
        if(psCnt[addr] < PS_VALIDATE_LIMIT)
        {
            psCnt[addr]++;
        }
        else
        {
            // we have recieved this byte enough to max out our counter
            // and push it into the low probability array as well
            psCnt[addr] = PS_VALIDATE_LIMIT;
            psTmp1[addr] = byte;
        }
    }
    else if(psTmp1[addr] == byte)

⌨️ 快捷键说明

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