usbkvm_fw5.ino 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. RemdesKVM USB-KVM
  3. Firmware for PCB design v5
  4. Author: tobychui
  5. Upload Settings
  6. CH552G
  7. 24Mhz (Internal)
  8. */
  9. #include <Serial.h>
  10. /* Build flags */
  11. //Enable debug print to Serial, do not use this in IP-KVM setup
  12. //#define ENABLE_DEBUG 1
  13. /* Enums */
  14. #define USB_MS_SIDE_KVM_HOST 0
  15. #define USB_MS_SIDE_REMOTE_PC 1
  16. /* Pins definations */
  17. #define LED_PROG 14
  18. #define ATX_PWR_LED 15
  19. #define ATX_HDD_LED 16
  20. #define ATX_RST_BTN 33
  21. #define ATX_PWR_BTN 34
  22. #define USB_MS_PWR 31 //Active high, set to HIGH to enable USB 5V power and LOW to disable
  23. #define USB_MS_SW 30 //LOW = remote computer, HIGH = KVM
  24. /* Runtime defs */
  25. #define USB_PWR_SW_PWR_DELAY 100 //ms
  26. #define USB_PWR_SW_DATA_DELAY 10 //ms
  27. /* Runtime variables */
  28. uint8_t atx_status[2] = { 0, 0 }; //PWR LED, HDD LED
  29. uint8_t usb_ms_side = 1; //0 = KVM Controller, 1 = Computer being controlled
  30. char c;
  31. int led_tmp;
  32. bool led_status = true; //Default LED PROG state is high, on every command recv it switch state
  33. void update_atx_led_status() {
  34. led_tmp = digitalRead(ATX_PWR_LED);
  35. atx_status[0] = led_tmp;
  36. led_tmp = digitalRead(ATX_HDD_LED);
  37. atx_status[1] = led_tmp;
  38. }
  39. void switch_usbms_to_kvm() {
  40. if (usb_ms_side == USB_MS_SIDE_KVM_HOST) {
  41. //Already on the KVM side
  42. return;
  43. }
  44. #if ENABLE_DEBUG == 1
  45. USBSerial_println("[DEBUG] Switching USB Mass Storage node to KVM host side");
  46. #endif
  47. //Disconnect the power to USB
  48. digitalWrite(USB_MS_PWR, LOW);
  49. delay(USB_PWR_SW_PWR_DELAY);
  50. //Switch over the device
  51. digitalWrite(USB_MS_PWR, HIGH);
  52. delay(USB_PWR_SW_DATA_DELAY);
  53. digitalWrite(USB_MS_SW, HIGH);
  54. usb_ms_side = USB_MS_SIDE_KVM_HOST;
  55. }
  56. void switch_usbms_to_remote() {
  57. if (usb_ms_side == USB_MS_SIDE_REMOTE_PC) {
  58. //Already on Remote Side
  59. return;
  60. }
  61. #if ENABLE_DEBUG == 1
  62. USBSerial_println("[DEBUG] Switching USB Mass Storage node to remote computer side");
  63. #endif
  64. //Disconnect the power to USB
  65. digitalWrite(USB_MS_PWR, LOW);
  66. delay(USB_PWR_SW_PWR_DELAY);
  67. //Switch over the device
  68. digitalWrite(USB_MS_PWR, HIGH);
  69. delay(USB_PWR_SW_DATA_DELAY);
  70. digitalWrite(USB_MS_SW, LOW);
  71. usb_ms_side = USB_MS_SIDE_REMOTE_PC;
  72. }
  73. void report_status() {
  74. //Report status of ATX and USB mass storage switch in 1 byte
  75. //Bit 0: PWR LED status
  76. //Bit 1: HDD LED status
  77. //Bit 2: USB Mass Storage mounted side
  78. //Bit 3 - 7: Reserved
  79. uint8_t status = 0x00;
  80. status |= (atx_status[0] & 0x01);
  81. status |= (atx_status[1] & 0x01) << 1;
  82. status |= (usb_ms_side & 0x01) << 2;
  83. #if ENABLE_DEBUG == 1
  84. USBSerial_print("[DEBUG] ATX State");
  85. USBSerial_print("PWR=");
  86. USBSerial_print(atx_status[0]);
  87. USBSerial_print(" HDD=");
  88. USBSerial_print(atx_status[1]);
  89. USBSerial_print(" USB_MS=");
  90. USBSerial_println(usb_ms_side);
  91. #endif
  92. USBSerial_print(status);
  93. }
  94. void execute_cmd(char c) {
  95. switch (c) {
  96. case '1':
  97. //Press down the power button
  98. digitalWrite(ATX_PWR_BTN, HIGH);
  99. break;
  100. case '2':
  101. //Release the power button
  102. digitalWrite(ATX_PWR_BTN, LOW);
  103. break;
  104. case '3':
  105. //Press down the reset button
  106. digitalWrite(ATX_RST_BTN, HIGH);
  107. break;
  108. case '4':
  109. //Release the reset button
  110. digitalWrite(ATX_RST_BTN, LOW);
  111. break;
  112. case '5':
  113. //Switch USB mass storage to KVM side
  114. switch_usbms_to_kvm();
  115. break;
  116. case '6':
  117. //Switch USB mass storage to remote computer
  118. switch_usbms_to_remote();
  119. break;
  120. case '7':
  121. //Return the UUID of this device
  122. default:
  123. //Unknown command
  124. break;
  125. }
  126. }
  127. void setup() {
  128. pinMode(ATX_PWR_LED, INPUT);
  129. pinMode(ATX_HDD_LED, INPUT);
  130. pinMode(ATX_RST_BTN, OUTPUT);
  131. pinMode(ATX_PWR_BTN, OUTPUT);
  132. pinMode(USB_MS_PWR, OUTPUT);
  133. pinMode(USB_MS_SW, OUTPUT);
  134. pinMode(LED_PROG, OUTPUT);
  135. digitalWrite(LED_PROG, HIGH);
  136. digitalWrite(ATX_RST_BTN, LOW);
  137. digitalWrite(ATX_PWR_BTN, LOW);
  138. digitalWrite(USB_MS_PWR, LOW);
  139. digitalWrite(USB_MS_SW, LOW);
  140. //Blink 10 times for initiations
  141. for (int i = 0; i < 10; i++) {
  142. digitalWrite(LED_PROG, HIGH);
  143. delay(100);
  144. digitalWrite(LED_PROG, LOW);
  145. delay(100);
  146. }
  147. digitalWrite(LED_PROG, HIGH);
  148. delay(1000);
  149. //Switch the USB thumbnail to host
  150. switch_usbms_to_kvm();
  151. }
  152. void loop() {
  153. if (USBSerial_available()) {
  154. c = USBSerial_read();
  155. #if ENABLE_DEBUG == 1
  156. USBSerial_print("[DEBUG] Serial Recv: ");
  157. USBSerial_println(c);
  158. #endif
  159. execute_cmd(c);
  160. led_status = !led_status;
  161. digitalWrite(LED_PROG, led_status ? HIGH : LOW);
  162. }
  163. //update_atx_led_status();
  164. //report_status();
  165. delay(100);
  166. }