signal display process

本文深入解析了GSM数据连接跟踪器的工作原理,包括其构造方法、事件处理流程及与GPRS状态的交互机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在GsmDataConnectiontracker构造方法中
     p.mSST.registerForGprsAttached(this, EVENT_GPRS_ATTACHED, null);
        p.mSST.registerForGprsDetached(this, EVENT_GPRS_DETACHED, null);
mSST是GsmServiceStateTrack。
    void registerForGprsDetached(Handler h, int what, Object obj) {
        Registrant r = new Registrant(h, what, obj);
        gprsDetachedRegistrants.add(r);

        if (gprsState == ServiceState.STATE_OUT_OF_SERVICE) {
            r.notifyRegistrant();
        }
        }
在mGsmServiceStateTrack中,当收到底层上来的PS注册状态时,执行:
    case EVENT_POLL_STATE_GPRS:
                    states = (String[])ar.result;

                    int type = 0;
                    regState = -1;
                    if (states.length > 0) {
                        try {
                            regState = Integer.parseInt(states[0]);

                            // states[3] (if present) is the current radio technology
                            if (states.length >= 4 && states[3] != null) {
                                type = Integer.parseInt(states[3]);
                            }
                        } catch (NumberFormatException ex) {
                            Log.w(LOG_TAG, "error parsing GprsRegistrationState: " + ex);
                        }
                    }
                    newGPRSState = regCodeToServiceState(regState);
                    mDataRoaming = regCodeIsRoaming(regState);
                    newNetworkType = type;
                    newSS.setRadioTechnology(type);
                break;
然后调用pollStateDone(),方法中:
     if (hasGprsAttached) {
            gprsAttachedRegistrants.notifyRegistrants();
        }

        if (hasGprsDetached) {
            gprsDetachedRegistrants.notifyRegistrants();
        }
