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

Проблема инициализации Ethernet-контроллера W5100 по SPI.

Всем доброго времени суток!

Что есть?

Есть Ethernet-контроллер WIZNET W5100, подключенный к микроконтроллеру ATmega64 по интерфейсу SPI (линии MOSI, MISO, CLK, SS). Дополнительно к SPI имеется линия Reset, позволяющая аппаратно перегружать контроллер W5100 и линия INT – для вызова прерываний в программе ATmega64 по событиям в W5100.

ffc98ce5269et.jpg

К выводам "LINKLED" и "FDXLED" подключены светодиоды.

940f372e3cb9t.jpg

Что нужно?

Необходимо, чтобы устройство стало TCP-клиентом, время от времени подключалось к TCP-серверу и обменивалось с сервером некоторым количеством данных (объемом несколько сот байт).

Что такое Ethernet-контроллер W5100?

Ethernet-контроллер W5100 – специальная микросхема, позволяющая соединить относительно медленный микроконтроллер (в данном случае ATmega64) с относительно быстрым интерфейсом Ethernet. В W5100 реализованы на аппаратном уровне протоколы TCP-IP, UDP и ряд других. Задача микроконтроллера ATmega64 состоит в том, чтобы просто передать нужные данные на W5100, а Ethernet-контроллер W5100 уже сам в соответствии с выбранным протоколом передаст данные по нужному адресу в сети Ethernet. Тоже и с получением данных. Ethernet-контроллер W5100 способен одновременно работать с четырьмя независимыми потоками данных, каждый из которых может работать по своему протоколу (4 сокета).

В чем проблема?

Для инициализации Ethernet-контроллера W5100 необходимо установить значения некоторого количества его управляющих регистров. Есть управляющие регистры общего назначения – позволяющие задать режимы работы всего Ethernet-контроллера W5100 в целом, и есть регистры управления каждым сокетом в отдельности – позволяющие задать режимы работы каждого сокета в отдельности.

Проблема состоит в том, что у меня не получается инициализировать значение регистров

"Socket N Destination IP Address Register" (он четырехбайтный, хранит IP-адрес устройства назначения (сервера), например, 192.168.1.2);

и

"Socket N Destination Port Register" (он двухбайтный, хранит номер порта устройства назначения (сервера), например 3000).

При попытке изменить значения этих регистров, значения в них не изменяются, а остаются нулевыми.

Что и как делаю?

Если Ethernet-контроллер W5100 не инициализировать вообще никак, он остается "мертвым", на запросы "ping" не отвечает, светодиоды не светятся. Для инициализации:

Сначала на W5100 выдается аппаратный сигнал Reset (на вывод "/RESET" выдается 0);

Через 100мс аппаратный сигнал Reset снимается (на вывод "/RESET" выдается 1);

Еще через 100мс на W5100 выдается команда "софтового" сброса. Для этого в регистр "Mode Register" (с адресом $0000) заносится значение b10000000 (устанавливается бит RST);

Сразу после этого начинается, собственно, процесс инициализации внутренних регистров. Процесс инициализации выполнен в строгом соответствии с Datasheet-ом на W5100. Итак:

Значение регистра "Mode Register" ($0000) устанавливается в $00. Считываем что записали, проверяем – Ok!

Значение регистра "Interrupt Mask Register" ($0016) устанавливается в $00. Считываем, проверяем, Ok!

Значение регистра "Retry Time-value Register" ($0017) устанавливается в $0F. Считываем, проверяем, Ok!

Значение регистра "Retry Time-value Register" ($0018) устанавливается в $A0. Считываем, проверяем, Ok!

Таким образом, общее значение регистра "Retry Time-value Register" получается 4000 ($0FA0).

Значение регистра "Retry Count Register" ($0019) устанавливается в $08. Считываем, проверяем, Ok!

Далее следует настройка IP-адреса устройства назначения (сервера) (192.168.1.2). Для этого:

Значение регистра "Gateway Address Register" ($0001) устанавливается в 192. Считываем, проверяем, Ok!

Значение регистра "Gateway Address Register" ($0002) устанавливается в 168. Считываем, проверяем, Ok!

Значение регистра "Gateway Address Register" ($0003) устанавливается в 1. Считываем, проверяем, Ok!

