浏览代码

esplink: fix handshake between ESP and FPGA

Fix the initial handshake between ESP and FPGA.
H. Peter Anvin 2 年之前
父节点
当前提交
bec7285913
共有 20 个文件被更改,包括 30 次插入28 次删除
  1. 23 21
      esp32/max80/fpgasvc.c
  2. 二进制
      esp32/output/max80.ino.bin
  3. 3 3
      fpga/max80.qpf
  4. 二进制
      fpga/output/bypass.jic
  5. 二进制
      fpga/output/v1.fw
  6. 二进制
      fpga/output/v1.jic
  7. 二进制
      fpga/output/v1.rbf.gz
  8. 二进制
      fpga/output/v1.rpd.gz
  9. 二进制
      fpga/output/v1.sof
  10. 二进制
      fpga/output/v1.svf.gz
  11. 二进制
      fpga/output/v1.xsvf.gz
  12. 二进制
      fpga/output/v2.fw
  13. 二进制
      fpga/output/v2.jic
  14. 二进制
      fpga/output/v2.rbf.gz
  15. 二进制
      fpga/output/v2.rpd.gz
  16. 二进制
      fpga/output/v2.sof
  17. 二进制
      fpga/output/v2.svf.gz
  18. 二进制
      fpga/output/v2.xsvf.gz
  19. 1 1
      rv32/checksum.h
  20. 3 3
      rv32/esp.c

+ 23 - 21
esp32/max80/fpgasvc.c

