2025-01-07 05:21 AM - last edited on 2025-01-07 06:27 AM by SofLit
Hello,
I am having issue with running two SPI (SPI2 & SPI 3) in two streams like Stream4 and Stream7 in single DMA1.
Later on i checked individually checking Stream4 for output1 and then Stream7 for output 2. I found out i am able to get the wave forms for Stream 4 but not able to get the output for Stream7.
Can someone please help me out what is wrong with Stream7 in DMA1 with SPI.
void SigGenInitSigGen(void) {
uint16_t tempPrescalerValue = 0;
SigGenSpiInitData_u tempInitData;
//RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12, ENABLE);
// Configuration GPIO
IoSpiGpioInit();
/* SPI configuration ------------------------------------------------*/
memset(&tempInitData, 0x00, sizeof(SigGenSpiInitData_u));
tempInitData.spiInitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
tempInitData.spiInitStructure.SPI_Mode = SPI_Mode_Master;
tempInitData.spiInitStructure.SPI_DataSize = SPI_DataSize_16b;
tempInitData.spiInitStructure.SPI_CPOL = SPI_CPOL_Low;
tempInitData.spiInitStructure.SPI_CPHA = SPI_CPHA_1Edge;
tempInitData.spiInitStructure.SPI_NSS = SPI_NSS_Soft;
tempInitData.spiInitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
tempInitData.spiInitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
tempInitData.spiInitStructure.SPI_CRCPolynomial = 10;
SPI_Init(SPI2, &(tempInitData.spiInitStructure));
/* DMA_Channel configuration ---------------------------------*/
memset(&tempInitData, 0x00, sizeof(SigGenSpiInitData_u));
DMA_DeInit(DMA1_Stream4); // De-initialize the DMA Stream (DMA1_Stream4 for SPI2 TX)
tempInitData.dmaInitStructure.DMA_Channel = DMA_Channel_1; // Channel selection
tempInitData.dmaInitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DR; // SPI2 data register address
tempInitData.dmaInitStructure.DMA_Memory0BaseAddr = (uint32_t)m_SigGenGenBuffer_ch1; // Memory buffer address
tempInitData.dmaInitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; // Data direction: Memory to Peripheral
tempInitData.dmaInitStructure.DMA_BufferSize = CONF_SIGGEN_GEN_BUFFER_SIZE; // Buffer size
tempInitData.dmaInitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // Peripheral increment mode
tempInitData.dmaInitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Memory increment mode
tempInitData.dmaInitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // Peripheral data size (16 bits)
tempInitData.dmaInitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // Memory data size (16 bits)
tempInitData.dmaInitStructure.DMA_Mode = DMA_Mode_Circular; // Circular mode
tempInitData.dmaInitStructure.DMA_Priority = DMA_Priority_VeryHigh; // Priority level
tempInitData.dmaInitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; // FIFO mode
// tempInitData.dmaInitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; // FIFO threshold
// tempInitData.dmaInitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; // Memory burst
// tempInitData.dmaInitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // Peripheral burst
DMA_Init(DMA1_Stream4, &tempInitData);
//timer
/* Compute the prescaler value */
tempPrescalerValue = (uint16_t)(SystemCoreClock / 168000000) - 1;
/* Time base configuration */
memset(&tempInitData, 0x00, sizeof(SigGenSpiInitData_u));
tempInitData.timTimeBaseStructure.TIM_Period = CONF_SIGGEN_GEN_PERIOD;
tempInitData.timTimeBaseStructure.TIM_Prescaler =tempPrescalerValue;
tempInitData.timTimeBaseStructure.TIM_ClockDivision = 0;
tempInitData.timTimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM7, &(tempInitData.timTimeBaseStructure));
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure2;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseStructure2.TIM_Period = CONF_SIGGEN_GEN_PERIOD;
TIM_TimeBaseStructure2.TIM_Prescaler = tempPrescalerValue;
TIM_TimeBaseStructure2.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure2.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM12, &TIM_TimeBaseStructure2);
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = ( CONF_SIGGEN_GEN_PERIOD * 7 / 10 ); // Adjust the pulse width as needed
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC1Init(TIM12, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM12, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM12, ENABLE);
TIM_Cmd(TIM12, ENABLE); // Start Timer 12
/* TIM1 Update DMA Request enable */
TIM_DMACmd(TIM7, TIM_DMA_Update, ENABLE);
/* TIM1 counter enable */
TIM_Cmd(TIM7, ENABLE);
TIM_ARRPreloadConfig(TIM7, ENABLE);
/* Enable SPI DMA Tx request */
//SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
/* Enable SPI */
SPI_Cmd(SPI2, ENABLE);
/* Enable the selected DMA interrupts */
DMA_ITConfig(DMA1_Stream4, DMA_IT_HT | DMA_IT_TC, ENABLE);
// /* 1 bit for pre-emption priority, 3 bits for subpriority */
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
/* Configure and enable DMA interrupt -------------------------------*/
memset(&tempInitData, 0x00, sizeof(SigGenSpiInitData_u));
tempInitData.nvicInitStructure.NVIC_IRQChannel = DMA1_Stream4_IRQn;
tempInitData.nvicInitStructure.NVIC_IRQChannelPreemptionPriority = 0;
tempInitData.nvicInitStructure.NVIC_IRQChannelSubPriority = 0;
tempInitData.nvicInitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&(tempInitData.nvicInitStructure));
/* Enable DMA channels */
DMA_Cmd(DMA1_Stream4, ENABLE);
memset(&tempInitData, 0x00, sizeof(SigGenSpiInitData_u));
tempInitData.spiInitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
tempInitData.spiInitStructure.SPI_Mode = SPI_Mode_Master;
tempInitData.spiInitStructure.SPI_DataSize = SPI_DataSize_16b;
tempInitData.spiInitStructure.SPI_CPOL = SPI_CPOL_Low;
tempInitData.spiInitStructure.SPI_CPHA = SPI_CPHA_1Edge;
tempInitData.spiInitStructure.SPI_NSS = SPI_NSS_Soft;
tempInitData.spiInitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
tempInitData.spiInitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
tempInitData.spiInitStructure.SPI_CRCPolynomial = 10;
SPI_Init(SPI3, &(tempInitData.spiInitStructure));
/* DMA_Channel configuration ---------------------------------*/
memset(&tempInitData, 0x00, sizeof(SigGenSpiInitData_u));
DMA_DeInit(DMA1_Stream7); // De-initialize the DMA Stream (DMA1_Stream4 for SPI2 TX)// Activated to check output2 on 6th Jan Manas
tempInitData.dmaInitStructure.DMA_Channel = DMA_Channel_3; // Channel selection
tempInitData.dmaInitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI3->DR; // SPI2 data register address
tempInitData.dmaInitStructure.DMA_Memory0BaseAddr = (uint32_t)m_SigGenGenBuffer_ch2; // Memory buffer address
tempInitData.dmaInitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; // Data direction: Memory to Peripheral
tempInitData.dmaInitStructure.DMA_BufferSize = CONF_SIGGEN_GEN_BUFFER_SIZE; // Buffer size
tempInitData.dmaInitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // Peripheral increment mode
tempInitData.dmaInitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Memory increment mode
tempInitData.dmaInitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // Peripheral data size (16 bits)
tempInitData.dmaInitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // Memory data size (16 bits)
tempInitData.dmaInitStructure.DMA_Mode = DMA_Mode_Circular; // Circular mode
tempInitData.dmaInitStructure.DMA_Priority = DMA_Priority_VeryHigh; // Priority level
tempInitData.dmaInitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; // FIFO mode
// tempInitData.dmaInitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; // FIFO threshold
// tempInitData.dmaInitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; // Memory burst
// tempInitData.dmaInitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // Peripheral burst
DMA_Init(DMA1_Stream7, &tempInitData);
//
// //timer
//
// /* Compute the prescaler value */
tempPrescalerValue = (uint16_t)(SystemCoreClock / 168000000) - 1;
//
// /* Time base configuration */
memset(&tempInitData, 0x00, sizeof(SigGenSpiInitData_u));
tempInitData.timTimeBaseStructure.TIM_Period = CONF_SIGGEN_GEN_PERIOD;
tempInitData.timTimeBaseStructure.TIM_Prescaler =tempPrescalerValue;
tempInitData.timTimeBaseStructure.TIM_ClockDivision = 0;
tempInitData.timTimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &(tempInitData.timTimeBaseStructure));
TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);
/* TIM1 counter enable */
TIM_Cmd(TIM2, ENABLE);
SPI_Cmd(SPI3, ENABLE);
/* Enable the selected DMA interrupts */
DMA_ITConfig(DMA1_Stream7, DMA_IT_HT | DMA_IT_TC, ENABLE);
// /* 1 bit for pre-emption priority, 3 bits for subpriority */
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
/* Configure and enable DMA interrupt -------------------------------*/
memset(&tempInitData, 0x00, sizeof(SigGenSpiInitData_u));
tempInitData.nvicInitStructure.NVIC_IRQChannel = DMA1_Stream7_IRQn;
tempInitData.nvicInitStructure.NVIC_IRQChannelPreemptionPriority = 0;
tempInitData.nvicInitStructure.NVIC_IRQChannelSubPriority = 0;
tempInitData.nvicInitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&(tempInitData.nvicInitStructure));
TIM6_Config();
DMA_Cmd(DMA1_Stream7, ENABLE);
// TIM9_Config();
}
void DMA1_Stream4_IRQHandler(void)
{
if (DMA_GetFlagStatus(DMA1_Stream4, DMA_FLAG_HTIF4) != RESET)
{
// Clear DMA transfer complete flag
DMA_ClearFlag(DMA1_Stream4, DMA_FLAG_HTIF4); // Commented by Manas to check further with interrupt flag clear
//DMA_ClearITPendingBit(DMA1_Stream4, DMA_FLAG_HTIF4);
m_SigGenTempGenBufferPtr_ch1 = m_SigGenPingGenBufferPtr_ch1;
m_SigGenData_Op1.ptrCallBackInitGenBuffer();
// SigGenInitMonoPhasePulseGenBuffer();
// SigGenUpdateMonoPhasePulseGenParams();
if(gal_flag)
{
SigGenInitSine1GenBuffer();
}
// McuGalSwCh3On();
// McuGalSwCh4On();
}
if(DMA_GetFlagStatus(DMA1_Stream4, DMA_FLAG_TCIF4) != RESET)
{
DMA_ClearFlag(DMA1_Stream4, DMA_FLAG_TCIF4);// Commented by Manas to check further with interrupt flag clear
//DMA_ClearITPendingBit(DMA1_Stream4, DMA_FLAG_TCIF4);
m_SigGenTempGenBufferPtr_ch1 = m_SigGenPongGenBufferPtr_ch1;
m_SigGenData_Op1.ptrCallBackInitGenBuffer();
// SigGenInitSine1GenBuffer();
// SigGenInitMonoPhasePulseGenBuffer();
// SigGenUpdateMonoPhasePulseGenParams();
// McuGalSwCh3On();
// McuGalSwCh4On();
}
}
void DMA1_Stream7_IRQHandler(void)
{
if (DMA_GetFlagStatus(DMA1_Stream7, DMA_FLAG_HTIF7) != RESET)
{
// Clear DMA transfer complete flag
DMA_ClearFlag(DMA1_Stream7, DMA_FLAG_HTIF7);
//DMA_ClearITPendingBit(DMA1_Stream7, DMA_FLAG_HTIF7);
//m_SigGenTempGenBufferPtr_ch2 = m_SigGenPingGenBufferPtr_ch2;
//m_SigGenData_Op2.ptrCallBackInitGenBuffer();
if(gal_flag)
{
SigGenInitSine2GenBuffer();
}
}
if(DMA_GetFlagStatus(DMA1_Stream7, DMA_FLAG_TCIF7) != RESET)
{
DMA_ClearFlag(DMA1_Stream7, DMA_FLAG_TCIF7);
//DMA_ClearITPendingBit(DMA1_Stream7, DMA_FLAG_TCIF7);
//m_SigGenTempGenBufferPtr_ch2 = m_SigGenPongGenBufferPtr_ch2;
//m_SigGenData_Op2.ptrCallBackInitGenBuffer();
}
}
2025-01-07 05:38 AM
So, SPI3 does not work, regardless of whether SPI2/DMA1_Stream4 is enabled or not, correct?
Please prepare a *minimal* version of the code which exhibits the problem, i.e. don't put unnecessary elements to it. When posting code, use the </> icon at the top of the editor.
Check if SPI3 works if you feed it "manually", i.e. not through DMA (that checks if you've set up SPI3 and its pins properly).
Read out and check/post content of SPI and relevant DMA registers in the non-working state.
JW
2025-01-07 05:42 AM
Thanks @waclawek.jan ,
For the quick replay, but i have verified the SPI pins are good along with SPI3 is working with individually working fine. But once i integrate that to DMA with Stream there is no output.
2025-01-07 05:54 AM - edited 2025-01-07 05:54 AM
Read out and check/post content of SPI, TIM and relevant DMA registers (including HISR) in the non-working state.
JW