/* main.c - 7-segment LED display example for Dragon12-Plus
 * Copyright 2008 Colin D. Bennett <colin@gibibit.com>.
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * The Dragon12-Plus board has four 7-segment LED displays.  This 
 * program demostrates how to control the 7-segment displays.
 * 
 * Refer to p. 25 in the Dragon12-Plus manual (dragon12-plus_manual.pdf) 
 * for a diagram showing the display circuit.  Essentially each of the
 * four digits has its own cathode line shared by its 7 segments, but 
 * there are 7 lines for the segments (the anodes) of a digit which are 
 * shared among all four digits.  The diagram in the manual should help
 * to clarify the configuration.  To display four digits simultaneously, 
 * the program must continuously cycle through the four digits, lighting
 * each briefly for 1-2 milliseconds.  If the update speed is high enough,
 * the human eye perceives the digits as being constantly lit.
 *
 * This program uses a delay loop for timing, for simplicity's sake,
 * but using the timer interrupt would be a better option for many
 * programs, particularly when the program has other work to do while
 * using the display.
 */

#include "hc12drivers/led7seg.h"
#include "hc12/interrupt.h"
#include "hc12/delay.h"

int main(void)
{
	/* Intialize the 7-segment LED driver. This sets up a timer interrupt 
	 * handler to be called at a high rate. */
	led7seg_init();

	/* Display "1234" on the display. */
	led7seg_bits[0] = 0x06;   /* Digit '1' */
	led7seg_bits[1] = 0x5B;   /* Digit '2' */
	led7seg_bits[2] = 0x4F;   /* Digit '3' */
	led7seg_bits[3] = 0x66;   /* Digit '4' */

	/* 
	 * Main loop:  Updates the led7seg_brightness[] array periodically
	 * while the timer interrupt handler in led7seg.c continually refreshes
	 * the LED digits. 
	 *
	 * The brightnesses are simply cycled to demonstrate how an 
	 * application can control what is being displayed by the 
	 * interrupt handler. 
	 */
	uint8_t phase = 0;
	while (1)
	{
		/* Delay to allow digits to be refreshed for a while. */
		delay_ms(500 / 32);     

		/* Note the critical section while we update led7seg_brightness.
		 * We don't want the interrupt handler to get a partially updated
		 * array, so we ensure that it won't be called in this section. */
		disable_interrupts();   /* Critical section. */
		for (uint8_t i = 0; i < 4; i++)
			led7seg_brightness[i] = (phase - i*(256/4));
		enable_interrupts();    /* End critical section. */

		phase += 8;
	}
}

