2024-10-02 06:41 AM
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?
2024-10-02 07:51 AM
Does HAL_SPI_TransmitReceive() produce the correct output?