// range is 5=5V or 2=2.5V static GOOD_OR_BAD OW_set_range( int range, struct parsedname * pn ) { int stored_range ; /* Range */ if ( BAD( Cache_Get_SlaveSpecific(&stored_range, sizeof(stored_range), SlaveSpecificTag(RAN), pn)) || stored_range != range) { // need to set resolution BYTE p[_1W_2450_PAGESIZE]; RETURN_BAD_IF_BAD( OW_r_mem(p, _1W_2450_PAGESIZE, _ADDRESS_CONTROL_PAGE, pn) ) ; switch ( range ) { case 2: p[_1W_2450_REG_A+1] &= ~_1W_2450_IR ; p[_1W_2450_REG_B+1] &= ~_1W_2450_IR ; p[_1W_2450_REG_C+1] &= ~_1W_2450_IR ; p[_1W_2450_REG_D+1] &= ~_1W_2450_IR ; break ; case 5: default: p[_1W_2450_REG_A+1] |= _1W_2450_IR ; p[_1W_2450_REG_B+1] |= _1W_2450_IR ; p[_1W_2450_REG_C+1] |= _1W_2450_IR ; p[_1W_2450_REG_D+1] |= _1W_2450_IR ; break ; } RETURN_BAD_IF_BAD( OW_w_mem(p, _1W_2450_PAGESIZE, _ADDRESS_CONTROL_PAGE, pn) ); return Cache_Add_SlaveSpecific(&range, sizeof(int), SlaveSpecificTag(RAN), pn); } return gbGOOD ; }
/* 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_r_mask(int *y, BYTE mask, struct parsedname *pn) { BYTE p[1]; RETURN_BAD_IF_BAD( OW_r_mem(p, 1, _ADDRESS_CONTROL_PAGE + 2 * pn->extension + 1, pn) ) ; y[0] = (p[0] & mask) ? 1 : 0 ; return gbGOOD; }
/* read powered flag */ static ZERO_OR_ERROR FS_r_power(struct one_wire_query *owq) { BYTE p; RETURN_ERROR_IF_BAD( OW_r_mem(&p, 1, _ADDRESS_POWERED, PN(owq)) ) ; OWQ_Y(owq) = (p == _1W_2450_POWERED); Cache_Add_SlaveSpecific(&OWQ_Y(owq), sizeof(int), SlaveSpecificTag(POW), PN(owq)); return 0; }
/* read a pio register */ static GOOD_OR_BAD OW_r_pio(int *pio, struct parsedname *pn) { BYTE p[1]; // 2 bytes per register RETURN_BAD_IF_BAD( OW_r_mem(p, 1, _ADDRESS_CONTROL_PAGE + 2 * pn->extension, pn) ) ; pio[0] = ((p[0] & (_1W_2450_OC|_1W_2450_OE)) != _1W_2450_OE); return gbGOOD; }
/* Write a pio register */ static GOOD_OR_BAD OW_w_pio( int pio, struct parsedname *pn) { BYTE p[1]; RETURN_BAD_IF_BAD( OW_r_mem(p, 1, _ADDRESS_CONTROL_PAGE + 2 * pn->extension, pn) ) ; p[0] |= _1W_2450_OE | _1W_2450_OC ; if ( pio==0 ) { p[0] &= ~_1W_2450_OC ; } return OW_w_mem(p, 1, _ADDRESS_CONTROL_PAGE + 2 * pn->extension, pn); }
// good if powered. static GOOD_OR_BAD OW_get_power( struct parsedname * pn ) { int power ; /* power */ if ( BAD( Cache_Get_SlaveSpecific(&power, sizeof(power), SlaveSpecificTag(POW), pn)) ) { BYTE p[1]; /* get power flag -- to see if pullup can be avoided */ RETURN_BAD_IF_BAD( OW_r_mem(p, 1, _ADDRESS_POWERED, pn) ) ; power = (p[0]==_1W_2450_POWERED) ? 1 : 0 ; Cache_Add_SlaveSpecific(&power, sizeof(power), SlaveSpecificTag(POW), pn); } return power==1 ? gbGOOD : gbBAD ; }
static GOOD_OR_BAD OW_w_mask( int y, BYTE mask, struct parsedname *pn) { BYTE p[1]; RETURN_BAD_IF_BAD( OW_r_mem(p, 1, _ADDRESS_CONTROL_PAGE + 2 * pn->extension + 1, pn) ) ; if ( y ) { p[0] |= mask ; } else { p[0] &= ~mask ; } // Clear POR as well p[0] &= ~_1W_2450_POR ; return OW_w_mem(p, 1, _ADDRESS_CONTROL_PAGE + 2 * pn->extension + 1, pn) ; }
/* range adjustment made elsewhere */ static GOOD_OR_BAD OW_volts(_FLOAT * V, struct parsedname *pn) { BYTE data[_1W_2450_PAGESIZE]; // read data RETURN_BAD_IF_BAD( OW_r_mem(data, _1W_2450_PAGESIZE, _ADDRESS_CONVERSION_PAGE, pn) ) ; // data conversions V[0] = 7.8126192E-5 * ((((UINT) data[1]) << 8) | data[0]); V[1] = 7.8126192E-5 * ((((UINT) data[3]) << 8) | data[2]); V[2] = 7.8126192E-5 * ((((UINT) data[5]) << 8) | data[4]); V[3] = 7.8126192E-5 * ((((UINT) data[7]) << 8) | data[6]); return gbGOOD; }
static GOOD_OR_BAD OW_w_vset( _FLOAT V, enum V_alarm_level ae, struct parsedname *pn) { BYTE p[_1W_2450_PAGESIZE]; RETURN_BAD_IF_BAD( OW_r_mem(p, 2, _ADDRESS_ALARM_PAGE + 2 * pn->extension, pn) ) ; switch ( ae ) { case V2_ae_high: p[1] = 100. * V ; break ; case V2_ae_low: p[0] = 100. * V ; break ; case V5_ae_high: p[1] = 50. * V ; break ; case V5_ae_low: p[0] = 50. * V ; break ; } return OW_w_mem(p, 2, _ADDRESS_ALARM_PAGE + 2 * pn->extension, pn) ; }
static GOOD_OR_BAD OW_r_vset(_FLOAT * V, enum V_alarm_level ae, struct parsedname *pn) { BYTE p[2]; RETURN_BAD_IF_BAD( OW_r_mem(p, 2, _ADDRESS_ALARM_PAGE + 2 * pn->extension, pn) ) ; switch ( ae ) { case V2_ae_high: V[0] = .01 * p[1]; break ; case V2_ae_low: V[0] = .01 * p[0]; break ; case V5_ae_high: V[0] = .02 * p[1]; break ; case V5_ae_low: V[0] = .02 * p[0]; break ; } return gbGOOD; }
static GOOD_OR_BAD OW_set_resolution( int resolution, struct parsedname * pn ) { int stored_resolution ; /* Resolution */ if ( BAD( Cache_Get_SlaveSpecific(&stored_resolution, sizeof(stored_resolution), SlaveSpecificTag(RES), pn)) || stored_resolution != resolution) { // need to set resolution BYTE p[_1W_2450_PAGESIZE]; RETURN_BAD_IF_BAD( OW_r_mem(p, _1W_2450_PAGESIZE, _ADDRESS_CONTROL_PAGE, pn) ) ; p[_1W_2450_REG_A] &= ~_1W_2450_RC_MASK ; p[_1W_2450_REG_A] |= ( resolution & _1W_2450_RC_MASK ) ; p[_1W_2450_REG_B] &= ~_1W_2450_RC_MASK ; p[_1W_2450_REG_B] |= ( resolution & _1W_2450_RC_MASK ) ; p[_1W_2450_REG_C] &= ~_1W_2450_RC_MASK ; p[_1W_2450_REG_C] |= ( resolution & _1W_2450_RC_MASK ) ; p[_1W_2450_REG_D] &= ~_1W_2450_RC_MASK ; p[_1W_2450_REG_D] |= ( resolution & _1W_2450_RC_MASK ) ; RETURN_BAD_IF_BAD( OW_w_mem(p, _1W_2450_PAGESIZE, _ADDRESS_CONTROL_PAGE, pn) ); return Cache_Add_SlaveSpecific(&resolution, sizeof(int), SlaveSpecificTag(RES), pn); } return gbGOOD ; }
/* DS2430A memory */ static ZERO_OR_ERROR FS_r_memory(struct one_wire_query *owq) { OWQ_length(owq) = OWQ_size(owq) ; return GB_to_Z_OR_E(OW_r_mem((BYTE *) OWQ_buffer(owq), OWQ_size(owq), (size_t) OWQ_offset(owq), PN(owq))) ; }