| #include <Arduino.h> |
| #include <SPI.h> |
| |
| #include "gonk/pin_config.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() { 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); |
| } |
| |
| 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 |