From 71dc93b3b1239221c5dc92671f4d876dd569bd03 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Mon, 29 Apr 2024 20:50:59 +0200 Subject: [PATCH] icE1usb fw: Add AIS error flag and fill it along with LOS from linemon Now that we monitor low level line status, we can fill in a proper LOS signal along with the newly introduced AIS flag Signed-off-by: Sylvain Munaut Change-Id: Ied28b6b3da74f6a63a007fae889b571cc2c1e835 --- firmware/ice40-riscv/icE1usb/e1.c | 33 ++++++++++++++++++-- firmware/ice40-riscv/icE1usb/e1.h | 1 + firmware/ice40-riscv/icE1usb/ice1usb_proto.h | 1 + 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/firmware/ice40-riscv/icE1usb/e1.c b/firmware/ice40-riscv/icE1usb/e1.c index 1582cec..6baee16 100644 --- a/firmware/ice40-riscv/icE1usb/e1.c +++ b/firmware/ice40-riscv/icE1usb/e1.c @@ -565,12 +565,18 @@ e1_poll(int port) if (e1_regs->rx.csr & E1_RX_SR_ALIGNED) { e1_platform_led_set(port, E1P_LED_GREEN, E1P_LED_ST_ON); led_color(0, 48, 0); - e1->errors.flags &= ~(E1_ERR_F_LOS|E1_ERR_F_ALIGN_ERR); + e1->errors.flags &= ~( + E1_ERR_F_LOS | + E1_ERR_F_AIS | + E1_ERR_F_RAI | + E1_ERR_F_ALIGN_ERR + ); } else { e1_platform_led_set(port, E1P_LED_GREEN, E1P_LED_ST_BLINK); e1_platform_led_set(port, E1P_LED_YELLOW, E1P_LED_ST_OFF); led_color(48, 0, 0); - e1->errors.flags |= E1_ERR_F_ALIGN_ERR; + e1->errors.flags |= E1_ERR_F_ALIGN_ERR; + e1->errors.flags &= ~E1_ERR_F_RAI; /* TODO: completely off if rx tick counter not incrementing */ } @@ -748,7 +754,30 @@ e1_linemon_update(void) /* Next cycle */ if (++cycle == 6) + { + /* We did one full cycle of data, update our local flags */ + for (int port=0; portlinemon.rx_pulse < 16) { + /* No pulse ? -> LOS */ + e1->errors.flags |= E1_ERR_F_LOS; + e1->errors.flags &= ~E1_ERR_F_AIS; + } else { + /* We have "some" pulses, so somone is talking */ + e1->errors.flags &= ~E1_ERR_F_LOS; + + /* If it's mostly ones, consider it AIS */ + if (e1->linemon.rx_one > 2040) + e1->errors.flags |= E1_ERR_F_AIS; + else + e1->errors.flags &= ~E1_ERR_F_AIS; + } + } + + /* Start over */ cycle = 0; + } } void diff --git a/firmware/ice40-riscv/icE1usb/e1.h b/firmware/ice40-riscv/icE1usb/e1.h index 883e1ec..1e8e747 100644 --- a/firmware/ice40-riscv/icE1usb/e1.h +++ b/firmware/ice40-riscv/icE1usb/e1.h @@ -35,6 +35,7 @@ unsigned int e1_tx_level(int port); #define E1_ERR_F_ALIGN_ERR 0x01 #define E1_ERR_F_LOS 0x02 #define E1_ERR_F_RAI 0x04 +#define E1_ERR_F_AIS 0x08 struct e1_error_count { uint16_t crc; diff --git a/firmware/ice40-riscv/icE1usb/ice1usb_proto.h b/firmware/ice40-riscv/icE1usb/ice1usb_proto.h index 8cf8439..8bc8fbb 100644 --- a/firmware/ice40-riscv/icE1usb/ice1usb_proto.h +++ b/firmware/ice40-riscv/icE1usb/ice1usb_proto.h @@ -143,6 +143,7 @@ enum ice1usb_irq_type { #define ICE1USB_ERR_F_ALIGN_ERR 0x01 #define ICE1USB_ERR_F_LOS 0x02 #define ICE1USB_ERR_F_RAI 0x04 +#define ICE1USB_ERR_F_AIS 0x08 struct ice1usb_irq_err { /* 16-bit little-endian counters */