예제 #1
0
파일: eeprom.c 프로젝트: INQNET/klimalogger
/********************************************************************
 * 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;
}
예제 #2
0
/**
 * 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;
}
예제 #3
0
파일: eeprom.c 프로젝트: INQNET/klimalogger
/********************************************************************
 * 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;
}
예제 #4
0
void SerialInterface::start_sequence()
{
    //clog(trace) << "start_sequence" << std::endl;
    set_RTS(false);
    nanodelay();
    set_DTR(false);
    nanodelay();
}
예제 #5
0
/**
 * 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);
}
예제 #6
0
void SerialInterface::end_command()
{
    //clog(trace) << "end_command" << std::endl;
    set_RTS(true);
    nanodelay();
    set_DTR(false);
    nanodelay();
    set_RTS(false);
    nanodelay();
}
예제 #7
0
파일: eeprom.c 프로젝트: INQNET/klimalogger
/********************************************************************
 * 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);
}
예제 #8
0
/**
 * 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();
}
예제 #9
0
/**
 * 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);
}
예제 #10
0
파일: eeprom.c 프로젝트: INQNET/klimalogger
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;
}
예제 #11
0
/**
 * 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);
}
예제 #12
0
/**
 * 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;
}
예제 #13
0
파일: eeprom.c 프로젝트: INQNET/klimalogger
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();
}
예제 #14
0
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);
}
예제 #15
0
파일: eeprom.c 프로젝트: INQNET/klimalogger
void read_next_byte_seq(WEATHERSTATION ws) {
  print_log(3,"read_next_byte_seq");
  write_bit(ws,0);
  set_RTS(ws,0);
  nanodelay();
}