Skip to content

Commit c3b862f

Browse files
authored
Add files via upload
1 parent 3387be0 commit c3b862f

File tree

5 files changed

+1210
-0
lines changed

5 files changed

+1210
-0
lines changed

MoDisp_v2/MoDisp_v2.ino

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/* select "Tools->ATmega328 on breadboard 8MHz" to use internal clock */
2+
#include <stdint.h>
3+
#include <avr/interrupt.h>
4+
#include <avr/wdt.h>
5+
#include <util/delay.h>
6+
#include "operation.h"
7+
8+
/* max7221 select pins */
9+
#define G_SS 8
10+
#define R_SS 9
11+
12+
/* --- temp --- */
13+
uint8_t test_img[8] = {0xff, 0, 0xff, 0, 0xff, 0, 0xff, 0};
14+
/* --- Global Variables --- */
15+
uint8_t op;
16+
bool hasAddress = false;
17+
uint16_t myAddress; // address of this module s{row(x),column(y)}
18+
uint8_t parent_position;
19+
uint8_t PORT_DIR[4]; // PORT:index , content: direction
20+
bool isConnect[4] = {false}; // connection status
21+
/* --- I2C --- */
22+
volatile uint8_t dir, i2c_addr = 0, i2c_addr_last = 0; // current i2c data
23+
/* --- Ports --- */
24+
/* All serial ports are inverse logic(internal pull up)*/
25+
const uint8_t rx[4] = {14, 16, 4, 6};
26+
const uint8_t tx[4] = {15, 17, 5, 7};
27+
SoftwareSerial UART0(rx[0], tx[0], true);
28+
SoftwareSerial UART1(rx[1], tx[1], true);
29+
SoftwareSerial UART2(rx[2], tx[2], true);
30+
SoftwareSerial UART3(rx[3], tx[3], true);
31+
/* --- Image --- */
32+
volatile uint8_t image[8];
33+
volatile uint8_t intensity_G, intensity_R;
34+
/* --- Timer --- */
35+
volatile bool dispEnable = false;
36+
volatile bool loadEnable = false;
37+
38+
void timer_setup() {
39+
TCNT1 = 64286; // 10ms at 8MHz
40+
TCCR1A = 0x00;
41+
TCCR1B = (1 << CS11) | (1 << CS10); // 64 prescaler
42+
}
43+
44+
ISR(TIMER1_OVF_vect) {
45+
static bool colorToggle = true;
46+
if (loadEnable) {
47+
transform(image);
48+
disp(G_SS, intensity_G, image);
49+
disp(R_SS, intensity_R, image);
50+
loadEnable = false;
51+
}
52+
if (dispEnable) {
53+
if (colorToggle) {
54+
// shutdown red, enable green
55+
max7221(R_SS, SHUTDOWN, 0x00);
56+
max7221(G_SS, SHUTDOWN, 0x01);
57+
}
58+
else {
59+
// shutdown green, enable red
60+
max7221(G_SS, SHUTDOWN, 0x00);
61+
max7221(R_SS, SHUTDOWN, 0x01);
62+
}
63+
colorToggle = !colorToggle;
64+
}
65+
else {
66+
// turn off display
67+
max7221(G_SS, SHUTDOWN, 0x00);
68+
max7221(R_SS, SHUTDOWN, 0x00);
69+
}
70+
TCNT1 = 64286;
71+
}
72+
73+
void setup() {
74+
// MCUSR = 0;
75+
// WDTCSR = 0;
76+
MCUSR = 0; // clear WDT reset flag
77+
wdt_disable(); // disable WDT reset
78+
79+
SPI.begin();
80+
Serial.begin(9600);
81+
82+
// not sure why this will fail
83+
// Wire.begin(127); // fake i2c slave for reset function
84+
// TWAR |= (1 << TWGCE);
85+
// Wire.onReceive(fakeReceiveEvent);
86+
87+
module_setup();
88+
timer_setup();
89+
90+
Serial.println("reset");
91+
requestAddress();
92+
if (myAddress != plane_center)
93+
wait_i2cAddr();
94+
}
95+
96+
void loop() {
97+
/* polling 4 serial ports
98+
probably change to interrupt-driven*/
99+
for (uint8_t i = 0; i < 4; i++) {
100+
bool connection = !(digitalRead( rx[PORT[i]] ));
101+
if (connection) { // connected
102+
listenPort(PORT[i]);
103+
_delay_ms(10);
104+
if (availablePort(PORT[i])) {
105+
op = readPort(PORT[i]);
106+
action(i, op);
107+
}
108+
}
109+
else {
110+
// connection status changed
111+
if (connection != isConnect[i]) {
112+
// check connection again
113+
// if disconnected: note controller to reset all modules: reset_i2c = true
114+
_delay_ms(200); // time for manually reset
115+
connection = connect_check(PORT[i]);
116+
}
117+
}
118+
isConnect[i] = connection; // refresh connection status
119+
}
120+
}
121+
122+
void fakeReceiveEvent(int bytes) {
123+
if (Wire.available()) {
124+
cli();
125+
WDTCSR |= (1 << WDE);
126+
sei();
127+
while (1);
128+
}
129+
}
130+
131+
void receiveEvent(int bytes) {
132+
if (Wire.available()) {
133+
uint8_t i2c_op = Wire.read();
134+
135+
switch (i2c_op) {
136+
// perform actions according to op
137+
case (I2C_RST):
138+
cli();
139+
WDTCSR |= (1 << WDE); // enable WDT reset
140+
sei();
141+
// wdt_enable(WDTO_15MS);
142+
while (1); // lock until reset
143+
break;
144+
case (I2C_ADDR):
145+
if (Wire.available() >= 2) {
146+
dir = Wire.read();
147+
i2c_addr = Wire.read();
148+
}
149+
// sendI2CAddr(dir, i2c_addr); this function in I2C cause trouble, put this into normal flow
150+
break;
151+
case (I2C_IMAGE):
152+
if (Wire.available() >= 10) {
153+
for (uint8_t i = 0; i < 8; i++)
154+
image[i] = Wire.read();
155+
intensity_G = Wire.read();
156+
intensity_R = Wire.read();
157+
}
158+
break;
159+
case (I2C_DISP): // refresh image-related data
160+
dispEnable = true;
161+
loadEnable = true;
162+
TIMSK1 = (1 << TOIE1); // enable timer
163+
sei();
164+
break;
165+
case (I2C_SHUTDOWN):
166+
dispEnable = false;
167+
TIMSK1 &= ~(1 << TOIE1); // disable timer
168+
break;
169+
case (I2C_TEST):
170+
break;
171+
default: break;
172+
}
173+
}
174+
}

0 commit comments

Comments
 (0)