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.

10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  1. /* Copyright (C) 2011-2013 by Joseph Makuch ([email protected])
  2. * Additions by Jacob Alexander (2013-2014) ([email protected])
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. * THE SOFTWARE.
  21. */
  22. // ----- Includes -----
  23. // Compiler Includes
  24. #include <Lib/ScanLib.h>
  25. // Project Includes
  26. #include <cli.h>
  27. #include <led.h>
  28. #include <macro.h>
  29. #include <print.h>
  30. // Local Includes
  31. #include "scan_loop.h"
  32. // ----- Defines -----
  33. // TODO dfj defines...needs commenting and maybe some cleaning...
  34. #define MAX_PRESS_DELTA_MV 450 // As measured from the Teensy ADC pin
  35. #define THRESHOLD_MV (MAX_PRESS_DELTA_MV >> 1)
  36. //(2560 / (0x3ff/2)) ~= 5
  37. #define MV_PER_ADC 5
  38. #define THRESHOLD (THRESHOLD_MV / MV_PER_ADC)
  39. #define STROBE_SETTLE 1
  40. #define ADHSM 7
  41. // Right justification of ADLAR
  42. #define ADLAR_BITS 0
  43. // full muxmask
  44. #define FULL_MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4))
  45. // F0-f7 pins only muxmask.
  46. #define MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2))
  47. // Strobe Masks
  48. #define D_MASK (0xff)
  49. #define E_MASK (0x03)
  50. #define C_MASK (0xff)
  51. // set ADC clock prescale
  52. #define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2))
  53. #define PRESCALE_SHIFT (ADPS0)
  54. #define PRESCALE 3
  55. // Max number of strobes supported by the hardware
  56. // Strobe lines are detected at startup, extra strobes cause anomalies like phantom keypresses
  57. #define MAX_STROBES 18
  58. // Number of consecutive samples required to pass debounce
  59. #define DEBOUNCE_THRESHOLD 5
  60. // Scans to remain idle after all keys were release before starting averaging
  61. // XXX So this makes the initial keypresses fast,
  62. // but it's still possible to lose a keypress if you press at the wrong time -HaaTa
  63. #define KEY_IDLE_SCANS 30000
  64. // Total number of muxes/sense lines available
  65. #define MUXES_COUNT 8
  66. #define MUXES_COUNT_XSHIFT 3
  67. // Number of warm-up loops before starting to scan keys
  68. #define WARMUP_LOOPS ( 1024 )
  69. #define WARMUP_STOP (WARMUP_LOOPS - 1)
  70. #define SAMPLE_CONTROL 3
  71. #define KEY_COUNT ((MAX_STROBES) * (MUXES_COUNT))
  72. #define RECOVERY_CONTROL 1
  73. #define RECOVERY_SOURCE 0
  74. #define RECOVERY_SINK 2
  75. #define ON 1
  76. #define OFF 0
  77. // mix in 1/4 of the current average to the running average. -> (@mux_mix = 2)
  78. #define MUX_MIX 2
  79. #define IDLE_COUNT_SHIFT 8
  80. // av = (av << shift) - av + sample; av >>= shift
  81. // e.g. 1 -> (av + sample) / 2 simple average of new and old
  82. // 2 -> (3 * av + sample) / 4 i.e. 3:1 mix of old to new.
  83. // 3 -> (7 * av + sample) / 8 i.e. 7:1 mix of old to new.
  84. #define KEYS_AVERAGES_MIX_SHIFT 3
  85. // ----- Macros -----
  86. // Select mux
  87. #define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK))))
  88. // ----- Function Declarations -----
  89. // CLI Functions
  90. void cliFunc_avgDebug ( char* args );
  91. void cliFunc_echo ( char* args );
  92. void cliFunc_keyDebug ( char* args );
  93. void cliFunc_pressDebug ( char* args );
  94. void cliFunc_problemKeys( char* args );
  95. void cliFunc_senseDebug ( char* args );
  96. // Debug Functions
  97. void dumpSenseTable();
  98. // High-level Capsense Functions
  99. void setup_ADC();
  100. void capsense_scan();
  101. // Capsense Sense Functions
  102. void testColumn ( uint8_t strobe );
  103. void sampleColumn( uint8_t column );
  104. // Low-level Capsense Functions
  105. void strobe_w( uint8_t strobe_num );
  106. void recovery( uint8_t on );
  107. // ----- Variables -----
  108. // Scan Module command dictionary
  109. CLIDict_Entry( echo, "Example command, echos the arguments." );
  110. CLIDict_Entry( avgDebug, "Enables/Disables averaging results." NL "\t\tDisplays each average, starting from Key 0x00, ignoring 0 valued averages." );
  111. CLIDict_Entry( keyDebug, "Enables/Disables long debug for each keypress." NL "\t\tkeycode - [strobe:mux] : sense val : threshold+delta=total : margin" );
  112. CLIDict_Entry( pressDebug, "Enables/Disables short debug for each keypress." );
  113. CLIDict_Entry( problemKeys, "Display current list of problem keys," );
  114. CLIDict_Entry( senseDebug, "Prints out the current sense table N times." NL "\t\tsense:max sense:delta" );
  115. CLIDict_Def( scanCLIDict, "DPH Module Commands" ) = {
  116. CLIDict_Item( echo ),
  117. CLIDict_Item( avgDebug ),
  118. CLIDict_Item( keyDebug ),
  119. CLIDict_Item( pressDebug ),
  120. CLIDict_Item( problemKeys ),
  121. CLIDict_Item( senseDebug ),
  122. { 0, 0, 0 } // Null entry for dictionary end
  123. };
  124. // CLI Control Variables
  125. uint8_t enableAvgDebug = 0;
  126. uint8_t enableKeyDebug = 0;
  127. uint8_t enablePressDebug = 0;
  128. uint8_t senseDebugCount = 3; // In order to get boot-time oddities
  129. // Variables used to calculate the starting sense value (averaging)
  130. uint32_t full_avg = 0;
  131. uint32_t high_avg = 0;
  132. uint32_t low_avg = 0;
  133. uint8_t high_count = 0;
  134. uint8_t low_count = 0;
  135. uint16_t samples[MAX_STROBES][MUXES_COUNT]; // Overall table of cap sense ADC values
  136. uint16_t sampleMax[MAX_STROBES][MUXES_COUNT]; // Records the max seen ADC value
  137. uint8_t key_activity = 0; // Increments for each detected key per each full scan of the keyboard, it is reset before each full scan
  138. uint16_t key_idle = 0; // Defines how scans after all keys were released before starting averaging again
  139. uint8_t key_release = 0; // Indicates if going from key press state to release state (some keys pressed to no keys pressed)
  140. uint16_t threshold = THRESHOLD;
  141. uint16_t keys_averages_acc[KEY_COUNT];
  142. uint16_t keys_averages [KEY_COUNT];
  143. uint8_t keys_debounce [KEY_COUNT]; // Contains debounce statistics
  144. uint8_t keys_problem [KEY_COUNT]; // Marks keys that should be ignored (determined by averaging at startup)
  145. // TODO: change this to 'booting', then count down.
  146. uint16_t boot_count = 0;
  147. uint8_t total_strobes = MAX_STROBES;
  148. uint8_t strobe_map[MAX_STROBES];
  149. // ----- Functions -----
  150. // Initial setup for cap sense controller
  151. inline void Scan_setup()
  152. {
  153. // Register Scan CLI dictionary
  154. CLI_registerDictionary( scanCLIDict, scanCLIDictName );
  155. // Scan for active strobes
  156. // NOTE1: On IBM PCBs, each strobe line that is *NOT* used is connected to GND.
  157. // This means, the strobe GPIO can be set to Tri-State pull-up to detect which strobe lines are not used.
  158. // NOTE2: This will *NOT* detect floating strobes.
  159. // NOTE3: Rev 0.4, the strobe numbers are reversed, so D0 is actually strobe 0 and C7 is strobe 17
  160. info_msg("Detecting Strobes...");
  161. DDRC = 0;
  162. PORTC = C_MASK;
  163. DDRD = 0;
  164. PORTD = D_MASK;
  165. DDRE = 0;
  166. PORTE = E_MASK;
  167. // Initially there are 0 strobes
  168. total_strobes = 0;
  169. // Iterate over each the strobes
  170. for ( uint8_t strobe = 0; strobe < MAX_STROBES; strobe++ )
  171. {
  172. uint8_t detected = 0;
  173. // If PIN is high, then strobe is *NOT* connected to GND and may be a strobe
  174. switch ( strobe )
  175. {
  176. // Strobe Mappings
  177. // Rev Rev
  178. // 0.2 0.4
  179. #ifndef REV0_4_DEBUG // XXX These pins should be reworked, and connect to GND on Rev 0.4
  180. case 0: // D0 0 n/c
  181. case 1: // D1 1 n/c
  182. #endif
  183. case 2: // D2 2 15
  184. case 3: // D3 3 14
  185. case 4: // D4 4 13
  186. case 5: // D5 5 12
  187. case 6: // D6 6 11
  188. case 7: // D7 7 10
  189. detected = PIND & (1 << strobe);
  190. break;
  191. case 8: // E0 8 9
  192. case 9: // E1 9 8
  193. detected = PINE & (1 << (strobe - 8));
  194. break;
  195. case 10: // C0 10 7
  196. case 11: // C1 11 6
  197. case 12: // C2 12 5
  198. case 13: // C3 13 4
  199. case 14: // C4 14 3
  200. case 15: // C5 15 2
  201. #ifndef REV0_2_DEBUG // XXX If not using the 18 pin connector on Rev 0.2, rework these pins to GND
  202. case 16: // C6 16 1
  203. case 17: // C7 17 0
  204. #endif
  205. detected = PINC & (1 << (strobe - 10));
  206. break;
  207. default:
  208. break;
  209. }
  210. // Potential strobe line detected
  211. if ( detected )
  212. {
  213. strobe_map[total_strobes] = strobe;
  214. total_strobes++;
  215. }
  216. }
  217. printInt8( total_strobes );
  218. print( " strobes found." NL );
  219. // Setup Pins for Strobing
  220. DDRC = C_MASK;
  221. PORTC = 0;
  222. DDRD = D_MASK;
  223. PORTD = 0;
  224. DDRE = E_MASK;
  225. PORTE = 0 ;
  226. // Initialize ADC
  227. setup_ADC();
  228. // Reset debounce table
  229. for ( int i = 0; i < KEY_COUNT; ++i )
  230. {
  231. keys_debounce[i] = 0;
  232. }
  233. // Warm things up a bit before we start collecting data, taking real samples.
  234. for ( uint8_t i = 0; i < total_strobes; ++i )
  235. {
  236. sampleColumn( strobe_map[i] );
  237. }
  238. }
  239. // Main Detection Loop
  240. // This is where the important stuff happens
  241. inline uint8_t Scan_loop()
  242. {
  243. capsense_scan();
  244. // Return non-zero if macro and USB processing should be delayed
  245. // Macro processing will always run if returning 0
  246. // USB processing only happens once the USB send timer expires, if it has not, Scan_loop will be called
  247. // after the macro processing has been completed
  248. return 0;
  249. }
  250. // Signal from macro module that keys have been processed
  251. // NOTE: Only really required for implementing "tricks" in converters for odd protocols
  252. void Scan_finishedWithMacro( uint8_t sentKeys )
  253. {
  254. return;
  255. }
  256. // Signal from output module that keys have been processed/sent
  257. // NOTE: Only really required for implementing "tricks" in converters for odd protocols
  258. void Scan_finishedWithOutput( uint8_t sentKeys )
  259. {
  260. return;
  261. }
  262. inline void capsense_scan()
  263. {
  264. // Accumulated average used for the next scan
  265. uint32_t cur_full_avg = 0;
  266. uint32_t cur_high_avg = 0;
  267. // Reset average counters
  268. low_avg = 0;
  269. low_count = 0;
  270. high_count = 0;
  271. // Reset key activity, if there is no key activity, averages will accumulate for sense deltas, otherwise they will be reset
  272. key_activity = 0;
  273. // Scan each of the mapped strobes in the matrix
  274. for ( uint8_t strober = 0; strober < total_strobes; ++strober )
  275. {
  276. uint8_t map_strobe = strobe_map[strober];
  277. // Sample the ADCs for the given column/strobe
  278. sampleColumn( map_strobe );
  279. // Only process sense data if warmup is finished
  280. if ( boot_count >= WARMUP_LOOPS )
  281. {
  282. testColumn( map_strobe );
  283. }
  284. uint8_t strobe_line = map_strobe << MUXES_COUNT_XSHIFT;
  285. for ( int mux = 0; mux < MUXES_COUNT; ++mux )
  286. {
  287. // discard sketchy low bit, and meaningless high bits.
  288. uint8_t sample = samples[map_strobe][mux] >> 1;
  289. keys_averages_acc[strobe_line + mux] += sample;
  290. }
  291. // Accumulate 3 total averages (used for determining starting average during warmup)
  292. // full_avg - Average of all sampled lines on the previous scan set
  293. // cur_full_avg - Average of all sampled lines for this scan set
  294. // high_avg - Average of all sampled lines above full_avg on the previous scan set
  295. // cur_high_avg - Average of all sampled lines above full_avg
  296. // low_avg - Average of all sampled lines below or equal to full_avg
  297. if ( boot_count < WARMUP_LOOPS )
  298. {
  299. for ( uint8_t mux = 0; mux < MUXES_COUNT; ++mux )
  300. {
  301. uint8_t sample = samples[map_strobe][mux] >> 1;
  302. // Sample is high, add it to high avg
  303. if ( sample > full_avg )
  304. {
  305. high_count++;
  306. cur_high_avg += sample;
  307. }
  308. // Sample is low, add it to low avg
  309. else
  310. {
  311. low_count++;
  312. low_avg += sample;
  313. }
  314. // If sample is higher than previous high_avg, then mark as "problem key"
  315. // XXX Giving a bit more margin to pass (high_avg vs. high_avg + high_avg - full_avg) -HaaTa
  316. keys_problem[strobe_line + mux] = sample > high_avg + (high_avg - full_avg) ? sample : 0;
  317. // Prepare for next average
  318. cur_full_avg += sample;
  319. }
  320. }
  321. } // for strober
  322. // Update total sense average (only during warm-up)
  323. if ( boot_count < WARMUP_LOOPS )
  324. {
  325. full_avg = cur_full_avg / (total_strobes * MUXES_COUNT);
  326. high_avg = cur_high_avg / high_count;
  327. low_avg /= low_count;
  328. // Update the base average value using the low_avg (best chance of not ignoring a keypress)
  329. for ( int i = 0; i < KEY_COUNT; ++i )
  330. {
  331. keys_averages[i] = low_avg;
  332. keys_averages_acc[i] = low_avg;
  333. }
  334. }
  335. // Warm up voltage references
  336. if ( boot_count < WARMUP_LOOPS )
  337. {
  338. boot_count++;
  339. switch ( boot_count )
  340. {
  341. // First loop
  342. case 1:
  343. // Show msg at first iteration only
  344. info_msg("Warming up the voltage references");
  345. break;
  346. // Middle iterations
  347. case 300:
  348. case 600:
  349. case 900:
  350. case 1200:
  351. print(".");
  352. break;
  353. // Last loop
  354. case WARMUP_STOP:
  355. print( NL );
  356. info_msg("Warmup finished using ");
  357. printInt16( WARMUP_LOOPS );
  358. print(" iterations" NL );
  359. // Display the final calculated averages of all the sensed strobes
  360. info_msg("Full average (");
  361. printInt8( total_strobes * MUXES_COUNT );
  362. print("): ");
  363. printHex( full_avg );
  364. print(" High average (");
  365. printInt8( high_count );
  366. print("): ");
  367. printHex( high_avg );
  368. print(" Low average (");
  369. printInt8( low_count );
  370. print("): ");
  371. printHex( low_avg );
  372. print(" Rejection threshold: ");
  373. printHex( high_avg + (high_avg - full_avg) );
  374. print( NL );
  375. // Display problem keys, and the sense value at the time
  376. for ( uint8_t key = 0; key < KEY_COUNT; key++ )
  377. {
  378. if ( keys_problem[key] )
  379. {
  380. warn_msg("Problem key detected: ");
  381. printHex( key );
  382. print(" (");
  383. printHex( keys_problem[key] );
  384. print(")" NL );
  385. }
  386. }
  387. info_print("If problem keys were detected, and were being held down, they will be reset as soon as let go.");
  388. info_print("Some keys have unusually high sense values, on the first press they should be re-enabled.");
  389. break;
  390. }
  391. }
  392. else
  393. {
  394. // No keypress, accumulate averages
  395. if( !key_activity )
  396. {
  397. // Only start averaging once the idle counter has counted down to 0
  398. if ( key_idle == 0 )
  399. {
  400. // Average Debugging
  401. if ( enableAvgDebug )
  402. {
  403. print("\033[1mAvg\033[0m: ");
  404. }
  405. // aggregate
  406. for ( uint8_t i = 0; i < KEY_COUNT; ++i )
  407. {
  408. uint16_t acc = keys_averages_acc[i];
  409. //uint16_t acc = keys_averages_acc[i] >> IDLE_COUNT_SHIFT; // XXX This fixes things... -HaaTa
  410. uint32_t av = keys_averages[i];
  411. av = (av << KEYS_AVERAGES_MIX_SHIFT) - av + acc;
  412. av >>= KEYS_AVERAGES_MIX_SHIFT;
  413. keys_averages[i] = av;
  414. keys_averages_acc[i] = 0;
  415. // Average Debugging
  416. if ( enableAvgDebug && av > 0 )
  417. {
  418. printHex( av );
  419. print(" ");
  420. }
  421. }
  422. // Average Debugging
  423. if ( enableAvgDebug )
  424. {
  425. print( NL );
  426. }
  427. // No key presses detected, set key_release indicator
  428. key_release = 1;
  429. }
  430. // Otherwise decrement the idle counter
  431. else
  432. {
  433. key_idle--;
  434. }
  435. }
  436. // Keypresses, reset accumulators
  437. else if ( key_release )
  438. {
  439. for ( uint8_t c = 0; c < KEY_COUNT; ++c ) { keys_averages_acc[c] = 0; }
  440. key_release = 0;
  441. }
  442. // If the debugging sense table is non-zero, display
  443. if ( senseDebugCount > 0 )
  444. {
  445. senseDebugCount--;
  446. print( NL );
  447. dumpSenseTable();
  448. }
  449. }
  450. }
  451. void setup_ADC()
  452. {
  453. // disable adc digital pins.
  454. DIDR1 |= (1 << AIN0D) | (1<<AIN1D); // set disable on pins 1,0.
  455. DDRF = 0x0;
  456. PORTF = 0x0;
  457. uint8_t mux = 0 & 0x1f; // 0 == first. // 0x1e = 1.1V ref.
  458. // 0 = external aref 1,1 = 2.56V internal ref
  459. uint8_t aref = ((1 << REFS1) | (1 << REFS0)) & ((1 << REFS1) | (1 << REFS0));
  460. uint8_t adate = (1 << ADATE) & (1 << ADATE); // trigger enable
  461. uint8_t trig = 0 & ((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2)); // 0 = free running
  462. // ps2, ps1 := /64 ( 2^6 ) ps2 := /16 (2^4), ps1 := 4, ps0 :=2, PS1,PS0 := 8 (2^8)
  463. uint8_t prescale = ( ((PRESCALE) << PRESCALE_SHIFT) & PRESCALE_MASK ); // 001 == 2^1 == 2
  464. uint8_t hispeed = (1 << ADHSM);
  465. uint8_t en_mux = (1 << ACME);
  466. ADCSRA = (1 << ADEN) | prescale; // ADC enable
  467. // select ref.
  468. //ADMUX |= ((1 << REFS1) | (1 << REFS0)); // 2.56 V internal.
  469. //ADMUX |= ((1 << REFS0) ); // Vcc with external cap.
  470. //ADMUX &= ~((1 << REFS1) | (1 << REFS0)); // 0,0 : aref.
  471. ADMUX = aref | mux | ADLAR_BITS;
  472. // set free-running
  473. ADCSRA |= adate; // trigger enable
  474. ADCSRB = en_mux | hispeed | trig | (ADCSRB & ~((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2))); // trigger select free running
  475. ADCSRA |= (1 << ADEN); // ADC enable
  476. ADCSRA |= (1 << ADSC); // start conversions q
  477. }
  478. void recovery( uint8_t on )
  479. {
  480. DDRB |= (1 << RECOVERY_CONTROL);
  481. PORTB &= ~(1 << RECOVERY_SINK); // SINK always zero
  482. DDRB &= ~(1 << RECOVERY_SOURCE); // SOURCE high imp
  483. if ( on )
  484. {
  485. // set strobes to sink to gnd.
  486. DDRC |= C_MASK;
  487. DDRD |= D_MASK;
  488. DDRE |= E_MASK;
  489. PORTC &= ~C_MASK;
  490. PORTD &= ~D_MASK;
  491. PORTE &= ~E_MASK;
  492. DDRB |= (1 << RECOVERY_SINK); // SINK pull
  493. PORTB |= (1 << RECOVERY_CONTROL);
  494. PORTB |= (1 << RECOVERY_SOURCE); // SOURCE high
  495. DDRB |= (1 << RECOVERY_SOURCE);
  496. }
  497. else
  498. {
  499. PORTB &= ~(1 << RECOVERY_CONTROL);
  500. DDRB &= ~(1 << RECOVERY_SOURCE);
  501. PORTB &= ~(1 << RECOVERY_SOURCE); // SOURCE low
  502. DDRB &= ~(1 << RECOVERY_SINK); // SINK high-imp
  503. }
  504. }
  505. void hold_sample( uint8_t on )
  506. {
  507. if ( !on )
  508. {
  509. PORTB |= (1 << SAMPLE_CONTROL);
  510. DDRB |= (1 << SAMPLE_CONTROL);
  511. }
  512. else
  513. {
  514. DDRB |= (1 << SAMPLE_CONTROL);
  515. PORTB &= ~(1 << SAMPLE_CONTROL);
  516. }
  517. }
  518. void strobe_w( uint8_t strobe_num )
  519. {
  520. PORTC &= ~(C_MASK);
  521. PORTD &= ~(D_MASK);
  522. PORTE &= ~(E_MASK);
  523. // Strobe table
  524. // Not all strobes are used depending on which are detected
  525. switch ( strobe_num )
  526. {
  527. case 0: PORTD |= (1 << 0); break;
  528. case 1: PORTD |= (1 << 1); break;
  529. case 2: PORTD |= (1 << 2); break;
  530. case 3: PORTD |= (1 << 3); break;
  531. case 4: PORTD |= (1 << 4); break;
  532. case 5: PORTD |= (1 << 5); break;
  533. case 6: PORTD |= (1 << 6); break;
  534. case 7: PORTD |= (1 << 7); break;
  535. case 8: PORTE |= (1 << 0); break;
  536. case 9: PORTE |= (1 << 1); break;
  537. case 10: PORTC |= (1 << 0); break;
  538. case 11: PORTC |= (1 << 1); break;
  539. case 12: PORTC |= (1 << 2); break;
  540. case 13: PORTC |= (1 << 3); break;
  541. case 14: PORTC |= (1 << 4); break;
  542. case 15: PORTC |= (1 << 5); break;
  543. case 16: PORTC |= (1 << 6); break;
  544. case 17: PORTC |= (1 << 7); break;
  545. default:
  546. break;
  547. }
  548. }
  549. inline uint16_t getADC(void)
  550. {
  551. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  552. //wait for last read to complete.
  553. while ( !( ADCSRA & (1 << ADIF) ) );
  554. return ADC; // return sample
  555. }
  556. void sampleColumn( uint8_t column )
  557. {
  558. // ensure all probe lines are driven low, and chill for recovery delay.
  559. ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
  560. PORTC &= ~C_MASK;
  561. PORTD &= ~D_MASK;
  562. PORTE &= ~E_MASK;
  563. PORTF = 0;
  564. DDRF = 0;
  565. recovery( OFF );
  566. strobe_w( column );
  567. hold_sample( OFF );
  568. SET_FULL_MUX( 0 );
  569. // Allow strobes to settle
  570. for ( uint8_t i = 0; i < STROBE_SETTLE; ++i ) { getADC(); }
  571. hold_sample( ON );
  572. uint8_t mux = 0;
  573. SET_FULL_MUX( mux );
  574. getADC(); // throw away; unknown mux.
  575. do {
  576. SET_FULL_MUX( mux + 1 ); // our *next* sample will use this
  577. // retrieve current read.
  578. uint16_t readVal = getADC();
  579. samples[column][mux] = readVal;
  580. // Update max sense sample table
  581. if ( readVal > sampleMax[column][mux] )
  582. {
  583. sampleMax[column][mux] = readVal;
  584. }
  585. mux++;
  586. } while ( mux < 8 );
  587. hold_sample( OFF );
  588. recovery( ON );
  589. // turn off adc.
  590. ADCSRA &= ~(1 << ADEN);
  591. // pull all columns' strobe-lines low.
  592. DDRC |= C_MASK;
  593. DDRD |= D_MASK;
  594. DDRE |= E_MASK;
  595. PORTC &= ~C_MASK;
  596. PORTD &= ~D_MASK;
  597. PORTE &= ~E_MASK;
  598. }
  599. void testColumn( uint8_t strobe )
  600. {
  601. uint16_t db_delta = 0;
  602. uint8_t db_sample = 0;
  603. uint16_t db_threshold = 0;
  604. uint8_t column = 0;
  605. uint8_t bit = 1;
  606. for ( uint8_t mux = 0; mux < MUXES_COUNT; ++mux )
  607. {
  608. uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + mux];
  609. uint8_t key = (strobe << MUXES_COUNT_XSHIFT) + mux;
  610. // Check if this is a bad key (e.g. test point, or non-existent key)
  611. if ( keys_problem[key] )
  612. {
  613. // If the sample value of the problem key goes above initally recorded result + threshold
  614. // re-enable the key
  615. if ( (db_sample = samples[strobe][mux] >> 1) > keys_problem[key] + threshold )
  616. //if ( (db_sample = samples[strobe][mux] >> 1) < high_avg )
  617. {
  618. info_msg("Re-enabling problem key: ");
  619. printHex( key );
  620. print( NL );
  621. keys_problem[key] = 0;
  622. }
  623. // Do not waste any more cycles processing, regardless, a keypress cannot be detected
  624. continue;
  625. }
  626. // Keypress detected
  627. // db_sample (uint8_t), discard meaningless high bit, and garbage low bit
  628. if ( (db_sample = samples[strobe][mux] >> 1) > (db_threshold = threshold) + (db_delta = delta) )
  629. {
  630. column |= bit;
  631. key_activity++; // No longer idle, stop averaging ADC data
  632. key_idle = KEY_IDLE_SCANS; // Reset idle count-down
  633. // Only register keypresses once the warmup is complete, or not enough debounce info
  634. if ( keys_debounce[key] <= DEBOUNCE_THRESHOLD )
  635. {
  636. // Add to the Macro processing buffer if debounce criteria met
  637. // Automatically handles converting to a USB code and sending off to the PC
  638. if ( keys_debounce[key] == DEBOUNCE_THRESHOLD )
  639. {
  640. // Debug message, pressDebug CLI
  641. if ( enablePressDebug )
  642. {
  643. print("0x");
  644. printHex_op( key, 2 );
  645. print(" ");
  646. }
  647. // Initial Keypress
  648. Macro_keyState( key, 0x01 );
  649. }
  650. keys_debounce[key]++;
  651. }
  652. else if ( keys_debounce[key] >= DEBOUNCE_THRESHOLD )
  653. {
  654. // Held Key
  655. Macro_keyState( key, 0x02 );
  656. }
  657. // Long form key debugging
  658. if ( enableKeyDebug )
  659. {
  660. // Debug message
  661. // <key> [<strobe>:<mux>] : <sense val> : <delta + threshold> : <margin>
  662. dbug_msg("");
  663. printHex_op( key, 1 );
  664. print(" [");
  665. printInt8( strobe );
  666. print(":");
  667. printInt8( mux );
  668. print("] : ");
  669. printHex( db_sample ); // Sense
  670. print(" : ");
  671. printHex( db_threshold );
  672. print("+");
  673. printHex( db_delta );
  674. print("=");
  675. printHex( db_threshold + db_delta ); // Sense compare
  676. print(" : ");
  677. printHex( db_sample - ( db_threshold + db_delta ) ); // Margin
  678. print( NL );
  679. }
  680. }
  681. // Clear debounce entry if no keypress detected
  682. else
  683. {
  684. // Release Key
  685. if ( keys_debounce[key] >= DEBOUNCE_THRESHOLD )
  686. {
  687. Macro_keyState( key, 0x03 );
  688. }
  689. // Clear debounce entry
  690. keys_debounce[key] = 0;
  691. }
  692. bit <<= 1;
  693. }
  694. }
  695. void dumpSenseTable()
  696. {
  697. // Initial table alignment, with base threshold used for every key
  698. print("\033[1m");
  699. printHex( threshold );
  700. print("\033[0m ");
  701. // Print out headers first
  702. for ( uint8_t mux = 0; mux < MUXES_COUNT; ++mux )
  703. {
  704. print(" Mux \033[1m");
  705. printInt8( mux );
  706. print("\033[0m ");
  707. }
  708. print( NL );
  709. // Display the full strobe/sense table
  710. for ( uint8_t strober = 0; strober < total_strobes; ++strober )
  711. {
  712. uint8_t strobe = strobe_map[strober];
  713. // Display the strobe
  714. print("Strobe \033[1m");
  715. printHex( strobe );
  716. print("\033[0m ");
  717. // For each mux, display sense:threshold:delta
  718. for ( uint8_t mux = 0; mux < MUXES_COUNT; ++mux )
  719. {
  720. uint8_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + mux];
  721. uint8_t sample = samples[strobe][mux] >> 1;
  722. uint8_t max = sampleMax[strobe][mux] >> 1;
  723. // Indicate if the key is being pressed by displaying green
  724. if ( sample > delta + threshold )
  725. {
  726. print("\033[1;32m");
  727. }
  728. printHex_op( sample, 2 );
  729. print(":");
  730. printHex_op( max, 2 );
  731. print(":");
  732. printHex_op( delta, 2 );
  733. print("\033[0m ");
  734. }
  735. // New line for each strobe
  736. print( NL );
  737. }
  738. }
  739. // ----- CLI Command Functions -----
  740. // XXX Just an example command showing how to parse arguments (more complex than generally needed)
  741. void cliFunc_echo( char* args )
  742. {
  743. char* curArgs;
  744. char* arg1Ptr;
  745. char* arg2Ptr = args;
  746. // Parse args until a \0 is found
  747. while ( 1 )
  748. {
  749. print( NL ); // No \r\n by default after the command is entered
  750. curArgs = arg2Ptr; // Use the previous 2nd arg pointer to separate the next arg from the list
  751. CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
  752. // Stop processing args if no more are found
  753. if ( *arg1Ptr == '\0' )
  754. break;
  755. // Print out the arg
  756. dPrint( arg1Ptr );
  757. }
  758. }
  759. void cliFunc_avgDebug( char* args )
  760. {
  761. print( NL );
  762. // Args ignored, just toggling
  763. if ( enableAvgDebug )
  764. {
  765. info_print("Cap Sense averaging debug disabled.");
  766. enableAvgDebug = 0;
  767. }
  768. else
  769. {
  770. info_print("Cap Sense averaging debug enabled.");
  771. enableAvgDebug = 1;
  772. }
  773. }
  774. void cliFunc_keyDebug( char* args )
  775. {
  776. print( NL );
  777. // Args ignored, just toggling
  778. if ( enableKeyDebug )
  779. {
  780. info_print("Cap Sense key long debug disabled - pre debounce.");
  781. enableKeyDebug = 0;
  782. }
  783. else
  784. {
  785. info_print("Cap Sense key long debug enabled - pre debounce.");
  786. enableKeyDebug = 1;
  787. }
  788. }
  789. void cliFunc_pressDebug( char* args )
  790. {
  791. print( NL );
  792. // Args ignored, just toggling
  793. if ( enablePressDebug )
  794. {
  795. info_print("Cap Sense key debug disabled - post debounce.");
  796. enablePressDebug = 0;
  797. }
  798. else
  799. {
  800. info_print("Cap Sense key debug enabled - post debounce.");
  801. enablePressDebug = 1;
  802. }
  803. }
  804. void cliFunc_problemKeys( char* args )
  805. {
  806. print( NL );
  807. uint8_t count = 0;
  808. // Args ignored, just displaying
  809. // Display problem keys, and the sense value at the time
  810. for ( uint8_t key = 0; key < KEY_COUNT; key++ )
  811. {
  812. if ( keys_problem[key] )
  813. {
  814. if ( count++ == 0 )
  815. {
  816. warn_msg("Problem keys: ");
  817. }
  818. printHex( key );
  819. print(" (");
  820. printHex( keys_problem[key] );
  821. print(") " );
  822. }
  823. }
  824. }
  825. void cliFunc_senseDebug( char* args )
  826. {
  827. // Parse code from argument
  828. // NOTE: Only first argument is used
  829. char* arg1Ptr;
  830. char* arg2Ptr;
  831. CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
  832. // Default to a single print
  833. senseDebugCount = 1;
  834. // If there was an argument, use that instead
  835. if ( *arg1Ptr != '\0' )
  836. {
  837. senseDebugCount = numToInt( arg1Ptr );
  838. }
  839. }