gc_read.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #include "gc_read.h"
  2. #include "gc_controller.h"
  3. #define CONTROLLER_TIMEOUT 60
  4. bool init_message[9] = {0, 0, 0, 0, 0, 0, 0, 0, 1};
  5. bool request_message[25] = {
  6. 0, 1, 0, 0, 0, 0, 0, 0,
  7. 0, 0, 0, 0, 0, 0, 1, 1,
  8. 0, 0, 0, 0, 0, 0, 1, 0, 1};
  9. void start_message(void) {
  10. setPinOutput(GAMECUBE_DATA_PIN);
  11. writePinLow(GAMECUBE_DATA_PIN);
  12. }
  13. void send_bit(bool b) {
  14. if (b) {
  15. writePinLow(GAMECUBE_DATA_PIN);
  16. wait_ns(900);
  17. writePinHigh(GAMECUBE_DATA_PIN);
  18. wait_ns(2900);
  19. } else {
  20. writePinLow(GAMECUBE_DATA_PIN);
  21. wait_ns(2900);
  22. writePinHigh(GAMECUBE_DATA_PIN);
  23. wait_ns(900);
  24. }
  25. }
  26. void wait_for_ready(void) {
  27. setPinInputHigh(GAMECUBE_DATA_PIN);
  28. // wait for long high
  29. uint8_t ready = 0;
  30. while (ready < 5) {
  31. if (readPin(GAMECUBE_DATA_PIN))
  32. ready++;
  33. else
  34. ready = 0;
  35. wait_us(1);
  36. }
  37. }
  38. void end_message(void) {
  39. setPinInputHigh(GAMECUBE_DATA_PIN);
  40. }
  41. uint8_t buffer[9] = {0};
  42. uint16_t buttons_debounce = 0;
  43. bool initialised = false;
  44. bool calibrated = false;
  45. uint8_t mid_values[4] = {128, 128, 128, 128};
  46. uint8_t max_values[4] = {210, 210, 210, 210};
  47. uint8_t min_values[4] = {35, 35, 35, 35};
  48. void gamecube_init(void) {
  49. setPinInputHigh(GAMECUBE_DATA_PIN);
  50. }
  51. void gamecube_scan(uint16_t * buttons, uint8_t * joysticks) {
  52. bool exiting = false;
  53. uint16_t timeout_counter = 0;
  54. // somehow we're missing the first bit, which can safely be ignored
  55. // i'm not sure if it's something with the timing or what
  56. uint8_t buffer_bit = 1;
  57. chSysLock();
  58. if (!initialised) {
  59. wait_for_ready();
  60. start_message();
  61. for (uint8_t i = 0; i < 9; i++)
  62. send_bit(init_message[i]);
  63. end_message();
  64. initialised = true;
  65. }
  66. wait_for_ready();
  67. start_message();
  68. for (uint8_t i = 0; i < 25; i++)
  69. send_bit(request_message[i]);
  70. end_message();
  71. while (!exiting) {
  72. timeout_counter = 0;
  73. // wait for low or timeout
  74. while (readPin(GAMECUBE_DATA_PIN)) {
  75. wait_ns(100);
  76. timeout_counter++;
  77. if (timeout_counter > CONTROLLER_TIMEOUT) {
  78. exiting = true;
  79. break;
  80. }
  81. }
  82. if (!exiting) {
  83. // wait for the data part
  84. wait_ns(1950);
  85. bool b = readPin(GAMECUBE_DATA_PIN);
  86. if (b)
  87. buffer[buffer_bit / 8] |= (1 << (7 - (buffer_bit % 8)));
  88. else
  89. buffer[buffer_bit / 8] &= ~(1 << (7 - (buffer_bit % 8)));
  90. buffer_bit++;
  91. // wait for high
  92. while (!readPin(GAMECUBE_DATA_PIN));
  93. }
  94. }
  95. chSysUnlock();
  96. // basic debouncing for buttons
  97. uint16_t combined_buttons = buffer[0] | (buffer[1] << 8);
  98. *buttons |= buttons_debounce & combined_buttons;
  99. *buttons &= buttons_debounce | combined_buttons;
  100. buttons_debounce = combined_buttons;
  101. if (!calibrated && mid_values[0] > 0) {
  102. mid_values[0] = buffer[2];
  103. mid_values[1] = buffer[3];
  104. mid_values[2] = buffer[4];
  105. mid_values[3] = buffer[5];
  106. calibrated = true;
  107. }
  108. if (max_values[0] < buffer[2])
  109. max_values[0] = buffer[2];
  110. if (max_values[1] < buffer[3])
  111. max_values[1] = buffer[3];
  112. if (max_values[2] < buffer[4])
  113. max_values[2] = buffer[4];
  114. if (max_values[3] < buffer[5])
  115. max_values[3] = buffer[5];
  116. if (min_values[0] > buffer[2])
  117. min_values[0] = buffer[2];
  118. if (min_values[1] > buffer[3])
  119. min_values[1] = buffer[3];
  120. if (min_values[2] > buffer[4])
  121. min_values[2] = buffer[4];
  122. if (min_values[3] > buffer[5])
  123. min_values[3] = buffer[5];
  124. // values from my GC controller in Windows
  125. // 30 - 138 - 236
  126. // 20 - 124 - 225
  127. // 37 - 135 - 222
  128. // 34 - 126 - 216
  129. // this should be 127? i don't understand what i'm doing wrong yet
  130. #define JOYSTICK_SCALER 180.0
  131. int32_t lx_temp = (int16_t)buffer[2] - mid_values[0];
  132. if (lx_temp > 0)
  133. lx_temp *= JOYSTICK_SCALER / (max_values[0]-mid_values[0]);
  134. else
  135. lx_temp *= JOYSTICK_SCALER / (mid_values[0]-min_values[0]);
  136. lx_temp += STICK_CENTER;
  137. if (lx_temp > 255)
  138. lx_temp = 255;
  139. if (lx_temp < 0)
  140. lx_temp = 0;
  141. int32_t ly_temp = (int16_t)buffer[3] - mid_values[1];
  142. if (ly_temp > 0)
  143. ly_temp *= JOYSTICK_SCALER / (max_values[1]-mid_values[1]);
  144. else
  145. ly_temp *= JOYSTICK_SCALER / (mid_values[1]-min_values[1]);
  146. ly_temp += STICK_CENTER;
  147. if (ly_temp > 255)
  148. ly_temp = 255;
  149. if (ly_temp < 0)
  150. ly_temp = 0;
  151. int32_t rx_temp = (int16_t)buffer[4] - mid_values[2];
  152. if (rx_temp > 0)
  153. rx_temp *= JOYSTICK_SCALER / (max_values[2]-mid_values[2]);
  154. else
  155. rx_temp *= JOYSTICK_SCALER / (mid_values[2]-min_values[2]);
  156. rx_temp += STICK_CENTER;
  157. if (rx_temp > 255)
  158. rx_temp = 255;
  159. if (rx_temp < 0)
  160. rx_temp = 0;
  161. int32_t ry_temp = (int16_t)buffer[5] - mid_values[3];
  162. if (ry_temp > 0)
  163. ry_temp *= JOYSTICK_SCALER / (max_values[3]-mid_values[3]);
  164. else
  165. ry_temp *= JOYSTICK_SCALER / (mid_values[3]-min_values[3]);
  166. ry_temp += STICK_CENTER;
  167. if (ry_temp > 255)
  168. ry_temp = 255;
  169. if (ry_temp < 0)
  170. ry_temp = 0;
  171. // checks to avoid a data skip (0 values on input, which aren't possible, i think)
  172. if (buffer[2])
  173. joysticks[0] = lx_temp;
  174. if (buffer[3])
  175. joysticks[1] = ly_temp;
  176. if (buffer[4])
  177. joysticks[2] = rx_temp;
  178. if (buffer[5])
  179. joysticks[3] = ry_temp;
  180. if (buffer[6])
  181. joysticks[4] = buffer[6];
  182. if (buffer[7])
  183. joysticks[5] = buffer[7];
  184. }