cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with SPI3 on STM32H725ZGT6 device

SMali.3
Associate III

Hello

I would like to make SPI3 on my board with STM32H725ZGT6 micro-controller work.

Here is my initialization:

void MX_SPI3_Init(void) {
	GPIO_InitTypeDef GPIO_InitStruct;

	/* SPI3 parameter configuration*/
	hspi3.Instance = SPI3;
	hspi3.Init.Mode = SPI_MODE_MASTER;
	hspi3.Init.Direction = SPI_DIRECTION_2LINES;
	hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
	hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;
	hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
	hspi3.Init.NSS = SPI_NSS_SOFT;
	hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
	hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
	hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
	hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
	hspi3.Init.CRCPolynomial = 0x0;
	hspi3.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
	hspi3.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
	hspi3.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
	hspi3.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
	hspi3.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
	hspi3.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
	hspi3.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
	hspi3.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
	hspi3.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
	hspi3.Init.IOSwap = SPI_IO_SWAP_DISABLE;
	if (HAL_SPI_Init(&hspi3) != HAL_OK) {
		Error_Handler();
	}
	//Now lets make our initialization

	__HAL_RCC_SPI3_CLK_ENABLE();
	__HAL_RCC_GPIOC_CLK_ENABLE();

	spi3UInttmp=(RCC->APB1LENR);
	sprintf(print_string,"SPI3 Device: APB1LENR register = 0x%x\n",spi3UInttmp);
	writeMessageRS232(PRIMARY_COM_PORT, (uint8_t *)print_string, strlen(print_string));

	/**SPI1 GPIO Configuration
  	PC10     ------> SPI1_SCK
	PC11     ------> SPI1_MISO
  	PC12     ------> SPI1_MOSI
	 */
	GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);


	(SPI3->CR1)|=0x00000001; //enable SPI
	(SPI3->CR1)&=0xfffffffe; //disable SPI

	/* SPI3 interrupt Init */
//    HAL_NVIC_SetPriority(SPI3_IRQn, 0, 0);
//    HAL_NVIC_EnableIRQ(SPI3_IRQn);
//    writeSPI3Index=0;
//    readSPI3Index=0;



	(RCC->CFGR)&=0x0000ffff;
	(RCC->CFGR)|=0x60000000; //uC clock output 2 -> pll1_p_ck
	(RCC->CFGR)|=0x14000000; //division by 10
	(RCC->CFGR)|=0x00c00000; //uC clock output 1 -> pll1_q_ck
	(RCC->CFGR)|=0x00280000; //division by 10

	/**Clock Output 2
  	PC9     ------> MCO2
	 */
	GPIO_InitStruct.Pin = GPIO_PIN_9;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

	/**Clock Output 1
  	PA8     ------> MCO1
	 */
	GPIO_InitStruct.Pin = GPIO_PIN_8;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

void spiGeneral_Init(void) {
	GPIO_InitTypeDef GPIO_InitStruct;

	MX_SPI3_Init();
	/* PD11, PD12, PD13, - SPI address Decoder pins - Output */
	GPIO_InitStruct.Pin =  GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

	DEC_DISABLE_RESET

#if 0
	GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	GPIO_InitStruct.Alternate = 0x0;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,1);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,1);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,1);
#endif

	sprintf(print_string,"SPI3 Device -> RCC source control register: RCC_CR = 0x%x\n",(unsigned int)(RCC->CR));
	writeMessageRS232(PRIMARY_COM_PORT, (uint8_t *)print_string, strlen(print_string));
	sprintf(print_string,"SPI3 Device -> RCC clock configuration register: RCC_CFGR = 0x%x\n",(unsigned int)(RCC->CFGR));
	writeMessageRS232(PRIMARY_COM_PORT, (uint8_t *)print_string, strlen(print_string));
	sprintf(print_string,"SPI3 Device -> RCC PLL configuration register: RCC_PLLCFGR = 0x%x\n",(unsigned int)(RCC->PLLCFGR));
	writeMessageRS232(PRIMARY_COM_PORT, (uint8_t *)print_string, strlen(print_string));
	sprintf(print_string,"SPI3 Device -> RCC domain 2 kernel clock configuration register: RCC_D2CCIP1R = 0x%x\n",(unsigned int)(RCC->D2CCIP1R));
	writeMessageRS232(PRIMARY_COM_PORT, (uint8_t *)print_string, strlen(print_string));
	sprintf(print_string,"SPI3 Device -> RCC APB1 clock enable register: RCC_APB1LENR = 0x%x\n",(unsigned int)(RCC->APB1LENR));
	writeMessageRS232(PRIMARY_COM_PORT, (uint8_t *)print_string, strlen(print_string));
	sprintf(print_string,"SPI3 Device -> RCC APB1 clock LP enable register: RCC_APB1LLPENR = 0x%x\n",(unsigned int)(RCC->APB1LLPENR));
	writeMessageRS232(PRIMARY_COM_PORT, (uint8_t *)print_string, strlen(print_string));


}

 

