Jump to content

    

Не работает Ethernet на stm32f107

Использую TE-stm32f107. Пытался запустить тестовый пример из IAR'а - WebServer_Demo_uIP. Контроллер на все попытки общения по сети не отзывается. Тогда я нашел на сайте терры аналогичный пример (правда под gcc), взял из него инициализацию пинов (подумал, вдруг различается). Результата нет. Тогда я убрал инициализацию веб-сервера и попробовал на уровне MAC передавать сообщения от контроллера на хост и обратно. Соединил проводом - пробую. Контроллер напрямую отправляет пакеты, хост ловит. Обратно - пакеты отправляются, контроллер - ноль эмоций. Предположил, что может не вызываться обработка приходящих сообщений (хотя до этого брейки ставил везде где можно) - попробовал настроить прерывания по Ethernet - не реагируют ни на прием, ни на отправку. При этом другие прерывания работают.

Пока больше идей нет.

В чем может быть дело? Помогите, пожалуйста!

Edited by GreyM

Share this post


Link to post
Share on other sites

Попробовал. Один пример уходит в хард фолт (пока что не понял где), второй запускается, но пинг не идет.

Начинаю сомневаться в работоспособности эвернета на плате. Может быть посоветуете, как вообще можно проверить работоспособность платы на прием сообщений?

Edited by GreyM

Share this post


Link to post
Share on other sites
Попробовал. Один пример уходит в хард фолт (пока что не понял где), второй запускается, но пинг не идет.

 

Второй пример работает нормально, идет пинг, окрывается WEB-страница, управляются LED

Правда пришлось под свою плату подкрутить, STM32F107RCT6 (64pin), PHY ST802RT1, RMII без ремапа, отрезал LCD и TFTP за неимением железа.

 

По умолчанию LwIP настроен на DHCP, если в сетке нету раздачи адресов, надо его отключить и задать правильный статический IP.

Edited by EugenyAM

Share this post


Link to post
Share on other sites
Попробовал. Один пример уходит в хард фолт (пока что не понял где), второй запускается, но пинг не идет.

Начинаю сомневаться в работоспособности эвернета на плате. Может быть посоветуете, как вообще можно проверить работоспособность платы на прием сообщений?

Можно осциллографом посмотреть на физический уровень: при отсутствии трафика должны идти периодические импульсы (это на 10 мбит/с, на 100, кажется, сложнее). По ним можно проверить на обрывы и КЗ.

Ну а в программе ищем, где ловятся принятые пакеты и ставим точку останова под отладчиком. Далее - собственно отладка ethernet драйвера, TCP/IP стека и т.д.

Share this post


Link to post
Share on other sites
Ну а в программе ищем, где ловятся принятые пакеты и ставим точку останова под отладчиком. Далее - собственно отладка ethernet драйвера, TCP/IP стека и т.д.

 

В программе поочередно ставил точки останова где только можно - ни одна ни разу не сработала. Поэтому и есть подозрение на нерабочий PHY.

 

Остальное буду пробовать

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
В программе поочередно ставил точки останова где только можно - ни одна ни разу не сработала. Поэтому и есть подозрение на нерабочий PHY.

 

Разные PHY отличаются расширенным набором регистров. Тот пример, который я запустил, был написан под DP83848, она стоит на платах STM3210C-EVAL, на платах MCB2300 (LPC) от KEIL, StarterKit использует KS8721BL, я использовал ST802RT1. Если посмотреть на наборы регистров различных PHY, видно, что совпадают только первые 9 регистров. Дальше каждый производитель придумывает по-своему.

 

Инициализация PHY в примере находится в Stm32eth.c, функция

 uint32_t ETH_Init(ETH_InitTypeDef* ETH_InitStruct, uint16_t PHYAddress)

Обращение к регистрам делается из нее вызовами функций

uint16_t ETH_ReadPHYRegister(uint16_t PHYAddress, uint16_t PHYReg)
uint32_t ETH_WritePHYRegister(uint16_t PHYAddress, uint16_t PHYReg, uint16_t PHYValue)

Если посмотреть, к каким регистрам PHY идет обращение, мы увидим PHY_BCR, PHY_BSR и PHY_SR

их номера определены в Stm32_eth.h, в комментариях написано, что определения для DP83848.

