Announcements
IMPORTANT: Cypress Developer Community is transitioning on October 20th. To learn more and be prepared for this change, check out our latest announcement.
cancel
Showing results for 
Search instead for 
Did you mean: 

WICED Studio Wi-Fi Combo

MoNo_2793136
New Contributor

I am trying to enable the SPI Receive DMA interrupt on the 4343 combo chip.

I added this function to platform_spi.c file to enable the Rx DMA interrupt:

static platform_result_t spi_dma_rx( const platform_spi_t* spi, const platform_spi_message_segment_t* message )
{
    DMA_InitTypeDef dma_init;
    uint32_t loop_count;
    platform_result_t result = PLATFORM_SUCCESS;
    uint32_t pending_intr = 0;

    /* Error check buffers */
    if ((message->rx_buffer == NULL) && (message->tx_buffer == NULL))
        return PLATFORM_ERROR;

    /* Enable DMA peripheral clock */

    RCC->AHB1ENR |= RCC_AHB1Periph_DMA1; // DMA1 for Rx only


    dma_init.DMA_PeripheralBaseAddr = ( uint32_t )&spi->port->DR;
    dma_init.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
    dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    dma_init.DMA_BufferSize         = message->length;
    dma_init.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
    dma_init.DMA_Mode               = DMA_Mode_Normal;
    dma_init.DMA_Priority           = DMA_Priority_High;
    dma_init.DMA_FIFOMode           = DMA_FIFOMode_Disable;
    dma_init.DMA_FIFOThreshold      = DMA_FIFOThreshold_1QuarterFull;
    dma_init.DMA_MemoryBurst        = DMA_MemoryBurst_Single;
    dma_init.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;

    wiced_assert( "for debug", message->rx_buffer == NULL ); // only for debugging by mn
    /* Setup RX first */
    DMA_ClearFlag( spi->rx_dma.stream, spi->rx_dma.complete_flags | spi->rx_dma.error_flags );

    DMA_DeInit( spi->rx_dma.stream );

    loop_count = 0;
    while (DMA_GetCmdStatus( spi->rx_dma.stream ) == ENABLE)
    {
        loop_count++;
          if ( loop_count >= (uint32_t) SPI_DMA_CTL_TIMEOUT_LOOPS )
            return PLATFORM_TIMEOUT;
    }

    dma_init.DMA_Channel            = spi->rx_dma.channel;
    dma_init.DMA_DIR                = DMA_DIR_PeripheralToMemory;
    if (message->rx_buffer != NULL)
    {
        dma_init.DMA_Memory0BaseAddr    = (uint32_t)message->rx_buffer;
        dma_init.DMA_MemoryInc          = DMA_MemoryInc_Enable;
    }

    /* Init and activate RX DMA channel */
    DMA_Init( spi->rx_dma.stream, &dma_init );

    DMA_Cmd( spi->rx_dma.stream, ENABLE );
    loop_count = 0;
    while (DMA_GetCmdStatus( spi->rx_dma.stream ) == DISABLE)
    {
        loop_count++;
        if ( loop_count >= (uint32_t) SPI_DMA_CTL_TIMEOUT_LOOPS )
        {
            return PLATFORM_TIMEOUT;
        }
    }

    SPI_I2S_DMACmd( spi->port, SPI_I2S_DMAReq_Rx, ENABLE );

    DMA_ITConfig(spi->rx_dma.stream, ( DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_FE ) , ENABLE);
    //DMA_ITConfig(spi->rx_dma.stream, DMA_IT_TC | DMA_IT_TE, ENABLE);
    NVIC_SetPriority(spi->rx_dma.irq_vector, 7);
    NVIC_EnableIRQ( spi->rx_dma.irq_vector );

   

    return result;
}

=====================================================================

The following is my interrupt service routine:

host_semaphore_type_t spi_rx_complete_sem;
void platform_spi2_rx_dma_irq( const platform_spi_t* driver )
{
    int rx_count;
    platform_spi_port_t* spi = (platform_spi_port_t*) driver->port;

  

    if ( (DMA1->LISR & DMA_LISR_TCIF3 ) != 0 ) // check the interrupt
    {
        // Clear the IRQ
        DMA1->LIFCR |= DMA_LISR_TCIF3;
        //driver->last_receive_result = PLATFORM_SUCCESS;
    }

    // Check for error
    if ( (  DMA1->LISR & (DMA_LISR_TEIF3 | DMA_LISR_FEIF3 | DMA_LISR_DMEIF3) ) != 0 )
    {
        // Clear the DMA interrupt's errors
        DMA1->LIFCR |= (DMA_LISR_TEIF3 | DMA_LISR_FEIF3 | DMA_LISR_DMEIF3);

        //driver->last_receive_result = PLATFORM_ERROR;
    }


}

=======================================================================

I added the following code snippet  to the file platform.c

WWD_RTOS_DEFINE_ISR( spi2_rx_dma_irq )

{

    platform_spi2_rx_dma_irq( &platform_spi_peripherals[WICED_SPI_2] );

}

WWD_RTOS_MAP_ISR( spi2_rx_dma_irq, DMA1_Stream3_irq )

=============================================================

The above steps should be sufficient to enable the invocation of the SPI DMA IRQ. But the IRQ is never invoke. However, the Rx DMA runs to completion since I can see that the stream->NDTR count drops to zero.

==========================================================

What is missing in the above step that prevents the invocation of the DMA ISR?

Thanks, Mohammad

0 Likes
1 Solution
VinayakS_26
Moderator
Moderator

workaround for the problem

   if ( !( driver->rx_dma.stream->NDTR  ) )

    {

        sem_result = host_rtos_set_semaphore( &spi_rx_complete_sem, WICED_TRUE );

    }

View solution in original post

0 Likes
2 Replies
VinayakS_26
Moderator
Moderator

Hi,

Let me check this code in my setup and try it out.

Regards

0 Likes
VinayakS_26
Moderator
Moderator

workaround for the problem

   if ( !( driver->rx_dma.stream->NDTR  ) )

    {

        sem_result = host_rtos_set_semaphore( &spi_rx_complete_sem, WICED_TRUE );

    }

View solution in original post

0 Likes