Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions Firmware/LogicAnalyzer_V2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)

# == DO NOT EDIT THE FOLLOWING LINES for the Raspberry Pi Pico VS Code Extension to work ==
if(WIN32)
set(USERHOME $ENV{USERPROFILE})
else()
set(USERHOME $ENV{HOME})
endif()
set(sdkVersion 2.1.1)
set(toolchainVersion 14_2_Rel1)
set(picotoolVersion 2.1.1)
set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake)
if (EXISTS ${picoVscode})
include(${picoVscode})
endif()
# == DO NOT EDIT THE FOLLOWING LINES for the Raspberry Pi Pico VS Code Extension to work ==
if(WIN32)
set(USERHOME $ENV{USERPROFILE})
else()
set(USERHOME $ENV{HOME})
endif()
set(sdkVersion 2.2.0)
set(toolchainVersion 14_2_Rel1)
set(picotoolVersion 2.1.1)
set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake)
if (EXISTS ${picoVscode})
include(${picoVscode})
endif()
# ====================================================================================

include(LogicAnalyzer_Build_Settings.cmake)
Expand Down Expand Up @@ -91,6 +91,7 @@ endif()
# Create C header file with the name <pio program>.pio.h
pico_generate_pio_header(${PROJECT_NAME}
${CMAKE_CURRENT_LIST_DIR}/LogicAnalyzer.pio
${CMAKE_CURRENT_LIST_DIR}/fpga_clock.pio
)

pico_set_program_name(LogicAnalyzer "LogicAnalyzer")
Expand Down Expand Up @@ -141,6 +142,10 @@ if(BOARD_TYPE STREQUAL "BOARD_INTERCEPTOR")
message(STATUS "Configuring for Interceptor")
add_compile_definitions(BUILD_INTERCEPTOR)
endif()
if(BOARD_TYPE STREQUAL "BOARD_PICO_ICE")
message(STATUS "Configuring for Pico-ICE")
add_compile_definitions(BUILD_PICO_ICE)
endif()

# Add any user requested librariesUna pregu
target_link_libraries(LogicAnalyzer
Expand Down
9 changes: 9 additions & 0 deletions Firmware/LogicAnalyzer_V2/LogicAnalyzer.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include "LogicAnalyzer_Board_Settings.h"

#ifdef BUILD_PICO_ICE
#include "LogicAnalyzer_FPGA.h"
#endif

#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
Expand Down Expand Up @@ -614,6 +618,11 @@ int main()
//Initialize USB stdio
stdio_init_all();

#ifdef BUILD_PICO_ICE
// Initialize FPGA (release reset, wait for CDONE) and start 10 MHz clock on GPIO24
fpga_init();
#endif

#if defined (BUILD_PICO_W) || defined (BUILD_PICO_2_W)
cyw43_arch_init();
#elif defined (BUILD_PICO_W_WIFI) || defined (BUILD_PICO_2_W_WIFI)
Expand Down
33 changes: 33 additions & 0 deletions Firmware/LogicAnalyzer_V2/LogicAnalyzer_Board_Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,39 @@
#define CAPTURE_BUFFER_SIZE (128 * 1024)
#define MAX_CHANNELS 28

#elif defined (BUILD_PICO_ICE)

#define BOARD_NAME "PICO_ICE"
#define SUPPORTS_COMPLEX_TRIGGER
#define INPUT_PIN_BASE 0
#define COMPLEX_TRIGGER_OUT_PIN 0
#define COMPLEX_TRIGGER_IN_PIN 1
#define GPIO_LED
#define LED_IO 12 // Use green LED to avoid conflict with capture pins
#define PIN_MAP {0,1,2,3,4,5,6,7,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,COMPLEX_TRIGGER_IN_PIN}

// FPGA control pins for pico-ice
#define PIN_FPGA_CRESETN 27 // CRESET_B (active-low)
#define PIN_FPGA_CDONE 26 // CDONE
#define PIN_CLOCK 24 // Clock to FPGA (10MHz)

// FPGA SPI configuration pins (set as high-Z during config)
#define PIN_ICE_SI 8 // SPI MOSI to FPGA flash
#define PIN_ICE_SO 11 // SPI MISO from FPGA flash
#define PIN_ICE_SCK 10 // SPI clock to FPGA flash
#define PIN_ICE_SSN 9 // SPI CS to FPGA flash (active-low)
#define PIN_RAM_SS 14 // PSRAM chip select

#ifdef TURBO_MODE
#define MAX_FREQ 200000000
#define MAX_BLAST_FREQ 400000000
#else
#define MAX_FREQ 100000000
#define MAX_BLAST_FREQ 200000000
#endif
#define CAPTURE_BUFFER_SIZE (128 * 1024)
#define MAX_CHANNELS 24

#endif

#endif
6 changes: 3 additions & 3 deletions Firmware/LogicAnalyzer_V2/LogicAnalyzer_Build_Settings.cmake
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# This file controls the build settings, set your board version
# Current versions: "BOARD_PICO", "BOARD_PICO_W", "BOARD_PICO_W_WIFI", "BOARD_ZERO", "BOARD_PICO_2"
set(BOARD_TYPE "BOARD_PICO")
# Current versions: "BOARD_PICO", "BOARD_PICO_W", "BOARD_PICO_W_WIFI", "BOARD_ZERO", "BOARD_PICO_2", "BOARD_PICO_ICE"
set(BOARD_TYPE "BOARD_PICO_ICE")

# Set to 1 to enable 200Mhz mode (warning! extreme overclock and overvoltage!)
# Set to 0 to disable turbo mode
# Not available for the Pico W
set(TURBO_MODE 1)
set(TURBO_MODE 0)

# Uncomment to be able to debug the build
# set(DEBUG_BUILD 1)
124 changes: 109 additions & 15 deletions Firmware/LogicAnalyzer_V2/LogicAnalyzer_Capture.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,23 @@ void disable_gpios()
gpio_deinit(COMPLEX_TRIGGER_IN_PIN);
#endif

// Universal pin state preservation: Don't change ANY pin states after capture
// This preserves all pin configurations (inputs, outputs, high-Z) for user applications
// Logic Analyzer only needs to READ pins during capture, not control them after
// Comment out this entire section if you need the old behavior that changed pins to high-Z
/*
for(uint8_t i = 0; i < lastCapturePinCount; i++)
gpio_deinit(lastCapturePins[i]);

{
gpio_deinit(lastCapturePins[i]); // Old behavior - disrupted user applications
}
*/

gpio_set_inover(lastTriggerPin, 0);
// Universal trigger pin preservation: Only reset inover for input trigger pins
// This preserves output trigger pins in their output state for user applications
if (!gpio_is_dir_out(lastTriggerPin))
{
gpio_set_inover(lastTriggerPin, 0);
}
}


