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

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

Что нужно?
Необходимо, чтобы устройство стало 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.