Kiibohd Controller
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  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/io.h>
  24. #include <util/delay.h>
  25. // Project Includes
  26. #include <print.h>
  27. // Local Includes
  28. #include "matrix_scan.h"
  29. // Matrix Configuration
  30. #include <matrix.h>
  31. // ----- Macros -----
  32. // -- pinSetup Macros --
  33. #define REG_SET(reg) reg |= (1 << ( matrix[row*(MAX_ROW_SIZE+1)+col] % 10 ) ) // Modulo 10 for the define offset for each pin set 12 or 32 -> shift of 2
  34. #define REG_UNSET(reg) reg &= ~(1 << ( matrix[row*(MAX_ROW_SIZE+1)+col] % 10 ) )
  35. #define PIN_SET(pin,scan,direction) \
  36. switch ( direction ) { \
  37. case columnSet: PIN_SET_COL(pin,scan); \
  38. case rowSet: PIN_SET_ROW(pin,scan); \
  39. } \
  40. break
  41. // TODO Only scanCol_powrRow Tested (and powrRow)
  42. #define PIN_SET_COL(pin,scan) \
  43. switch ( scan ) { \
  44. case scanCol: \
  45. case scanRow_powrCol: \
  46. case scanDual: \
  47. REG_SET(port##pin); break; \
  48. case scanCol_powrRow: REG_UNSET(ddr##pin); REG_UNSET(DDR##pin); \
  49. REG_SET(port##pin); REG_SET(PORT##pin); break; \
  50. case powrRow: break; \
  51. case powrCol: REG_SET(ddr##pin); REG_SET(DDR##pin); \
  52. REG_SET(port##pin); REG_SET(PORT##pin); break; \
  53. } \
  54. break
  55. // TODO Only scanCol_powrRow Tested (and powrRow)
  56. #define PIN_SET_ROW(pin,scan) \
  57. switch ( scan ) { \
  58. case scanRow_powrCol: REG_UNSET(ddr##pin); REG_SET(port##pin); break; \
  59. case scanRow: \
  60. case scanDual: \
  61. REG_SET(port##pin); break; \
  62. case scanCol_powrRow: REG_SET(ddr##pin); REG_SET(DDR##pin); \
  63. REG_UNSET(port##pin); REG_UNSET(PORT##pin); break; \
  64. case powrRow: REG_SET(ddr##pin); REG_SET(DDR##pin); \
  65. REG_SET(port##pin); REG_SET(PORT##pin); break; \
  66. case powrCol: break; \
  67. } \
  68. break
  69. #define PIN_CASE(pinLetter) \
  70. case pin##pinLetter##0: \
  71. case pin##pinLetter##1: \
  72. case pin##pinLetter##2: \
  73. case pin##pinLetter##3: \
  74. case pin##pinLetter##4: \
  75. case pin##pinLetter##5: \
  76. case pin##pinLetter##6: \
  77. case pin##pinLetter##7
  78. // -- Column Scan Macros --
  79. #define PIN_TEST_COL(pin) \
  80. scanCode = matrix[row*(MAX_ROW_SIZE+1)+col]; \
  81. if ( scanCode && !( pin & ( 1 << ( matrix[0*(MAX_ROW_SIZE+1)+col] % 10 ) ) ) ) \
  82. { \
  83. detectArray[scanCode]++; \
  84. } \
  85. break
  86. // -- Row Scan Macros --
  87. #define PIN_TEST_ROW(pin) \
  88. scanCode = matrix[row*(MAX_ROW_SIZE+1)+col]; \
  89. if ( scanCode && !( pin & ( 1 << ( matrix[row*(MAX_ROW_SIZE+1)+0] % 10 ) ) ) ) \
  90. { \
  91. detectArray[scanCode]++; \
  92. } \
  93. break
  94. // -- Scan Dual Macros --
  95. #define PIN_DUALTEST_ROW(pin) \
  96. scanCode = matrix[row*(MAX_ROW_SIZE+1)+col]; \
  97. if ( scanCode \
  98. && !( pin & ( 1 << ( matrix[row*(MAX_ROW_SIZE+1)+0] % 10 ) ) ) \
  99. && detectArray[scanCode] & 0x01 ) \
  100. { \
  101. detectArray[scanCode]++; \
  102. } \
  103. else \
  104. { \
  105. if ( detectArray[scanCode] & 0x01 ) \
  106. detectArray[scanCode]--; \
  107. } \
  108. break
  109. // ----- Variables -----
  110. uint8_t showDebug = 0;
  111. // Debug Variables for GPIO setting
  112. uint8_t portA = 0x00;
  113. uint8_t portB = 0x00;
  114. uint8_t portC = 0x00;
  115. uint8_t portD = 0x00;
  116. uint8_t portE = 0x00;
  117. uint8_t portF = 0x00;
  118. uint8_t ddrA = 0x00;
  119. uint8_t ddrB = 0x00;
  120. uint8_t ddrC = 0x00;
  121. uint8_t ddrD = 0x00;
  122. uint8_t ddrE = 0x00;
  123. uint8_t ddrF = 0x00;
  124. // ----- Functions -----
  125. // Pin Setup Debug
  126. inline void matrix_debugPins()
  127. {
  128. char tmpStr[6];
  129. info_print("Initial Matrix Pin Setup");
  130. info_print(" ddrA ddrB ddrC ddrD ddrE ddrF");
  131. print(" ");
  132. hexToStr_op( ddrA, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  133. hexToStr_op( ddrB, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  134. hexToStr_op( ddrC, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  135. hexToStr_op( ddrD, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  136. hexToStr_op( ddrE, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  137. hexToStr_op( ddrF, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  138. print("\n");
  139. info_print("portA portB portC portD portE portF");
  140. print(" ");
  141. hexToStr_op( portA, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  142. hexToStr_op( portB, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  143. hexToStr_op( portC, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  144. hexToStr_op( portD, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  145. hexToStr_op( portE, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  146. hexToStr_op( portF, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  147. print("\n");
  148. showDebug++;
  149. }
  150. // Column Setup
  151. inline void matrix_columnSet( uint8_t *matrix, uint8_t scanType, uint16_t startIndex, uint16_t colsToIterate )
  152. {
  153. // Calculate the number of pins to iterate over
  154. uint8_t maxColumns = startIndex + colsToIterate - 1;
  155. if ( maxColumns > MAX_COL_SIZE )
  156. maxColumns = MAX_COL_SIZE;
  157. uint16_t row, col;
  158. // Columns
  159. for ( col = startIndex, row = 0; col <= maxColumns; col++ )
  160. {
  161. // We can't pass 2D arrays, so just point to the first element and calculate directly
  162. switch ( matrix[row*(MAX_ROW_SIZE+1)+col] )
  163. {
  164. #if defined(__AVR_AT90USB1286__)
  165. PIN_CASE(A):
  166. PIN_SET(A, scanType, columnSet);
  167. #endif
  168. PIN_CASE(B):
  169. PIN_SET(B, scanType, columnSet);
  170. PIN_CASE(C):
  171. PIN_SET(C, scanType, columnSet);
  172. PIN_CASE(D):
  173. PIN_SET(D, scanType, columnSet);
  174. PIN_CASE(E):
  175. PIN_SET(E, scanType, columnSet);
  176. PIN_CASE(F):
  177. PIN_SET(F, scanType, columnSet);
  178. default:
  179. continue;
  180. }
  181. }
  182. }
  183. // Row Setup
  184. inline void matrix_rowSet( uint8_t *matrix, uint8_t scanType, uint16_t startIndex, uint8_t rowsToIterate )
  185. {
  186. // Calculate the number of pins to iterate over
  187. uint16_t maxRows = startIndex + rowsToIterate - 1;
  188. if ( maxRows > MAX_ROW_SIZE )
  189. maxRows = MAX_ROW_SIZE;
  190. uint16_t row, col;
  191. // Rows
  192. for ( col = 0, row = startIndex; row <= maxRows; row++ )
  193. {
  194. // We can't pass 2D arrays, so just point to the first element and calculate directly
  195. switch ( matrix[row*(MAX_ROW_SIZE+1)+col] )
  196. {
  197. #if defined(__AVR_AT90USB1286__)
  198. PIN_CASE(A):
  199. PIN_SET(A, scanType, rowSet);
  200. #endif
  201. PIN_CASE(B):
  202. PIN_SET(B, scanType, rowSet);
  203. PIN_CASE(C):
  204. PIN_SET(C, scanType, rowSet);
  205. PIN_CASE(D):
  206. PIN_SET(D, scanType, rowSet);
  207. PIN_CASE(E):
  208. PIN_SET(E, scanType, rowSet);
  209. PIN_CASE(F):
  210. PIN_SET(F, scanType, rowSet);
  211. default:
  212. continue;
  213. }
  214. }
  215. }
  216. // Goes through the defined matrix and matrix mode, and sets the initial state of all of the available pins
  217. void matrix_pinSetup( uint8_t *matrix, uint8_t scanType )
  218. {
  219. // Loop through all the pin assignments, for the initial pin settings
  220. matrix_rowSet ( matrix, scanType, 1, MAX_ROW_SIZE );
  221. matrix_columnSet( matrix, scanType, 1, MAX_COL_SIZE );
  222. // Pin Status
  223. if ( showDebug == 0 ) // Only show once
  224. {
  225. matrix_debugPins();
  226. }
  227. }
  228. // Scans the given matrix determined by the scanMode method
  229. inline void matrix_scan( uint8_t *matrix, uint8_t *detectArray )
  230. {
  231. // Loop variables for all modes
  232. uint16_t col = 1;
  233. uint16_t row = 1;
  234. uint16_t scanCode = 0;
  235. // TODO Only scanCol_powrRow tested
  236. // Column Scan and Column Scan, Power Row
  237. #if scanMode == scanCol || scanMode == scanCol_powrRow
  238. for ( ; row <= MAX_ROW_SIZE; row++ )
  239. {
  240. // Power each row separately
  241. matrix_rowSet( matrix, powrRow, row, 1 );
  242. for ( col = 1; col <= MAX_COL_SIZE; col++ )
  243. {
  244. // Scan over the pins for each of the columns, and using the pin alias to determine which pin to set
  245. // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.))
  246. switch ( matrix[0*(MAX_ROW_SIZE+1)+col] / 10 )
  247. {
  248. #if defined(__AVR_AT90USB1286__)
  249. case 0: // PINA
  250. PIN_TEST_COL(PINA);
  251. #endif
  252. case 1: // PINB
  253. PIN_TEST_COL(PINB);
  254. case 2: // PINC
  255. PIN_TEST_COL(PINC);
  256. case 3: // PIND
  257. PIN_TEST_COL(PIND);
  258. case 4: // PINE
  259. PIN_TEST_COL(PINE);
  260. case 5: // PINF
  261. PIN_TEST_COL(PINF);
  262. }
  263. }
  264. // Unset the row power
  265. matrix_rowSet( matrix, scanMode, row, 1 );
  266. }
  267. #endif // scanMode
  268. // Row Scan and Row Scan, Power Row
  269. #if scanMode == scanRow || scanMode == scanRow_powrCol
  270. for ( ; col <= MAX_COL_SIZE; col++ )
  271. {
  272. // Power each column separately
  273. matrix_columnSet( matrix, powrCol, col, 1 );
  274. for ( row = 1; row <= MAX_ROW_SIZE; row++ )
  275. {
  276. // Scan over the pins for each of the rows, and using the pin alias to determine which pin to set
  277. // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.))
  278. switch ( matrix[row*(MAX_ROW_SIZE+1)+0] / 10 )
  279. {
  280. #if defined(__AVR_AT90USB1286__)
  281. case 0: // PINA
  282. PIN_TEST_ROW(PINA);
  283. #endif
  284. case 1: // PINB
  285. PIN_TEST_ROW(PINB);
  286. case 2: // PINC
  287. PIN_TEST_ROW(PINC);
  288. case 3: // PIND
  289. PIN_TEST_ROW(PIND);
  290. case 4: // PINE
  291. PIN_TEST_ROW(PINE);
  292. case 5: // PINF
  293. PIN_TEST_ROW(PINF);
  294. }
  295. }
  296. // Unset the column power
  297. matrix_columnSet( matrix, scanMode, col, 1 );
  298. }
  299. #endif // scanMode
  300. // Dual Scan
  301. #if scanMode == scanDual
  302. // First do a scan of all of the columns, marking each one
  303. matrix_pinSetup( matrix, scanCol_powrRow, 0, MAX_ROW_SIZE, MAX_COL_SIZE );
  304. _delay_us( 1 );
  305. for ( ; row < (MAX_COL_SIZE+1); row++ ) for ( ; col < (MAX_ROW_SIZE+1); col++ )
  306. {
  307. // Scan over the pins for each of the columns, and using the pin alias to determine which pin to set
  308. // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.))
  309. switch ( matrix[0*(MAX_ROW_SIZE+1)+col] / 10 )
  310. {
  311. #if defined(__AVR_AT90USB1286__)
  312. case 0: // PINA
  313. PIN_TEST_COL(PINA);
  314. #endif
  315. case 1: // PINB
  316. PIN_TEST_COL(PINB);
  317. case 2: // PINC
  318. PIN_TEST_COL(PINC);
  319. case 3: // PIND
  320. PIN_TEST_COL(PIND);
  321. case 4: // PINE
  322. PIN_TEST_COL(PINE);
  323. case 5: // PINF
  324. PIN_TEST_COL(PINF);
  325. }
  326. }
  327. // Next, do a scan of all of the rows, clearing any "vague" keys (only detected on row, but not column, or vice-versa)
  328. // And marking any keys that are detected on the row and column
  329. matrix_pinSetup( matrix, scanRow_powrCol, 0, MAX_ROW_SIZE, MAX_COL_SIZE );
  330. _delay_us( 1 );
  331. col = 1;
  332. row = 1;
  333. for ( ; col < (MAX_ROW_SIZE+1); col++ ) for ( ; row < (MAX_COL_SIZE+1); row++ )
  334. {
  335. // Scan over the pins for each of the rows, and using the pin alias to determine which pin to set
  336. // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.))
  337. switch ( matrix[row*(MAX_ROW_SIZE+1)+0] / 10 )
  338. {
  339. #if defined(__AVR_AT90USB1286__)
  340. case 0: // PINA
  341. PIN_DUALTEST_ROW(PINA);
  342. #endif
  343. case 1: // PINB
  344. PIN_DUALTEST_ROW(PINB);
  345. case 2: // PINC
  346. PIN_DUALTEST_ROW(PINC);
  347. case 3: // PIND
  348. PIN_DUALTEST_ROW(PIND);
  349. case 4: // PINE
  350. PIN_DUALTEST_ROW(PINE);
  351. case 5: // PINF
  352. PIN_DUALTEST_ROW(PINF);
  353. }
  354. }
  355. #endif
  356. }