Expand Down Expand Up @@ -640,7 +652,15 @@ bool StartCaptureFast(uint32_t freq, uint32_t preLength, uint32_t postLength, co
pio_gpio_init(capturePIO, COMPLEX_TRIGGER_IN_PIN);

for(uint8_t i = 0; i < MAX_CHANNELS; i++)
pio_gpio_init(capturePIO, pinMap[i]);
{
// Universal output protection: Don't take PIO ownership of pins already configured as outputs
// This allows monitoring of output signals while preserving their output state
// Comment out the gpio_is_dir_out() check if you need PIO to control output pins
if (!gpio_is_dir_out(pinMap[i]))
{
pio_gpio_init(capturePIO, pinMap[i]);
}
}

//Configure capture SM
sm_Capture = pio_claim_unused_sm(capturePIO, true);
Expand All @@ -650,7 +670,15 @@ bool StartCaptureFast(uint32_t freq, uint32_t preLength, uint32_t postLength, co

//Modified for the W
for(int i = 0; i < MAX_CHANNELS; i++)
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, pinMap[i], 1, false);
{
// Universal output protection: Only change pin direction for pins not already configured as outputs
// This preserves output pins (like FPGA clocks, LEDs, etc.) while still allowing monitoring
// Comment out this loop and use pio_sm_set_consecutive_pindirs() directly to revert
if (!gpio_is_dir_out(pinMap[i]))
{
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, pinMap[i], 1, false);
}
}

