Kiibohd Controller
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
此仓库已存档。您可以查看文件和克隆,但不能推送或创建工单/合并请求。

scan_loop.c 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /* Copyright (C) 2011 by Jacob Alexander
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to deal
  5. * in the Software without restriction, including without limitation the rights
  6. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. * copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. * THE SOFTWARE.
  20. */
  21. // ----- Includes -----
  22. // AVR Includes
  23. #include <avr/interrupt.h>
  24. #include <avr/io.h>
  25. // Project Includes
  26. #include <led.h>
  27. #include <print.h>
  28. // Local Includes
  29. #include "scan_loop.h"
  30. // ----- Defines -----
  31. // ----- Macros -----
  32. // ----- Variables -----
  33. uint8_t KeyIndex_Array[KEYBOARD_SIZE + 1];
  34. // Known signals
  35. static uint8_t cmd_clickOFF = 0x0A; // Short beep, turns off clicker
  36. static uint8_t cmd_clickON = 0x04; // Long beep, turns on clicker
  37. static uint8_t cmd_ACK_AA = 0x10; // Keyboard will send ack (0xAA) back to PC
  38. // Other known signals
  39. // 0x02 turns on clicker but with short beep
  40. // ----- Functions -----
  41. // Setup
  42. inline void scan_setup()
  43. {
  44. // Setup the the USART interface for keyboard data input
  45. // Setup baud rate
  46. // 16 MHz / ( 16 * Baud ) = UBRR
  47. // Baud <- 3.358 ms per bit, thus 1000 / 3.358 = 297.80
  48. // Thus baud = 3357
  49. uint16_t baud = 3357; // Max setting of 4095
  50. UBRR1H = (uint8_t)(baud >> 8);
  51. UBRR1L = (uint8_t)baud;
  52. // Enable the receiver, transitter, and RX Complete Interrupt
  53. UCSR1B = 0x98;
  54. // Set frame format: 8 data, no stop bits or parity
  55. // Asynchrounous USART mode
  56. // Kaypro sends ASCII codes (mostly standard) with 1 start bit and 8 data bits, with no trailing stop or parity bits
  57. UCSR1C = 0x06;
  58. }
  59. // Main Detection Loop
  60. inline uint8_t scan_loop()
  61. {
  62. /*
  63. // Packet Read
  64. if ( packet_index == 8 )
  65. {
  66. // Disable Error LED, proper key found
  67. errorLED( 0 );
  68. //#ifdef MAX_DEBUG
  69. // Crazy Debug (Read the Scan Code)
  70. char tmpStr[3];
  71. hexToStr_op( inputData, tmpStr, 2 );
  72. dPrintStrsNL( "Read Data: 0x", tmpStr );
  73. //#endif
  74. // - Map the scan code to the index array -
  75. // If the 8th bit is high, remove the keypress, else, add the keypress
  76. // The lower 7 bits are the array index
  77. KeyIndex_Array[(inputData & 0x7F)] = (inputData & 0x80) ? 0x00 : 0x80;
  78. // Reset Containers
  79. packet_index = 0;
  80. inputData = 0xFF;
  81. }
  82. // Bad Packet
  83. else if ( packet_index > 8 )
  84. {
  85. // Signal Error
  86. errorLED( 1 );
  87. char tmpStr[3];
  88. int8ToStr( packet_index, tmpStr );
  89. erro_dPrint( "Big packet? Mismatched... ", tmpStr );
  90. packet_index = 0;
  91. inputData = 0xFF;
  92. }
  93. */
  94. /*
  95. // Disable keyboard interrupt (does nothing if already off)
  96. UNSET_INTR();
  97. // Read the clock 8 times
  98. if ( READ_CLK )
  99. {
  100. // Mis-read packet, set back to 0
  101. if ( packet_index == -1 )
  102. packet_index = 0;
  103. // Append 1 bit of data
  104. inputData &= ~(READ_DATA << packet_index);
  105. packet_index++;
  106. // 8 Bits have been read
  107. if ( packet_index == 8 )
  108. {
  109. // Wait till clock edge falls
  110. while ( READ_CLK );
  111. // Sample both lines to make sure this is not a data value
  112. // and definitely the end of packet data blip
  113. uint16_t badDataCounter = 0;
  114. while ( !( READ_DATA ) && !( READ_CLK ) )
  115. badDataCounter++;
  116. if ( badDataCounter < 25 )
  117. {
  118. //#ifdef MAX_DEBUG
  119. // Crazy Debug (Read the Scan Code)
  120. char tmpStr[3];
  121. hexToStr_op( inputData, tmpStr, 2 );
  122. dbug_dPrint( "Read Data: 0x", tmpStr );
  123. //#endif
  124. // - Map the scan code to the index array -
  125. // If the 8th bit is high, remove the keypress, else, add the keypress
  126. // The lower 7 bits are the array index
  127. KeyIndex_Array[(inputData & 0x7F)] = (inputData & 0x80) ? 0x00 : 0x80;
  128. }
  129. // Even though this is a mis-read packet, we still know what the value is
  130. else
  131. {
  132. // Signal Error
  133. errorLED( 1 );
  134. char tmpStr[3];
  135. hexToStr_op( inputData, tmpStr, 2 );
  136. erro_dPrint( "Bad packet? Mismatched... 0x", tmpStr );
  137. }
  138. // Reset Containers
  139. inputData = 0xFF;
  140. packet_index = 0;
  141. // Interrupt the keyboard, so we don't get packet pieces...
  142. SET_INTR();
  143. // Do not wait for next clock, let USB do it's thing (if desired)
  144. return packet_index;
  145. }
  146. // Wait till clock edge falls
  147. while ( READ_CLK );
  148. }
  149. // Interrupt keyboard if there is no pending packet
  150. SET_INTR();
  151. */
  152. return 0;
  153. }
  154. // USART Receive Buffer Full Interrupt
  155. ISR(USART1_RX_vect)
  156. {
  157. cli(); // Disable Interrupts
  158. uint8_t keyValue = UDR1;
  159. char tmpStr1[6];
  160. hexToStr( keyValue, tmpStr1 );
  161. dPrintStrs( tmpStr1, " " );
  162. // Special keys - For communication to the keyboard
  163. // TODO Try to push this functionality into the macros...somehow
  164. switch ( keyValue )
  165. {
  166. case 0xC3: // Keypad Enter
  167. print("\n");
  168. info_print("BEEEEP! - Clicker on");
  169. UDR1 = cmd_clickON;
  170. break;
  171. case 0xB2: // Keypad Decimal
  172. print("\n");
  173. info_print("BEEP! - Clicker off");
  174. UDR1 = cmd_clickOFF;
  175. break;
  176. case 0x0A: // Line Feed
  177. print("\n");
  178. info_print("ACK!!");
  179. UDR1 = cmd_ACK_AA;
  180. break;
  181. }
  182. // Add key to processing buffer
  183. sei(); // Re-enable Interrupts
  184. }