////////////////////////////////////////////////////////////////////////////////
// ATmega328: 
// начальное: RC - 1 МHz: Higt D9; Ext 07; Lok 3F; Low 62;
//            RC - 8 МHz: Higt D9; Ext 07; Lok 3F; Low E2;
//         кварц - 8 МHz: Higt D9; Ext 07; Lok 3F; Low E7; XTAL2(PB7) - выход -V
//    XTAL1(PB6) – вход;  Higt D9; Ext 07; Lok 3F; Low 60;
/////////////////////////////////////////////////////////////////////////////////
//Ethernet preamble = 8 байт
//Ethernet Data = 60...1514 байт
//Ethernet crc = 4 байт  
//Ethernet межпакетный интервал = 12 байт (96 бит * 0,1 мкс = 9,6 мкс). 
/////////////////////////////////////////////////////////////////////////////////


.include "m328Pdef.inc"// мега328
/////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////// SRAM
/**/
.DSEG  // SRAM
FIFO: .BYTE 2048
.CSEG  // Program

/////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////// PORT
////////////////////////////// выход  (Port B)
//DDRB.7=0;         // вход XTAL1 – IN
//PORTB.7=0;        // вход XTAL1 – IN
//DDRB.6=0;         // вход XTAL2 –OUT
//PORTB.6=0;        // вход XTAL2 –OUT
////////////////////////////// SPI (мастер) 
//DDRB.5=1;         // выход SCK
//PORTB.5=0;        // выход SCK
//DDRB.4=0;         // вход MISO
//PORTB.4=0;        // вход MISO
//DDRB.3=1;         // выход MOSI
//PORTB.3=0;        // выход MOSI
//DDRB.2=1;         // выход SS (! SS настроен на выход)  
//PORTB.2=1;        // выход SS (! SS настроен на выход)  
////////////////////////////// SPI (слейв)
//DDRB.5=0;         // вход SCK
//PORTB.5=0;        // вход SCK
//DDRB.4=1;         // выход MISO
//PORTB.4=0;        // выход MISO
//DDRB.3=0;         // вход MOSI
//PORTB.3=0;        // вход MOSI
//DDRB.2=0;         // вход SS 
//PORTB.2=1;        // вход SS+
//////////////////////////////
//DDRB.1=1;         // выход INT 
//PORTB.1=1;        // выход INT+
//DDRB.0=1;         // выход LCD  
//PORTB.0=1;        // выход LCD 
////////////////////////////// выход  (Port B)
LDI R22, 0b00000011    // Запись регистра -1 такт // SPI (слейв) // выкл выход MISO
OUT DDRB, R22          // OUT Port -1 такт
LDI R22, 0b00000110    // Запись регистра -1 такт // SPI (слейв) SS+ INT+  
OUT PORTB, R22         // OUT Port -1 такт
////////////////////////////// кнопки (Port C)
LDI R22, 0b00000000    // Запись регистра -1 такт  
OUT DDRC, R22          // OUT Port -1 такт
LDI R22, 0b11111111    // Запись регистра -1 такт ++++++++
OUT PORTC, R22         // OUT Port -1 такт
////////////////////////////// вход  (Port D)
LDI R22, 0b00000000    // Запись регистра -1 такт  
//LDI R22, 0b11111111  // Запись регистра -1 такт  
OUT DDRD, R22          // OUT Port -1 такт
LDI R22, 0b00000000    // Запись регистра -1 такт 
OUT PORTD, R22         // OUT Port -1 такт
/////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////// REG
////////////////////////////// счёт
//LDI R16, 0b00000000  // x
//LDI R17, 0b00000000  // x1
//LDI R18, 0b00000000  // x2
//LDI R19, 0b00000000  // x3
////////////////////////////// TX_Ethernet 
//LDI R20, 0b00000000  // Запись регистра -1 такт
//LDI R21, 0b00000001  // Запись регистра -1 такт
////////////////////////////// Data
//LDI R22, 0b00000000  // Запись регистра -1 такт
////////////////////////////// Ethernet preamble/SFD (synchronizer): 10101010 
LDI R23, 0b10101010    // Запись регистра -1 такт
////////////////////////////// 
//LDI R24, 0b00000000  // Запись регистра -1 такт
//LDI R25, 0b00000000  // Запись регистра -1 такт
////////////////////////////// X 
//LDI R26, 0b00000000  // Запись регистра -1 такт
//LDI R27, 0b00000000  // Запись регистра -1 такт
////////////////////////////// Y
//LDI R28, 0b00000000  // Запись регистра -1 такт
//LDI R29, 0b00000000  // Запись регистра -1 такт
////////////////////////////// Z
//LDI R30, 0b00000000  // Запись регистра -1 такт
//LDI R31, 0b00000000  // Запись регистра -1 такт
/////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////// SPI
//SPCR=0b01010000;  // Регистр управления
// 0... .... SPIE разрешение прерывания...
// .1.. .... SPE разрешается работа SPI.
// ..0. .... DORD порядок сдвига данных DORD=0 первым передается старший разряд.
// ...1 .... MSTR (1-мастер, 0-слейв).
// .... 0... CPOL   0 = SCK имеет низкий уровень в состоянии ожидания. (полярность синхро).
// .... .0.. CPHA   0 = установка-задний фронт/выборка передий фронт SCK (фаза синхро).
// .... ..00 SPR1, SPR0      SCK = кварц 8 Мгц/4 = 2 МГц (частота синхро).
// .... ..00 SPR1, SPR0  f/4
// .... ..01 SPR1, SPR0  f/16
// .... ..10 SPR1, SPR0  f/64         
// .... ..11 SPR1, SPR0  f/128
/*
//SPCR=0x50;        // 8 МГц/4 = 2 МГц -режим мастер
LDI R22, 0b01010000 // Запись регистра -1 такт 
OUT SPCR, R22       // 8 МГц/4 = 2 МГц -режим мастер // OUT -1 такт
*/
/**/
//SPCR=0x40;        // 8 МГц/4 = 2 МГц -режим слейв
LDI R22, 0b01000000 // Запись регистра -1 такт 
OUT SPCR, R22       // 8 МГц/4 = 2 МГц -режим слейв  // OUT -1 такт

