Exemple #1
0
/*
 * Fastinit: ISO14230-2 sec 5.2.4.2.3
 * Caller should have waited W5 (>300ms) before calling this (from _initbus only!)
 * we assume the L line was at the correct state (1) during that time.
 * returns 0 (success), 50ms after starting the wake-up pattern.
 * Exceptionally we dont diag_iseterr on return since _initbus() takes care of that.
 */
static int
diag_l0_dumb_fastinit(struct diag_l0_device *dl0d)
{
	int rv=0;
	uint8_t cbuf[MAXRBUF];

	if (diag_l0_debug & DIAG_DEBUG_INIT)
		fprintf(stderr, FLFMT "dl0d=%p fastinit\n",
			FL, (void *)dl0d);
	//Tidle before break : W5 (>300ms) on poweron; P3 (>55ms) after a StopCommunication; or 0ms after a P3 timeout.
	// We assume the caller took care of this.
	/* Send 25/25 ms break as initialisation pattern (TiniL) */
	//ISO14230-2 says we should send the same sync pattern on both L and K together.
	// we do it almost perfectly; the L \_/ pulse starts before and ends after the K \_/ pulse.

	if (dumb_flags & USE_LLINE) {
		// do K+L only if the user wants to do both
		if (dumb_flags & FAST_BREAK) {
			//but we can't use diag_tty_fastbreak while doing the L-line.
			fprintf(stderr, FLFMT "Warning : not using L line for FAST_BREAK.\n", FL);
			rv=diag_tty_fastbreak(dl0d, 50-WUPFLUSH);
		} else {
			//normal fast break on K and L.
			//note : if LLINE_INV is 1, then we need to clear RTS to pull L down !
			if (diag_tty_control(dl0d, !(dumb_flags & CLEAR_DTR), !(dumb_flags & LLINE_INV)) < 0) {
				fprintf(stderr, FLFMT "fastinit: Failed to set L\\_\n", FL);
				return DIAG_ERR_GENERAL;
				}
			rv=diag_tty_break(dl0d, 25);	//K line low for 25ms
				/* Now restore DTR/RTS */
			if (diag_tty_control(dl0d, !(dumb_flags & CLEAR_DTR), (dumb_flags & SET_RTS)) < 0) {
				fprintf(stderr, FLFMT "fastinit: Failed to restore DTR & RTS!\n",
					FL);
			}
			diag_os_millisleep(25-WUPFLUSH);
		}	//if FAST_BREAK
	} else {
		// do K line only
		if (dumb_flags & FAST_BREAK) {
			rv=diag_tty_fastbreak(dl0d, 50-WUPFLUSH);
		} else {
			//normal break
			rv=diag_tty_break(dl0d, 25);	//K line low for 25ms
			diag_os_millisleep(25-WUPFLUSH);
		}
	}	//if USE_LLINE
	// here we have WUPFLUSH ms before tWUP is done; we use this
	// short time to flush RX buffers. (L2 needs to send a StartComm
	// request very soon.)

	diag_tty_read(dl0d, cbuf, sizeof(cbuf), WUPFLUSH);


	//there may have been a problem in diag_tty_break, if so :
	if (rv) {
		fprintf(stderr, FLFMT " L0 fastinit : problem !\n", FL);
		return DIAG_ERR_GENERAL;
	}
	return 0;
}
Exemple #2
0
static void
diag_l0_dumb_Lline(struct diag_l0_device *dl0d, uint8_t ecuaddr)
{
	/*
	 * The bus has been high for w0 ms already, now send the
	 * 8 bit ecuaddr at 5 baud LSB first
	 *
	 */
	int i, rv=0;
//	uint8_t cbuf[10];

	// We also toggle DTR to disable RXD (blocking it at logical 1).
	// However, at least one system I tested doesn't react well to
	// DTR-toggling.
	/* Set RTS low, for 200ms (Start bit) */
	if (diag_tty_control(dl0d, (dumb_flags & CLEAR_DTR), !(dumb_flags & LLINE_INV)) < 0) {
		fprintf(stderr, FLFMT "_LLine: Failed to set DTR & RTS\n", FL);
		return;
	}
	diag_os_millisleep(BPS_PERIOD);		/* 200ms -5% */

	for (i=0; i<8; i++) {
		if (ecuaddr & (1<<i)) {
			/* High */
			rv |= diag_tty_control(dl0d, (dumb_flags & CLEAR_DTR), (dumb_flags & LLINE_INV));
		} else {
			/* Low */
			rv |= diag_tty_control(dl0d, (dumb_flags & CLEAR_DTR), !(dumb_flags & LLINE_INV));
		}

		if (rv < 0) {
			fprintf(stderr, FLFMT "_LLine: Failed to set DTR & RTS\n",
				FL);
			return;
		}
		diag_os_millisleep(BPS_PERIOD);		/* 200ms -5% */
	}
	/* And set high for the stop bit */
	if (diag_tty_control(dl0d, (dumb_flags & CLEAR_DTR), !(dumb_flags & LLINE_INV)) < 0) {
		fprintf(stderr, FLFMT "_LLine: Failed to set DTR & RTS\n",
			FL);
		return;
	}
	diag_os_millisleep(BPS_PERIOD);		/* 200ms -5% */

	/* Now put DTR/RTS back correctly so RX side is enabled */
	if (diag_tty_control(dl0d, !(dumb_flags & CLEAR_DTR), (dumb_flags & SET_RTS)) < 0) {
		fprintf(stderr, FLFMT "_LLine: Failed to restore DTR & RTS\n",
			FL);
	}

	/* And clear out the break XXX no, _slowinit will do this for us after calling dumb_Lline*/
//	diag_tty_read(dl0d, cbuf, sizeof(cbuf), 20);

	return;
}
Exemple #3
0
/*
 * Slowinit:
 *	We need to send a byte (the address) at 5 baud, then
 *	switch back to 10400 baud
 *	and then wait W1 (60-300ms) until we get Sync byte 0x55.
 * Caller (in L2 typically) must have waited with bus=idle beforehand.
 * This optionally does the L_line stuff according to the flags in dumb_flags.
 * Ideally returns 0 (success) immediately after receiving Sync byte.
 * This one, like fastinit, doesnt diag_iseterr when returning errors
 * since _initbus() takes care of that.
 *
 */
