Beispiel #1
0
static GOOD_OR_BAD OW_w_std(BYTE *buf, size_t size, BYTE type, BYTE stype, const struct parsedname *pn)
{
	BYTE p[4] = { _1W_WRITE_MOAT, type,stype, size};
	BYTE crcbuf[2];
	UINT crc;

	struct transaction_log tfirst[] = {
		TRXN_START,
		TRXN_WRITE(p,4),
		TRXN_WRITE(buf,size),
		TRXN_READ2(crcbuf),
		TRXN_END,
	};
	struct transaction_log xmit_crc[] = {
		TRXN_WRITE2(crcbuf),
		TRXN_END,
	};

	if (size == 0) {
		return gbGOOD;
	}
	if (size > 255) {
		return gbBAD;
	}

	LEVEL_DEBUG( "write: %d for %d %d",size,type,stype) ;
	
	if ( BAD(BUS_transaction(tfirst, pn))) {
		goto out_bad;
	}

	crc = CRC16compute(p,4,0);
	crc = CRC16compute(buf,size,crc);
	if ( CRC16seeded (crcbuf,2,crc) ) {
		LEVEL_DEBUG("CRC error");
		goto out_bad;
	}
	LEVEL_DEBUG( "read CRC: GOOD, got %02x%02x",crcbuf[0],crcbuf[1]) ;
	crcbuf[0] = ~crcbuf[0];
	crcbuf[1] = ~crcbuf[1];
	if ( BAD(BUS_transaction(xmit_crc, pn)) ) {
		goto out_bad;
	}
	return gbGOOD;
out_bad:
	return gbBAD;
}
Beispiel #2
0
/* write to 2450 */
static GOOD_OR_BAD OW_w_mem(BYTE * p, size_t size, off_t offset, struct parsedname *pn)
{
	// command, address(2) , data , crc(2), databack
	BYTE buf[6] = { _1W_WRITE_MEMORY, LOW_HIGH_ADDRESS(offset), p[0], };
	BYTE echo[1];
	size_t i;
	struct transaction_log tfirst[] = {
		TRXN_START,
		TRXN_WR_CRC16(buf, 4, 0),
		TRXN_READ1(echo),
		TRXN_COMPARE(echo, p, 1),
		TRXN_END,
	};
	struct transaction_log trest[] = {	// note no TRXN_START
		TRXN_WRITE1(buf),
		TRXN_READ2(&buf[1]),
		TRXN_READ1(echo),
		TRXN_END,
	};
//printf("2450 W mem size=%d location=%d\n",size,location) ;

	if (size == 0) {
		return gbGOOD;
	}

	/* Send the first byte (handled differently) */
	RETURN_BAD_IF_BAD(BUS_transaction(tfirst, pn)) ;
	/* rest of the bytes */
	for (i = 1; i < size; ++i) {
		buf[0] = p[i];
		RETURN_BAD_IF_BAD( BUS_transaction(trest, pn) ) ;
		if ( CRC16seeded(buf, 3, offset + i) || (echo[0] != p[i]) ) {
			return gbBAD;
		}
	}
	return gbGOOD;
}
Beispiel #3
0
static GOOD_OR_BAD OW_r_std(BYTE *buf, size_t *buflen, BYTE type, BYTE stype, const struct parsedname *pn)
{
	BYTE p[3] = { _1W_READ_MOAT, type,stype };

    size_t maxlen = *buflen;
    BYTE len;
	GOOD_OR_BAD ret = gbGOOD;

	struct transaction_log tfirst[] = {
		TRXN_START,
		TRXN_WRITE3(p),
		TRXN_READ1(&len),
		TRXN_END,
	};
	if (maxlen == 0) {
		return gbGOOD;
	}

	LEVEL_DEBUG( "read: read len for %d %d",type,stype) ;
	/* 0xFF means the device was too slow */
	if ( BAD(BUS_transaction(tfirst, pn)) || len == 0xFF) {
		goto out_bad;
	}
	LEVEL_DEBUG( "read: got len %d",len) ;
	if (len > maxlen) {
		/* don't read all and don't bother with CRC.
		 * This will abort the read on the client side so that
		 * there'll be no side effects like marked-as-sent buffers
		 * or cleared 'conditional search' flags */
		struct transaction_log tinfo[] = {
			TRXN_READ(buf,maxlen),
			TRXN_END,
		};

		if ( BAD(BUS_transaction(tinfo, pn)) ) {
			goto out_bad;
		}
	} else {
		UINT crc;
		BYTE crcbuf[2];
		struct transaction_log recv_buf[] = {
			TRXN_READ(buf,len),
			TRXN_READ2(crcbuf),
			TRXN_END,
		};
		struct transaction_log recv_crc[] = {
			TRXN_READ2(crcbuf),
			TRXN_END,
		};
		struct transaction_log xmit_crc[] = {
			TRXN_WRITE2(crcbuf),
			TRXN_END,
		};

		if ( BAD(BUS_transaction(len ? recv_buf : recv_crc, pn)) ) {
			goto out_bad;
		}

		crc = CRC16compute(p,3,0);
		crc = CRC16compute(&len,1,crc);
		if (len) crc = CRC16compute(buf,len,crc);
		LEVEL_DEBUG( "read CRC: GOOD, got %02x%02x",crcbuf[0],crcbuf[1]) ;
		if ( CRC16seeded (crcbuf,2,crc) ) {
			LEVEL_DEBUG("CRC error");
			goto out_bad;
		}
		crcbuf[0] = ~crcbuf[0];
		crcbuf[1] = ~crcbuf[1];
		if ( BAD(BUS_transaction(xmit_crc, pn)) ) {
			goto out_bad;
		}
		*buflen = len;
	}

	LEVEL_DEBUG( "read: GOOD, got %d",*buflen) ;
	return ret;
out_bad:
	return gbBAD;
}
static GOOD_OR_BAD BUS_transaction_single(const struct transaction_log *t, const struct parsedname *pn)
{
	GOOD_OR_BAD ret = gbGOOD;
	switch (t->type) {
	case trxn_select:			// select a 1-wire device (by unique ID)
		ret = BUS_select(pn);
		LEVEL_DEBUG("select = %d", ret);
		break;
	case trxn_compare:			// match two strings -- no actual 1-wire
		if ((t->in == NULL) || (t->out == NULL)
			|| (memcmp(t->in, t->out, t->size) != 0)) {
			ret = gbBAD;
		}
		LEVEL_DEBUG("compare = %d", ret);
		break;
	case trxn_bitcompare:			// match two strings -- no actual 1-wire
		if ((t->in == NULL) || (t->out == NULL)
			|| BAD( BUS_compare_bits( t->in, t->out, t->size)) ) {
			ret = gbBAD;
		}
		LEVEL_DEBUG("compare = %d", ret);
		break;
	case trxn_match:			// send data and compare response
		assert(t->in == NULL);	// else use trxn_compare
		if (t->size == 0) {		/* ignore for both cases */
			break;
		} else {
			ret = BUS_send_data(t->out, t->size, pn);
			LEVEL_DEBUG("send = %d", ret);
		}
		break;
	case trxn_bitmatch:			// send data and compare response
		assert(t->in == NULL);	// else use trxn_compare
		if (t->size == 0) {		/* ignore for both cases */
			break;
		} else {
			ret = BUS_send_bits(t->out, t->size, pn);
			LEVEL_DEBUG("send bits = %d", ret);
		}
		break;
	case trxn_read:
		assert(t->out == NULL);	// pure read
		if (t->size == 0) {		/* ignore for all cases */
			break;
		} else if (t->out == NULL) {
			ret = BUS_readin_data(t->in, t->size, pn);
			LEVEL_DEBUG("readin = %d", ret);
		}
		break;
	case trxn_bitread:
		assert(t->out == NULL);	// pure read
		if (t->size == 0) {		/* ignore for all cases */
			break;
		} else if (t->out == NULL) {
			ret = BUS_readin_bits(t->in, t->size, pn);
			LEVEL_DEBUG("readin bits = %d", ret);
		}
		break;
	case trxn_modify:			// write data and read response. No match needed
		ret = BUS_sendback_data(t->out, t->in, t->size, pn);
		LEVEL_DEBUG("modify = %d", ret);
		break;
	case trxn_bitmodify:			// write data and read response. No match needed
		ret = BUS_sendback_bits(t->out, t->in, t->size, pn);
		LEVEL_DEBUG("bit modify = %d", ret);
		break;
	case trxn_blind:			// write data ignore response
		{
			BYTE *dummy = owmalloc(t->size);
			if (dummy != NULL) {
				ret = BUS_sendback_data(t->out, dummy, t->size, pn);
				owfree(dummy);
			} else {
				ret = gbBAD;
			}
		}
		LEVEL_DEBUG("blind = %d", ret);
		break;
	case trxn_power:
		ret = BUS_PowerByte(t->out[0], t->in, t->size, pn);
		LEVEL_DEBUG("power (%d usec) = %d", t->size, ret);
		break;
	case trxn_bitpower:
		ret = BUS_PowerBit(t->out[0], t->in, t->size, pn);
		LEVEL_DEBUG("power bit (%d usec) = %d", t->size, ret);
		break;
	case trxn_program:
		ret = BUS_ProgramPulse(pn);
		LEVEL_DEBUG("program pulse = %d", ret);
		break;
	case trxn_crc8:
		ret = CRC8(t->out, t->size);
		LEVEL_DEBUG("CRC8 = %d", ret);
		break;
	case trxn_crc8seeded:
		ret = CRC8seeded(t->out, t->size, ((UINT *) (t->in))[0]);
		LEVEL_DEBUG("seeded CRC8 = %d", ret);
		break;
	case trxn_crc16:
		ret = CRC16(t->out, t->size);
		LEVEL_DEBUG("CRC16 = %d", ret);
		break;
	case trxn_crc16seeded:
		ret = CRC16seeded(t->out, t->size, ((UINT *) (t->in))[0]);
		LEVEL_DEBUG("seeded CRC16 = %d", ret);
		break;
	case trxn_delay:
		if (t->size > 0) {
			UT_delay(t->size);
		}
		LEVEL_DEBUG("Delay %d", t->size);
		break;
	case trxn_udelay:
		if (t->size > 0) {
			UT_delay_us(t->size);
		}
		LEVEL_DEBUG("Micro Delay %d", t->size);
		break;
	case trxn_reset:
		ret = BUS_reset(pn)==BUS_RESET_OK ? gbGOOD : gbBAD;
		LEVEL_DEBUG("reset = %d", ret);
		break;
	case trxn_end:
		LEVEL_DEBUG("end = %d", ret);
		return gbOTHER;			// special "end" flag
	case trxn_verify:
		{
			struct parsedname pn2;
			memcpy(&pn2, pn, sizeof(struct parsedname));	//shallow copy
			pn2.selected_device = NO_DEVICE;
			if ( BAD( BUS_select(&pn2) )) {
				ret = gbBAD ;
			} else if ( BAD(BUS_verify(t->size, pn) )) {
				ret = gbBAD ;
			} else {
				ret = gbGOOD;
			}
			LEVEL_DEBUG("verify = %d", ret);
		}
		break;
	case trxn_nop:
		ret = gbGOOD;
		break;
	}
	return ret;
}
static GOOD_OR_BAD Bundle_unpack(struct transaction_bundle *tb)
{
	int packet_index;
	const struct transaction_log *tl;
	BYTE *data = MemblobData(&(tb->mb));
	GOOD_OR_BAD ret = gbGOOD;

	LEVEL_DEBUG("unpacking");

	for (packet_index = 0, tl = tb->start; packet_index < tb->packets; ++packet_index, ++tl) {
		switch (tl->type) {
		case trxn_compare:		// match two strings -- no actual 1-wire
			LEVEL_DEBUG("unpacking #%d COMPARE", packet_index);
			if ((tl->in == NULL) || (tl->out == NULL)
				|| (memcmp(tl->in, tl->out, tl->size) != 0)) {
				ret = gbBAD;
			}
			break;
		case trxn_bitcompare:			// match two strings -- no actual 1-wire
			if ((tl->in == NULL) || (tl->out == NULL)
				|| BAD( BUS_compare_bits( tl->in, tl->out, tl->size)) ) {
				ret = gbBAD;
			}
			break ;
		case trxn_match:		// send data and compare response
			LEVEL_DEBUG("unpacking #%d MATCH", packet_index);
			if (memcmp(tl->out, data, tl->size) != 0) {
				ret = gbBAD;
			}
			data += tl->size;
			break;
		case trxn_read:
		case trxn_modify:		// write data and read response. No match needed
			LEVEL_DEBUG("unpacking #%d READ MODIFY", packet_index);
			memmove(tl->in, data, tl->size);
			data += tl->size;
			break;
		case trxn_blind:
			LEVEL_DEBUG("unpacking #%d BLIND", packet_index);
			data += tl->size;
			break;
		case trxn_power:
		case trxn_program:
			LEVEL_DEBUG("unpacking #%d POWER PROGRAM", packet_index);
			memmove(tl->in, data, 1);
			data += 1;
			UT_delay(tl->size);
			break;
		case trxn_crc8:
			LEVEL_DEBUG("unpacking #%d CRC8", packet_index);
			if (CRC8(tl->out, tl->size) != 0) {
				ret = gbBAD;
			}
			break;
		case trxn_crc8seeded:
			LEVEL_DEBUG("unpacking #%d CRC8 SEEDED", packet_index);
			if (CRC8seeded(tl->out, tl->size, ((UINT *) (tl->in))[0]) != 0) {
				ret = gbBAD;
			}
			break;
		case trxn_crc16:
			LEVEL_DEBUG("unpacking #%d CRC16", packet_index);
			if (CRC16(tl->out, tl->size) != 0) {
				ret = gbBAD;
			}
			break;
		case trxn_crc16seeded:
			LEVEL_DEBUG("unpacking #%d CRC16 SEEDED", packet_index);
			if (CRC16seeded(tl->out, tl->size, ((UINT *) (tl->in))[0]) != 0) {
				ret = gbBAD;
			}
			break;
		case trxn_delay:
			LEVEL_DEBUG("unpacking #%d DELAY", packet_index);
			UT_delay(tl->size);
			break;
		case trxn_udelay:
			LEVEL_DEBUG("unpacking #%d UDELAY", packet_index);
			UT_delay_us(tl->size);
			break;
		case trxn_reset:
		case trxn_end:
		case trxn_verify:
			// should never get here
			LEVEL_DEBUG("unpacking #%d RESET END VERIFY", packet_index);
			ret = gbBAD;
			break;
		case trxn_nop:
		case trxn_select:
			LEVEL_DEBUG("unpacking #%d NOP or SELECT", packet_index);
			break;
		case trxn_bitmatch:
			LEVEL_DEBUG("Unsupported transaction request trxn_bitmatch");
			break ;
		case trxn_bitmodify:
			LEVEL_DEBUG("Unsupported transaction request trxn_bitmodify");
			break ;
		case trxn_bitread:
			LEVEL_DEBUG("Unsupported transaction request trxn_bitread");
			break ;
		case trxn_bitpower:
			LEVEL_DEBUG("Unsupported transaction request trxn_bitpower");
			break ;
		}
		if ( BAD(ret) ) {
			break;
		}
	}

	// clear the bundle
	MemblobClear(&tb->mb);
	tb->packets = 0;
	tb->select_first = 0;

	return ret;
}