Stolbov 0 14 мая, 2018 Опубликовано 14 мая, 2018 · Жалоба Всем добрый день! Я продолжаю изучать программирование микроконтроллеров, и в качестве следующей цели выбрал организацию простого web-сервера на AVR. Я изучил основные моменты инициализации в официальной документации, плюс нашёл в интернете несколько примеров (правда, все они под STM32), но у меня всё равно не получается его инициализировать даже на обычный пинг. Вот как выглядит сам девайс: Общаюсь я с ним по SPI. В документации сказано, что сначала передаётся старший байт адреса назначения, потом младший, затем контрольная фаза и, на конец, сами данные. Сейчас я приведу небольшой пример, как я всё это реализовываю: uint8_t opcode = 0; //Переменная для хранения опкода uint8_t ip[4] = {192,168,1,197}; //ip адрес //Данные, необходимые для формирования контрольной фазы #define BSB_COMMON 0x0000 //bsb блок #define WRITE 1 //бит записи #define READ 0 //бит чтения #define OM_FDM0 0x00 //Режим передачи данных переменной длинны #define SIPR0 0x000F //Адреса регистров w5500, в которых хранится ip адрес #define SIPR1 0x0010 #define SIPR2 0x0011 #define SIPR3 0x0012 //Провожу инициализацию SPI void spi_init() { DDRB = (1<<PORTB7)|(1<<PORTB5)|(1<<PORTB4); //Clock - 7, MOSI - 5, Chip Select - 4. Всё на выход. MISO (6) - на вход. SPCR = (1<<MSTR)|(1<<SPE)|(1<<SPR0); //Мастер, SPI включен. } //Функция записи данных в чип void w5500_write(uint16_t addr, uint8_t opcode, uint8_t data) //Функция записи данных в регистр { selectW5500(); //Выбрать чип unsigned char i; //счётчик uint8_t buf[4]; //буфер для данных buf[0] = (uint8_t)(addr >> 8); //передаём старшую часть адреса buf[1] = (uint8_t)(addr); //передаём младшуя часть адреса buf[2] = opcode; //передаём контрольную фазу buf[3] = (uint8_t)(data); //передаём данные for(i=0;i<4;i++) //цикл передачи данных { SPDR = buf[i]; while(!(SPSR&(1<<SPIF))); } deselectW5500(); } Не знаю, почему, но мне кажется, что я что-то делаю не так с передачей данных. Я привёл пример записи одного байта данных в регистр, отвечающий за хранение ip адреса. Формирование контрольной фазы выглядит так: opcode = (BSB_COMMON<<3)|(WRITE<<2)|OM_FDM0; Функции выбора чипа в этом посте я писать не стал, так как там происходит просто "притягивание" линии к 0, а потом "отпускание". Я постарался как можно короче изложить свою проблему, но, тем не менее, указав важные детали. Буду рад любой помощи или совету. Заранее спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 14 мая, 2018 Опубликовано 14 мая, 2018 · Жалоба opcode должен быть первым в последовательности, затем адрес , потом данные. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stolbov 0 14 мая, 2018 Опубликовано 14 мая, 2018 · Жалоба opcode должен быть первым в последовательности, затем адрес , потом данные. Большое спасибо за ответ! Завтра я обязательно попробую так сделать. Скажите, пожалуйста, а откуда у Вас такая информация? Просто в даташите SPI Frame начинается с адреса, и я руководствовался именно этой схемой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 15 мая, 2018 Опубликовано 15 мая, 2018 · Жалоба Скажите, пожалуйста, а откуда у Вас такая информация? Извините, похоже я ввел Вас в заблуждение. Написал по инерции для наиболее распространенного варианта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stolbov 0 18 мая, 2018 Опубликовано 18 мая, 2018 · Жалоба Если кому-нибудь интересно: все данные в чип пишутся, и читаются (настройки mac, ip и прочее). Даже считал версию чипа (0x04), но он упорно не хочет пинговаться, и выдаёт свои стандартные настройки. Буду разбираться дальше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 18 мая, 2018 Опубликовано 18 мая, 2018 · Жалоба все данные в чип пишутся, и читаются (настройки mac, ip и прочее). Даже считал версию чипа (0x04), но он упорно не хочет пинговатьсяЯ работал с 5100, по параллельной шине и очень давно. В порядке предположения: а порядок байт при записи "ip и прочего" не попутан случайно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stolbov 0 18 мая, 2018 Опубликовано 18 мая, 2018 · Жалоба Вот так выглядит "кадр" передачи данных SPI: Функцию записи я немного переписал: void w5500_write(uint16_t addr, uint8_t op, uint8_t data) //Функция записи данных в регистр { char MSB = (addr>>8); char LSB = (addr); char opcode = op; char sdata = data; SPDR = MSB; while(!(SPSR&(1<<SPIF))); SPDR = LSB; while(!(SPSR&(1<<SPIF))); SPDR = opcode; while(!(SPSR&(1<<SPIF))); SPDR = sdata; while(!(SPSR&(1<<SPIF))); } Так как сперва надо передать старший байт адреса, я его двигаю, и потом в след за ним передаю младшую часть, потом сформированный "опкод", а затем непосредственно сами данные. В чём может быть причина неудачи, я не знаю. Само собой, перед записью данных я делаю два сброса, как это сказано в даташите: хард и софт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 18 мая, 2018 Опубликовано 18 мая, 2018 · Жалоба Так как сперва надо передать старший байт адреса, я его двигаю, и потом в след за ним передаю младшую часть, потом сформированный "опкод", а затем непосредственно сами данные.Так вот в этих "самих данных" не может быть попутаны байты? Вы уверены, что в регистры попадает "192.168.0.1", а не "1.0.168.192"? У W5100 и предыдущих данные хранились в виде больших индейцев (big endian), все известные мне компиляторы для AVR используют маленьких индейцев. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stolbov 0 18 мая, 2018 Опубликовано 18 мая, 2018 · Жалоба Думаю, что всё записывается правильно. Каждый байт записывается по своему собственному адресу. 192 пишется в 0x0001, 168 в 0x0002 и т.д. Я попробовал прочитать все адреса и получил правильный порядок байтов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 18 мая, 2018 Опубликовано 18 мая, 2018 · Жалоба 192 пишется в 0x0001, 168 в 0x0002 и т.д.Да, я именно это и имел ввиду. Раз здесь все правильно - остается только схема. Потому что если у вас в MR биты RST и PB сброшены, то после записи GAR, SUBR, SHAR и SIPR оно должно начать пинговаться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stolbov 0 21 мая, 2018 Опубликовано 21 мая, 2018 · Жалоба Ещё одно дополнение. Чип работает, отвечает на пинг. Нужно было соблюсти несколько условий: 1) Чип и ПК соединяются через кросс-кабель. 2) Чип и ПК должны находится в одной подсети. 3) Обязательно нужно открыть порт. Всем спасибо за участие! :yeah: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
To4noNeRobot 0 23 марта, 2019 Опубликовано 23 марта, 2019 · Жалоба Здравствуйте, я тоже пытаюсь освоить W5500, у меня чип отвечает на пинг но ни как не хочет подключаться к серверу в режиме TCP клиента. Т.е. я делаю следующее: провожу инициализацию, , проверяют что регистр Sn_SR == SOCK_INIT. записываю IP адрес и порт сервера в соответствующие регистры потом отправляю команду в регистр Sn_CR - CONNECT, и как я понял работу чипа - в этот момент он должен отправить что-то типа запроса на соединение (SYN packet) и получив ответ от сервера регистр Sn_SR должен измениться с SOCK_INIT(0x13) на SOCK_ESTABLISHED(0x17), но вместо этого где-то через 1,5 секунды регистр Sn_SR устанавливается в SOCK_CLOSE(0x00). В качестве сервера я использую скрипт на питоне на ПК, с этого компьютера чип отлично пингуется и не понятно в чём может быть причина. Мне кажется что у меня какая то не правильная последовательность действий при установки соединения, но всё что сказано в гайде на сайте производителя этих чипов по поводу работы в режиме TCP-клиента - это: Transmit the connect-request (SYN packet) to “TCP SERVER”. It may occurs the timeout such as ARPTO, TCPTO when make the “connection SOCKET” with “TCP SERVER” { Sn_DIPR0 = server_ip; /* set TCP SERVER IP address*/ Sn_DPORT0 = server_port; /* set TCP SERVER listen port number*/ Sn_CR = CONNECT; /* set CONNECT command */ } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться