icE1usb firmware: Detect A-bit in TS0; report via USB + LED

Scan over every odd E1 frame TS0 byte to check if the A-bit is set,
indicating a remote alarm.  If so, set yellow LED and report via the
error flags communicated to the host by USB interrupt transfer.

Change-Id: Ic4f57cf79bd32cf75f81ef3073cb8d4a2d1857d8
diff --git a/firmware/ice40-riscv/icE1usb/e1.c b/firmware/ice40-riscv/icE1usb/e1.c
index 5e57480..f5e367e 100644
--- a/firmware/ice40-riscv/icE1usb/e1.c
+++ b/firmware/ice40-riscv/icE1usb/e1.c
@@ -290,9 +290,11 @@
 unsigned int
 e1_rx_need_data(unsigned int usb_addr, unsigned int max_frames, unsigned int *pos)
 {
+	bool rai_received = false;
+	bool rai_possible = false;
 	unsigned int ofs;
 	int tot_frames = 0;
-	int n_frames;
+	int n_frames, i;
 
 	while (max_frames) {
 		/* Get some data from the FIFO */
@@ -314,10 +316,34 @@
 		max_frames -= n_frames;
 		tot_frames += n_frames;
 
+		/* While DMA is running: Determine if remote end indicates any alarms */
+		for (i = 0; i < n_frames; i++) {
+			unsigned int frame_nr = ofs + i;
+			/* A bit is present in every odd frame TS0 */
+			if (frame_nr & 1) {
+				uint8_t ts0 = *e1_data_ptr(0, ofs + i, 0);
+				rai_possible = true;
+				if (ts0 & 0x20) {
+					rai_received = true;
+					break;
+				}
+			}
+		}
+
 		/* Wait for DMA completion */
 		while (dma_poll());
 	}
 
+	if (rai_possible) {
+		if (rai_received) {
+			g_e1.errors.flags |= E1_ERR_F_RAI;
+			e1_platform_led_set(0, E1P_LED_YELLOW, E1P_LED_ST_ON);
+		} else {
+			g_e1.errors.flags &= ~E1_ERR_F_RAI;
+			e1_platform_led_set(0, E1P_LED_YELLOW, E1P_LED_ST_OFF);
+		}
+	}
+
 	return tot_frames;
 }