Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PS2 Continuously Emits the First Character and Cannot Be Stopped #69

Open
zoushiyin opened this issue Dec 19, 2024 · 0 comments
Open

PS2 Continuously Emits the First Character and Cannot Be Stopped #69

zoushiyin opened this issue Dec 19, 2024 · 0 comments

Comments

@zoushiyin
Copy link

I am trying to send characters through a serial connection to my Raspberry Pi Pico, and then have it control PS/2 output to emit corresponding characters. However, I'm encountering an issue where the PS/2 interface continuously emits the first character and cannot be stopped unless I disconnect the PS/2 device. Below is my program:
_#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "hardware/watchdog.h"
#include "hardware/gpio.h"
#include "hardware/uart.h"
#include "hardware/irq.h"
#include "bsp/board_api.h"
#include "tusb.h"
#include "ps2x2pico.h"
#include "ps2kb.h"

// UART configuration
#define UART_ID uart1
#define BAUD_RATE 115200
#define UART_TX_PIN 8
#define UART_RX_PIN 9

// Receive buffer
#define UART_BUFFER_SIZE 128
volatile char uart_rx_buffer[UART_BUFFER_SIZE];
volatile int uart_rx_index = 0;
volatile bool uart_data_ready = false;

// ASCII to HID_KEY mapping table
typedef struct {
uint8_t hid_key; // HID key value
bool shift_required; // Whether Shift key is required
} HidKeyMap;

HidKeyMap convert_ascii_to_hid_key(char ascii) {
switch (ascii) {
// Lowercase letters (no Shift needed)
case 'a': return (HidKeyMap){HID_KEY_A, false};
case 'b': return (HidKeyMap){HID_KEY_B, false};
case 'c': return (HidKeyMap){HID_KEY_C, false};
// ... specify the same logic for other lowercase letters ...
case 'z': return (HidKeyMap){HID_KEY_Z, false};

    // Uppercase letters (Shift needed)
    case 'A': return (HidKeyMap){HID_KEY_A, true};
    case 'B': return (HidKeyMap){HID_KEY_B, true};
    case 'C': return (HidKeyMap){HID_KEY_C, true};

    case '\n': return (HidKeyMap){HID_KEY_ENTER, false};

    // Unknown character
    default: return (HidKeyMap){0, false};
}

}
static int chars_rxed = 0;

// UART RX interrupt handler
void on_uart_rx() {
while (uart_is_readable(UART_ID)) {
char c = uart_getc(UART_ID);
if (uart_rx_index < UART_BUFFER_SIZE - 1) {
uart_rx_buffer[uart_rx_index++] = c;
uart_putc(UART_ID, c);
uart_data_ready = true; // Mark data as ready
}
}
uart_rx_buffer[uart_rx_index] = '\0'; // Ensure buffer ends with '\0'
}

// Initialize UART
void init_uart() {
uart_init(UART_ID, BAUD_RATE);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);

// Configure UART data format
uart_set_format(UART_ID, 8, 1, UART_PARITY_NONE);

// Disable hardware flow control
uart_set_hw_flow(UART_ID, false, false);

// Disable FIFO
uart_set_fifo_enabled(UART_ID, false);

// Enable interrupts
int UART_IRQ = UART_ID == uart0 ? UART0_IRQ : UART1_IRQ;
irq_set_exclusive_handler(UART_IRQ, on_uart_rx);
irq_set_enabled(UART_IRQ, true);
uart_set_irq_enables(UART_ID, true, false);

// Send test message
uart_puts(UART_ID, "\nHello, UART1 interrupts\n");

}

// Process UART input data
void process_uart_input() {
if (uart_data_ready) {
uart_data_ready = false; // Reset flag

    char received_data[UART_BUFFER_SIZE];
    memcpy((void *)received_data, (void *)uart_rx_buffer, uart_rx_index);
    received_data[uart_rx_index] = '\0';
    uart_rx_index = 0; // Clear buffer

    // Convert data byte by byte to HID_KEY and send
    for (int i = 0; received_data[i] != '\0'; i++) {
        HidKeyMap key_map = convert_ascii_to_hid_key(received_data[i]);
        if (key_map.hid_key != 0) {
            // Output for debugging
            // Press Shift key if required
            if (key_map.shift_required) {
                kb_send_key(HID_KEY_SHIFT_LEFT, true, 0);
            }

            // Press target key
            kb_send_key(key_map.hid_key, true, 0);
            sleep_ms(2); // Add 2ms delay
            kb_send_key(key_map.hid_key, false, 0);

            // Release Shift key
            if (key_map.shift_required) {
                kb_send_key(HID_KEY_SHIFT_LEFT, false, 0);
            }
        }
    }
}

}

int main() {
board_init();

gpio_init(LVOUT);
gpio_init(LVIN);
gpio_set_dir(LVOUT, GPIO_OUT);
gpio_set_dir(LVIN, GPIO_OUT);
gpio_put(LVOUT, 1);
gpio_put(LVIN, 1);

tuh_hid_set_default_protocol(HID_PROTOCOL_REPORT);
tusb_init();
kb_init(KBOUT, KBIN);
ms_init(MSOUT, MSIN);

// Initialize UART
init_uart();

// Main loop
while (1) {
    tuh_task();
    kb_task();
    ms_task();

    // Process UART data
    process_uart_input();
}

}

void reset() {
printf("\n\n *** PANIC via tinyusb: watchdog reset!\n\n");
watchdog_enable(100, false);
}_

Could you please help me identify what might be causing this issue and suggest any potential fixes?

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant