DMA completion interrupt not working for slave STM32 SPI
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-01-18 3:26 PM
I am using stm32f103 to transmit some data over SPI while stm32 acts as slave. I need to use DMA for sending data to the SPI but the corresponding interrupt handler is never called.
The code comes in the following:
#include ''stm32f10x.h''
uint16_t SPI_Buffer[4]; void DMA_Configure( void ) { DMA_InitTypeDef DMA_InitStructure; /* DMA configuration */ DMA_DeInit(SPI_SLAVE_DMA); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &SPI1->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) SPI_Buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = 4; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel6, &DMA_InitStructure); /* Enable DMA Transfer Complete interrupt */ DMA_ITConfig(DMA1_Channel6, DMA1_IT_TC6, ENABLE); /* Enable DMA */ DMA_Cmd(DMA1_Channel6, ENABLE); } void SPI_Configure( void ) { /* SPI_SLAVE configuration */ SPI_InitTypeDef SPI_InitStructure; SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI_SLAVE, &SPI_InitStructure); /* Enable SPI_SLAVE Tx request */ SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE); /* Enable SPI_SLAVE */ SPI_Cmd(SPI1, ENABLE); } void GPIO_Configur( void ) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* Configure NSS and SCK pins as Input Floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure MISO pin as Alternate Function Push Pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); } void NVIC_Configur( void ) { NVIC_InitTypeDef NVIC_InitStructure; /* 1 bit for pre-emption priority, 3 bits for subpriority */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); /* Configure and enable SPI_DMA interrupt -------------------------------*/ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStructure); } void RCC_Configur( void ) { /* PCLK2 = HCLK/2 := GPIO, SPI1)*/ RCC_PCLK2Config(RCC_HCLK_Div2); /* Enable SPI_SLAVE Periph and GPIO clock */ RCC_APB2PeriphClockCmd(GPIOA | RCC_APB2Periph_SPI1, ENABLE); /* Enable DMA1 clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); } int main( void ) { RCC_Configur(); GPIO_Configur(); NVIC_Configur(); DMA_Configur(); SPI_Configur(); } void DMA1_Channel6_IRQHandler( void ) { /* Test on SPI_DMA Channel Transfer Complete interrupt */ if (DMA_GetITStatus(DMA1_IT_TC6)) { // WE NEVER REACH THIS LINE :( /* Clear DMA1 Channel6 Half Transfer, Transfer Complete and Global interrupt pending bits */ DMA_ClearITPendingBit(DMA1_IT_GL6); } }
When I use SPI interrupt handler, my system works. But using the code written above, interrupt handler of SPI_SLAVE_DMA channel is never called.
#stm32 #selective-cut-n-paste #spi #dma- Labels:
-
DMA
-
SPI
-
STM32F1 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-01-18 4:19 PM
Rule#1 Post ALL relevant code and defines, ideally something that will actually compile.
Make sure the interrupts are enabled in the NVICUp vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-01-19 1:32 AM
Thanks clive. I edited the first post. Now the complete code is there.
BTW, I'm using CoIDE with GNU tools.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-01-19 1:44 AM
Couple of quick observations:
DMA1 Clock not enabled DMA1_Channel6 is not associated with SPI1_TX, that would need to be DMA1_Channel3Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-01-19 1:57 AM
Thanks clive. I just missed to copy the line for enabling DMA clock. But I didn't know that there is a restriction on using DMA channels for different peripherals. I will check it out on my board.
Just a question. In which document I can find that which DMA channel works for a peripheral.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-01-19 4:25 AM
I found it!
Inhttp://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf
, page 273, table 78.