2 * Copyright 2017 Jonathan McDowell <noodles@earth.li>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
28 /* This is a small 8x4 font */
29 #include "font-atari.h"
31 /* The number of 8x8 displays we have daisy chained together */
32 #define MAX7219_WIDTH 4
54 uint8_t buf[8 * MAX7219_WIDTH];
58 static struct max7219_ctx ctx;
60 static void ICACHE_FLASH_ATTR max7219_write_reg(uint8_t reg, uint8_t data)
65 gpio_output_set(0, ctx.cs, ctx.cs, 0);
66 for (block = 0; block < ctx.width; block++) {
70 /* Set CS high to latch data into MAX7219 */
71 gpio_output_set(ctx.cs, 0, ctx.cs, 0);
75 void ICACHE_FLASH_ATTR max7219_set_pixel(unsigned int x, unsigned int y,
84 ctx.buf[y + block] |= 1 << x;
86 ctx.buf[y + block] &= ~(1 << x);
90 void ICACHE_FLASH_ATTR max7219_blit(unsigned int x, unsigned int y,
91 const uint8_t *data, unsigned int width, unsigned int height)
93 unsigned int block = x & 0x38;
94 unsigned int left_shift = x & 7;
95 bool twoblocks = ((left_shift + width) > 8) &&
96 ((x + width) < (ctx.width * 8));
97 unsigned int right_shift;
100 if (block >= (ctx.width << 3)) {
101 /* We're off the right hand side; do nothing */
106 if (block > (ctx.width << 3)) {
107 /* 2nd block is off the edge; ignore it */
110 right_shift = (8 - left_shift);
114 for (row = 0; row < height; row++)
119 ctx.buf[y + row + block] |= ((data[row] << left_shift) & 0xFF);
121 ctx.buf[y + row + (block + 8)] |=
122 (data[row] >> right_shift);
127 void ICACHE_FLASH_ATTR max7219_clear(void)
131 for (i = 0; i < ctx.width * 8;i++)
135 void ICACHE_FLASH_ATTR max7219_show(void)
140 for (y = 0; y < 8; y++) {
142 gpio_output_set(0, ctx.cs, ctx.cs, 0);
143 for (block = ctx.width - 1; block >= 0; block--) {
144 data[0] = 8 - y; /* Row reg */
145 data[1] = ctx.buf[y + (block << 3)]; /* Pixel val */
148 /* Set CS high to latch data into MAX7219 */
149 gpio_output_set(ctx.cs, 0, ctx.cs, 0);
154 void ICACHE_FLASH_ATTR max7219_print(const char *str)
159 while ((cur = (unsigned char) *str++) && x < (ctx.width * 8)) {
160 if ((cur > 31) && (cur < 127)) {
162 max7219_blit(x, 0, font[cur].bitmap,
164 x += font[cur].width + 1;
169 void ICACHE_FLASH_ATTR max7219_init(unsigned int cs)
171 ctx.width = MAX7219_WIDTH;
174 max7219_write_reg(SHUTDOWN, 0);
175 max7219_write_reg(DISPLAYTEST, 0);
176 max7219_write_reg(SCANLIMIT, 7);
177 max7219_write_reg(DECODEMODE, 0);
178 max7219_write_reg(INTENSITY, 0);
179 max7219_write_reg(SHUTDOWN, 1);