/* 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; }
/* paged, and pre-screened */ static GOOD_OR_BAD OW_w_23page(BYTE * data, size_t size, off_t offset, struct parsedname *pn) { BYTE p[1 + 2 + 32 + 2] = { _1W_WRITE_SCRATCHPAD, LOW_HIGH_ADDRESS(offset), }; struct transaction_log tcopy[] = { TRXN_START, TRXN_WR_CRC16(p, 3 + size, 0), TRXN_END, }; struct transaction_log treread[] = { TRXN_START, TRXN_WRITE1(p), TRXN_READ(&p[1], 3 + size), TRXN_COMPARE(&p[4], data, size), TRXN_END, }; struct transaction_log twrite33[] = { TRXN_START, TRXN_WRITE(p, 4), TRXN_DELAY(5), TRXN_END, }; struct transaction_log twriteEC20[] = { TRXN_START, TRXN_WRITE(p, 4), TRXN_DELAY(10), TRXN_END, }; /* Copy to scratchpad */ memcpy(&p[3], data, size); if (((offset + size) & 0x1F)) { // doesn't end on page boundary, no crc16 tcopy[2].type = tcopy[3].type = trxn_nop; } RETURN_BAD_IF_BAD(BUS_transaction(tcopy, pn)) ; /* Re-read scratchpad and compare */ /* Note that we tacitly shift the data one byte down for the E/S byte */ p[0] = _1W_READ_SCRATCHPAD; RETURN_BAD_IF_BAD(BUS_transaction(treread, pn)) ; /* Copy Scratchpad to SRAM */ p[0] = _1W_COPY_SCRATCHPAD; switch (pn->sn[0]) { case 0x23: // DS2433 return BUS_transaction(twrite33,pn); case 0x43: default: // DS28EC20 return BUS_transaction(twriteEC20,pn); } }
/* Extra 8 bytes, too */ GOOD_OR_BAD COMMON_read_memory_plus_counter(BYTE * extra, size_t page, size_t pagesize, struct parsedname *pn) { off_t offset = (page + 1) * pagesize - _1W_Throw_Away_Bytes; // last byte of page BYTE p[3 + _1W_Throw_Away_Bytes + 8 + 2] = { _1W_READ_A5, LOW_HIGH_ADDRESS(offset), }; struct transaction_log t[] = { TRXN_START, TRXN_WR_CRC16(p, 3, _1W_Throw_Away_Bytes + 8), TRXN_END, }; RETURN_BAD_IF_BAD(BUS_transaction(t, pn)) ; memcpy(extra, &p[3 + _1W_Throw_Away_Bytes], 8); LEVEL_DEBUG("Counter Data: %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X", extra[0], extra[1], extra[2], extra[3], extra[4], extra[5], extra[6], extra[7] ); return gbGOOD; }
/* Read 6 bytes -- 0x88 PIO logic State 0x89 PIO output Latch state 0x8A PIO Activity Latch 0x8B Conditional Ch Mask 0x8C Londitional Ch Polarity 0x8D Control/Status plus 2 more bytes to get to the end of the page and qualify for a CRC16 checksum */ static GOOD_OR_BAD OW_r_reg(BYTE * data, const struct parsedname *pn) { BYTE p[3 + 8 + 2] = { _1W_READ_PIO_REGISTERS, LOW_HIGH_ADDRESS(_ADDRESS_PIO_LOGIC_STATE), }; struct transaction_log t[] = { TRXN_START, TRXN_WR_CRC16(p, 3, 8), TRXN_END, }; RETURN_BAD_IF_BAD(BUS_transaction(t, pn)) ; memcpy(data, &p[3], 6); return gbGOOD; }
/* read REAL DS2431 pages -- 8 bytes. */ static GOOD_OR_BAD OW_w_2Dpage(BYTE * data, size_t size, off_t offset, struct parsedname *pn) { off_t pageoff = offset & 0x07; BYTE p[4 + 8 + 2] = { _1W_WRITE_SCRATCHPAD, LOW_HIGH_ADDRESS(offset - pageoff), }; struct transaction_log tcopy[] = { TRXN_START, TRXN_WRITE(p, 3 + 8), TRXN_END, }; struct transaction_log tread[] = { TRXN_START, TRXN_WR_CRC16(p, 1, 3 + 8), TRXN_COMPARE(&p[4], data, size), TRXN_END, }; struct transaction_log tsram[] = { TRXN_START, TRXN_WRITE(p, 4), TRXN_DELAY(13), TRXN_END, }; if (size != 8) { // incomplete page OWQ_allocate_struct_and_pointer(owq_old); OWQ_create_temporary(owq_old, (char *) &p[3], 8, offset - pageoff, pn); if (COMMON_read_memory_F0(owq_old, 0, 0)) { return gbBAD; } } memcpy(&p[3 + pageoff], data, size); /* Copy to scratchpad */ RETURN_BAD_IF_BAD(BUS_transaction(tcopy, pn)) ; /* Re-read scratchpad and compare */ p[0] = _1W_READ_SCRATCHPAD; RETURN_BAD_IF_BAD(BUS_transaction(tread, pn)) ; /* Copy Scratchpad to SRAM */ p[0] = _1W_COPY_SCRATCHPAD; return BUS_transaction(tsram, pn) ; }
/* Extra 8 bytes, (for counter) too -- discarded */ GOOD_OR_BAD COMMON_read_memory_toss_counter(struct one_wire_query *owq, size_t page, size_t pagesize) { off_t offset = OWQ_offset(owq) + page * pagesize; BYTE p[3 + pagesize + 8 + 2]; int rest = pagesize - (offset % pagesize); struct transaction_log t[] = { TRXN_START, TRXN_WR_CRC16(p, 3, rest + 8), TRXN_END, }; p[0] = _1W_READ_A5; p[1] = BYTE_MASK(offset); p[2] = BYTE_MASK(offset >> 8); RETURN_BAD_IF_BAD(BUS_transaction(t, PN(owq))) ; memcpy(OWQ_buffer(owq), &p[3], OWQ_size(owq)); Set_OWQ_length(owq); return gbGOOD; }
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; }
/* read up to end of page to CRC16 -- 0xA5 code */ static GOOD_OR_BAD OW_r_crc16(BYTE code, struct one_wire_query *owq, size_t page, size_t pagesize) { off_t offset = OWQ_offset(owq) + page * pagesize; size_t size = OWQ_size(owq); BYTE p[3 + pagesize + 2]; int rest = pagesize - (offset % pagesize); struct transaction_log t[] = { TRXN_START, TRXN_WR_CRC16(p, 3, rest), TRXN_END, }; p[0] = code; p[1] = BYTE_MASK(offset); p[2] = BYTE_MASK(offset >> 8); RETURN_BAD_IF_BAD(BUS_transaction(t, PN(owq))) ; memcpy(OWQ_buffer(owq), &p[3], size); Set_OWQ_length(owq); return gbGOOD; }
/* Write control/status */ static GOOD_OR_BAD OW_w_control(const BYTE data, const struct parsedname *pn) { BYTE write_string[1 + 2 + 1] = { _1W_WRITE_CONDITIONAL_SEARCH_REGISTER, LOW_HIGH_ADDRESS(_ADDRESS_CONTROL_STATUS_REGISTER), data, }; BYTE check_string[1 + 2 + 3 + 2] = { _1W_READ_PIO_REGISTERS, LOW_HIGH_ADDRESS(_ADDRESS_CONTROL_STATUS_REGISTER), }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE(write_string, 4), /* Read registers */ TRXN_START, TRXN_WR_CRC16(check_string, 3, 3), TRXN_END, }; RETURN_BAD_IF_BAD(BUS_transaction(t, pn)) ; return ((data & 0x0F) != (check_string[3] & 0x0F)) ? gbBAD : gbGOOD ; }
/* paged, and pre-screened */ static GOOD_OR_BAD OW_w_mem(BYTE * data, size_t size, off_t offset, struct parsedname *pn) { BYTE p[1 + 2 + 32 + 2] = { _1W_WRITE_SCRATCHPAD, LOW_HIGH_ADDRESS(offset), }; struct transaction_log tcopy[] = { TRXN_START, TRXN_WRITE(p, 3 + size), TRXN_END, }; struct transaction_log tcopy_crc16[] = { TRXN_START, TRXN_WR_CRC16(p, 3 + size, 0), TRXN_END, }; struct transaction_log tread[] = { TRXN_START, TRXN_WRITE1(p), TRXN_READ(&p[1], 3 + size), TRXN_COMPARE(data, &p[4], size), TRXN_END, }; struct transaction_log tsram[] = { TRXN_START, TRXN_WRITE(p, 4), TRXN_END, }; /* Copy to scratchpad */ memcpy(&p[3], data, size); RETURN_BAD_IF_BAD(BUS_transaction(((offset + size) & 0x1F) != 0 ? tcopy : tcopy_crc16, pn)) ; /* Re-read scratchpad and compare */ /* Note that we tacitly shift the data one byte down for the E/S byte */ p[0] = _1W_READ_SCRATCHPAD; RETURN_BAD_IF_BAD(BUS_transaction(tread, pn)) ; /* Copy Scratchpad to SRAM */ p[0] = _1W_COPY_SCRATCHPAD; return BUS_transaction(tsram, pn) ; }
/* 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; }