/*
* Copyright (C) 2022, Andrei Egorov
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define NumPixels 200
#define NumColors 3
#define DO_PIN 13
#if DO_PIN > 19
#error !!! DO_PIN must be less than 20 !!!
#endif
#define DOPORT (DO_PIN>=0 && DO_PIN<=7) ? 0x0B : (DO_PIN>=8 && DO_PIN<=13) ? 0x05 : (DO_PIN>=14 && DO_PIN<=19) ? 0x08 : 0
#define DOPIN (DO_PIN>=0 && DO_PIN<=7) ? DO_PIN : (DO_PIN>=8 && DO_PIN<=13) ? DO_PIN - 8 : (DO_PIN>=14 && DO_PIN<=19) ? DO_PIN - 14 : 0
uint8_t pixels[NumPixels][NumColors];
void __attribute__ ((noinline))send_pixels(uint16_t num, uint8_t *ppixels) {
static uint32_t endsend=0;
while ((micros()-endsend)<300);
asm volatile(
"IN __tmp_reg__,%0 \n\t"
"PUSH __tmp_reg__ \n\t"
"CLI \n\t"
"LDI r19,1<<%3 \n\t"
"LDI r18,2 \n\t"
"LD __tmp_reg__,%a1+ \n\t"
"label_1: \n\t"
"BST __tmp_reg__,7 \n\t"
"OUT %2-2,r19 \n\t"
"BRTC label_2 \n\t"
"ROL __tmp_reg__ \n\t"
"LSL r18 \n\t"
"RJMP .+0\n\t"
"RJMP .+0\n\t"
"BRCS label_3 \n\t"
"NOP \n\t"
"OUT %2-2,r19 \n\t"
"RJMP label_1 \n\t"
"label_2: \n\t"
"BST __tmp_reg__,7 \n\t"
"OUT %2-2,r19 \n\t"
"ROL __tmp_reg__ \n\t"
"LSL r18 \n\t"
"RJMP .+0\n\t"
"RJMP .+0\n\t"
"BRCC label_1 \n\t"
"RJMP label_4 \n\t"
"label_3: \n\t"
"OUT %2-2,r19 \n\t"
"RJMP .+0\n\t"
"BST __tmp_reg__,7 \n\t"
"label_4: \n\t"
"OUT %2-2,r19 \n\t"
"BRTC label_5 \n\t"
"RJMP .+0\n\t"
"LDI r18,2 \n\t"
"SBIW %4,1 \n\t"
"BREQ label_6 \n\t"
"LD __tmp_reg__,%a1+ \n\t"
"OUT %2-2,r19 \n\t"
"RJMP label_1 \n\t"
"label_5: \n\t"
"LDI r18,2 \n\t"
"OUT %2-2,r19 \n\t"
"SBIW %4,1 \n\t"
"LD __tmp_reg__,%a1+ \n\t"
"RJMP .+0\n\t"
"BRNE label_1 \n\t"
"RJMP label_7 \n\t"
"label_6: \n\t"
"NOP \n\t"
"OUT %2-2,r19 \n\t"
"label_7: \n\t"
"POP __tmp_reg__ \n\t"
"OUT %0,__tmp_reg__\n\t"
::"I" (_SFR_IO_ADDR(SREG)), "e" (ppixels), "I" (_SFR_IO_ADDR(_SFR_IO8(DOPORT))), "M" (DOPIN), "w" (num):"r18","r19"
);
endsend=micros();
}
void setup () {
asm volatile(
"SBI %0-1,%1 \n\t"
"CBI %0,%1 \n\t"
::"I" (_SFR_IO_ADDR(_SFR_IO8(DOPORT))), "I" (DOPIN)//, "r" (DO)
);
}
void loop() {
auto static p=0;
send_pixels(NumPixels*NumColors, *pixels);
pixels[p][random(NumColors)]=255;
pixels[p][random(NumColors)]=255;
pixels[p][random(NumColors)]=255;
for (auto i=0;i<NumPixels;i++) {
auto p=random(16);
if (pixels[i][0]<=p) pixels[i][0]=0; else pixels[i][0]-=p;
if (pixels[i][1]<=p) pixels[i][1]=0; else pixels[i][1]-=p;
if (pixels[i][2]<=p) pixels[i][2]=0; else pixels[i][2]-=p;
}
p++;
if (p==NumPixels) p=0;
}