Реализация SPI застряла на «while (! Spi_is_tx_empty (WINC1500_SPI));» - PullRequest
0 голосов
/ 06 февраля 2020

В настоящее время я реализую драйвер для WINC1500, который будет использоваться с микроконтроллером ATMEGA32, и он застревает в этой строке "while (! Spi_is_tx_empty (WINC1500_SPI));". Код создается и запускается, но он не сможет понять, что находится внутри этой функции, чтобы пройти через мой код и загрузить модуль Wifi. Я застрял на этой проблеме в течение нескольких недель без какого-либо прогресса и не знаю, как ее решить.

static inline bool spi_is_tx_empty(volatile avr32_spi_t *spi)
{
    // 1 = All Transmissions complete
    // 0 = Transmissions not complete 
    return (spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) != 0;
}

Вот моя реализация функции SPI Tx / Rx

void m2mStub_SpiTxRx(uint8_t *p_txBuf,
uint16_t txLen,
uint8_t *p_rxBuf,
uint16_t rxLen)

{
uint16_t byteCount;
uint16_t i;

uint16_t data;

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

// Read / Transmit.
for (i = 0; i < byteCount; ++i)
{
    // Wait for transmitter to be ready.
    while(!spi_is_tx_ready(WINC1500_SPI));

    // Transmit.
    if (txLen > 0)
    {
        // Send data from the transmit buffer
        spi_put(WINC1500_SPI, *p_txBuf++);
        --txLen;
    }
    else
    {
        // No more Tx data to send, just send something to keep clock active.
        // Here we clock out a don't care byte 
        spi_put(WINC1500_SPI, 0x00U);

        // Not reading it back, not being cleared 16/1/2020
    }

    // Reference http://asf.atmel.com/docs/latest/avr32.components.memory.sdmmc.spi.example.evk1101/html/avr32_drivers_spi_quick_start.html
    // Wait for transfer to finish, stuck on here
    // Need to clear the buffer for it to be able to continue 
    while(!spi_is_tx_empty(WINC1500_SPI));

    // Wait for transmitter to be ready again
    while(!spi_is_tx_ready(WINC1500_SPI));

    // Send dummy data to slave, so we can read something from it.
    spi_put(WINC1500_SPI, 0x00U);    // Change dummy data from 00U to 0xFF idea

    // Wait for a complete transmission
    while(!spi_is_tx_empty(WINC1500_SPI));

    // Read or throw away data from the slave as required.
    if (rxLen > 0)
    {
        *p_rxBuf++ = spi_get(WINC1500_SPI);
        --rxLen;
    }
    else
    {
        spi_get(WINC1500_SPI);
    }
}

Отладочный журнал вывода

Disable SPI
Init SPI module as master
Configure SPI and Clock settings
spi_enable(WINC1500_SPI)
InitStateMachine()
INIT_START_STATE
InitStateMachine()
INIT_WAIT_FOR_CHIP_RESET_STATE
m2mStub_PinSet_CE
m2mStub_PinSet_RESET
m2mStub_GetOneMsTimer();
SetChipHardwareResetState (CHIP_HARDWARE_RESET_FIRST_DELAY_1MS)
InitStateMachine()
INIT_WAIT_FOR_CHIP_RESET_STATE
if(m2m_get_elapsed_time(startTime) >= 2)
m2mStub_PinSet_CE(M2M_WIFI_PIN_HIGH)
startTime = m2mStub_GetOneMsTimer();
SetChipHardwareResetState(CHIP_HARDWARE_RESET_SECOND_DELAY_5_MS);
InitStateMachine()
INIT_WAIT_FOR_CHIP_RESET_STATE
m2m_get_elapsed_time(startTime) >= 6
m2mStub_PinSet_RESET(M2M_WIFI_PIN_HIGH)
startTime = m2mStub_GetOneMsTimer();
SetChipHardwareResetState(CHIP_HARDWARE_RESET_FINAL_DELAY);
InitStateMachine()
INIT_WAIT_FOR_CHIP_RESET_STATE
m2m_get_elapsed_time(startTime) >= 10
SetChipHardwareResetState(CHIP_HARDWARE_RESET_COMPLETE)
retVal =  true // State machine has completed successfully
g_scanInProgress = false
nm_spi_init();
reg = spi_read_reg(NMI_SPI_PROTOCOL_CONFIG)
Wait for a complete transmission
Wait for transmitter to be ready
SPI_PUT(WINC1500_SPI, *p_txBuf++);
--txLen;
Wait for transfer to finish, stuck on here
Wait for transfer to finish, stuck on here

1 Ответ

0 голосов
/ 06 февраля 2020

ATmega32 - это 8-битный AVR, но вы, кажется, используете код для AVR32, семейства 32-битных AVR. Вероятно, вы просто используете совершенно неверный код, и вам следует обратиться к таблице данных ATmega32 и найти SPI для семейства AVR ATmega.

...