Сетевые технологии - это интересные технологии)) они меня не утомляют))
Отправить данные на сервер по UDP можно только если сервер поддерживает UDP.
Перевести W5500 на UDP не проблема))
Я открываю два сокета чтобы W5500 мог работать одновременно и по TCP и по UDP.
Вот так.
А дальше пишем...
Объявляем переменные и массивы для UDP.
////////////////////////////
// FIFO_Ethernet UDP // IP | порт | len | Data.
// IP - 0x00 0x00 0x00 0x00
// порт - 0x00 0x00
// len - 0x00 0x00(len=Data).
//////////////////////////// IP - клиент
unsigned char IP_RX[4]={192,168,0,101}; //начальное -192.168.0.101
//////////////////////////// порт - клиент
unsigned char port_RX[2]={0,0};
//////////////////////////// len - клиент
unsigned char len_RX[2]={0,0};
//////////////////////////// TX_int
unsigned char TX_int[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//////////////////////////// RX_int
unsigned char RX_int[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
Общая настройка W5500 для TCP и UDP.
///////////////////////////////////////////////////////////////// инициализация W5500:
/**/
// 00000000 - Address (автоматическая инкрементная адресация +1).
// 00000000 - Address (автоматическая инкрементная адресация +1).
///////////////////////////////////////////////
// Control Registers:
// 0000 0... - BSB [4:0] блок
// .... .0.. - R/W - 0 чтение/1 запись
// .... ..00 - OP Mode (VDM)- данные переменной длины (Длина данных контролируется SS).
/////////////////////////////////////////////// RESET W5500:
PORTB.6=0; //
delay_ms(100); //
PORTB.6=1; //
delay_ms(100); //
/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// W5500 PHY:
// перед настройкой PHY сделать программный Cброс PHY:
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x2E; SPI(); tx=0x04; SPI(); // Address + Control Registers
tx=0x00; SPI(); // Data -0x00
tx=0x00; SPI(); // Data -0x00
PORTB.2=1; // SS W5500
// пишем режим PHY:
// 1... .... RST - 1.
// .1.. .... программная настройка режима - 1
// ..0. .... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode
// ...0 .... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode
// .... 1... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode
// .... .1.. Duplex Status
// .... ..0. Speed Status
// .... ...1 Link Status
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x2E; SPI(); tx=0x04; SPI(); // Address + Control Registers
tx=0xC8; SPI(); // Data -0xC8 (10 Мбит/с, Full-duplex)
tx=0x00; SPI(); // Data -0x00
PORTB.2=1; // SS W5500
/////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// настройка W5500:
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x01; SPI(); tx=0x04; SPI(); // Address + Control Registers
// -шлюз
tx=192; SPI(); // Gateway Address (GAR0) (0x0001 - Address)
tx=168; SPI(); // Gateway Address (GAR1) (0x0002 - Address)
tx=0; SPI(); // Gateway Address (GAR2) (0x0003 - Address)
tx=1; SPI(); // Gateway Address (GAR3) (0x0004 - Address)
// -маска
tx=255; SPI(); // Subnet Mask Address (SUBR0) (0x0005 - Address)
tx=255; SPI(); // Subnet Mask Address (SUBR1) (0x0006 - Address)
tx=255; SPI(); // Subnet Mask Address (SUBR2) (0x0007 - Address)
tx=0; SPI(); // Subnet Mask Address (SUBR3) (0x0008 - Address)
// -MAC (Wiznet_01:02:03)
tx=0x00; SPI(); // Source Hardware Address (SHAR0) (0x0009 - Address)
tx=0x08; SPI(); // Source Hardware Address (SHAR1) (0x000A - Address)
tx=0xDC; SPI(); // Source Hardware Address (SHAR2) (0x000B - Address)
tx=0x01; SPI(); // Source Hardware Address (SHAR3) (0x000C - Address)
tx=0x02; SPI(); // Source Hardware Address (SHAR4) (0x000D - Address)
tx=0x03; SPI(); // Source Hardware Address (SHAR5) (0x000E - Address)
// -IP
tx=192; SPI(); // Source IP Address (SIPR0) (0x000F - Address)
tx=168; SPI(); // Source IP Address (SIPR1) (0x0010 - Address)
tx=0; SPI(); // Source IP Address (SIPR2) (0x0011 - Address)
tx=3; SPI(); // Source IP Address (SIPR3) (0x0012 - Address)
PORTB.2=1; // SS W5500
Для UDP:
/////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////// Socket_1 - UDP:
// Протокол: пишем протокол UDP Socket_1:
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x00; SPI(); tx=0x2C; SPI(); // Address Registers + Control Registers
tx=0x02; SPI(); // Data 0x02 -protocol UDP.
PORTB.2=1; // SS W5500
// Порт: пишем Port Source Socket_1:
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x04; SPI(); tx=0x2C; SPI(); // Address Registers + Control Registers
tx=0x1F; SPI(); // Data -0x1F (порт 8000)
tx=0x40; SPI(); // Data -0x40 (порт 8000)
PORTB.2=1; // SS W5500
// пишем команду OPEN Socket_1:
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x01; SPI(); tx=0x2C; SPI(); // Address Registers + Control Registers
tx=0x01; SPI(); // Data -0x01 (команда OPEN)
PORTB.2=1; // SS W5500
Тут добавим прерывание на вывод INT модуля W5500 по приёму пакета UDP. Для ускорения работы))
В исходном состоянии вывод INT в высоком состоянии (лог 1).
Когда W5500 примет пакет по UDP то вывод INT перейдёт в низкое состояние (лог 0).
/////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////// Socket_1 - INT:
// INT Mask Socket_1: пишем INT Mask Socket_1: (SIMR) 0x0018
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x18; SPI(); tx=0x04; SPI(); // Address + Control Registers
tx=0x02; SPI(); // Data 0x02 -Enable INT Socket_1 .
PORTB.2=1; // SS W5500
// INT Mask Socket_1 RECV: пишем INT Mask завершение приёма Socket_1: (Sn_IMR) 0x002C
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x2C; SPI(); tx=0x2C; SPI(); // Address Registers + Control Registers
tx=0x04; SPI(); // Data 0x04 -INT Mask завершение приёма.
PORTB.2=1; // SS W5500
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
_1: // основной цикл программы
/////////////////////////////////////////////////////////////////////////////////////////////
... // лампочки
... // датчики
... // реле
... // и т.д.
// В основном цикле программы проверяем вывод INT.
// проверка INT:
if (PINB.7 == 1) {goto _1;}; // FIFO_Ethernet пуст > _1
/////////////////////////////////////////////////////////////////////////////////////////////
// вывод INT в низком состоянии (лог 0): пишем сброс флаг завершение приёма INT Socket_1: (Sn_IR) 0x0002
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x02; SPI(); tx=0x2C; SPI(); // Address Registers + Control Registers
tx=0x04; SPI(); // Data 0x04 -сброс флаг завершение приёма.
PORTB.2=1; // SS W5500
// после сброса флага вывод INT переходит в высокое состояние (лог 1).
// читаем размер принятых данных Socket_1 Sn_RX_RSR:
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x26; SPI(); tx=0x28; SPI(); // Address + Control Registers
tx=0x00; SPI(); x1 = rx; // Data -Sn_RX_RSR0 -размер принятых данных //сарший регистр
tx=0x00; SPI(); x2 = rx; // Data -Sn_RX_RSR1 -размер принятых данных //младший регистр
PORTB.2=1; // SS W5500
// На всякий случай проверяем что приёмный буфер не пустой.
len=x1; len=(len<<8)|x2; // размер принятых данных // 0x0000...0xFFFF
if (len == 0x00) {
//////////////////////////////////////////////
goto _1; //FIFO_Ethernet пуст > _1
};
/////////////////////////////////////////////////////////////////////////////////////////////
// Читаем начальный адрес принятых данных Socket_1 Sn_RX_RD
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x28; SPI(); tx=0x28; SPI(); // Address
tx=0x00; SPI(); x1 = rx; // Data -Sn_RX_RD0 -начальный адрес принятых данных //сарший регистр
tx=0x00; SPI(); x2 = rx; // Data -Sn_RX_RD1 -начальный адрес принятых данных //младший регистр
PORTB.2=1; // SS W5500
add=x1; add=(add<<8)|x2; // начальный адрес принятых данных // 0x0000...0xFFFF
////////////////////////////////////////////////////////////////////////////////////////////
// Читаем данные с начального адреса буфера Socket_1 RX Buffer:
x1 = (add>>8);
x2 = add;
PORTB.2=0; // SS W5500
tx=x1; SPI(); tx=x2; SPI(); tx=0x38; SPI(); // Address + Control Registers
////////////////////////////
// FIFO_Ethernet UDP // IP | порт | len | Data.
// IP - 0x00 0x00 0x00 0x00
// порт - 0x00 0x00
// len - 0x00 0x00(len=Data).
//////////////////////////// IP - клиент
//unsigned char IP_RX[4]={192,168,0,101}; //начальное -192.168.0.101
//////////////////////////// порт - клиент
//unsigned char port_RX[2]={0,0};
//////////////////////////// len - клиент
//unsigned char len_RX[2]={0,0};
//////////////////////////// TX_int
//unsigned char TX_int[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//////////////////////////// RX_int
//unsigned char RX_int[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
for (x=0; x<4; x++) {
tx=0; SPI(); IP_RX[x]=rx; // IP_RX - клиент 0x00 0x00 0x00 0x00
};
for (x=0; x<2; x++) {
tx=0x00; SPI(); port_RX[x]=rx; // порт_RX - клиент 0x00 0x00
};
for (x=0; x<2; x++) {
tx=0x00; SPI(); len_RX[x]=rx; // len_RX - клиент 0x00 0x00
};
for (x=0; x<32; x++) {
tx=0x00; SPI(); RX_int[x]=rx; // RX_int - 32
};
PORTB.2=1; // SS W5500
////////////////////////////////////////////////////////////////////////////////////////////
// Пишем регистр указателя Sn_RX_RD до увеличенного значения:
add = add + len; //add - начальный/конечный адрес принятых данных // 0x0000...0xFFFF
//len - размер полученных данных // 0x0000...0xFFFF
x1 = (add>>8);
x2 = add;
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x28; SPI(); tx=0x2C; SPI(); // Address + Control Registers
tx=x1; SPI(); // Data -Sn_RX_RD0 -конечный адрес принятых данных //сарший регистр
tx=x2; SPI(); // Data -Sn_RX_RD1 -конечный адрес принятых данных //младший регистр
PORTB.2=1; // SS W5500
////////////////////////////////////////////////////////////////////////////////////////////
// Пишем команду завершения приема RECV:
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x01; SPI(); tx=0x2C; SPI(); // Address + Control Registers
tx=0x40; SPI(); // Data -0x40 (команда RECV)
PORTB.2=1; // SS W5500
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// приём UDP закончен.
// передача UDP:
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// пишем MAC, IP, порт > Destination
////////////////////////////// Socket_1 + Register Block 1: (0000 1... BSB[4:0]блок)
PORTB.2=0; // SS W5500
// (для команды SEND без автоматического ARP-запроса)
//tx=0x00; SPI(); tx=0x06; SPI(); tx=0x2C; SPI(); // MAC, IP, порт
// (для команды SEND c автоматическим ARP-запросом): -8 ARP
tx=0x00; SPI(); tx=0x0C; SPI(); tx=0x2C; SPI(); //(MAC = ARP), IP, порт
// MAC адрес: > Destination
//tx=0xFF; SPI(); // Data // Destination Hardware Address (Sn_DHAR0)(0x0006 - Address)
//tx=0xFF; SPI(); // Data // Destination Hardware Address (Sn_DHAR1)(0x0007 - Address)
//tx=0xFF; SPI(); // Data // Destination Hardware Address (Sn_DHAR2)(0x0008 - Address)
//tx=0xFF; SPI(); // Data // Destination Hardware Address (Sn_DHAR3)(0x0009 - Address)
//tx=0xFF; SPI(); // Data // Destination Hardware Address (Sn_DHAR4)(0x000A - Address)
//tx=0xFF; SPI(); // Data // Destination Hardware Address (Sn_DHAR5)(0x000B - Address)
//IP адрес : > Destination
tx=192; SPI(); // Data // Destination IP Address (Sn_DIPR0)(0x000C - Address)
tx=168; SPI(); // Data // Destination IP Address (Sn_DIPR1)(0x000D - Address)
tx=0; SPI(); // Data // Destination IP Address (Sn_DIPR2)(0x000E - Address)
tx=1; SPI(); // Data // Destination IP Address (Sn_DIPR3)(0x000F - Address)
// порт: > Destination
tx=0x1F; SPI(); // Data // Destination Port (Sn_DPORT0) (0x0010 - Address) -порт 8000
tx=0x40; SPI(); // Data // Destination Port (Sn_DPORT1) (0x0011 - Address) -порт 8000
PORTB.2=1; // SS W5500
/////////////////////////////////////////////////////////////////////////////////////////////
// Читаем начальный адрес для записи данных Socket 1 Sn_TX_WR:
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x24; SPI(); tx=0x28; SPI(); // Address + Control Registers
tx=0x00; SPI(); x1 = rx; // Data -Sn_TX_WR0 -начальный адрес для записи данных //сарший регистр
tx=0x00; SPI(); x2 = rx; // Data -Sn_TX_WR1 -начальный адрес для записи данных //младший регистр
PORTB.2=1; // SS W5500
add=x1; add = (add<<8)|x2; // начальный адрес для записи данных // 0x0000...0xFFFF
/////////////////////////////////////////////////////////////////////////////////////////////
//Пишем данные с начального адреса буфера Socket 1 TX Buffer:
x1 = (add>>8);
x2 = add;
PORTB.2=0; // SS W5500
tx=x1; SPI(); tx=x2; SPI(); tx=0x34; SPI(); // Address + Control Registers
///////////////////////////////////////////////
len = 0; // сброс len
/////////////////////////////////////////////// TX_int > W5500
for (x=0; x<32 ; x++) {
tx=TX_int[x]; SPI(); len++;
};
PORTB.2=1; // SS W5500
/////////////////////////////////////////////////////////////////////////////////////////////
// Пишем регистр указателя Socket 1 Sn_TX_WR до увеличенного значения:
add = add + len;
x1 = (add>>8);
x2 = add;
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x24; SPI(); tx=0x2C; SPI(); // Address + Control Registers
tx=x1; SPI(); // Data -Sn_TX_WR0 -конечный адрес передачи данных //сарший регистр
tx=x2; SPI(); // Data -Sn_TX_WR1 -конечный адрес передачи данных //младший регистр
PORTB.2=1; // SS W5500
/////////////////////////////////////////////////////////////////////////////////////////////
//Пишем команду передачи SEND Socket 1 Command:
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x01; SPI(); tx=0x2C; SPI(); // Address + Control Registers
tx=0x20; SPI(); // Data -0x20 (команда SEND c автоматическим ARP-запросом)
//tx=0x21; SPI();// Data -0x21 (команда SEND без автоматического ARP-запроса)
PORTB.2=1; // SS W5500
/////////////////////////////////////////////////////////////////////////////////////////////
//If (Sn_CR == 0x00) по окончанию передачи статус меняется на Sn_CR = 0x00
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// передача UDP закончена.
goto _1; // > основной цикл программы
Всё))
Как видим в UDP нет никаких "рукопожатий" и всяких SYN и FIN и прочей фигни))
P.S.
А если вывод INT модуля W5500 подключить к выводу INT мк, то будет работать ещё быстрей))
А если мк перевести в режим SLEEP то модуль W5500 будет будить мк по приёму пакета UDP.
И т.д. и т.п.
А нулевой сокет настроем в режим MACRAW.
Это самый интересный режим))
В режиме MACRAW модуль W5500 работает так же как модуль ENC28J60 для Ардуино. ))
Т.е. все протоколы Ethernet пишем сами))
А дальше пишем...
Объявляем переменные и массивы для MACRAW.
////////////////////////////
// FIFO_Ethernet MACRAW // len | Data
// len - 0x00 0x00(len=len+Data).
//////////////////////////// TX_int
unsigned char TX_int[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//////////////////////////// RX_int
unsigned char RX_int[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
Общая настройка W5500 для TCP и UDP и MACRAW.
///////////////////////////////////////////////////////////////// инициализация W5500:
/**/
// 00000000 - Address (автоматическая инкрементная адресация +1).
// 00000000 - Address (автоматическая инкрементная адресация +1).
///////////////////////////////////////////////
// Control Registers:
// 0000 0... - BSB [4:0] блок
// .... .0.. - R/W - 0 чтение/1 запись
// .... ..00 - OP Mode (VDM)- данные переменной длины (Длина данных контролируется SS).
/////////////////////////////////////////////// RESET W5500:
PORTB.6=0; //
delay_ms(100); //
PORTB.6=1; //
delay_ms(100); //
/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// W5500 PHY:
// перед настройкой PHY сделать программный Cброс PHY:
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x2E; SPI(); tx=0x04; SPI(); // Address + Control Registers
tx=0x00; SPI(); // Data -0x00
tx=0x00; SPI(); // Data -0x00
PORTB.2=1; // SS W5500
// пишем режим PHY:
// 1... .... RST - 1.
// .1.. .... программная настройка режима - 1
// ..0. .... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode
// ...0 .... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode
// .... 1... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode
// .... .1.. Duplex Status
// .... ..0. Speed Status
// .... ...1 Link Status
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x2E; SPI(); tx=0x04; SPI(); // Address + Control Registers
tx=0xC8; SPI(); // Data -0xC8 (10 Мбит/с, Full-duplex)
tx=0x00; SPI(); // Data -0x00
PORTB.2=1; // SS W5500
Для режима MACRAW шлюз, маска, MAC указывать не нужно.
Для режима TCP и UDP шлюз, маска, MAC указывать нужно.
Настройка W5500 для режима TCP и UDP:
/////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// настройка W5500:
PORTB.2=0; // SS W5500
tx=0x00; SPI(); tx=0x01; SPI(); tx=0x04; SPI(); // Address + Control Registers
// -шлюз
tx=192; SPI(); // Gateway Address (GAR0) (0x0001 - Address)
tx=168; SPI(); // Gateway Address (GAR1) (0x0002 - Address)
tx=0; SPI(); // Gateway Address (GAR2) (0x0003 - Address)
tx=1; SPI(); // Gateway Address (GAR3) (0x0004 - Address)
// -маска
tx=255; SPI(); // Subnet Mask Address (SUBR0) (0x0005 - Address)
tx=255; SPI(); // Subnet Mask Address (SUBR1) (0x0006 - Address)
tx=255; SPI(); // Subnet Mask Address (SUBR2) (0x0007 - Address)
tx=0; SPI(); // Subnet Mask Address (SUBR3) (0x0008 - Address)
// -MAC (Wiznet_01:02:03)
tx=0x00; SPI(); // Source Hardware Address (SHAR0) (0x0009 - Address)
tx=0x08; SPI(); // Source Hardware Address (SHAR1) (0x000A - Address)
tx=0xDC; SPI(); // Source Hardware Address (SHAR2) (0x000B - Address)
tx=0x01; SPI(); // Source Hardware Address (SHAR3) (0x000C - Address)
tx=0x02; SPI(); // Source Hardware Address (SHAR4) (0x000D - Address)
tx=0x03; SPI(); // Source Hardware Address (SHAR5) (0x000E - Address)
// -IP
tx=192; SPI(); // Source IP Address (SIPR0) (0x000F - Address)
tx=168; SPI(); // Source IP Address (SIPR1) (0x0010 - Address)
tx=0; SPI(); // Source IP Address (SIPR2) (0x0011 - Address)
tx=3; SPI(); // Source IP Address (SIPR3) (0x0012 - Address)
PORTB.2=1; // SS W5500
Для MACRAW:
/////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////// Socket_0 - MACRAW:
// Протокол: пишем протокол MACRAW Socket_0:
PORTB.6=0; // SS W5500
tx=0x00; SPI(); tx=0x00; SPI(); tx=0x0C; SPI(); // Address
tx=0x04; SPI(); // Data -0x04 // MACRAW // Socket_0
//tx=0xE4; SPI(); // Data -0xE4 // MACRAW // Socket_0
// 0xE4: - Блокирование широковещательной и многоадресной рассылки в режиме MACRAW:
// 1... .... - блокировка широковещательной и многоадресной рассылки в режиме MACRAW
// .1.. .... - блокировка broadcast в режиме MACRAW
// ..1. .... - блокировка multicast в режиме MACRAW
PORTB.6=1; // SS W5500
///////////////////////////////////////////////
// пишем команду OPEN Socket_0:
PORTB.6=0; // SS W5500
tx=0x00; SPI(); tx=0x01; SPI(); tx=0x0C; SPI(); // Address
tx=0x01; SPI(); // Data -0x01 (команда OPEN)
PORTB.6=1; // SS W5500
///////////////////////////////////////////////
_1: // основной цикл программы
/////////////////////////////////////////////////////////////////////////////////////////////
... // лампочки
... // датчики
... // реле
... // и т.д.
// В основном цикле программы проверяем размер принятых данных MACRAW:
/////////////////////////////////////////////////////////////////////////////////////////////
// читаем размер принятых данных Socket_0 MACRAW:
PORTB.6=0; // SS W5500
tx=0x00; SPI(); tx=0x26; SPI(); tx=0x08; SPI(); // Address
tx=0x00; SPI(); x1 = rx; // Data -Sn_RX_RSR0 -размер принятых данных //сарший регистр
tx=0x00; SPI(); x2 = rx; // Data -Sn_RX_RSR1 -размер принятых данных //младший регистр
PORTB.6=1; // SS W5500
len = x1; len = (len<<8)|x2; // len - размер принятых данных
x1 = (len>>8);
x2 = len;
/////////////////////////////////////////////////////////////////////////////////////////////
if (len == 0x00) {
goto _1; // FIFO RX пуст > goto _1;
};
/////////////////////////////////////////////////////////////////////////////////////////////
Приём MACRAW:
/////////////////////////////////////////////////////////////////////////////////////////////
// Читаем начальный адрес принятых данных Socket_0 Sn_RX_RD MACRAW
PORTB.6=0; // SS W5500
tx=0x00; SPI(); tx=0x28; SPI(); tx=0x08; SPI(); // Address
tx=0x00; SPI(); x1 = rx; // Data -Sn_RX_RD0 -начальный адрес принятых данных //сарший регистр
tx=0x00; SPI(); x2 = rx; // Data -Sn_RX_RD1 -начальный адрес принятых данных //младший регистр
PORTB.6=1; // SS W5500
add=x1; add=(add<<8)|x2; // начальный адрес принятых данных // 0x0000...0xFFFF
////////////////////////////////////////////////////////////////////////////////////////////
// Читаем данные с начального адреса буфера Socket_0 RX Buffer MACRAW:
x1 = (add>>8);
x2 = add;
PORTB.6=0; // SS W5500
tx=x1; SPI(); tx=x2; SPI(); tx=0x18; SPI(); // Address = add
/////////////////////////////////////////
// FIFO_Ethernet MACRAW // len | Data
// len - 0x00 0x00(len=len+Data).
/////////////////////////////////////////
for (x=0; x<32; x++) {
tx=0; SPI(); RX_int[x] = rx; // W5500 > Data буфер
};
////////////////////////////////////////
PORTB.6=1; // SS W5500
////////////////////////////////////////////////////////////////////////////////////////////
// Пишем регистр указателя Sn_RX_RD MACRAW до увеличенного значения:
add = add + len; //add - начальный/конечный адрес принятых данных // 0x0000...0xFFFF
//len - размер полученных данных // 0x0000...0xFFFF
x1 = (add>>8);
x2 = add;
PORTB.6=0; // SS W5500
tx=0x00; SPI(); tx=0x28; SPI(); tx=0x0C; SPI(); // Address
tx=x1; SPI(); // Data -Sn_RX_RD0 -конечный адрес принятых данных //сарший регистр
tx=x2; SPI(); // Data -Sn_RX_RD1 -конечный адрес принятых данных //младший регистр
PORTB.6=1; // SS W5500
////////////////////////////////////////////////////////////////////////////////////////////
// Пишем команду завершения приема RECV MACRAW:
PORTB.6=0; // SS W5500
tx=0x00; SPI(); tx=0x01; SPI(); tx=0x0C; SPI(); // Address
tx=0x40; SPI(); // Data -0x40 (команда RECV)
PORTB.6=1; // SS W5500
/////////////////////////////////////////////////////////////////////////////////////////////
// приём MACRAW закончен.
// передача MACRAW:
/////////////////////////////////////////////////////////////////////////////////////////////
// Читаем начальный адрес для записи данных Socket_0 Sn_TX_WR MACRAW:
PORTB.6=0; // SS W5500
tx=0x00; SPI(); tx=0x24; SPI(); tx=0x08; SPI(); // Address
tx=0x00; SPI(); x1 = rx; // Data -Sn_TX_WR0 -начальный адрес для записи данных //сарший регистр
tx=0x00; SPI(); x2 = rx; // Data -Sn_TX_WR1 -начальный адрес для записи данных //младший регистр
PORTB.6=1; // SS W5500
add=x1; add = (add<<8)|x2; // начальный адрес для записи данных // 0x0000...0xFFFF
/////////////////////////////////////////////////////////////////////////////////////////////
//Пишем данные с начального адреса буфера Socket 0 TX Buffer MACRAW:
x1 = (add>>8);
x2 = add;
PORTB.6=0; // SS W5500
tx=x1; SPI(); tx=x2; SPI(); tx=0x14; SPI(); // Address = add
len = 0; // сброс len
/////////////////////////////
for (x=0; x<32 ; x++) {
tx = TX_int[x]; SPI(); // MACRAW_TX > W5500
len++;
};
/////////////////////////////
PORTB.6=1; // SS W5500
/////////////////////////////////////////////////////////////////////////////////////////////
// Пишем регистр указателя Socket 0 Sn_TX_WR до увеличенного значения MACRAW:
add = add + len;
x1 = (add>>8);
x2 = add;
PORTB.6=0; // SS W5500
tx=0x00; SPI(); tx=0x24; SPI(); tx=0x0C; SPI(); // Address
tx=x1; SPI(); // Data -Sn_TX_WR0 -конечный адрес передачи данных //сарший регистр
tx=x2; SPI(); // Data -Sn_TX_WR1 -конечный адрес передачи данных //младший регистр
PORTB.6=1; // SS W5500
/////////////////////////////////////////////////////////////////////////////////////////////
//Пишем команду передачи SEND Socket 0 Command MACRAW:
PORTB.6=0; // SS W5500
tx=0x00; SPI(); tx=0x01; SPI(); tx=0x0C; SPI(); // Address
//tx=0x20; SPI(); // Data -0x20 (команда SEND c автоматическим ARP-запросом)
tx=0x21; SPI(); // Data -0x21 (команда SEND без автоматического ARP-запроса)
PORTB.6=1; // SS W5500
/////////////////////////////////////////////////////////////////////////////////////////////
//If (Sn_CR == 0x00) по окончанию передачи статус меняется на Sn_CR = 0x00
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// передача MACRAW закончена.
Всё))
Как видим режим MACRAW работает ещё проще))
Зачем нужен режим MACRAW ?
Как сказано в даташите "для протоколов которые не поддерживает W5500 на аппаратном уровне".
Например протоколы DHCP, ICMP, и т.д.
Если мы захотим например получить автоматически IP адрес от DHCP сервера, то для этого нам нужен режим MACRAW.
Хотя DHCP работает поверх UDP )) Но не важно))
Если мы захотим например получить IP адрес от DNS сервера, то для этого нам нужен режим MACRAW.
Хотя DNS работает поверх UDP )) Но не важно))
Если мы захотим например пропинговать како-то сервер (командой PING), то для этого нам нужен режим MACRAW.
Вот к примеру W5500 пингует Сервер Яндекса (IP - 87.250.250.242) в режиме MACRAW.
И т.д.
P.S.
Если передающий буфер в режим MACRAW пуст, то W5500 будет передавать пустые пакеты Ethernet ))
Т.е. все протоколы Ethernet надо писать самому.
Писать свои протоколы Ethernet - это очень увлекательное занятие))