Dp83848 ethernet board подключение к stm32
Main reference:
STM32F407 and DP83848 chip RMII mode hardware circuit diagram reference
How to use common components 13: How to use the physical layer interface chip DP83848
Share the STM32F407 and DP83848 chip RMII mode hardware circuit diagram
The circuit schematic diagram is as shown in the figure above. Among them, the 40-pin of the DP83848 chip is the RMII_CRS_DV pin, but I have seen many schematics on the Internet that connect RMII_CRS_DV to the 39-pin of the DP83848 chip. I checked the chip manual and found that the 39-pin is a mode Select the pin, pin 40 is the CRS_DV pin.
InHow to use common components 13: How to use the physical layer interface chip DP83848 It is described as:
Should the CRS_DV of RMII be connected to the RX_DV pin of DP838348 or the CRS_DV pin:
According to common sense, the CRS_DV pin should be connected, but ST's DEMO circuit board is connected to RX_DV. There is a description on the Internet for reference: "I finally figured it out. If the full-duplex communication is set in the RMII mode, the specification is Without CRS signal, it is easier to use RX_DV directly than using CRS_DV (no need to recover CRS signal from CRS_DV and TX_EN signal). When working in half-duplex mode, RMII needs CRS signal, so CRS_DV signal must be used instead of RX_DV only Pin; Therefore, if we only use full-duplex work, we can connect to the RX_DV pin (the PIN39), but if we want to support both full-duplex and half-duplex, then we must connect the 83848 CRS_DV pin (that is, PIN40). "
Determination of the default address:
DP83848 can set 32 address values, which are determined by the state of the 5 pins at power-on, as shown in the following table. It can be seen that if the external pull-up or pull-down resistors of these 5 pins are not connected, PHYAD0 is internally pulled up and the other pins are internally pulled down, so the physical address is 1.
The manual says: If PHYAD[0] is internally pulled up, and the rest are pulled down weakly, in a floating state, the default address of this DP83848 is 0x01. And its state is latched in the PHYCTRL register when the system hardware is reset.
MII or RMII mode selection:
It can be done through the MII_MODE and SNI_MODE pins. Mode selection. If you want to run in RMII mode, pin 39 needs to be set high and pin 6 needs to be set low. Pin 39 and Pin 6 have internal pull-down circuits, so the external 2.2K pull-up of Pin 39 can make the chip work in RMII_MODE.
Automatic conversion between crossover line and straight line:
As shown in the table below, if no pull-down resistor is added, the "Cross Line-Straight Line Automatic Conversion" is automatically turned on.
Power feedback circuit:
The design method of the power feedback circuit is shown in the figure below, and the capacitor should be close to the pin.
Differential pair interface circuit design:
Network cable hot plug problem
For the 7th pin of DP83848, it is generally recommended to pull up a 2.2K resistor and connect it to the IO pin of STM32, because we still need some interrupts to handle events, such as hot plugging of the network cable.
The power-down and interrupt functions are multiplexed on pin 7 of the device. By default, this pin is used as a power-off input and the interrupt function is disabled. Set bit 0 (INT\ U OE) of MICR (0x11h) to configure the pin as an active low interrupt output.
The interrupt function is controlled by register access. By default, all interrupt sources are disabled. Setting bit 1 (INTEN) of MICR (0x11h) to 1 will enable interrupt output, depending on the interrupt mask set in the low byte of MISR (0x12h). When an interrupt condition occurs, the PWRDOWN_INT pin is asynchronously set to low level. The source of the interrupt can be determined by reading the high byte of MISR. One or more bits in MISR will be set to 1, indicating all currently pending interrupts. Reading MISR will clear all pending interrupts.
Example: To generate an interrupt when the link state changes or the energy detection power state changes, the steps are as follows:
• Write 0003h to MICR to set INTEN and INT_OE
• Write 0060h to MISR to set ED_INT_EN and LINK_INT_EN
• Monitor PWRDOWN_INT pin
When the PWRDOWN_INT pin is low, the user will read the MISR register to see the ED_INT or LINK_INT bit is 1, for example, the source that caused the interrupt. After reading MISR, the interrupt bit should be cleared and the PWRDOWN_INT pin will be set to invalid.
На днях стал счастливым(ли?) обладателем китайского клона STM3210C-EVAL под названием Open107V.
Среди прочего в наборе есть плата расширения с микросхемой DP83848C, которая реализует PHY Ethernet. Соединяется через MII/RMII, по схеме абсолютно идентично оному в оригинальной плате. Суть в том, что попытки создать соединение с компьютером при использовании примеров, представленных ST и компанией Waveshare(чуть переработанные), не увенчались успехом. Симптомы заключаются в отсутствии исходящих пакетов с платы.
Вопрос: кто-нибудь разбирался со встроенным ethernet в stm, в частоности в связке с указанной микросхемой? В чем может быть загвоздка?
Комментарии ( 57 )
Тут не надо гадать, тут надо отлаживать. Для начала повесить анализатор на clock, MDC и MDIO и посмотреть, если ли такт в 50 МГц и команды инициализации. JP3 и JP4 проверь.
JP3-4 не проверить ввиду их отсутсвия, но все линии RMII на месте. Сигнал 50МГц присутствует. Выяснил, что пакеты успешно доходят до контроллера, MAC-адрес компа записывается, но по некотоырм причинам не формируются ответные пакеты на ARP-запросы. Я, к сожалению, не имею возможности постоянно заниматсья этим вопросом, так что ковыряю достаточно медленно. Планирую сегодня-завтра доковырять.
В некоторых демопроектах программа затыкается в месте, где производится сброс ethernet-контрллера — не сбрасывается флаг SR в регистре DMABSR.
А зачем Вам U-Link? Rbnfqcrbq j-Link — дешевле, и поддерживается всюду. Как вариант — ST-Link/v2 (ориганальный) у тех же китайцев порядка 20-24$, например, тут.
А какой отладчик используешь? Собираюсь похожую китайскую платку купить, вот не знаю, купить ли китайский U-Link или оригинальный от ST.
Я ST-Link пользую. Говорят, что с U-link в кейле есть некоторые преимущества, хотя я конекретно в этом не разбирался. Но надо обратить внимание, что U-link, если память не изменяет, не поддерживается в IAR. Впрочем, большинство демопроектов как есть исключительно под кейл.
Тем, что она стоит в большинстве отладочных плат с ethernet, и под нее, соответственно, есть примеры. По цене — у нас она дороговата.
Тем, что поддерживает 100BASE-T. Ну и интерфейс у нее, соответственно, более высокоскоростной. Однако требуется МК со встроенным Ethernet-модулем, потому что стек TCP/IP здесь аппаратно не реализован, только Phy и MAC, вроде.
А в чем бред? Там написано что микруха реализует физ уровень и мак, вроде. Всё вполне корректно написано. Позже подправили что мак нету. С чего вы взяли что кто-то утверждал, что TCP = MAC = PHY?
Тащемта таки бред, потому что Ethernet-модуль — это MAC+PHY, TCP/IP — несколько из другой оперы, и если бы в микре были MAC+PHY — встроенного Ethernet от МК бы не потребовалось (пример — ENC28J60, от МК требует только SPI, содержит только MAC и PHY). Так что правильный вариант — эта микра PHY, и потому требуется МК с встроенным Ethernet (точнее, MAC — есть вроде МК, где и PHY встроен, им эта микра тоже не нужна). Впрочем, AFAIK, PHY лучше поискать у Realtek — они у них дешевле.
Есть еще недорогие PHY у SMSC — LAN8720. Реалтековские дешевые RTL8201 поддерживают только MII, а LAN8720 умеет и RMII.
Чуть не забыл: есть еще относительно недорогой ST802RT1, но он требует трансформатора 1.4:1, а они встречаются заметно реже чем 1:1.
А насколько существенна эта разница? У меня на ENC28J60 вроде вообще стоит транс (точнее, магджек — что было) 1:1/2.5:1 (TX/RX или наоборот, не помню), при требуемом 1:1 в оба канала и вроде работает.
Заметно меньшее количество связей между контроллером и PHY, соответственно больше свободных выводов останется, да и разводить проще.
Интерфейс между PHY и контроллером не влияет на скорость по сети, они оба позволяют выдать 100МБит. Разница в количестве связей и тактировании MII требует 25МГц, RMII — 50. В STM32 поддерживаются оба интерфейса, так что тут особой разницы нет. Упоминавшаяся выше DP83848C умеет оба, RTL8201 — только MII, LAN8720 — только RMII. Из всех упомянутых LAN8720 — самая маленькая — QFN24, остальные — LQFP48.
Насколько существенна разница точнее не подскажу, но в доке на ST802RT1 это отдельно оговаривается, в отличие от других PHY.
У меня ещё и разница в потреблении ощутимая получилась: LAN8720 жрёт 48ма, у остальных за 70. Для батарейного прибора всё это дополнительное время работы. От ST не пробовал, отпугнул транс с нетрадиционными обмотками. Пробовал RTL и DP. LAN понравилась — дешёвая и маленькая.
О, круто. Я закупил пачку, а попробовать все руки не доходят. А код инициализации там сильно от DP-шек отличается?
Уважаемый Egoist как вам удалось побороть вот ету проблему «В некоторых демопроектах программа затыкается в месте, где производится сброс ethernet-контрллера — не сбрасывается флаг SR в регистре DMABSR.» у меня такая же проблема висит в цикле опроса етого флага. Использую MII DP83848. Демопроект скачивал с STM -> «AN3226».
Ещо есть CP2200. Там MAC и PHY встроены. По цене не дорогой(~35грн). Дата шит просто образцовый. С Силикон Лабс — никогда проблем не было. Платка под него уже на руках. Как попробую — отпишусь :)
тоже купил платку с DP83848C на алиэкспрессе. Пытаюсь подружить с stm32f4discovery — те же симптомы — пакетов исходящих с платы нет (смотрел даже wireshark'ом). В чем может быть дело, как удалось побороть? Грешу на длинные проводки между дисковери и платкой с PHY (частоты все-таки высокие)
В обычных модах появляются сигналы RMII_PPS_OUT и MII_PPS_OUT соответственно (на PG8), и в доках почти нигде не встречается, за исключением, но есть селектор в конфигураторе для STM32, с 207.
Если посмотреть доки на DP83848, то там в описании RMII и MII отсутствуют подобные сигналы. Вероятно, это относится к зарезервированным режимам работы. Или для поддержки протокола IEEE 1588 (PTP).
Спасибо, теперь понятнее стало )
Интересно — эта фича как-либо влияет на коррекцию RTC самой стм-ки? В примере с физическим ethernet для stm32 не нашел такой реализации.
MAC поддерживает 2 метода корректировки системного времени:
«Грубый»: часы корректируются за один цикл тактирования, это используется для корректировки времени во время фазы инициализации
«Точный»: часы корректируются за период времени после сложной синхронизации через аппаратный алгоритм, это используется для коррекции дрейфа частоты
На тему реализации в stm32 железе:
Я вот только не понял одного, если все микросхемы PHY уровня стоят в районе 200-350 рублей, то какой смысл использовать аппаратный Ethernet в микроконтроллерах .
Ведь даже W5200 стоит 290 рублей…
Хм, в терре DP83848KSQ стоит порядка 100 рэ, какой-нибудь стмовский LAN8720 ещё раза в два меньше, и это только те две, которые я вспомнил вот так сразу.
Доброе время суток.
Работаю над Ethernet MAC в stm32f107, использую PHY ksz8041.
Развел платку, спаял, особых косяков и ошибок не обнаружил )
Проверил, что есть на PHY 50мГц (от кварцевого генератора, на — RMII_REF_CLK контроллера все так же придоходит).
Но проблема в том, что пример uIP — «зависает» в цикле в попытке правильно сконфигурировать PHY, дальше после >timeout выставляет Error и все.
Причем если адресс PHY == 1, то в ответе (регистр MACMIIDR) данные похожи на адекватные — 0x7849, а если PHY адрес присвоить отличный от 1 — данные равны 0xFFFFF, т.е. PHY по MDC что-то отвечает, надо полагать…
использую RMII, куда копать дальше пока не знаю )
Если смотреть осцилографом на MDIO-MDC, пока программа топчется в этом цикле, — то виден интенсивный поток данных.
LAN у PHY при этом не светится.
Ксати если Reset у PHY притянуть в 0, то 0x7849 в ответе так же пропадает, т.е. PHY похоже действительно живой )
спасибо.
Похоже все прояснилось.
0x00007849 по даташиту соответствует сборошенному биту — 1.2 (Link Status, 1 — UP — 0 Down).
Похоже на проблему с физикой разъема )
Долго облизывался на подключение МК к Ethernet, ходил вокруг цикла статей Lifelover'a, и решил попробовать. Но как в том анекдоте «не в лото, а в покер, не Волгу, а сто рублей и не выиграл, а проиграл» отличия от проекта Lifelover'a будут следующие:
- камень stm32f103v, флеша у которого аж 512к. Меньше 64к у STM32 — редкость, что не может не радовать
- tcp стек решил взять готовый, в частности uIP. Пробовал стек от Lifelover'a, но там много AVR-овских особенностей — раздельная адресация как минимум. В итоге запустил, погонял, но решил все-таки перейти на стандартный стек.
- ОС, естественно, FreeRTOS,
- Ну а Ethernet-контроллер все тот же enc28j60, подключенный через SPI
Итак, качаем исходники uIP отсюда
Копируем (или подключаем) полностью папку /uIP, там лежат неизменяемые библиотечные файлы
Проект берем из статьи про FreeRTOS, настройку FreeRTOS я здесь опускаю.
В каталог проекта копируем следующие файлы:
uip-conf.h — берем стандартный и потом чуть подправим
clock-arch.c/clock-arch.h – копируем стандартные и закомментируем функцию работы со временем, потом ее допишем
hello-world.с/hello-world.h — это, собственно, приложение, которое и будет крутиться поверх стека
enc28j60.c/enc28j60.h – это драйвер Ethernet контроллера, написаный Lifelover'ом для AVR и адаптированный к stm32. Переписана функция инициализации и работы с SPI
Теперь разберем чуть подробнее, как же части системы должны взаимодействовать друг с другом.
Соответственно, главный цикл будет выглядеть так:
Вся остальная настройка сводится к тому, чтобы подключить приложение hello-world в файле uip-conf.h (раскомментировать соответствующую строчку).
Теперь наш файл main.c
Сначала надо проинициализировать все что у нас есть:
Также есть необходимость периодически дергать еще пару функций uIP – чтобы он вовремя широковещательные пакеты рассылал и таблицы чистил.
В оригинале это все предлагалось делать в процедуре main в бесконечном цикле. Но у нас же RTOS! Оформим это все в виде двух тасков:
Ну, собственно, и все. Компилируем, запускаем — опаньки, все работает :)
Все вместе (RTOS и uIP) заняли чуть меньше 11кб кода. Размер буферов для пакетов, количество соединений и т. п., что влияет на оперативку, можно настроить все в том же uip-conf.h
При компиляции вываливается неожиданно много ворнингов на тему «dereferencing type-punned pointer will break strict-aliasing rules», отключил пока опцией -fno-strict-aliasing компилятора, потом гляну подробнее. Ну и ругань на тему «функция не-void, а return нету». Это особенность используемых в библиотеке protothreads.
PS. и пару слов, что изменилось в драйвере от Lifelover'a:
все остальное — без изменений, поскольку хорошо абстрагировано от железа. Ну и понятно, что enc28j60 висит на SPI2, его reset заведен на GPIOA_Pin_7
Алексей Сонькин
Мм, есть приборы с такой физикой, работают. Слышал о каких-то проблемах с генерацией рефклока от кварца или что-то подобное, там что-то про разность фаз. Лечилось подачей одного рефклока на фи и проц от генератора. Про другие проблемы не слыхал.
Алексей Сонькин ответил Игорю
Алексей Сонькин ответил Игорю
Игорь, ну у каждого фи есть регистры настроек и статуса, как минимум, их можно посмотреть, я по ним отлаживался (read_PHY_register или как там они).
А дефайны регистров микросхемы PHY в файле stm32f4x7_eth.h меняли, или их расположение везде стандартное?
Алексей Сонькин ответил Игорю
Игорь, не везде. Часть регистров одинаковая (но я фз, так ли во всех) с lan8720, но большая часть нет. Я не помню уже, что используется из регистров в стандартном примере. Помню, переписывал номер какого-то статусного регистра с 16 на 31 что ли.
Alexey, крч проблема заключалась. в неплотном контакте кабеля с разъёмом RJ45 на Ethernet board
Да, вот так можно убить неделю времени на выяснение такого пустяка
Алексей Сонькин ответил Игорю
Алексей Сонькин ответил Игорю
Игорь, кстати, стандартный пример надо дорабатывать, если хотите его где использовать в серьёзных вещах. Если нет сети — стартует полгода, автоопределение только при старте — если переткнут в другой порт, не факт, что заработает~
Алексей Сонькин ответил Игорю
Игорь, ну не то что бы вачдога, просто следить за флагами наличия линка и делать автоопределение при его появлении, как минимум.
Алексей Сонькин ответил Игорю
Игорь, ну это не прерывание. Я сделал монитор, функция пару раз в секунду проверяет флаги состояния phy, а там уже что-то делает. Например, программно может сообщить интересующимся, есть ли линк и возможна ли связь, или вызвать событие, чтоб все поняли, что что-то не ок или уже можно начинать работать. Да и вообще старт быстрый, если настройка и проверка состояния эзернета выполняется не в синхронном режиме, когда он ждёт делаями и бесконечными циклами каждого следующего события. Дефолтные таймауты там драконовские.
Алексей Сонькин ответил Игорю
Игорь, я уже сталкивался с проблемами с этим кодом. Например, устройства, которые работают по РОЕ, при старте коммутатора включаются, пытаются подключиться, нифига у них не получается (коммутаторы не быстро стартуют), где-то вылетают по таймауту и не донастраивают контроллер или настраивают его неверно. Как результат — устройство не может получать и отправлять пакеты при таком включении. Ну и всякие такие мелочи, не заметные сразу.
Alexey, Можете мне кинуть ф-цию обработчик Вашего монитора регистров состояния PHY?
Т.к. регистры в подобных микросхемах очень похожи, попробую адаптировать что-то к своему проекту
Алексей Сонькин ответил Игорю
Оно не заведётся просто так, там есть зависимости от левых библиотек (в bsp), но как-то так.
Alexey, Библиотеки я использую те же самые, мне интересная именна ф-ция ETH_Test, которая как я понял у вас используется вместо монитора
Т.е. Какие именно регистры вы мониторите, PHY Status Register как основной источник инфы?
Алексей Сонькин ответил Игорю
Игорь, не, я про функции работы с GPIO и системным таймером, они самопал.
Да, там самое главное. Остальное так, на всякий случай посмотреть, в момент отладки.
Alexey, Вопрос такой - в случае потери связи по эзернету (Link not established) как именно вы перезагружаете эзернет, при условии использования РТОСа?
Вот как я реализовал это:
ETH_BSP_Config(); //настройка переферии
Показать полностью.
uint16_t eth_register=ETH_ReadPHYRegister(1, PHY_SR);
/* Initialize the PTP daemon. */
ptpd_init();
udpecho_receive_init();
udpecho_transmit_init();
>
else
<
TIM_ETH_Check_Connection();
>
Ф-ция TIM_ETH_Check_Connection настраивает таймер, в теле которого проверка на наличие установки соединения, и если соединение ок - настраиваем эзернет
проблема в том, что если настройка эзернета в main'e работает, то в прерывании вылетают ошибки создания потоков. В чём может быть проблема?
Engineering version:
cube:6.0.1
cube Pack:STM32Cube FW_H7 V1.8.0
KEIL:5.29.0.0
Clock configuration and other project configuration omitted
Turn on DCache:
ETH configuration:
LWIP configuration:
Basically, the default configuration is used, and the IP uses static IP
The following options must be configured, and then modify a little configuration in the project.
Then click Generate Project.
Open the KEIL project, all the following steps are the key configuration:
The starting address of RAM must start at 24000000, because peripherals cannot access the following memory. For details, please refer to ST's official documentation for H7
Next is to configure the MPU, directly copy the routine configuration in the development kit as follows:
static void MPU_Config(void)
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU attributes as Device not cacheable
for ETH DMA descriptors */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30040000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
/* Configure the MPU attributes as Cacheable write through
for LwIP RAM heap which contains the Tx buffers */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30044000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
>
Enable DCache:
SCB_EnableDCache();
Add the following function to the interrupt:
osSemaphoreRelease(RxPktSemaphore);
Find the ethernetif.c file
Find the static err_t low_level_output(struct netif *netif, struct pbuf *p) function and add:
SCB_CleanInvalidateDCache();//user add
Find the static struct pbuf * low_level_input(struct netif *netif) function and add:
SCB_CleanInvalidateDCache();//user add
The function added in the above two functions is to clear invalid data in DCache, and it can be pinged without clearing. But when sending and receiving data, once the data is too much or too fast, the data will be wrong.
The most critical step is that the hardware driver automatically generated by cube is LAN8742, but we are using DP83848. Here we need to modify the value of the corresponding register when initializing the device. In the past, when configuring M4, there was an option to set the address of the external network chip in the cube, but this option was not available when configuring H7, but you will find that you will find that in fact it will all 32 The addresses are traversed to query until the correct address is queried, otherwise an error will be returned. The specific code is at the beginning of int32_t LAN8742_Init(lan8742_Object_t *pObj):
Note that comparing the data sheets of the LAN8742 and DP83848 chips, the register value of the query address is different, as follows
LAN8742:
DP83848:
Compare the register definition of the LAN8742.h file automatically generated by CUBE:
The next step is to add the code application of the client layer. Here I use the tcp_echoserver experiment. The file can be directly copied into the development package of the cube and added to the project. The file path is as follows:
The last step is to initialize tcp_echoserver, I am using FreeRTOS here
Читайте также: