-
Notifications
You must be signed in to change notification settings - Fork 0
/
ledmatrix.c
150 lines (131 loc) · 4.79 KB
/
ledmatrix.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
* ledmatrix.c
*
* Author: Peter Sutton
*
* See the LED matrix Reference for details of the SPI commands used.
*/
#include <avr/io.h>
#include "ledmatrix.h"
#include "spi.h"
#define CMD_UPDATE_ALL 0x00
#define CMD_UPDATE_PIXEL 0x01
#define CMD_UPDATE_ROW 0x02
#define CMD_UPDATE_COL 0x03
#define CMD_SHIFT_DISPLAY 0x04
#define CMD_CLEAR_SCREEN 0x0F
static MatrixData game =
{
{0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0},
{0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0},
{0x0F, 0x0F, 0x0F, 0x0F, 0xF0, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00},
{0x0F, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0xF0, 0xF0},
{0x0F, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00},
{0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00},
{0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00}
};
static MatrixData over =
{
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F},
{0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x00},
{0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x00, 0x00, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x00, 0x00, 0x0F},
{0xF0, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F},
{0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0x0F, 0x0F, 0x0F, 0x00},
{0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00}
};
uint8_t game_over_screen = 0;
void ledmatrix_setup(void) {
// Setup SPI - we divide the clock by 128.
// (This speed guarantees the SPI buffer will never overflow on
// the LED matrix.)
spi_setup_master(128);
}
void ledmatrix_update_all(MatrixData data) {
(void)spi_send_byte(CMD_UPDATE_ALL);
for(uint8_t x = 0; x < MATRIX_NUM_ROWS; x++) {
for(uint8_t y = 0; y < MATRIX_NUM_COLUMNS; y++) {
(void)spi_send_byte(data[x][y]);
}
}
}
void ledmatrix_update_pixel(uint8_t x, uint8_t y, PixelColour pixel) {
if(x >= MATRIX_NUM_COLUMNS || y >= MATRIX_NUM_ROWS) {
// Position isn't valid - we ignore the request.
return;
}
(void)spi_send_byte(CMD_UPDATE_PIXEL);
(void)spi_send_byte( ((y & 0x07)<<4) | (x & 0x0F));
(void)spi_send_byte(pixel);
}
void ledmatrix_update_row(uint8_t y, MatrixRow row) {
if(y >= MATRIX_NUM_ROWS) {
// y value is too large - we ignore the request
return;
}
(void)spi_send_byte(CMD_UPDATE_ROW);
(void)spi_send_byte(y & 0x07); // row number
for(uint8_t x = 0; x<MATRIX_NUM_COLUMNS; x++) {
(void)spi_send_byte(row[x]);
}
}
void ledmatrix_update_column(uint8_t x, MatrixColumn col) {
if(x >= MATRIX_NUM_COLUMNS) {
// x value is too large - we ignore the request
return;
}
(void)spi_send_byte(CMD_UPDATE_COL);
(void)spi_send_byte(x & 0x0F); // column number
for(uint8_t y = 0; y<MATRIX_NUM_ROWS; y++) {
(void)spi_send_byte(col[y]);
}
}
void ledmatrix_shift_display_left(void) {
(void)spi_send_byte(CMD_SHIFT_DISPLAY);
(void)spi_send_byte(0x02);
}
void ledmatrix_shift_display_right(void) {
(void)spi_send_byte(CMD_SHIFT_DISPLAY);
(void)spi_send_byte(0x01);
}
void ledmatrix_shift_display_up(void) {
(void)spi_send_byte(CMD_SHIFT_DISPLAY);
(void)spi_send_byte(0x08);
}
void ledmatrix_shift_display_down(void) {
(void)spi_send_byte(CMD_SHIFT_DISPLAY);
(void)spi_send_byte(0x04);
}
void ledmatrix_clear(void) {
(void)spi_send_byte(CMD_CLEAR_SCREEN);
}
void copy_matrix_column(MatrixColumn from, MatrixColumn to) {
for(uint8_t row = 0; row <MATRIX_NUM_ROWS; row++) {
to[row] = from[row];
}
}
void copy_matrix_row(MatrixRow from, MatrixRow to) {
for(uint8_t col = 0; col < MATRIX_NUM_COLUMNS; col++) {
to[col] = from[col];
}
}
void set_matrix_column_to_colour(MatrixColumn matrix_column, PixelColour colour) {
for(uint8_t row = 0; row < MATRIX_NUM_ROWS; row++) {
matrix_column[row] = colour;
}
}
void set_matrix_row_to_colour(MatrixRow matrix_row, PixelColour colour) {
for(uint8_t column = 0; column < MATRIX_NUM_COLUMNS; column++) {
matrix_row[column] = colour;
}
}
void show_game_over(void) {
if (!game_over_screen) {
ledmatrix_update_all(game);
} else {
ledmatrix_update_all(over);
}
game_over_screen = 1 - game_over_screen;
}