/* (c) 2009 Jean Bélanger  */

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <winbase.h>
#include <string.h>

main(int argc, char *argv[]) {

    unsigned char command[3];
	unsigned short rpm;
	HANDLE hSerial;
	DCB dcbSerialParams = {0};
	COMMTIMEOUTS timeouts = {0};
	DWORD dwBytesTrans = 0;

    if (argc != 3) {
        fprintf(stderr, "Command usage is %s <COMx> <baud_rate>\n", argv[0]);
        exit(1);
    }

	hSerial = CreateFile(argv[1],
						 GENERIC_READ | GENERIC_WRITE,
						 0,
						 0,
						 OPEN_EXISTING,
						 FILE_ATTRIBUTE_NORMAL,
						 0);

	if (hSerial == INVALID_HANDLE_VALUE) {
		if (GetLastError() == ERROR_FILE_NOT_FOUND) {
			printf("Serial port does not exist.\n");
		} else {
			printf("Other error.\n");
		}
		exit(1);
	}

	dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

	if (!GetCommState(hSerial, &dcbSerialParams)) {
		printf("Error getting serial port state.\n");
	}

	if (strncmp(argv[2], "9600", 4) == 0) {
		dcbSerialParams.BaudRate = CBR_9600;
	} else if (strncmp(argv[4], "19200", 5) == 0) {
		dcbSerialParams.BaudRate = CBR_19200;
	} else if (strncmp(argv[4], "38400", 5) == 0) {
		dcbSerialParams.BaudRate = CBR_38400;
	} else if (strncmp(argv[4], "57600", 5) == 0) {
		dcbSerialParams.BaudRate = CBR_57600;
	} else {
		printf("Invalid baud rate. Must be 9600, 19200, 38400 or 57600.\n");
		exit(1);
	}
	dcbSerialParams.ByteSize = 8;
	dcbSerialParams.StopBits = ONESTOPBIT;
	dcbSerialParams.Parity = NOPARITY;

	if (!SetCommState(hSerial, &dcbSerialParams)) {
		printf("Error setting serial port state.\n");
	}

	timeouts.ReadIntervalTimeout = 0;
	timeouts.ReadTotalTimeoutConstant = 250;
	timeouts.ReadTotalTimeoutMultiplier = 1;
	timeouts.WriteTotalTimeoutConstant = 25;
	timeouts.WriteTotalTimeoutMultiplier = 1;

	if (!SetCommTimeouts(hSerial, &timeouts)) {
		printf("Error setting timeouts.\n");
	}

	// Send the command to go in interactive mode
	command[0] = 'i';
	command[1] = 0;
	if (!WriteFile(hSerial, command, 1, &dwBytesTrans, NULL)) {
		printf("Error sending interactive command.\n");
	}
	//printf("wait:\n");
	//getc(stdin);
	//Sleep(200);

	rpm = 1000;
	if (!WriteFile(hSerial, (unsigned char *)(&rpm)+1, 1, &dwBytesTrans, NULL)) {
		printf("Error sending MSB RPM.\n");
	}
	// Send the  LSB RPM
	if (!WriteFile(hSerial, &rpm, 1, &dwBytesTrans, NULL)) {
		printf("Error sending LSB RPM.\n");
	}
	Sleep(1000);

	for (rpm = 1000; rpm < 12001; rpm+=10){
		// Send the MSB RPM
		if (!WriteFile(hSerial, (unsigned char *)(&rpm)+1, 1, &dwBytesTrans, NULL)) {
			printf("Error sending MSB RPM.\n");
		}
		// Send the  LSB RPM
		if (!WriteFile(hSerial, &rpm, 1, &dwBytesTrans, NULL)) {
			printf("Error sending LSB RPM.\n");
		}
		//Sleep(10);
	}
	Sleep(2000);
	for (; rpm >= 1000; rpm-=10){
		// Send the MSB RPM
		if (!WriteFile(hSerial, (unsigned char *)(&rpm)+1, 1, &dwBytesTrans, NULL)) {
			printf("Error sending MSB RPM.\n");
		}
		// Send the  LSB RPM
		if (!WriteFile(hSerial, &rpm, 1, &dwBytesTrans, NULL)) {
			printf("Error sending LSB RPM.\n");
		}
		//Sleep(10);
	}
	rpm = 65535;
	// Send the RPM
	if (!WriteFile(hSerial, &rpm, 2, &dwBytesTrans, NULL)) {
		printf("Error sending LSB RPM.\n");
	}

	CloseHandle(hSerial);

}


/* end of main */