static int
diag_l0_dumb_slowinit(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in,
	struct diag_l0_dumb_device *dev)
{
	uint8_t cbuf[10];
	int rv;
	unsigned int tout;
	struct diag_serial_settings set;

	if (diag_l0_debug & DIAG_DEBUG_PROTO) {
		fprintf(stderr, FLFMT "slowinit dl0d=%p address 0x%X\n",
			FL, (void *)dl0d, in->addr);
	}


	//two methods of sending at 5bps. Most USB-serial converts don't support such a slow bitrate !
	if (dumb_flags & MAN_BREAK) {
		//MAN_BREAK means we bitbang K and optionally L as well.
		if (dumb_flags & USE_LLINE) {
			//do manual 5bps init on K and L.
			//we need to send the byte at in->addr, bit by bit.

			int bitcounter;
			uint8_t tempbyte=in->addr;
			diag_tty_control(dl0d, !(dumb_flags & CLEAR_DTR), !(dumb_flags & LLINE_INV));	//L is the logical opposite of RTS...
			diag_tty_break(dl0d, BPS_PERIOD);	//start startbit
			for (bitcounter=0; bitcounter<=7; bitcounter++) {
				//LSB first.
				if (tempbyte & 1) {
					diag_tty_control(dl0d, !(dumb_flags & CLEAR_DTR), (dumb_flags & LLINE_INV));	//release L
					diag_os_millisleep(BPS_PERIOD);
				} else {
					unsigned int lowtime=BPS_PERIOD;
					//to prevent spurious breaks if we have a sequence of 0's :
					//this is an RLE of sorts...
					for (; bitcounter <=6; bitcounter++) {
						if (tempbyte & 2) //test bit 1; we just tested bit 0 before getting here.
							break;
						lowtime += BPS_PERIOD;
						tempbyte = tempbyte >>1;
					}
					//this way, we know for sure the next bit is 1 (either bit 7==1 or stopbit==1 !)
					diag_tty_control(dl0d, !(dumb_flags & CLEAR_DTR), !(dumb_flags & LLINE_INV));	//pull L down
					diag_tty_break(dl0d, lowtime);
				}
				tempbyte = tempbyte >>1;
			}
			//at this point we just finished the last bit, we'll wait the duration of the stop bit.
			diag_tty_control(dl0d, !(dumb_flags & CLEAR_DTR), (dumb_flags & SET_RTS));	//release L
			diag_os_millisleep(BPS_PERIOD);	//stop bit
		} else {
Exemple #4
0
/*
 * Open the diagnostic device, returns a file descriptor
 * records original state of term interface so we can restore later
 */
static struct diag_l0_device *
diag_l0_muleng_open(const char *subinterface, int iProtocol)
{
	int rv;
	struct diag_l0_device *dl0d;
	struct diag_l0_muleng_device *dev;
	struct diag_serial_settings set;

	if (diag_l0_debug & DIAG_DEBUG_OPEN) {
		fprintf(stderr, FLFMT "open subinterface %s protocol %d\n",
			FL, subinterface, iProtocol);
	}

	diag_l0_muleng_init();

	if ((rv=diag_calloc(&dev, 1)))
		return diag_pseterr(rv);

	dev->protocol = iProtocol;

	dl0d = diag_l0_new(&diag_l0_me, (void *)dev);
	if (!dl0d) {
		free(dev);
		return diag_pseterr(rv);
	}
	/* try to open TTY */
	if ((rv=diag_tty_open(dl0d, subinterface))) {
		diag_l0_del(dl0d);
		free(dev);
		return diag_pseterr(rv);
	}

	/* And set to 19200 baud , 8N1 */

	set.speed = 19200;
	set.databits = diag_databits_8;
	set.stopbits = diag_stopbits_1;
	set.parflag = diag_par_n;

	if ((rv=diag_tty_setup(dl0d, &set))) {
		diag_l0_muleng_close(dl0d);
		return diag_pseterr(rv);
	}

	/* And set DTR high and RTS low to power the device */
	if ((rv=diag_tty_control(dl0d, 1, 0))) {
		diag_l0_muleng_close(dl0d);
		return diag_pseterr(rv);
	}

	diag_tty_iflush(dl0d);	/* Flush unread input */

	return dl0d ;
}
Exemple #5
0
/*
 * Open the diagnostic device, returns a file descriptor
 * records original state of term interface so we can restore later
 */
static struct diag_l0_device *
diag_l0_dumb_open(const char *subinterface, int iProtocol)
{
	int rv;
	struct diag_l0_device *dl0d;
	struct diag_l0_dumb_device *dev;

	if (diag_l0_debug & DIAG_DEBUG_OPEN) {
		fprintf(stderr, FLFMT "open subinterface %s protocol %d\n",
			FL, subinterface, iProtocol);
	}

	diag_l0_dumb_init();	 //make sure it is initted

	if ((rv=diag_calloc(&dev, 1)))
		return diag_pseterr(DIAG_ERR_NOMEM);

	dev->protocol = iProtocol;

	dl0d = diag_l0_new(&diag_l0_dumb, (void *)dev);
	if (!dl0d) {
		free(dev);
		return diag_pseterr(rv);
	}
	/* try to open TTY */
	if ((rv=diag_tty_open(dl0d, subinterface))) {
		diag_l0_del(dl0d);
		free(dev);
		return diag_pseterr(rv);
	}

	/*
	 * We set RTS to low, and DTR high, because this allows some
	 * interfaces to work than need power from the DTR/RTS lines;
	 * this is altered according to dumb_flags.
	 */
	if (diag_tty_control(dl0d, !(dumb_flags & CLEAR_DTR), (dumb_flags & SET_RTS)) < 0) {
		diag_l0_dumb_close(&dl0d);
		return diag_pseterr(DIAG_ERR_GENERAL);
	}

	if (dumb_flags & DUMBDEFAULTS)
		dumb_flags = DUMBDEFAULTS & MAN_BREAK;

	(void)diag_tty_iflush(dl0d);	/* Flush unread input */

	return dl0d;
}