/*-----------------------------------------------------------------------------
* File: LED01.C
* Author: David Boydston - Solutions Consulting - http://www.serialio.com
* Copyright (c) 1999 Solutions Consulting All Rights Reserved.
*
* Function: Test the light sequence on Atmel 8515 development board
* Lights should blink one at a time 'up' from PB0 to PB7 then back 'down'
* from PB7 to PB0. Then the lights will 'stack up' from PB0 to PB7 and
* 'stack down' from PB7 to PB0. At any time when the PB2 button is
* pressed the lights should display with an alternating pattern momentarily
* then continue with the blinking pattern.
*
* See disclaimer at http://www.serialio.com/Legal/SoftDisclaimer.htm
*---------------------------------------------------------------------------*/
#include <io8515.h>
#include <macros.h>
#define CLK_DIV_BY_0 0x01 //rolls at 8.19ms with 4Mhz Clock
#define CLK_DIV_BY_8 0x02 //rolls at 65.5ms with 4Mhz Clock
#define CLK_DIV_BY_64 0x03 //rolls at 524ms with 4Mhz Clock
#define CLK_DIV_BY_256 0x04 //rolls at 2.1sec with 4Mhz Clock
#define CLK_DIV_BY_1024 0x05 //rolls at 8.4sec with 4Mhz Clock
#define TMR1_OVF_INT_ENA 0x80
#define GLOBAL_INT_ENA 0x80
#define INT0_ENA 0x40
#define INT0_TRIG_FALL_EDGE 0x02
#define INT1_ENA 0x80
unsigned char tmrRollFlag = 0;
void delay2(unsigned char);
#pragma interrupt_handler ISR_int0_handler:2
//Note: GIMSK I-bit cleared by MCU on INT and set by MCU on RETI
//Thus there should be no danger of us being involked multiple
//times by switch bounce (as long as delay is reasonable to see LED)
void ISR_int0_handler()
{
unsigned char a, b;
PORTB = 0x55;
delay2(5); //doing this in ISR causes heavy stack use.
/*
//this way is easier on the stack
for (a = 1; a; a++)
for (b = 1; b; b++)
;
*/
}
#pragma interrupt_handler ISR_tmr1_ovf_handler:7
void ISR_tmr1_ovf_handler()
{
// PORTB = 0x0f; //sanity check
tmrRollFlag = 1;
}
void delay(unsigned char n)
{
int i;
for (i = 0; i < n; i++) {
tmrRollFlag = 0;
while (!tmrRollFlag); //wait for IRQ
}
}
#ifdef FIXED_DELAY
void delay()
{
tmrRollFlag = 0;
while (!tmrRollFlag); //wait for IRQ
}
#endif
void delay2(unsigned char n)
{
unsigned char a, b, c;
for (a = 1; a; a++)
for (b = 1; b; b++)
for (c = 1; c<n; c++)
;
}
void LED_On(int i)
{
PORTB = ~BIT(i); /* low output to turn LED on */
// delay2(0);
delay(3);
}
void main()
{
signed char i, v;
DDRB = 0xFF; /* output */
PORTB = 0x55; //sanity check
delay2(5);
TCCR1A = 0;
TCCR1B = CLK_DIV_BY_8;
// TCCR1B = CLK_DIV_BY_64;
TIMSK = TMR1_OVF_INT_ENA;
MCUCR = INT0_TRIG_FALL_EDGE;
MCUCR = 0; //low level trig
GIMSK = INT0_ENA;
SREG = GLOBAL_INT_ENA; //enable ints
while (1)
{
/* forward march */
for (i = 0; i < 8; i++)
LED_On(i);
/* backward march, don't repeat bit 7 */
for (i = 6; i >= 0; i--)
LED_On(i);
//PORTB = 0xF0; //sanity check
//delay();
/* stack, don't repeat bit 0 */
for (i = 0, v = 3; i < 7; i++) {
PORTB = ~v;
v |= v << 1;
delay(3);
}
/* unstack */
for (i = 0, v = 0x7F; i < 8; i++) {
PORTB = ~v;
v &= v >> 1;
delay(3);
}
}
}