2015-05-12 02:01 AM
Hello,
I am working on simple project, where i need to exchange data with other microcontroller, but it would be better to use DMA for it in circular mode. I had this program working without a glitch on STM32F4 part, but no luck with STM32F373 part. As far as my understanding goes, if i select circular mode and use SPI as master, i should get constant data flow from SPI. If i run this code, and using software spi commands like while(!SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)); SPI_I2S_SendData16(SPI3,(x)); I get data on output, so it looks like at least SPI part is working, but DMA not#define SPIx_TX_DMA_CHANNEL DMA2_Channel2
#define SPIx_RX_DMA_CHANNEL DMA2_Channel1
#define SPI_DMAx_CLK RCC_AHBPeriph_DMA2
#define SPIx SPI3
#define SPIx_CLK RCC_APB1Periph_SPI3
#define SPIx_SCK_PIN GPIO_Pin_3
#define SPIx_SCK_GPIO_PORT GPIOB
#define SPIx_SCK_GPIO_CLK RCC_AHBPeriph_GPIOB
#define SPIx_SCK_SOURCE GPIO_PinSource3
#define SPIx_SCK_AF GPIO_AF_6
#define SPIx_MISO_PIN GPIO_Pin_4
#define SPIx_MISO_GPIO_PORT GPIOB
#define SPIx_MISO_GPIO_CLK RCC_AHBPeriph_GPIOB
#define SPIx_MISO_SOURCE GPIO_PinSource4
#define SPIx_MISO_AF GPIO_AF_6
#define SPIx_MOSI_PIN GPIO_Pin_5
#define SPIx_MOSI_GPIO_PORT GPIOB
#define SPIx_MOSI_GPIO_CLK RCC_AHBPeriph_GPIOB
#define SPIx_MOSI_SOURCE GPIO_PinSource5
#define SPIx_MOSI_AF GPIO_AF_6
void SPI_DMA_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* Enable the SPI peripheral */
RCC_APB1PeriphClockCmd(SPIx_CLK, ENABLE);
RCC_AHBPeriphClockCmd(SPIx_SCK_GPIO_CLK | SPIx_MISO_GPIO_CLK | SPIx_MOSI_GPIO_CLK, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
/* SPI pin mappings */
GPIO_PinAFConfig(SPIx_SCK_GPIO_PORT, SPIx_SCK_SOURCE, SPIx_SCK_AF);
GPIO_PinAFConfig(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_SOURCE, SPIx_MOSI_AF);
GPIO_PinAFConfig(SPIx_MISO_GPIO_PORT, SPIx_MISO_SOURCE, SPIx_MISO_AF);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/* SPI SCK pin configuration */
GPIO_InitStructure.GPIO_Pin = SPIx_SCK_PIN;
GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStructure);
/* SPI MOSI pin configuration */
GPIO_InitStructure.GPIO_Pin = SPIx_MOSI_PIN;
GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure);
/* SPI MISO pin configuration */
GPIO_InitStructure.GPIO_Pin = SPIx_MISO_PIN;
GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStructure);
/* SPI configuration -------------------------------------------------------*/
SPI_I2S_DeInit(SPIx);
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//SPI_Mode_Slave;//
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPIx, &SPI_InitStructure);
/* DMA Configuration -------------------------------------------------------*/
DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_HalfWord;//DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
/* DMA channel Rx of SPI Configuration */
DMA_InitStructure.DMA_BufferSize = (uint16_t)7;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(SPI3->DR));
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxData;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_Init(SPIx_RX_DMA_CHANNEL, &DMA_InitStructure);
/* DMA channel Tx of SPI Configuration */
DMA_InitStructure.DMA_BufferSize = (uint16_t)7;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(SPI3->DR));
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxData;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_Init(SPIx_TX_DMA_CHANNEL, &DMA_InitStructure);
DMA_ClearFlag(DMA2_FLAG_GL1);
DMA_ClearFlag(DMA2_FLAG_GL2);
/* Enable the SPI Rx and Tx DMA requests */
SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE);
SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, ENABLE);
/* Enable the SPI peripheral */
SPI_Cmd(SPIx, ENABLE);
DMA_Cmd(SPIx_RX_DMA_CHANNEL, ENABLE);
DMA_Cmd(SPIx_TX_DMA_CHANNEL, ENABLE);
DMA_ITConfig(DMA2_Channel1,DMA_IT_TC, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = DMA2_Channel1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
}
Could any one spot the possible problem ? Its third day with no progress, and i am starting to regret to use STM32F373 part, since with STM32F4 it will be working in few minutes
2015-05-12 02:23 AM
Looks reasonable at the first glance, but you might want to read the relevant registers in SPI and DMA in the debugger and check whether they are set correctly.
JW2015-05-12 03:16 AM
Hi,
Well, what do you know, cross checking DMA registers showed problem. & was missing indicating address. Thanks for the tip ( I am still using bad approach for problem solving, i usually referencing my work with examples, not registers inside reference manual, sometimes it works faster, but this approach is not a way to go)