Explorar o código

Have ESP issue a handshake interrupt; some common link code

Have ESP send a handshake interrupt to the FPGA in case it is already
up and running (e.g. after an ESP-only reboot.) Some initial work on
sharing header files.

XXX: interrupt not received on the ESP side?!
H. Peter Anvin %!s(int64=2) %!d(string=hai) anos
pai
achega
832c07c31f
Modificáronse 25 ficheiros con 108 adicións e 41 borrados
  1. 29 0
      esp32/max80/esplink.h
  2. 26 16
      esp32/max80/fpgasvc.c
  3. BIN=BIN
      esp32/output/max80.ino.bin
  4. 2 2
      fpga/max80.qpf
  5. BIN=BIN
      fpga/output/bypass.jic
  6. BIN=BIN
      fpga/output/v1.fw
  7. BIN=BIN
      fpga/output/v1.jic
  8. BIN=BIN
      fpga/output/v1.rbf.gz
  9. BIN=BIN
      fpga/output/v1.rpd.gz
  10. BIN=BIN
      fpga/output/v1.sof
  11. BIN=BIN
      fpga/output/v1.svf.gz
  12. BIN=BIN
      fpga/output/v1.xsvf.gz
  13. BIN=BIN
      fpga/output/v2.fw
  14. BIN=BIN
      fpga/output/v2.jic
  15. BIN=BIN
      fpga/output/v2.rbf.gz
  16. BIN=BIN
      fpga/output/v2.rpd.gz
  17. BIN=BIN
      fpga/output/v2.sof
  18. BIN=BIN
      fpga/output/v2.svf.gz
  19. BIN=BIN
      fpga/output/v2.xsvf.gz
  20. 1 1
      rv32/Makefile
  21. 1 1
      rv32/checksum.h
  22. 44 0
      rv32/esp.c
  23. 1 0
      rv32/esplink.h
  24. 3 0
      rv32/fw.h
  25. 1 21
      rv32/system.c

+ 29 - 0
esp32/max80/esplink.h

@@ -0,0 +1,29 @@
+/*
+ * Common header file for ESP32 and RV32 sides of link
+ */
+#ifndef ESPLINK_H
+#define ESPLINK_H 1
+
+#include <inttypes.h>
+#include <stddef.h>
+
+#define FPGA_HDR_ADDR	0x40000000
+
+#define DRAM_IO_MAGIC	0x3648dec4
+struct dram_io_head {
+    uint32_t    magic;
+    size_t      hlen;
+    void       *dptr;
+    size_t      dlen;
+    uint32_t    board;
+    const char *signature;
+    size_t      signature_len;
+    uint32_t    resv[1];
+};
+
+#define RV_IRQ_UNDERRUN	0
+#define RV_IRQ_HELLO	1
+#define ESP_IRQ_READY	1
+
+#endif
+

+ 26 - 16
esp32/max80/fpgasvc.c

@@ -1,6 +1,7 @@
 #include "common.h"
 #include "config.h"
 #include "fpga.h"
+#include "esplink.h"
 
 #include <driver/gpio.h>
 #include <driver/spi_common.h>
@@ -137,10 +138,8 @@ void fpga_service_stop(void)
     printf("[FPGA] FPGA services stopped\n");
 }
 
-#define FPGA_CMD_IRQ1	(1 << 0)
-#define FPGA_CMD_IRQ2	(2 << 0)
-#define FPGA_CMD_IRQ3	(3 << 0)
-#define FPGA_CMD_ACK1	(1 << 2)
+#define FPGA_CMD_IRQ(x)	((x) << 0)
+#define FPGA_CMD_ACK(x)	((x) << 2)
 #define FPGA_CMD_ACK2	(2 << 2)
 #define FPGA_CMD_ACK3	(3 << 2)
 #define FPGA_CMD_WR	(0 << 4)
@@ -153,6 +152,11 @@ static esp_err_t fpga_io(uint8_t cmd, uint32_t addr, void *data, size_t len)
     spi_transaction_ext_t trans;
     esp_err_t err;
 
