Проблема SPI реализации драйвера ATMEGA2561 WINC1500

Я пытаюсь реализовать драйвер WINC1500 MLA для работы с микроконтроллером ATMEGA2561, и я написал свой код драйвера, и он застрял в строке «while ((SPSR & (1 ‹---------------- SPIF)) == 0); в функции m2mStub_SpiTxRx.

Понятия не имею, почему это не продвигается. Для этого проекта я использую IDE ImageCraft для быстрого запуска.

Вот его реализация

void m2mStub_SpiTxRx(uint8_t *p_txBuf,
                     uint16_t txLen,
                     uint8_t *p_rxBuf,
                     uint16_t rxLen)
{
    uint16_t byteCount;
    uint16_t i;

    // Calculate the number of clock cycles necessary, this implies a full-duplex SPI.
    byteCount = (txLen >= rxLen) ? txLen : rxLen;
    DEBUGOUTF("Calculate the number of clock cycles\n");

    DEBUGOUTF("byteCount %d", byteCount, "\n");
    DEBUGOUTF("txLen %d", txLen, "\n");
    DEBUGOUTF("rxLen %d", rxLen, "\n");

    // Read / Transmit.
    for (i = 0; i < byteCount; ++i)
    {
        // Wait for transmitter to be ready. (This is causing the entire thing to crash)
        while((SPSR & (1 << SPIF)) == 0);

        // Transmit.
        if (txLen > 0)
        {
            // Send data from the transmit buffer.
            SPDR = (*p_txBuf++);
            --txLen;
        }
        else
        {
            // No more Tx data to send, just send something to keep clock active.
            SPDR = 0x00U;
        }

        // Wait for transfer to finish.
        while((SPSR & (1 << SPIF)) == 0);

        // Send dummy data to slave, so we can read something from it.
        SPDR = 0x00U;

        // Wait for transfer to finish.
        while((SPSR & (1 << SPIF)) == 0);

        // Read or throw away data from the slave as required.
        if (rxLen > 0)
        {
            *p_rxBuf++ = SPDR;
            --rxLen;
        }
        else
        {
            // Clear the registers
            volatile uint8_t reg_clear = 0U;
            reg_clear = SPDR;
            (void)reg_clear;
        }

    }
}

person Sahil Bora    schedule 02.04.2020    source источник
comment
Хорошо, вы говорите, что вызывает сбой, но остальная часть вашего описания больше похожа на зависание, чем на сбой. И этого следовало ожидать, если передатчик просто не готов, или неправильно подключен, или что-то в этом роде! Я бы сказал, вам следует начать с отладки вашего SPI-подключения в целом   -  person CherryDT    schedule 02.04.2020


Ответы (1)


У меня недостаточно информации, чтобы сказать наверняка, но я предполагаю, что ваше SPI-соединение настроено неправильно.

В частности, я думаю, вы забыли установить /SS в качестве вывода, так же, как в этой проблеме или это < / а>.

В даташите сказано:

Режим ведущего Когда SPI настроен как ведущий (установлен MSTR в SPCR), пользователь может определять направление вывода SS.

Если SS настроен как выход, контакт является общим выходным контактом, который не влияет на систему SPI. Обычно вывод будет управлять выводом SS ведомого устройства SPI.

Если SS настроен как вход, он должен поддерживаться на высоком уровне, чтобы гарантировать работу Master SPI. Если на выводе SS низкий уровень из-за периферийных схем, когда SPI настроен как ведущий с выводом SS, определенным как вход, система SPI интерпретирует это как другое ведущее устройство, выбирающее SPI в качестве ведомого и начинающее посылать ему данные. Чтобы избежать конфликтов на шине, система SPI предпринимает следующие действия:

  1. Бит MSTR в SPCR очищается, и система SPI становится ведомой. В результате того, что SPI становится подчиненным, выводы MOSI и SCK становятся входами.
  2. Флаг SPIF в SPSR установлен, и если прерывание SPI разрешено и установлен бит I в SREG, будет выполняться процедура обработки прерывания.

Таким образом, когда в ведущем режиме используется передача SPI, управляемая прерыванием, и существует вероятность того, что SS переведен в низкий уровень, прерывание всегда должно проверять, что бит MSTR все еще установлен. Если бит MSTR был сброшен выбором ведомого, он должен быть установлен пользователем для повторного включения режима ведущего SPI.

Итак, вам просто нужно настроить вывод /SS в качестве вывода и установить высокий уровень в вашем коде инициализации, это должно решить вашу проблему:

DDRB |= (1 << PB0); // Set /SS (PB0) as output
PORTB |= (1 << PB0); // Set /SS (PB0) high
person CherryDT    schedule 02.04.2020
comment
Спасибо за ваш ответ, но я настроил SS Pin как выход, как вы упомянули, и установил его на высокий уровень, но он все еще не решил проблему. - person Sahil Bora; 03.04.2020