День добрый, коллеги!
У меня такой вопрос по подключению W5300 и микроконтроллера MSP430F5419A:
Подключил W5300 к MSP430F5419A в режиме прямого доступа к памяти (direct address mode) c шириной шины 8бит (8 Bit data bus width). Попробовал считать MR-регистр (mode register) по адресу 0x000 (MR0) и 0x001 (MR1) - возвращает 0x3800, т.е. что и должен. Пробежался по другим регистрам - возвращает ноль, глянул документацию на момент состояния регистров после сброса - так и должно быть.
Кой чего я не понял. В даташите есть такая фраза:
Physical Address of W5300 Reg = Base Address of T.M.S + Address offset of W5300 Reg (раздел 3, стр.24)
Смотрю дальше (раздел 4, стр 45):
For convenience, we assume the Base Address(BA) of T.M.S is 0x08000, and BA of the Physical Address of W5300 Register is 0x08000.
Т.е. для удобства приняли базовый адрес равным 0x08000, к которому прибавляют сдвиг (offset). Но адрес не может быть больше 10бит (0x3FF) как физически, так и программно (адресное пространство 0x000-0x3FF полностью под регистрами).
Как я понял, порядок чередования байтов применим в данном случае только к регистрам (не к адресам).
The byte ordering of W5300 registers is big-endian – low address byte is used as the most significant byte.
Попробовал записать - установить бит RST в MR1 (старший 7-й бит по адресу 0x001). Не перезагрузился камушек.
Такое ощущение, что при записи сдвигается адрес на 1, хотя при пошаговой отладке отчетливо видно, что на линии адреса выставляются нужные значения. Теряюсь в догадках, читаю даташит.
Код
LANdata_in();
getMR[0] = LANdata_RD(MR0); //0x38 - ok
getMR[1] = LANdata_RD(MR1); //0x00 - ok
//Setting SHAR - Source Hardware Address register
LANdata_out();
LANdata_WR(SHAR0, mac[0]); // 0x00
LANdata_WR(SHAR1, mac[1]); // 0x08
LANdata_WR(SHAR2, mac[2]); // 0xDC
LANdata_WR(SHAR3, mac[3]); // 0x11
LANdata_WR(SHAR4, mac[4]); // 0x22
LANdata_WR(SHAR5, mac[5]); // 0x86
//Reading SHAR - Source Hardware Address register
LANdata_in();
getMAC[0] = LANdata_RD(SHAR0); // 0x00
getMAC[1] = LANdata_RD(SHAR1); // 0x00
getMAC[2] = LANdata_RD(SHAR2); // 0x08
getMAC[3] = LANdata_RD(SHAR3); // 0xDC
getMAC[4] = LANdata_RD(SHAR4); // 0x11
getMAC[5] = LANdata_RD(SHAR5); // 0x22
// where is 0x86?
//setting GAR - Gateway IP Address register
LANdata_out();
LANdata_WR(GAR0, ip[0]); //192
LANdata_WR(GAR1, ip[1]); //168
LANdata_WR(GAR2, ip[2]); //1
LANdata_WR(GAR3, ip[3]); //86
//Reading GAR - Gateway IP Address register
LANdata_in();
getIP[0] = LANdata_RD(GAR0); // ?0
getIP[1] = LANdata_RD(GAR1); // ?192
getIP[2] = LANdata_RD(GAR2); // ?168
getIP[3] = LANdata_RD(GAR3); // ?1
// where is 86?
Если что - нога BIT16EN притянута к земле, т.е. 8бит ширина шины.
Если к адресу считываемого регистра прибавить 1, то все сдвигается вверх, как и должно, но SHAR5 и GAR3 занулены.
Устанавливал FIFO Swap Bit, записывая в MR1:
Код
LANdata_in();
getMR[0] = LANdata_RD(MR0); //reset state 0x38
getMR[1] = LANdata_RD(MR1); //reset state 0x00
LANdata_out();
LANdata_WR(MR1, 0x39); //Trying to change MR0 register, writing to MR1!
LANdata_WR(MR0, 0x00);
LANdata_in();
getMR[0] = LANdata_RD(MR0); //return 0x39
getMR[1] = LANdata_RD(MR1); //return 0x00
Бит судя по всему устанавливается. Результатов от этого ноль. Пробовал достучаться до софтовой перезагрузки (S/W Reset в MR1), но безрезультатно - попытка установить хоть какой-нибудь бит в MR1 всегда возвращает ноль.
Я вот думаю - может зря оставил Data[15:8] висеть в воздухе? Хотя по даташиту не требуют их притягивать - можно оставлять плавающими. одно расстройство, блин. Прям хоть перепаивай на шину 16бит.
Если нужно, вот подпрограммы записи/чтения данных и установки адреса.
Делал пока линейно, т.е. без указателей.
Код
void LANdata_in()
{
P8OUT = 0x00; //P8 reset
P8DIR = 0x00; //Data input
}
void LANdata_out()
{
P8OUT = 0; //P8 reset
P8DIR = 0xFF; //Data line D[0..7], IO
}
unsigned int LANdata_WR(unsigned int addr, unsigned int data8)
{
LANaddr_WR(addr); // write address
clrLAN_CS; // chip-select low
clrLAN_WR; // LAN-WR low
P8OUT = data8; // write 8-bit data
setLAN_WR; // LAN-WR high
setLAN_CS; // chip-select high
LANaddr_WR(0x00); // write 0 address to clear address bits
return 1;
}
unsigned int LANdata_RD(unsigned int addr)
{
unsigned int data_in;
LANaddr_WR(addr); // write address
clrLAN_CS; // chip-select low
clrLAN_RD; // LAN-WR low
data_in = P8IN; // read 8-bit data
setLAN_RD; // LAN-WR high
setLAN_CS; // chip-select high
LANaddr_WR(0x00); // write 0 address to clear address bits
return data_in;
}
void LANaddr_WR(unsigned int address)
{
unsigned short int addr_low=0, addr_high=0;
addr_low = address & 0x00FF; //bit 7..0; P6.7..6.0
addr_high = ((address & 0x0300) >> 5); //bit 9..8; P7.5..7.4,
P6OUT = addr_low;
P7OUT = P7OUT | addr_high;
//return 1;
}
Ваши комментарии по проблеме, пожалуйста.