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 25KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123
  1. /* Copyright (C) 2011-2013 by Joseph Makuch
  2. * Additions by Jacob Alexander (2013)
  3. *
  4. * dfj, put whatever license here you want -HaaTa
  5. */
  6. // ----- Includes -----
  7. // Compiler Includes
  8. #include <Lib/ScanLib.h>
  9. // Project Includes
  10. #include <led.h>
  11. #include <print.h>
  12. // Local Includes
  13. #include "scan_loop.h"
  14. // ----- Defines -----
  15. // TODO dfj defines...needs cleaning up and commenting...
  16. #define THRESHOLD 0x0a
  17. #define BUMP_THRESHOLD 0x50
  18. //((THRESHOLD) * 3)
  19. #define BUMP_REST_US 1200
  20. #define HYST 1
  21. #define HYST_T 0x10
  22. #define TEST_KEY_STROBE (0x05)
  23. #define TEST_KEY_MASK (1 << 0)
  24. #define ADHSM 7
  25. /** Whether to use all of D and C, vs using E0, E1 instead of D6, D7,
  26. * or alternately all of D, and E0,E1 and C0,..5 */
  27. //#define ALL_D_C
  28. //#define SHORT_D
  29. #define SHORT_C
  30. // rough offset voltage: one diode drop, about 50mV = 0x3ff * 50/3560 = 20
  31. //#define OFFSET_VOLTAGE 0x14
  32. #define OFFSET_VOLTAGE 0x28
  33. #define RIGHT_JUSTIFY 0
  34. #define LEFT_JUSTIFY (0xff)
  35. // set left or right justification here:
  36. #define JUSTIFY_ADC RIGHT_JUSTIFY
  37. #define ADLAR_MASK (1 << ADLAR)
  38. #ifdef JUSTIFY_ADC
  39. #define ADLAR_BITS ((ADLAR_MASK) & (JUSTIFY_ADC))
  40. #else // defaults to right justification.
  41. #define ADLAR_BITS 0
  42. #endif
  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. #define MUX_1_1 0x1e
  48. #define MUX_GND 0x1f
  49. // set ADC clock prescale
  50. #define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2))
  51. #define PRESCALE_SHIFT (ADPS0)
  52. #define PRESCALE 3
  53. #ifdef EXTENDED_STROBE
  54. #define STROBE_LINES 18
  55. #else
  56. #define STROBE_LINES 16
  57. #endif
  58. #define STROBE_LINES_XSHIFT 4
  59. #define STROBE_LINES_MASK 0x0f
  60. #define MUXES_COUNT 8
  61. #define MUXES_COUNT_XSHIFT 3
  62. #define MUXES_MASK 0x7
  63. #define WARMUP_LOOPS ( 1024 )
  64. #define RECOVERY_US 6
  65. #define SAMPLES 10
  66. #define SAMPLE_OFFSET ((SAMPLES) - MUXES_COUNT)
  67. //#define SAMPLE_OFFSET 9
  68. #define STROBE_OFFSET 0
  69. #define KEY_COUNT ((STROBE_LINES) * (MUXES_COUNT))
  70. #define LX2FX
  71. #define RECOVERY_CONTROL 1
  72. #define RECOVERY_SOURCE 0
  73. #define RECOVERY_SINK 2
  74. #define RECOVERY_MASK 0x03
  75. // mix in 1/4 of the current average to the running average. -> (@mux_mix = 2)
  76. #define MUX_MIX 2
  77. #define IDLE_COUNT_MASK 0xff
  78. #define MAX_ICS 8
  79. #define IDLE_COUNT_SHIFT 4
  80. #define KEYS_AVERAGES_MIX 2
  81. #ifdef ALL_D_C
  82. #define D_MASK (0xff)
  83. #define D_SHIFT 0
  84. #define E_MASK (0x00)
  85. #define E_SHIFT 0
  86. #define C_MASK (0xff)
  87. #define C_SHIFT 8
  88. #else
  89. #if defined(SHORT_D)
  90. #define D_MASK (0x3f)
  91. #define D_SHIFT 0
  92. #define E_MASK (0x03)
  93. #define E_SHIFT 6
  94. #define C_MASK (0xff)
  95. #define C_SHIFT 8
  96. #else
  97. #if defined(SHORT_C)
  98. #define D_MASK (0xff)
  99. #define D_SHIFT 0
  100. #define E_MASK (0x03)
  101. #define E_SHIFT 6
  102. #define C_MASK (0xff)
  103. #define C_SHIFT 8
  104. #endif
  105. #endif
  106. #endif
  107. // ----- Macros -----
  108. // Make sure we haven't overflowed the buffer
  109. #define bufferAdd(byte) \
  110. if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
  111. KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
  112. // TODO dfj macros...needs cleaning up and commenting...
  113. #define STROBE_CASE(SC_CASE, SC_REG_A) case (SC_CASE): PORT##SC_REG_A = \
  114. (( (PORT##SC_REG_A) & ~(1 << (SC_CASE - SC_REG_A##_SHIFT)) ) | (1 << (SC_CASE - SC_REG_A##_SHIFT)))
  115. #define SET_MUX(X) ((ADMUX) = (((ADMUX) & ~(MUX_MASK)) | ((X) & (MUX_MASK))))
  116. #define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK))))
  117. // ----- Variables -----
  118. // Buffer used to inform the macro processing module which keys have been detected as pressed
  119. volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
  120. volatile uint8_t KeyIndex_BufferUsed;
  121. // TODO dfj variables...needs cleaning up and commenting
  122. uint8_t blink = 0;
  123. volatile uint8_t idle_count = 1;
  124. volatile uint16_t full_av = 0;
  125. /**/ uint8_t ze_strober = 0;
  126. int16_t samples [SAMPLES];
  127. //int16_t gsamples [SAMPLES];
  128. /**/ int16_t adc_mux_averages[MUXES_COUNT];
  129. /**/ int16_t adc_strobe_averages[STROBE_LINES];
  130. /**/ uint8_t cur_keymap[STROBE_LINES];
  131. // /**/ int8_t last_keymap[STROBE_LINES];
  132. /**/ uint8_t usb_keymap[STROBE_LINES];
  133. uint8_t dirty;
  134. uint8_t unstable;
  135. uint8_t usb_dirty;
  136. int16_t threshold = THRESHOLD;
  137. uint16_t tests = 0;
  138. uint8_t col_a=0;
  139. uint8_t col_b=0;
  140. uint8_t col_c=0;
  141. uint8_t column=0;
  142. int16_t keys_averages_acc[KEY_COUNT];
  143. uint16_t keys_averages[KEY_COUNT];
  144. uint8_t full_samples[KEY_COUNT];
  145. /* viable starting biases for near 0.830V offset. and adc PRESCALE 3
  146. 0017 0016 001B 001A 0016 0016 000F 000E 001B 001E 001E 0018 0017 0015 000E 001D
  147. 001B 001A 0016 0016 000F 000E 001C 001B 001E 0018 0017 0015 000E 001D 0024 001F
  148. 0016 0016 000F 000E 001C 001B 001E 001E 0017 0015 000E 001D 0024 001F 0020 001F
  149. 000F 000E 001C 001B 001E 001E 0018 0017 000E 001D 0024 001F 0020 001F 0020 0017
  150. 001C 001B 001E 001E 0018 0017 0015 000E 0024 001F 0020 001F 0020 0017 0010 001D
  151. 001E 001E 0018 0017 0015 000E 001D 0024 0020 001F 0020 0017 0010 001D 0024 0021
  152. 0018 0017 0015 000E 001D 0024 001F 0020 0020 0017 0010 001D 0024 0021 0021 0021
  153. 0015 000E 001D 0024 001F 0020 001F 0020 0010 001D 0024 0021 0021 0021 0021 0018
  154. */
  155. /*** starting bias relative to fixed offset estimate of 820mV (0x50)
  156. * 77 69 65 5B 50 4E 4C 45 66 53 4D 49 45 3F 3E 35
  157. * 68 54 4F 49 45 40 3F 34 74 66 5F 56 4E 4D 4C 3F
  158. * 6D 5D 53 4C 49 46 45 38 6D 5A 53 4E 49 48 45 3E
  159. * 6F 5D 56 4E 4B 48 48 3A 6D 5C 54 4E 48 48 45 37
  160. * 75 68 5F 57 4F 4D 4C 3F 60 4E 48 41 3C 3C 39 2F
  161. * 65 53 4E 49 41 3F 3E 34 65 54 4E 49 43 3F 3E 34
  162. * 60 51 4A 45 3F 3E 3C 30 57 4C 45 3E 3B 37 37 2E
  163. * 64 4E 48 44 3C 3B 39 2F 5D 4F 48 45 3E 3C 3B 30
  164. */
  165. /*volatile*/ uint16_t count = 0;
  166. /*volatile*/ uint8_t error = 0;
  167. uint16_t error_data = 0;
  168. int16_t mux_averages[MUXES_COUNT];
  169. int16_t strobe_averages[STROBE_LINES];
  170. uint8_t dump_count = 0;
  171. // ----- Function Declarations -----
  172. void dump ( void );
  173. void dumpkeys( void );
  174. void recovery( uint8_t on );
  175. int sampleColumn ( uint8_t column );
  176. int sampleColumn_i( uint8_t column, uint8_t muxes, int16_t * buffer); // XXX Not currently used
  177. int sampleColumn_k( uint8_t column, int16_t *buffer );
  178. void setup_ADC( void );
  179. void strobe_w( uint8_t strobe_num );
  180. uint8_t testColumn( uint8_t strobe );
  181. // ----- Functions -----
  182. // Initial setup for cap sense controller
  183. inline void scan_setup()
  184. {
  185. // TODO dfj code...needs cleanup + commenting...
  186. setup_ADC();
  187. // Configure timer 0 to generate a timer overflow interrupt every
  188. // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
  189. // This demonstrates how to use interrupts to implement a simple
  190. // inactivity timeout.
  191. //TCCR0A = 0x00;
  192. //TCCR0B = 0x05;
  193. //TIMSK0 = (1<<TOIE0);
  194. DDRC = C_MASK;
  195. PORTC = 0;
  196. DDRD = D_MASK;
  197. PORTD = 0;
  198. DDRE = E_MASK;
  199. PORTE = 0 ;
  200. //DDRC |= (1 << 6);
  201. //PORTC &= ~(1<< 6);
  202. //uint16_t strobe = 1;
  203. // TODO all this code should probably be in scan_resetKeyboard
  204. for (int i=0; i< STROBE_LINES; ++i) {
  205. cur_keymap[i] = 0;
  206. //last_keymap[i] = 0;
  207. usb_keymap[i] = 0;
  208. }
  209. for(int i=0; i < MUXES_COUNT; ++i) {
  210. adc_mux_averages[i] = 0x20; // experimentally determined.
  211. }
  212. for(int i=0; i < STROBE_LINES; ++i) {
  213. adc_strobe_averages[i] = 0x20; // yup.
  214. }
  215. for(int i=0; i< KEY_COUNT; ++i) {
  216. keys_averages[i] = 0x40;
  217. keys_averages_acc[i] = (0x400);
  218. }
  219. /** warm things up a bit before we start collecting data, taking real samples. */
  220. for(uint8_t i = 0; i< STROBE_LINES; ++i) {
  221. sampleColumn(i);
  222. }
  223. // Reset the keyboard before scanning, we might be in a wierd state
  224. // Also sets the KeyIndex_BufferUsed to 0
  225. scan_resetKeyboard();
  226. }
  227. // Main Detection Loop
  228. // This is where the important stuff happens
  229. inline uint8_t scan_loop()
  230. {
  231. // TODO dfj code...needs commenting + cleanup...
  232. uint8_t strober = 0;
  233. uint32_t full_av_acc = 0;
  234. for (strober = 0; strober < STROBE_LINES; ++strober) {
  235. uint8_t tries;
  236. tries = 1;
  237. while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
  238. column = testColumn(strober);
  239. if( column != cur_keymap[strober] && (count >= WARMUP_LOOPS) ) {
  240. tests++;
  241. tries = 1;
  242. while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
  243. col_a = testColumn(strober);
  244. tries = 1;
  245. while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
  246. col_b = testColumn(strober);
  247. tries = 1;
  248. while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop.
  249. col_c = testColumn(strober);
  250. if( (col_a == col_b) && (col_b == col_c) && (cur_keymap[strober] != col_a) ) {
  251. cur_keymap[strober] = col_a;
  252. usb_dirty = 1;
  253. }
  254. }
  255. if(error == 0x50) {
  256. error_data |= (((uint16_t)strober) << 12);
  257. }
  258. for(int i=0; i<MUXES_COUNT; ++i) {
  259. full_samples[(strober << MUXES_COUNT_XSHIFT) + i] = samples[SAMPLE_OFFSET + i];
  260. }
  261. strobe_averages[strober] = 0;
  262. for (uint8_t i = SAMPLE_OFFSET; i < (SAMPLE_OFFSET + MUXES_COUNT); ++i) {
  263. //samples[i] -= samples[i-SAMPLE_OFFSET]; // av; // + full_av); // -something.
  264. //samples[i] -= OFFSET_VOLTAGE; // moved to sampleColumn.
  265. full_av_acc += (samples[i]);
  266. mux_averages[i - SAMPLE_OFFSET] += samples[i];
  267. strobe_averages[strober] += samples[i];
  268. //samples[i] -= (full_av - HYST_T);
  269. //++count;
  270. }
  271. adc_strobe_averages[strober] += strobe_averages[strober] >> 3;
  272. adc_strobe_averages[strober] >>= 1;
  273. /** test if we went negative. */
  274. if ((adc_strobe_averages[strober] & 0xFF00) && (count
  275. >= WARMUP_LOOPS)) {
  276. //count = 0; // TODO : constrain properly.
  277. error = 0xf; error_data = adc_strobe_averages[strober];
  278. }
  279. uint8_t strobe_line = strober << MUXES_COUNT_XSHIFT;
  280. for (int i = 0; i < MUXES_COUNT; ++i) {
  281. keys_averages_acc[strobe_line + i]
  282. += samples[SAMPLE_OFFSET + i];
  283. }
  284. } // for strober
  285. if (count < WARMUP_LOOPS) {
  286. error = 0x0C;
  287. error_data = count;
  288. count++;
  289. }
  290. // verify test key is not down.
  291. if((cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK) ) {
  292. //count=0;
  293. error = 0x05;
  294. error_data = cur_keymap[TEST_KEY_STROBE] << 8;
  295. error_data += full_samples[TEST_KEY_STROBE * 8];
  296. //threshold++;
  297. }
  298. // calc mux averages.
  299. if (count < WARMUP_LOOPS) {
  300. full_av += (full_av_acc >> (7));
  301. full_av >>= 1;
  302. //full_av = full_av_acc / count;
  303. full_av_acc = 0;
  304. for (int i=0; i < MUXES_COUNT; ++i) {
  305. adc_mux_averages[i] = (adc_mux_averages[i] << MUX_MIX) - adc_mux_averages[i];
  306. adc_mux_averages[i] += (mux_averages[i] >> 4);
  307. adc_mux_averages[i] >>= MUX_MIX;
  308. mux_averages[i] = 0;
  309. }
  310. }
  311. idle_count++;
  312. idle_count &= IDLE_COUNT_MASK;
  313. if (/*usb_dirty &&*/ (count >= WARMUP_LOOPS) ) {
  314. for (int i=0; i<STROBE_LINES; ++i) {
  315. usb_keymap[i] = cur_keymap[i];
  316. }
  317. dumpkeys();
  318. usb_dirty=0;
  319. _delay_ms(2);
  320. }
  321. if (count < WARMUP_LOOPS) {
  322. for (uint8_t i = 0; i < KEY_COUNT; ++i) {
  323. uint16_t acc = keys_averages_acc[i];
  324. uint32_t av = keys_averages[i];
  325. av = av + av + av + acc;
  326. av >>= 2;
  327. keys_averages[i] = av;
  328. keys_averages_acc[i] = 0;
  329. }
  330. }
  331. if(!idle_count) {
  332. for (int i=0; i< KEY_COUNT; ++i) {
  333. keys_averages_acc[i] = 0;
  334. }
  335. sampleColumn(0x0); // to resync us if we dumped a mess 'o text.
  336. }
  337. // Return non-zero if macro and USB processing should be delayed
  338. // Macro processing will always run if returning 0
  339. // USB processing only happens once the USB send timer expires, if it has not, scan_loop will be called
  340. // after the macro processing has been completed
  341. return 0;
  342. }
  343. // Reset Keyboard
  344. void scan_resetKeyboard( void )
  345. {
  346. // Empty buffer, now that keyboard has been reset
  347. KeyIndex_BufferUsed = 0;
  348. }
  349. // Send data to keyboard
  350. // NOTE: Only used for converters, since the scan module shouldn't handle sending data in a controller
  351. uint8_t scan_sendData( uint8_t dataPayload )
  352. {
  353. return 0;
  354. }
  355. // Reset/Hold keyboard
  356. // NOTE: Only used for converters, not needed for full controllers
  357. void scan_lockKeyboard( void )
  358. {
  359. }
  360. // NOTE: Only used for converters, not needed for full controllers
  361. void scan_unlockKeyboard( void )
  362. {
  363. }
  364. // Signal KeyIndex_Buffer that it has been properly read
  365. // NOTE: Only really required for implementing "tricks" in converters for odd protocols
  366. void scan_finishedWithBuffer( uint8_t sentKeys )
  367. {
  368. // Convenient place to clear the KeyIndex_Buffer
  369. KeyIndex_BufferUsed = 0;
  370. return;
  371. }
  372. // Signal KeyIndex_Buffer that it has been properly read and sent out by the USB module
  373. // NOTE: Only really required for implementing "tricks" in converters for odd protocols
  374. void scan_finishedWithUSBBuffer( uint8_t sentKeys )
  375. {
  376. return;
  377. }
  378. void
  379. _delay_loop(uint8_t __count)
  380. {
  381. __asm__ volatile (
  382. "1: dec %0" "\n\t"
  383. "brne 1b"
  384. : "=r" (__count)
  385. : "0" (__count)
  386. );
  387. }
  388. void setup_ADC (void) {
  389. // disable adc digital pins.
  390. DIDR1 |= (1 << AIN0D) | (1<<AIN1D); // set disable on pins 1,0.
  391. //DIDR0 = 0xff; // disable all. (port F, usually). - testing w/o disable.
  392. DDRF = 0x0;
  393. PORTF = 0x0;
  394. uint8_t mux = 0 & 0x1f; // 0 == first. // 0x1e = 1.1V ref.
  395. // 0 = external aref 1,1 = 2.56V internal ref
  396. uint8_t aref = ((1 << REFS1) | (1 << REFS0)) & ((1 << REFS1) | (1 << REFS0));
  397. // uint8_t adlar = 0xff & (1 << ADLAR); // 1 := left justify bits, 0 := right
  398. uint8_t adate = (1 << ADATE) & (1 << ADATE); // trigger enable
  399. uint8_t trig = 0 & ((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2)); // 0 = free running
  400. // ps2, ps1 := /64 ( 2^6 ) ps2 := /16 (2^4), ps1 := 4, ps0 :=2, PS1,PS0 := 8 (2^8)
  401. uint8_t prescale = ( ((PRESCALE) << PRESCALE_SHIFT) & PRESCALE_MASK ); // 001 == 2^1 == 2
  402. uint8_t hispeed = (1 << ADHSM);
  403. uint8_t en_mux = (1 << ACME);
  404. //ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS1) | (1 << ADPS2)); // 2, 1 := /64 ( 2^6 )
  405. //ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS0) | (1 << ADPS2)); // 2, 0 := /32 ( 2^5 )
  406. //ADCSRA = (ADCSRA & ~PRESCALES) | ((1 << ADPS2)); // 2 := /16 ( 2^4 )
  407. ADCSRA = (1 << ADEN) | prescale; // ADC enable
  408. // select ref.
  409. //ADMUX |= ((1 << REFS1) | (1 << REFS0)); // 2.56 V internal.
  410. //ADMUX |= ((1 << REFS0) ); // Vcc with external cap.
  411. //ADMUX &= ~((1 << REFS1) | (1 << REFS0)); // 0,0 : aref.
  412. ADMUX = aref | mux | ADLAR_BITS;
  413. // enable MUX
  414. // ADCSRB |= (1 << ACME); // enable
  415. // ADCSRB &= ~(1 << ADEN); // ?
  416. // select first mux.
  417. //ADMUX = (ADMUX & ~MUXES); // start at 000 = ADC0
  418. // clear adlar to left justify data
  419. //ADMUX = ~();
  420. // set adlar to right justify data
  421. //ADMUX |= (1 << ADLAR);
  422. // set free-running
  423. ADCSRA |= adate; // trigger enable
  424. ADCSRB = en_mux | hispeed | trig | (ADCSRB & ~((1 << ADTS0) | (1 << ADTS1) | (1 << ADTS2))); // trigger select free running
  425. // ADCSRA |= (1 << ADATE); // tiggger enable
  426. ADCSRA |= (1 << ADEN); // ADC enable
  427. ADCSRA |= (1 << ADSC); // start conversions q
  428. }
  429. void recovery(uint8_t on) {
  430. DDRB |= (1 << RECOVERY_CONTROL);
  431. PORTB &= ~(1 << RECOVERY_SINK); // SINK always zero
  432. DDRB &= ~(1 << RECOVERY_SOURCE); // SOURCE high imp
  433. if(on) {
  434. DDRB |= (1 << RECOVERY_SINK); // SINK pull
  435. PORTB |= (1 << RECOVERY_CONTROL);
  436. PORTB |= (1 << RECOVERY_SOURCE); // SOURCE high
  437. DDRB |= (1 << RECOVERY_SOURCE);
  438. } else {
  439. _delay_loop(10);
  440. PORTB &= ~(1 << RECOVERY_CONTROL);
  441. DDRB &= ~(1 << RECOVERY_SOURCE);
  442. PORTB &= ~(1 << RECOVERY_SOURCE); // SOURCE low
  443. DDRB &= ~(1 << RECOVERY_SINK); // SINK high-imp
  444. //DDRB &= ~(1 << RECOVERY_SINK);
  445. }
  446. }
  447. void strobe_w(uint8_t strobe_num) {
  448. PORTC &= ~(D_MASK);
  449. PORTD &= ~(D_MASK);
  450. PORTE &= ~(E_MASK);
  451. #ifdef SHORT_C
  452. strobe_num = 15 - strobe_num;
  453. #endif
  454. switch(strobe_num) {
  455. case 0: PORTD |= (1 << 0); break;
  456. case 1: PORTD |= (1 << 1); break;
  457. case 2: PORTD |= (1 << 2); break;
  458. case 3: PORTD |= (1 << 3); break;
  459. case 4: PORTD |= (1 << 4); break;
  460. case 5: PORTD |= (1 << 5); break;
  461. #ifdef ALL_D
  462. case 6: PORTD |= (1 << 6); break;
  463. case 7: PORTD |= (1 << 7); break;
  464. case 8: PORTC |= (1 << 0); break;
  465. case 9: PORTC |= (1 << 1); break;
  466. case 10: PORTC |= (1 << 2); break;
  467. case 11: PORTC |= (1 << 3); break;
  468. case 12: PORTC |= (1 << 4); break;
  469. case 13: PORTC |= (1 << 5); break;
  470. case 14: PORTC |= (1 << 6); break;
  471. case 15: PORTC |= (1 << 7); break;
  472. case 16: PORTE |= (1 << 0); break;
  473. case 17: PORTE |= (1 << 1); break;
  474. #else
  475. #ifdef SHORT_D
  476. case 6: PORTE |= (1 << 0); break;
  477. case 7: PORTE |= (1 << 1); break;
  478. case 8: PORTC |= (1 << 0); break;
  479. case 9: PORTC |= (1 << 1); break;
  480. case 10: PORTC |= (1 << 2); break;
  481. case 11: PORTC |= (1 << 3); break;
  482. case 12: PORTC |= (1 << 4); break;
  483. case 13: PORTC |= (1 << 5); break;
  484. case 14: PORTC |= (1 << 6); break;
  485. case 15: PORTC |= (1 << 7); break;
  486. #else
  487. #ifdef SHORT_C
  488. case 6: PORTD |= (1 << 6); break;
  489. case 7: PORTD |= (1 << 7); break;
  490. case 8: PORTE |= (1 << 0); break;
  491. case 9: PORTE |= (1 << 1); break;
  492. case 10: PORTC |= (1 << 0); break;
  493. case 11: PORTC |= (1 << 1); break;
  494. case 12: PORTC |= (1 << 2); break;
  495. case 13: PORTC |= (1 << 3); break;
  496. case 14: PORTC |= (1 << 4); break;
  497. case 15: PORTC |= (1 << 5); break;
  498. case 16: PORTC |= (1 << 6); break;
  499. case 17: PORTC |= (1 << 7); break;
  500. #endif
  501. #endif
  502. #endif
  503. default:
  504. break;
  505. }
  506. }
  507. int sampleColumn_i(uint8_t column, uint8_t muxes, int16_t * buffer) {
  508. // ensure all probe lines are driven low, and chill for recovery delay.
  509. PORTC &= ~C_MASK;
  510. PORTD &= ~D_MASK;
  511. PORTE &= ~E_MASK;
  512. recovery(1);
  513. _delay_us(RECOVERY_US);
  514. recovery(0);
  515. uint8_t index = 0;
  516. for (uint8_t i=0; i<8; ++i) {
  517. if(muxes & (1 << i)) {
  518. buffer[index++] = i;
  519. }
  520. }
  521. SET_FULL_MUX(MUX_1_1); // crap sample will use this.
  522. ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
  523. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  524. //uint16_t sample;
  525. while (! (ADCSRA & (1 << ADIF))); // wait until ready.
  526. //sample = ADC; // 1st sample, icky.
  527. ADC; // 1st sample, icky. XXX Not sure if the compiler throws this away, but less compiler warnings -HaaTa
  528. strobe_w(column);
  529. //recovery(0);
  530. /**
  531. * we are running in continuous mode, so we must setup the next
  532. * read _before_ the current read completes.
  533. *
  534. * setup 0,
  535. * read garbage,
  536. * do not store
  537. *
  538. * setup 1,
  539. * read 0,
  540. * store 0,
  541. *
  542. * ...
  543. *
  544. * setup junk,
  545. * read n
  546. * store n
  547. *
  548. * */
  549. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  550. //wait for last read to complete.
  551. while (! (ADCSRA & (1 << ADIF)));
  552. //sample = ADC; // throw away strobe'd value.
  553. ADC; // throw away strobe'd value.
  554. #if 0
  555. for (uint8_t i=0; i <= index; ++i) {
  556. // setup i'th read.
  557. SET_FULL_MUX(buffer[i]); // _next_ read will use this.
  558. // wait for i-1'th read to complete:
  559. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  560. while (! (ADCSRA & (1 << ADIF)));
  561. // retrieve last (i-1'th) read.
  562. if (i) {
  563. buffer[i-1] = ADC - OFFSET_VOLTAGE;
  564. } /*else {
  565. buffer[0] = ADC - OFFSET_VOLTAGE;
  566. }*/
  567. //index++;
  568. }
  569. #else
  570. for (uint8_t i=0; i < index; ++i) {
  571. // setup i'th read.
  572. SET_FULL_MUX(buffer[i]); // _next_ read will use this.
  573. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  574. while (! (ADCSRA & (1 << ADIF)));
  575. //sample = ADC; // throw away warmup value.
  576. ADC; // throw away warmup value.
  577. /*
  578. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  579. while (! (ADCSRA & (1 << ADIF)));
  580. //sample = ADC; // throw away warmup value.
  581. ADC; // throw away warmup value.
  582. */
  583. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  584. while (! (ADCSRA & (1 << ADIF)));
  585. // retrieve current read.
  586. buffer[i] = ADC - OFFSET_VOLTAGE;
  587. }
  588. #endif
  589. // turn off adc.
  590. ADCSRA &= ~(1 << ADEN);
  591. // pull all columns' probe-lines low.
  592. PORTC &= ~C_MASK;
  593. PORTD &= ~D_MASK;
  594. PORTE &= ~E_MASK;
  595. // test for humps. :/
  596. /*uint16_t delta = full_av;
  597. if(buffer[0] > BUMP_THRESHOLD + delta) {
  598. // ze horror.
  599. return 1;
  600. } else {
  601. return 0; //all good.
  602. }*/
  603. return 0;
  604. }
  605. int sampleColumn_k(uint8_t column, int16_t * buffer) {
  606. // ensure all probe lines are driven low, and chill for recovery delay.
  607. //uint16_t sample;
  608. ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions
  609. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  610. // sync up with adc clock:
  611. while (! (ADCSRA & (1 << ADIF))); // wait until ready.
  612. ADC; // throw it away. // XXX Not sure if the compiler throws this away, but less compiler warnings -HaaTa
  613. //sample = ADC; // throw it away.
  614. for(uint8_t mux=0; mux < 8; ++mux) {
  615. PORTC &= ~C_MASK;
  616. PORTD &= ~D_MASK;
  617. PORTE &= ~E_MASK;
  618. SET_FULL_MUX(mux); // our sample will use this
  619. for(uint8_t i=0; i < 2; ++i) {
  620. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  621. //wait for last read to complete.
  622. while (! (ADCSRA & (1 << ADIF)));
  623. //sample = ADC; // throw away strobe'd value.
  624. ADC; // throw away strobe'd value.
  625. }
  626. recovery(0);
  627. strobe_w(column);
  628. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  629. //wait for last read to complete.
  630. while (! (ADCSRA & (1 << ADIF)));
  631. //sample = ADC; // throw away strobe'd value.
  632. ADC; // throw away strobe'd value.
  633. ADCSRA |= (1 << ADIF); // clear int flag by writing 1.
  634. while (! (ADCSRA & (1 << ADIF)));
  635. // retrieve current read.
  636. buffer[mux] = ADC - OFFSET_VOLTAGE;
  637. recovery(1);
  638. }
  639. // turn off adc.
  640. ADCSRA &= ~(1 << ADEN);
  641. // pull all columns' probe-lines low.
  642. PORTC &= ~C_MASK;
  643. PORTD &= ~D_MASK;
  644. PORTE &= ~E_MASK;
  645. // recovery(1);
  646. return 0;
  647. }
  648. int sampleColumn(uint8_t column) {
  649. int rval = 0;
  650. /*
  651. sampleColumn_i(column, 0x0f, samples+SAMPLE_OFFSET);
  652. sampleColumn_i(column, 0xf0, samples+SAMPLE_OFFSET + 4 );
  653. */
  654. rval = sampleColumn_k(column, samples+SAMPLE_OFFSET);
  655. for(uint8_t i=0; i<8; ++i) {
  656. if(samples[SAMPLE_OFFSET + i] - adc_mux_averages[i] > BUMP_THRESHOLD) {
  657. // was a hump
  658. _delay_us(BUMP_REST_US);
  659. rval++;
  660. error = 0x50;
  661. error_data = samples[SAMPLE_OFFSET +i]; // | ((uint16_t)i << 8);
  662. return rval;
  663. }
  664. }
  665. return rval;
  666. }
  667. uint8_t testColumn(uint8_t strobe) {
  668. uint8_t column = 0;
  669. uint8_t bit = 1;
  670. for (uint8_t i=0; i < MUXES_COUNT; ++i) {
  671. uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + i];
  672. if ((int16_t)samples[SAMPLE_OFFSET + i] > threshold + delta) {
  673. column |= bit;
  674. }
  675. bit <<= 1;
  676. }
  677. return column;
  678. }
  679. void dumpkeys(void) {
  680. //print(" \n");
  681. if(error) {
  682. for (uint8_t i=0; i < STROBE_LINES; ++i) {
  683. printHex(usb_keymap[i]);
  684. print(" ");
  685. //print(" ");
  686. }
  687. if (count >= WARMUP_LOOPS && error) {
  688. dump();
  689. }
  690. print(" : ");
  691. printHex(error);
  692. error = 0;
  693. print(" : ");
  694. printHex(error_data);
  695. error_data = 0;
  696. print(" : " NL);
  697. }
  698. // XXX Will be cleaned up eventually, but this will do for now :P -HaaTa
  699. for (uint8_t i=0; i < STROBE_LINES; ++i) {
  700. for(uint8_t j=0; j<MUXES_COUNT; ++j) {
  701. if ( usb_keymap[i] & (1 << j) ) {
  702. uint8_t key = (i << MUXES_COUNT_XSHIFT) + j;
  703. // Add to the Macro processing buffer
  704. // Automatically handles converting to a USB code and sending off to the PC
  705. bufferAdd( key );
  706. if(usb_dirty) {
  707. printHex( key );
  708. print(" ");
  709. }
  710. }
  711. }
  712. }
  713. if(usb_dirty) print("\n");
  714. usb_keyboard_send();
  715. }
  716. void dump(void) {
  717. if(!dump_count) { // we don't want to debug-out during the measurements.
  718. for(int i =0; i< KEY_COUNT; ++i) {
  719. if(!(i & 0x0f)) {
  720. print("\n");
  721. } else if (!(i & 0x07)) {
  722. print(" ");
  723. }
  724. print(" ");
  725. //printHex (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]);
  726. printHex (keys_averages[i]);
  727. }
  728. print("\n");
  729. for(int i =0; i< KEY_COUNT; ++i) {
  730. if(!(i & 0x0f)) {
  731. print("\n");
  732. } else if (!(i & 0x07)) {
  733. print(" ");
  734. }
  735. print(" ");
  736. //printHex (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]);
  737. //printHex (keys_averages_acc[i]);
  738. printHex(full_samples[i]);
  739. }
  740. }
  741. //}
  742. // uint8_t cur_strober = 0xe;
  743. uint8_t cur_strober = ze_strober;
  744. print("\n");
  745. printHex(cur_strober);
  746. //print(": ");
  747. print(": ");
  748. #if 1
  749. print("\n");
  750. for (uint8_t i=0; i < MUXES_COUNT; ++i) {
  751. print(" ");
  752. printHex(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
  753. }
  754. print("\n");
  755. // printHex(threshold);
  756. // print(": ");
  757. for (uint8_t i=0; i < MUXES_COUNT; ++i) {
  758. print(" ");
  759. printHex(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]);
  760. }
  761. #endif
  762. /*
  763. for (uint8_t i=0; i< SAMPLES; ++i) {
  764. print(" ");
  765. printHex(samples[i]);
  766. //printHex(ADC);
  767. }*/
  768. //print(" : ");
  769. //dPrint((was_active)?" ":"*");
  770. //printHex(keymap[TEST_KEY_STROBE] & TEST_KEY_MASK);
  771. /*print(" "); */
  772. //printHex(keymap[TEST_KEY_STROBE]);
  773. //print("\n");
  774. //print(":");
  775. //printHex(full_av);
  776. //printHex(count);
  777. //print(" : ");
  778. print("\n");
  779. for (uint8_t i=0; i < STROBE_LINES; ++i) {
  780. printHex(cur_keymap[i]);
  781. print(" ");
  782. //print(" ");
  783. }
  784. //print(": ");
  785. //printHex(adc_strobe_averages[ze_strober]);
  786. //print(" ");
  787. for (uint8_t i=0; i < MUXES_COUNT; ++i) {
  788. print(" ");
  789. //printHex(adc_mux_averages[i] + adc_strobe_averages[ze_strober] - full_av);
  790. //printHex((adc_mux_averages[i] + adc_strobe_averages[ze_strober]) >> 1);
  791. //printHex((adc_mux_averages[i] * 3 + adc_strobe_averages[ze_strober]) >> 2);
  792. //printHex(adc_mux_averages[i] + threshold);
  793. //printHex(gsamples[i + SAMPLE_OFFSET] - (adc_mux_averages[i] + threshold) + 0x100);
  794. //printHex(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i] + (uint8_t)threshold);
  795. printHex(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i]);
  796. }
  797. if(error) {
  798. print(" ");
  799. printHex(error);
  800. print(" ");
  801. printHex(error_data);
  802. error = 0;
  803. error_data = 0;
  804. }
  805. //print("\n");
  806. ze_strober++;
  807. ze_strober &= 0xf;
  808. dump_count++;
  809. dump_count &= 0x0f;
  810. //ze_strobe = (1 << (ze_strober ) );
  811. //printHex(ADCSRA);
  812. //print(" ");
  813. //print("\n");
  814. }