/******************************************************************** * write_data writes data to the WS2300. * It can both write nibbles and set/unset bits * * Inputs: ws2300 - device number of the already open serial port * address (interger - 16 bit) * number - number of nibbles to be written/changed * must 1 for bit modes (SETBIT and UNSETBIT) * max 80 for nibble mode (WRITENIB) * writedata - pointer to an array of chars containing * data to write, not zero terminated * data must be in hex - one digit per byte * If bit mode value must be 0-3 and only * the first byte can be used. * * Output: commanddata - pointer to an array of chars containing * the commands that were sent to the station * * Returns: number of bytes written, -1 if failed * ********************************************************************/ int write_data(WEATHERSTATION ws, int address, int number, unsigned char *writedata) { unsigned char command = 0xa0; int i = -1; write_byte(ws,command); write_byte(ws,address/256); write_byte(ws,address%256); if (writedata!=NULL) { for (i = 0; i < number; i++) { write_byte(ws,writedata[i]); } } set_DTR(ws,0); nanodelay(); set_RTS(ws,0); nanodelay(); set_RTS(ws,1); nanodelay(); set_DTR(ws,1); nanodelay(); set_RTS(ws,0); nanodelay(); //return -1 for errors return i; }
/** * Write one byte. * @param value Value to write. * @param verify Whether the write has to be verified (default: true). * @return Whether the write was successful. */ bool SerialInterface::write_byte(byte value, bool verify) { //clog(trace) << "Send byte 0x" << std::hex << value << std::endl; for (size_t i = 0; i < 8; i++) { write_bit((value & 0x80) > 0); value <<= 1; } set_RTS(false); nanodelay(); bool status = true; if (verify) { status = get_CTS(); //TODO: checking value of status, error routine // TODO: exceptions? nanodelay(); set_DTR(false); nanodelay(); set_DTR(true); nanodelay(); } return status; }
/******************************************************************** * write_byte * Writes one byte to the COM * * Inputs: serdevice - opened file handle * byte - byte to write * * Returns: nothing * ********************************************************************/ int write_byte(WEATHERSTATION ws, int byte) { int status; int i; char str[20]; sprintf(str,"Writing byte %i",byte); print_log(3,str); for (i = 0; i < 8; i++) { write_bit(ws, byte & 0x80); byte <<= 1; byte &= 0xff; } set_RTS(ws,0); nanodelay(); status = get_CTS(ws); //TODO: checking value of status, error routine nanodelay(); set_DTR(ws,0); nanodelay(); set_DTR(ws,1); nanodelay(); if (status) return 1; else return 0; }
void SerialInterface::start_sequence() { //clog(trace) << "start_sequence" << std::endl; set_RTS(false); nanodelay(); set_DTR(false); nanodelay(); }
/** * Write one bit. * @param bit Bit to write. */ void SerialInterface::write_bit(bool bit) { //clog(trace) << "Write bit " << (bit ? "1" : "0") << std::endl; set_RTS(!bit); nanodelay(); set_DTR(false); nanodelay(); set_DTR(true); }
void SerialInterface::end_command() { //clog(trace) << "end_command" << std::endl; set_RTS(true); nanodelay(); set_DTR(false); nanodelay(); set_RTS(false); nanodelay(); }
/******************************************************************** * write_bit * Writes one bit to the COM * * Inputs: serdevice - opened file handle * bit - bit to write * * Returns: nothing * ********************************************************************/ void write_bit(WEATHERSTATION ws,int bit) { char str[20]; set_RTS(ws,!bit); nanodelay(); set_DTR(ws,0); nanodelay(); set_DTR(ws,1); sprintf(str,"Write bit %i",bit); print_log(4,str); }
/** * Advance to the next byte. */ void SerialInterface::request_next() { //clog(debug) << "request_next_byte_seq" << std::endl; set_RTS(true); nanodelay(); set_DTR(false); nanodelay(); set_DTR(true); nanodelay(); set_RTS(false); nanodelay(); }
/** * Read one bit. * @return Bit read. */ byte SerialInterface::read_bit() { //clog(trace) << "Read bit ..." << std::endl; set_DTR(false); nanodelay(); bool status = get_CTS(); nanodelay(); set_DTR(true); nanodelay(); //clog(trace) << "Bit = " << (status ? "0" : "1") << std::endl; return (byte)(status ? 0 : 1); }
int read_bit(WEATHERSTATION ws) { int bit_value; char str[20]; set_DTR(ws,0); nanodelay(); bit_value = get_CTS(ws); nanodelay(); set_DTR(ws,1); nanodelay(); sprintf(str,"Read bit %i",!bit_value); print_log(4,str); return !bit_value; }
/** * Send a command. * @param value Command to send. * @param verify Whether the send has to be verified (default: true). * @return Whether the command was send successfully. */ bool SerialInterface::send_command(byte command, bool verify) { set_DTR(false); nanodelay(); set_RTS(false); nanodelay(); set_RTS(true); nanodelay(); set_DTR(true); nanodelay(); set_RTS(false); nanodelay(); return write_byte(command, verify); }
/** * Write an arbitrary amount of data. * @param location Location to write to. * @param data Data to write. */ bool SerialInterface::write_data(address location, const std::vector<byte> &data) { start_sequence(); if (!request(location)) return false; for (size_t i = 0; i < data.size(); i++) if (!write_byte(data[i])) return false; end_command(); start_sequence(); for (size_t i = 0; i < 3; i++) send_command(0xA0, false); set_DTR(false); nanodelay(); bool result = get_CTS(); set_DTR(true); nanodelay(); return result; }
void read_last_byte_seq(WEATHERSTATION ws) { print_log(3,"read_last_byte_seq"); set_RTS(ws,1); nanodelay(); set_DTR(ws,0); nanodelay(); set_RTS(ws,0); nanodelay(); set_RTS(ws,1); nanodelay(); set_DTR(ws,1); nanodelay(); set_RTS(ws,0); nanodelay(); }
int main(int argc, char *argv[]) { FILE *fileptr; unsigned char data[BUFSIZE]; int start_adr, len; int block_len = 1000; int retries = 0; char* filename; if (argc != 2) { fprintf(stderr, "E: no dump file specified.\n"); print_usage(); } if (argc >= 3) { filename = argv[2]; } else { // generate filename based on current time time_t t; struct tm *tm; t = time(NULL); tm = localtime(&t); if (tm == NULL) { perror("localtime"); exit(EXIT_FAILURE); } filename = malloc(50); sprintf(filename, "tfa.dump."); strftime(filename+strlen(filename), sizeof(filename)-strlen(filename), "%Y%m%d.%H%M", tm); } // need root for (timing) portio if (geteuid() != 0) { fprintf(stderr, "E: this program needs root privileges to do direct port I/O.\n"); exit(EXIT_FAILURE); } // Setup open_weatherstation(); // Setup file fileptr = fopen(filename, "w"); if (fileptr == NULL) { printf("Cannot open file %s\n", filename); exit(EXIT_FAILURE); } // Start. start_adr = 0; len = 0x7FFF; // 1802*3; //(0x7ef4+259) - start_adr; printf("Dumping %d bytes to %s.\n", len, filename); memset(data, 0xAA, BUFSIZE); while (start_adr < len) { int got_len; int this_len = block_len; if (start_adr + block_len > len) this_len = len-start_adr; printf(" ... reading %d bytes beginning from %d\n", this_len, start_adr); nanodelay(); eeprom_seek(start_adr); got_len = eeprom_read(data+start_adr, this_len); if (got_len != this_len) { if (got_len == -1 && retries < MAX_RETRIES) { retries++; fprintf(stderr, "W: eeprom ack failed, retrying read (retries left: %d).\n", MAX_RETRIES-retries); close_weatherstation(); open_weatherstation(); continue; } printf(" >>> got %d bytes\n", got_len); fprintf(stderr, "E: got less than requested bytes, dump is probably unusable.\n"); break; } start_adr += block_len; retries = 0; } fwrite(data, len, 1, fileptr); close_weatherstation(); fclose(fileptr); return(0); }
void read_next_byte_seq(WEATHERSTATION ws) { print_log(3,"read_next_byte_seq"); write_bit(ws,0); set_RTS(ws,0); nanodelay(); }