After calling this initialization I get this printout:

SPI3 Device: APB1LENR register = 0xa28000
SPI3 Device -> RCC source control register: RCC_CR = 0x303f025
SPI3 Device -> RCC clock configuration register: RCC_CFGR = 0x74e8001b
SPI3 Device -> RCC PLL configuration register: RCC_PLLCFGR = 0x1ff000d
SPI3 Device -> RCC domain 2 kernel clock configuration register: RCC_D2CCIP1R = 0x0
SPI3 Device -> RCC APB1 clock enable register: RCC_APB1LENR = 0xa28000
SPI3 Device -> RCC APB1 clock LP enable register: RCC_APB1LLPENR = 0xeaffc3ff

I assume that the 3 clocks are present on SPI3 block. I can measure both pll1_q_ck (on pin MCO1 -> PA8 - 97 is 55MHz with divider 10) and pll1_p_ck (on pin MCO2 -> PC9 - 96 is 11MHz with divider 10) with an oscilloscope on the pins of the micro-controller.

Then I am periodically sending 6 bytes of information to the transmit buffer to this function:

unsigned int i_spi, i_spiTimeout;
//for now limited to 16 bytes in one frame
unsigned char SPI3_TxRx(unsigned char device, unsigned char *dataRx, unsigned char *dataTx, unsigned int datalength) { //sending and receiving 8 bit data stream
	(SPI3->CR1)&=0xfffffffe; //disable SPI

	(SPI3->CFG1)&=0x8fffffff; //Master baud rate to 000
	(SPI3->CFG1)|=0x70000000; //Master baud rate to SPI master clock/256

	(SPI3->CFG1)&=0xffbfffff; //disable CRC calculation
//	(SPI3->CFG1)|=0x00400000; //enable CRC calculation
//	(SPI3->CFG1)&=0xffe0ffff; //reset CRCSIZE value
//	(SPI3->CFG1)|=0x00070000; //set CRCSIZE to 8bit
	(SPI3->CFG1)&=0xfffffe1f; //reset FIFO Threshold
//	(SPI3->CFG1)|=0x000001e0; //set FIFO Threshold level to 16 data
	(SPI3->CFG1)&=0xfffffff0; //reset DSIZE number of bits in the data frame
	(SPI3->CFG1)|=0x00000007; //set DSIZE to 8 bit data frame

	(SPI3->CFG2)|=0x10000000; //SPI is always in the control of associated GPIOs
	(SPI3->CFG2)&=0xbfffffff; //SSOE is disabled
//	(SPI3->CFG2)&=0xfdffffff; //CPOL is 0 -> sck is 0 when idle
	(SPI3->CFG2)|=0x02000000; //CPOL is 1 -> sck is 1 when idle
	(SPI3->CFG2)&=0xfeffffff; //CPHA is 0 -> first clock transition is the first data capture edge
//	(SPI3->CFG2)|=0x01000000; //CPHA is 1 -> the second clock transition is the first data capture edge
	(SPI3->CFG2)&=0xff7fffff; //LSBFIRST is 0 -> MSB is transmitted first
//	(SPI3->CFG2)|=0x00800000; //LSBFIRST is 1 -> LSB is transmitted first
//	(SPI3->CFG2)&=0xffbfffff; //MASTER is 0 -> device configured as slave
	(SPI3->CFG2)|=0x00400000; //MASTER is 1 -> device configured as master
	(SPI3->CFG2)&=0xffc7ffff; //SPI Motorola
//	(SPI3->CFG2)|=0x00080000; //SPI TI
	(SPI3->CFG2)&=0xfff9ffff; //COMM is full duplex
//	(SPI3->CFG2)|=0x00020000; //COMM is simplex transmitter
	(SPI3->CFG2)&=0xffffff0f; //MIDI - master inter data idleness -> no delay
	(SPI3->CFG2)|=0x00000050; //MIDI - master inter data idleness -> 5 SPI clock cycles

	(SPI3->IER)&=0x00000000; //disable all interrupts

	sprintf(print_string,"SPI3 Device: Status register 1 = 0x%x\n",(unsigned int)(SPI3->SR));
	writeMessageRS232(PRIMARY_COM_PORT, (uint8_t *)print_string, strlen(print_string));

	(SPI3->IFCR)|=0x0ff8; //clear all flags
	(SPI3->CR1)|=0x00000001; //enable SPI

	(SPI3->CR2)=datalength; //TSIZE number of data for current transfer
//	(SPI3->CR2)=0; //TSIZE number of data for current transfer
//	(SPI3->CR2)&=0x0000ffff; //TSER is 0, only one buffer to transmit
//	(SPI3->CR2)|=0xffff0000; //TSER is 0, only one buffer to transmit





	for(i_spi=0;i_spi<datalength;i_spi++) {
		*((__IO uint8_t *)SPI3->TXDR) = *((unsigned char *)dataTx);
//		*((__IO unsigned short int *)SPI3->TXDR) = *((unsigned char *)dataTx);
//		*((__IO unsigned int *)SPI3->TXDR) = *((unsigned char *)dataTx);
	}

	(SPI3->CR1)|=0x00000100; //master transfer start


	sprintf(print_string,"SPI3 Device: Status register 2 = 0x%x\n",(unsigned int)(SPI3->SR));
	writeMessageRS232(PRIMARY_COM_PORT, (uint8_t *)print_string, strlen(print_string));
	sprintf(print_string,"SPI3 Device: CR2 register = 0x%x\n",(unsigned int)(SPI3->CR2));
	writeMessageRS232(PRIMARY_COM_PORT, (uint8_t *)print_string, strlen(print_string));


	//wait till all bytes are transmitted and all received
	i_spiTimeout=0;
	while(((SPI3->SR)|0x00000008)!=0x00000008) { //check EOT bit for end of transfer
		i_spiTimeout++;
		if(i_spiTimeout>100000) {
			sprintf(print_string,"Error: SPI3 Device: EOT bit not set. Status register = 0x%x\n",(unsigned int)(SPI3->SR));
			writeMessageRS232(PRIMARY_COM_PORT, (uint8_t *)print_string, strlen(print_string));
			break;
//			return 1;
		}
	}
	for(i_spi=0;i_spi<datalength;i_spi++) {
		*((unsigned char *)dataRx) = *((__IO uint8_t *)SPI3->RXDR);
	}
	return 0;
}

 

The output to my console for the first 3 messages which I would like to send:

SPI3 Device: Status register 1 = 0x1202
SPI3 Device: Status register 2 = 0x202
SPI3 Device: CR2 register = 0x6
Error: SPI3 Device: EOT bit not set. Status register = 0x202

SPI3 Device: Status register 1 = 0x202
SPI3 Device: Status register 2 = 0x202
SPI3 Device: CR2 register = 0x6
Error: SPI3 Device: EOT bit not set. Status register = 0x202

SPI3 Device: Status register 1 = 0x202
SPI3 Device: Status register 2 = 0x202
SPI3 Device: CR2 register = 0x6
Error: SPI3 Device: EOT bit not set. Status register = 0x202

I see no activity on the SPI3 IO pins, no clock, no output. If I am controlling this pins PC10, PC11, P12 as a GPIO I can do that without problems. But no working SPI3. What I am doing wrong?

 

2 REPLIES 2
TDK
Guru

Does HAL_SPI_TransmitReceive() produce the correct output?

If you feel a post has answered your question, please click "Accept as Solution".
SMali.3
Associate III

Yes, using HAL_SPI_TransmitReceive() I get the expected output MOSI with CLK signal. I will go deeper into my code to see why it is not working. Thank you very much for the hint.