|
|
  |
Как заставить PHY Ethernet отправлять и получать пакеты |
|
|
|
Sep 29 2010, 05:32
|
Гуру
     
Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369

|
Цитата(x736C @ Sep 28 2010, 23:53)  Байты 0x55 и 0xАА подобны с точностью до сдвига на один бит. Я бы тут покопал. Тут надо не "копать" а "изучать". На самом деле все работает так: сеть может быть проведена так, что + и - в паре окажутся перекрещенными. Далее. И линия по получению преамбулы начинает "накачиваться", постоянная составляющая меандра приходит к нулю. Трансивер начинает хватать данные. Он может первым схватить 0, а может 1. Соотв. Получаем на приеме "Байты 0x55 и 0xАА". И это абсолютно правильно... Когда в преамбуле идет шахматный код, то в линии это выглядит как меандр. И далее выдается код с нарушением этого меандра. Трансивер запоминает эту ситуацию и заносит бит в регистр "ксоринья". И после этого трансивер либо пропускает данные "как есть", либо инвертирует биты. Вот поэтому после преамбулы данные Вы получаете правильные. Удачи!
--------------------
www.iosifk.narod.ru
|
|
|
|
|
Oct 1 2010, 14:47
|

Частый гость
 
Группа: Участник
Сообщений: 85
Регистрация: 8-04-10
Из: Нижний Новгород
Пользователь №: 56 498

|
Реализовал на уровне драйвера интерфейс 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; }
|
|
|
|
|
Oct 1 2010, 16:21
|

Частый гость
 
Группа: Участник
Сообщений: 85
Регистрация: 8-04-10
Из: Нижний Новгород
Пользователь №: 56 498

|
Цитата(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 портом
|
|
|
|
|
Oct 2 2010, 03:23
|

Частый гость
 
Группа: Участник
Сообщений: 85
Регистрация: 8-04-10
Из: Нижний Новгород
Пользователь №: 56 498

|
Запись идет следующими командами: Код 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
Сообщение отредактировал Shevnnov - Oct 2 2010, 03:28
|
|
|
|
|
Oct 2 2010, 06:22
|

Частый гость
 
Группа: Участник
Сообщений: 85
Регистрация: 8-04-10
Из: Нижний Новгород
Пользователь №: 56 498

|
Цитата(vadimuzzz @ Oct 2 2010, 07:44)  а адрес PHY правильный указали (надо в даташите смотреть)? Адрес PHY брал такой же как в примере в даташите был написан (0Ch)
|
|
|
|
|
Oct 2 2010, 08:42
|

Частый гость
 
Группа: Участник
Сообщений: 85
Регистрация: 8-04-10
Из: Нижний Новгород
Пользователь №: 56 498

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