////////////////////////////// SPI
//SPSR=0b10000000;   // Регистр статуса
// 1... .... Флаг SPIF завершении последовательной передачи. (SPIF Сбрасывается при чтении SPSR). 
// .1.. .... Флаг повторной записи (устанавливается, если выполнена запись в регистр данных SPI (SPDR) во
//            время передачи данных).
// .... ...1  SPI2X - удвоенная скорость передачи.  SCK = кварц 4 Мгц/2 = 2 МГц (частота синхро).
//           (период SCK будет равен двум периодам синхронизации ЦПУ. 
// Если SPI работает как подчиненный, то работа SPI гарантирована только на частоте fosc /4 или менее. 
//SPSR=0b00000001;  // .... ...1  SPI2X - удвоенная скорость
/*
LDI R22, 0b00000001 // Запись регистра -1 такт 
OUT SPSR, R22       // 8 МГц/4 = 2 МГц -режим мастер // OUT -1 такт
*/
////////////////////////////// SPI
/*
LDS R22, FIFO+0     // Чтение SRAM        -2 такт 
OUT SPDR, R22       // Запись SPI         -1 такт
while_0:            // while(!(SPSR & (1<<7)));
SBIC PINB, 2        // проверка SS = 0    -1 такт
RJMP SPI_stop       // > SPI_stop         -1 такт // -1 такт(переход)


//SBIC PINC     //пропуск следующей команды если регистр I/O номер (7...0) равен 0//-1 такт 
//SBIS PINC     //пропуск следующей команды если регистр I/O номер (7...0) равен 1//-1 такт  
//SBIS SPSR, 7           // проверка флаг SPIF -1 такт(SPIF Сбрасывается при чтении SPSR)


//SBRC R22, 0   //пропуск следующей команды если регистр номер(7...0) равен 0//-1 такт 
//SBRS R22, 0   //пропуск следующей команды если регистр номер(7...0) равен 1//-1 такт 
IN R18, SPSR           // проверка флаг SPIF -1 такт(SPIF Сбрасывается при чтении SPSR)
SBRS R18, 7            // проверка флаг SPIF -1 такт(SPIF Сбрасывается при чтении SPSR)



RJMP while_0        // > while_           -1 такт // -1 такт(переход)
IN  R22, SPDR       // Чтение SPI         -1 такт
STS FIFO+0, R22     // Запись SRAM        -2 такт 
SPI_stop:           // SPI_stop
*/
///////////////////////////////////////////////////////////////////////////////// 
//////////////////////////////////////////////////////////////////////////// main


