/* 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) ; }
/* 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); }
static GOOD_OR_BAD OW_volts(_FLOAT * V, const struct parsedname *pn) { BYTE b4[] = { _1W_CONVERT_V, }; BYTE b2[] = { _1W_READ_REGISTERS, _ADDRESS_VOLTAGE, }; BYTE v[2]; struct transaction_log tconvert[] = { TRXN_START, TRXN_WRITE1(b4), TRXN_DELAY(10), TRXN_END, }; struct transaction_log tdata[] = { TRXN_START, TRXN_WRITE2(b2), TRXN_READ2(v), TRXN_END, }; // initiate conversion RETURN_BAD_IF_BAD(BUS_transaction(tconvert, pn)) ; /* Get data */ RETURN_BAD_IF_BAD( BUS_transaction(tdata, pn)) ; // success //V[0] = .01 * (_FLOAT)( ( ((uint32_t)v[1]) <<8 )|v[0] ) ; V[0] = .01 * (_FLOAT) (UT_uint16(v)); return gbGOOD; }
static GOOD_OR_BAD OW_temp(_FLOAT * T, const struct parsedname *pn) { BYTE d2[] = { _1W_CONVERT_T, }; BYTE b2[] = { _1W_READ_REGISTERS, _ADDRESS_TEMPERATURE, }; BYTE t[2]; struct transaction_log tconvert[] = { TRXN_START, TRXN_WRITE1(d2), TRXN_DELAY(10), TRXN_END, }; struct transaction_log tdata[] = { TRXN_START, TRXN_WRITE2(b2), TRXN_READ3(t), TRXN_END, }; // initiate conversion RETURN_BAD_IF_BAD(BUS_transaction(tconvert, pn)) ; /* Get data */ RETURN_BAD_IF_BAD(BUS_transaction(tdata, pn)) ; // success //printf("Temp bytes %0.2X %0.2X\n",t[0],t[1]); //printf("temp int=%d\n",((int)((int8_t)t[1]))); //T[0] = ((int)((int8_t)t[1])) + .00390625*t[0] ; T[0] = UT_int16(t) / 256.; return gbGOOD; }
/* 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; }
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); }
static GOOD_OR_BAD OW_r_app(BYTE * data, size_t size, off_t offset, const struct parsedname *pn) { BYTE c3[] = { _1W_READ_APPLICATION_REGISTER, BYTE_MASK(offset), }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE2(c3), TRXN_READ(data, size), TRXN_END, }; return BUS_transaction(t, pn) ; }
static GOOD_OR_BAD LCD_2byte(BYTE * bytes, int delay, const struct parsedname *pn) { struct transaction_log t[] = { TRXN_START, TRXN_WRITE2(bytes), TRXN_DELAY(delay), TRXN_END, }; return BUS_transaction(t, pn) ; }
/* Byte-oriented write */ static GOOD_OR_BAD OW_r_mem( BYTE * data, size_t size, off_t offset, const struct parsedname *pn) { BYTE fo[] = { _1W_READ_MEMORY, BYTE_MASK(offset), }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE2(fo), TRXN_READ( data, size ) , TRXN_END, }; return BUS_transaction(t, pn); }
/* 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); }
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; }
// 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; }
/* only called for a single page, and that page is 0,1,2 only*/ static GOOD_OR_BAD OW_r_page(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, }; static BYTE copyin[] = { _1W_COPY_NV1_TO_SP1, _1W_COPY_NV2_TO_SP2, _1W_COPY_NV3_TO_SP3, }; BYTE *copy = ©in[page]; struct transaction_log tcopy[] = { TRXN_START, TRXN_WRITE1(copy), TRXN_DELAY(10), TRXN_END, }; struct transaction_log tscratch[] = { TRXN_START, TRXN_WRITE2(scratchin), TRXN_READ(data, size), TRXN_END, }; RETURN_BAD_IF_BAD(BUS_transaction(tcopy, pn)) ; return BUS_transaction(tscratch, pn) ; }
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; }