blob: 1dc187d42a4b5e6eb644726f9b667c8bf675a6df [file] [log] [blame]
#include <Arduino.h>
#include <SPI.h>
#include "gonk/pin_config.h"
#include "stm32f7xx_hal_qspi.h"
#define PW_LOG_LEVEL PW_LOG_LEVEL_DEBUG
#define PW_LOG_MODULE_NAME "PinConfig"
#include "pw_log/log.h"
namespace gonk::pin_config {
PinConfig::PinConfig()
: fpga_spi(FpgaDspiMOSI, FpgaDspiMISO, FpgaDspiCLK, FpgaDspiCS) {
flash_spi = SPIClass(FlashMOSI, FlashMISO, FlashCLK);
}
void PinConfig::Init() {
// Set STATUS LED mode and initial state.
pinMode(StatusLed, OUTPUT);
digitalWrite(StatusLed, LOW);
// Default CS pin to output high.
pinMode(FlashCS, OUTPUT);
digitalWrite(FlashCS, HIGH);
}
void PinConfig::InitFpgaPins() {
// Set FPGA reset pin mode and initial state.
pinMode(ICE40ResetN, OUTPUT);
digitalWrite(ICE40ResetN, HIGH);
// Set FPGA configure done signal pin as an input.
pinMode(ICE40Done, INPUT);
// FPGA Application IO pins
pinMode(FpgaIoReset, OUTPUT);
digitalWrite(FpgaIoReset, LOW);
pinMode(FpgaIoMode, OUTPUT);
digitalWrite(FpgaIoMode, LOW);
pinMode(FpgaIoValid, INPUT);
InitSampleBus();
}
void PinConfig::InitSampleBus() { fpga_spi.begin(); }
void PinConfig::FpgaHalt() {
// Set FlashCS to signal the FPGA it should load the bitstream from external
// flash.
pinMode(FlashCS, INPUT_FLOATING);
delay(10);
// Hold in reset for a small amount of time.
digitalWrite(ICE40ResetN, LOW);
delay(50);
// Boot fpga and give it time to reset any internal SPI pin configuration.
digitalWrite(ICE40ResetN, HIGH);
delay(10);
// Finally, hold in reset.
digitalWrite(ICE40ResetN, LOW);
}
void PinConfig::FpgaSpiConfigMode() {
// Turn on Flash Hold so it ignores any SPI communication.
pinMode(FlashHold, OUTPUT);
pinMode(FlashWP, OUTPUT);
digitalWrite(FlashHold, LOW);
digitalWrite(FlashWP, LOW);
delay(1);
// Set FlashCS (ICE_SPI_SS) low and pulse ICE40ResetN. This signals the FPGA
// to boot into SPI config mode.
pinMode(ICE40ResetN, OUTPUT);
pinMode(FlashCS, OUTPUT);
// Pulse ICE40ResetN
digitalWrite(ICE40ResetN, LOW);
digitalWrite(FlashCS, LOW);
delay(10);
digitalWrite(ICE40ResetN, HIGH);
// Enalble GPIO control of MOSI, MISO and CLK.
pinMode(FlashMOSI, OUTPUT);
pinMode(FlashMISO, OUTPUT);
pinMode(FlashCLK, OUTPUT);
delay(1);
// Send 8 clock pulses.
for (int i = 0; i < 8; i++) {
digitalWrite(FlashCLK, LOW);
delayMicroseconds(100);
digitalWrite(FlashCLK, HIGH);
delayMicroseconds(100);
}
delay(10);
}
void PinConfig::FpgaEnable() { digitalWrite(ICE40ResetN, HIGH); }
void PinConfig::SPIEnable() {
// Disable Flash hold and write protect.
pinMode(FlashHold, OUTPUT);
pinMode(FlashWP, OUTPUT);
digitalWrite(FlashHold, HIGH);
digitalWrite(FlashWP, HIGH);
}
void PinConfig::SPIDisable() {
pinMode(FlashCS, OUTPUT);
pinMode(FlashCLK, OUTPUT);
pinMode(FlashMOSI, OUTPUT);
pinMode(FlashMISO, INPUT_FLOATING);
digitalWrite(FlashCS, HIGH);
digitalWrite(FlashCLK, HIGH);
digitalWrite(FlashMOSI, HIGH);
}
} // namespace gonk::pin_config