//Configure state machines
pio_sm_config smConfig = FAST_CAPTURE_program_get_default_config(captureOffset);
Expand Down Expand Up @@ -807,7 +835,15 @@ bool StartCaptureComplex(uint32_t freq, uint32_t preLength, uint32_t postLength,
pio_gpio_init(capturePIO, COMPLEX_TRIGGER_IN_PIN);

for(uint8_t i = 0; i < MAX_CHANNELS; i++)
pio_gpio_init(capturePIO, pinMap[i]);
{
// Universal output protection: Don't take PIO ownership of pins already configured as outputs
// This allows monitoring of output signals while preserving their output state
// Comment out the gpio_is_dir_out() check if you need PIO to control output pins
if (!gpio_is_dir_out(pinMap[i]))
{
pio_gpio_init(capturePIO, pinMap[i]);
}
}

//Configure capture SM
sm_Capture = pio_claim_unused_sm(capturePIO, true);
Expand All @@ -816,7 +852,15 @@ bool StartCaptureComplex(uint32_t freq, uint32_t preLength, uint32_t postLength,
captureOffset = pio_add_program(capturePIO, &COMPLEX_CAPTURE_program);

for(int i = 0; i < MAX_CHANNELS; i++)
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, pinMap[i], 1, false);
{
// Universal output protection: Only change pin direction for pins not already configured as outputs
// This preserves output pins (like FPGA clocks, LEDs, etc.) while still allowing monitoring
// Comment out this loop and use pio_sm_set_consecutive_pindirs() directly to revert
if (!gpio_is_dir_out(pinMap[i]))
{
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, pinMap[i], 1, false);
}
}

//Configure state machines
pio_sm_config smConfig = COMPLEX_CAPTURE_program_get_default_config(captureOffset);
Expand Down Expand Up @@ -978,14 +1022,39 @@ bool StartCaptureBlast(uint32_t freq, uint32_t length, const uint8_t* capturePin

//Configure capture pins
for(int i = 0; i < MAX_CHANNELS; i++)
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, pinMap[i], 1, false);
{
// Universal output protection: Only change pin direction for pins not already configured as outputs
// This preserves output pins (like FPGA clocks, LEDs, etc.) while still allowing monitoring
// Comment out this loop and use pio_sm_set_consecutive_pindirs() directly to revert
if (!gpio_is_dir_out(pinMap[i]))
{
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, pinMap[i], 1, false);
}
}

for(uint8_t i = 0; i < MAX_CHANNELS; i++)
pio_gpio_init(capturePIO, pinMap[i]);
{
// Universal output protection: Don't take PIO ownership of pins already configured as outputs
// This allows monitoring of output signals while preserving their output state
// Comment out the gpio_is_dir_out() check if you need PIO to control output pins
if (!gpio_is_dir_out(pinMap[i]))
{
pio_gpio_init(capturePIO, pinMap[i]);
}
}

//Configure trigger pin
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, triggerPin, 1, false);
pio_gpio_init(capturePIO, triggerPin);
// Universal output protection: Only change pin direction for pins not already configured as outputs
if (!gpio_is_dir_out(triggerPin))
{
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, triggerPin, 1, false);
}
// Universal output protection: Don't take PIO ownership of pins already configured as outputs
// This preserves output signals while still allowing them to be monitored for triggers
if (!gpio_is_dir_out(triggerPin))
{
pio_gpio_init(capturePIO, triggerPin);
}

if(!invertTrigger)
gpio_set_inover(triggerPin, 1);
Expand Down Expand Up @@ -1115,14 +1184,39 @@ bool StartCaptureSimple(uint32_t freq, uint32_t preLength, uint32_t postLength,

//Configure capture pins
for(int i = 0; i < MAX_CHANNELS; i++)
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, pinMap[i], 1, false);
{
// Universal output protection: Only change pin direction for pins not already configured as outputs
// This preserves output pins (like FPGA clocks, LEDs, etc.) while still allowing monitoring
// Comment out this loop and use pio_sm_set_consecutive_pindirs() directly to revert
if (!gpio_is_dir_out(pinMap[i]))
{
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, pinMap[i], 1, false);
}
}

for(uint8_t i = 0; i < MAX_CHANNELS; i++)
pio_gpio_init(capturePIO, pinMap[i]);
{
// Universal output protection: Don't take PIO ownership of pins already configured as outputs
// This allows monitoring of output signals while preserving their output state
// Comment out the gpio_is_dir_out() check if you need PIO to control output pins
if (!gpio_is_dir_out(pinMap[i]))
{
pio_gpio_init(capturePIO, pinMap[i]);
}
}

//Configure trigger pin
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, triggerPin, 1, false);
pio_gpio_init(capturePIO, triggerPin);
// Universal output protection: Only change pin direction for pins not already configured as outputs
if (!gpio_is_dir_out(triggerPin))
{
pio_sm_set_consecutive_pindirs(capturePIO, sm_Capture, triggerPin, 1, false);
}
// Universal output protection: Don't take PIO ownership of pins already configured as outputs
// This preserves output signals while still allowing them to be monitored for triggers
if (!gpio_is_dir_out(triggerPin))
{
pio_gpio_init(capturePIO, triggerPin);
}

//Configure state machines
pio_sm_config smConfig = measureBursts?
Expand Down
Loading