2018-01-22 08:56 AM
Hello all,
i have a aplication for a 3 phase motor, where i have 3 sensors read via SPI.
The microcontroler is a stm32F427 device
I am using timer1 for 6 pwm output, and the timer in countin mode TIM_CounterMode_CenterAligned3
So i am expecting a update event on the middle of the 'ON period', till here everything works as expected.
I am using two main IRQ handlers, one is timer2 where i setup the timer1 outputs ( acording to HALL inputs on TIM2 and XORED)
And the other IRQ handler is TIM1 Update handler
My problem is that if i have SPI read inside the timer1 update handler, the microcontroler wont start the motor.
If i dont have spi code, everything works. Why?
What is even courious, that i have SPI activiti which seems ok ( seen with a logic analyzer)... I
void TIM1_UP_TIM10_IRQHandler(void){
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_Update);// Read Phase current U
GPIOE->BSRRH = GPIO_Pin_10; // set Chip select 3 Low SPI1->DR = 0x00;/// write dummy data to trigger clock while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore current[0] =SPI1->DR; // return received data from SPI data register GPIOE->BSRRL = GPIO_Pin_10; //set Chip select 3
High}
}2018-01-23 09:48 AM
busy loop delays inside an ISR are never a good thing ...
busy loop delays with no timeout escape are never a good thing ...
2018-01-23 02:32 PM
your code seems incorrect,
// Read Phase current
while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) )
current[0] =SPI1->DR; // empty receiver
GPIOE->BSRRH = GPIO_Pin_10; // set Chip select 3 Low
SPI1->DR = 0x00;/// write dummy data to trigger clock
while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit completewhile( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore
current[0] =SPI1->DR; // return received data from SPI data register
2018-01-23 02:54 PM
Hello,
i have moved along with the SPI trough a DMA which handles TX and RX of the SPI periph.
The big question now is, how to trigger the SPI1 TX stream from the timer update event interrupt?
The timer1 update occurs in the middle of each pwm ON period, and from here, i want to trigger a DMA SPI TX event. Is this posible?
bellow is my SPI DMA code
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 , ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // transmit in master mode, NSS pin has to be always high SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; // one packet of data is 8 bits wide SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // clock is low when idle SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // data sampled at first edge SPI_InitStructure.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; // SPI frequency is APB2 frequency / 4 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first SPI_Init(SPI1, &SPI_InitStructure);/* Deinitialize DMA Streams */
DMA_DeInit(DMA2_Stream0); DMA_DeInit(DMA2_Stream3);DMA_InitTypeDef DMA_InitStructure;
/* Configure DMA Initialization Structure */
DMA_InitStructure.DMA_BufferSize = SPI_BUFF_SIZE ; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 16bit of data DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//DMA_MemoryInc_Enable; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) (&(SPI1->DR)) ; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_Priority = DMA_Priority_High;/* Configure TX DMA */
DMA_InitStructure.DMA_Channel = DMA_Channel_3; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral ; DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)aTxBuffer ; DMA_Init(DMA2_Stream3, &DMA_InitStructure);/* Configure RX DMA */
DMA_InitStructure.DMA_Channel = DMA_Channel_3 ; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ; DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)aRxBuffer ; DMA_Init(DMA2_Stream0, &DMA_InitStructure); //Enable the transfer complete interrupt for DMA2 Stream5 DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);/* Enable DMA SPI TX Stream */
DMA_Cmd(DMA2_Stream3,ENABLE);/* Enable DMA SPI RX Stream */
DMA_Cmd(DMA2_Stream0,ENABLE);/* Enable SPI DMA TX Requsts */
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE); /* Enable SPI DMA RX Requsts */ SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE); SPI_Cmd(SPI1, ENABLE); // enable SPI12018-01-31 04:30 AM
DMA_FIFOThreshold_1QuarterFull ;
are you sure that is what you want?