Firmware MiST - Maverick-Shark/retroGuru GitHub Wiki

Función SPI()

  • Serial Peripheral Interface - Protocolo de comunicación entre ARM y FPGA
unsigned char SPI(unsigned char data_out);

Comportamiento:

SPI(0x42);
   → 1. Envía 0x42 a la FPGA por MOSI  
   → 2. Simultaneamente, recibe un byte de la FPGA por MISO  
   → 3. Devuelve el byte recibido  

Señales:

  MOSI (Master Out Slave In) - ARM → FPGA  
  MISO (Master In Slave Out) - FPGA → ARM  
  SCK  (Serial Clock)        - Reloj  
  SS   (Slave Select)        - Chip enable  

Enviar comando

EnableFpga();              // Activa SS (chip select)
SPI(DIO_FILE_TX);          // Envia instrucción: "transmitir archivo"
SPI(0xff);                 // Envia el parámetro 0xff
DisableFpga();             // Desactiva SS (chip select)

Enviar datos

EnableFpga();
SPI(DIO_FILE_TX_DAT);      // Comando: "se van a enviar datos"

for (int i = 0; i < 512; i++) {
    SPI(buffer[i]);         // Envía cada byte del buffer
}

DisableFpga();

Recibir datos

EnableFpga();
SPI(DIO_FILE_RX_DAT);      // Comando: "recibir datos"

for (int i = 0; i < 512; i++) {
    buffer[i] = SPI(0xFF);  // Envía 0xFF (dummy) y recibe el dato real que lo carga en buffur
}

DisableFpga();

🎯 FLUJO: ARM → FPGA (Carga de TAP)

1. ARM ejecuta: data_io_file_tx_prepare()
   ├─> SPI(DIO_FILE_INFO) + datos → FPGA guarda info
   ├─ EnableFpga()
   ├─ SPI(DIO_FILE_INFO)          → ARM: "te voy a dar la info del archivo"
   ├─ SPI(datos...)               → FPGA: Recibe los datos con el nombre, tamaño, etc.
   └─ DisableFpga()

2. ARM ejecuta: data_io_file_tx_start()
   ├SPI(DIO_FILE_TX) + 0xFF → FPGA inicia recepción
   ├─ EnableFpga()
   ├─ SPI(DIO_FILE_TX)      → ARM: "empiezo transmisión"
   ├─ SPI(0xFF)             → FPGA: Recibe la señal de inicialización
   └─ DisableFpga()

3. ARM ejecuta: data_io_file_tx_send()
   ├─> SPI(DIO_FILE_TX_DAT) + datos → FPGA guarda en SDRAM
   └─ Para cada chunk:
      ├─ f_read(file, buffer, 512)  → Lee 512 bytes de SD
      ├─ EnableFpga()
      ├─ SPI(DIO_FILE_TX_DAT)       → ARM: "aquí vienen datos"
      ├─ for (i=0; i<512; i++)
      │  └─ SPI(buffer[i])          → FPGA: Recibe cada byte transmitido
      └─ DisableFpga()

4. ARM ejecuta: data_io_file_tx_done()
   ├─> SPI(DIO_FILE_TX) + 0x00 → FPGA termina
   ├─ EnableFpga()
   ├─ SPI(DIO_FILE_TX)         → ARM: "terminé"
   ├─ SPI(0x00)                → FPGA: Recibe la señal de fin de transmisión
   └─ DisableFpga()

En el lado de la FPGA (c1530.vhd)

case spi_cmd is
    when DIO_FILE_INFO =>
        file_size <= spi_data;        -- Guarda info del archivo en memoria
    when DIO_FILE_TX =>
        if spi_data = 0xFF then
            state <= RECEIVING;       -- Inicia recepción
        else
            state <= IDLE;            -- Finaliza
        end if;
    when DIO_FILE_TX_DAT =>
        SDRAM[addr] <= spi_data;      -- Guarda datos en SDRAM
        addr <= addr + 1;
end case;

Comandos SPI

#define DIO_FILE_TX       0x53  // Iniciar TX
#define DIO_FILE_TX_DAT   0x54  // Datos TX
#define DIO_FILE_RX       0x55  // Iniciar RX
#define DIO_FILE_RX_DAT   0x56  // Datos RX
#define DIO_FILE_INDEX    0x57  // Índice
#define DIO_FILE_INFO     0x58  // Info archivo