Kiibohd Controller
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

matrix_scan.c 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. /* Copyright (C) 2011,2014 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. void matrix_debugPins(void);
  126. // Pin Setup Debug
  127. inline void matrix_debugPins()
  128. {
  129. char tmpStr[6];
  130. info_print("Initial Matrix Pin Setup");
  131. info_print(" ddrA ddrB ddrC ddrD ddrE ddrF");
  132. print(" ");
  133. hexToStr_op( ddrA, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  134. hexToStr_op( ddrB, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  135. hexToStr_op( ddrC, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  136. hexToStr_op( ddrD, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  137. hexToStr_op( ddrE, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  138. hexToStr_op( ddrF, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  139. print("\n");
  140. info_print("portA portB portC portD portE portF");
  141. print(" ");
  142. hexToStr_op( portA, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  143. hexToStr_op( portB, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  144. hexToStr_op( portC, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  145. hexToStr_op( portD, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  146. hexToStr_op( portE, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  147. hexToStr_op( portF, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
  148. print("\n");
  149. showDebug++;
  150. }
  151. // Column Setup
  152. inline void matrix_columnSet( uint8_t *matrix, uint8_t scanType, uint16_t startIndex, uint16_t colsToIterate )
  153. {
  154. // Calculate the number of pins to iterate over
  155. uint8_t maxColumns = startIndex + colsToIterate - 1;
  156. if ( maxColumns > MAX_COL_SIZE )
  157. maxColumns = MAX_COL_SIZE;
  158. uint16_t row, col;
  159. // Columns
  160. for ( col = startIndex, row = 0; col <= maxColumns; col++ )
  161. {
  162. // We can't pass 2D arrays, so just point to the first element and calculate directly
  163. switch ( matrix[row*(MAX_ROW_SIZE+1)+col] )
  164. {
  165. #if defined(__AVR_AT90USB1286__)
  166. PIN_CASE(A):
  167. PIN_SET(A, scanType, columnSet);
  168. #endif
  169. PIN_CASE(B):
  170. PIN_SET(B, scanType, columnSet);
  171. PIN_CASE(C):
  172. PIN_SET(C, scanType, columnSet);
  173. PIN_CASE(D):
  174. PIN_SET(D, scanType, columnSet);
  175. PIN_CASE(E):
  176. PIN_SET(E, scanType, columnSet);
  177. PIN_CASE(F):
  178. PIN_SET(F, scanType, columnSet);
  179. default:
  180. continue;
  181. }
  182. }
  183. }
  184. // Row Setup
  185. inline void matrix_rowSet( uint8_t *matrix, uint8_t scanType, uint16_t startIndex, uint8_t rowsToIterate )
  186. {
  187. // Calculate the number of pins to iterate over
  188. uint16_t maxRows = startIndex + rowsToIterate - 1;
  189. if ( maxRows > MAX_ROW_SIZE )
  190. maxRows = MAX_ROW_SIZE;
  191. uint16_t row, col;
  192. // Rows
  193. for ( col = 0, row = startIndex; row <= maxRows; row++ )
  194. {
  195. // We can't pass 2D arrays, so just point to the first element and calculate directly
  196. switch ( matrix[row*(MAX_ROW_SIZE+1)+col] )
  197. {
  198. #if defined(__AVR_AT90USB1286__)
  199. PIN_CASE(A):
  200. PIN_SET(A, scanType, rowSet);
  201. #endif
  202. PIN_CASE(B):
  203. PIN_SET(B, scanType, rowSet);
  204. PIN_CASE(C):
  205. PIN_SET(C, scanType, rowSet);
  206. PIN_CASE(D):
  207. PIN_SET(D, scanType, rowSet);
  208. PIN_CASE(E):
  209. PIN_SET(E, scanType, rowSet);
  210. PIN_CASE(F):
  211. PIN_SET(F, scanType, rowSet);
  212. default:
  213. continue;
  214. }
  215. }
  216. }
  217. // Goes through the defined matrix and matrix mode, and sets the initial state of all of the available pins
  218. void matrix_pinSetup( uint8_t *matrix, uint8_t scanType )
  219. {
  220. // Loop through all the pin assignments, for the initial pin settings
  221. matrix_rowSet ( matrix, scanType, 1, MAX_ROW_SIZE );
  222. matrix_columnSet( matrix, scanType, 1, MAX_COL_SIZE );
  223. // Pin Status
  224. if ( showDebug == 0 ) // Only show once
  225. {
  226. matrix_debugPins();
  227. }
  228. }
  229. // Scans the given matrix determined by the scanMode method
  230. inline void matrix_scan( uint8_t *matrix, uint8_t *detectArray )
  231. {
  232. // Loop variables for all modes
  233. uint16_t col = 1;
  234. uint16_t row = 1;
  235. uint16_t scanCode = 0;
  236. // TODO Only scanCol_powrRow tested
  237. // Column Scan and Column Scan, Power Row
  238. #if scanMode == scanCol || scanMode == scanCol_powrRow
  239. for ( ; row <= MAX_ROW_SIZE; row++ )
  240. {
  241. // Power each row separately
  242. matrix_rowSet( matrix, powrRow, row, 1 );
  243. for ( col = 1; col <= MAX_COL_SIZE; col++ )
  244. {
  245. // Scan over the pins for each of the columns, and using the pin alias to determine which pin to set
  246. // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.))
  247. switch ( matrix[0*(MAX_ROW_SIZE+1)+col] / 10 )
  248. {
  249. #if defined(__AVR_AT90USB1286__)
  250. case 0: // PINA
  251. PIN_TEST_COL(PINA);
  252. #endif
  253. case 1: // PINB
  254. PIN_TEST_COL(PINB);
  255. case 2: // PINC
  256. PIN_TEST_COL(PINC);
  257. case 3: // PIND
  258. PIN_TEST_COL(PIND);
  259. case 4: // PINE
  260. PIN_TEST_COL(PINE);
  261. case 5: // PINF
  262. PIN_TEST_COL(PINF);
  263. }
  264. }
  265. // Unset the row power
  266. matrix_rowSet( matrix, scanMode, row, 1 );
  267. }
  268. #endif // scanMode
  269. // Row Scan and Row Scan, Power Row
  270. #if scanMode == scanRow || scanMode == scanRow_powrCol
  271. for ( ; col <= MAX_COL_SIZE; col++ )
  272. {
  273. // Power each column separately
  274. matrix_columnSet( matrix, powrCol, col, 1 );
  275. for ( row = 1; row <= MAX_ROW_SIZE; row++ )
  276. {
  277. // Scan over the pins for each of the rows, and using the pin alias to determine which pin to set
  278. // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.))
  279. switch ( matrix[row*(MAX_ROW_SIZE+1)+0] / 10 )
  280. {
  281. #if defined(__AVR_AT90USB1286__)
  282. case 0: // PINA
  283. PIN_TEST_ROW(PINA);
  284. #endif
  285. case 1: // PINB
  286. PIN_TEST_ROW(PINB);
  287. case 2: // PINC
  288. PIN_TEST_ROW(PINC);
  289. case 3: // PIND
  290. PIN_TEST_ROW(PIND);
  291. case 4: // PINE
  292. PIN_TEST_ROW(PINE);
  293. case 5: // PINF
  294. PIN_TEST_ROW(PINF);
  295. }
  296. }
  297. // Unset the column power
  298. matrix_columnSet( matrix, scanMode, col, 1 );
  299. }
  300. #endif // scanMode
  301. // Dual Scan
  302. #if scanMode == scanDual
  303. // First do a scan of all of the columns, marking each one
  304. //matrix_pinSetup( matrix, scanCol_powrRow, 0, MAX_ROW_SIZE, MAX_COL_SIZE ); TODO
  305. _delay_us( 1 );
  306. for ( ; row < (MAX_COL_SIZE+1); row++ ) for ( ; col < (MAX_ROW_SIZE+1); col++ )
  307. {
  308. // Scan over the pins for each of the columns, and using the pin alias to determine which pin to set
  309. // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.))
  310. switch ( matrix[0*(MAX_ROW_SIZE+1)+col] / 10 )
  311. {
  312. #if defined(__AVR_AT90USB1286__)
  313. case 0: // PINA
  314. PIN_TEST_COL(PINA);
  315. #endif
  316. case 1: // PINB
  317. PIN_TEST_COL(PINB);
  318. case 2: // PINC
  319. PIN_TEST_COL(PINC);
  320. case 3: // PIND
  321. PIN_TEST_COL(PIND);
  322. case 4: // PINE
  323. PIN_TEST_COL(PINE);
  324. case 5: // PINF
  325. PIN_TEST_COL(PINF);
  326. }
  327. }
  328. // Next, do a scan of all of the rows, clearing any "vague" keys (only detected on row, but not column, or vice-versa)
  329. // And marking any keys that are detected on the row and column
  330. //matrix_pinSetup( matrix, scanRow_powrCol, 0, MAX_ROW_SIZE, MAX_COL_SIZE ); TODO
  331. _delay_us( 1 );
  332. col = 1;
  333. row = 1;
  334. for ( ; col < (MAX_ROW_SIZE+1); col++ ) for ( ; row < (MAX_COL_SIZE+1); row++ )
  335. {
  336. // Scan over the pins for each of the rows, and using the pin alias to determine which pin to set
  337. // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.))
  338. switch ( matrix[row*(MAX_ROW_SIZE+1)+0] / 10 )
  339. {
  340. #if defined(__AVR_AT90USB1286__)
  341. case 0: // PINA
  342. PIN_DUALTEST_ROW(PINA);
  343. #endif
  344. case 1: // PINB
  345. PIN_DUALTEST_ROW(PINB);
  346. case 2: // PINC
  347. PIN_DUALTEST_ROW(PINC);
  348. case 3: // PIND
  349. PIN_DUALTEST_ROW(PIND);
  350. case 4: // PINE
  351. PIN_DUALTEST_ROW(PINE);
  352. case 5: // PINF
  353. PIN_DUALTEST_ROW(PINF);
  354. }
  355. }
  356. #endif
  357. }