// Matt Edwards // RGB LED color test (for MDE RGB board v1) // Based on hello.array.44.c, "Charlieplex LED array hello-world", by Neil Gershenfeld #include #include #include #define output(directions,pin) (directions |= pin) // set port direction for output #define input(directions,pin) (directions &= (~pin)) // set port direction for input #define set(port,pin) (port |= pin) // set port pin #define clear(port,pin) (port &= (~pin)) // clear port pin #define pin_test(pins,pin) (pins & pin) // test for port pin #define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set static const uint8_t rowPins[16] = { 1 << PD2, 1 << PD1, 1 << PD0, 1 << PC5, 1 << PC4, 1 << PC3, 1 << PC2, 1 << PC1, 1 << PC0, 1 << PB5, 1 << PB4, 1 << PB2, 1 << PB1, 1 << PB0, 1 << PD7, 1 << PD6, }; static const uint8_t map[4][4][4] = { { {0xff, 0, 0, 0xff}, {0xff,0xff,0xff, 0xff}, {0xff, 0, 0, 0xff}, {0xff, 0, 0, 0xff}, }, { {0xff,0xff,0xff,0xff}, { 0,0xff,0xff, 0}, { 0,0xff,0xff, 0}, {0xff,0xff,0xff,0xff}, }, { {0xff,0xff,0xff,0xff}, { 0,0xff,0xff, 0}, { 0,0xff,0xff, 0}, { 0,0xff,0xff, 0}, }, { {0xff,0xff,0xff,0xff}, { 0,0xff,0xff, 0}, { 0,0xff,0xff, 0}, { 0,0xff,0xff, 0}, }, }; static volatile uint8_t* rowPorts[16]; static volatile uint8_t* rowDirections[16]; void rgbflash(uint8_t from, uint8_t to1, uint8_t to2, uint8_t to3, uint8_t Rpct, uint8_t Gpct, uint8_t Bpct, uint8_t cycles) { set(*rowPorts[from], rowPins[from]); clear(*rowPorts[to1], rowPins[to1]); clear(*rowPorts[to2], rowPins[to2]); clear(*rowPorts[to3], rowPins[to3]); output(*rowDirections[from], rowPins[from]); for (uint8_t j = 0; j < cycles; ++j) { output(*rowDirections[to1], rowPins[to1]); output(*rowDirections[to2], rowPins[to2]); output(*rowDirections[to3], rowPins[to3]); for (uint8_t i = 0; i < 100; ++i) { if (i >= Rpct) { clear(*rowDirections[to1], rowPins[to1]); } if (i >= Gpct) { clear(*rowDirections[to2], rowPins[to2]); } if (i >= Bpct) { clear(*rowDirections[to3], rowPins[to3]); } _delay_us(1); } } input(*rowDirections[from], rowPins[from]); input(*rowDirections[to1], rowPins[to1]); input(*rowDirections[to2], rowPins[to2]); input(*rowDirections[to3], rowPins[to3]); } int main(void) { // set clock divider to /1 CLKPR = (1 << CLKPCE); CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); rowPorts[0] = &PORTD; rowPorts[1] = &PORTD; rowPorts[2] = &PORTD; rowPorts[3] = &PORTC; rowPorts[4] = &PORTC; rowPorts[5] = &PORTC; rowPorts[6] = &PORTC; rowPorts[7] = &PORTC; rowPorts[8] = &PORTC; rowPorts[9] = &PORTB; rowPorts[10] = &PORTB; rowPorts[11] = &PORTB; rowPorts[12] = &PORTB; rowPorts[13] = &PORTB; rowPorts[14] = &PORTD; rowPorts[15] = &PORTD; rowDirections[0] = &DDRD; rowDirections[1] = &DDRD; rowDirections[2] = &DDRD; rowDirections[3] = &DDRC; rowDirections[4] = &DDRC; rowDirections[5] = &DDRC; rowDirections[6] = &DDRC; rowDirections[7] = &DDRC; rowDirections[8] = &DDRC; rowDirections[9] = &DDRB; rowDirections[10] = &DDRB; rowDirections[11] = &DDRB; rowDirections[12] = &DDRB; rowDirections[13] = &DDRB; rowDirections[14] = &DDRD; rowDirections[15] = &DDRD; uint8_t t = 1, mult = 0; uint8_t r = 0, g = 0, b = 100; uint16_t count = 0; // green pin of top left LED is not soldered correctly (bottom right pin). while (1) { for (uint8_t base = 0; base < 16; base += 4) { mult = map[(count >> 7) & 3][base/4][0]; rgbflash(0 + base, 1 + base, 2 + base, 3 + base, r&mult, g&mult, b&mult, t); mult = map[(count >> 7) & 3][base/4][1]; rgbflash(3 + base, 2 + base, 1 + base, 0 + base, r&mult, g&mult, b&mult, t); mult = map[(count >> 7) & 3][base/4][2]; rgbflash(1 + base, 0 + base, 3 + base, 2 + base, r&mult, g&mult, b&mult, t); mult = map[(count >> 7) & 3][base/4][3]; rgbflash(2 + base, 3 + base, 0 + base, 1 + base, r&mult, g&mult, b&mult, t); if ((count & 0xf) == 0) { r += (rand() % 5) - 2; g += (rand() % 5) - 2; b += (rand() % 5) - 2; r %= 100; g %= 100; b %= 100; } count += 1; } continue; rgbflash(4, 5, 6, 7, r, g, b, t); rgbflash(5, 6, 4, 7, r, g, b, t); rgbflash(6, 4, 5, 7, r, g, b, t); rgbflash(7, 4, 5, 6, r, g, b, t); rgbflash(8, 9, 10, 11, r, g, b, t); rgbflash(9, 10, 8, 11, r, g, b, t); rgbflash(10, 8, 9, 11, r, g, b, t); rgbflash(11, 8, 9, 10, r, g, b, t); rgbflash(12, 13, 14, 15, r, g, b, t); rgbflash(13, 14, 12, 15, r, g, b, t); rgbflash(14, 12, 13, 15, r, g, b, t); rgbflash(15, 12, 13, 14, r, g, b, t); // rgbflash(0, 1, 2, 3, 0, 0, 0, 100); } }