/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// INT = 1:
LDI R22, 0b00000110    // Запись регистра -1 такт // SPI (слейв) SS+ 
OUT PORTB, R22         // OUT Port        -1 такт
/////////////////////////////////////////////////////////////////////////////////




_1:
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Ждём SS = 0...
//SBIC // пропуск следующей команды если регистр I/O номер (7...0) равен 0//-1 такт 
SBIC PINB, 2           // проверка SS = 0 -1 такт
RJMP _1                // > _1            -1 такт // -1 такт(переход)
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Ethernet preamble/SFD (synchronizer): =10101010 
preamble:
IN  R22, PIND          // IN Port         -1 такт
NOP                    //                 -1 такт
//LDI R23, 0b10101010  // Запись регистра -1 такт
//CPSE // пропуск следующей команды если регистры равны   //-1 такт 
CPSE R22, R23          // проверка =10101010  -1 такт 
RJMP preamble          // > preamble      -1 такт // -1 такт(переход)
/////////////////////////////////////////////////////////////////////////////////




//RX_Ethernet: 
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// INT = 0:
LDI R22, 0b00000100    // Запись регистра -1 такт // SPI (слейв) SS+
OUT PORTB, R22         // OUT Port        -1 такт
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////// Port D > Запись SRAM (1 байт):
////////////////////////////// Запись SRAM: 
LDI XL, LOW(FIFO)      // загузить адрес массива FIFO -1 такт
LDI XH, HIGH(FIFO)     // загузить адрес массива FIFO -1 такт  
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Запись SRAM: (0...255)
LDI R16, 0             // Запись регистра -1 такт // сброс  
W_SRAM_0: 
//////////////////////////////
IN  R22, PIND          // IN Port         -1 такт
ST  X+, R22            // запись регистр R22 в массив FIFO (адрес X)  -2 такт
NOP NOP
//////////////////////////////
DEC R16                // Decrement--     -1 такт 
BRNE W_SRAM_0          // > W_SRAM_0      -1 такт // -1 такт(переход)
//////////////////////////////
////////////////////////////// Запись SRAM: (256...511)
LDI R16, 0             // Запись регистра -1 такт // сброс  
W_SRAM_1: 
//////////////////////////////
IN  R22, PIND          // IN Port         -1 такт
ST  X+, R22            // запись регистр R22 в массив FIFO (адрес X)  -2 такт
NOP NOP
//////////////////////////////
DEC R16                // Decrement--     -1 такт 
BRNE W_SRAM_1          // > W_SRAM_1      -1 такт // -1 такт(переход)
//////////////////////////////
////////////////////////////// Запись SRAM: (512...767)
/*
LDI R16, 3             // Запись регистра -1 такт // сброс  
W_SRAM_2: 
//////////////////////////////
IN  R22, PIND          // IN Port         -1 такт
ST  X+, R22            // запись регистр R22 в массив FIFO (адрес X)  -2 такт
NOP NOP
//////////////////////////////
DEC R16                // Decrement--     -1 такт 
BRNE W_SRAM_2          // > W_SRAM_2      -1 такт // -1 такт(переход)
//////////////////////////////
////////////////////////////// Запись SRAM: (768...1023)
LDI R16, 3             // Запись регистра -1 такт // сброс  
W_SRAM_3: 
//////////////////////////////
IN  R22, PIND          // IN Port         -1 такт
ST  X+, R22            // запись регистр R22 в массив FIFO (адрес X)  -2 такт
NOP NOP
//////////////////////////////
DEC R16                // Decrement--     -1 такт 
BRNE W_SRAM_3          // > W_SRAM_3      -1 такт // -1 такт(переход)
*/
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// FIFO полный:
/////////////////////////////////////////////////////////////////////////////////




/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Ждём SS = 1...
_2:
//SBIS // пропуск следующей команды если регистр I/O номер (7...0) равен 1//-1 такт 
SBIS PINB, 2           // проверка SS = 1 -1 такт
RJMP _2                // > _2            -1 такт // -1 такт(переход)
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// INT = 1:
LDI R22, 0b00000110    // Запись регистра -1 такт // SPI (слейв) SS+ 
OUT PORTB, R22         // OUT Port        -1 такт
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Ждём SS = 0...
_3:
//SBIC // пропуск следующей команды если регистр I/O номер (7...0) равен 0//-1 такт 
SBIC PINB, 2           // проверка SS = 0 -1 такт
RJMP _3                // > _3            -1 такт // -1 такт(переход)
/////////////////////////////////////////////////////////////////////////////////