然后调用在GsmDataConnectiontracker的方法:
     public void handleMessage (Message msg) {
        if (DBG) Log.d(LOG_TAG,"GSMDataConnTrack handleMessage "+msg);

        if (!mGsmPhone.mIsTheCurrentActivePhone) {
            Log.d(LOG_TAG, "Ignore GSM msgs since GSM phone is inactive");
            return;
        }

        switch (msg.what) {
            case EVENT_RECORDS_LOADED:
                onRecordsLoaded();
                break;

            case EVENT_GPRS_DETACHED:
                onGprsDetached();
                break;

            case EVENT_GPRS_ATTACHED:
                onGprsAttached();
                break;
        }
        private void onGprsAttached() {
        if (state == State.CONNECTED) {
            startNetStatPoll();
            phone.notifyDataConnection(Phone.REASON_GPRS_ATTACHED);
        } else {
            if (state == State.FAILED) {
                cleanUpConnection(false, Phone.REASON_GPRS_ATTACHED);
                mRetryMgr.resetRetryCount();
            }
            trySetupData(Phone.REASON_GPRS_ATTACHED);
        }
        }

        protected void startNetStatPoll() {
        if (state == State.CONNECTED && mPingTestActive == false && netStatPollEnabled == false) {
            Log.d(LOG_TAG, "[DataConnection] Start poll NetStat");
            resetPollStats();
            netStatPollEnabled = true;
            mPollNetStat.run();
        }
        }
    private Runnable mPollNetStat = new Runnable()
        {

        public void run() {
            long sent, received;
            long preTxPkts = -1, preRxPkts = -1;

            Activity newActivity;

            preTxPkts = txPkts;
            preRxPkts = rxPkts;

            txPkts = TrafficStats.getMobileTxPackets();
            rxPkts = TrafficStats.getMobileRxPackets();setupData

            //Log.d(LOG_TAG, "rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));

            if (netStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
                sent = txPkts - preTxPkts;
                received = rxPkts - preRxPkts;

                if ( sent > 0 && received > 0 ) {
                    sentSinceLastRecv = 0;
                    newActivity = Activity.DATAINANDOUT;
                    mPdpResetCount = 0;
                } else if (sent > 0 && received == 0) {
                    if (phone.getState() == Phone.State.IDLE) {
                        sentSinceLastRecv += sent;
                    } else {
                        sentSinceLastRecv = 0;
                    }
                    newActivity = Activity.DATAOUT;
                } else if (sent == 0 && received > 0) {
                    sentSinceLastRecv = 0;
                    newActivity = Activity.DATAIN;
                    mPdpResetCount = 0;
                } else if (sent == 0 && received == 0) {
                    newActivity = Activity.NONE;
                } else {
                    sentSinceLastRecv = 0;
                    newActivity = Activity.NONE;
                }

                if (activity != newActivity && mIsScreenOn) {
                    activity = newActivity;
                    phone.notifyDataActivity();
                }
            }
PhoneBase中:
        public void notifyDataActivity() {
        mNotifier.notifyDataActivity(this);
        }
        public void notifyDataActivity() {
        mNotifier.notifyDataActivity(this);
        }
DefaultPhoneNotifier:
        public void notifyDataActivity(Phone sender) {
        try {
            mRegistry.notifyDataActivity(convertDataActivityState(sender.getDataActivityState()));
        } catch (RemoteException ex) {
            // system process is dead
        }
        }
GsmPhone:
    public DataActivityState getDataActivityState() {
        DataActivityState ret = DataActivityState.NONE;

        if (mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE) {
            switch (mDataConnection.getActivity()) {
                case DATAIN:
                    ret = DataActivityState.DATAIN;
                break;

                case DATAOUT:
                    ret = DataActivityState.DATAOUT;
                break;

                case DATAINANDOUT:
                    ret = DataActivityState.DATAINANDOUT;
                break;
            }
        }

        return ret;
        }
调用DefaultPhoneNotifier:
        public static int convertDataActivityState(Phone.DataActivityState state) {
        switch (state) {
            case DATAIN:
                return TelephonyManager.DATA_ACTIVITY_IN;
            case DATAOUT:
                return TelephonyManager.DATA_ACTIVITY_OUT;
            case DATAINANDOUT:
                return TelephonyManager.DATA_ACTIVITY_INOUT;
            case DORMANT:
                return TelephonyManager.DATA_ACTIVITY_DORMANT;
            default:
                return TelephonyManager.DATA_ACTIVITY_NONE;
        }
        }
调用TelephonyRegister:
     public void notifyDataActivity(int state) {
        369         if (!checkNotifyPermission("notifyDataActivity()" )) {
        370             return;
        371         }
        372         synchronized (mRecords) {
        373             mDataActivity = state;
        374             for (int i = mRecords.size() - 1; i >= 0; i--) {
        375                 Record r = mRecords.get(i);
        376                 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
        377                     try {
        378                         r.callback.onDataActivity(state);
        379                     } catch (RemoteException ex) {
        380                         remove(r.binder);
        381                     }
        382                 }
        383             }
        384         }
        385     }

StatusBarPolicy中:
     private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
        @Override
        public void onDataActivity(int direction) {
            mDataActivity = direction;
            updateDataIcon();
        }
        };
    private final void updateDataIcon() {
        int iconId;
        boolean visible = true;

        if (!isCdma()) {
            // GSM case, we have to check also the sim state
            if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
                if (hasPsService() && mDataState == TelephonyManager.DATA_CONNECTED) {
                    switch (mDataActivity) {
                        case TelephonyManager.DATA_ACTIVITY_IN:
                            iconId = mDataIconList[1];
                            break;
                        case TelephonyManager.DATA_ACTIVITY_OUT:
                            iconId = mDataIconList[2];
                            break;
                        case TelephonyManager.DATA_ACTIVITY_INOUT:
                            iconId = mDataIconList[3];
                            break;
                        default:
                            iconId = mDataIconList[0];
                            break;
                    }
                    mService.setIcon("data_connection", iconId, 0);
                } else {
                    visible = false;
                }
            } else {
                iconId = R.drawable.stat_sys_no_sim;
                mService.setIcon("data_connection", iconId, 0);
            }
        }
        }


