cancel
Showing results for 
Search instead for 
Did you mean: 

SPI comunication in STM32H743ZI (continuous clock on SPI ).

kgang
Associate II

Hi all,

I am using SPI protocol on STM32H7 for interfacing with external ADC . STM32H7 is acting as master and ADC as slave . SPI clock i am using is at 40 Mhz. spi clock is getting disabled after 25-30 clock cycles. i want continuous clock for this application for capturing data from ADC. otherwise i am missing ADC converted values in receiver buffer .

So i filled SPI control registers 2 TSER and TSIZE with value 0xFFFE.

and i also enabled TIFREIE bit in interrupt enable register.

In interrupt handler of SPI i check for status of TSERF bit of SPI SR register if it is SET. i load TSER [31:16] of CR2 with 0xFFFF and clear the TSERF bit in IFCR register.

But still i am unable to get continuous clock on SPI.

Any solution to this is highly appreciated.

Regards,

Krishna .

6 REPLIES 6
berendi
Principal

The clock stops when there is no data to transmit.

Either ensure that the output FIFO is always filled, or set SPI in receive only mode.

>  i also enabled TIFREIE bit in interrupt enable register

Why? Are you using TI framing?

kgang
Associate II

Thanks berendi for reply,

I have set it in receive only mode. This time i am getting continuous clock but as i am receiving data in spi interrupt mode the execution is coming to interrupt handler only once and then after it is staying in main while loop.and i am not able to receive any further data from adc.

Is the ADC data stream of a certain length or should it run indefinitely once started?

How do you read the incoming data? Can you post the interrupt handler code?

kgang
Associate II

Thanks berendi for reply ,

The data length from adc is 14 bit .it will send data continuously .

the requirement from ADC datasheet is the chip chip select(SS) or slave select of slave adc from master has to go low for first 14 clock cycles and after 14 clock cycles four clock cycles has to be maintained high (for aquisition period) so through put of ADC is 18 T clock cycles. and then chip select has to go low again this has to be a periodic . it will send data continuously and all the data needed to be captured for application.

so i disabled the spi cs of stm32 and chosen the gpio of stm32 as slave select for ADC. and controlled it through timer.

kgang
Associate II

//SPI IRQ handler code

void SPI1_IRQHandler(void)

{

 /* USER CODE BEGIN SPI1_IRQn 1 */

// receiving the data from adc

if( READ_BIT(hspi1.Instance->SR, SPI_SR_RXP) )

{

do{

rxBuffer[i++] = *(__IO uint16_t *)(&(hspi1.Instance->RXDR));

if(i>=1024)

i=0;

}while( READ_BIT(hspi1.Instance->SR, SPI_SR_RXP));

// CS HIGH for ADC

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

         

//enable the timer

htim2.Instance->CR1=0x00000001

//enable the timer update interrupt

  htim2.Instance->DIER=0x00000001;

}

}

//timer irq handler

void TIM2_IRQHandler(void)

{

// Clear update Interrupt

 if(READ_BIT(htim2.Instance->SR,TIM_SR_UIF))

  {

   // CLEAR_BIT(htim2.Instance->SR,TIM_SR_UIF);

    htim2.Instance->SR=0x00000000;

  }

 // CS operation

  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);

 /* USER CODE END TIM2_IRQn 1 */

}

so in the spi irq handler i am receiving the data from ADC as soon as i receive i am making gpio chip select high i am switching on timer and enabling the timer interrupt and in timer interrupt handler i am making gpio chip select low. so by doing this execution is coming to handler only once.

(Just formatted the code to be able to read it at all)

void SPI1_IRQHandler(void)
{
	/* USER CODE BEGIN SPI1_IRQn 1 */
	// receiving the data from adc
	if( READ_BIT(hspi1.Instance->SR, SPI_SR_RXP) )
	{
		do{
			rxBuffer[i++] = *(__IO uint16_t *)(&(hspi1.Instance->RXDR));
			if(i>=1024)
				i=0;
		}while( READ_BIT(hspi1.Instance->SR, SPI_SR_RXP));
		// CS HIGH for ADC
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
		//enable the timer
		htim2.Instance->CR1=0x00000001
				//enable the timer update interrupt
				htim2.Instance->DIER=0x00000001;
	}
}
//timer irq handler
void TIM2_IRQHandler(void)
{
	// Clear update Interrupt
	if(READ_BIT(htim2.Instance->SR,TIM_SR_UIF))
	{
		// CLEAR_BIT(htim2.Instance->SR,TIM_SR_UIF);
		htim2.Instance->SR=0x00000000;
	}
	// CS operation
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
	/* USER CODE END TIM2_IRQn 1 */
}