/******************************************************************** * 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; }
/** * 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); }
/******************************************************************** * 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; }
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(); }
/** * 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); }
void SerialInterface::start_sequence() { //clog(trace) << "start_sequence" << std::endl; set_RTS(false); nanodelay(); set_DTR(false); nanodelay(); }
void SerialInterface::end_command() { //clog(trace) << "end_command" << std::endl; set_RTS(true); nanodelay(); set_DTR(false); nanodelay(); set_RTS(false); nanodelay(); }
/** * 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; }
/******************************************************************** * open_weatherstation, Windows version * * Input: devicename (COM1, COM2 etc) * * Returns: Handle to the weatherstation (type WEATHERSTATION) * ********************************************************************/ WEATHERSTATION open_weatherstation (char *device) { WEATHERSTATION ws; struct termios adtio; unsigned char buffer[BUFFER_SIZE]; long i; print_log(1,"open_weatherstation"); //calibrate nanodelay function microdelay_init(1); // Set up gpi pointer for direct register access setup_io(); // Switch GPIO 7..11 to output mode /************************************************************************\ * You are about to change the GPIO settings of your computer. * * Mess this up and it will stop working! * * It might be a good idea to 'sync' before running this program * * so at least you still have your code changes written to the SD-card! * \************************************************************************/ // Set GPIO pins 7-11 to output for (g=7; g<=11; g++) { INP_GPIO(g); // must use INP_GPIO before we can use OUT_GPIO OUT_GPIO(g); } //Setup serial port if ((ws = open(device, O_RDWR | O_NOCTTY)) < 0) { printf("\nUnable to open serial device %s\n", device); exit(EXIT_FAILURE); } if ( flock(ws, LOCK_EX) < 0 ) { perror("\nSerial device is locked by other program\n"); exit(EXIT_FAILURE); } //We want full control of what is set and simply reset the entire adtio struct memset(&adtio, 0, sizeof(adtio)); // Serial control options adtio.c_cflag &= ~PARENB; // No parity adtio.c_cflag &= ~CSTOPB; // One stop bit adtio.c_cflag &= ~CSIZE; // Character size mask adtio.c_cflag |= CS8; // Character size 8 bits adtio.c_cflag |= CREAD; // Enable Receiver //adtio.c_cflag &= ~CREAD; // Disable Receiver adtio.c_cflag &= ~HUPCL; // No "hangup" adtio.c_cflag &= ~CRTSCTS; // No flowcontrol adtio.c_cflag |= CLOCAL; // Ignore modem control lines // Baudrate, for newer systems cfsetispeed(&adtio, BAUDRATE); cfsetospeed(&adtio, BAUDRATE); // Serial local options: adtio.c_lflag // Raw input = clear ICANON, ECHO, ECHOE, and ISIG // Disable misc other local features = clear FLUSHO, NOFLSH, TOSTOP, PENDIN, and IEXTEN // So we actually clear all flags in adtio.c_lflag adtio.c_lflag = 0; // Serial input options: adtio.c_iflag // Disable parity check = clear INPCK, PARMRK, and ISTRIP // Disable software flow control = clear IXON, IXOFF, and IXANY // Disable any translation of CR and LF = clear INLCR, IGNCR, and ICRNL // Ignore break condition on input = set IGNBRK // Ignore parity errors just in case = set IGNPAR; // So we can clear all flags except IGNBRK and IGNPAR adtio.c_iflag = IGNBRK|IGNPAR; // Serial output options // Raw output should disable all other output options adtio.c_oflag &= ~OPOST; adtio.c_cc[VTIME] = 10; // timer 1s adtio.c_cc[VMIN] = 0; // blocking read until 1 char if (tcsetattr(ws, TCSANOW, &adtio) < 0) { printf("Unable to initialize serial device"); exit(0); } tcflush(ws, TCIOFLUSH); for (i = 0; i < 448; i++) { buffer[i] = 'U'; } write(ws, buffer, 448); set_DTR(ws,0); set_RTS(ws,0); i = 0; do { sleep_short(10); i++; } while (i < INIT_WAIT && !get_DSR(ws)); if (i == INIT_WAIT) { print_log(2,"Connection timeout 1"); printf ("Connection timeout\n"); close_weatherstation(ws); exit(0); } i = 0; do { sleep_short(10); i++; } while (i < INIT_WAIT && get_DSR(ws)); if (i != INIT_WAIT) { set_RTS(ws,1); set_DTR(ws,1); } else { print_log(2,"Connection timeout 2"); printf ("Connection timeout\n"); close_weatherstation(ws); exit(0); } write(ws, buffer, 448); return ws; }