2014-01-18 03: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 #dma2014-01-18 04:19 PM
Rule#1 Post ALL relevant code and defines, ideally something that will actually compile.
Make sure the interrupts are enabled in the NVIC2014-01-19 01:32 AM
Thanks clive. I edited the first post. Now the complete code is there.
BTW, I'm using CoIDE with GNU tools.2014-01-19 01:44 AM
Couple of quick observations:
DMA1 Clock not enabled DMA1_Channel6 is not associated with SPI1_TX, that would need to be DMA1_Channel32014-01-19 01: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.2014-01-19 04:25 AM
I found it!
Inhttp://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf
, page 273, table 78.