siderta писал(а):
...
Козырный заход: не зная ни STM32, ни W5500 сразу начинать работать с W5500 через его регистры. Может, просто взять библиотеку от Wiznet и начать работать с ней? Тут где-то roman.ru выкладывал свои результаты по работе с W5500 через его регистры. Может, сначала изучить его труды?
Надо не задержку делать, а читать регистр состояния W5500. И делать это не _после_ отправки команды, а _перед_, ибо пока готовится отправка очередной команды, предыдущая команда, скорей всего, уже выполнится. Может, почитать мурзилку от Визнета, изучить исходники их библиотеки, почитать тему с работой Романа?
1) Светодиодом помигал. Частоту в 72МГц, далеко не сразу, но настроил (там в конце концов оказалось, что флюс остался на кварце). Печать через UART заработала. Теперь нужно, чтобы заработало сопряжение через Ethernet с помощью W5500. Да приходится учиться новому, а как иначе-то?
2) "Почитать тему от Романа" - а где ее можно почитать? И кто такой Роман
?
3) С W5500 так раз и работаю через их wiznet библиотеку, пытаясь скопировать код из разных примеров. Например, вот этого
https://github.com/IOsetting/stm32f103- ... ware/spi.c (примеров для blue pill и w5500 кстати очень мало находится). Но только код для W5500 у меня пока не завелся. Стал разбираться в причинах, через некоторое время залез внутрь функций
wizchip_setnetinfo/wizchip_getnetinfo. Нашел там функции
setSIPR/getSIPR. Сделал из них маленький примерчик с чтением ip-адреса и установки ip-адреса. Вот на нем пока и отлаживаюсь. (Упрощал пример еще дальше, чтобы просто посмотреть на работу spi.) Так что запись/чтение регистров W5500 взято для выделения маленького отладочного примера на основе wiznet-библиотеки. Наверное, придется пойти и на форум к wiznet'у.
Кстати, отладка на маленьком примере приводит к следующему выводу. Функция
setSIPR пишет 3 байта с адресом wiznet-регистра SIPR и пишет 4 байта с новым значением ip-адреса для w5500. Функция
getSIPR пишет 3 байта с адресом wiznet-регистра SIPR и читает 4 байта с ip-адресом из w5500.
Так вот. Пробую записать ip-адрес A.B.C.D, затем прочитать ip-адрес. Но в моем случае при моих реализациях read/write функция
getSIPR возвращает 1.B.C.D, причем осцилограмма похоже говорит о том, что от w5500 возвращается также A.B.C.D, но вместо A всегда получается 1. Видимо у меня по-прежнему в коде какие-то баги с настройкой SPI и/или функциями read/write, которые передаются в wiznet-библиотеку в качестве параметром при настройке библиотеки.
Добавлено after 7 minutes 17 seconds:отладочный примерчик для записи ip-адреса в W5500 и чтения ip-адреса из W5500:
Код:
while ( 1 ) {
int i;
uint8_t defip[4] = {0, 0, 0, 0};
for ( i = 0; i < 1*1000; ++i ) ;
getSIPR( defip);
#if 0
usart_print_string( USART1, "wiznet_init: ");
usart_print_number( USART1, defip[0]);
usart_print_string( USART1, ".");
usart_print_number( USART1, defip[1]);
usart_print_string( USART1, ".");
usart_print_number( USART1, defip[2]);
usart_print_string( USART1, ".");
usart_print_number( USART1, defip[3]);
usart_print_string( USART1, "\n");
#endif
for ( i = 0; i < 1*100; ++i ) ;
setSIPR( netInfo.ip);
}
Добавлено after 15 minutes 3 seconds:ВОТ КСТАТИ.
Записал с stm32 ip-адрес 192.168.10.20 в w5500, подключил w5500 к компьютеру и с компьютера можно ПИНГОВАТЬ 192.168.10.20!!! (Раньше пинга не было.) То есть как минимум команды записи в w5500 проходят. Осталось разобраться, что не так с командами чтения с w5500.
Добавлено after 1 hour 23 minutes 32 seconds:Подсмотрел еще в одном проекте.
Код:
// Передать байт через SPI и вернуть полученный по SPI байт.
static uint8_t
spi2_write_read_byte( uint8_t v) {
// Put output value to the w-buffer.
SPI2->DR = v;
// Wait until w-buffer will be ready.
while ( !(SPI2->SR & SPI_SR_TXE) ) ;
// Wait until the transmition to be completed.
while ( (SPI2->SR & SPI_SR_BSY) ) ;
// Wait until r-buffer will be ready.
while ( !(SPI2->SR & SPI_SR_RXNE) ) ;
// Get input value from the r-buffer.
v = SPI2->DR;
return (v);
}
Тогда функции чтения и записи байта становятся просто вызовами одной и той же функции:
Код:
// Принять байт через SPI.
static uint8_t
spi2_read_byte() {
uint8_t v = spi2_write_read_byte( 0x5a);
return (v);
}
// Передать байт через SPI.
static void
spi2_write_byte( uint8_t v) {
spi2_write_read_byte( v);
return;
}
Все дело в том, что при записи все равно приходит ответный байт. И если от последней записи этот полученный байт не забрать, то ближайшее следующее чтение возьмет неверное значение. Получается, что операции записи в SPI->DR и чтения из SPI->DR должны быть парными?