Перейти к содержанию
    

Проблема с запуском Wiznet W5100

Запустил я свой модуль, пишу в него, читаю регистры, могу IP прочитать, что записал, тут все норм.

 

но в упор не получается принятый байт из него считать.

подскажите, что не так делаю?

 

void WIZnet_main (void)
{
    WIZ_Init();
    uint8_t recv_msg[8];
      
      //  режим сервера
      socket (1, Sn_MR_TCP, 3001, 0); //for socket: number, protokol, source port, option ???   
      listen (1); //socket number    
      
      while (1)
      {
            if (IINCHIP_READ (Sn_SR(1))== SOCK_ESTABLISHED) {  //Sn_SR статус регистр           
              
              recv (1, &recv_msg[0], 8);  //socket, передаю адрес массива- куда читать, и длина данных
              
              Usart1_Send_String( (char *)recv_msg );
              
              disconnect (1);
              close (1);
              
              //Usart1_Send_String( (char *)recv_msg );
              
            }               
            
      }  

  }

хочу в терминалку отправить принятые данные.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

пишу новую процедуру.

в общем, не могу победить переполнение буфера.

 

как только указатель переваливает за 2048, и если я от текущего значения отниму 2048, и, например, получу, 9

то размер принятых данных сразу становится = много.

 

Кто как решил этот вопрос?

Изменено пользователем Метценгерштейн

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

vesago, а почему у Вас два сигнала W_SCS и W_SEN подвешены к +U пит. ?

 

там же надо (в WIZ811MJ так) /SCS выбирать, а SEN через инвертор подается на др. вход. А у Вас оба в + 3,3.

 

И если выбор SPI, то /SCS активен в лог. нуле, зачем его подвешивать на + 3,3 ?

Я запостил кусок схемы с обвязкой w5100. У меня выбор spi идет через 74lvc125. На другом листе схемы.

 

По буферу - я особо не вдавался. Прикрутил визнетовский код. Он вполне рабочий. Два сокета. По одному конфигурирую дивайс. По второму гоняю данные изернет-485. По 4к на сокет. При приеме данных я сначала считываю объем wiznet.rsize = getSn_RX_RSR(0); Потом, если не равен 0 вычерпываю из буфера recv(0, wiznet.buf, wiznet.rsize); в количестве wiznet.rsize. Вы выше постили recv (1, &recv_msg[0], 8); Однако в текущий момент может и не быть 8 байт. Смутно припоминаю, что были у меня какие-то проблемы, когда пытался из буфер черпануть больше, чем принято.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я уже не пользую штатную ф-ю, т.к. она не заработала. Пишу свою. Там что-то поднакручено у них.

 

Можно попросить кодом поделиться? Может какую идею подгляжу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

к слову сказать, запустил я родные дрова под него, начал смотреть на то, что с поинтером происходит. Он спокойно перевалил за 2048 и дальше поскакал. надо 65536 подождать и посмотреть на него тогда.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Запустил я свой модуль, пишу в него, читаю регистры, могу IP прочитать, что записал, тут все норм.

Вы бы рассказали, в чём была проблема с SPI, вдруг кому-то ещё пригодится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

обязательно расскажу. Только пока что победил визнет. Сегодня- завтра проверю этот указатель (странно, что переполняется и хоть бы хрен), обкатаю еще две идеи, выложу все здесь. Пока что работают и мои драйвера, и родные.

 

SPI пока я не занимался, т.к. увлекся визнетом. Схема пока на 2097 КГц работает.

В той теме отпишусь про SPI. Пока надо попробовать разные тактовые и делители.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

разобрался я с указателем этим. Резюмирую:

 

он должен крутиться пока не перевалит за 16 бит. Обнулять его и приводить к размеру сокета нельзя, т.к. сразу размер принятых данных (регистр Sn_RX_RSR0) будет равен 2048.

исходя из данного указателя мы сами должны высчитать физический адрес начала данных. При этом, если указатель будет равен 4097, то, при сокете 2К, адрес должен начинаться с начала, т.е. 0x6001 - это для нулевого сокета.

 

делается это так:

uint16_t RX_beginDataAddr =(RX_pointer&(S0_RX_MASK+(SNum*0x0800)))+(S0_RX_BASE+(SNum*0x0800)); // вычислим физ. адрес начала данных

 

ну и собственно код работы с визнетом. Мой драйвер + закомментированы штатные дрова- можете их использовать- просто пример как с ними работать.

