STM8 встречает Интернет.

Отладочный макет STM8S103F3
В целом ничего нового тут не ожидается. Уже всем знакомое семейство STM8 в качестве мозга. ENC28J60 в качестве Ethernet контроллера и PHY. И немного модифицированный код от Lifelover’а в качестве примера.

Тов. Lifelover’у ещё раз огромное спасибо за его труды.

Вода-вода

Решил таки в коем то веке помучить Ethernet на контроллерах. Но LPC1768 я не увлекаюсь, а в LPC1343 Ethernet’а и нету. И так выбор пал на купленную с год назад плату с ENC28J60. В качестве ядра же было решено задействовать дешёвый (35р. на момент покупки) контроллер STM8S103F3 (есть и портированная на STM8S-Discovery версия). Ну а в качестве среды разработки у нас выступает бесплатная версия IAR, имеющая ограничение в 8кБайт кода (это важно, запомните это).

Задачей было собрать некое подобие tinyhttp, но так как последний был написан на ассемблере, в основу лег пример webif2. Главным условием было использование языка Си, для возможности легкой переделки проекта. Главной целью – освоить SPI микроконтроллеров STM8.

Надо заметить что SPI не вызвал совершенно никаких сложностей, в отличие от запуска ENC’и. Ну кто же ожидал что Си код окажется не универсальным, отвык я уже от граблей, привык к рабочим библиотекам. Странно только откуда, на работе и то кривые библиотеки. Но всё же надо отдать должное Lifelover’у, код перенёсся в касание, проблема была только в незнании архитектуры.

Код

Я человек ленивый, по этому за основу взят пример webif2.zip, хранящийся еще со времён прошлого конкурса (а второй тур то и заглох, не?). Поскольку код написан для AVR, хоть и на Си, потребовалась небольшая работа напильником.

В первую очередь, и самое очевидное, это единое линейное адресное пространство STM8. Нам совершенно нет никакой разницы, находятся ли данные во флэш-памяти или же в оперативной памяти. Так что ни какие prog_char нам не нужны.

Настройка SPI не вызывает никаких проблем: выставляем нужные биты и..., всё описано в datasheet’е. Функция обмена ничем практически не отличается от AVR версии, разве что именами регистров и битов:

uint8_t enc28j60_rxtx(uint8_t data)
{
  SPI_DR = data;
  while(!(SPI_SR & MASK_SPI_SR_RXNE));
  return SPI_DR;
}

Вот за что я люблю аппаратные интерфейсы. Настроил, запустил – и они работают (конечно не всегда бывает такое счастье). Да к тому же более качественно нежели ножкодрыгство.

Ну и в завершении убираем PWM со светодиода. Это тема для отдельного рассмотрения, не зачем лепить всё и сразу.

Собираем, запускаем и... облом. Кто заметил, что не правильно?

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

Святая вещь отладчик, без него бы просто плюнул и забил бы. А так, лезем в отладку и видим что при извлечении пакета получается какой-то мусор.

enc28j60_read_buffer((void*)&enc28j60_rxrdpt, sizeof(enc28j60_rxrdpt));
enc28j60_read_buffer((void*)&rxlen, sizeof(rxlen));
enc28j60_read_buffer((void*)&status, sizeof(status)); 

А мусор ли? Одинокая мысль в тёмном углу пустой черепной коробки не решительно выползла на свет.

Интересно, вот почему в описании архитектуры STM нет ни слова о порядке байт? Почему ответ на данный вопрос находится только в районе 28 страницы PM0044? Вот этот упущенный момент. В архитектуре STM8 для много байтовых величин старший байт находится по младшему адресу, Это так называемый сетевой порядок байт. В то время как у ENC28J60 (и у AVR, и у x86) старший байт расположен по старшему адресу.

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

 uint16_t enc28j60_read_buffer_u16()
{
   	uint16_t val;
	enc28j60_select();
	enc28j60_tx(ENC28J60_SPI_RBM);
	val =	enc28j60_rx() |
		(uint16_t)enc28j60_rx() << 8;
	enc28j60_release();
	return val;
}

Ну и по сколько порядок байт у нас сетевой, то не забудем и про группу функций htons.

Повторный запуск дает уже положительный результат.
Окно браузера со страницей полученной от STM8

DHCP?

Надо заметить, что отладочная версия собиралась без DHCP и успешно поместилась в 8кБайт flash-памяти stm8s103f3. И это притом, что было напичкано ещё достаточно отладочного вывода на консоль. Так же 1кБайта оперативной памяти вполне достаточно для работы программы. Ну вот чем вам не замена ATmega8?

С использованием же DHCP код по-прежнему помещается на контроллер, но вот только в релиз сборке и без отладочного вывода на консоль. В прочем не велика беда, но нам же всегда хочется чего-то большего.

Вспоминаем, что программируем то мы через STM8S-Discovery, а в ней контроллер на 32кБайта. Их то нам хватит на 3 DHCP версии.

Правим конфиг, собираем, и ... вспоминаем что студия то у нас халявная (внезапно). Мдя. Можно было бы конечно написать библиотечку, но стало как-то лень.

Так что переключаемся в релиз, возвращаем отладочный вывод, убираем дублирование кода, делаем непростительную оптимизацию (быдлокод жив), и всё-таки помещаемся в 8кБайт и более того, ещё 2 байта свободно!
Лог работы сервера с DHCP

Стоит отметить, что отключение буферизованного вывода на COM-порт крайне негативно сказалось на быстродействии системы. Так пинг 450 байтовыми пакетами с 4мсек вырос до 9мсек:
Время отклика при отключении у UART буфферезованного вывода

Кто хочет проверить

Прошивка stm8s103f3 без DHCP (ip: 192.168.1.222) - тут.

Прошивка stm8s105c6 c DHCP - тут.

Подключение:

// PIN – discovery - stm8s103f3 - name
// ENC28J60
// pc5 - CN2.6  - 15 in TSSOP20 - sck
// pc6 - CN2.9  - 16 in TSSOP20 - mosi
// pc7 - CN2.10 - 17 in TSSOP20 - miso
// pa3 - CN1.9  - 10 in TSSOP20 – nss
// UART
// PD5 - CN4.10 - 2 in TSSOP20 - tx
// PD6 - CN4.11 - 3 in TSSOP20 - rx

Быдлокод желающие смогут найти самостоятельно.

Важно! Пинг из-под ОС Windows у меня не заработал вообще, я не стал разбираться почему (может Wi-Fi, может недосмотрел в коде что, может...).

UPD: Без каких либо изменений прошивка от STM8S103F3 работает и на STM8S003F3.

Файлы: 103f3_nodhcp.zip, 105c6_dhcp.zip, ramexecute.zip, DSC03031_1.jpg

Hosted by uCoz