Перейти к содержанию

AVR и W5500

Всем добрый день!

Я продолжаю изучать программирование микроконтроллеров, и в качестве следующей цели выбрал организацию простого web-сервера на AVR.
Я изучил основные моменты инициализации в официальной документации, плюс нашёл в интернете несколько примеров (правда, все они под STM32), но у меня всё равно не получается его инициализировать даже на обычный пинг. Вот как выглядит сам девайс:


Общаюсь я с ним по SPI. В документации сказано, что сначала передаётся старший байт адреса назначения, потом младший, затем контрольная фаза и, на конец, сами данные. Сейчас я приведу небольшой пример, как я всё это реализовываю:

Код
uint8_t opcode = 0; //Переменная для хранения опкода
uint8_t ip[4] = {192,168,1,197}; //ip адрес

//Данные, необходимые для формирования контрольной фазы
#define BSB_COMMON 0x0000     //bsb блок
#define WRITE 1                         //бит записи
#define READ 0                           //бит чтения
#define OM_FDM0 0x00 //Режим передачи данных переменной длинны

#define SIPR0 0x000F //Адреса регистров w5500, в которых хранится ip адрес
#define SIPR1 0x0010
#define SIPR2 0x0011
#define SIPR3 0x0012

//Провожу инициализацию SPI
void spi_init()                    
{
    DDRB = (1<<PORTB7)|(1<<PORTB5)|(1<<PORTB4); //Clock - 7, MOSI - 5, Chip Select - 4. Всё на выход. MISO (6) - на вход.
    SPCR = (1<<MSTR)|(1<<SPE)|(1<<SPR0); //Мастер, SPI включен.
}

//Функция записи данных в чип
void w5500_write(uint16_t addr, uint8_t opcode, uint8_t data) //Функция записи данных в регистр
{
        selectW5500();        //Выбрать чип
    unsigned char i;       //счётчик                  
    uint8_t buf[4];         //буфер для данных
    buf[0] = (uint8_t)(addr >> 8);   //передаём старшую часть адреса
    buf[1] = (uint8_t)(addr);            //передаём младшуя часть адреса
    buf[2] = opcode;                        //передаём контрольную фазу
    buf[3] = (uint8_t)(data);            //передаём данные
    
    for(i=0;i<4;i++)                       //цикл передачи данных
    {
        SPDR = buf[i];
        while(!(SPSR&(1<<SPIF)));
    }    
        deselectW5500();
}


Не знаю, почему, но мне кажется, что я что-то делаю не так с передачей данных. Я привёл пример записи одного
байта данных в регистр, отвечающий за хранение ip адреса. Формирование контрольной фазы выглядит так:

Код
opcode = (BSB_COMMON<<3)|(WRITE<<2)|OM_FDM0;


Функции выбора чипа в этом посте я писать не стал, так как там происходит просто "притягивание" линии к 0, а потом "отпускание".

Я постарался как можно короче изложить свою проблему, но, тем не менее, указав важные детали. Буду рад
любой помощи или совету.

Заранее спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
opcode должен быть первым в последовательности, затем адрес , потом данные.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(aiwa @ May 14 2018, 18:35) <{POST_SNAPBACK}>
opcode должен быть первым в последовательности, затем адрес , потом данные.


Большое спасибо за ответ! Завтра я обязательно попробую так сделать. Скажите, пожалуйста, а откуда у Вас такая информация?
Просто в даташите SPI Frame начинается с адреса, и я руководствовался именно этой схемой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Скажите, пожалуйста, а откуда у Вас такая информация?

Извините, похоже я ввел Вас в заблуждение. Написал по инерции для наиболее распространенного варианта.

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если кому-нибудь интересно: все данные в чип пишутся, и читаются (настройки mac, ip и прочее). Даже считал версию чипа (0x04), но он упорно не хочет пинговаться, и выдаёт свои стандартные настройки. Буду разбираться дальше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
все данные в чип пишутся, и читаются (настройки mac, ip и прочее). Даже считал версию чипа (0x04), но он упорно не хочет пинговаться
Я работал с 5100, по параллельной шине и очень давно. В порядке предположения: а порядок байт при записи "ip и прочего" не попутан случайно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот так выглядит "кадр" передачи данных SPI:

 

 

Screenshot_1.png

 

Функцию записи я немного переписал:

 

void w5500_write(uint16_t addr, uint8_t op, uint8_t data) //Функция записи данных в регистр
{ 
    char MSB = (addr>>8);
    char LSB = (addr);
    char opcode = op;
    char sdata = data;
    SPDR = MSB;
    while(!(SPSR&(1<<SPIF)));
    SPDR = LSB;
    while(!(SPSR&(1<<SPIF)));
    SPDR = opcode;
    while(!(SPSR&(1<<SPIF)));
    SPDR = sdata;
    while(!(SPSR&(1<<SPIF)));
}

 

Так как сперва надо передать старший байт адреса, я его двигаю, и потом в след за ним передаю младшую часть, потом сформированный "опкод", а затем непосредственно сами данные. В чём может быть причина неудачи, я не знаю. Само собой, перед записью данных я делаю два сброса, как это сказано в даташите: хард и софт.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Так как сперва надо передать старший байт адреса, я его двигаю, и потом в след за ним передаю младшую часть, потом сформированный "опкод", а затем непосредственно сами данные.
Так вот в этих "самих данных" не может быть попутаны байты? Вы уверены, что в регистры попадает "192.168.0.1", а не "1.0.168.192"? У W5100 и предыдущих данные хранились в виде больших индейцев (big endian), все известные мне компиляторы для AVR используют маленьких индейцев.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Думаю, что всё записывается правильно. Каждый байт записывается по своему собственному адресу.

192 пишется в 0x0001, 168 в 0x0002 и т.д. Я попробовал прочитать все адреса и получил правильный порядок байтов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
192 пишется в 0x0001, 168 в 0x0002 и т.д.
Да, я именно это и имел ввиду. Раз здесь все правильно - остается только схема. Потому что если у вас в MR биты RST и PB сброшены, то после записи GAR, SUBR, SHAR и SIPR оно должно начать пинговаться.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ещё одно дополнение.

Чип работает, отвечает на пинг. Нужно было соблюсти несколько условий:

1) Чип и ПК соединяются через кросс-кабель.

2) Чип и ПК должны находится в одной подсети.

3) Обязательно нужно открыть порт.

 

Всем спасибо за участие! :yeah:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация