CON pin_ = 16 rp = 500.0 'pull-up resistor r1 = 500.0 '1st button resistor, should be approximately rp r2 = 1_000.0 '2nd button resistor, should be approximately r1 * 2 r3 = 2_000.0 '3rd button resistor, should be approximately r2 * 2 r4 = 4_000.0 '4th button resistor, should be approximately r3 * 2 scale = 3300.0 'calculate r1..r4 parallel resistance sums per button combination r0001 = 1.0 / (0.0 / r1 + 0.0 / r2 + 0.0 / r3 + 1.0 / r4) r0010 = 1.0 / (0.0 / r1 + 0.0 / r2 + 1.0 / r3 + 0.0 / r4) r0011 = 1.0 / (0.0 / r1 + 0.0 / r2 + 1.0 / r3 + 1.0 / r4) r0100 = 1.0 / (0.0 / r1 + 1.0 / r2 + 0.0 / r3 + 0.0 / r4) r0101 = 1.0 / (0.0 / r1 + 1.0 / r2 + 0.0 / r3 + 1.0 / r4) r0110 = 1.0 / (0.0 / r1 + 1.0 / r2 + 1.0 / r3 + 0.0 / r4) r0111 = 1.0 / (0.0 / r1 + 1.0 / r2 + 1.0 / r3 + 1.0 / r4) r1000 = 1.0 / (1.0 / r1 + 0.0 / r2 + 0.0 / r3 + 0.0 / r4) r1001 = 1.0 / (1.0 / r1 + 0.0 / r2 + 0.0 / r3 + 1.0 / r4) r1010 = 1.0 / (1.0 / r1 + 0.0 / r2 + 1.0 / r3 + 0.0 / r4) r1011 = 1.0 / (1.0 / r1 + 0.0 / r2 + 1.0 / r3 + 1.0 / r4) r1100 = 1.0 / (1.0 / r1 + 1.0 / r2 + 0.0 / r3 + 0.0 / r4) r1101 = 1.0 / (1.0 / r1 + 1.0 / r2 + 0.0 / r3 + 1.0 / r4) r1110 = 1.0 / (1.0 / r1 + 1.0 / r2 + 1.0 / r3 + 0.0 / r4) r1111 = 1.0 / (1.0 / r1 + 1.0 / r2 + 1.0 / r3 + 1.0 / r4) 'calculate voltage readings for button combinations v0000 = scale v0001 = scale * r0001 / (rp + r0001) v0010 = scale * r0010 / (rp + r0010) v0011 = scale * r0011 / (rp + r0011) v0100 = scale * r0100 / (rp + r0100) v0101 = scale * r0101 / (rp + r0101) v0110 = scale * r0110 / (rp + r0110) v0111 = scale * r0111 / (rp + r0111) v1000 = scale * r1000 / (rp + r1000) v1001 = scale * r1001 / (rp + r1001) v1010 = scale * r1010 / (rp + r1010) v1011 = scale * r1011 / (rp + r1011) v1100 = scale * r1100 / (rp + r1100) v1101 = scale * r1101 / (rp + r1101) v1110 = scale * r1110 / (rp + r1110) v1111 = scale * r1111 / (rp + r1111) 'calculate voltage thresholds for button combinations t0000 = round((v0000 + v0001) / 2.0) t0001 = round((v0001 + v0010) / 2.0) t0010 = round((v0010 + v0011) / 2.0) t0011 = round((v0011 + v0100) / 2.0) t0100 = round((v0100 + v0101) / 2.0) t0101 = round((v0101 + v0110) / 2.0) t0110 = round((v0110 + v0111) / 2.0) t0111 = round((v0111 + v1000) / 2.0) t1000 = round((v1000 + v1001) / 2.0) t1001 = round((v1001 + v1010) / 2.0) t1010 = round((v1010 + v1011) / 2.0) t1011 = round((v1011 + v1100) / 2.0) t1100 = round((v1100 + v1101) / 2.0) t1101 = round((v1101 + v1110) / 2.0) t1110 = round((v1110 + v1111) / 2.0) t1111 = round((v1111 + 0.0 ) / 2.0) _clkfreq = 50_000_000 'set clock frequency VAR stack[30], v1, v2, v3 PUB go() cogspin(newcog, go2(), @stack) repeat debug(udec(v1, v2), ubin_byte(v3), dly(50)) PUB go2() pr0 := pin_ regexec(@adcpgm) repeat v1 := reg[clocks] v2 := reg[sample] v3 := reg[states] DAT adcpgm word 0, adc_end org 0 ' ' ' ADC program setup ' adc_start mov pin,pr0 fltl pin 'set pin to ADC mode + count highs wrpin adc_gio,pin wxpin clocks,pin wypin #0,pin drvl pin mov ijmp3,#adc_isr 'set interrupt jump mov x,pin 'set ADC pin IN-rise event or x,#%001<<6 setse1 x _ret_ setint3 #event_se1 'enable interrupt on event ' ' ' ADC interrupt service routine - runs in background ' adc_isr akpin pin 'let ADC adjust before GIO measurement resi3 rdpin lev_gio,pin 'read GIO measurement wrpin adc_pin,pin 'connect ADC to pin resi3 akpin pin 'let ADC adjust before pin measurement resi3 rdpin lev_pin,pin 'read pin measurement wrpin adc_vio,pin 'connect ADC to VIO resi3 akpin pin 'let ADC adjust before VIO measurement resi3 rdpin lev_vio,pin 'read VIO measurement wrpin adc_gio,pin 'connect ADC to GIO sub lev_vio,lev_gio 'tune measurement period so that cmp lev_vio,target wcz 'VIO - GIO = target count if_ne sumnc clocks,#1 if_ne wxpin clocks,pin sub lev_pin,lev_gio 'get pin sample mov sample,lev_pin mov x,#0 'scan thresholds for button pattern .loop altgw x,#thresholds getword y cmp y,sample wc if_nc incmod x,#15 wc if_nc jmp #.loop mov states,x drvnot #8 mov ijmp3,#adc_isr 'loop to start on next interrupt reti3 ' ' ' Defined data ' target long round(scale) clocks long round(scale * 1.5) adc_gio long p_adc_gio | p_count_highs adc_pin long p_adc_1x | p_count_highs adc_vio long p_adc_vio | p_count_highs thresholds word t0000,t0001,t0010,t0011,t0100,t0101,t0110,t0111 word t1000,t1001,t1010,t1011,t1100,t1101,t1110,t1111 adc_end ' ' ' Undefined data ' x res 1 y res 1 pin res 1 lev_gio res 1 lev_pin res 1 lev_vio res 1 sample res 1 states res 1