/* 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 "hc12/hcs12.h"
#include "hc12/delay.h"

/* Bit patterns for the digits 1, 2, 3, 4. */
static const uint8_t bits[] = { 0x06, 0x5B, 0x4F, 0x66 };

int main(void)
{
	/*** Configure 7-segment display. ***/
	/*
	 * The common cathodes of the digits 3, 2, 1, and 0 are driven by 
	 * PP0, PP1, PP2, and PP3, respectively.
	 *
	 * The anodes are separate for each of the 7 segments:
	 *       
	 *       --0--           Each of these numbers is the port B pin
	 *    5 |     | 1        number that controls the segment.  Pin 7
	 *      |     |          controls the decimal point, which is actually
	 *       --6--           in the upper left for the last 2 digits.
	 *      |     |          (This allows a colon to be displayed between
	 *    4 |     | 2        the 2nd and 3rd digits.)
	 *       --3--     . 7 
	 *
	 */
	DDRB = 0xFF;   // Set port B to output for LEDs (PB7:0 are LED anodes).
	DDRP = 0xFF;   // Set port P to output (PP0:3 are common cathodes)

	while (1)
	{
		uint8_t digit_bit = 1;
		for (uint8_t digit = 0; digit < 4; digit++)
		{
			/* Set only one cathode to low, all others to high. */
			PTP = ~digit_bit;
			PORTB = bits[digit];    /* Write segment bit pattern. */
			delay_ms(1);            /* Delay to make visible. */
			digit_bit <<= 1;        /* Select the next digit. */
		}
	}
}

