/* 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) ; }
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; }
/* 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_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; }
/* 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_simple_command(BYTE lcd_command_code, const struct parsedname *pn) { struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(&lcd_command_code), TRXN_END, }; return BUS_transaction(t, pn); }
static GOOD_OR_BAD OW_reset( const struct parsedname *pn) { BYTE p[] = { _1W_RESET_CYCLE_COUNTER, } ; struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(p), TRXN_END, }; return BUS_transaction( t, pn ) ; }
static GOOD_OR_BAD LCD_byte(BYTE b, int delay, const struct parsedname *pn) { struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(&b), TRXN_DELAY(delay), TRXN_END, }; return BUS_transaction(t, pn); }
static GOOD_OR_BAD OW_increment( const struct parsedname *pn) { BYTE p[] = { _1W_INCREMENT_CYCLE, } ; struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(p), TRXN_DELAY(10), TRXN_END, }; return BUS_transaction( t, pn ) ; }
static GOOD_OR_BAD OW_nv1_unlock( const struct parsedname *pn) { BYTE p[] = { _1W_UNLOCK_NV1, } ; struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(p), TRXN_DELAY(5), TRXN_END, }; return BUS_transaction( t, pn ) ; }
static GOOD_OR_BAD OW_r_scratch(BYTE * data, int length, const struct parsedname *pn) { BYTE read_command[1] = { _LCD_COMMAND_SCRATCHPAD_READ, }; struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(read_command), TRXN_READ(data, length), TRXN_END, }; return BUS_transaction(t, 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); } }
/* Send several bytes to the channel */ static GOOD_OR_BAD OW_w_pios(const BYTE * data, const size_t size, const struct parsedname *pn) { BYTE cmd[] = { _1W_CHANNEL_ACCESS_WRITE, }; size_t formatted_size = 4 * size; BYTE formatted_data[formatted_size]; struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(cmd), TRXN_MODIFY(formatted_data, formatted_data, formatted_size), TRXN_END, }; size_t i; // setup the array // each byte takes 4 bytes after formatting for (i = 0; i < size; ++i) { int formatted_data_index = 4 * i; formatted_data[formatted_data_index + 0] = data[i]; formatted_data[formatted_data_index + 1] = (BYTE) ~ data[i]; formatted_data[formatted_data_index + 2] = 0xFF; formatted_data[formatted_data_index + 3] = 0xFF; } if ( BAD(BUS_transaction(t, pn)) ) { // may be in test mode, which causes Channel Access Write to fail // fix now, but need another attempt to see if will work OW_out_of_test_mode(pn) ; return gbBAD ; } for (i = 0; i < size; ++i) { int formatted_data_index = 4 * i; BYTE rdata = ((BYTE)~data[i]); // get rid of warning: comparison of promoted ~unsigned with unsigned if (formatted_data[formatted_data_index + 0] != data[i]) { return gbBAD; } if (formatted_data[formatted_data_index + 1] != rdata) { return gbBAD; } if (formatted_data[formatted_data_index + 2] != 0xAA) { return gbBAD; } if (formatted_data[formatted_data_index + 3] != data[i]) { return gbBAD; } } return gbGOOD; }
/* 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); }
/* read Wiper */ static GOOD_OR_BAD OW_r_wiper(UINT * val, const struct parsedname *pn) { BYTE fo[] = { _1W_READ_POSITION, }; BYTE resp[2]; struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(fo), TRXN_READ2(resp), TRXN_END }; RETURN_BAD_IF_BAD(BUS_transaction(t, pn)) ; *val = resp[1]; return gbGOOD; }
/* 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); }
/* read Charge Pump */ static GOOD_OR_BAD OW_r_cp(int *val, const struct parsedname *pn) { BYTE aa[] = { _1W_READ_CONTROL_REGISTER, }; BYTE resp[2]; struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(aa), TRXN_READ2(resp), TRXN_END }; RETURN_BAD_IF_BAD(BUS_transaction(t, pn)) ; *val = ((resp[1] & 0x40) != 0); return gbGOOD; }
// 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; }
/* Reset activity latch */ static GOOD_OR_BAD OW_c_latch(const struct parsedname *pn) { BYTE reset_string[] = { _1W_RESET_ACTIVITY_LATCHES, }; BYTE read_back[1]; struct transaction_log t[] = { TRXN_START, TRXN_WRITE1(reset_string), TRXN_READ1(read_back), TRXN_END, }; RETURN_BAD_IF_BAD(BUS_transaction(t, pn)) ; if (read_back[0] != 0xAA) { return gbBAD; } return 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) ; }
/* 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) ; }
/* 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; }