Значение регистра "Gateway Address Register" ($0004) устанавливается в 2. Считываем, проверяем, Ok!

Далее следует настройка MAC-адреса нашей системы (аппаратный адрес нашего устройства). MAC-адрес тупо взят из Datasheet-а и равен "00 08 DC 01 02 03". Итак:

Значение регистра "Source Hardware Address Register" ($0009) устанавливается в $00. Считываем, проверяем, Ok!

Значение регистра "Source Hardware Address Register" ($000A) устанавливается в $08. Считываем, проверяем, Ok!

Значение регистра "Source Hardware Address Register" ($000B) устанавливается в $DC. Считываем, проверяем, Ok!

Значение регистра "Source Hardware Address Register" ($000C) устанавливается в $01. Считываем, проверяем, Ok!

Значение регистра "Source Hardware Address Register" ($000D) устанавливается в $02. Считываем, проверяем, Ok!

Значение регистра "Source Hardware Address Register" ($000E) устанавливается в $03. Считываем, проверяем, Ok!

Далее следует настройка маски подсети (255.255.255.0). Для этого:

Значение регистра "Subnet Mask Register" ($0005) устанавливается в 255. Считываем, проверяем, Ok!

Значение регистра "Subnet Mask Register" ($0006) устанавливается в 255. Считываем, проверяем, Ok!

Значение регистра "Subnet Mask Register" ($0007) устанавливается в 255. Считываем, проверяем, Ok!

Значение регистра "Subnet Mask Register" ($0008) устанавливается в 0. Считываем, проверяем, Ok!

Далее следует настройка IP-адреса нашего устройства (192.168.1.30). Для этого:

Значение регистра "Source IP Address Register" ($000F) устанавливается в 192. Считываем, проверяем, Ok!

Значение регистра "Source IP Address Register" ($0010) устанавливается в 168. Считываем, проверяем, Ok!

Значение регистра "Source IP Address Register" ($0011) устанавливается в 1. Считываем, проверяем, Ok!

Значение регистра "Source IP Address Register" ($0012) устанавливается в 30. Считываем, проверяем, Ok!

Теперь необходимо настроить размеры входных и выходных буферов под сокеты (всего 4 сокета в W5100). Мне нужен только один сокет, я выбрал "сокет 0", ему и отдадим всю память:

Значение регистра "RX Memory Size Register" ($001A) устанавливается в b00000011. Считываем, проверяем, Ok!

Значение регистра "TX Memory Size Register" ($001B) устанавливается в b00000011. Считываем, проверяем, Ok!

На этом инициализация регистров общего назначения завершена.

Начиная с этого момента Ethernet-контроллер W5100 "оживает", становится доступен для команды "ping" (с любого компьютера в сети), с помощью команды "apr –a" можно увидеть введенный нами MAC-адрес. Светодиоды контроллера W5100 также начинают светиться при подключении к сети (Ethernet).

Далее следует настройка регистров для сокета 0. Мне нужен протокол TCP, поэтому:

Значение регистра "Socket 0 Mode Register" ($0400) устанавливается в $01. Считываем, проверяем, Ok!

Далее настраиваем № порта нашего устройства, например, 5000 ($1388). Для этого:

Значение регистра "Socket 0 Source Port Register" ($0404) устанавливается в $13. Считываем, проверяем, Ok!

Значение регистра "Socket 0 Source Port Register" ($0405) устанавливается в $88. Считываем, проверяем, Ok!

Теперь даем команду ОТКРЫТЬ сокет 0. Для этого в "Socket 0 Command Register" ($0401) заносим $01.

Для проверки открытия сокета 0 считываем регистр "Socket 0 Status Register" ($0403). Его значение должно быть $13 – "SOCK_INIT". Проверяем – так и есть, Ok!

Вот теперь начинаются косяки!

Согласно Datasheet-у теперь необходимо настроить регистры "Socket 0 Destination IP Address Register". Остается непонятным, зачем еще раз настраивать IP-адрес устройства назначения (сервера), если мы уже его настроили в регистрах общего назначения, а именно в регистре "Gateway Address Register" ($0001, $0002, $0003, $0004), ну да ладно. Итак, пытаемся настроить (192.168.1.2):

Значение регистра "Socket 0 Destination IP Address Register" ($040C) пытаемся установить в 192. Считываем – получаем 0! Данные НЕ совпадают!

