a vim plugin that displays stuff on an led matrix
at main 3.7 kB view raw
1#include <stdlib.h> 2 3#include <cstring> 4#include <stdio.h> 5 6#include "pico/multicore.h" 7#include "pico/stdlib.h" 8#include <time.h> 9 10// Define GPIO pins for rows and columns 11#define ROWS 4 12#define COLS 6 13 14const uint ROW_PINS[4] = {12, 13, 14, 15}; 15const uint COL_PINS[6] = {17, 18, 19, 20, 21, 22}; 16 17// LED state matrix 18uint8_t led_states[ROWS][COLS] = {0}; 19 20// brightness control 21uint8_t brightness = 100; 22 23// timing vars 24bool fading = false; 25absolute_time_t last_char_time; 26absolute_time_t fade_start_time; 27const uint32_t inactivity_timeout_ms = 0; 28const uint32_t fade_duration_ms = 1200; 29 30void randomize_matrix() { 31 for (int row = 0; row < ROWS; row++) { 32 for (int col = 0; col < COLS; col++) { 33 led_states[row][col] = rand() % 2; 34 } 35 } 36} 37 38// Function to update the display at variable frequencies 39void update_led_display(uint32_t refresh_rate_hz) { 40 static uint32_t last_update = 0; 41 uint32_t current_time = to_ms_since_boot(get_absolute_time()); 42 uint32_t update_interval = 1000 / refresh_rate_hz; 43 44 // Only update at the specified frequency 45 if (current_time - last_update < update_interval) { 46 return; 47 } 48 49 last_update = current_time; 50 51 uint32_t time_since_last_char = absolute_time_diff_us(last_char_time, get_absolute_time()) / 1000; 52 53 if (!fading && time_since_last_char > inactivity_timeout_ms) { 54 // start fading 55 fading = true; 56 fade_start_time = get_absolute_time(); 57 } 58 59 if (fading) { 60 uint32_t fade_elapsed_ms = absolute_time_diff_us(fade_start_time, get_absolute_time()) / 1000; 61 62 if (fade_elapsed_ms >= fade_duration_ms) { 63 brightness = 0; 64 } else { 65 brightness = 100 - ((fade_elapsed_ms * 100) / fade_duration_ms); 66 } 67 } 68 69 // Skip display update if brightness is 0 70 if (brightness == 0) { 71 // Turn off all rows and set all columns high to ensure LEDs are off 72 for (int i = 0; i < ROWS; i++) { 73 gpio_put(ROW_PINS[i], 0); 74 } 75 for (int j = 0; j < COLS; j++) { 76 gpio_put(COL_PINS[j], 1); 77 } 78 79 return; 80 } 81 82 // Software PWM cycle 83 for (uint8_t pwm_cycle = 0; pwm_cycle < brightness; pwm_cycle++) { 84 // For each row 85 for (int row = 0; row < ROWS; row++) { 86 // Activate row 87 gpio_put(ROW_PINS[row], 1); 88 89 // Set column states for this row 90 for (int col = 0; col < COLS; col++) { 91 gpio_put(COL_PINS[col], led_states[row][col] ? 0 : 1); 92 } 93 94 // Keep row active for a short time 95 sleep_us(50); 96 97 // Deactivate row 98 gpio_put(ROW_PINS[row], 0); 99 } 100 } 101} 102void setup_pins() { 103 // Set up row pins 104 for (int i = 0; i < ROWS; i++) { 105 gpio_init(ROW_PINS[i]); 106 gpio_set_dir(ROW_PINS[i], GPIO_OUT); 107 gpio_put(ROW_PINS[i], 0); // Start with LEDs off 108 } 109 110 // Set up column pins 111 for (int j = 0; j < COLS; j++) { 112 gpio_init(COL_PINS[j]); 113 gpio_set_dir(COL_PINS[j], GPIO_OUT); 114 gpio_put(COL_PINS[j], 1); // Start with LEDs off 115 } 116} 117 118void core1_main() { 119 while (true) { 120 update_led_display(1000); // Update at 60Hz for smoother display 121 sleep_ms(1); // Small delay to prevent tight loop 122 } 123} 124 125int main() { 126 stdio_init_all(); 127 setup_pins(); 128 129 // seed the random number generator 130 srand(time_us_32()); 131 132 last_char_time = get_absolute_time(); 133 134 multicore_launch_core1(core1_main); 135 136 while (true) { 137 // check if there are characters available from the input 138 int c = getchar_timeout_us(0); 139 140 if (c != PICO_ERROR_TIMEOUT) { 141 // echo char back 142 printf("%c", c); 143 144 last_char_time = get_absolute_time(); 145 146 fading = false; 147 brightness = 100; 148 149 randomize_matrix(); 150 151 while (getchar_timeout_us(0) != PICO_ERROR_TIMEOUT) {} 152 } 153 154 sleep_ms(10); 155 } 156}