//SPI:
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// вкл выход MISO: 
LDI R22, 0b00010011    // Запись регистра -1 такт // SPI (слейв)  
OUT DDRB, R22          // OUT Port        -1 такт
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////// Чтение SRAM > SPI:
////////////////////////////// Чтение SRAM: 
LDI XL, LOW(FIFO)      // загузить адрес массива FIFO -1 такт
LDI XH, HIGH(FIFO)     // загузить адрес массива FIFO -1 такт
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Чтение SRAM: (0...1023)
//LDI R17, 4           // Запись регистра -1 такт (255+255+255+255) 
LDI R17, 2             // Запись регистра -1 такт (255+255) 
//LDI R17, 1           // Запись регистра -1 такт (255) 
R_SRAM_1:                   
LDI R16, 0             // Запись регистра -1 такт (0...255)
R_SRAM_0:                   
//////////////////////////////
LD  R22, X+            // чтение  массива FIFO (адрес X) в регистр R22 -2 такт
//////////////////////////////
OUT SPDR, R22          // Запись SPI         -1 такт
RX_SPI:                // while(!(SPSR & (1<<7)));
//SBIC // пропуск следующей команды если регистр I/O номер (7...0) равен 0//-1 такт 
SBIC PINB, 2           // проверка SS = 0    -1 такт
RJMP SPI_stop          // > SPI_stop         -1 такт // -1 такт(переход)


//SBIC PINC     //пропуск следующей команды если регистр I/O номер (7...0) равен 0//-1 такт 
//SBIS PINC     //пропуск следующей команды если регистр I/O номер (7...0) равен 1//-1 такт  
//SBIS SPSR, 7           // проверка флаг SPIF -1 такт(SPIF Сбрасывается при чтении SPSR)


//SBRC R22, 0   //пропуск следующей команды если регистр номер(7...0) равен 0//-1 такт 
//SBRS R22, 0   //пропуск следующей команды если регистр номер(7...0) равен 1//-1 такт 
IN R18, SPSR           // проверка флаг SPIF -1 такт(SPIF Сбрасывается при чтении SPSR)
SBRS R18, 7            // проверка флаг SPIF -1 такт(SPIF Сбрасывается при чтении SPSR)


RJMP RX_SPI            // > RX_SPI           -1 такт // -1 такт(переход)
//////////////////////////////
DEC R16                // Decrement--     -1 такт
BRNE R_SRAM_0          // > R_SRAM_0      -1 такт // -1 такт(переход)
DEC R17                // Decrement--     -1 такт
BRNE R_SRAM_1          // > R_SRAM_1      -1 такт // -1 такт(переход)
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Ждём SS = 1...
/*
OUT  SPDR, R20         // Запись SPI         -1 такт // SPI = 0
SPI_0:                 // while(!(SPSR & (1<<7)));
//SBIC // пропуск следующей команды если регистр I/O номер (7...0) равен 0//-1 такт 
SBIC PINB, 2           // проверка SS = 0    -1 такт
RJMP SPI_stop          // > SPI_stop         -1 такт // -1 такт(переход)


SBIC SPSR, 7           // проверка флаг SPIF -1 такт(SPIF Сбрасывается при чтении SPSR)


OUT  SPDR, R20         // Запись SPI         -1 такт // SPI = 0
RJMP SPI_0             // > SPI_0            -1 такт // -1 такт(переход)
*/
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// SPI_stop:
SPI_stop:
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// выкл выход MISO:
LDI R22, 0b00000011    // Запись регистра -1 такт // SPI (слейв) 
OUT DDRB, R22          // OUT Port        -1 такт
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Ждём SS = 1...
/**/
_4:
//SBIS // пропуск следующей команды если регистр I/O номер (7...0) равен 1//-1 такт 
SBIS PINB, 2           // проверка SS = 1 -1 такт
RJMP _4                // > _2            -1 такт // -1 такт(переход)

/////////////////////////////////////////////////////////////////////////////////
RJMP _1                // > _1            -1 такт // -1 такт(переход)


/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