Значение регистра "Socket 0 Destination IP Address Register" ($040D) пытаемся установить в 168. Считываем – получаем 0! Данные НЕ совпадают!

Значение регистра "Socket 0 Destination IP Address Register" ($040E) пытаемся установить в 1. Считываем – получаем 0! Данные НЕ совпадают!

Значение регистра "Socket 0 Destination IP Address Register" ($040F) пытаемся установить в 2. Считываем – получаем 0! Данные НЕ совпадают!

Следующая настройка – настройка номера порта устройства назначения (сервера). Пытаемся настроить значение, например, 3000 ($0BB8). Для этого:

Значение регистра "Socket 0 Destination Port Register" ($0410) пытаемся установить в $0B. Считываем – получаем 0! Данные НЕ совпадают!

Значение регистра "Socket 0 Destination Port Register" ($0410) пытаемся установить в $B8. Считываем – получаем 0! Данные НЕ совпадают!

Вот на этом у меня и произошел "затык". Как решить эту проблему, т. е. как установить значения этих регистров, я пока не придумал.

Дальнейшее действие по передаче данных – есть соединение (CONNECT).

Для этого надо выдать команду CONNECT путем записи в "Socket 0 Command Register" ($0401) значения $04.

Для контроля установления соединения с сервером смотрим значение регистра "Socket 0 Status Register" ($0403).

При этом, если сетевой кабель НЕ подключен, возвращаемое значение сначала $01 – в Datasheet-е вообще не прописано, а через время истечения всех TimeOut-ов - $00 – сокет 0 закрыт.

Если сетевой кабель подключен, возвращаемое значение - $15 – SOCK_SYNSENT. Данное значение остается сколь угодно долго, TimeOut-ы не срабатывают.

Дальше пока не продвинулся.

Кроме того, никто не знает ли, где можно взять некое простейшее приложение для компьютера (программу, компьютерный интерфейс), которое бы являлось сервером и позволило бы получить и отправить некоторые данные на удаленное устройство по протоколу TCP? Порт, по которому надо "стучаться" к этому приложению должен быть четко задан и известен, а лучше, чтобы была возможность его задать вручную.

Буду рад любым конструктивным предложениям!

С уважением, Ярослав, www.yarst.org.

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


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

Функция записи удаленного IP адреса и порта

unsigned char config_dst_ip_address[4]= {172,17,229,94};

 

void wr_dst_addr_TCP(unsigned char socket_no,unsigned char *config_dst_ip_address,unsigned char *config_dst_port_address )

{

unsigned int addri;

int i8;

addri = Sn_DIPR0(socket_no);

 

for(i8=0;i8<4;++i8)

 

wiz_wr(addri++,config_dst_ip_address[i8]);

 

addri = Sn_DPORT0(socket_no);

 

for(i8=0;i8<2;++i8)

 

wiz_wr(addri++,config_dst_port_address[i8]);

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


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

Долго мучился с подобной проблемой. Правда работал с микросхемой по UDP. Писал в регистры Destination IP Address и Destination Port, а при считывании оказывались нули. В дэйташите по этому поводу вычитал следующие:

"In UDP mode, this register value decided to user’s written value after receiving peer’s ARP response. Before receiving peer’s ARP response, this register has reset value."

В общем, микросхема не запишет в эти регистры твои значения пока не получит ARP ответ. Правда ни слова не было написано, что нужно сделать для того, чтобы этот ответ получить. Оказалось надо просто записать команду SEND в Sn_CR. После этого Destination IP и Destination Port приняли нужные значения.

Это всё случай UDP. На счет TCP точно сказать не могу - пока не пробовал с ним работать. Но скорее всего принцип такой же - микросхема запишет твои значения после ARP ответа. Попробуй следующий эксперимент:

1)выполни сброс и проинициализируй микросхему.

2)запиши destination адрес и порт.

3)в SN_CR команду connect

4)запиши Sn_Tx_WR какое нибудь число (0х0004h например)

5)в Sn_CR команду SEND

6)после прочти значения регистров destination адреса и порта. должно записаться.

Если получиться справиться с этой проблемой - напиши ;)

