2013-12-16 09:44 AM
Hello, I've been having issue with getting DMA to work properly with with SPI. My goal is to have the stm32f3 configured in slave mode and wait for a specific byte code, then when it receives the expected code send a DMA request to read an array of data to be transmitted back. The code I have so far is below:
void init(void){ SPI_InitTypeDef spi_init_struct; NVIC_InitTypeDef nvic_init_struct; DMA_InitTypeDef dma_init_struct; /* Enable peripheral clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Initialize SPI Struct */ SPI_I2S_DeInit(SPI1); SPI_StructInit(&spi_init_struct); spi_init_struct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; spi_init_struct.SPI_Mode = SPI_Mode_Slave; spi_init_struct.SPI_DataSize = SPI_DataSize_8b; spi_init_struct.SPI_CPOL = SPI_CPOL_Low; spi_init_struct.SPI_CPHA = SPI_CPHA_2Edge; spi_init_struct.SPI_NSS = SPI_NSS_Hard; spi_init_struct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; spi_init_struct.SPI_FirstBit = SPI_FirstBit_MSB; spi_init_struct.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &spi_init_struct); /* Configure the Priority Group to 1 bit */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Initialize SPI FIFO Threshold */ SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF); /* Initialize NVIC Struct for SPI*/ nvic_init_struct.NVIC_IRQChannel = SPI1_IRQn; nvic_init_struct.NVIC_IRQChannelPreemptionPriority = 1; nvic_init_struct.NVIC_IRQChannelSubPriority = 0; nvic_init_struct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic_init_struct); /* Initialize DMA Struct */ DMA_DeInit(DMA1_Channel3); DMA_StructInit(&dma_init_struct); dma_init_struct.DMA_PeripheralBaseAddr = (uint32_t) & SPI1->DR; dma_init_struct.DMA_MemoryBaseAddr = (uint32_t) table; /* This is an array */ dma_init_struct.DMA_DIR = DMA_DIR_PeripheralDST; dma_init_struct.DMA_BufferSize = 0; /* Start at 0, because no data to send yet */ dma_init_struct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma_init_struct.DMA_MemoryInc = DMA_PeripheralInc_Enable; dma_init_struct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma_init_struct.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte; dma_init_struct.DMA_Mode = DMA_Mode_Normal; dma_init_struct.DMA_Priority = DMA_Priority_VeryHigh; dma_init_struct.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel3, &dma_init_struct); /* Initialize NVIC Struct for DMA */ nvic_init_struct.NVIC_IRQChannel = DMA1_Channel3_IRQn; nvic_init_struct.NVIC_IRQChannelPreemptionPriority = 1; nvic_init_struct.NVIC_IRQChannelSubPriority = 0; nvic_init_struct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic_init_struct); /* Enable SPI Error Interrupt */ SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_ERR, ENABLE); /* Enable SPI RXNE Interrupt */ SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE); /* Enable SPI */ SPI_Cmd(SPI1, ENABLE); /* Enable DMA */ DMA_Cmd(DMA1_Channel3, ENABLE); /* Enable DMA Error Interrupt */ DMA_ITConfig(DMA1_Channel3, DMA_IT_TE, ENABLE); /* Enable DMA Error Interrupt */ DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);}Elsewhere is an interrupt service routine:void spi_rx_isr(void){ RxIdx = 0; RxBuffer[RxIdx] = SPI_ReceiveData8(SPI1); printf(''Byte received: %x\n\r'', RxBuffer[RxIdx]); if (RxBuffer[RxIdx] == RX_READ) { active_table_status status = valves_toggle_active_table(); DMA_Cmd(DMA1_Channel3, DISABLE); /* Set number of data to send */ DMA1_Channel3->CNDTR = (uint16_t) sizeof(table_row) * TABLE_SIZE; DMA_Cmd(DMA1_Channel3, ENABLE); /* Send request */ SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE); } RxIdx++;}Before you ask, I have the gpio pins configured elsewhere and I can confirm that spi mode works when not attempting to use DMA. I've looked at the output with a logic analyzer, and it's clear that the MOSI, Clock, and SS lines are performing as expected, but the output from MISO is completely flat. I also originally had SPI configured to catch overrun interrupts, but I read that because I was using DMA in tx only mode, the OVR bit was inevitable because I wasn't reading the received bytes. I've run out of ideas... Any help would be appreciated. #dma #spi