/* vim: noexpandtab fileencoding=utf-8 nomodified nowrap textwidth=200 foldmethod=marker foldmarker={{{,}}} foldcolumn=4 ruler showcmd lcs=tab\:|- list: */ #define VERZE "ChipTest v.0.6 (pins)" /* ChipTest - Scans for chip, manipulates pins, 115.200 Bd, ANSI color HW: Arduino Mega + ShieldMega-001 TL;DR; H-Help, T-test (see help() for more) examples: 10:^ set pin D10 to weak pullup (INPUT_PULLUP) - if it is input on 74HCxx, then it counts as log. 1; if it is output, it will be driven to output value vvvvv (Space+5v) set pins 0..4 to weak pulldown (INPUT+5k Ohm) 13:1 set pin 13 to logical 1 (digitalWrite(HIGH);) - input is logical 1, if it is output and driven toward zero, then it cannot destroy anything, as there is 500 Ohm resistor anyway 2:0000^v set pins 2..5 to logical 0 (digitalWrite(LOW);), 6 to ^ and 7 to v // ShieldMega-001 have pulldown resistors for all zif40 pins */ // #define SERIAL_SPEED 9600 #define SERIAL_SPEED 115200 #include #include "b40.h" #define INPUTLINE_LENGTH 80 #include "InputLine.h" InputLine line; #define BUTTON_PIN 2 // {{{ NeoPixel #include "Adafruit_NeoPixel.h" #define NEO_PIN A15 #define NUMPIXELS 2 Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, NEO_PIN, NEO_GRB + NEO_KHZ800); uint32_t colNone=pixels.Color(0,0,0), colRed=pixels.Color(32,0,0), colDRed=pixels.Color(8,0,0), colGreen=pixels.Color(0,32,0), colDGreen=pixels.Color(0,8,0), colBlue=pixels.Color(0,0,32), colLBlue=pixels.Color(16,16,32), colGray=pixels.Color(16,16,16), colYellow=pixels.Color(8,4,2), colWhite=pixels.Color(32,32,32); // }}} #define P(A) Serial.print(F(A)); #define Pn(A) Serial.println(F(A)); #define Pnl() Serial.println(); #define Px(A) Serial.print(A); #define Pxn(A) Serial.println(A); int zif40[] = {53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 5, 6, 7, 8, 9, 10, 11, 12 }; class Pin { // {{{ private: uint8_t count, pin[40]; bool zeroBased; public: int GND, PWR; Pin(bool zb) : count(40), GND(-1), PWR(-1), zeroBased(zb) {for (uint8_t i=0; i=count) {P(" ERROR - out of range ");Px(p);P(">");Px(count);Pn(" in pinMode");}; if (p==PWR || p==GND) { mode=OUTPUT; ::pinMode(zif40[pin[p-(zeroBased?0:1)]], mode); ::digitalWrite(zif40[pin[p-(zeroBased?0:1)]],(p==PWR)?1:0); } else { ::pinMode(zif40[pin[p-(zeroBased?0:1)]], mode); }; }; bool digitalRead(uint8_t p) { if (p-(zeroBased?0:1)>=count) {P(" ERROR - out of range ");Px(p);P(">");Px(count);Pn(" in digitalRead");}; return ::digitalRead(zif40[pin[p-(zeroBased?0:1)]]); }; void digitalWrite(uint8_t p, bool b) { if (p-(zeroBased?0:1)>=count) {P(" ERROR - out of range ");Px(p);P(">");Px(count);Pn(" in digitalWrite");}; if (p==PWR || p==GND) return; ::digitalWrite(zif40[pin[p-(zeroBased?0:1)]], b); }; void point(uint8_t p, uint8_t val) {pin[p-(zeroBased?0:1)] = val;}; void limit(uint8_t val) {count=val;}; uint8_t getCount() { return count; }; void dump() { // {{{ P("Pin(");Px(count);if (zeroBased) P(") zero") else P(") ONE");P("Based; PWR:");Px(PWR);P("; GND:");Px(GND);P("; ["); for (uint8_t i=0; i send line"); Pn(" delete last char"); Pn("t, T run tests"); Pn("h, H, ? print help"); Pn("( /pin:)[ |.01v^]* manipulate pins (Space, Pipe are ignored, . means no change, v pulldown, ^ pullup; if line does not start wit Space, pin number is first manipulated pin"); pinIdent.dump(); pinRemap.dump(); } // }}} void setup() { // {{{ pinLink=pinIdent; for (int i=0; i<40;++i){ pinMode(zif40[i],INPUT); // digitalWrite(i,LOW); dig[i]='v'; }; pinMode(BUTTON_PIN,INPUT_PULLUP); // internal pullup pixels.begin(); // This initializes the NeoPixel library. /* for (uint8_t i=0;i1) { hiaH.ANDwith(tmp); }; if (! tmp.val(i)) { GNDcand.set(i); }; }; // walking v for (int i=0; i<40; ++i) { pinMode(zif40[i],INPUT_PULLUP); dig[i]='^'; }; for (int i=0; i<40; ++i) { pinMode(zif40[i],INPUT); dig[i]='v'; tmp.zero(); for (int j=0; j<40;++j){ // {{{ test pins bb = digitalRead(zif40[j]); b = match(bb, dig[j]); if (!b) alive.set(j); tmp.set(j,bb); }; // }}} status(); dig[i]='^'; pinMode(zif40[i],INPUT_PULLUP); // if (!tmp.isZero()) hiaH.ANDwith(tmp); }; // -------------------------------------------------------------------------------- int pins = 0; pinRemap.limit(40); for (int i=0; i<40;++i){ // {{{ ~~##~~ mezery(i); if (alive.val(i)) { P("#"); pinRemap.point(++pins,i); // ONEbased } else { P("~"); }; }; // }}} pinRemap.limit(pins); P(" Pins found: "); Pxn(pins); // -------------------------------------------------------------------------------- uint8_t ch_GND,ch_PWR,ch_pins, ch_from, ch_to; bool chb_GND, chb_PWR, chb_pins, chb_ok; ch_GND=255; ch_PWR=255; ch_pins=0; ch_from=255; ch_to=255; chb_GND=false; chb_PWR=false; chb_pins=true; for (int i=0; i<40/2;++i){ // {{{ chip pins, from, to if (alive.val(i) || alive.val(40-1-i)) { ch_pins += 2; if (ch_from==255) ch_from = i; ch_to = i; }; if (alive.val(i) != alive.val(40-1-i)) { chb_pins=false; }; }; // }}} if (!GNDcand.isZero()) { // {{{ chb_GND, ch_GND P("GND candidates:"); for (int i=0; i<40;++i) if (GNDcand.val(i)) { ch_GND=i; P(" ");Px(i); }; chb_GND = (GNDcand.bits()==1); if (chb_GND) { P(" - OK "); if (ch_GND == ch_to) { P("Gnd L.Dn "); if (hiaH.val(40-1-ch_from)) { chb_PWR = true; ch_PWR = 40-1-ch_from; P("and PWR R.Up, nice - "); Px(ch_PWR); }; } else if (ch_GND == 40-1-ch_from) { P("Gnd R.Up "); if (hiaH.val(ch_to)) { chb_PWR = true; ch_PWR = ch_to; P("and PWR L.Dn, nice - "); Px(ch_PWR); }; } else { P("Gnd in middle "); if ( (ch_GND < 20 )) P( "left") else P("right"); if (hiaH.val(40-1-ch_GND)) { chb_PWR = true; ch_PWR = 40-1-ch_GND; P("and PWR in middle "); if ( (ch_PWR < 20 )) P( "left") else P("right"); P(" nice - "); Px(ch_PWR); }; }; }; Pnl(); }; // }}} if (!hiaH.isZero()) { // {{{ uint8_t x; P("High if any High:"); for (int i=0; i<40;++i) if (hiaH.val(i)) { x=i; P(" ");Px(i); }; if (hiaH.bits()==1) { P(" - OK "); if (chb_GND) { P("chb_GND set " ANSI_CLASH ) } else if (x==ch_PWR) { P("(we know) "); } else { if (ch_PWR!=255) { P(ANSI_CLASH); } else { chb_PWR=true; ch_PWR=x; if (ch_PWR == ch_to) { P("Pwr L.Dn "); if (GNDcand.val(40-1-ch_from)) { chb_GND = true; ch_GND = 40-1-ch_from; P("and Gnd R.Up, nice - "); Px(ch_GND); }; } else if (ch_PWR == 40-1-ch_from) { P("Pwr R.Up "); if (GNDcand.val(ch_to)) { chb_GND = true; ch_GND = ch_to; P("and Gnd L.Dn, nice - "); Px(ch_GND); }; } else { P("Pwr in middle "); if ( (ch_PWR < 20 )) P( "left") else P("right"); if (GNDcand.val(40-1-ch_PWR)) { chb_GND = true; ch_GND = 40-1-ch_PWR; P("and Gnd in middle "); if ( (ch_GND < 20 )) P( "left") else P("right"); P(" nice - "); Px(ch_GND); }; }; }; }; }; Pnl(); }; // }}} // -------------------------------------------------------------------------------- P("Chip pins: ");Px(ch_pins);P(" from ");Px(ch_from);P(" to ");Px(ch_to);P(" and back from "); Px(40-1-ch_to);P(" to ");Px(40-1-ch_from);Pnl(); chb_ok = chb_GND && chb_PWR && chb_pins && (pins == ch_pins); // && (chb_GND+chb_PWR == 40-1); if (! chb_ok) { Pn("Chip looks: " ANSI_strange ANSI_GREY); pixels.setPixelColor(0,colRed); pixels.show(); }; if (chb_ok) { Pn("Chip looks: " ANSI_OK); pixels.setPixelColor((ch_GND < 20)?0:1,colGreen); pixels.show(); P(" Face "); if ( (ch_GND < 20 )) P("Up") else P("Down"); Pnl(); }; pinRemap.PWR=-1;pinRemap.GND=-1; P("Recomendation: R ");Px(pins);P(": "); if ( (ch_GND < 20 )) { Px(ch_from); P(".."); Px(ch_to); uint8_t x=pins-1-((40-1-ch_from)-ch_PWR)+1; pinRemap.PWR=chb_ok?x:-1; P(" P:");Px(x); x=ch_GND-ch_from+1; pinRemap.GND=chb_ok?x:-1; P(" G:"); Px(x); } else { Px(40-1-ch_to); P(".."); Px(40-1-ch_from); uint8_t x=ch_GND-(40-1-ch_to)+1; pinRemap.GND=chb_ok?x:-1; P(" G:"); Px(x); x=pins-1-(ch_to-ch_PWR)+1; pinRemap.PWR=chb_ok?x:-1; P(" P:");Px(x); }; Pn(ANSI_END); pinRemap.dump(); // -------------------------------------------------------------------------------- } // }}} void err(int linepos, char c, const char *msg) { // {{{ pixels.setPixelColor(0,colDRed); pixels.setPixelColor(1, colNone); pixels.show(); if (linepos>1) { for (int i=1; i'9')) { err(line.atChar,c,"Space or : expected"); return;}; if (c!=' ') { if(! line.get_uint8_t(pin0)) { err(line.atChar,line.buff[line.atChar], "bad pin0 number"); return;}; if( pin0 >= 40 ) { err(line.atChar,line.buff[line.atChar], "too big pin0 number"); return;}; c=line.nextChar(); if ( c != ':' ) { err(line.atChar,c,": expected"); return;}; }; // from pin0 read 01v^ while ((c=line.nextChar())) { if (c == ' ' || c == '|') continue; if (pin0 >= 40) { err(line.atChar,c,"too many symbols"); break; }; uint8_t x=pin0; pin0++; if (c == '.' ) { continue; }; if (c=='0') {pinMode(zif40[x],OUTPUT);digitalWrite(zif40[x],LOW); } else if (c=='1') {pinMode(zif40[x],OUTPUT);digitalWrite(zif40[x],HIGH); } else if (c=='v') {pinMode(zif40[x],INPUT); } else if (c=='^') {pinMode(zif40[x],INPUT_PULLUP); } else { err(line.atChar,c,"unknown symbol"); break; }; dig[x]=c; }; Serial.println("OK"); } // }}} void loop() { line.Update(); if (line.isReady()){ if (line.charsReady ==0) { pixels.setPixelColor(0,colDGreen); pixels.setPixelColor(1, colNone); pixels.show(); status(); } else { pixels.setPixelColor(0,colDGreen); pixels.setPixelColor(1, colNone); pixels.show(); solveLine(); headers(); status(); }; }; if (0==digitalRead(BUTTON_PIN)) { test(); headers(); status(); }; }