P.S.На счет Gataway Address - это адрес шлюза - не тоже самое что Destination IP Address. У меня меня микросхема подключена через роутер, я в качестве Gataway Addreыs пишу адрес роутера, а качестве Destination IP адрес компа.

P.P.S.Простейшее приложение отправляющие данные с компа по TCP и UDP писал сам..

 

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


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

Не хотите использовать готовые исходники? Они у них на сайте выложены для тестовых плат на AVR. Я их переносил на BlackFin, работает.

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


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

Исходники на их сайте нашел http://www.efo.ru/doc/Wiznet/Wiznet.pl?2595. Там даже драйвер есть.

Вот только описания функций ни бэ ни мэ. Толи я слепой, толи сайт не тот. ткните носом пожалуйста.

Использую W5100.

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


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

Теперь необходимо настроить размеры входных и выходных буферов под сокеты (всего 4 сокета в W5100). Мне нужен только один сокет, я выбрал "сокет 0", ему и отдадим всю память:

 

насколько я понял даташит, у этой железки бывает только две конфигурации памяти для сокетов:

 2к memory per socket

или

4K,2K,1K,1K соответственно сок0,сок1,сок2,сок3

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


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

Вот цитата из даташита:

//-------------------------------------------------

RMSR(RX Memory Size Register) [R/W] [0x001A] [0x55]

This register assigns total 8K RX Memory to each socket.

 

7 6 5 4 3 2 1 0

Socket 3 Socket 2 Socket 1 Socket 0

S1 S0 S1 S0 S1 S0 S1 S0

 

The memory size according to the configuration of S1, S0, is as below.

S1 S0 Memory size

0 0 1KB

0 1 2KB

1 0 4KB

1 1 8KB

According to the value of S1 and S0, the memory is assigned to the sockets from socket 0

within the range of 8KB. If there is not enough memory to be assigned, the socket should not

be used. The initial value is 0x55 and the 2K memory is assigned to each 4 sockets

respectively.

 

Ex) When setting as 0xAA, the 4KB memory should be assigned to each socket.

However, the total memory size is 8KB. The memory is normally assigned to the socket 0 and

1, but not to the socket 2 and 3. Therefore, socket 2 and 3 can not be absolutely used.

Socket 3 Socket 2 Socket 1 Socket 0

0KB 0KB 4KB 4KB

 

//---------------конец цитаты-------------------------

 

Здесь есть возможность давать одному соккету все 8 Кб памяти. Запрета на это действие здесь нет. В примере лишь показывается, как можно поделить память на два соккета.

 

Но у меня другой вопрос: Делаю модулю сброс, сначала аппаратный, потом программный. Но инициализироваться он отказывается, т.е. в регистры свои ничего писать не хочет. Пишу, после этого читаю регистр - там 0x0. В чём может быть проблема?

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


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

А выход SPI_EN к VCC через резистор подключили? Что у вас с выходом SCS? И вообще какой у вас интерфейс связи с W5100?

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


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

Данная проблема решена. Интерфейс был тоже SPI. Там действительно не хватало разрешения SPI_EN. Появился новый вопрос: из даташита не совсем понятно, как (там какая-то хитроумная методика) рассчитываются значения регистров Sn_TX_RR (Socket n TX Read Pointer Register), Sn_TX_WR (Socket n TX Write Pointer Register) и Sn_RX_RD (Socket n RX Read Pointer Register). Если кто работал и/или знает - напишите пожалуйста. Из их рисунков и объяснений я понял только то, что физ. адрес отправляемой информации и адрес в регистре разные. Конкретнее - большой вопрос...

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


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

как (там какая-то хитроумная методика) рассчитываются значения регистров Sn_TX_RR (Socket n TX Read Pointer Register), Sn_TX_WR (Socket n TX Write Pointer Register) и Sn_RX_RD (Socket n RX Read Pointer Register).
Там для собственно адресации внутри буфера используются только младшие биты регистра. Старшие - для каких-то внутренних нужд (типа для формирования уникального/случайного номера пакета или подобного). Поэтому вам нужно при чтении накладывать маску, выделяя нужные биты и добавлять к полученному смещению в буфере начальный адрес буфера в адресном пространстве микросхемы. При записи аналогично - получать смещение в буфере и добавлять к нему считанные старшие биты.

 

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


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

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

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

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

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

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

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

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

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

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