|
@@ -0,0 +1,303 @@
|
|
|
+//Arduino\hardware\arduino\avr\cores\arduino
|
|
|
+#define SERIAL_RX_BUFFER_SIZE = 256
|
|
|
+
|
|
|
+#include <dataflash.h>
|
|
|
+#include <EEPROM.h>
|
|
|
+#include <TimerOne.h>
|
|
|
+
|
|
|
+int animationId = 0;
|
|
|
+unsigned long animationStart = 0;
|
|
|
+unsigned long animationLength = 0;
|
|
|
+unsigned long frameIndex = 0;
|
|
|
+bool animate = 0;
|
|
|
+Dataflash dflash;
|
|
|
+
|
|
|
+unsigned char buf[32];
|
|
|
+
|
|
|
+byte zpin[4]={6,5,9,10}; // z axis on pwmable pins
|
|
|
+byte sw[3]={A4,A5,2}; // 3 switches
|
|
|
+unsigned long led[4][2];//led[plane] [regNo] = brightness + (ledNo(8) << 16)
|
|
|
+unsigned int brightness[16] = {0, 1, 257, 2113, 4369, 9361, 35476, 21833, 43690, 21931, 30422, 61142, 30583, 65518, 63479, 65535};
|
|
|
+
|
|
|
+void setup() {
|
|
|
+ Serial.begin(115200);
|
|
|
+
|
|
|
+ pinMode(A0, OUTPUT);//data
|
|
|
+ pinMode(A1, OUTPUT);//sck
|
|
|
+ pinMode(A2, OUTPUT);//rck
|
|
|
+ pinMode(A3, OUTPUT);//sclr
|
|
|
+
|
|
|
+ for(byte i=0; i<4; i++) {
|
|
|
+ pinMode(zpin[i], OUTPUT);
|
|
|
+ }
|
|
|
+ for(byte i=0; i<3; i++) {
|
|
|
+ pinMode(sw[i], INPUT_PULLUP);
|
|
|
+ }
|
|
|
+ attachInterrupt(0, ta3, FALLING );
|
|
|
+ //attachInterrupt(1, suspend, CHANGE );
|
|
|
+
|
|
|
+ digitalWrite(A3, 0);
|
|
|
+ digitalWrite(A3, 1);
|
|
|
+
|
|
|
+ Timer1.initialize(16667);
|
|
|
+ Timer1.attachInterrupt( timerIsr );
|
|
|
+
|
|
|
+ dflash.init();
|
|
|
+ Serial.println("AtMega168PA");
|
|
|
+}
|
|
|
+
|
|
|
+void loop() {
|
|
|
+ while(Serial.available()>=1) {
|
|
|
+ char com = Serial.read();
|
|
|
+ if(com == '~') {
|
|
|
+ if(waitForSerial(1)) return;
|
|
|
+ exec(Serial.read());
|
|
|
+ } else {
|
|
|
+ error("no cmd",com);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ show();
|
|
|
+}
|
|
|
+void exec(byte com) {
|
|
|
+ if(com < 48) { //data
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if(com == '`') { //set 1 led
|
|
|
+ if(waitForSerial(2)) return;
|
|
|
+ byte get[2]={Serial.read()-32,Serial.read()-32};
|
|
|
+ if(get[0]<64 && get[1]<16) {
|
|
|
+ set(get[0], get[1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(com == 'a') {//set all leds
|
|
|
+ byte i = 0;
|
|
|
+ for(byte k=16; k<=64; k+=16) {
|
|
|
+ if(waitForSerial(16)) return;
|
|
|
+ while(i < k) {
|
|
|
+ set(i++, Serial.read()-32);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(com == 'b') {//set eeprom
|
|
|
+ if(waitForSerial(9)) return;//0:id, 1-4:start, 5-8:length
|
|
|
+ int i = Serial.read() * 8; //64 Id's
|
|
|
+ if(i>=512) {
|
|
|
+ error("EEPROM index", i);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for(byte n=0;n<8;n++) {
|
|
|
+ EEPROM.write(i+n, Serial.read());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(com == 'B') {//get eeprom
|
|
|
+ //0-3:start, 4-7:length
|
|
|
+ //64 Id's
|
|
|
+ for(int i=0; i<64; i++) {
|
|
|
+ Serial.print(i);
|
|
|
+ Serial.print(',');
|
|
|
+ Serial.print(eepromReadLong(i*8));
|
|
|
+ Serial.print(',');
|
|
|
+ Serial.println(eepromReadLong(i*8+4));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(com == 'c') {//set all leds to a value
|
|
|
+ if(waitForSerial(1)) return;
|
|
|
+ byte x = Serial.read()-32;
|
|
|
+ memset(led,x+(x<<4),sizeof(led));
|
|
|
+ }
|
|
|
+ else if(com == 'd') {//dump buffer
|
|
|
+ for(byte i=0;i<16;i++)
|
|
|
+ debug(String(dflash.Buffer_Read_Byte(1,i*32)), i);
|
|
|
+ }
|
|
|
+ else if(com == 'g') {//get frame count
|
|
|
+ Serial.println(frameIndex);
|
|
|
+ }
|
|
|
+ else if(com == 'h') {//set frame count
|
|
|
+ if(waitForSerial(4)) return;
|
|
|
+ frameIndex = readLong();
|
|
|
+ if(frameIndex >= 65536)
|
|
|
+ frameIndex = 0;
|
|
|
+ dflash.Page_To_Buffer(frameIndex/16, 2);
|
|
|
+ dflash.Buffer_Read_Str(2, (frameIndex % 16)*32, 32, buf);
|
|
|
+ for(byte i=0;i<8;i++) {
|
|
|
+ led[i>>1][i&1] = buf2Long(i*4);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ if(com == 's') {
|
|
|
+ animate = 1;
|
|
|
+
|
|
|
+ if(waitForSerial(1)) return;
|
|
|
+ int i = Serial.read(); //64 Id's
|
|
|
+ if(i>=64) {
|
|
|
+ error("EEPROM index", i);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ animationId = i;
|
|
|
+ readAnim();
|
|
|
+ }
|
|
|
+ else if(com == 't') {
|
|
|
+ if(frameIndex<animationStart+animationLength)
|
|
|
+ animate = !animate;
|
|
|
+ }
|
|
|
+ else if(com == 'u') {
|
|
|
+ animate = 0;
|
|
|
+ //readAnim();
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ if(com == 'x') {//load page to buffer 1
|
|
|
+ //4196 pages
|
|
|
+ if(waitForSerial(2)) return;
|
|
|
+ int i = readInt();
|
|
|
+ if(i>=4196) {
|
|
|
+ error("read page index", i);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ dflash.Page_To_Buffer(i, 1);
|
|
|
+ }
|
|
|
+ else if(com == 'y') {//set pattern in buffer 1
|
|
|
+ if(waitForSerial(1)) return;
|
|
|
+ int i = Serial.read() * 32;//16
|
|
|
+ if(i>=512) {
|
|
|
+ error("buffer index", i);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for(byte i=0;i<8;i++) {
|
|
|
+ buf[i*4] = (led[i>>1][i&1]>>24)&0xff;
|
|
|
+ buf[i*4+1] = (led[i>>1][i&1]>>16)&0xff;
|
|
|
+ buf[i*4+2] = (led[i>>1][i&1]>>8)&0xff;
|
|
|
+ buf[i*4+3] = (led[i>>1][i&1])&0xff;
|
|
|
+ }
|
|
|
+ dflash.Buffer_Write_Str(1,i,32,buf);
|
|
|
+ }
|
|
|
+ else if(com == 'z') {//write buffer 1 to page
|
|
|
+ /* 4bit/led * 64 = 32 byte
|
|
|
+ 2097152 byte / 32 = 65536
|
|
|
+ 18m12@60p/s
|
|
|
+ 528/32=16.5
|
|
|
+ * 4196 pages
|
|
|
+ */
|
|
|
+ if(waitForSerial(2)) return;
|
|
|
+ int i = readInt();
|
|
|
+ if(i>=4196) {
|
|
|
+ error("write page index", i);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ dflash.Buffer_To_Page(1, i);
|
|
|
+ debug("buffer to page", i);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ error("no cmd", com);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool waitForSerial(byte n) {
|
|
|
+ unsigned long t = millis();
|
|
|
+ while(Serial.available()<n) {
|
|
|
+ if(millis() - t > n * 2) {
|
|
|
+ error("timeout at byte", Serial.available());
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ show();
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+unsigned int readInt() {
|
|
|
+ return (Serial.read()<<8)+(Serial.read());
|
|
|
+}
|
|
|
+unsigned long readLong() {
|
|
|
+ return (Serial.read()<<24)+(Serial.read()<<16)+(Serial.read()<<8)+(Serial.read());
|
|
|
+}
|
|
|
+unsigned long eepromReadLong(int addr) {
|
|
|
+ return ((unsigned long)EEPROM.read(addr)<<24)+
|
|
|
+ ((unsigned long)EEPROM.read(addr+1)<<16)+
|
|
|
+ ((unsigned long)EEPROM.read(addr+2)<<8)+
|
|
|
+ ((unsigned long)EEPROM.read(addr+3));
|
|
|
+}
|
|
|
+unsigned long buf2Long(byte addr) {
|
|
|
+ return ((unsigned long)buf[addr]<<24)+
|
|
|
+ ((unsigned long)buf[addr+1]<<16)+
|
|
|
+ ((unsigned long)buf[addr+2]<<8)+
|
|
|
+ ((unsigned long)buf[addr+3]);
|
|
|
+}
|
|
|
+void set(byte i, unsigned long b) {
|
|
|
+ led[i>>4][(i&B100)>>2] &= ~((unsigned long)0xf << (((i&B11) << 3) + ((i&B1000)>>1)));
|
|
|
+ led[i>>4][(i&B100)>>2] |= (b&B1111) << (((i&B11) << 3) + ((i&B1000)>>1));
|
|
|
+}
|
|
|
+void add(byte x, byte y, byte z, unsigned long b) {
|
|
|
+ led[z][y%2] += b << (x*8+y*2);
|
|
|
+}
|
|
|
+void show() {
|
|
|
+ byte hOld = 3;
|
|
|
+ for(byte i=0;i<16;i++) { //brightnesses
|
|
|
+ for(byte h=0;h<4;h++) { //z axis
|
|
|
+ for(byte k=0;k<8; k++) {
|
|
|
+ PORTC |= (brightness[(led[h][0] >> (k<<2)) & 0xf] >> i) & 1;
|
|
|
+ PORTC |= B00000010;
|
|
|
+ PORTC &= B11111100;
|
|
|
+ PORTC |= (brightness[(led[h][1] >> (k<<2)) & 0xf] >> i) & 1;
|
|
|
+ PORTC |= B00000010;
|
|
|
+ PORTC &= B11111100;
|
|
|
+ }
|
|
|
+
|
|
|
+ digitalWrite(zpin[hOld],0);
|
|
|
+ PORTC |= B00000100;
|
|
|
+ PORTC &= B11111011;
|
|
|
+ digitalWrite(zpin[h],1);
|
|
|
+ hOld = h;
|
|
|
+ delayMicroseconds(5);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void suspend() {
|
|
|
+ Serial.println("ISR: suspend");
|
|
|
+}
|
|
|
+void ta3() {
|
|
|
+ readAnim();
|
|
|
+ if(++animationId==64 || animationLength == 0) animationId = 0;
|
|
|
+ if(animationLength == 0) {
|
|
|
+ animate=0;
|
|
|
+ memset(led,0,sizeof(led));
|
|
|
+ } else {
|
|
|
+ animate=1;
|
|
|
+ }
|
|
|
+}
|
|
|
+void readAnim() {
|
|
|
+ animationStart = eepromReadLong(animationId*8);
|
|
|
+ animationLength = eepromReadLong(animationId*8+4);
|
|
|
+ debug("Animation Id:", animationId);
|
|
|
+ debug("Start:", animationStart);
|
|
|
+ debug("length:", animationLength);
|
|
|
+ frameIndex=animationStart;
|
|
|
+}
|
|
|
+
|
|
|
+void timerIsr() {
|
|
|
+ if(animate) {
|
|
|
+ if(frameIndex >= 65536) frameIndex = 0;
|
|
|
+ if(frameIndex % 4 == 0) dflash.Page_To_Buffer(frameIndex/4, 2);
|
|
|
+ dflash.Buffer_Read_Str(2, (frameIndex % 4)*32, 32, buf);
|
|
|
+ for(byte i=0;i<8;i++) {
|
|
|
+ led[i>>1][i&1] = buf2Long(i*4);
|
|
|
+ }
|
|
|
+ frameIndex++;
|
|
|
+ if(frameIndex>=animationStart+animationLength) {
|
|
|
+ animate = 0;
|
|
|
+ memset(led,0,sizeof(led));
|
|
|
+ debug("animation stopped", frameIndex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+void error(const String& txt, const uint32_t& val) {
|
|
|
+ Serial.print("ERR: ");
|
|
|
+ Serial.print(txt);
|
|
|
+ Serial.print(" ");
|
|
|
+ Serial.println(val);
|
|
|
+}
|
|
|
+void debug(const String& txt, const uint32_t& val) {
|
|
|
+ Serial.print("DEBUG: ");
|
|
|
+ Serial.print(txt);
|
|
|
+ Serial.print(" ");
|
|
|
+ Serial.println(val);
|
|
|
+}
|