; vim: set syntax=avr ai :
#include <avr/io.h>
.global SIG_OUTPUT_COMPARE2
.section .bss
; данные
; формат :
; {
; интервал до следующего изменения состояния любого пина (1 байт)
; маска порта A (1 байт)
; маска порта B (1 байт)
; маска порта C (1 байт)
; маска порта D (1 байт)
; } * (количество пинов + 1)
; 0 - признак конца
data: .fill 86, 1, 0
; указатель на текущее положение в массиве data
ptr: .word 0
; выравнивающий до 20 мс интервал
ctr: .byte 1
; обратный cчетчик выравнивающего интервала
ctr1: .byte 1
; маски портов A,B,C, D
; определяют задействованные пины
masks: .byte 0,0,0,0
.section .text
SIG_OUTPUT_COMPARE2:
push R24
push R25
push R24
push R27
in R24, 0x3F
push R24
lds R26, ptr
lds R27, ptr+1
ld R24, X+
cpi R24, 0x00
breq zero
in R25, OCR2 - 0x20
add R25, R24
out OCR2 - 0x20, R25
ld R24, X+
in R25, PORTA-0x20
and R25, R24
out PORTA-0x20, R25
ld R24, X+
in R25, PORTA-0x20
and R25, R24
out PORTA-0x20, R25
ld R24, X+
in R25, PORTA-0x20
and R25, R24
out PORTA-0x20, R25
ld R24, X+
in R25, PORTA-0x20
and R25, R24
out PORTA-0x20, R25
sts ptr, R26
sts ptr+1, R27
rjmp exit
zero:
lds R24, ctr1
dec R24
brne store_ctr
ldi R26, lo8(masks)
ldi R27, hi8(masks)
ld R24, X+
in R25, PORTA - 0x20
or R24, R25
out PORTA-0x20, R24
ld R24, X+
in R25, PORTA - 0x20
or R24, R25
out PORTA-0x20, R24
ld R24, X+
in R25, PORTA - 0x20
or R24, R25
out PORTA-0x20, R24
ld R24, X+
in R25, PORTA - 0x20
or R24, R25
out PORTA-0x20, R24
ldi R24, lo8(data)
sts ptr, R24
ldi R24, hi8(data)
sts ptr+1, R24
in R24, OCR2 - 0x20
inc R24
out OCR2 - 0x20, R24
lds R24, ctr
store_ctr:
sts ctr1, R24
exit:
pop R24
out 0x3F, R24
pop R27
pop R26
pop R25
pop R24
reti
;uint8_t data[86];
;uint8_t* ptr;
;uint8_t ctr;
;uint8_t ctr1;
;uint8_t masks[4];
;
;
;ISR(SIG_OUTPUT_COMPARE2) {
; uint8_t* p = ptr;
; uint8_t interval = *(p++);
; if (interval == 0) {
; ctr1--;
; if (!ctr1) {
; PORTA |= masks[0];
; PORTB |= masks[1];
; PORTC |= masks[2];
; PORTD |= masks[3];
; ctr1 = ctr;
; ptr = data;
; OCR2++;
; }
; } else {
; OCR2 += interval;
; PORTA &= *(p++);
; PORTA &= *(p++);
; PORTA &= *(p++);
; PORTA &= *(p++);
; ptr = p;
; }
;}
;