#include <SPI.h>
#include "main.h"
#define CLK 52
#define DIN 51
#define CS 53
#define X_SEGMENTS 4
#define Y_SEGMENTS 1
#define NUM_SEGMENTS (X_SEGMENTS * Y_SEGMENTS)
#define X_LEDS_PER_SEGMENT 8
#define Y_LEDS_PER_SEGMENT 8
// a framebuffer to hold the state of the entire matrix of LEDs
// laid out in raster order, with (0, 0) at the top-left
byte fb[X_LEDS_PER_SEGMENT * Y_LEDS_PER_SEGMENT * X_SEGMENTS] =
{
1, 1, 0, 1, 1, 0, 0, 0,
0, 1, 1, 1, 1, 0, 0, 1,
0, 0, 0, 0, 1, 1, 1, 1,
};
void shiftAll(byte send_to_address, byte send_this_data) {
digitalWrite(CS, LOW);
for (int i = 0; i < NUM_SEGMENTS; i++) {
SPI.transfer(send_to_address);
SPI.transfer(send_this_data);
}
digitalWrite(CS, HIGH);
}
void setup() {
Serial.begin(115200);
pinMode(CLK, OUTPUT);
pinMode(DIN, OUTPUT);
pinMode(CS, OUTPUT);
SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
// Setup each MAX7219
shiftAll(0x0f, 0x00); //display test register - test mode off
shiftAll(0x0b, 0x07); //scan limit register - display digits 0 thru 7
shiftAll(0x0c, 0x01); //shutdown register - normal operation
shiftAll(0x0a, 0x0f); //intensity register - max brightness
shiftAll(0x09, 0x00); //decode mode register - No decode
}
/*void loop() {
// generate a Lissajous figure
static int16_t sx1 = 15 << 8, sx2 = sx1, sy1, sy2;
sx1 = sx1 - (sy1 >> 6);
sy1 = sy1 + (sx1 >> 6);
sx2 = sx2 - (sy2 >> 5);
sy2 = sy2 + (sx2 >> 5);
int8_t x_offset = (sx1 >> 8) - X_SEGMENTS * 4;
int8_t y_offset = (sx2 >> 8) - Y_SEGMENTS * 4;
static byte travel = 0;
travel--;
byte *dst = fb;
byte output = 0;
uint8_t screenx, screeny, xroot, yroot;
uint16_t xsumsquares, ysumsquares, xnextsquare, ynextsquare;
int8_t x, y;
// offset the origin in screen space
x = x_offset;
y = y_offset;
ysumsquares = x * x + y * y;
yroot = int(sqrtf(ysumsquares));
ynextsquare = yroot * yroot;
// Quadrant II (top-left)
screeny = Y_SEGMENTS * 8;
while (y < 0 && screeny) {
x = x_offset;
screenx = X_SEGMENTS * 8;
xsumsquares = ysumsquares;
xroot = yroot;
if (x < 0) {
xnextsquare = xroot * xroot;
while (x < 0 && screenx) {
screenx--;
output <<= 1;
output |= ((xroot + travel) & 8) >> 3;
if (!(screenx & 7))
*dst++ = output;
xsumsquares += 2 * x++ + 1;
if (xsumsquares < xnextsquare)
xnextsquare -= 2 * xroot-- - 1;
}
}
// Quadrant I (top-right)
if (screenx) {
xnextsquare = (xroot + 1) * (xroot + 1);
while (screenx) {
screenx--;
output <<= 1;
output |= ((xroot + travel) & 8) >> 3;
if (!(screenx & 7))
*dst++ = output;
xsumsquares += 2 * x++ + 1;
if (xsumsquares >= xnextsquare)
xnextsquare += 2 * ++xroot + 1;
}
}
ysumsquares += 2 * y++ + 1;
if (ysumsquares < ynextsquare)
ynextsquare -= 2 * yroot-- - 1;
screeny--;
}
// Quadrant III (bottom-left)
ynextsquare = (yroot + 1) * (yroot + 1);
while (screeny) {
x = x_offset;
screenx = X_SEGMENTS * 8;
xsumsquares = ysumsquares;
xroot = yroot;
if (x < 0) {
xnextsquare = xroot * xroot;
while (x < 0 && screenx) {
screenx--;
output <<= 1;
output |= ((xroot + travel) & 8) >> 3;
if (!(screenx & 7))
*dst++ = output;
xsumsquares += 2 * x++ + 1;
if (xsumsquares < xnextsquare)
xnextsquare -= 2 * xroot-- - 1;
}
}
// Quadrant IV (bottom-right)
if (screenx) {
xnextsquare = (xroot + 1) * (xroot + 1);
while (screenx--) {
output <<= 1;
output |= ((xroot + travel) & 8) >> 3;
if (!(screenx & 7))
*dst++ = output;
xsumsquares += 2 * x++ + 1;
if (xsumsquares >= xnextsquare)
xnextsquare += 2 * ++xroot + 1;
}
}
ysumsquares += 2 * y++ + 1;
if (ysumsquares >= ynextsquare)
ynextsquare += 2 * ++yroot + 1;
screeny--;
}
show();
delay(20);
}*/
// MAX7219 SPI LED Driver
#define MAX7219_TEST 0x0f // in real code put into a .h file
#define MAX7219_BRIGHTNESS 0x0a // in real code put into a .h file
#define MAX7219_SCAN_LIMIT 0x0b // in real code put into a .h file
#define MAX7219_DECODE_MODE 0x09 // in real code put into a .h file
#define MAX7219_SHUTDOWN 0x0C // in real code put into a .h file
void maxTransferCMD(uint8_t address, uint8_t value)
{
uint8_t i;
digitalWrite(CS, LOW);
SPI.transfer(address); // Send address.
SPI.transfer(value); // Send the value.
SPI.transfer(address); // Send address.
SPI.transfer(value); // Send the value.
digitalWrite(CS, HIGH); // Finish transfer.
}
void maxTransferDATA(uint8_t address, uint8_t value, uint8_t v2)
{
uint8_t i;
digitalWrite(CS, LOW);
SPI.transfer(address); // Send address.
SPI.transfer(value); // Send the value.
// SPI.transfer(address); // Send address.
// SPI.transfer(v2); // Send the value.
digitalWrite(CS, HIGH); // Finish transfer.
}
#define X_SEGMENTS 4
#define Y_SEGMENTS 1
#define NUM_SEGMENTS (X_SEGMENTS * Y_SEGMENTS)
#define X_LEDS_PER_SEGMENT 8
#define Y_LEDS_PER_SEGMENT 8
void loop()
{
int segment, n, x, i;
byte flag, shift;
for (int y = 0; y < Y_LEDS_PER_SEGMENT; y++)
{
digitalWrite(CS, LOW); // start of row
for (segment = 0; segment < X_SEGMENTS; segment++)
{
flag = 0;
for (n = 0; n < X_LEDS_PER_SEGMENT; n++)
{
x = X_LEDS_PER_SEGMENT * segment + n;
i = Y_LEDS_PER_SEGMENT * x + y;
shift = X_LEDS_PER_SEGMENT - 1 - n;
flag |= (fb[i] ? 1 : 0) << shift;
}
SPI.transfer(y+1);
SPI.transfer(flag);
//Serial.println(segment);
}
digitalWrite(CS, HIGH); // end of row
}
// uint8_t row=0;
// int i=0,ud=1; // Need signed numbers.
// for(int i = 0; i < sizeof(fb); i++)
// {
// //maxTransferDATA(1 + i, 64, 0);
// maxTransferDATA((i % 8) + 1, 2, 0);
// //maxTransferCMD(MAX7219_BRIGHTNESS,i>>4);
// delay(1000);
// //Serial.print(" i ");
// //Serial.println(i);
// //Serial.print(" ud ");
// //Serial.println(ud);
// }
// delay(3000);
}
// send the raster order framebuffer in the correct order
// for the boustrophedon layout of daisy-chained MAX7219s
void show()
{
for (int i = 0; i < sizeof(fb); i++)
{
digitalWrite(CS, LOW);
SPI.transfer(i+1);//sizeof(fb) % (X_LEDS_PER_SEGMENT * X_SEGMENTS));
SPI.transfer(1);//fb[i]);
digitalWrite(CS, HIGH);
}
/*
for (byte row = 0; row < 8; row++) {
digitalWrite(CS, LOW);
byte segment = NUM_SEGMENTS;
while (segment--) {
byte x = segment % X_SEGMENTS;
byte y = segment / X_SEGMENTS * 8;
byte addr = (row + y) * X_SEGMENTS;
if (segment & X_SEGMENTS) { // odd rows of segments
SPI.transfer(8 - row);
byte c = fb[addr + x];
// reverse the byte (LSB to MSB)
c = ((c >> 1) & 0x55) | ((c << 1) & 0xAA);
c = ((c >> 2) & 0x33) | ((c << 2) & 0xCC);
c = (c >> 4) | (c << 4);
SPI.transfer(c);
} else { // even rows of segments
SPI.transfer(1 + row);
SPI.transfer(fb[addr - x + X_SEGMENTS - 1]);
}
}
digitalWrite(CS, HIGH);
}*/
}