#include #include #include #define interrupt(x) void __attribute__((interrupt (x))) #define LEDS 8 #define DECAY 5 #define MAX 255 // ",".join([str(int(x**3/256/256)) for x in range(0, 256)]) const uint8_t bright_map[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3, 4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,8,8,8,9,9,9,10,10,10,11,11,11, 12,12,13,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,22, 22,23,23,24,25,25,26,27,27,28,29,29,30,31,32,32,33,34,35,35,36, 37,38,39,40,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56, 57,59,60,61,62,63,64,66,67,68,69,71,72,73,74,76,77,79,80,81,83, 84,86,87,88,90,91,93,95,96,98,99,101,103,104,106,108,109,111, 113,114,116,118,120,122,123,125,127,129,131,133,135,137,139,141, 143,145,147,149,151,153,155,158,160,162,164,166,169,171,173,176, 178,180,183,185,188,190,193,195,198,200,203,205,208,210,213,216, 218,221,224,227,229,232,235,238,241,244,247,250,253 }; // ",".join([str(int(128 + sin(x/256.0*pi*2)*127)) for x in range(0, 256)]) const uint8_t sin_table[] = { 128,131,134,137,140,143,146,149,152,155,158,161,164,167,170,173, 176,179,182,185,187,190,193,195,198,201,203,206,208,210,213,215, 217,219,222,224,226,228,230,231,233,235,236,238,240,241,242,244, 245,246,247,248,249,250,251,251,252,253,253,254,254,254,254,254, 255,254,254,254,254,254,253,253,252,251,251,250,249,248,247,246, 245,244,242,241,240,238,236,235,233,231,230,228,226,224,222,219, 217,215,213,210,208,206,203,201,198,195,193,190,187,185,182,179, 176,173,170,167,164,161,158,155,152,149,146,143,140,137,134,131, 128,124,121,118,115,112,109,106,103,100,97,94,91,88,85,82,79,76, 73,70,68,65,62,60,57,54,52,49,47,45,42,40,38,36,33,31,29,27,25, 24,22,20,19,17,15,14,13,11,10,9,8,7,6,5,4,4,3,2,2,1,1,1,1,1,1,1, 1,1,1,1,2,2,3,4,4,5,6,7,8,9,10,11,13,14,15,17,19,20,22,24,25,27, 29,31,33,36,38,40,42,45,47,49,52,54,57,60,62,65,68,70,73,76,79, 82,85,88,91,94,97,100,103,106,109,112,115,118,121,124 }; uint8_t bright[LEDS]; void delay_ms(uint16_t ms) { while (ms--) __delay_cycles(16000); } int16_t effect = 0; void knight_rider(uint8_t speed) { static int16_t cur = 0, dir = 1; static uint8_t frame = 1; static uint8_t decay = 0; uint16_t i; frame--; for (i = 0; i < LEDS; i++) { if (decay || i != cur) { if (bright[i] <= DECAY) bright[i] = 0; else bright[i] -= DECAY; } } if (frame == 0) { frame = speed; cur += dir; if (cur == LEDS - 1) { dir = -1; frame = speed * 3; decay = 0; } else if (cur == 0) { dir = 1; frame = speed * 3; decay = 0; } else { decay = 1; } bright[cur] = MAX; } } void sine(uint8_t speed) { static uint8_t frame = 1; static uint8_t a = 0; uint16_t i; frame--; if (frame == 0) { frame = speed; for (i = 0; i < LEDS; i++) bright[i] = sin_table[(i * 32 + a) & 0xFF]; a++; } } const uint8_t annoying_pattern[] = { // blink 0x55, 0x00, 0x00, 0x55, 0x00, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x55, 0x00, 0x00, 0x55, 0x00, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0x00, 0x00, // double blink 0x33, 0x00, 0x00, 0x33, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xCC, 0x00, 0x00, // left to right 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, // accumulate left to right 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88, 0x90, 0xA0, 0xC0, 0xC1, 0xC2, 0xC4, 0xC8, 0xD0, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xF0, 0xF1, 0xF2, 0xF4, 0xF8, 0xF9, 0xFA, 0xFC, 0xFD, 0xFE, // long on 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, // 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, // long pass 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, // out from middle 0x18, 0x24, 0x42, 0x81, 0x00, 0x00, 0x18, 0x24, 0x42, 0x81, 0x00, 0x00, // long out from middle 0x18, 0x3C, 0x7E, 0xFF, 0xE7, 0xC3, 0x81, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xE7, 0xC3, 0x81, 0x00, 0x00, // pause 0x00, 0x00, }; void annoying_christmas_lights(uint8_t speed) { static uint8_t frame = 0; static uint8_t a = 0; uint16_t i; uint8_t bit; frame++; if (frame == speed) { frame = 0; for (i = 0, bit = 1; i < LEDS; i++, bit <<= 1) bright[i] = (annoying_pattern[a] & bit) ? 255 : 0; a++; if (a >= sizeof(annoying_pattern) / sizeof(uint8_t)) a = 0; } } volatile uint8_t unsleep; void sleep(uint8_t speed) { uint16_t i; for (i = 0; i < LEDS; i++) bright[i] = 0; delay_ms(10); while (!(P2IN & 0x08)) ; delay_ms(10); P2IE |= 0x08; P2IFG = 0; unsleep = 0; while (!unsleep) __bis_SR_register(LPM3_bits | GIE); P2IE &= ~0x08; __bic_SR_register(GIE); effect = 0; delay_ms(10); } struct { void (*func)(uint8_t speed); int8_t speed; } effects[] = { { &knight_rider, 10 }, { &knight_rider, 5 }, { &sine, 1 }, { &sine, 3 }, { &annoying_christmas_lights, 10 }, { &sleep, 0 }, { 0, 0} }; uint16_t debug[8]; int main() { // Disable watchdog WDTCTL = WDTPW | WDTHOLD; // 16MHz clock BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; P1SEL = 0; P1SEL2 = 0; P2SEL = 0; P2SEL2 = 0; P1OUT = 0; P2OUT = 0; P1DIR = 0x3E; P2DIR = 0x07; P2REN |= 0x08; P2OUT |= 0x08; P2IES |= 0x08; // high-to-low interrupt delay_ms(10); int16_t i; uint8_t pwm = 0; uint8_t prev_down = !(P2IN & 0x08); for (i = 0; i < LEDS; i++) bright[i] = 0; while (1) { uint16_t val = 0; for (i = 0; i < LEDS; i++) { if (pwm * 2 < bright_map[bright[i]]) val |= 1 << i; } P1OUT &= ~0x3E; P1OUT |= (val << 1) & 0x3E; P2OUT &= ~0x07; P2OUT |= (val >> 5) & 0x07; pwm++; if (pwm == 128) { pwm = 0; uint8_t down = !(P2IN & 0x08); if (down && !prev_down) { effect++; if (!effects[effect].func) effect = 0; } prev_down = down; effects[effect].func(effects[effect].speed); } __delay_cycles(1200); } } interrupt(PORT2_VECTOR) port2_interrupt() { if (P2IFG & 0x08) { unsleep = 1; __bic_SR_register_on_exit(LPM3_bits); } P2IFG = 0; }