void WIZnet_main (void)
{
    WIZ_Init();
    uint8_t recv_IP[32];
    for (uint8_t i = 0; i < sizeof (recv_IP); i++)
    {
      recv_IP[i] = 0;
    }
    uint16_t RX_pointer =0;
    
#define SNum    0
    
#define S0_RX_BASE     0x6000     //начало памяти Rx
#define S0_RX_MASK     0x07FF     //2K-1
   
           // режим сервера
            socket (SNum, Sn_MR_TCP, 3001, 0); //for socket: number, protokol, source port, option ???      
    
            while ( !listen (SNum) ) { }       
            
            while (IINCHIP_READ (Sn_SR(SNum)) != SOCK_ESTABLISHED) { }    
            while (IINCHIP_READ (Sn_SR(SNum)) == SOCK_ESTABLISHED) {      
              
              
            uint16_t RX_dataSize; // размер принятых данных
            while (!(RX_dataSize = IINCHIP_READ16 (Sn_RX_RSR0(SNum))));

            RX_pointer = IINCHIP_READ16 (Sn_RX_RD0(SNum)); // считали указатель RX        
            
            uint16_t RX_beginDataAddr =(RX_pointer&(S0_RX_MASK+(SNum*0x0800)))+(S0_RX_BASE+(SNum*0x0800)); // вычислим физ. адрес начала данных
            
            //тут обыграем переполнение буфера RX memory
            uint16 src_mask = RX_pointer & getIINCHIP_RxMASK(SNum);          
           if( (src_mask + RX_dataSize) > getIINCHIP_RxMAX(SNum) )          
            {        
              uint16_t upper_size = (S0_RX_MASK + 1 - RX_pointer); //размер первых байт, кот влезли в конец буфера
            
              for (uint16_t i=0; i<upper_size; i++) {
                recv_IP[i] = IINCHIP_READ (RX_beginDataAddr + i); // пишем их в массив
                } 
                
              for (uint16_t i=upper_size; i<RX_dataSize; i++) {
                recv_IP[i] = IINCHIP_READ ((S0_RX_BASE+(SNum*0x0800)) + (i - upper_size)); // пишем оставшиеся байты с начала буфера
                }
              
            } 
          
          else 
            {                                           // если данные не вылезли за размер буфера 
              for (uint16_t i=0; i<RX_dataSize; i++) {
                recv_IP[i] = IINCHIP_READ (RX_beginDataAddr + i); // положили данные в массив
                }              
              
            }             
            
            RX_pointer += RX_dataSize;   // изменим указатель на длину принятых данных
          
            IINCHIP_WRITE16 ((Sn_RX_RD0(SNum)), RX_pointer);         
            IINCHIP_WRITE (Sn_CR(SNum), Sn_CR_RECV); // команда на изменение регистра
            while( IINCHIP_READ(Sn_CR(SNum)));
           
            RX_pointer = IINCHIP_READ16 (Sn_RX_RD0(SNum)); // считали указатель RX
            printf("RX_pointer -> %4d      recv_IP -> %s\r\n", RX_pointer, recv_IP);     
              
            
            
            
            
            
//
//              uint16_t RX_dataSize; // размер принятых данных
//              while (!(RX_dataSize = IINCHIP_READ16 (Sn_RX_RSR0(SNum))));
//                       
//              recv (SNum, recv_IP, RX_dataSize);
//              printf("recv_IP -> %s   \r\n  \r\n", recv_IP);    
              
            }//while
     
              
              
              
            disconnect (SNum);
            close (SNum);
            
            printf("connection closed");
            
           
           
  }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и еще, касательно документации на wiznet. Особенно для тех, кто говорит, что там все настолько шикарно расписано)

 

стр. 52 даташита 1.2.1

 

написано, что в UDP первые 8 байт- заголовок, кот содержит:

цитата:

Destination IP adress 4 байта.

Что такое Destination? Так вот, именно в корее, это означает, что это адрес исходящего IP- т.е. source.

 

Лично принял пакет и посмотрел, что в нем содержится.

 

Это не только на этой странице. Описание регистров, где IP принимаются, там тоже все в таком духе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

новая засада- такой код с UDP работает нормально

for (;;) {
            uint16_t RX_dataSize; // размер принятых данных
            while (!(RX_dataSize = IINCHIP_READ16 (Sn_RX_RSR0(0))));
                       
            recv (0, recv_IP, RX_dataSize);
           
            for (int i = 8; i < RX_dataSize; i++) {
            Usart1_Send_symbol ( IINCHIP_READ(0x6000 + i)); 
                
    }

 

а такой код

for (;;) {
    
            uint16_t RX_dataSize; // размер принятых данных
            while (!(RX_dataSize = IINCHIP_READ16 (Sn_RX_RSR0(0))));
                       
            recv (0, recv_IP, RX_dataSize);

    sendto(0, recv_IP, RX_dataSize, WIZ_DESTIP, 3000); 
                
    }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вроде нашел решение

Изменено пользователем Метценгерштейн

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...