123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- /*
- RemdesKVM USB-KVM
- Firmware for PCB design v5
- Author: tobychui
- Upload Settings
- CH552G
- 24Mhz (Internal)
- */
- #include <Serial.h>
- /* Build flags */
- //Enable debug print to Serial, do not use this in IP-KVM setup
- //#define ENABLE_DEBUG 1
- /* Enums */
- #define USB_MS_SIDE_KVM_HOST 0
- #define USB_MS_SIDE_REMOTE_PC 1
- /* Pins definations */
- #define LED_PROG 14
- #define ATX_PWR_LED 15
- #define ATX_HDD_LED 16
- #define ATX_RST_BTN 33
- #define ATX_PWR_BTN 34
- #define USB_MS_PWR 31 //Active high, set to HIGH to enable USB 5V power and LOW to disable
- #define USB_MS_SW 30 //LOW = remote computer, HIGH = KVM
- /* Runtime defs */
- #define USB_PWR_SW_PWR_DELAY 100 //ms
- #define USB_PWR_SW_DATA_DELAY 10 //ms
- /* Runtime variables */
- uint8_t atx_status[2] = { 0, 0 }; //PWR LED, HDD LED
- uint8_t usb_ms_side = 1; //0 = KVM Controller, 1 = Computer being controlled
- char c;
- int led_tmp;
- bool led_status = true; //Default LED PROG state is high, on every command recv it switch state
- void update_atx_led_status() {
- led_tmp = digitalRead(ATX_PWR_LED);
- atx_status[0] = led_tmp;
- led_tmp = digitalRead(ATX_HDD_LED);
- atx_status[1] = led_tmp;
- }
- void switch_usbms_to_kvm() {
- if (usb_ms_side == USB_MS_SIDE_KVM_HOST) {
- //Already on the KVM side
- return;
- }
- #if ENABLE_DEBUG == 1
- USBSerial_println("[DEBUG] Switching USB Mass Storage node to KVM host side");
- #endif
- //Disconnect the power to USB
- digitalWrite(USB_MS_PWR, LOW);
- delay(USB_PWR_SW_PWR_DELAY);
- //Switch over the device
- digitalWrite(USB_MS_PWR, HIGH);
- delay(USB_PWR_SW_DATA_DELAY);
- digitalWrite(USB_MS_SW, HIGH);
- usb_ms_side = USB_MS_SIDE_KVM_HOST;
- }
- void switch_usbms_to_remote() {
- if (usb_ms_side == USB_MS_SIDE_REMOTE_PC) {
- //Already on Remote Side
- return;
- }
- #if ENABLE_DEBUG == 1
- USBSerial_println("[DEBUG] Switching USB Mass Storage node to remote computer side");
- #endif
- //Disconnect the power to USB
- digitalWrite(USB_MS_PWR, LOW);
- delay(USB_PWR_SW_PWR_DELAY);
- //Switch over the device
- digitalWrite(USB_MS_PWR, HIGH);
- delay(USB_PWR_SW_DATA_DELAY);
- digitalWrite(USB_MS_SW, LOW);
- usb_ms_side = USB_MS_SIDE_REMOTE_PC;
- }
- void report_status() {
- //Report status of ATX and USB mass storage switch in 1 byte
- //Bit 0: PWR LED status
- //Bit 1: HDD LED status
- //Bit 2: USB Mass Storage mounted side
- //Bit 3 - 7: Reserved
- uint8_t status = 0x00;
- status |= (atx_status[0] & 0x01);
- status |= (atx_status[1] & 0x01) << 1;
- status |= (usb_ms_side & 0x01) << 2;
- #if ENABLE_DEBUG == 1
- USBSerial_print("[DEBUG] ATX State");
- USBSerial_print("PWR=");
- USBSerial_print(atx_status[0]);
- USBSerial_print(" HDD=");
- USBSerial_print(atx_status[1]);
- USBSerial_print(" USB_MS=");
- USBSerial_println(usb_ms_side);
- #endif
- USBSerial_print(status);
- }
- void execute_cmd(char c) {
- switch (c) {
- case '1':
- //Press down the power button
- digitalWrite(ATX_PWR_BTN, HIGH);
- break;
- case '2':
- //Release the power button
- digitalWrite(ATX_PWR_BTN, LOW);
- break;
- case '3':
- //Press down the reset button
- digitalWrite(ATX_RST_BTN, HIGH);
- break;
- case '4':
- //Release the reset button
- digitalWrite(ATX_RST_BTN, LOW);
- break;
- case '5':
- //Switch USB mass storage to KVM side
- switch_usbms_to_kvm();
- break;
- case '6':
- //Switch USB mass storage to remote computer
- switch_usbms_to_remote();
- break;
- case '7':
- //Return the UUID of this device
-
- default:
- //Unknown command
- break;
- }
- }
- void setup() {
- pinMode(ATX_PWR_LED, INPUT);
- pinMode(ATX_HDD_LED, INPUT);
- pinMode(ATX_RST_BTN, OUTPUT);
- pinMode(ATX_PWR_BTN, OUTPUT);
- pinMode(USB_MS_PWR, OUTPUT);
- pinMode(USB_MS_SW, OUTPUT);
- pinMode(LED_PROG, OUTPUT);
- digitalWrite(LED_PROG, HIGH);
- digitalWrite(ATX_RST_BTN, LOW);
- digitalWrite(ATX_PWR_BTN, LOW);
- digitalWrite(USB_MS_PWR, LOW);
- digitalWrite(USB_MS_SW, LOW);
- //Blink 10 times for initiations
- for (int i = 0; i < 10; i++) {
- digitalWrite(LED_PROG, HIGH);
- delay(100);
- digitalWrite(LED_PROG, LOW);
- delay(100);
- }
- digitalWrite(LED_PROG, HIGH);
- delay(1000);
- //Switch the USB thumbnail to host
- switch_usbms_to_kvm();
- }
- void loop() {
- if (USBSerial_available()) {
- c = USBSerial_read();
- #if ENABLE_DEBUG == 1
- USBSerial_print("[DEBUG] Serial Recv: ");
- USBSerial_println(c);
- #endif
- execute_cmd(c);
- led_status = !led_status;
- digitalWrite(LED_PROG, led_status ? HIGH : LOW);
- }
- //update_atx_led_status();
- //report_status();
- delay(100);
- }
|