| #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 { |
| |
| volatile uint8_t gpio1_assert_ = 0; |
| volatile uint8_t gpio2_assert_ = 0; |
| volatile uint8_t gpio3_assert_ = 0; |
| volatile uint8_t gpio6_assert_ = 0; |
| |
| void Gpio1Interrupt() { |
| gpio1_assert_ = 1; |
| PW_LOG_INFO("Header pin assert: 1"); |
| } |
| void Gpio2Interrupt() { |
| gpio2_assert_ = 1; |
| PW_LOG_INFO("Header pin assert: 2"); |
| } |
| void Gpio3Interrupt() { |
| gpio3_assert_ = 1; |
| PW_LOG_INFO("Header pin assert: 3"); |
| } |
| void Gpio6Interrupt() { |
| gpio6_assert_ = 1; |
| PW_LOG_INFO("Header pin assert: 6"); |
| } |
| |
| } // namespace |
| |
| 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); |
| |
| // Top header GPIO inputs. |
| pinMode(HeaderPin1, INPUT_PULLUP); |
| pinMode(HeaderPin2, INPUT_PULLUP); |
| pinMode(HeaderPin3, INPUT_PULLUP); |
| pinMode(HeaderPin6, INPUT_PULLUP); |
| attachInterrupt(/*pin=*/HeaderPin1, |
| /*callback=*/&Gpio1Interrupt, |
| /*mode=*/LOW); |
| attachInterrupt(/*pin=*/HeaderPin2, |
| /*callback=*/&Gpio2Interrupt, |
| /*mode=*/LOW); |
| attachInterrupt(/*pin=*/HeaderPin3, |
| /*callback=*/&Gpio3Interrupt, |
| /*mode=*/LOW); |
| attachInterrupt(/*pin=*/HeaderPin6, |
| /*callback=*/&Gpio6Interrupt, |
| /*mode=*/LOW); |
| } |
| |
| 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); |
| } |
| |
| void PinConfig::ClearGpioInterrupts() { |
| gpio1_assert_ = 0; |
| gpio2_assert_ = 0; |
| gpio3_assert_ = 0; |
| gpio6_assert_ = 0; |
| } |
| |
| } // namespace gonk::pin_config |