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.

scan_loop.c 22KB

10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. /* Copyright (C) 2011-2013 by Joseph Makuch
  2. * Additions by Jacob Alexander (2013-2014)
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 3.0 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. // ----- Includes -----
  18. // Compiler Includes
  19. #include <Lib/ScanLib.h>
  20. // Project Includes
  21. #include <led.h>
  22. #include <print.h>
  23. // Local Includes
  24. #include "scan_loop.h"
  25. // ----- Defines -----
  26. // TODO dfj defines...needs commenting and maybe some cleaning...
  27. #define MAX_PRESS_DELTA_MV 450 // As measured from the Teensy ADC pin
  28. #define THRESHOLD_MV (MAX_PRESS_DELTA_MV >> 1)
  29. //(2560 / (0x3ff/2)) ~= 5
  30. #define MV_PER_ADC 5
  31. #define THRESHOLD (THRESHOLD_MV / MV_PER_ADC)
  32. #define STROBE_SETTLE 1
  33. #define TEST_KEY_STROBE (0x05)
  34. #define TEST_KEY_MASK (1 << 0)
  35. #define ADHSM 7
  36. #define RIGHT_JUSTIFY 0
  37. #define LEFT_JUSTIFY (0xff)
  38. // set left or right justification here:
  39. #define JUSTIFY_ADC RIGHT_JUSTIFY
  40. #define ADLAR_MASK (1 << ADLAR)
  41. #ifdef JUSTIFY_ADC
  42. #define ADLAR_BITS ((ADLAR_MASK) & (JUSTIFY_ADC))
  43. #else // defaults to right justification.
  44. #define ADLAR_BITS 0
  45. #endif
  46. // full muxmask
  47. #define FULL_MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4))
  48. // F0-f7 pins only muxmask.
  49. #define MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2))
  50. // Strobe Masks
  51. #define D_MASK (0xff)
  52. #define E_MASK (0x03)
  53. #define C_MASK (0xff)
  54. // set ADC clock prescale
  55. #define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2))
  56. #define PRESCALE_SHIFT (ADPS0)
  57. #define PRESCALE 3
  58. // Max number of strobes supported by the hardware
  59. // Strobe lines are detected at startup, extra strobes cause anomalies like phantom keypresses
  60. #define MAX_STROBES 18
  61. // Number of consecutive samples required to pass debounce
  62. #define DEBOUNCE_THRESHOLD 5
  63. #define MUXES_COUNT 8
  64. #define MUXES_COUNT_XSHIFT 3
  65. #define WARMUP_LOOPS ( 1024 )
  66. #define WARMUP_STOP (WARMUP_LOOPS - 1)
  67. #define SAMPLE_CONTROL 3
  68. #define KEY_COUNT ((MAX_STROBES) * (MUXES_COUNT))
  69. #define RECOVERY_CONTROL 1
  70. #define RECOVERY_SOURCE 0
  71. #define RECOVERY_SINK 2
  72. #define ON 1
  73. #define OFF 0
  74. // mix in 1/4 of the current average to the running average. -> (@mux_mix = 2)
  75. #define MUX_MIX 2
  76. #define IDLE_COUNT_MASK 0xff
  77. #define IDLE_COUNT_SHIFT 8
  78. // av = (av << shift) - av + sample; av >>= shift
  79. // e.g. 1 -> (av + sample) / 2 simple average of new and old
  80. // 2 -> (3 * av + sample) / 4 i.e. 3:1 mix of old to new.
  81. // 3 -> (7 * av + sample) / 8 i.e. 7:1 mix of old to new.
  82. #define KEYS_AVERAGES_MIX_SHIFT 3
  83. // ----- Macros -----
  84. // Select mux
  85. #define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK))))
  86. // ----- Variables -----
  87. // Buffer used to inform the macro processing module which keys have been detected as pressed
  88. volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
  89. volatile uint8_t KeyIndex_BufferUsed;
  90. // TODO dfj variables...needs cleaning up and commenting
  91. // Variables used to calculate the starting sense value (averaging)
  92. uint32_t full_avg = 0;
  93. uint32_t high_avg = 0;
  94. uint32_t low_avg = 0;
  95. uint8_t high_count = 0;
  96. uint8_t low_count = 0;
  97. uint8_t ze_strober = 0;
  98. uint16_t samples[MUXES_COUNT];
  99. uint8_t cur_keymap[MAX_STROBES];
  100. uint8_t keymap_change;
  101. uint16_t threshold = THRESHOLD;
  102. uint8_t column = 0;
  103. uint16_t keys_averages_acc[KEY_COUNT];
  104. uint16_t keys_averages [KEY_COUNT];
  105. uint8_t keys_debounce [KEY_COUNT]; // Contains debounce statistics
  106. uint8_t keys_problem [KEY_COUNT]; // Marks keys that should be ignored (determined by averaging at startup)
  107. uint8_t full_samples[KEY_COUNT];
  108. // TODO: change this to 'booting', then count down.
  109. uint16_t boot_count = 0;
  110. uint16_t idle_count = 0;
  111. uint8_t idle = 1;
  112. uint8_t error = 0;
  113. uint16_t error_data = 0;
  114. uint8_t total_strobes = MAX_STROBES;
  115. uint8_t strobe_map[MAX_STROBES];
  116. uint8_t dump_count = 0;
  117. // ----- Function Declarations -----
  118. void dump( void );
  119. void recovery( uint8_t on );
  120. int sampleColumn( uint8_t column );
  121. void capsense_scan( void );
  122. void setup_ADC( void );
  123. void strobe_w( uint8_t strobe_num );
  124. uint8_t testColumn( uint8_t strobe );
  125. // ----- Functions -----
  126. // Initial setup for cap sense controller
  127. inline void Scan_setup()
  128. {
  129. // TODO dfj code...needs cleanup + commenting...
  130. setup_ADC();
  131. DDRC = C_MASK;
  132. PORTC = 0;
  133. DDRD = D_MASK;
  134. PORTD = 0;
  135. DDRE = E_MASK;
  136. PORTE = 0 ;
  137. // Hardcoded strobes for debugging
  138. // Strobes start at 0 and go to 17 (18), not all Model Fs use all of the available strobes
  139. // The single row ribbon connector Model Fs only have a max of 16 strobes
  140. #define KISHSAVER_STROBE
  141. //#define KISHSAVER_OLD_STROBE
  142. //#define TERMINAL_6110668_OLD_STROBE
  143. //#define UNSAVER_OLD_STROBE
  144. #ifdef KISHSAVER_OLD_STROBE
  145. total_strobes = 9;
  146. strobe_map[0] = 2; // Kishsaver doesn't use strobe 0 and 1
  147. strobe_map[1] = 3;
  148. strobe_map[2] = 4;
  149. strobe_map[3] = 5;
  150. strobe_map[4] = 6;
  151. strobe_map[5] = 7;
  152. strobe_map[6] = 8;
  153. strobe_map[7] = 9;
  154. strobe_map[8] = 15; // Test point strobe (3 test points, sense 1, 4, 5)
  155. #elif defined(KISHSAVER_STROBE)
  156. total_strobes = 9;
  157. strobe_map[0] = 15; // Kishsaver doesn't use strobe 0 and 1
  158. strobe_map[1] = 14;
  159. strobe_map[2] = 13;
  160. strobe_map[3] = 12;
  161. strobe_map[4] = 11;
  162. strobe_map[5] = 10;
  163. strobe_map[6] = 9;
  164. strobe_map[7] = 8;
  165. strobe_map[8] = 2; // Test point strobe (3 test points, sense 1, 4, 5)
  166. #elif defined(TERMINAL_6110668_OLD_STROBE)
  167. total_strobes = 16;
  168. strobe_map[0] = 0;
  169. strobe_map[1] = 1;
  170. strobe_map[2] = 2;
  171. strobe_map[3] = 3;
  172. strobe_map[4] = 4;
  173. strobe_map[5] = 5;
  174. strobe_map[6] = 6;
  175. strobe_map[7] = 7;
  176. strobe_map[8] = 8;
  177. strobe_map[9] = 9;
  178. strobe_map[10] = 10;
  179. strobe_map[11] = 11;
  180. strobe_map[12] = 12;
  181. strobe_map[13] = 13;
  182. strobe_map[14] = 14;
  183. strobe_map[15] = 15;
  184. #elif defined(UNSAVER_OLD_STROBE)
  185. total_strobes = 14;
  186. strobe_map[0] = 0;
  187. strobe_map[1] = 1;
  188. strobe_map[2] = 2;
  189. strobe_map[3] = 3;
  190. strobe_map[4] = 4;
  191. strobe_map[5] = 5;
  192. strobe_map[6] = 6;
  193. strobe_map[7] = 7;
  194. strobe_map[8] = 8;
  195. strobe_map[9] = 9;
  196. strobe_map[10] = 10;
  197. strobe_map[11] = 11;
  198. strobe_map[12] = 12;
  199. strobe_map[13] = 13;
  200. #else
  201. // Strobe detection
  202. // TODO
  203. #endif
  204. // TODO all this code should probably be in Scan_resetKeyboard
  205. for ( int i = 0; i < total_strobes; ++i)
  206. {
  207. cur_keymap[i] = 0;
  208. }
  209. // Reset debounce table
  210. for ( int i = 0; i < KEY_COUNT; ++i )
  211. {
  212. keys_debounce[i] = 0;
  213. }
  214. // Warm things up a bit before we start collecting data, taking real samples.
  215. for ( uint8_t i = 0; i < total_strobes; ++i )
  216. {
  217. sampleColumn( strobe_map[i] );
  218. }
  219. // Reset the keyboard before scanning, we might be in a wierd state
  220. // Also sets the KeyIndex_BufferUsed to 0
  221. scan_resetKeyboard();
  222. }
  223. // Main Detection Loop
  224. // This is where the important stuff happens
  225. inline uint8_t Scan_loop()
  226. {
  227. capsense_scan();
  228. // Error case, should not occur in normal operation
  229. if ( error )
  230. {
  231. erro_msg("Problem detected... ");
  232. // Keymap scan debug
  233. for ( uint8_t i = 0; i < total_strobes; ++i )
  234. {
  235. printHex(cur_keymap[strobe_map[i]]);
  236. print(" ");
  237. }
  238. print(" : ");
  239. printHex(error);
  240. error = 0;
  241. print(" : ");
  242. printHex(error_data);
  243. error_data = 0;
  244. // Display keymaps and other debug information if warmup completede
  245. if ( boot_count >= WARMUP_LOOPS )
  246. {
  247. dump();
  248. }
  249. }
  250. // Return non-zero if macro and USB processing should be delayed
  251. // Macro processing will always run if returning 0
  252. // USB processing only happens once the USB send timer expires, if it has not, Scan_loop will be called
  253. // after the macro processing has been completed
  254. return 0;
  255. }
  256. // Signal KeyIndex_Buffer that it has been properly read
  257. // NOTE: Only really required for implementing "tricks" in converters for odd protocols
  258. void Scan_finishedWithBuffer( uint8_t sentKeys )
  259. {
  260. // Convenient place to clear the KeyIndex_Buffer
  261. KeyIndex_BufferUsed = 0;
  262. return;
  263. }
  264. // Signal KeyIndex_Buffer that it has been properly read and sent out by the USB module
  265. // NOTE: Only really required for implementing "tricks" in converters for odd protocols
  266. void Scan_finishedWithUSBBuffer( uint8_t sentKeys )
  267. {
  268. return;
  269. }
  270. inline void capsense_scan()
  271. {
  272. // Accumulated average used for the next scan
  273. uint32_t cur_full_avg = 0;
  274. uint32_t cur_high_avg = 0;
  275. // Reset average counters
  276. low_avg = 0;
  277. low_count = 0;
  278. high_count = 0;
  279. // Scan each of the mapped strobes in the matrix
  280. for ( uint8_t strober = 0; strober < total_strobes; ++strober )
  281. {
  282. uint8_t map_strobe = strobe_map[strober];
  283. uint8_t tries = 1;
  284. while ( tries++ && sampleColumn( map_strobe ) ) { tries &= 0x7; } // don't waste this one just because the last one was poop.
  285. // Only process sense data if warmup is finished
  286. if ( boot_count >= WARMUP_LOOPS )
  287. {
  288. column = testColumn( map_strobe );
  289. idle |= column; // if column has any pressed keys, then we are not idle.
  290. // TODO Is this needed anymore? Really only helps debug -HaaTa
  291. if( column != cur_keymap[map_strobe] && ( boot_count >= WARMUP_LOOPS ) )
  292. {
  293. cur_keymap[map_strobe] = column;
  294. keymap_change = 1;
  295. }
  296. idle |= keymap_change; // if any keys have changed inc. released, then we are not idle.
  297. }
  298. if ( error == 0x50 )
  299. {
  300. error_data |= (((uint16_t)map_strobe) << 12);
  301. }
  302. uint8_t strobe_line = map_strobe << MUXES_COUNT_XSHIFT;
  303. for ( int i = 0; i < MUXES_COUNT; ++i )
  304. {
  305. // discard sketchy low bit, and meaningless high bits.
  306. uint8_t sample = samples[i] >> 1;
  307. full_samples[strobe_line + i] = sample;
  308. keys_averages_acc[strobe_line + i] += sample;
  309. }
  310. // Accumulate 3 total averages (used for determining starting average during warmup)
  311. // full_avg - Average of all sampled lines on the previous scan set
  312. // cur_full_avg - Average of all sampled lines for this scan set
  313. // high_avg - Average of all sampled lines above full_avg on the previous scan set
  314. // cur_high_avg - Average of all sampled lines above full_avg
  315. // low_avg - Average of all sampled lines below or equal to full_avg
  316. if ( boot_count < WARMUP_LOOPS )
  317. {
  318. for ( uint8_t i = 0; i < MUXES_COUNT; ++i )
  319. {
  320. uint8_t sample = samples[i] >> 1;
  321. // Sample is high, add it to high avg
  322. if ( sample > full_avg )
  323. {
  324. high_count++;
  325. cur_high_avg += sample;
  326. }
  327. // Sample is low, add it to low avg
  328. else
  329. {
  330. low_count++;
  331. low_avg += sample;
  332. }
  333. // If sample is higher than previous high_avg, then mark as "problem key"
  334. keys_problem[strobe_line + i] = sample > high_avg ? sample : 0;
  335. // Prepare for next average
  336. cur_full_avg += sample;
  337. }
  338. }
  339. } // for strober
  340. // Update total sense average (only during warm-up)
  341. if ( boot_count < WARMUP_LOOPS )
  342. {
  343. full_avg = cur_full_avg / (total_strobes * MUXES_COUNT);
  344. high_avg = cur_high_avg / high_count;
  345. low_avg /= low_count;
  346. // Update the base average value using the low_avg (best chance of not ignoring a keypress)
  347. for ( int i = 0; i < KEY_COUNT; ++i )
  348. {
  349. keys_averages[i] = low_avg;
  350. keys_averages_acc[i] = low_avg;
  351. }
  352. }
  353. #ifdef VERIFY_TEST_PAD
  354. // verify test key is not down.
  355. if ( ( cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK ) )
  356. {
  357. error = 0x05;
  358. error_data = cur_keymap[TEST_KEY_STROBE] << 8;
  359. error_data += full_samples[TEST_KEY_STROBE * 8];
  360. }
  361. #endif
  362. /** aggregate if booting, or if idle;
  363. * else, if not booting, check for dirty USB.
  364. * */
  365. idle_count++;
  366. idle_count &= IDLE_COUNT_MASK;
  367. // Warm up voltage references
  368. if ( boot_count < WARMUP_LOOPS )
  369. {
  370. boot_count++;
  371. switch ( boot_count )
  372. {
  373. // First loop
  374. case 1:
  375. // Show msg at first iteration only
  376. info_msg("Warming up the voltage references");
  377. break;
  378. // Middle iterations
  379. case 300:
  380. case 600:
  381. case 900:
  382. case 1200:
  383. print(".");
  384. break;
  385. // Last loop
  386. case WARMUP_STOP:
  387. print("\n");
  388. info_msg("Warmup finished using ");
  389. printInt16( WARMUP_LOOPS );
  390. print(" iterations\n");
  391. // Display the final calculated averages of all the sensed strobes
  392. info_msg("Full average (");
  393. printInt8( total_strobes * MUXES_COUNT );
  394. print("): ");
  395. printHex( full_avg );
  396. print(" High average (");
  397. printInt8( high_count );
  398. print("): ");
  399. printHex( high_avg );
  400. print(" Low average (");
  401. printInt8( low_count );
  402. print("): ");
  403. printHex( low_avg );
  404. print("\n");
  405. // Display problem keys, and the sense value at the time
  406. for ( uint8_t key = 0; key < KEY_COUNT; key++ )
  407. {
  408. if ( keys_problem[key] )
  409. {
  410. warn_msg("Problem key detected: ");
  411. printHex( key );
  412. print(" (");
  413. printHex( keys_problem[key] );
  414. print(")\n");
  415. }
  416. }
  417. info_print("If problem keys were detected, and were being held down, they will be reset as soon as let go");
  418. break;
  419. }
  420. }
  421. else
  422. {
  423. // Reset accumulators and idle flag/counter
  424. if ( keymap_change )
  425. {
  426. for ( uint8_t c = 0; c < KEY_COUNT; ++c ) { keys_averages_acc[c] = 0; }
  427. idle_count = 0;
  428. idle = 0;
  429. keymap_change = 0;
  430. }
  431. if ( !idle_count )
  432. {
  433. if( idle )
  434. {
  435. // aggregate
  436. for ( uint8_t i = 0; i < KEY_COUNT; ++i )
  437. {
  438. uint16_t acc = keys_averages_acc[i] >> IDLE_COUNT_SHIFT;
  439. uint32_t av = keys_averages[i];
  440. av = (av << KEYS_AVERAGES_MIX_SHIFT) - av + acc;
  441. av >>= KEYS_AVERAGES_MIX_SHIFT;
  442. keys_averages[i] = av;
  443. keys_averages_acc[i] = 0;
  444. }
  445. }
  446. if ( boot_count >= WARMUP_LOOPS )
  447. {
  448. dump();
  449. }
  450. }
  451. }
  452. }
  453. void setup_ADC()
  454. {
  455. // disable adc digital pins.
  456. DIDR1 |= (1 << AIN0D) | (1<<AIN1D); // set disable on pins 1,0.
  457. DDRF = 0x0;
  458. PORTF = 0x0;
  459. uint8_t mux = 0 & 0x1f; // 0 == first. // 0x1e = 1.1V ref.
  460. // 0 = external aref 1,1 = 2.56V internal ref
  461. uint8_t aref = ((1 << REFS1) | (1 << REFS0)) & ((1 << REFS1) | (1 << REFS0));
  462. uint8_t adate = (1 << ADATE) & (1 << ADATE); // trigger enable
  463. uint8_t trig = 0 & ((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2)); // 0 = free running
  464. // ps2, ps1 := /64 ( 2^6 ) ps2 := /16 (2^4), ps1 := 4, ps0 :=2, PS1,PS0 := 8 (2^8)
  465. uint8_t prescale = ( ((PRESCALE) << PRESCALE_SHIFT) & PRESCALE_MASK ); // 001 == 2^1 == 2
  466. uint8_t hispeed = (1 << ADHSM);
  467. uint8_t en_mux = (1 << ACME);
  468. ADCSRA = (1 << ADEN) | prescale; // ADC enable
  469. // select ref.
  470. //ADMUX |= ((1 << REFS1) | (1 << REFS0)); // 2.56 V internal.
  471. //ADMUX |= ((1 << REFS0) ); // Vcc with external cap.
  472. //ADMUX &= ~((1 << REFS1) | (1 << REFS0)); // 0,0 : aref.
  473. ADMUX = aref | mux | ADLAR_BITS;
  474. // set free-running
  475. ADCSRA |= adate; // trigger enable
  476. ADCSRB = en_mux | hispeed | trig | (ADCSRB & ~((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2))); // trigger select free running
  477. ADCSRA |= (1 << ADEN); // ADC enable
  478. ADCSRA |= (1 << ADSC); // start conversions q
  479. }
  480. void recovery( uint8_t on )
  481. {
  482. DDRB |= (1 << RECOVERY_CONTROL);
  483. PORTB &= ~(1 << RECOVERY_SINK); // SINK always zero
  484. DDRB &= ~(1 << RECOVERY_SOURCE); // SOURCE high imp
  485. if ( on )
  486. {
  487. // set strobes to sink to gnd.
  488. DDRC |= C_MASK;
  489. DDRD |= D_MASK;
  490. DDRE |= E_MASK;
  491. PORTC &= ~C_MASK;
  492. PORTD &= ~D_MASK;
  493. PORTE &= ~E_MASK;
  494. DDRB |= (1 << RECOVERY_SINK); // SINK pull
  495. PORTB |= (1 << RECOVERY_CONTROL);
  496. PORTB |= (1 << RECOVERY_SOURCE); // SOURCE high
  497. DDRB |= (1 << RECOVERY_SOURCE);
  498. }
  499. else
  500. {
  501. PORTB &= ~(1 << RECOVERY_CONTROL);
  502. DDRB &= ~(1 << RECOVERY_SOURCE);
  503. PORTB &= ~(1 << RECOVERY_SOURCE); // SOURCE low
  504. DDRB &= ~(1 << RECOVERY_SINK); // SINK high-imp
  505. }
  506. }
  507. void hold_sample( uint8_t on )
  508. {
  509. if ( !on )
  510. {
  511. PORTB |= (1 << SAMPLE_CONTROL);
  512. DDRB |= (1 << SAMPLE_CONTROL);
  513. }
  514. else
  515. {
  516. DDRB |= (1 << SAMPLE_CONTROL);
  517. PORTB &= ~(1 << SAMPLE_CONTROL);
  518. }
  519. }
  520. void strobe_w( uint8_t strobe_num )
  521. {
  522. PORTC &= ~(C_MASK);
  523. PORTD &= ~(D_MASK);
  524. PORTE &= ~(E_MASK);
  525. // Strobe table
  526. // Not all strobes are used depending on which are detected
  527. switch ( strobe_num )
  528. {
  529. case 0: PORTD |= (1 << 0); break;
  530. case 1: PORTD |= (1 << 1); break;
  531. case 2: PORTD |= (1 << 2); break;
  532. case 3: PORTD |= (1 << 3); break;
  533. case 4: PORTD |= (1 << 4); break;
  534. case 5: PORTD |= (1 << 5); break;
  535. case 6: PORTD |= (1 << 6); break;
  536. case 7: PORTD |= (1 << 7); break;
  537. case 8: PORTE |= (1 << 0); break;
  538. case 9: PORTE |= (1 << 1); break;
  539. case 10: PORTC |= (1 << 0); break;
  540. case 11: PORTC |= (1 << 1); break;
  541. case 12: PORTC |= (1 << 2); break;
  542. case 13: PORTC |= (1 << 3); break;
  543. case 14: PORTC |= (1 << 4); break;
  544. case 15: PORTC |= (1 << 5); break;
  545. case 16: PORTC |= (1 << 6); break;
  546. case 17: PORTC |= (1 << 7); break;
  547. default:
  548. break;
  549. }
  550. }
  551. inline uint16_t getADC(void)
  552. {
  553. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  554. //wait for last read to complete.
  555. while ( !( ADCSRA & (1 << ADIF) ) );
  556. return ADC; // return sample
  557. }
  558. int sampleColumn_8x( uint8_t column, uint16_t * buffer )
  559. {
  560. // ensure all probe lines are driven low, and chill for recovery delay.
  561. ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
  562. PORTC &= ~C_MASK;
  563. PORTD &= ~D_MASK;
  564. PORTE &= ~E_MASK;
  565. PORTF = 0;
  566. DDRF = 0;
  567. recovery( OFF );
  568. strobe_w( column );
  569. hold_sample( OFF );
  570. SET_FULL_MUX( 0 );
  571. // Allow strobes to settle
  572. for ( uint8_t i = 0; i < STROBE_SETTLE; ++i ) { getADC(); }
  573. hold_sample( ON );
  574. uint8_t mux = 0;
  575. SET_FULL_MUX( mux );
  576. getADC(); // throw away; unknown mux.
  577. do {
  578. SET_FULL_MUX( mux + 1 ); // our *next* sample will use this
  579. // retrieve current read.
  580. buffer[mux] = getADC();
  581. mux++;
  582. } while ( mux < 8 );
  583. hold_sample( OFF );
  584. recovery( ON );
  585. // turn off adc.
  586. ADCSRA &= ~(1 << ADEN);
  587. // pull all columns' strobe-lines low.
  588. DDRC |= C_MASK;
  589. DDRD |= D_MASK;
  590. DDRE |= E_MASK;
  591. PORTC &= ~C_MASK;
  592. PORTD &= ~D_MASK;
  593. PORTE &= ~E_MASK;
  594. return 0;
  595. }
  596. int sampleColumn( uint8_t column )
  597. {
  598. int rval = 0;
  599. rval = sampleColumn_8x( column, samples );
  600. return rval;
  601. }
  602. uint8_t testColumn( uint8_t strobe )
  603. {
  604. uint16_t db_delta = 0;
  605. uint8_t db_sample = 0;
  606. uint16_t db_threshold = 0;
  607. uint8_t column = 0;
  608. uint8_t bit = 1;
  609. for ( uint8_t mux = 0; mux < MUXES_COUNT; ++mux )
  610. {
  611. uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + mux];
  612. uint8_t key = (strobe << MUXES_COUNT_XSHIFT) + mux;
  613. // Check if this is a bad key (e.g. test point, or non-existent key)
  614. if ( keys_problem[key] )
  615. {
  616. // If the sample value of the problem key goes below full_avg (overall initial average)
  617. // re-enable the key
  618. if ( (db_sample = samples[mux] >> 1) < full_avg )
  619. {
  620. info_msg("Re-enabling problem key: ");
  621. printHex( key );
  622. print("\n");
  623. keys_problem[key] = 0;
  624. }
  625. // Otherwise, don't waste any more cycles processing the problem key
  626. else
  627. {
  628. continue;
  629. }
  630. }
  631. // Keypress detected
  632. // db_sample (uint8_t), discard meaningless high bit, and garbage low bit
  633. if ( (db_sample = samples[mux] >> 1) > (db_threshold = threshold) + (db_delta = delta) )
  634. {
  635. column |= bit;
  636. // Only register keypresses once the warmup is complete, or not enough debounce info
  637. if ( keys_debounce[key] <= DEBOUNCE_THRESHOLD )
  638. {
  639. // Add to the Macro processing buffer if debounce criteria met
  640. // Automatically handles converting to a USB code and sending off to the PC
  641. if ( keys_debounce[key] == DEBOUNCE_THRESHOLD )
  642. {
  643. //#define KEYSCAN_DEBOUNCE_DEBUG
  644. #ifdef KEYSCAN_DEBOUNCE_DEBUG
  645. // Debug message
  646. print("0x");
  647. printHex_op( key, 2 );
  648. print(" ");
  649. #endif
  650. // Only add the key to the buffer once
  651. // NOTE: Buffer can easily handle multiple adds, just more efficient
  652. // and nicer debug messages :P
  653. //Macro_bufferAdd( key );
  654. }
  655. keys_debounce[key]++;
  656. #define KEYSCAN_THRESHOLD_DEBUG
  657. #ifdef KEYSCAN_THRESHOLD_DEBUG
  658. // Debug message
  659. // <key> [<strobe>:<mux>] : <sense val> : <delta + threshold> : <margin>
  660. dbug_msg("0x");
  661. printHex_op( key, 2 );
  662. print(" [");
  663. printInt8( strobe );
  664. print(":");
  665. printInt8( mux );
  666. print("] : ");
  667. printHex( db_sample ); // Sense
  668. print(" : ");
  669. printHex( db_threshold );
  670. print("+");
  671. printHex( db_delta );
  672. print("=");
  673. printHex( db_threshold + db_delta ); // Sense compare
  674. print(" : ");
  675. printHex( db_sample - ( db_threshold + db_delta ) ); // Margin
  676. print("\n");
  677. #endif
  678. }
  679. }
  680. // Clear debounce entry if no keypress detected
  681. else
  682. {
  683. // If the key was previously pressed, remove from the buffer
  684. for ( uint8_t c = 0; c < KeyIndex_BufferUsed; c++ )
  685. {
  686. // Key to release found
  687. if ( KeyIndex_Buffer[c] == key )
  688. {
  689. // Shift keys from c position
  690. for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
  691. KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
  692. // Decrement Buffer
  693. KeyIndex_BufferUsed--;
  694. break;
  695. }
  696. }
  697. // Clear debounce entry
  698. keys_debounce[key] = 0;
  699. }
  700. bit <<= 1;
  701. }
  702. return column;
  703. }
  704. void dump(void) {
  705. #ifdef DEBUG_FULL_SAMPLES_AVERAGES
  706. // we don't want to debug-out during the measurements.
  707. if ( !dump_count )
  708. {
  709. // Averages currently set per key
  710. for ( int i = 0; i < KEY_COUNT; ++i )
  711. {
  712. if ( !(i & 0x0f) )
  713. {
  714. print("\n");
  715. }
  716. else if ( !(i & 0x07) )
  717. {
  718. print(" ");
  719. }
  720. print(" ");
  721. printHex( keys_averages[i] );
  722. }
  723. print("\n");
  724. // Previously read full ADC scans?
  725. for ( int i = 0; i< KEY_COUNT; ++i)
  726. {
  727. if ( !(i & 0x0f) )
  728. {
  729. print("\n");
  730. }
  731. else if ( !(i & 0x07) )
  732. {
  733. print(" ");
  734. }
  735. print(" ");
  736. printHex(full_samples[i]);
  737. }
  738. }
  739. #endif
  740. #ifdef DEBUG_STROBE_SAMPLES_AVERAGES
  741. // Per strobe information
  742. uint8_t cur_strober = ze_strober;
  743. print("\n");
  744. printHex(cur_strober);
  745. // Previously read ADC scans on current strobe
  746. print(" :");
  747. for ( uint8_t i = 0; i < MUXES_COUNT; ++i )
  748. {
  749. print(" ");
  750. printHex(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
  751. }
  752. // Averages current set on current strobe
  753. print(" :");
  754. for ( uint8_t i = 0; i < MUXES_COUNT; ++i )
  755. {
  756. print(" ");
  757. printHex(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
  758. }
  759. #endif
  760. #ifdef DEBUG_USB_KEYMAP
  761. print("\n ");
  762. // Current keymap values
  763. for ( uint8_t i = 0; i < total_strobes; ++i )
  764. {
  765. printHex(cur_keymap[i]);
  766. print(" ");
  767. }
  768. #endif
  769. ze_strober++;
  770. ze_strober &= 0xf;
  771. dump_count++;
  772. dump_count &= 0x0f;
  773. }