/* 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) ; }
/* 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); } }
/* Byte-oriented write */ static GOOD_OR_BAD OW_w_mem(const BYTE * data, size_t size, off_t offset, const struct parsedname *pn) { BYTE scratch[_DS2430A_MEM_SIZE]; BYTE vr[] = { _1W_READ_SCRATCHPAD, BYTE_MASK(offset), }; BYTE of[] = { _1W_WRITE_SCRATCHPAD, BYTE_MASK(offset), }; BYTE cp[] = { _1W_COPY_SCRATCHPAD, _1W_COPY_SCRATCHPAD_VALIDATION_KEY, }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE2(of), TRXN_WRITE(data, size), TRXN_START, TRXN_WRITE2(vr), TRXN_READ(scratch, size), TRXN_COMPARE(data,scratch,size), TRXN_START, TRXN_WRITE2(cp), TRXN_DELAY(10), TRXN_END, }; /* load scratch pad if incomplete write */ if ( size != _DS2430A_MEM_SIZE ) { RETURN_BAD_IF_BAD( OW_r_mem( scratch, 0, 0x00, pn)) ; } /* write data to scratchpad */ /* read back the scratchpad */ /* copy scratchpad to memory */ return BUS_transaction(t, pn); }
/* only called for a single page, and that page is 0,1,2 only*/ static GOOD_OR_BAD OW_w_page(const BYTE * data, size_t size, off_t offset, const struct parsedname *pn) { int page = offset / _1W_2436_PAGESIZE; // integer round-down ok BYTE scratchin[] = { _1W_READ_SCRATCHPAD, offset, }; BYTE scratchout[] = { _1W_WRITE_SCRATCHPAD, offset, }; BYTE p[_1W_2436_PAGESIZE]; static BYTE copyout[] = { _1W_COPY_SP1_TO_NV1, _1W_COPY_SP2_TO_NV2, _1W_COPY_SP3_TO_NV3, }; BYTE *copy = ©out[page]; struct transaction_log twrite[] = { TRXN_START, TRXN_WRITE2(scratchout), TRXN_WRITE(data, size), TRXN_END, }; struct transaction_log tread[] = { TRXN_START, TRXN_WRITE2(scratchin), TRXN_READ(p, size), TRXN_COMPARE(data, p, size), TRXN_END, }; struct transaction_log tcopy[] = { TRXN_START, TRXN_WRITE1(copy), TRXN_DELAY(10), TRXN_END, }; RETURN_BAD_IF_BAD(BUS_transaction(twrite, pn)) ; RETURN_BAD_IF_BAD(BUS_transaction(tread, pn)) ; return BUS_transaction(tcopy, pn) ; }
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; }
/* 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) ; }
// very strange command to get out of test mode. // Uses a different 1-wire command static GOOD_OR_BAD OW_out_of_test_mode( const struct parsedname * pn ) { BYTE out_of_test[] = { 0x96, SNvar(pn->sn), 0x3C, } ; struct transaction_log t[] = { TRXN_RESET, TRXN_WRITE(out_of_test, 1 + SERIAL_NUMBER_SIZE + 1 ), TRXN_END, }; return BUS_transaction( t, pn ) ; }
static GOOD_OR_BAD OW_w_app(const BYTE * data, size_t size, off_t offset, const struct parsedname *pn) { BYTE nn[] = { _1W_WRITE_APPLICATION_REGISTER, BYTE_MASK(offset), }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE2(nn), TRXN_WRITE(data, size), TRXN_END, }; return BUS_transaction(t, pn); }
static GOOD_OR_BAD OW_w_scratch(const BYTE * data, int length, const struct parsedname *pn) { BYTE write_command[1] = { _LCD_COMMAND_SCRATCHPAD_WRITE, }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(write_command), TRXN_WRITE(data, length), TRXN_END, }; return BUS_transaction(t, pn); }
/* 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) ; }
static GOOD_OR_BAD OW_w_config(BYTE config0, BYTE config1, struct parsedname *pn) { BYTE p[4] ; struct transaction_log t[] = { TRXN_START, TRXN_WRITE(p,4), TRXN_END, }; p[0] = _1W_WRITE_CONFIG ; p[1] = config0 ; p[2] = config1 ; p[3] = CRC8( &p[1], 2 ) ; return BUS_transaction(t, pn) ; }
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) ; }
/* 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 ; }