Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

executable file 308 lines (257 sloc) 6.354 kb
/*
* shhh_5th_avr.c
*
* Created: 28/09/2013 5:57:33 PM
* Author: Richard
*/
#define F_CPU 1000000UL // 1 MHz
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#define DELAY_SET_COL //_delay_us(1)
#define DELAY_SET_ROW //_delay_ms(1)
#define DELAY_H_BLANK //_delay_ms(500)
#define DELAY_V_BLANK //_delay_ms(1000)
#define NUM_ROWS 8
#define NUM_COLS 16
struct ButtonState
{
uint8_t up;
uint8_t down;
uint8_t left;
uint8_t right;
uint8_t center;
uint8_t action;
};
#define BUTTON_PRESSED(CURR_BUTTONS, PREV_BUTTONS, BUTTON) ((CURR_BUTTONS.BUTTON != 0) && (PREV_BUTTONS.BUTTON == 0))
struct Pixel
{
uint8_t g, r;
};
struct Pixel gLEDMatrix[NUM_COLS][NUM_ROWS];
struct ButtonState gButtons;
int gCurrRow;
int gCurrCol;
void GetButtonState(struct ButtonState* pButtonState)
{
uint8_t bval = (PINC >> 1) & 0b00000111;
pButtonState->up = (bval == 1);
pButtonState->left = (bval == 3);
pButtonState->right = (bval == 4);
pButtonState->down = (bval == 6);
pButtonState->center = (bval == 7);
pButtonState->action = 1 - (PINC & 0b00000001);
}
#define ROW_ENABLE_FROM_CPU (1 << PORTD7)
void BlankRow(uint8_t aBlank)
{
if (aBlank)
PORTD &= ~ROW_ENABLE_FROM_CPU;
else
PORTD |= ROW_ENABLE_FROM_CPU;
}
#define COLUMN_FROM_CPU_CLOCK (1 << PORTD5)
#define COLUMN_FROM_CPU_DATA (1 << PORTD6)
void SetColumn(uint8_t c)
{
uint8_t portd = PORTD;
if (c == 0)
portd |= COLUMN_FROM_CPU_DATA;
else
portd &= ~COLUMN_FROM_CPU_DATA;
PORTD = portd & ~COLUMN_FROM_CPU_CLOCK;
PORTD = portd | COLUMN_FROM_CPU_CLOCK;
}
#define GREEN_ROW_FROM_CPU_DATA (1 << PORTB0)
#define RED_ROW_FROM_CPU_DATA (1 << PORTB1)
#define ROW_FROM_CPU_CLOCK (1 << PORTB2)
void ClockRowData(uint8_t green_data, uint8_t red_data)
{
uint8_t portb = PORTB;
if (green_data)
portb |= GREEN_ROW_FROM_CPU_DATA;
else
portb &= ~GREEN_ROW_FROM_CPU_DATA;
if (red_data)
portb |= RED_ROW_FROM_CPU_DATA;
else
portb &= ~RED_ROW_FROM_CPU_DATA;
PORTB = portb & ~ROW_FROM_CPU_CLOCK;
PORTB = portb | ROW_FROM_CPU_CLOCK;
}
void updateInput(void)
{
struct ButtonState prev_buttons = gButtons;
GetButtonState(&gButtons);
if (BUTTON_PRESSED(gButtons, prev_buttons, up))
{
gCurrRow--;
if (gCurrRow < 0)
gCurrRow = NUM_ROWS - 1;
}
else if (BUTTON_PRESSED(gButtons, prev_buttons, down))
{
gCurrRow++;
if (gCurrRow == NUM_ROWS)
gCurrRow = 0;
}
else if (BUTTON_PRESSED(gButtons, prev_buttons, left))
{
gCurrCol--;
if (gCurrCol < 0)
gCurrCol = NUM_COLS - 1;
}
else if (BUTTON_PRESSED(gButtons, prev_buttons, right))
{
gCurrCol++;
if (gCurrCol == NUM_COLS)
gCurrCol = 0;
}
else if (BUTTON_PRESSED(gButtons, prev_buttons, center))
{
asm("nop");
}
if (BUTTON_PRESSED(gButtons, prev_buttons, action))
{
struct Pixel* pCurrPixel = &(gLEDMatrix[gCurrCol][gCurrRow]);
if ((pCurrPixel->g == 0) && (pCurrPixel->r == 0))
pCurrPixel->g = 1;
else if ((pCurrPixel->g != 0) && (pCurrPixel->r == 0))
pCurrPixel->r = 1;
else if ((pCurrPixel->g != 0) && (pCurrPixel->r != 0))
pCurrPixel->g = 0;
else if ((pCurrPixel->g == 0) && (pCurrPixel->r != 0))
pCurrPixel->r = 0;
}
}
void refreshLEDMatrix(void)
{
for (uint8_t col=0; col<NUM_COLS; col++)
{
BlankRow(1);
SetColumn(col);
for (uint8_t row=0; row<NUM_ROWS; row++)
{
ClockRowData(gLEDMatrix[col][row].g != 0, gLEDMatrix[col][row].r != 0);
}
BlankRow(0);
_delay_ms(8);
}
}
static const unsigned char tom[8][16] = {
{ 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0,},
{ 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1,},
{ 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0,},
{ 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0,},
{ 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1,},
{ 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1,},
{ 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0,},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
};
void updateMatrix()
{
static unsigned char state = 0;
if (++state > 5) state = 0;
for (uint8_t col=0; col<NUM_COLS; col++)
{
for (uint8_t row=0; row<NUM_ROWS; row++)
{
switch(state)
{
default:
gLEDMatrix[col][row].g = 1;
gLEDMatrix[col][row].r = 0;
break;
case 1:
gLEDMatrix[col][row].g = 0;
gLEDMatrix[col][row].r = 1;
break;
case 2:
gLEDMatrix[col][row].g = 1;
gLEDMatrix[col][row].r = 1;
break;
case 3:
gLEDMatrix[col][row].g = tom[row][col];
gLEDMatrix[col][row].r = tom[row][col] == 1 ? 0 : 1;
break;
case 4:
gLEDMatrix[col][row].g = (row % 2) == (col %2) ;
gLEDMatrix[col][row].r = 0;
break;
case 5:
gLEDMatrix[col][row].g = 0;
gLEDMatrix[col][row].r = ((row % 2) == (col %2)) ? 0 : 1;
break;
}
}
}
}
void loop(void)
{
// updateInput();
refreshLEDMatrix();
static unsigned short counter = 0;
if (++counter != 100) return;
counter = 0;
updateMatrix();
}
int main(void)
{
DDRC = 0b00110000; // PC inputs (I2C? ADC6/7?)
DDRD = 0b11111110;
DDRB = 0b00101111;
// Turn pullup on for PC0 (action button)
PORTC = 0b00000001;
// memset(gLEDMatrix, 0x0, sizeof(gLEDMatrix));
memset(&gButtons, 0, sizeof(gButtons));
GetButtonState(&gButtons);
BlankRow(1);
for (uint8_t ix=0; ix < NUM_COLS; ++ix)
{
SetColumn(ix);
ClockRowData(0, 0);
}
BlankRow(0);
#if 0
while(1)
for (uint8_t col=0; col<NUM_COLS; ++col)
{
BlankRow(1);
SetColumn(col);
for (uint8_t row=0; row<NUM_ROWS; row++)
{
ClockRowData((row % 2) == (col %2) ? 0 : 1, 0);
}
BlankRow(0);
_delay_ms(8);
}
while (1);
SetColumn(0);
while(1)
{
BlankRow(1);
for (uint8_t col=0; col<NUM_COLS; ++col)
{
SetColumn(col);
for (uint8_t row=0; row<NUM_ROWS; row++)
{
ClockRowData(1,0);
}
BlankRow(0);
_delay_ms(5);
}
}
gCurrCol = 0;
gCurrRow = 0;
for (uint8_t row=0; row<NUM_ROWS; row++)
{
ClockRowData(0,0); // G
}
#endif
// initial display
updateMatrix();
while(1)
{
loop();
}
}
Jump to Line
Something went wrong with that request. Please try again.