diff --git a/CMakeLists.txt b/CMakeLists.txt index 26e4e0f..c27b327 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ pico_generate_pio_header(clock ${CMAKE_CURRENT_LIST_DIR}/quadrature_encoder.pio) # Pull in standard library and hardware abstraction target_link_libraries(clock pico_stdlib + hardware_adc hardware_pwm hardware_gpio hardware_pio diff --git a/include/globals.h b/include/globals.h index b11ecd3..dd9fe71 100644 --- a/include/globals.h +++ b/include/globals.h @@ -21,6 +21,12 @@ static constexpr uint8_t OUT_8_PIN = 14; static constexpr uint8_t IN_CLK_PIN = 16; static constexpr uint8_t IN_RUN_PIN = 17; +static constexpr uint8_t IN_CV_1_ADC_PIN = 0; +static constexpr uint8_t IN_CV_2_ADC_PIN = 1; + +extern volatile float cv_values[2]; +extern const float conversion_factor; + static constexpr uint8_t SCREEN_SCL_PIN = 18; static constexpr uint8_t SCREEN_SDA_PIN = 19; diff --git a/src/DisplayHandler.cpp b/src/DisplayHandler.cpp index be1bdf4..2cd0cf9 100644 --- a/src/DisplayHandler.cpp +++ b/src/DisplayHandler.cpp @@ -134,12 +134,12 @@ void DisplayHandler::handleCursorOnOutputScreen(bool dir) { } } - if (matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx > 7) { + if (matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx > 9) { matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx = 0; } if (matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx < 0) { - matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx = 7; + matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx = 9; } } else if (currentScreen == 10) { // CV1 DEST @@ -490,8 +490,13 @@ void DisplayHandler::renderOutPage() { matrix.slots[outputs[currentOut]->slotIdx1].active ? "ON" : "OFF"; } else if (currentScreen == 9) { // CV1 Source Chan Screen - param_string = std::to_string( - matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx + 1); + uint8_t sourceIdx = matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx + 1; + + if (sourceIdx <= 7) { + param_string = std::to_string(sourceIdx); + } else { + param_string = "Ext" + std::to_string(sourceIdx - 7); + } } else if (currentScreen == 10) { // CV1 DEST Screen param_string = modDestToString( @@ -512,8 +517,13 @@ void DisplayHandler::renderOutPage() { matrix.slots[outputs[currentOut]->slotIdx2].active ? "ON" : "OFF"; } else if (currentScreen == 14) { // CV2 Source Chan Screen - param_string = std::to_string( - matrix.slots[outputs[currentOut]->slotIdx2].sourceIdx + 1); + uint8_t sourceIdx = matrix.slots[outputs[currentOut]->slotIdx1].sourceIdx + 1; + + if (sourceIdx <= 7) { + param_string = std::to_string(sourceIdx); + } else { + param_string = "Ext" + std::to_string(sourceIdx - 7); + } } else if (currentScreen == 15) { // CV2 DEST Screen param_string = modDestToString( diff --git a/src/Gate.cpp b/src/Gate.cpp index 2a1bdcf..9088c7f 100644 --- a/src/Gate.cpp +++ b/src/Gate.cpp @@ -381,7 +381,8 @@ void Gate::update() { if (finalLevel > 1.0f) finalLevel = 1.0f; if (finalLevel < 0.0f) finalLevel = 0.0f; - writeAnalog((uint16_t)(outVal * 1023.0f * finalLevel));} + writeAnalog((uint16_t)(outVal * 1023.0f * finalLevel)); +} void Gate::writeAnalog(uint16_t val) { pwm_set_gpio_level(pin, val); } diff --git a/src/Mod.cpp b/src/Mod.cpp index 277bbde..ddeddd6 100644 --- a/src/Mod.cpp +++ b/src/Mod.cpp @@ -23,7 +23,15 @@ void ModMatrix::process(Gate **gates, uint8_t gateCount) { if (slots[i].active == 0) continue; - float srcVal = gates[slots[i].sourceIdx]->lastOutVal; + float srcVal = 0.0f; + + if (slots[i].sourceIdx < 8) { + srcVal = gates[slots[i].sourceIdx]->lastOutVal; + } else if (slots[i].sourceIdx == 8) { + srcVal = cv_values[0]; + } else if (slots[i].sourceIdx == 9) { + srcVal = cv_values[1]; + } float amt = (float)slots[i].amount; float normalizedAmt = amt / 100.0f; diff --git a/src/main.cpp b/src/main.cpp index 4b3dc06..e24429c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "DisplayHandler.h" #include "EncoderHandler.h" @@ -17,6 +18,7 @@ #include "Mod.h" #include "Settings.h" #include "globals.h" +#include "hardware/adc.h" #include "hardware/pwm.h" // Time based operations @@ -47,6 +49,9 @@ Gate out8(OUT_8_PIN, 7, 14, 15); static Gate *outputs[] = {&out1, &out2, &out3, &out4, &out5, &out6, &out7, &out8}; +volatile float cv_values[2] = {0.0f, 0.0f}; +const float conversion_factor = 1.0f / (1 << 12); + // Initialize Handlers static DisplayHandler display_handler(outputs); static EncoderHandler encoder_handler(&display_handler); @@ -208,6 +213,60 @@ void setup_ins() { gpio_set_irq_enabled(IN_CLK_PIN, GPIO_IRQ_EDGE_RISE, true); // SETUP CV INS + adc_init(); + adc_gpio_init(26); + adc_gpio_init(27); +} + +// Helper to scale your current range to 0.0 - 1.0 +float fmap(float x, float in_min, float in_max) { + float result = (x - in_min) / (in_max - in_min); + // Constraints to keep it between 0.0 and 1.0 + if (result < 0.0f) + return 0.0f; + if (result > 1.0f) + return 1.0f; + return result; +} + +void update_cv() { + static uint64_t last_adc_read = 0; + uint64_t now = to_us_since_boot(get_absolute_time()); + if (now - last_adc_read < 2000) + return; // 2ms is plenty fast + last_adc_read = now; + + // Calibration (Adjust these based on your earlier -0.19 to 0.15 range) + const float raw_min = -0.19f; + const float raw_max = 0.15f; + const float offset_zero = 0.404f; // Your calibrated offset + + for (int i = 0; i < 2; i++) { + adc_select_input(i); + + // CROSSTALK FIX: Dummy read to clear the ADC capacitor + adc_read(); + busy_wait_us(10); // Tiny pause to settle + + // Actual read + float raw_val = (float)adc_read() * (1.0f / 4095.0f); + float centered = offset_zero - raw_val; + + // SCALING & FLIPPING: + // By using (max - centered), we flip the inversion. + float scaled = (centered - raw_min) / (raw_max - raw_min); + + // Optional: If it's STILL upside down, use this instead: + // float scaled = 1.0f - ((centered - raw_min) / (raw_max - raw_min)); + + // Constrain 0.0 to 1.0 + if (scaled < 0.01f) + scaled = 0.0f; + if (scaled > 1.0f) + scaled = 1.0f; + + cv_values[i] = scaled; + } } int main() { @@ -251,6 +310,7 @@ int main() { } while (true) { + update_cv(); encoder_handler.update(); if (PLAY) {