diff options
author | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-09-02 21:36:25 +0000 |
---|---|---|
committer | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-09-02 21:36:25 +0000 |
commit | f9d97f28383eba55a138e116171cf8cc153d18fe (patch) | |
tree | e83492fa0fdfe76dba819de5575d13e87b7c8922 /xpp/card_fxo.c | |
parent | 4d459f43f7b214c26ad33c8206179a3f9c76aac8 (diff) |
Fix problems with battery voltage fluctuations:
- Use a higher voltage.
- Add a software debounce counter.
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@1381 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/card_fxo.c')
-rw-r--r-- | xpp/card_fxo.c | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/xpp/card_fxo.c b/xpp/card_fxo.c index d905a38..5600a9f 100644 --- a/xpp/card_fxo.c +++ b/xpp/card_fxo.c @@ -51,6 +51,9 @@ enum fxo_leds { #define NUM_LEDS 1 #define DELAY_UNTIL_DIALTONE 3000 +#define BAT_THRESHOLD 3 +#define BAT_DEBOUNCE 3 /* compensate for battery voltage fluctuation (in poll_battery_interval's) */ + /*---------------- FXO Protocol Commands ----------------------------------*/ static /* 0x0F */ DECLARE_CMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on); @@ -83,6 +86,7 @@ struct FXO_priv_data { slic_reply_t requested_reply; slic_reply_t last_reply; xpp_line_t battery; + ushort battery_debounce[CHANNELS_PERXPD]; xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */ xpp_line_t ledcontrol[NUM_LEDS]; /* 0 - OFF, 1 - ON */ int blinking[NUM_LEDS][CHANNELS_PERXPD]; @@ -699,22 +703,28 @@ HANDLER_DEF(FXO, DAA_REPLY) priv = xpd->priv; BUG_ON(!priv); if(!info->indirect && info->reg_num == DAA_VBAT_REGISTER) { - xpp_line_t last_batt_on = priv->battery; - xpp_line_t changed_lines; - signed char bat = info->data_low; + byte bat = abs((signed char)info->data_low); int i; - if(abs(bat) < BAT_THRESHOLD) { - priv->battery &= ~lines; - // DBG("%s/%s: BATTERY OFF (%04X) = %d\n", xpd->xbus->busname, xpd->xpdname, lines, bat); - } else { - priv->battery |= lines; - // DBG("%s/%s: BATTERY ON (%04X) = %d\n", xpd->xbus->busname, xpd->xpdname, lines, bat); - } - changed_lines = last_batt_on ^ priv->battery; for_each_line(xpd, i) { - if(IS_SET(changed_lines, i)) { - update_line_status(xpd, i, IS_SET(priv->battery, i)); + if(!IS_SET(lines, i)) + continue; + if(bat < BAT_THRESHOLD) { + /* + * Check for battery voltage fluctuations + */ + if(IS_SET(priv->battery, i) && priv->battery_debounce[i]++ > BAT_DEBOUNCE) { + DBG("%s/%s: BATTERY OFF (%04X) voltage=%d\n", xpd->xbus->busname, xpd->xpdname, lines, bat); + priv->battery &= ~lines; + update_line_status(xpd, i, 0); + } + } else { + priv->battery_debounce[i] = 0; + if(!IS_SET(priv->battery, i)) { + DBG("%s/%s: BATTERY ON (%04X) voltage=%d\n", xpd->xbus->busname, xpd->xpdname, lines, bat); + priv->battery |= lines; + update_line_status(xpd, i, 1); + } } } } @@ -824,38 +834,42 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count, in len += sprintf(page + len, "\t%-17s: ", "Channel"); for_each_line(xpd, i) { if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) - len += sprintf(page + len, "%d ", i % 10); + len += sprintf(page + len, "%2d ", i % 10); } len += sprintf(page + len, "\n\t%-17s: ", "ledstate"); for_each_line(xpd, i) { if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) - len += sprintf(page + len, "%d ", IS_SET(priv->ledstate[LED_GREEN], i)); + len += sprintf(page + len, "%2d ", IS_SET(priv->ledstate[LED_GREEN], i)); } len += sprintf(page + len, "\n\t%-17s: ", "ledcontrol"); for_each_line(xpd, i) { if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) - len += sprintf(page + len, "%d ", IS_SET(priv->ledcontrol[LED_GREEN], i)); + len += sprintf(page + len, "%2d ", IS_SET(priv->ledcontrol[LED_GREEN], i)); } len += sprintf(page + len, "\n\t%-17s: ", "blinking"); for_each_line(xpd, i) { if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) - len += sprintf(page + len, "%d ", IS_BLINKING(priv,i,LED_GREEN)); + len += sprintf(page + len, "%2d ", IS_BLINKING(priv,i,LED_GREEN)); } #ifdef SOFT_RING len += sprintf(page + len, "\n\t%-17s: ", "ring_thresh"); for_each_line(xpd, i) { if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) - len += sprintf(page + len, "%d ", priv->ring_thresh[i]); + len += sprintf(page + len, "%2d ", priv->ring_thresh[i]); } len += sprintf(page + len, "\n\t%-17s: ", "noring_thresh"); for_each_line(xpd, i) { if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) - len += sprintf(page + len, "%d ", priv->noring_thresh[i]); + len += sprintf(page + len, "%2d ", priv->noring_thresh[i]); } #endif len += sprintf(page + len, "\n\t%-17s: ", "battery"); for_each_line(xpd, i) { - len += sprintf(page + len, "%d ", IS_SET(priv->battery, i)); + len += sprintf(page + len, "%2d ", IS_SET(priv->battery, i)); + } + len += sprintf(page + len, "\n\t%-17s: ", "battery_debounce"); + for_each_line(xpd, i) { + len += sprintf(page + len, "%2d ", priv->battery_debounce[i]); } len += sprintf(page + len, "\n"); spin_unlock_irqrestore(&xpd->lock, flags); |