+    if ((len|addr) & 3) {
+	printf("[FPGA] ERROR: I/O must be aligned dwords\n");
+	return ESP_FAIL;
+    }
+
     memset(&trans, 0, sizeof trans);
     trans.base.flags   =
 	SPI_TRANS_MODE_DIO |
@@ -180,27 +184,33 @@ static esp_err_t fpga_io(uint8_t cmd, uint32_t addr, void *data, size_t len)
     return err;
 }
 
+
 static void fpga_service_task(void *dummy)
 {
     (void)dummy;
-    uint32_t head[8];
+    struct dram_io_head head;
 
-    while (1) {
-	vTaskDelay(10 * configTICK_RATE_HZ);
-
-	fpga_io(FPGA_CMD_RD|FPGA_CMD_ACK1, FPGA_HDR_ADDR,
-		head, sizeof head);
-
-	for (unsigned int i = 0; i < ARRAY_SIZE(head); i++) {
-	    printf("[FPGA] head[%u] = 0x%08x (%u)\n",
-		   i, head[i], head[i]);
-	}
-    }
+    /* If the FPGA is already up, need to issue our own active handshake */
+    fpga_io(FPGA_CMD_WR|FPGA_CMD_IRQ(RV_IRQ_HELLO), 0, NULL, 0);
 
     while (1) {
 	while (!digitalRead(PIN_FPGA_INT)) {
 	    printf("[FPGA] FPGA signals ready\n");
 
+	    fpga_io(FPGA_CMD_RD|FPGA_CMD_ACK(ESP_IRQ_READY), FPGA_HDR_ADDR,
+		    &head, sizeof head);
+
+	    if (head.magic == DRAM_IO_MAGIC && head.hlen >= sizeof head) {
+		printf("[FPGA] Ready, board = %u.%u\n",
+		       (uint8_t)(head.board >> 24), (uint8_t)(head.board >> 16));
+	    }
+
+	    char signature_string[head.signature_len + 3];
+	    fpga_io(FPGA_CMD_RD, (size_t)head.signature,
+		    signature_string, (head.signature_len + 3) & ~3);
+	    signature_string[head.signature_len] = '\0';
+
+	    printf("[FPGA] \"%s\"\n", signature_string);
 	}
 
 	/* Wait until an interrupt is received */

BIN=BIN
esp32/output/max80.ino.bin


+ 2 - 2
fpga/max80.qpf

@@ -19,12 +19,12 @@
 #
 # Quartus Prime
 # Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
-# Date created = 06:01:40  May 01, 2022
+# Date created = 13:46:46  May 02, 2022
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "21.1"
-DATE = "06:01:40  May 01, 2022"
+DATE = "13:46:46  May 02, 2022"
 
 # Revisions
 

BIN=BIN
fpga/output/bypass.jic


BIN=BIN
fpga/output/v1.fw


BIN=BIN
fpga/output/v1.jic


BIN=BIN
fpga/output/v1.rbf.gz


BIN=BIN
fpga/output/v1.rpd.gz


BIN=BIN
fpga/output/v1.sof


BIN=BIN
fpga/output/v1.svf.gz


BIN=BIN
fpga/output/v1.xsvf.gz


BIN=BIN
fpga/output/v2.fw


BIN=BIN
fpga/output/v2.jic


BIN=BIN
fpga/output/v2.rbf.gz


BIN=BIN
fpga/output/v2.rpd.gz


BIN=BIN
fpga/output/v2.sof


BIN=BIN
fpga/output/v2.svf.gz


BIN=BIN
fpga/output/v2.xsvf.gz


+ 1 - 1
rv32/Makefile

@@ -45,7 +45,7 @@ ROMOBJS  = $(ROMS:.rom=.o)
 
 LIBOBJ   = head.o dummy.o die.o system.o \
 	   ioregsa.o irqasm.o irqtable.o spurious_irq.o sbrk.o \
-	   console.o rtc.o romcopy.o spiflash.o \
+	   console.o rtc.o romcopy.o spiflash.o esp.o \
 	   sdcard.o diskcache.o \
 	   abcmem.o abcio.o abcdisk.o abcrtc.o abcpun80.o \
 	   memset.o memcpy.o \

+ 1 - 1
rv32/checksum.h

@@ -1,4 +1,4 @@
 #ifndef CHECKSUM_H
 #define CHECKSUM_H
-#define SDRAM_SUM 0x77dade67
+#define SDRAM_SUM 0x1ec13164
 #endif

+ 44 - 0
rv32/esp.c

@@ -0,0 +1,44 @@
+#include "compiler.h"
+#include "fw.h"
+#include "io.h"
+#include "console.h"
+#include "esplink.h"
+
+struct dram_io_head __dram_io_head dram_io_head;
+
+uint32_t __dram_io dram_io[(65536 - sizeof(struct dram_io_head)) >> 2];
+
+IRQHANDLER(esp,0)
+{
+    uint32_t irqstatus = ESP_CPU_IRQ;
+    ESP_CPU_IRQ_CLR = irqstatus;
+
+    if (irqstatus & (1 << RV_IRQ_UNDERRUN)) {
+	con_printf("[ESP] ESP link memory underrun!!\n");
+    }
+    if (irqstatus & (1 << RV_IRQ_HELLO)) {
+	con_printf("[ESP] Got hello, sending ready...\n");
+	/* Hello, are you there? Yes, I'm here... */
+	ESP_SPI_IRQ_SET = 1 << ESP_IRQ_READY;
+    }
+}
+
+void esp_init(void)
+{
+    static const char __aligned(4) esp_signature[]
+	= "Hej tomtebuggar slå i glasen!";
+
+    dram_io_head.magic         = 0;
+    dram_io_head.hlen          = sizeof dram_io_head;
+    dram_io_head.dptr          = dram_io;
+    dram_io_head.dlen          = sizeof dram_io;
+    dram_io_head.board         = SYS_BOARDCFG;
+    dram_io_head.signature     = esp_signature;
+    dram_io_head.signature_len = sizeof esp_signature - 1;
+    memset(&dram_io_head.resv, 0, sizeof dram_io_head.resv);
+
+    dram_io_head.magic         = DRAM_IO_MAGIC;
+    ESP_SPI_IRQ_SET = 1 << ESP_IRQ_READY;
+
+    unmask_irq(ESP_IRQ);
+}

+ 1 - 0
rv32/esplink.h

@@ -0,0 +1 @@
+#include "../esp32/max80/esplink.h"

+ 3 - 0
rv32/fw.h

@@ -77,4 +77,7 @@ extern void run_test_image(void);
 
 extern void rom_flash_from_memory(void *, size_t);
 extern void rom_flash_from_sdcard(void);
+
+extern void esp_init(void);
+
 #endif /* FW_H */

+ 1 - 21
rv32/system.c

@@ -9,18 +9,6 @@
 #define MINITESTS 1
 #define DELAY     0
 
-#define DRAM_IO_MAGIC 0x3648dec4
-struct dram_io_head {
-    uint32_t magic;
-    size_t   hlen;
-    void    *dptr;
-    size_t   dlen;
-    uint32_t board;
-};
-struct dram_io_head __dram_io_head dram_io_head;
-
-uint32_t __dram_io dram_io[(65536 - sizeof(struct dram_io_head)) >> 2];
-
 void __hot con_print_hex(unsigned int n)
 {
     for (int i = 0; i < 8; i++) {
@@ -282,15 +270,7 @@ static void __noinline late_init(void)
 
     abc_init();
 
-    /* Ready for communications */
-    dram_io_head.hlen  = sizeof dram_io_head;
-    dram_io_head.dptr  = dram_io;
-    dram_io_head.dlen  = sizeof dram_io;
-    dram_io_head.board = SYS_BOARDCFG;
-    dram_io_head.magic = DRAM_IO_MAGIC;
-
-    static const char dram_io_test[] = "Hej tomtebuggar slå i glasen!";
-    memcpy(dram_io_head.dptr, dram_io_test, sizeof dram_io_test);
+    esp_init();    /* Ready for communications */
 
     /* Release WAIT# if asserted */
     ABC_BUSCTL = 0;