BCR и BSR для всех PHY равны 0 и 1 соответственно, а вот SR (из которого мы читаем фактические параметры соединения скорость/дуплекс после автодетекта) для DP83848 равен 0x10, для ST802RT1 уже 0x11, а если посмотреть даташит на KS8721, окажется, что нужная нам информация находится в регистре 0x1F. Естественно, что у каждого PHY используются свои комбинации битов для индикации состояния. Вот эти моменты и нужно в первую очередь исправить в процедуре инициализации под конкретную модель PHY.

Также если в ките предусмотрены джамперы для переключения MII/RMII и выбора адреса PHY, нужно проверить, правильно ли они выставлены. В примере используется адрес PHY 0x01.

 

Замечено, что в широко известных примерах применения Ethernet-контроллера для STM и LPC работе с PHY уделяется мало внимания. Например процедура автоопределения проводится только в момент инициализации, при этом, если кабель не подключен, мы выйдем из инита по ошибке, которую далее никто не ловит и программа продолжает работать, как будто все прошло нормально. Если после этого воткнуть кабель, не факт, что связь будет установлена, хотя индикатор Link загорится. Постоянно отслеживать Link Status в регистре PHY не есть красиво (но в примерах не делается даже это). Разработчики китов часто игнорируют сигналы прерывания от PHY, а ведь ими можно воспользоваться для отслеживания ситуации с кабелем. Можно настроить PHY на выработку прерываний при подключении/отключении кабеля и при наступлении данного события проводить процедуру автоопределения заново, ведь не только в PHY производится выбор скорости и дуплекса, но и в регистрах MAC тоже должны быть установлены соответствующие биты.

 

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

--------

 

Что и где можно посмотреть осциллографом. (считаем, что у нас режим RMII, скорость 100Мбит/с).

Обозначения выводов даны по STM32 Reference Manual (далее REF)

 

MCO -> ETH_RMII_REF_CLK - частота 50 MHz

 

ETH_MDC - при обращениях к регистру PHY пачка импульсов ~64шт. с частотой 2,5 МГц

ETH_MDIO - на втором канале осциллографа смотрим обмен данными с PHY после первых 32 импульсов на ETH_MDC. Здесь можно увидеть, отвечает ли нам PHY по каналу управления (SMI).

Описание формата данных REF стр 918, figure 327-328.

 

ETH_RMII_CRS_DV - Импульс лог.1 длительностью от 6 мкс. В это время вторым каналом наблюдаем принимаемые от PHY пакеты данных на ETH_RMII_RXD0, ETH_RMII_RXD1 (частота 25МГц). Если этого импульса нет - PHY не ловит входные пакеты (естественно хост должен что-то передавать, например Ping). Если импульсы есть - проверяем соответствие настроек MAC и PHY (скорость/дуплекс).

 

ETH_RMII_TX_EN - Импульс лог.1 длительностью от 6 мкс. В это время вторым каналом наблюдаем передаваемые от МК пакеты данных на ETH_RMII_TXD0, ETH_RMII_TXD1 (Частота 25МГц) (МК должен быть настроен на передачу пакетов или отвечать на принимаемые).

---------

 

PS А проблемы, описанной в данной теме в Вашем ките случайно нет?

http://electronix.ru/forum/index.php?showt...amp;hl=ethernet

Edited by EugenyAM

Share this post


Link to post
Share on other sites

-------

Пример из IAR тоже работоспособен, только на WEB-страничке все ссылки жестко привязаны к IP 192.168.0.8

 

Share this post


Link to post
Share on other sites

Итак, вот результаты: проверил PHY - действительно в некоторых примерах оно инициализировалось не верно (в примере адрес 0x01, а у терры PHY по адресу 0x1F). Однако замена адреса PHY на нужный радикально ничего не поменяла. Всё остальное проверил - подходит.

В итоге результат тот же.

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

 

При этом как раз пример из ИАРа рассчитан на PHY по адресу 0x01.

На мою проблему вышеуказанный топик не похож, так как у меня до уровня МАС ни один пакет ни разу не поднялся. Если бы были только битые CRC, было бы пол беды. Да и PHY у меня - rtl8201cp.

При этом чтение всех регистров PHY проходит успешно, однако, как бы я не старался, счетчик принятых пакетов оставался нулевым.

Share this post


Link to post
Share on other sites

На досуге решил провести детальный разбор примера от ST в части инициализации и работы с PHY.

 

