- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Solved! Go to Solution.
- Labels:
-
SPI
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
workaround for the problem
if ( !( driver->rx_dma.stream->NDTR ) )
{
sem_result = host_rtos_set_semaphore( &spi_rx_complete_sem, WICED_TRUE );
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Let me check this code in my setup and try it out.
Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
workaround for the problem
if ( !( driver->rx_dma.stream->NDTR ) )
{
sem_result = host_rtos_set_semaphore( &spi_rx_complete_sem, WICED_TRUE );
}