реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Проблема с запуском Wiznet W5100
Метценгерштейн
сообщение Feb 2 2013, 14:36
Сообщение #16


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



Запустил я свой модуль, пишу в него, читаю регистры, могу 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 );
              
            }              
            
      }  

  }

хочу в терминалку отправить принятые данные.
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Feb 7 2013, 13:19
Сообщение #17


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



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

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

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

Сообщение отредактировал Метценгерштейн - Feb 7 2013, 19:50
Go to the top of the page
 
+Quote Post
vesago
сообщение Feb 8 2013, 07:07
Сообщение #18


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Цитата(Метценгерштейн @ Jan 22 2013, 12:49) *
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 байт. Смутно припоминаю, что были у меня какие-то проблемы, когда пытался из буфер черпануть больше, чем принято.
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Feb 8 2013, 07:43
Сообщение #19


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



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

Можно попросить кодом поделиться? Может какую идею подгляжу.
Go to the top of the page
 
+Quote Post
vesago
сообщение Feb 8 2013, 08:08
Сообщение #20


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



...
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Feb 8 2013, 16:03
Сообщение #21


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



к слову сказать, запустил я родные дрова под него, начал смотреть на то, что с поинтером происходит. Он спокойно перевалил за 2048 и дальше поскакал. надо 65536 подождать и посмотреть на него тогда.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 8 2013, 16:11
Сообщение #22


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Метценгерштейн @ Feb 2 2013, 20:36) *
Запустил я свой модуль, пишу в него, читаю регистры, могу IP прочитать, что записал, тут все норм.

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


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Feb 8 2013, 19:13
Сообщение #23


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



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

SPI пока я не занимался, т.к. увлекся визнетом. Схема пока на 2097 КГц работает.
В той теме отпишусь про SPI. Пока надо попробовать разные тактовые и делители.
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Feb 9 2013, 14:28
Сообщение #24


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



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

он должен крутиться пока не перевалит за 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");
            
          
          
  }
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Feb 11 2013, 08:15
Сообщение #25


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



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

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

написано, что в UDP первые 8 байт- заголовок, кот содержит:
цитата:
Destination IP adress 4 байта.
Что такое Destination? Так вот, именно в корее, это означает, что это адрес исходящего IP- т.е. source.

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

Это не только на этой странице. Описание регистров, где IP принимаются, там тоже все в таком духе.
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Feb 18 2013, 20:09
Сообщение #26


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



новая засада- такой код с 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);
                
    }
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Feb 18 2013, 20:09
Сообщение #27


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



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

Сообщение отредактировал Метценгерштейн - Feb 19 2013, 06:14
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 06:26
Рейтинг@Mail.ru


Страница сгенерированна за 0.01475 секунд с 7
ELECTRONIX ©2004-2016