/*
   FILE: PWM1_1.C
   AUTH: P.OH/Boondog Automation
   DESC: 8254 board and PWM programming
*/

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define crystalValue 1000000
#define TRUE  1
#define FALSE 0

void main(void) {

  int baseAddress, counter0, counter1, counter2, CNTRL;
  int gateAddress, gateValue;
  float dutyCyclePercent;
  unsigned int dutyCycleCount;

  unsigned int counterValue;  /* counterValue ranges from 0 to 65535 */
  int counterValueMSB, counterValueLSB;

  int t0_value, t1_value;
  int t0_valueMSB, t0_valueLSB;
  int t1_valueMSB, t1_valueLSB;
  int counter1Value;
  int choice;

  t0_value = 10240;
  t1_value = 10240;
  t0_valueMSB = (int)(t0_value/256);
  t0_valueLSB = (t0_value - t0_valueMSB*256);
  t1_valueMSB = (int)(t1_value/256);
  t1_valueLSB = (t1_value - t1_valueMSB*256);

  window(5,5,75,30);
  clrscr(); gotoxy(1,1);
  cprintf("Enter base Address (e.g. 608) in decimal:  ");
  scanf("%d", &baseAddress);
  gotoxy(1,3); cprintf("Enter duty cycle percentage e.g. 75.0: ");
  scanf("%f", &dutyCyclePercent);
  dutyCycleCount = (unsigned int)((dutyCyclePercent/100.0)*t1_value);

  counter0    = baseAddress;
  counter1    = baseAddress + 1;
  counter2    = baseAddress + 2;
  CNTRL       = baseAddress + 3;
  gateAddress = baseAddress + 7;

  /* set COUNTER0 as mode 2 rate generator:    00 11 010 0 */
  outportb(CNTRL, 52);
  /* set COUNTER1 as mode 2 rate generator:    01 11 010 0 */
  outportb(CNTRL, 116);

     /* Turn on gates 0 and 1 */
     outportb(gateAddress, 3);
     /* Next lines just reinitialize counter1, not especially needed */
     outportb(counter1, 0xff);
     outportb(counter1, 0xff);

     /* Load and start counter 1 with desired values */
     outportb(counter1, t1_valueLSB);
     outportb(counter1, t1_valueMSB);

     /* At this point, counterValue in Counter 1 should be 10240 */

  gotoxy(1,5); cprintf("Hit 0 and Enter to Quit\n");
  gotoxy(1,6); cprintf("Hit 1 and Enter to Start\n");
  gotoxy(1,7); cprintf("Hit 9 and Enter for new duty cycle\n");

  do {
     gotoxy(1,8); cprintf("Choice = ");
     scanf("%d", &choice);
     switch(choice) {
	 case 1 : break;
	 case 9 :
		  counterValueLSB = inportb(counter1);
		  counterValueMSB = inportb(counter1);
		  gotoxy(1,11); cprintf("New duty cycle? = ");
		  scanf("%f", &dutyCyclePercent);
		  dutyCycleCount = (unsigned int)((dutyCyclePercent/100.0)*t1_value);
		  gotoxy(1,12); cprintf("dutyCycleCount = %6u\n", dutyCycleCount);
		  break;
     }

     do {
       /* need to latch counter 1 */
       outportb(CNTRL, 64);
       counterValueLSB = inportb(counter1);
       counterValueMSB = inportb(counter1);
       counterValue = (unsigned int)(counterValueMSB*256 + counterValueLSB);
     } while (counterValue != dutyCycleCount);

     /* Next lines just reinitialize counter1, not especially needed */
     outportb(gateAddress, 0);
     outportb(gateAddress, 3);

     outportb(counter0, t0_valueLSB);
     outportb(counter0, t0_valueMSB);
     gotoxy(1,13); cprintf("counterValue = %6u\n", counterValue);

  } while(choice != 0);

  outportb(gateAddress, 0);

} /* end of main */

