Shevnnov
Sep 24 2010, 11:45
Всем доброго дня!
Продолжаю разрабатывать свой MAC блок. Столкнулся с очерендой проблемой - сейчас пытаюсь отладить свой компонент на плате Nios Embedded Evaluation Kit на Cyclone III. Встраиваю компонент в стандартный пример системы идущей вместе с платой. Драйверы, RTL проверены симуляцией (только увы не на этом Kit'e а на другом от Cyclone II - т.к. от платы никак не хочет симулироваться jtag_uart (( ) Порты моего компонента рукам прописываю в топовом файле quartus-проекта. Пины использую те, что были забиты ранее для tse (HC_RX_D, HC_RX_CLK и т.д.). RESET_N assign'ом присваиваю 1. Компилирую всё это. Всё более-менее, прошивка создается. Заливаю её в ПЛИС'ку запускаю программу - ничего не происходит. Регистры компонента вроде считываются - но попытка передать и принять набор данных (не ethernet-кадр а просто набор бит длиной 64 байта) не приводят ни к чему.
По структуре сейчас реализована RX часть, слушающая RX-порты MII интерфейса, и TX часть, отправляющая данные по TX интерфейсу (и то урезанно, реализованы порты RX_CLK, RXD, RX_DV, TX_CLK, TXD, TX_EN). MDC и MDIO поддержки нет.
Вопрос где искать подвох? Он может быть везде, но хотелось бы узнать примерные советы для проверки от людей, которые сталкивались с MAC'ом.
Может, как раз дело в отстутствии MDC-MDIO?
Я ни разу не работал с nios и отладочными платами, но там, очевидно, стоит какой-то внешний PHY, который, наверное, просто требует предварительной настройки...
а Reset на PHY выставляете как? какое состояние ног (TXD, RXD) когда активный ресет на PHY?
iosifk
Sep 24 2010, 13:05
Цитата(Shevnnov @ Sep 24 2010, 15:45)

Вопрос где искать подвох? Он может быть везде, но хотелось бы узнать примерные советы для проверки от людей, которые сталкивались с MAC'ом.
1. реализовать служебный интерфейс.
2. Произвести настройку регистров трансивера
3. Поставить режим "цифровой" заглушки.
4. Научиться передавать и принимать через нее данные.
5. Поставить режим аналоговой петли.
6. Повторить п.4.
7. вставить в разъем RJ45 провода "сам-на-себя". Проверить линк.
8. Повторить п.4.
9. Доделать МАС, чтобы он понимал адреса и CRC.
10. Сделать сеть "Компьютер-компьютер", без посторонних... и Повторить п.4.
11. Пинг.
Пока хватит...
vadimuzzz
Sep 24 2010, 13:05
а как реализован обмен с памятью? через DMA? тогда отсюда и начать, посмотреть сигналтапом, как транзакции на передачу идут. и так последовательно до выхода MII. приемный конец - в обратном порядке. ну, и MDIO зря не сделали, его первым делом надо смотреть, что линк есть. а то можно долго "отлаживать" сломанный кабель.
Shevnnov
Sep 24 2010, 13:22
Цитата(vadimuzzz @ Sep 24 2010, 17:05)

а как реализован обмен с памятью? через DMA? тогда отсюда и начать, посмотреть сигналтапом, как транзакции на передачу идут. и так последовательно до выхода MII. приемный конец - в обратном порядке. ну, и MDIO зря не сделали, его первым делом надо смотреть, что линк есть. а то можно долго "отлаживать" сломанный кабель.
Реализован без DMA - простое считывание регистров IOWR_ IORD_
to iosifk Спасибо за подробное описание порядка. ВОпрос - как аналогувую и цифровую петли реализовать правильно?
iosifk
Sep 24 2010, 13:48
Цитата(Shevnnov @ Sep 24 2010, 17:22)

to iosifk Спасибо за подробное описание порядка. ВОпрос - как аналогувую и цифровую петли реализовать правильно?
посмотрите у меня на сайте есть статьи об этом Ethernete....
Петли - путем записи бита управления в регистры по MDC и MDIO....
Shevnnov
Sep 25 2010, 07:17
Хорошо. Спасибо за статьи, обязательно их прочитаю. Попробую начать с проверки работы только MAC'a замыкания выхода ethernet на вход. Надеюсь хоть генераторы TX_CLK и RX_CLK будут подаваться без конфигурации PHY чипа
Петлю можно сделать, если обжать RJ45 коннектор, соединив 1-й вывод с 3-м, а 2-й - с 6-м. Будет ли при этом работать Ваш PHY зависит от значений регистров после подачи питания (см. документацию на чип в каком режиме он будет).
iosifk
Sep 27 2010, 05:45
Цитата(Shevnnov @ Sep 25 2010, 11:17)

Хорошо. Спасибо за статьи, обязательно их прочитаю. Попробую начать с проверки работы только MAC'a замыкания выхода ethernet на вход. Надеюсь хоть генераторы TX_CLK и RX_CLK будут подаваться без конфигурации PHY чипа
Зря потратите время!
Без правильной конфигурации не получится...
Цитата(iosifk @ Sep 27 2010, 09:45)

Зря потратите время!
Без правильной конфигурации не получится...
+1. По умолчанию, как правило, все выключено. Придется делать MIIM.
Shevnnov
Sep 27 2010, 13:54
Цитата(vitan @ Sep 27 2010, 10:33)

+1. По умолчанию, как правило, все выключено. Придется делать MIIM.
Спасибо. Буду сначала программировать MDIO, потом уже тестировать
Цитата(iosifk @ Sep 27 2010, 09:45)

Зря потратите время!
Без правильной конфигурации не получится...
Цитата(vitan @ Sep 27 2010, 10:33)

+1. По умолчанию, как правило, все выключено. Придется делать MIIM.
Если речь о работе rx_clk и tx_clk по умолчанию, то DP83848 по включению ведет себя как раз так.
Для простой работы можно вполне обойтись без конфигурирования регистров. Есть небольшие нюансы, но об этом можно почитать в документации.
P.S. С особенностями PHY на плате Nios Embedded Evaluation Kit не знаком.
Shevnnov
Sep 27 2010, 19:17
Цитата(x736C @ Sep 27 2010, 19:41)

Для простой работы можно вполне обойтись без конфигурирования регистров. Есть небольшие нюансы, но об этом можно почитать в документации.
В смысле, для простой? А зачем тогда конфигурировать, если можно обойтись и без?
Цитата(Shevnnov @ Sep 27 2010, 23:17)

В смысле, для простой? А зачем тогда конфигурировать, если можно обойтись и без?
Для простой работы, это с использованием autonegotiation mode, без использования петель, с настройками по умолчанию, отвечающими за светодиоды, без использования power down режима и прочее-прочее. Все нюансы в документации. Более того, выбор интерфейса MII/RMII/SNI можно тоже осуществлять без доступа к регистрам.
Первый раз воспользовался регистрами, когда потребовалось отключить autonegotiation mode и выставить нужный мне режим (10HD).
Цитата
ну, и MDIO зря не сделали, его первым делом надо смотреть, что линк есть. а то можно долго "отлаживать" сломанный кабель.
В моем случае поставил три светодиода в соответствии с документацией на м/с.
act, link, spd контролировал визуально. В моем случае этого было более чем достаточно.
Единственное, что забыл добавить. Если вам потребуется использовать прерывание от DP83848, без доступа к соотв. регистру не обойтись.
Shevnnov
Sep 28 2010, 19:11
Поправил проект квартуса (во-первых оказалось сначала выходы моего компонента из топового файла SOPC builder'a не включил в топовый файл квартуса, а во-вторых после того как включил, оказалось что память компонента у меня вместо RAM области полезла в логику - решилось переписывание модуля встроенной памяти по стандартному). Расставил пины, как они были до этого от TSE, в том числе RESET_N выставил единицу. Конфигурацию через MDIO не проводил (еще не писал). Включил в разъем RJ-45 заглушку (шла в комплекте с платой - такая как BSV писал).
Пакет отправил, пакет принялся. Данные совпадают кроме одного первого байта - он почему то всегда 0x505 был (хотя первый байт послыки был 0xAAAA). Остальный байты кадра дальше полностью совпадают.
Немного непонятно, как байт может иметь значения 0x505 или 0xAAAA. Первые два байта?
Байты 0x55 и 0xАА подобны с точностью до сдвига на один бит. Я бы тут покопал.
vadimuzzz
Sep 29 2010, 01:15
Цитата(x736C @ Sep 29 2010, 02:53)

Байты 0x55 и 0xАА подобны с точностью до сдвига на один бит.
или чтение по-арабски, задом наперед
iosifk
Sep 29 2010, 05:32
Цитата(x736C @ Sep 28 2010, 23:53)

Байты 0x55 и 0xАА подобны с точностью до сдвига на один бит. Я бы тут покопал.
Тут надо не "копать" а "изучать".
На самом деле все работает так: сеть может быть проведена так, что + и - в паре окажутся перекрещенными.
Далее. И линия по получению преамбулы начинает "накачиваться", постоянная составляющая меандра приходит к нулю. Трансивер начинает хватать данные. Он может первым схватить 0, а может 1. Соотв. Получаем на приеме "Байты 0x55 и 0xАА". И это абсолютно правильно...
Когда в преамбуле идет шахматный код, то в линии это выглядит как меандр. И далее выдается код с нарушением этого меандра. Трансивер запоминает эту ситуацию и заносит бит в регистр "ксоринья". И после этого трансивер либо пропускает данные "как есть", либо инвертирует биты. Вот поэтому после преамбулы данные Вы получаете правильные.
Удачи!
Shevnnov
Oct 1 2010, 14:47
Реализовал на уровне драйвера интерфейс MDIO (с помощью команды IOWR изменяю значение регистров, которые идут на выход MDC и MDIO). Пробую считать значение регистра 0 - в ответ получаю одни 1. Непонятно, вроде формат кадра соблюдаю.
CODE
alt_u16 eth_phy_get_config (alt_u8 reg_address)
{
alt_u16 mdio_request = 0;
alt_u16 mdio_request_blank = 0x1980;
alt_u16 mdio_readdata = 0;
int i;
int tmp;
mdio_request = mdio_request_blank | ((alt_u16)((reg_address)&0x1f));
IOWR_ETH_CONTROL_MDIO_OPCODE(ETH_CONTROL_BASE, ETH_MDIO_OP_WRITE);
tmp = IORD_ETH_CONTROL_MDIO_READ_DATA(ETH_CONTROL_BASE) & ETH_CONTROL_MDIO_DATA_MSK;
for (i = 0; i < 14; i++)
{
tmp = (mdio_request >> (13-i)) & ETH_CONTROL_MDIO_DATA_MSK;
IOWR_ETH_CONTROL_MDIO_WRITE_DATA(ETH_CONTROL_BASE, tmp);
IOWR_ETH_CONTROL_MDIO_MDC_CLK(ETH_CONTROL_BASE,1);
IOWR_ETH_CONTROL_MDIO_MDC_CLK(ETH_CONTROL_BASE,0);
}
IOWR_ETH_CONTROL_MDIO_OPCODE(ETH_CONTROL_BASE, ETH_MDIO_OP_READ);
for (i = 0; i< 2; i++)
{
IOWR_ETH_CONTROL_MDIO_MDC_CLK(ETH_CONTROL_BASE,1);
IOWR_ETH_CONTROL_MDIO_MDC_CLK(ETH_CONTROL_BASE,0);
if (i==1) tmp = IORD_ETH_CONTROL_MDIO_READ_DATA(ETH_CONTROL_BASE) & ETH_CONTROL_MDIO_DATA_MSK;
}
for (i = 0; i<16; i++)
{
IOWR_ETH_CONTROL_MDIO_MDC_CLK(ETH_CONTROL_BASE,1);
IOWR_ETH_CONTROL_MDIO_MDC_CLK(ETH_CONTROL_BASE,0);
mdio_readdata = mdio_readdata | ((IORD_ETH_CONTROL_MDIO_READ_DATA(ETH_CONTROL_BASE) & ETH_CONTROL_MDIO_DATA_MSK) << (15 - i));
}
return mdio_readdata;
}
vadimuzzz
Oct 1 2010, 14:56
скорее всего перепутали полярность mdio_oen, который управляет tri-state буфером
Цитата(Shevnnov @ Oct 1 2010, 18:47)

Пробую считать значение регистра 0 - в ответ получаю одни 1.
Не надо гадать, ткните осциллографом в MDIO. PHY обязательно ответит, если на на то будут условия: правильный адрес, неактивный ресет, ну и т.п....
Shevnnov
Oct 1 2010, 16:21
Цитата(vadimuzzz @ Oct 1 2010, 18:56)

скорее всего перепутали полярность mdio_oen, который управляет tri-state буфером
MDIO портом управляю следующим образом:
Код
assign MDIO = (mdio_opcode_r) ? mdio_data_r : 1'hz
mdio_opecode_r выстанавливается в "1" командой IOWR_ETH_CONTROL_MDIO_OPCODE(ETH_CONTROL_BASE, ETH_MDIO_OP_WRITE); и в "0" командой IOWR_ETH_CONTROL_MDIO_OPCODE(ETH_CONTROL_BASE, ETH_MDIO_OP_READ)
Должно быть все нормально с iout портом
vadimuzzz
Oct 1 2010, 22:42
Цитата(Shevnnov @ Oct 1 2010, 23:21)

Должно быть все нормально с iout портом
а запись как идет?
Shevnnov
Oct 2 2010, 03:23
Запись идет следующими командами:
Код
IOWR_ETH_CONTROL_MDIO_OPCODE(ETH_CONTROL_BASE, ETH_MDIO_OP_WRITE); // выставить значение mdc_opcode на 1
for (i = 0; i < 14; i++)
{
tmp = (mdio_request >> (13-i)) & ETH_CONTROL_MDIO_DATA_MSK;
IOWR_ETH_CONTROL_MDIO_WRITE_DATA(ETH_CONTROL_BASE, tmp); // выставить следующий бит посылки
IOWR_ETH_CONTROL_MDIO_MDC_CLK(ETH_CONTROL_BASE,1); // изменить значение mdc на 1
IOWR_ETH_CONTROL_MDIO_MDC_CLK(ETH_CONTROL_BASE,0); // изменить значение mdc на 0
}
в RTL это всё реализуется так:
CODE
//*********************** MIIM_MDIO *************************/
always @ (posedge clk or negedge rst)
begin
if(!rst)
mdio_opcode_r <= 1'b0;
else
if ((chipselect) && (ctrl_write) && (ctrl_address == MDIO_OPCODE))
mdio_opcode_r <= ctrl_writedata[0];
else
mdio_opcode_r <= mdio_opcode_r;
end
always @ (posedge clk or negedge rst)
begin
if (!rst)
mdio_data_r <= 1'b0;
else
if ((chipselect) && (ctrl_write) && (ctrl_address == MDIO_DATA))
mdio_data_r <= ctrl_writedata[0];
else
mdio_data_r <= mdio_data_r;
end
assign MDIO = (mdio_opcode_r) ? mdio_data_r : 1'bz;
always @(posedge clk or negedge rst)
begin
if(!rst)
mdio_clk_r <= 1'b0;
else
if ((chipselect) && (ctrl_write) && (ctrl_address == MDIO_DATA_CLK))
mdio_clk_r <= ctrl_writedata[0];
else
mdio_clk_r <= mdio_clk_r;
end
assign MDC = mdio_clk_r;
//****************** AVALON-MM_READ_INTERFACE *****************/
always @(posedge clk or negedge rst)
begin
if(!rst)
ctrl_readdata_r <= 32'b0;
else
if (chipselect & ctrl_read)
case (ctrl_address)
RX_RECEIVED_BYTES: ctrl_readdata_r <= {21'b0, rx_bite_count_clk_r};
TX_READY: ctrl_readdata_r <= {31'b0, tx_ready_clk_r};
MDIO_DATA: ctrl_readdata_r <= {31'b0, MDIO};
endcase
else
ctrl_readdata_r <= 32'd0;
end
assign ctrl_readdata = ctrl_readdata_r;
Симулировал систему в ModelSim'e - данные вылетают как надо (в плане записи по шине RTL). В нужном порядке. Только MDC получается не регулярный - состояние в значении 0 на порядок длиннее состояния в значении 1
vadimuzzz
Oct 2 2010, 03:44
а адрес PHY правильный указали (надо в даташите смотреть)?
Shevnnov
Oct 2 2010, 06:22
Цитата(vadimuzzz @ Oct 2 2010, 07:44)

а адрес PHY правильный указали (надо в даташите смотреть)?
Адрес PHY брал такой же как в примере в даташите был написан (0Ch)
vadimuzzz
Oct 2 2010, 06:29
Цитата(Shevnnov @ Oct 2 2010, 13:22)

Адрес PHY брал такой же как в примере в даташите был написан (0Ch)
может он на плате резисторами задается? попробуйте в цикле перебрать все адреса PHY, а читать какой-нибудь ID-регистр
Цитата(Shevnnov @ Oct 1 2010, 20:21)

Код
assign MDIO = (mdio_opcode_r) ? mdio_data_r : 1'hz
Я не знаток верилога... Это 1 Герц? Это может оказаться слишком медленно. Какой у Вас PHY?
Shevnnov
Oct 2 2010, 08:42
Цитата(vitan @ Oct 2 2010, 12:01)

Я не знаток верилога... Это 1 Герц? Это может оказаться слишком медленно. Какой у Вас PHY?
Не 1'hz - это не частота, это присваиваю высокоимпедансное значение (z) 1 биту (h - шестнадцатеричная система счисления)
Цитата(Shevnnov @ Oct 2 2010, 12:42)

Не 1'hz - это не частота, это присваиваю высокоимпедансное значение (z) 1 биту (h - шестнадцатеричная система счисления)
Сорри. А все-таки, какой PHY?
Цитата(Shevnnov @ Oct 2 2010, 10:22)

Адрес PHY брал такой же как в примере в даташите был написан (0Ch)
Может, порядок следования бит перепутали? Первым должен выезжать MSB (старший). Точнее - если смотреть на осциллограмму, то слева д.б. старшие биты, а справа - младшие. Что-то мысли с утра плохо выражаются...
Shevnnov
Oct 3 2010, 13:24
Цитата(vitan @ Oct 2 2010, 13:28)

Может, порядок следования бит перепутали? Первым должен выезжать MSB (старший). Точнее - если смотреть на осциллограмму, то слева д.б. старшие биты, а справа - младшие. Что-то мысли с утра плохо выражаются...
Порядок следования вроде верный. Есть у меня одна мысль, где коск может быть. Вычитал в даташите, что default значение PHY адреса 01h. Завтра выйду на работу, попробую.
Shevnnov
Oct 6 2010, 09:10
Проблема решилась. Был неправильный адрес PHY (нужно было обращаться по адресу 01h). Был еще один коск - я сначала присваивал занчению MDC ноль и единицу, а потом считывал при получении ответа от PHY, а надо наодборот (это видно если посмотреть временные диаграммы в документации к чипу).
Есть два вопроса - 1) можно ли менять адрес PHY чипа, и как это делается?
2) почему когда я записываю в 15 бит в поле данных MDIO-кадра 1 (этот бит отвечает за SW_RESET) он у меня вешается конкретно. В документации сказано что он 3мкс не отвечать будет - но мне кажется что проходит больше времени, а ответа нет ((
vadimuzzz
Oct 6 2010, 09:52
Цитата(Shevnnov @ Oct 6 2010, 16:10)

Есть два вопроса - 1) можно ли менять адрес PHY чипа, и как это делается?
это делается внешними резисторами, при включении PHY защелкивает уровни на соотв. ногах как адрес (PHYAD или что-то типа того)
Shevnnov
Oct 7 2010, 10:57
Цитата(vadimuzzz @ Oct 6 2010, 13:52)

это делается внешними резисторами, при включении PHY защелкивает уровни на соотв. ногах как адрес (PHYAD или что-то типа того)
Ясно. Значит програмно это не сконфигурировать и это определяется платой на которой стоит чип.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.