// File: dim2.c
//
// Hack Your Room: Intro. to Microcontrollers
// Lab 2, Program Problem 2b Solution
//
// dim2.c
//
// Read a brightness over serial
// Turn on red LED at this intensity for 3 seconds
// Repeat
//
// Abraham Flaxman <abie@mit.edu>
// MIT Robotics and Electronics Cooperative
// February, 2000
//
#case
#include <16F84.H>

// Configure PIC to use: HS clock, no Watchdog Timer, 
// no code protection, enable Power Up Timer
//
#fuses HS,NOWDT,NOPROTECT,PUT

// Tell compiler clock is 10MHz.  This is required for delay_ms()
// and for all serial I/O (such as printf(...).  These functions
// use software delay loops, so the compiler needs to know the
// processor speed.
//
#use DELAY(clock=10000000)

// Declare that we'll manually establish the data direction of
// each I/O pin on port B.
//
#use fast_io(B)

// Standard definitions for the irx2_1 board
//
#define RS232_XMT       PIN_B1  // (output) RS232 serial transmit
#define RED_LED         PIN_B2  // (output) Red LED (low true)
#define IR_LED          PIN_B3  // (output) Infrared LED (low true)
#define IR_SENSOR       PIN_B4  // (input) IR sensor (Sharp IS1U30)
#define RS232_RCV       PIN_B5  // (input) RS232 serial receive

// Macros to simplify I/O operations
//
#define RED_LED_ON      output_low(RED_LED)
#define RED_LED_OFF     output_high(RED_LED)
#define IR_LED_ON       output_low(IR_LED)
#define IR_LED_OFF      output_high(IR_LED)
#define IR_RECEIVED	(!input(IR_SENSOR))

// Default tri-state port direction bits: all PORT B bits are
// output except for IR_SENSOR (bit 4) and RC232_RCV (bit 5).
//
#define IRX_B_TRIS      0b00110000

// Inform printf() and friends of the desired baud rate 
// and which pins to use for serial I/O.
//
#use rs232(baud=9600, xmit=RS232_XMT, rcv=RS232_RCV)

#define MAX_INTENSITY   9           // allow 10 possible intensities (0-9)
#define LOW_INTENSITY   1           // 0 is off, we want dim

#define TICK_PERIOD     100         // pulse period = MAX_INTENSITY*TICK_PERIOD

void do_one_pulse(int intensity)
{
  int i;
  for (i = 0; i < MAX_INTENSITY; i++) {
    if (i >= intensity)
      RED_LED_OFF;
    else
      RED_LED_ON;

    delay_us(TICK_PERIOD);
  }
}

void do_pulses(long int pulse_count, int intensity)
{
  while (pulse_count > 0) {
    do_one_pulse(intensity);
    --pulse_count;
  }
}

void main() {
  int intensity;

  // since we've declared #use fast_io(B) (above), we MUST 
  // include a call to set_tris_b() at startup.
  // 
  set_tris_b(IRX_B_TRIS);

  RED_LED_ON;                    // reality check at startup
  delay_ms(200);
  RED_LED_OFF;

  while (1) {
    do {
      printf("Enter LED intensity: ");
      intensity = getc() - '0';

      printf("%c\r\n", intensity + '0');  // make it look nice

      if (intensity > 9)
        printf("Intensity must be a number between 0 and 9!\r\n");
    } while (intensity > 9);

    do_pulses(3000, intensity);
    RED_LED_OFF;
  }
}

