/* send A/D conversion command */ static GOOD_OR_BAD OW_convert( int simul_good, int delay, struct parsedname *pn) { BYTE convert[] = { _1W_CONVERT, 0x0F, 0x00, 0xFF, 0xFF, }; struct transaction_log tpower[] = { TRXN_START, TRXN_WR_CRC16(convert, 3, 0), TRXN_END, }; struct transaction_log tdead[] = { TRXN_START, TRXN_WRITE3(convert), TRXN_READ1(&convert[3]), TRXN_POWER( &convert[4], delay ) , TRXN_CRC16(convert, 5), TRXN_END, }; /* See if a conversion was globally triggered */ if ( GOOD(OW_get_power(pn) ) ) { if ( simul_good ) { return FS_Test_Simultaneous( simul_volt, delay, pn) ; } // Start conversion // 6 msec for 16bytex4channel (5.2) RETURN_BAD_IF_BAD(BUS_transaction(tpower, pn)); UT_delay(delay); /* don't need to hold line for conversion! */ } else { // Start conversion // 6 msec for 16bytex4channel (5.2) RETURN_BAD_IF_BAD(BUS_transaction(tdead, pn)) ; } return gbGOOD; }
static GOOD_OR_BAD OW_w_byte(BYTE data, off_t offset, struct parsedname *pn) { BYTE p[5] = { _1W_WRITE_MEMORY, LOW_HIGH_ADDRESS(offset), data, 0xFF }; BYTE q[1]; struct transaction_log t[] = { TRXN_START, TRXN_WRITE(p,4), TRXN_READ1(&p[4]), TRXN_CRC8(p, 4+1), TRXN_PROGRAM, TRXN_READ1(q), TRXN_COMPARE(q,&data,1) , TRXN_END, }; return BUS_transaction(t, pn) ; }
static GOOD_OR_BAD OW_w_status(BYTE * data, size_t size, off_t offset, struct parsedname *pn) { BYTE p[6] = { _1W_WRITE_STATUS, LOW_HIGH_ADDRESS(offset), data[0] }; GOOD_OR_BAD ret = gbGOOD; struct transaction_log tfirst[] = { TRXN_START, TRXN_WR_CRC16(p, 4, 0), TRXN_PROGRAM, TRXN_READ1(p), TRXN_END, }; if (size == 0) { return gbGOOD; } if (size == 1) { return BUS_transaction(tfirst, pn) || (p[0] & (~data[0])); } BUSLOCK(pn); if ( BAD(BUS_transaction(tfirst, pn)) || (p[0] & ~data[0])) { ret = gbBAD; } else { size_t i; const BYTE *d = &data[1]; UINT s = offset + 1; struct transaction_log trest[] = { //TRXN_WR_CRC16_SEEDED( p, &s, 1, 0 ) , TRXN_WR_CRC16_SEEDED(p, p, 1, 0), TRXN_PROGRAM, TRXN_READ1(p), TRXN_END, }; for (i = 0; i < size; ++i, ++d, ++s) { if ( BAD(BUS_transaction(trest, pn)) || (p[0] & ~d[0])) { ret = gbBAD; break; } } } BUSUNLOCK(pn); return ret; }
static GOOD_OR_BAD OW_r_status(BYTE * data, const struct parsedname *pn) { BYTE ss[] = { _1W_READ_STATUS_REGISTER, _1W_STATUS_VALIDATION_KEY }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE2(ss), TRXN_READ1(data), TRXN_END, }; return BUS_transaction(t, pn); }
// use new read_all command static GOOD_OR_BAD OW_r_all(BYTE * data, size_t size, off_t offset, struct parsedname *pn) { BYTE p[4] = { _1W_READ_ALL, LOW_HIGH_ADDRESS(offset), }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE3(p), TRXN_READ1(&p[3]), TRXN_CRC8(p, 4), TRXN_READ(data, size), }; RETURN_BAD_IF_BAD(BUS_transaction(t, pn)) ; return gbGOOD; }
/* 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; }
/* write Charge Pump */ static GOOD_OR_BAD OW_w_cp(const int val, const struct parsedname *pn) { BYTE resp[1]; BYTE cmd[] = { _1W_WRITE_CONTROL_REGISTER, (val) ? 0x4C : 0x0C }; BYTE ns[] = { _1W_RELEASE_WIPER, }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE2(cmd), TRXN_READ1(resp), TRXN_WRITE1(ns), TRXN_COMPARE(resp, &cmd[1], 1), TRXN_END }; return BUS_transaction(t, pn); }
/* write Wiper */ static GOOD_OR_BAD OW_w_wiper(const UINT val, const struct parsedname *pn) { BYTE resp[1]; BYTE cmd[] = { _1W_WRITE_POSITION, (BYTE) val, }; BYTE ns[] = { _1W_RELEASE_WIPER, }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE2(cmd), TRXN_READ1(resp), TRXN_WRITE1(ns), TRXN_COMPARE(resp, &cmd[1], 1), TRXN_END }; return BUS_transaction(t, pn); }
// uses CRC8 static GOOD_OR_BAD OW_reading(BYTE * data, struct parsedname *pn) { BYTE p[1] = { _1W_READ_SCRATCHPAD, }; BYTE q[3]; struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(p), TRXN_WRITE2(q), TRXN_READ1(&q[2]), TRXN_CRC8(q,3), TRXN_END, }; RETURN_BAD_IF_BAD(BUS_transaction(t, pn)) ; memcpy(data, q, 2); return gbGOOD; }
/* Reset activity latch */ static GOOD_OR_BAD OW_c_latch(const struct parsedname *pn) { BYTE reset_string[] = { _1W_RESET_ACTIVITY_LATCHES, }; BYTE read_back[1]; struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(reset_string), TRXN_READ1(read_back), TRXN_END, }; RETURN_BAD_IF_BAD(BUS_transaction(t, pn)) ; if (read_back[0] != 0xAA) { return gbBAD; } return gbGOOD; }
// reads to end of page and discards extra // uses CRC8 static GOOD_OR_BAD OW_r_page(BYTE * data, size_t size, off_t offset, struct parsedname *pn) { BYTE p[4] = { _1W_READ_DATA_CRC8, LOW_HIGH_ADDRESS(offset), }; BYTE q[33]; int rest = 33 - (offset & 0x1F); struct transaction_log t[] = { TRXN_START, TRXN_WRITE3(p), TRXN_READ1(&p[3]), TRXN_CRC8(p, 4), TRXN_READ(q, rest), TRXN_CRC8(q, rest), TRXN_END, }; RETURN_BAD_IF_BAD(BUS_transaction(t, pn)) ; memcpy(data, q, size); return gbGOOD; }
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; }