Ethernet-контроллер W5300. IPRAW режим

IPRAW — это передача данных с использованием уровня ниже, чем TCP и UDP. IPRAW поддерживает протоколы, такие как ICMP (0x01), IGMP (0x02), которые могут быть определены номером протокола (Sn_PROTOR). Как и в прошлый раз предупреждаю, здесь мы рассматриваем на примере произвольного пакета. Вы разумеется выбираете свой протокол.

Что нужно:

— WIZ830MJ;
— STM32F4-Discovery;
— Keil;
— Wireshark(+ WinPcap);
— Colasoft Packet Builder.

Таблица подключения WIZ830MJ к STM32F4-Discovery и часть адресов регистров были даны в статье Часть 3. Ethernet-контроллер W5300. Инициализация. Пинг
Дополнительные адреса регистров указаны в Часть 4. Ethernet-контроллер W5300. MACRAW режим

Инициализация STM32F4 и W5300

Процедуры инициализации STM32F4 (GPIO и TIM6) и инициализации W5300 (SHAR, GAR, SUBR, SIPR) были показаны в статье Часть 3. Ethernet-контроллер W5300. Инициализация. Пинг

Инициализация сокета

Начинаем, как обычно с открытия сокета. Я выбрал сокет 0, вы можете выбрать любой из 8 сокетов, который вам улыбнется.
Перед инициализацией сокета необходимо указать MAC-адрес и IP-адрес пункта назначения:

// MAC-адрес пункта назначения
WriteReg (S0_DHAR, 0xD027);                     
WriteReg (S0_DHAR2, 0x8885);
WriteReg (S0_DHAR4, 0x4D1D);
// IP-адрес пункта назначения
WriteReg (S0_DIPR, 0xC0A8);             
WriteReg (S0_DIPR2, 0x460B);

Далее прописываем регистр S0_PROTOR в соответсвии с тем, какой протокол выбрали (ICMP – 0x01, IGMP – 0x02, TCP – 0x06, UDP – 0x11). И еще, номер протокола должен быть установлен до открытия сокета.

do // /////////////  Инициализация IPRAW сокета  ////////////////////////////////////
{
        WriteReg (S0_PROTOR, 0x0008)    ;       // номер протокола
        WriteReg (S0_MR, 0x0003);               // сокет в режиме IPRAW
        WriteReg (S0_CR, OPEN);                 // открыть сокет
        Dat=ReadReg (S0_SSR);
}
while ((Dat & 0x00FF)!=SOCK_IPRAW);             // сокет 0 открыт в IPRAW режиме?

Передача

Сначала, прочитав регистр S0_TX_FSR2, проверяем наличие свободной памяти в памяти передатчика W5300. Открываем цикл записи данных. В регистры S0_TX_WRSR и S0_TX_WRSR2 записываем размер отправляемых данных. Внимание!!! Его необходимо указать в байтах. В регистр команд записываем команду SEND.

while (1)
{
                ///////////////////// ПЕРЕДАЧА /////////////////////////
        do Dat=ReadReg(S0_TX_FSR2);     // проврека наличия свободной памяти
        while (Dat<SizeB);

        do                              //запись отправляемых данных
        {
                WriteReg (S0_TX_FIFOR, SendData);
                SendData++;
        }
        while (SendData < SizeW);
        WriteReg (S0_TX_WRSR, 0x0000);  // размер отправляемых данных
        WriteReg (S0_TX_WRSR2, SizeB);          // размер отправляемых данных
        WriteReg (S0_CR, SEND);                 // отправили
        delay_us(1000);                         // просто задержка между пакетами
        SendData = 0;
}

Пакеты ловим на компе сниффером.

Прием

Принятый IP пакет согласно даташиту имеет вот такую структуру: 4 байта IP-адрес пунткта назначения и 2 байта- размер данных.

Для того чтобы принять пакет IPRAW мы следим за регистром S0_RX_RSR2, который сигнализирует нам о том, что данные приняты. Считываем 4 байта IP-адреса и размер данных в байтах, считаем сколько это будет в словах. Данные считываем в массив и отправляем команду RECV в регистр команд S0_CR.

while (1)
{
///////////////////// ПРИЕМ ////////////////////////////
        if (ReadReg (S0_RX_RSR2)!=0x0000 ) //размер принятых данных отличен от нуля
        {
                Dat = ReadReg (S0_RX_FIFOR);            // считываем   IP адрес
                Dat = ReadReg (S0_RX_FIFOR);
                        
                pack_size = ReadReg (S0_RX_FIFOR); // размер данных считали 

                // определяем сколько раз считывать данные
                if ( (pack_size%2) == 0)        {read_cnt = pack_size/2;}       
else {read_cnt = (pack_size+1)/2;}
                        
                for (Cnt=0; Cnt<read_cnt; Cnt++)        //SizeW чтение принятых                 
                        {
                                Rcv_data[Cnt]=ReadReg (S0_RX_FIFOR);
                        }
                i++;                                    // счетчик пакетов
                WriteReg (S0_CR, RECV);         // приняли
        }       
}

Отправляем пакет вот такого вида с помощью Packet Builder. Для этого нажимаем на кнопочку Send.

В появившемся окошке выбираем LoopSending, количество – 20 раз.

В режиме отладки смотрим данные в Rcv_data. Сниффер показывает те же данные.

Список литературы:
1. High-Performance Internet Connectivity Solution W5300. Version 1.2.5. 2008
2. WIZ830MJ Datasheet (Ver. 1.3). 2008
3. Reference manual. STM32F405xx, STM32F407xx, STM32F415xx and STM32F417xx advanced ARM-based 32-bit MCUs. 2011
4. User Manual. STM32F4DISCOVERY. STM32F4 high-performance discovery board. 2012

Прикрепленные файлы:
Архив с папкой проекта и пакетом для генератора пакетов
Исходник — main.c