читаем первые две части, продолжение следует.

http://eugenemcu.ru/publ/13-1-0-78

http://eugenemcu.ru/publ/13-1-0-79

 

Примеры от IAR и ST для PHY DP83848, надо смотреть чтение PHY_SR после автосогласования и его разбор.

Этот регистр у разных PHY имеет разные адреса и расположения битов.

из этого регистра берется текущий режим PHY по результатам автосогласования (10/100 Мбит и дуплекс),

затем он жестко прописывается в PHY_BCR и в регистр контроллера MAC. Сравнивайте по даташиту на Ваш PHY,

что там читается и откуда (см. пост#8).

Этот вопрос как раз готовится к публикации в 3 части.

 

RTL8201 не поддерживает режим RMII, проверьте в примере в файле stm32f107.c наличие #define MII_MODE

В этом случае, рекомендации по проверке осциллографом из поста #8 не подойдут

Edited by EugenyAM

Share this post


Link to post
Share on other sites

Заработало! Спасибо всем откликнувшимся!

Обстояло всё следующим образом: при проверке осциллографом выяснилось, что импульсы по RX от PHY не идут. Как оказалось, это было связано с маломощным источником питания (предположительно, во время приема потребление подскакивало и PHY отваливался). При замене на хороший источник импульсы пошли.

После этого был повторно проверен исходник и выяснилось, что для платы STM32F10С-EVAL, которая по сути является прообразом TE-STM32F107 по умолчанию используется PHY DP83848, для которого адрес PHY равен 1, в отличие от PHY rtl8201, используемого в TE, где адрес равен 0x1F. Плюс к этому лично мне помогла замена инициализации пинов из примера IAR на инициализацию из примера терры. Однако тут есть подводный камень - в основной программе происходит ремэп пинов, который можно не заметить, просто изменив GPIO_Configuration.

Так же в одном из примеров IAR напрямую проверялась версия PHY путем чтения 2 и 3 регистра и сравнения с контрольным значением для DP83848.

Отдельно хотелось бы упомянуть то, что в примере от терры в main осталась строчка "#define DP83848_PHY", которая лично меня поначалу сбивала с толку.

Еще раз благодарю всех, кто помогал мне с этой проблемой, особенно ув. EugenyAM.

Share this post


Link to post
Share on other sites

Доброго времени суток. Есть плата с stm32f107 и lan8710a. Режим MII. Стек LWIP из примера ST не хочет отвечать на ARP запросы. Причем, при инициализации самообращенные запросы, функция etharp_gratuitous(netif), выходят без проблем. А ответ на обычный запрос теряется где-то в недрах DMA. Ибо до функции ETH_TxPkt_ChainMode доходит, а на ногах процессора ничего.

Эта же программа на отладочной плате STM32-P107 с STE101P-1A в качестве PHY работает нормально. Режим RMII на MII поменял, ноги вродь все прописал. Регистр SR на 31 исправил.

Если кто в курсе, подскажите в каком направлении можно покопать.

ЗЫ. У lan8710a свободна 18я нога. Может ее надо куда нибудь заводить?

 

Конфигурация выводов:

/*Ethernet MII*/

GPIO_PinRemapConfig(GPIO_Remap_ETH, DISABLE);

 /* Configure PA2 as alternate function push-pull MII_MDIO */
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);

 /* Configure PC1, PC2, PC3 as alternate function push-pull MII_MDC, MII_TXD2, MII_TX_CLK*/
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 	GPIO_Init(GPIOC, &GPIO_InitStructure);

 /* Configure PB8, PB11, PB12 and PB13 as alternate function push-pull MII_TXD3, MII_TX_EN, MII_TXD0, MII_TXD1*/
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);

 /* Configure PA0, PA1, PA3 and PA7 as input MII_CRS, MII_RX_CLK, MII_COL, MII_RX_DV*/
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_7;
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);

 /* Configure PC4 and PC5 as input MII_RXD0, MII_RXD1*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC, &GPIO_InitStructure); /**/

 /* Configure PB0, PB1 and PB10 as input MII_RXD2, MII_RXD3, MII_RX_ER*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure); /**/

 /* MCO pin configuration------------------------------------------------- */
 /* Configure MCO (PA8) as alternate function push-pull */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_Init(GPIOA, &GPIO_InitStructure);

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this