library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity test is Port ( clk_50MHz : in STD_LOGIC; reset : in STD_LOGIC; freq_up : in STD_LOGIC; duty_up : in STD_LOGIC; led1 : out STD_LOGIC; seg : out STD_LOGIC_VECTOR(6 downto 0); an : out STD_LOGIC_VECTOR(3 downto 0) ); end test; architecture Behavioral of test is constant CLK_FREQ : integer := 50_000_000; constant DEBOUNCE_MS : integer := 20; constant DEBOUNCE_TICKS : integer := (CLK_FREQ/1000)*DEBOUNCE_MS; -- 20ms计数值 signal freq_reg : integer range 1 to 200 := 1; -- 1-200 kHz signal duty_reg : integer range 0 to 100 := 50; -- 0-100% signal wave_reg : STD_LOGIC := '0'; -- 按键消抖状态机信号 type debounce_state is (IDLE, WAIT_STABLE); signal freq_state, duty_state : debounce_state := IDLE; signal freq_cnt, duty_cnt : integer range 0 to DEBOUNCE_TICKS-1 := 0; signal freq_stable, duty_stable : STD_LOGIC := '0'; signal freq_prev, duty_prev : STD_LOGIC := '0'; -- 边沿检测信号 signal freq_pulse, duty_pulse : STD_LOGIC := '0'; signal display_num : integer range 0 to 9999 := 0; signal refresh_cnt : integer range 0 to (CLK_FREQ/1000)-1 := 0; signal seg_sel : integer range 0 to 3 := 0; signal period_cnt : integer := 0; signal period_max : integer := CLK_FREQ/1000; -- 1kHz default signal digit : integer range 0 to 9 := 0; begin -- 频率按键消抖状态机 process(clk_50MHz) begin if rising_edge(clk_50MHz) then if reset = '1' then freq_state <= IDLE; freq_cnt <= 0; freq_stable <= '0'; else case freq_state is when IDLE => if freq_up /= freq_stable then freq_state <= WAIT_STABLE; freq_cnt <= 0; end if; when WAIT_STABLE => if freq_cnt < DEBOUNCE_TICKS-1 then freq_cnt <= freq_cnt + 1; else freq_stable <= freq_up; -- 更新稳定信号 freq_state <= IDLE; end if; end case; end if; end if; end process; -- 占空比按键消抖状态机 process(clk_50MHz) begin if rising_edge(clk_50MHz) then if reset = '1' then duty_state <= IDLE; duty_cnt <= 0; duty_stable <= '0'; else case duty_state is when IDLE => if duty_up /= duty_stable then duty_state <= WAIT_STABLE; duty_cnt <= 0; end if; when WAIT_STABLE => if duty_cnt < DEBOUNCE_TICKS-1 then duty_cnt <= duty_cnt + 1; else duty_stable <= duty_up; -- 更新稳定信号 duty_state <= IDLE; end if; end case; end if; end if; end process; -- 边沿检测电路 process(clk_50MHz) begin if rising_edge(clk_50MHz) then freq_prev <= freq_stable; duty_prev <= duty_stable; -- 检测上升沿 if (freq_stable = '1' and freq_prev = '0') then freq_pulse <= '1'; else freq_pulse <= '0'; end if; if (duty_stable = '1' and duty_prev = '0') then duty_pulse <= '1'; else duty_pulse <= '0'; end if; end if; end process; -- 频率和占空比控制 process(clk_50MHz) variable temp_period : integer; begin if rising_edge(clk_50MHz) then if reset = '1' then freq_reg <= 1; duty_reg <= 50; period_max <= CLK_FREQ/1000; -- 1kHz else -- 频率增加:检测单脉冲 if freq_pulse = '1' then if freq_reg >= 200 then freq_reg <= 1; else freq_reg <= freq_reg + 1; end if; -- 安全计算周期 if freq_reg > 0 then temp_period := CLK_FREQ / (freq_reg * 1000); -- 确保周期至少为1 if temp_period > 0 then period_max <= temp_period; else period_max <= 1; -- 最小周期值 end if; else period_max <= CLK_FREQ/1000; -- 默认1kHz end if; end if; -- 占空比增加:检测单脉冲(10%步进) if duty_pulse = '1' then if duty_reg >= 100 then -- 达到100%后回到10% duty_reg <= 10; else -- 确保不超过100% if (duty_reg + 10) > 100 then duty_reg <= 100; else duty_reg <= duty_reg + 10; end if; end if; end if; display_num <= freq_reg; -- 显示当前频率(kHz) end if; end if; end process; -- PWM生成(增强保护) process(clk_50MHz) variable threshold : integer; begin if rising_edge(clk_50MHz) then -- 双重保护:确保period_max有效 if period_max > 0 then -- 防止除以零错误 threshold := (period_max * duty_reg) / 100; -- 计数器逻辑 if period_cnt < period_max-1 then period_cnt <= period_cnt + 1; else period_cnt <= 0; end if; -- PWM输出 if period_cnt < threshold then wave_reg <= '1'; else wave_reg <= '0'; end if; else -- 无效period_max时的安全处理 wave_reg <= '0'; period_cnt <= 0; end if; end if; end process; led1 <= wave_reg; -- 7段数码管显示 process(clk_50MHz) begin if rising_edge(clk_50MHz) then if refresh_cnt < (CLK_FREQ/1000)-1 then refresh_cnt <= refresh_cnt + 1; else refresh_cnt <= 0; seg_sel <= seg_sel + 1; if seg_sel = 3 then seg_sel <= 0; end if; end if; -- 使用单独的case语句处理每个分支 case seg_sel is when 0 => an <= "1110"; digit <= display_num mod 10; when 1 => an <= "1101"; digit <= (display_num / 10) mod 10; when 2 => an <= "1011"; digit <= (display_num / 100) mod 10; when 3 => an <= "0111"; digit <= display_num / 1000; end case; -- 单独处理段选信号 case digit is when 0 => seg <= "1000000"; when 1 => seg <= "1111001"; when 2 => seg <= "0100100"; when 3 => seg <= "0110000"; when 4 => seg <= "0011001"; when 5 => seg <= "0010010"; when 6 => seg <= "0000010"; when 7 => seg <= "1111000"; when 8 => seg <= "0000000"; when 9 => seg <= "0010000"; when others => seg <= "1111111"; end case; end if; end process; end Behavioral;要在显示屏上显示正在输出的频率
最新发布
06-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值