repcode() { outcont(0); yyval = genlab(); outcont(yyval); brkstk[++brkptr] = yyval+1; genlab(); genlab(); }
repcode() { transfer = 0; outcont(0); putcom("repeat"); yyval = genlab(3); indent++; outcont(yyval); brkstk[++brkptr] = yyval+1; typestk[brkptr] = REPEAT; brkused[brkptr] = 0; }
static void scanner_chessboard_control(struct parport *port) { /* Wiggle C1 and C3 (twice) */ outboth(port, 0x0, 13); usleep(10); outcont(port, 7, 0xf); usleep(10); outcont(port, 13, 0xf); usleep(10); outcont(port, 7, 0xf); usleep(10); }
/* Reset the scanner. At least, it works 50% of the time. */ static int scanner_reset(struct parport *port) { /* Resetting only works for the *30Ps, sorry */ if (readstatus(port) == 0x0b) { /* Init Block 1 - composed of a 0-byte IEEE read */ ieee1284_negotiate(port, 0x0); ieee1284_terminate(port); ieee1284_negotiate(port, 0x0); ieee1284_terminate(port); scanner_chessboard_data(port, 1); scanner_chessboard_data(port, 1); scanner_chessboard_data(port, 1); scanner_chessboard_data(port, 1); scanner_chessboard_data(port, 0); scanner_chessboard_data(port, 0); scanner_chessboard_data(port, 0); scanner_chessboard_data(port, 0); } /* Reset Block 2 =============== */ outboth(port, 0x04, 0x0d); /* Specifically, we want this: 00111 on S */ if (expect(port, "Reset 2 response 1", 0x7, 0x1f, 500000)) return 1; outcont(port, 0, HOSTCLK); usleep(5); outcont(port, 0x0f, 0xf); /* All lines must be 1. */ /* All lines 1 */ if (expect(port, "Reset 2 response 2 (READY)", 0x1f, 0x1f, 500000)) return 1; outcont(port, 0, HOSTBUSY); usleep(100000); /* a short pause */ outcont(port, HOSTBUSY, HOSTBUSY | NSELECTIN); return 0; }
static void scanner_chessboard_data(struct parport *port, int mode) { int count; /* initial weirdness here for 620P - seems to go quite fast, * just ignore it! */ for (count = 0; count < 2; count++) { /* Wiggle data lines (4 times) while strobing C1 */ /* 33 here for *30P, 55 for *20P */ if (mode == INITMODE_20P) outdata(port, 0x55); else outdata(port, 0x33); outcont(port, HOSTBUSY, HOSTBUSY); usleep(10); outcont(port, 0, HOSTBUSY); usleep(10); outcont(port, HOSTBUSY, HOSTBUSY); usleep(10); if (mode == INITMODE_20P) outdata(port, 0xaa); else outdata(port, 0xcc); outcont(port, HOSTBUSY, HOSTBUSY); usleep(10); outcont(port, 0, HOSTBUSY); usleep(10); outcont(port, HOSTBUSY, HOSTBUSY); usleep(10); } }
/* Send a byte to both ports */ static void outboth(struct parport *port, int d, int c) { ieee1284_write_data(port, d & 0xff); outcont(port, c, 0x0f); }
int sanei_canon_pp_read(struct parport *port, int length, unsigned char *data) { int count, offset; DBG(200, "NEW read_data (%i bytes):\n", length); ieee1284_negotiate(port, ieee_mode); /* This is special; Nibble mode needs a little extra help from us. */ if (ieee_mode == M1284_NIBBLE) { /* Interrupt phase */ outcont(port, NSELECTIN, HOSTBUSY | NSELECTIN); if (expect(port, "Read Data 1", 0, NDATAAVAIL, 6000000)) { DBG(10,"Error 1\n"); ieee1284_terminate(port); return 1; } outcont(port, HOSTBUSY, HOSTBUSY); if (expect(port, "Read Data 2", NACK, NACK, 1000000)) { DBG(1,"Error 2\n"); ieee1284_terminate(port); return 1; } if (expect(port, "Read Data 3 (Ready?)", 0, PERROR, 1000000)) { DBG(1,"Error 3\n"); ieee1284_terminate(port); return 1; } /* Host-Busy Data Available phase */ if ((readstatus(port) & NDATAAVAIL) == NDATAAVAIL) { DBG(1,"No data to read.\n"); ieee1284_terminate(port); return 1; } } offset = 0; DBG(100, "-> ieee_transfer(%d) *\n", length); count = ieee_transfer(port, length, data); DBG(100, "<- (%d)\n", count); /* Early-out if it was not implemented */ if (count == E1284_NOTIMPL) return 2; length -= count; offset+= count; while (length > 0) { /* If 0 bytes were transferred, it's a legal "No data" condition (I think). Otherwise, it may have run out of buffer.. keep reading*/ if (count < 0) { DBG(10, "Couldn't read enough data (need %d more " "of %d)\n", length+count,length+offset); ieee1284_terminate(port); return 1; } DBG(100, "-> ieee_transfer(%d)\n", length); count = ieee_transfer(port, length, data+offset); DBG(100, "<- (%d)\n", count); length-=count; offset+= count; } #ifdef DUMP_PACKETS if (length <= 60) { DBG(10,"Read: "); for (count = 0; count < length; count++) { DBG(10,"%02x ", data[count]); if (count % 20 == 19) DBG(10,"\n "); } if (count % 20 != 19) DBG(10,"\n"); } else { DBG(10,"Read: %i bytes\n", length); } #endif if (ieee_mode == M1284_NIBBLE) ieee1284_terminate(port); return 0; }
int sanei_canon_pp_wake_scanner(struct parport *port, int mode) { /* The scanner tristates the printer's control lines (essentially disabling the passthrough port) and exits from Transparent Mode ready for communication. */ int i = 0; int tmp; int max_cycles = 3; tmp = readstatus(port); /* Reset only works on 30/40 models */ if (mode != INITMODE_20P) { if ((tmp != READY)) { DBG(40, "Scanner not ready (0x%x). Attempting to " "reset...\n", tmp); scanner_reset(port); /* give it more of a chance to reset in this case */ max_cycles = 5; } } else { DBG(0, "WARNING: Don't know how to reset an FBx20P, you may " "have to power cycle\n"); } do { i++; /* Send the wakeup sequence */ scanner_chessboard_control(port); scanner_chessboard_data(port, mode); if (expect(port, NULL, 0x03, 0x1f, 800000) && (mode == INITMODE_AUTO)) { /* 630 Style init failed, try 620 style */ scanner_chessboard_control(port); scanner_chessboard_data(port, INITMODE_20P); } if (expect(port, "Scanner wakeup reply 1", 0x03, 0x1f, 50000)) { outboth(port, 0x04, 0x0d); usleep(100000); outcont(port, 0x07, 0x0f); usleep(100000); } } while ((i < max_cycles) && (!expect(port,"Scanner wakeup reply 2", 0x03, 0x1f, 100000) == 0)); /* Block just after chessboarding Reply 1 (S3 and S4 on, S5 and S7 off) */ outcont(port, 0, HOSTBUSY); /* C1 off */ /* Reply 2 - If it ain't happening by now, it ain't gonna happen. */ if (expect(port, "Reply 2", 0xc, 0x1f, 800000)) return -1; outcont(port, HOSTBUSY, HOSTBUSY); /* C1 on */ if (expect(port, "Reply 3", 0x0b, 0x1f, 800000)) return -1; outboth(port, 0, NSELECTIN | NINIT | HOSTCLK); /* Clear D, C3+, C1- */ /* If we had to try the wakeup cycle more than once, we should wait * here for 10 seconds to let the scanner pull itself together - * it can actually take longer, but I can't wait that long! */ if (i > 1) { DBG(10, "Had to reset scanner, waiting for the " "head to get back.\n"); usleep(10000000); } return 0; }