summaryrefslogtreecommitdiff
path: root/xpp/card_fxo.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-09-02 21:36:25 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-09-02 21:36:25 +0000
commitf9d97f28383eba55a138e116171cf8cc153d18fe (patch)
treee83492fa0fdfe76dba819de5575d13e87b7c8922 /xpp/card_fxo.c
parent4d459f43f7b214c26ad33c8206179a3f9c76aac8 (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.c54
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);