/* write alarm settings */ static GOOD_OR_BAD OW_w_s_alarm(const BYTE * data, const struct parsedname *pn) { BYTE old_register[6]; BYTE new_register[6]; BYTE control_value[1]; BYTE alarm_access[] = { _1W_WRITE_CONDITIONAL_SEARCH_REGISTER, LOW_HIGH_ADDRESS(_ADDRESS_ALARM_REGISTERS), }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE3(alarm_access), TRXN_WRITE2(data), TRXN_WRITE1(control_value), TRXN_END, }; // get the existing register contents RETURN_BAD_IF_BAD( OW_r_reg(old_register, pn) ) ; control_value[0] = (data[2] & 0x03) | (old_register[5] & 0x0C); RETURN_BAD_IF_BAD(BUS_transaction(t, pn)) ; /* Re-Read registers */ RETURN_BAD_IF_BAD(OW_r_reg(new_register, pn)) ; return (data[0] != new_register[3]) || (data[1] != new_register[4]) || (control_value[0] != (new_register[5] & 0x0F)) ? gbBAD : gbGOOD; }
/* PAged access -- pre-screened */ static GOOD_OR_BAD OW_w_mem(BYTE * data, size_t size, off_t offset, struct parsedname *pn) { BYTE p[4 + 32] = { _1W_WRITE_SCRATCHPAD, LOW_HIGH_ADDRESS(offset), }; struct transaction_log tcopy[] = { TRXN_START, TRXN_WRITE3(p), TRXN_WRITE(data, size), 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_DELAY(32), TRXN_END, }; /* 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) ; }
/* 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_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); } }
/* No CRC -- 0xF0 code */ GOOD_OR_BAD COMMON_read_memory_F0(struct one_wire_query *owq, size_t page, size_t pagesize) { off_t offset = OWQ_offset(owq) + page * pagesize; BYTE p[3] = { _1W_READ_F0, LOW_HIGH_ADDRESS(offset), }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE3(p), TRXN_READ((BYTE *) OWQ_buffer(owq), OWQ_size(owq)), TRXN_END, }; Set_OWQ_length(owq); return BUS_transaction(t, PN(owq)); }
// 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; }
/* 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; }
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) ; }
/* 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) ; }
// 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_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; }
/* 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; }