@@ -132,7 +132,7 @@ esp_err_t fpga_service_init(void)
 {
     esp_err_t err;
 
-    pinMode(PIN_FPGA_INT, INPUT_PULLUP);
+    pinMode(PIN_FPGA_INT, INPUT);
 
     setenv_bool("status.max80.fpga", false);
 
@@ -176,11 +176,12 @@ static bool fpga_link_enable(void)
 
     xEventGroupClearBits(spi_done_evgroup, EVENT_ALL_BITS);
     
-    pinMode(PIN_FPGA_INT, INPUT_PULLUP);
+    pinMode(PIN_FPGA_INT, INPUT);
     attachInterrupt(PIN_FPGA_INT, fpga_interrupt, FALLING);
 
     xEventGroupSetBits(fpga_service_evgroup, NOTIFY_ENABLE);
     xSemaphoreGiveRecursive(spi_mutex);
+    fpga_notify_from_task(NOTIFY_FPGA); /* In case FPGA_INT was already low */
     goto done;
 
 release_bus_fail:
@@ -223,8 +224,11 @@ static bool fpga_online(void)
     fpga_io_read(FPGA_CMD_ACK(EL_UIRQ_READY), ESPLINK_HDR_ADDR,
 		 &head, sizeof head);
 
-    if (head.magic != ESPLINK_HEAD_MAGIC || head.hlen <= 8)
+    if (head.magic != ESPLINK_HEAD_MAGIC || head.hlen <= 8) {
+	printf("[FPGA] Bad header received, magic = 0x%08x len = %u\n",
+	       head.magic, head.hlen);
 	return false;
+    }
 
     if (unlikely(head.hlen < sizeof head)) {
 	/* Clear any fields not provided */
@@ -288,7 +292,7 @@ esp_err_t fpga_iov(const struct fpga_iov *iov, size_t niov)
 	    t->base.rxlength  = iv->len << 3;
 	    t->base.rx_buffer = iv->rdata;
 	    /* Emulate partial word read by adding dummy bits for offset */
-	    t->dummy_bits     = (iv->iaddr & 3) << 2;
+	    t->dummy_bits     = 16 + ((iv->iaddr & 3) << 2);
 	    if (iv->cmd & FPGA_CMD_STATUS) {
 		/*
 		 * Include the status "dummy" bits
@@ -417,25 +421,23 @@ static void fpga_service_task(void *dummy)
 	    notifiers = notify_wait_for(NOTIFY_ENABLE);
 
 	    if ((notifiers & NOTIFY_ENABLE) && fpga_link_enable()) {
-		fputs("[FPGA] FPGA services enabled\n", stdout);
+		fputs("[FPGA] Enabling FPGA services\n", stdout);
 		fpga_state = FPGA_OFFLINE;
 	    }
 	    break;
 
 	case FPGA_OFFLINE:
-	    fpga_io_status(FPGA_CMD_IRQ(EL_DIRQ_HELLO));
-
-	    notifiers = notify_wait_for(NOTIFY_FPGA|NOTIFY_DISABLE);
-	    if (notifiers & NOTIFY_DISABLE)
-		break;
-
-	    status = fpga_io_status(FPGA_CMD_ACK(EL_UIRQ_READY));
-
-	    if ((status & ~0xfce) == 0x9030 && fpga_online()) {
-		fpga_state = FPGA_ONLINE;
-	    }
-
-	    break;
+	  status = fpga_io_status(FPGA_CMD_ACK(EL_UIRQ_READY)|
+				  FPGA_CMD_IRQ(EL_DIRQ_HELLO));
+	  printf("[FPGA] FPGA status flags = 0x%08x\n", status);
+
+	  if ((status & 0xf031) == 0x9030) {
+	      if (fpga_online())
+		  fpga_state = FPGA_ONLINE;
+	  } else if (digitalRead(PIN_FPGA_INT)) {
+	      notifiers = notify_wait_for(NOTIFY_FPGA|NOTIFY_DISABLE);
+	  }
+	  break;
 
 	case FPGA_ONLINE:
 	    notifiers = notify_wait_for(NOTIFY_FPGA|NOTIFY_DISABLE);
@@ -448,9 +450,9 @@ static void fpga_service_task(void *dummy)
 	    while (!digitalRead(PIN_FPGA_INT)) {
 		status = fpga_io_status(0);
 
-		if ((status & ~0xfce) != 0x9010) {
+		if ((status & 0xf031) != 0x9010) {
 		    fpga_offline();
-		    fputs("[FPGA] FPGA offline\n", stdout);
+		    printf("[FPGA] FPGA offline, status = 0x%08x\n", status);
 		    fpga_state = FPGA_OFFLINE;
 		    break;
 		}
@@ -467,7 +469,7 @@ static void fpga_service_task(void *dummy)
 	}
 
 	if (notifiers & NOTIFY_DISABLE) {
-	    fputs("[FPGA] FPGA services disabled\n", stdout);
+	    fputs("[FPGA] Disabling FPGA services\n", stdout);
 	    fpga_link_disable();
 	    fpga_state = FPGA_DISABLED;
 	}

二进制
esp32/output/max80.ino.bin


+ 3 - 3
fpga/max80.qpf

@@ -19,15 +19,15 @@
 #
 # Quartus Prime
 # Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
-# Date created = 02:29:52  May 14, 2022
+# Date created = 03:00:56  May 14, 2022
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "21.1"
-DATE = "02:29:52  May 14, 2022"
+DATE = "03:00:56  May 14, 2022"
 
 # Revisions
 
 PROJECT_REVISION = "v1"
-PROJECT_REVISION = "v1"
+PROJECT_REVISION = "v2"
 PROJECT_REVISION = "bypass"

二进制
fpga/output/bypass.jic


二进制
fpga/output/v1.fw


二进制
fpga/output/v1.jic


二进制
fpga/output/v1.rbf.gz


二进制
fpga/output/v1.rpd.gz


二进制
fpga/output/v1.sof


二进制
fpga/output/v1.svf.gz


二进制
fpga/output/v1.xsvf.gz


二进制
fpga/output/v2.fw


二进制
fpga/output/v2.jic


二进制
fpga/output/v2.rbf.gz


二进制
fpga/output/v2.rpd.gz


二进制
fpga/output/v2.sof


二进制
fpga/output/v2.svf.gz


二进制
fpga/output/v2.xsvf.gz


+ 1 - 1
rv32/checksum.h

@@ -1,4 +1,4 @@
 #ifndef CHECKSUM_H
 #define CHECKSUM_H
-#define SDRAM_SUM 0x910d2974
+#define SDRAM_SUM 0xfc05d140
 #endif

+ 3 - 3
rv32/esp.c

@@ -15,12 +15,12 @@ IRQHANDLER(esp,0)
 
     if (irqstatus & (1 << EL_DIRQ_UNDERRUN)) {
 	con_printf("[ESP] ESP link memory underrun!!\n");
-	ESP_SPI_IRQ = (0x10 << EL_UIRQ_READY); /* Block writes, reinitialize! */
+	ESP_SPI_IRQ = (1 << EL_UIRQ_READY); /* Block writes, reinitialize! */
     }
     if (irqstatus & (1 << EL_DIRQ_HELLO)) {
 	con_printf("[ESP] Got hello, sending ready...\n");
 	/* Hello, are you there? Yes, I'm here, and you can write data now */
-	ESP_SPI_IRQ_SET = (0x10 << EL_UIRQ_READY)|(0x10 << EL_UIRQ_WREN);
+	ESP_SPI_IRQ_SET = (1 << EL_UIRQ_READY)|(1 << EL_UIRQ_WREN);
     }
 }
 
@@ -39,7 +39,7 @@ void esp_init(void)
     esplink_head.signature_len = sizeof esp_signature - 1;
 
     esplink_head.magic         = ESPLINK_HEAD_MAGIC;
-    ESP_SPI_IRQ                = (0x10 << EL_UIRQ_READY);
+    ESP_SPI_IRQ                = (1 << EL_UIRQ_READY);
 
     unmask_irq(ESP_IRQ);
 }